diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1779fe9542f61851951275cecc37e367ad4acec5 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,9 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +./idea \ No newline at end of file diff --git a/.idea/PandaX.iml b/.idea/PandaX.iml new file mode 100644 index 0000000000000000000000000000000000000000..5e764c4f0b9a64bb78a5babfdd583713b2df47bf --- /dev/null +++ b/.idea/PandaX.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..4ddee959687abedd26abdb7a686b061a70236046 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..94a25f7f4cb416c083d265558da75d457237d671 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 5b01b951dda46be926e150d741c0884d97dc7653..d3dc81381e7b876f0877668f5da227cc8a4b1971 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@ # PandaX -
-

PandaX 快速开发平台

-

基于Gin前后端分离架构,代码精简,开箱即用,前端紧随前沿 Vue3.0 + TypeScript + vite2 + Element-plus技术

+
+

PandaX 物联网快速开发基座

+

基于Go前后端分离架构,代码精简,开箱即用,前端紧随前沿 Vue3.0 + TypeScript + vite3 + Element-plus技术

## 🌈平台简介 -* 采用前后端分离的模式,后端采用GO语言,后端集成框架gin和go-restful(k8s使用的api框架)通过对GIn和go-restful自封装框架ginx,restfulx,代码更简洁,逻辑更清晰。另外拥抱云原生后期更新会采用go-restful框架做主要开发 -* 根据不同分支选择使用的框架[gin分支](https://github.com/XM-GO/PandaX/tree/ginx) [go-restful分支](https://github.com/XM-GO/PandaX/tree/go-restful) -* 前端采用VUE3.0+ TypeScript + vite2 + Element-plus:[PandaUI](https://github.com/PandaGoAdmin/PandaUi),适配手机、平板、pc 内置多种ui功能减少开发量 +* 对前后端进行了大部分功能的封装,后端自封装go-restful,使用起来更加简洁,功能逻辑清晰,能快速上手学习,并用在生产中。 +* 报表大屏设计器: 我们只需要拖拉拽即可绑定数据库,完成组态,报表和炫酷大屏的制作,无需要单独开发大屏。 +* 成熟的规则引擎: 项目针对数据处理使用了规则链进行处理,简化开发及配置。 +* 前端采用VUE3.0+ TypeScript + vite3 + Element-plus:[PandaUI](https://gitee.com/XM-GO/PandaUi),适配手机、平板、pc 内置多种ui功能减少开发量 * 高效率的开发,使用代码生成器可以一键生成前后端代码,可在线预览代码,减少代码开发量。。 * 完善的权限认证系统:完善的权限认证系统,包含,菜单按钮权限,api权限,部门权限。 * 多数据库:项目同时支持MySQL,PostgreSql等数据库根据自身需求更改。 @@ -17,12 +18,13 @@ ## 🏭在线体验 演示地址:http://101.35.247.125:7789/ 帐号:admin 密码:123456 -组态大屏:http://101.35.247.125:7790/ +组态大屏:http://101.35.247.125:7790/ +规则引擎:http://101.35.247.125:7791/ --- 系统在线文档 --- -* 文档地址 :https://xm-go.gitee.io/pandax-docs/ +* 文档地址 :http://101.35.247.125 **> 未来会补充文档和视频,方便友友们使用!** @@ -30,52 +32,45 @@ - - + - - + + - - - - - - - -
更多功能请访问系统体验 -#### 💒 代码仓库 - -- PandaX 快速开发平台 https://github.com/PandaGoAdmin/PandaX -- PandaUI 平台Ui https://github.com/PandaGoAdmin/PandaUi - ## 联系我们 **QQ:2417920382** 点击这里给我发消息 **QQ群:467890197** PandaX快速开发交流群 -
## ⚡ 内置功能 -1. _用户管理:用户是系统操作者,该功能主要完成系统用户配置。_ -2. _部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。_ -3. _岗位管理:配置系统用户所属担任职务。_ -4. _菜单管理:配置系统菜单,操作权限,按钮权限标识等。_ -5. _角色管理:角色菜单,API权限分配、设置角色按机构进行数据范围权限划分。_ -6. _字典管理:对系统中经常使用的一些较为固定的数据进行维护。_ -7. _参数管理:对系统动态配置常用参数。_ -8. 通知公告:系统通知公告信息发布维护。 -9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 -10. _登录日志:系统登录日志记录查询包含登录异常。_ -11. 在线用户:当前系统中活跃用户状态监控。 -12. _定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。_ -13. _代码生成:前后端代码的生成(go、vue、sql)支持CRUD下载 。_ -14. 系统接口:根据业务代码自动生成相关的api接口文档。 -15. _服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。_ +- **`用户管理`** - _用户是系统操作者,该功能主要完成系统用户配置。._ +- **`部门管理`** - _配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。_ +- **`岗位管理`** - _配置系统用户所属担任职务。_ +- **`菜单管理`** - _配置系统菜单,操作权限,按钮权限标识等。_ +- **`角色管理`** - _角色菜单,API权限分配、设置角色按机构进行数据范围权限划分。_ +- **`字典管理`** - _对系统中经常使用的一些较为固定的数据进行维护。_ +- **`参数管理`** - _对系统动态配置常用参数。_ +- **`通知公告`** - _系统通知公告信息发布维护_ +- **`日志系统`** - _记录日志,更直观浏览_ +- **`系统接口`** - _根据业务代码自动生成相关的api接口文档。_ +- **`服务监控`** - _监视当前系统CPU、内存、磁盘、堆栈等相关信息。_ +- **`代码生成`** - _可直接通过框架生成前后端基础业务代码(go、vue),减少开发时间。_ +- **`组态大屏设计器`** - _通过拖拉拽直接生成组态、大屏。_ +- **`规则链设计`** - _物联网规则链过滤_ +- **`报表设计`** - _数据报表设计_ +- **`产品管理`** - _设备的产品管理_ +- **`设备管理`** - _设备的管理_ + +## 🛠 以后可能会有什么NB功能? +- 开发中 **`应用管理`** - _基于K8S编排能力,创建应用管理模块。_ +- 开发中 **`多协议接入`** - _根据插件形式创建多协议接入_ +- 开发中 **`3D组态`** - _根据2d组态自动生成3D组态_ +- 开发中 **`数字孪生编辑器`** - _web直接构建数字孪生模型_ --- 前端工程结构 @@ -101,32 +96,21 @@ ## 后端工程结构 -| 项目 | 说明 | -| --- | --- | -| `base` | 自封装restfulx和工具类 | -| `docs` | api接口文档 | -| `initialize` | 初始化 | -| `resource` | 文件导出目录 | -| `static` | 前端代码构建 | -| `system` | 系统模块 | +| 目录 | 功能 | +|:----------:|:-------------------------------------| +| `deploy` | 部署文件,本项目部署是利用`K3S`进行部署的,因此里面的文档为部署文档 | +| `apps` | 基本功能,所有功能模块全在这里面 | +| `iothub` | 设备接入层,设备数据上报在这里处理,使用emqx的hook模式 | +| `resource` | 项目启动或生成的资源文件存放目录。 | +| `pkg` | 所有开发过程中的全局通用代码。 | +| `uploads` | 存储上传的文件的地方 | 更多功能请访问系统。 -## 🍉 开发计划 - -* :clipboard: 代码生成器 -* :clipboard: 资源文件管理中心 -* :clipboard: 任务调度系统 -* :clipboard: 监控系统 -* :clipboard: 移动开发平台-基于uniapp -* :clipboard: 工作流 -* :clipboard: 大屏系统 -* :clipboard: 报表系统 - ## ❤特别鸣谢 - * 感谢[VUE-NEXT-ADMIN](https://github.com/lyt-Top/vue-next-admin) + * 感谢[VUE-NEXT-ADMIN](https://gitee.com/lyt-top/vue-next-admin) --- 版权说明 diff --git a/apps/device/api/device.go b/apps/device/api/device.go new file mode 100644 index 0000000000000000000000000000000000000000..ed7a8fee2bd7c51116792c78b9edc6c84386ba89 --- /dev/null +++ b/apps/device/api/device.go @@ -0,0 +1,214 @@ +package api + +// ========================================================================== +// 生成日期:2023-06-30 09:19:43 +0800 CST +// 生成路径: apps/device/api/devices.go +// 生成人:panda +// ========================================================================== +import ( + "encoding/json" + "fmt" + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "pandax/pkg/global" + "pandax/pkg/mqtt" + "strings" + "time" + + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +type DeviceApi struct { + DeviceApp services.DeviceModel + ProductApp services.ProductModel + ProductTemplateApp services.ProductTemplateModel +} + +// GetDeviceList Device列表数据 +func (p *DeviceApi) GetDeviceList(rc *restfulx.ReqCtx) { + data := entity.Device{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.Name = restfulx.QueryParam(rc, "name") + data.Status = restfulx.QueryParam(rc, "status") + data.Pid = restfulx.QueryParam(rc, "pid") + data.Gid = restfulx.QueryParam(rc, "gid") + data.DeviceType = restfulx.QueryParam(rc, "deviceType") + data.ParentId = restfulx.QueryParam(rc, "parentId") + data.LinkStatus = restfulx.QueryParam(rc, "linkStatus") + + list, total := p.DeviceApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// GetDeviceListAll Device获取所有 +func (p *DeviceApi) GetDeviceListAll(rc *restfulx.ReqCtx) { + data := entity.Device{} + data.Name = restfulx.QueryParam(rc, "name") + data.Status = restfulx.QueryParam(rc, "status") + data.Pid = restfulx.QueryParam(rc, "pid") + data.DeviceType = restfulx.QueryParam(rc, "deviceType") + + list := p.DeviceApp.FindList(data) + rc.ResData = list +} + +// GetDevice 获取Device +func (p *DeviceApi) GetDevice(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.DeviceApp.FindOne(id) +} + +// GetDeviceStatus 获取Device状态信息 +func (p *DeviceApi) GetDeviceStatus(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + classify := restfulx.QueryParam(rc, "classify") + device := p.DeviceApp.FindOne(id) + template := p.ProductTemplateApp.FindList(entity.ProductTemplate{Classify: classify, Pid: device.Pid}) + + res := make([]entity.DeviceStatusVo, 0) + rs, err := global.TdDb.GetOne(fmt.Sprintf(`select * from %s_%s ORDER BY ts DESC LIMIT 1`, device.Name, classify)) + biz.ErrIsNil(err, "查询设备状态信息失败") + for _, tel := range *template { + sdv := entity.DeviceStatusVo{ + Name: tel.Name, + Key: tel.Key, + Type: tel.Type, + Define: tel.Define, + Time: rs["ts"], + } + if v, ok := rs[tel.Key]; ok { + sdv.Value = v + } else { + sdv.Value = tel.Define["default_value"] + } + res = append(res, sdv) + } + + rc.ResData = res +} + +// 下发设备属性 +func (p *DeviceApi) DownAttribute(rc *restfulx.ReqCtx) { + //id := restfulx.PathParam(rc, "id") + key := restfulx.QueryParam(rc, "key") + value := restfulx.QueryParam(rc, "value") + // 下发指令 + contentMap := map[string]interface{}{ + key: value, + } + content, _ := json.Marshal(contentMap) + var rpc = &mqtt.RpcRequest{Client: global.MqttClient, RequestId: 1, Mode: "single"} + rpc.GetRequestId() + err := rpc.RequestAttributes(mqtt.RpcPayload{Params: string(content)}) + biz.ErrIsNil(err, "属性下发失败") +} + +// InsertDevice 添加Device +func (p *DeviceApi) InsertDevice(rc *restfulx.ReqCtx) { + var data entity.Device + restfulx.BindJsonAndValid(rc, &data) + list := p.DeviceApp.FindList(entity.Device{Name: data.Name}) + biz.IsTrue(!(list != nil && len(*list) > 0), fmt.Sprintf("名称%s已存在,设置其他命名", data.Name)) + data.Id = kgo.KStr.Uniqid("d_") + data.Owner = rc.LoginAccount.UserName + data.LinkStatus = global.INACTIVE + data.LastAt = time.Now() + p.DeviceApp.Insert(data) + // 视频设备不创建超级表 + if data.DeviceType != global.MONITOR { + createDeviceTable(data.Pid, data.Name) + } +} + +// UpdateDevice 修改Device +func (p *DeviceApi) UpdateDevice(rc *restfulx.ReqCtx) { + var data entity.Device + restfulx.BindJsonAndValid(rc, &data) + + p.DeviceApp.Update(data) +} + +// DeleteDevice 删除Device +func (p *DeviceApi) DeleteDevice(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + for _, id := range ids { + list := p.DeviceApp.FindOne(id) + // 删除表 + if list.DeviceType != global.MONITOR { + deleteDeviceTable(list.Name) + } + } + p.DeviceApp.Delete(ids) +} + +func (p *DeviceApi) ScreenTwinData(rc *restfulx.ReqCtx) { + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + classId := restfulx.QueryParam(rc, "classId") + if classId == "" { + vp := make([]entity.VisualClass, 0) + list := p.ProductApp.FindList(entity.Product{}) + for _, pro := range *list { + data := p.ProductTemplateApp.FindListAttrs(entity.ProductTemplate{Pid: pro.Id}) + vta := make([]entity.VisualTwinAttr, 0) + for _, attr := range *data { + twinAttr := entity.VisualTwinAttr{ + Key: attr.Key, + Name: attr.Name, + Type: attr.Type, + } + if attr.Classify == "attributes" { + if rw, ok := attr.Define["rw"].(string); ok { + twinAttr.Rw = rw + } else { + twinAttr.Rw = "r" + } + } else { + twinAttr.Rw = "r" + } + vta = append(vta, twinAttr) + } + vp = append(vp, entity.VisualClass{ + ClassId: pro.Id, + Name: pro.Name, + Attrs: vta, + }) + } + rc.ResData = vp + } else { + findList, _ := p.DeviceApp.FindListPage(pageNum, pageSize, entity.Device{Pid: classId}) + vt := make([]entity.VisualTwin, 0) + for _, device := range *findList { + vt = append(vt, entity.VisualTwin{ + TwinId: device.Id, + Name: device.Name + "-" + device.Alias, + }) + } + rc.ResData = vt + } +} + +func createDeviceTable(productId, device string) { + err := global.TdDb.CreateTable(productId+"_"+entity.ATTRIBUTES_TSL, device+"_"+entity.ATTRIBUTES_TSL) + biz.ErrIsNil(err, "创建时序属性表失败") + err = global.TdDb.CreateTable(productId+"_"+entity.TELEMETRY_TSL, device+"_"+entity.TELEMETRY_TSL) + biz.ErrIsNil(err, "创建时序遥测表失败") +} + +func deleteDeviceTable(device string) { + err := global.TdDb.DropTable(device + "_" + entity.ATTRIBUTES_TSL) + biz.ErrIsNil(err, "删除时序属性表失败") + err = global.TdDb.DropTable(device + "_" + entity.TELEMETRY_TSL) + biz.ErrIsNil(err, "删除时序遥测表失败") +} diff --git a/apps/device/api/device_alarm.go b/apps/device/api/device_alarm.go new file mode 100644 index 0000000000000000000000000000000000000000..d8a167d66ab0caa302569c9e6d10fcd98ed6d60e --- /dev/null +++ b/apps/device/api/device_alarm.go @@ -0,0 +1,49 @@ +package api + +// ========================================================================== +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "strings" + + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +type DeviceAlarmApi struct { + DeviceAlarmApp services.DeviceAlarmModel +} + +// GetDeviceAlarmList 告警列表数据 +func (p *DeviceAlarmApi) GetDeviceAlarmList(rc *restfulx.ReqCtx) { + data := entity.DeviceAlarm{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.DeviceId = restfulx.QueryParam(rc, "deviceId") + data.Type = restfulx.QueryParam(rc, "type") + data.Level = restfulx.QueryParam(rc, "level") + data.State = restfulx.QueryParam(rc, "state") + + list, total := p.DeviceAlarmApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// UpdateDeviceAlarm 修改告警 +func (p *DeviceAlarmApi) UpdateDeviceAlarm(rc *restfulx.ReqCtx) { + var data entity.DeviceAlarm + restfulx.BindJsonAndValid(rc, &data) + p.DeviceAlarmApp.Update(data) +} + +// DeleteDeviceAlarm 删除告警 +func (p *DeviceAlarmApi) DeleteDeviceAlarm(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + p.DeviceAlarmApp.Delete(ids) +} diff --git a/apps/device/api/device_cmd.go b/apps/device/api/device_cmd.go new file mode 100644 index 0000000000000000000000000000000000000000..1a806c549b636120d0a8f87112e2b666628ed6f7 --- /dev/null +++ b/apps/device/api/device_cmd.go @@ -0,0 +1,64 @@ +package api + +// ========================================================================== +import ( + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "pandax/pkg/global" + "pandax/pkg/mqtt" + "strings" + "time" + + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +type DeviceCmdLogApi struct { + DeviceCmdLogApp services.DeviceCmdLogModel +} + +// GetDeviceCmdLogList 告警列表数据 +func (p *DeviceCmdLogApi) GetDeviceCmdLogList(rc *restfulx.ReqCtx) { + data := entity.DeviceCmdLog{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.DeviceId = restfulx.QueryParam(rc, "deviceId") + data.State = restfulx.QueryParam(rc, "state") + data.Type = restfulx.QueryParam(rc, "type") + + list, total := p.DeviceCmdLogApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// InsertDeviceCmdLog 添加DeviceCmdLog +func (p *DeviceCmdLogApi) InsertDeviceCmdLog(rc *restfulx.ReqCtx) { + var data entity.DeviceCmdLog + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("cmd_") + data.State = "2" + data.RequestTime = time.Now().Format("2006-01-02 15:04:05") + err := p.DeviceCmdLogApp.Insert(data) + biz.ErrIsNil(err, "添加指令记录失败") + // 下发指令 + var rpc = &mqtt.RpcRequest{Client: global.MqttClient, Mode: "single"} + rpc.GetRequestId() + err = rpc.RequestCmd(mqtt.RpcPayload{Method: data.CmdName, Params: data.CmdContent}) + if err != nil { + global.Log.Error("指令下发失败") + } +} + +// DeleteDeviceCmdLog 删除告警 +func (p *DeviceCmdLogApi) DeleteDeviceCmdLog(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + p.DeviceCmdLogApp.Delete(ids) +} diff --git a/apps/device/api/device_group.go b/apps/device/api/device_group.go new file mode 100644 index 0000000000000000000000000000000000000000..106317a9a41ed64d13f86e93041048b0c0ac0261 --- /dev/null +++ b/apps/device/api/device_group.go @@ -0,0 +1,79 @@ +package api + +import ( + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "pandax/apps/device/entity" + "pandax/apps/device/services" + "strings" +) + +type DeviceGroupApi struct { + DeviceGroupApp services.DeviceGroupModel +} + +// GetDeviceGroupTree DeviceGroup 树 +func (p *DeviceGroupApi) GetDeviceGroupTree(rc *restfulx.ReqCtx) { + name := restfulx.QueryParam(rc, "name") + status := restfulx.QueryParam(rc, "status") + id := restfulx.QueryParam(rc, "id") + + sg := entity.DeviceGroup{Name: name, Status: status} + sg.Id = id + rc.ResData = p.DeviceGroupApp.SelectDeviceGroup(sg) +} + +func (p *DeviceGroupApi) GetDeviceGroupTreeLabel(rc *restfulx.ReqCtx) { + sg := entity.DeviceGroup{} + rc.ResData = p.DeviceGroupApp.SelectDeviceGroupLabel(sg) +} + +func (p *DeviceGroupApi) GetDeviceGroupList(rc *restfulx.ReqCtx) { + name := restfulx.QueryParam(rc, "name") + status := restfulx.QueryParam(rc, "status") + id := restfulx.QueryParam(rc, "id") + + sg := entity.DeviceGroup{Name: name, Status: status} + sg.Id = id + if sg.Name == "" { + rc.ResData = p.DeviceGroupApp.SelectDeviceGroup(sg) + } else { + rc.ResData = p.DeviceGroupApp.FindList(sg) + } +} + +// GetDeviceGroupAllList 查询所有 +func (p *DeviceGroupApi) GetDeviceGroupAllList(rc *restfulx.ReqCtx) { + var vsg entity.DeviceGroup + rc.ResData = p.DeviceGroupApp.FindList(vsg) +} + +// GetDeviceGroup 获取DeviceGroup +func (p *DeviceGroupApi) GetDeviceGroup(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.DeviceGroupApp.FindOne(id) +} + +// InsertDeviceGroup 添加DeviceGroup +func (p *DeviceGroupApi) InsertDeviceGroup(rc *restfulx.ReqCtx) { + var data entity.DeviceGroup + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("dg_") + data.Owner = rc.LoginAccount.UserName + p.DeviceGroupApp.Insert(data) +} + +// UpdateDeviceGroup 修改DeviceGroup +func (p *DeviceGroupApi) UpdateDeviceGroup(rc *restfulx.ReqCtx) { + var data entity.DeviceGroup + restfulx.BindJsonAndValid(rc, &data) + + p.DeviceGroupApp.Update(data) +} + +// DeleteDeviceGroup 删除DeviceGroup +func (p *DeviceGroupApi) DeleteDeviceGroup(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + p.DeviceGroupApp.Delete(ids) +} diff --git a/apps/device/api/product.go b/apps/device/api/product.go new file mode 100644 index 0000000000000000000000000000000000000000..4cff209844eb00f9a89215b29cb2a42c530731f5 --- /dev/null +++ b/apps/device/api/product.go @@ -0,0 +1,118 @@ +package api + +// ========================================================================== +// 生成日期:2023-06-30 08:57:48 +0800 CST +// 生成路径: apps/device/api/products.go +// 生成人:panda +// ========================================================================== +import ( + "fmt" + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "pandax/pkg/global" + "strings" + + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +type ProductApi struct { + ProductApp services.ProductModel + DeviceApp services.DeviceModel + TemplateApp services.ProductTemplateModel + OtaAPP services.ProductOtaModel +} + +// GetProductList Product列表数据 +func (p *ProductApi) GetProductList(rc *restfulx.ReqCtx) { + data := entity.Product{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.Status = restfulx.QueryParam(rc, "status") + data.ProductCategoryId = restfulx.QueryParam(rc, "productCategoryId") + data.ProtocolName = restfulx.QueryParam(rc, "protocolName") + data.DeviceType = restfulx.QueryParam(rc, "deviceType") + data.Name = restfulx.QueryParam(rc, "name") + + list, total := p.ProductApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +func (p *ProductApi) GetProductListAll(rc *restfulx.ReqCtx) { + data := entity.Product{} + data.Status = restfulx.QueryParam(rc, "status") + data.ProductCategoryId = restfulx.QueryParam(rc, "productCategoryId") + data.ProtocolName = restfulx.QueryParam(rc, "protocolName") + data.DeviceType = restfulx.QueryParam(rc, "deviceType") + data.Name = restfulx.QueryParam(rc, "name") + + rc.ResData = p.ProductApp.FindList(data) +} + +// GetProduct 获取Product +func (p *ProductApi) GetProduct(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.ProductApp.FindOne(id) +} + +// InsertProduct 添加Product +func (p *ProductApi) InsertProduct(rc *restfulx.ReqCtx) { + var data entity.Product + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("p_") + data.Owner = rc.LoginAccount.UserName + p.ProductApp.Insert(data) + // 创建taos数据库超级表 摄像头产品不创建 + if data.DeviceType != global.MONITOR { + createDeviceStable(data.Id) + } +} + +// UpdateProduct 修改Product +func (p *ProductApi) UpdateProduct(rc *restfulx.ReqCtx) { + var data entity.Product + restfulx.BindJsonAndValid(rc, &data) + + p.ProductApp.Update(data) +} + +// DeleteProduct 删除Product +func (p *ProductApi) DeleteProduct(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + for _, id := range ids { + list := p.DeviceApp.FindList(entity.Device{Pid: id}) + biz.IsTrue(!(list != nil && len(*list) > 0), fmt.Sprintf("产品ID%s下存在设备,不能被删除", id)) + } + // 删除产品 + p.ProductApp.Delete(ids) + for _, id := range ids { + // 删除所有模型,固件 + p.TemplateApp.Delete([]string{id}) + p.OtaAPP.Delete([]string{id}) + // 删除超级表 + deleteDeviceStable(id) + } +} + +func createDeviceStable(productId string) { + err := global.TdDb.CreateStable(productId + "_" + entity.ATTRIBUTES_TSL) + biz.ErrIsNil(err, "创建时序属性超级表失败") + err = global.TdDb.CreateStable(productId + "_" + entity.TELEMETRY_TSL) + biz.ErrIsNil(err, "创建时序遥测超级表失败") +} + +func deleteDeviceStable(productId string) { + err := global.TdDb.DropStable(productId + "_" + entity.ATTRIBUTES_TSL) + biz.ErrIsNil(err, "删除时序属性超级表失败") + err = global.TdDb.DropStable(productId + "_" + entity.TELEMETRY_TSL) + biz.ErrIsNil(err, "删除时序遥测超级表失败") +} diff --git a/apps/device/api/product_category.go b/apps/device/api/product_category.go new file mode 100644 index 0000000000000000000000000000000000000000..9e36c75b38c04ccba5e043838f66e05c7f16e2aa --- /dev/null +++ b/apps/device/api/product_category.go @@ -0,0 +1,80 @@ +package api + +import ( + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "pandax/apps/device/entity" + "pandax/apps/device/services" + "strings" +) + +type ProductCategoryApi struct { + ProductCategoryApp services.ProductCategoryModel +} + +// GetProductCategoryTree ProductCategory 树 +func (p *ProductCategoryApi) GetProductCategoryTree(rc *restfulx.ReqCtx) { + name := restfulx.QueryParam(rc, "name") + status := restfulx.QueryParam(rc, "status") + id := restfulx.QueryParam(rc, "id") + /*err := rc.Validate.Var(id, "required") + biz.ErrIsNil(err, "id 必传")*/ + sg := entity.ProductCategory{Name: name, Status: status} + sg.Id = id + rc.ResData = p.ProductCategoryApp.SelectProductCategory(sg) +} + +func (p *ProductCategoryApi) GetProductCategoryTreeLabel(rc *restfulx.ReqCtx) { + sg := entity.ProductCategory{} + rc.ResData = p.ProductCategoryApp.SelectProductCategoryLabel(sg) +} + +func (p *ProductCategoryApi) GetProductCategoryList(rc *restfulx.ReqCtx) { + name := restfulx.QueryParam(rc, "name") + status := restfulx.QueryParam(rc, "status") + id := restfulx.QueryParam(rc, "id") + + sg := entity.ProductCategory{Name: name, Status: status} + sg.Id = id + if sg.Name == "" { + rc.ResData = p.ProductCategoryApp.SelectProductCategory(sg) + } else { + rc.ResData = p.ProductCategoryApp.FindList(sg) + } +} + +// GetProductCategoryAllList 查询所有 +func (p *ProductCategoryApi) GetProductCategoryAllList(rc *restfulx.ReqCtx) { + var vsg entity.ProductCategory + rc.ResData = p.ProductCategoryApp.FindList(vsg) +} + +// GetProductCategory 获取ProductCategory +func (p *ProductCategoryApi) GetProductCategory(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.ProductCategoryApp.FindOne(id) +} + +// InsertProductCategory 添加ProductCategory +func (p *ProductCategoryApi) InsertProductCategory(rc *restfulx.ReqCtx) { + var data entity.ProductCategory + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("pc_") + data.Owner = rc.LoginAccount.UserName + p.ProductCategoryApp.Insert(data) +} + +// UpdateProductCategory 修改ProductCategory +func (p *ProductCategoryApi) UpdateProductCategory(rc *restfulx.ReqCtx) { + var data entity.ProductCategory + restfulx.BindJsonAndValid(rc, &data) + + p.ProductCategoryApp.Update(data) +} + +// DeleteProductCategory 删除ProductCategory +func (p *ProductCategoryApi) DeleteProductCategory(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + p.ProductCategoryApp.Delete(ids) +} diff --git a/apps/device/api/product_ota.go b/apps/device/api/product_ota.go new file mode 100644 index 0000000000000000000000000000000000000000..58246b10badcc353b376170fe6885bada78b6382 --- /dev/null +++ b/apps/device/api/product_ota.go @@ -0,0 +1,63 @@ +package api + +// ========================================================================== +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "strings" + + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +type ProductOtaApi struct { + ProductOtaApp services.ProductOtaModel +} + +// GetProductOtaList Ota列表数据 +func (p *ProductOtaApi) GetProductOtaList(rc *restfulx.ReqCtx) { + data := entity.ProductOta{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.Name = restfulx.QueryParam(rc, "name") + data.Pid = restfulx.QueryParam(rc, "pid") + + list, total := p.ProductOtaApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// GetProductOta 获取Ota +func (p *ProductOtaApi) GetProductOta(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.ProductOtaApp.FindOne(id) +} + +// InsertProductOta 添加Ota +func (p *ProductOtaApi) InsertProductOta(rc *restfulx.ReqCtx) { + var data entity.ProductOta + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("ota_") + p.ProductOtaApp.Insert(data) +} + +// UpdateProductOta 修改Ota +func (p *ProductOtaApi) UpdateProductOta(rc *restfulx.ReqCtx) { + var data entity.ProductOta + restfulx.BindJsonAndValid(rc, &data) + + p.ProductOtaApp.Update(data) +} + +// DeleteProductOta 删除Ota +func (p *ProductOtaApi) DeleteProductOta(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := strings.Split(id, ",") + p.ProductOtaApp.Delete(ids) +} diff --git a/apps/device/api/product_template.go b/apps/device/api/product_template.go new file mode 100644 index 0000000000000000000000000000000000000000..8f4f22af42db7b9f2b004e99db23e0fff181e3c1 --- /dev/null +++ b/apps/device/api/product_template.go @@ -0,0 +1,118 @@ +package api + +import ( + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "log" + "pandax/pkg/global" + "strings" + + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +type ProductTemplateApi struct { + ProductTemplateApp services.ProductTemplateModel +} + +// GetProductTemplateList Template列表数据 +func (p *ProductTemplateApi) GetProductTemplateList(rc *restfulx.ReqCtx) { + data := entity.ProductTemplate{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.Pid = restfulx.QueryParam(rc, "pid") + data.Classify = restfulx.QueryParam(rc, "classify") + data.Name = restfulx.QueryParam(rc, "name") + + list, total := p.ProductTemplateApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// GetProductTemplateListAll Template所有列表数据 +func (p *ProductTemplateApi) GetProductTemplateListAll(rc *restfulx.ReqCtx) { + data := entity.ProductTemplate{} + data.Pid = restfulx.QueryParam(rc, "pid") + data.Classify = restfulx.QueryParam(rc, "classify") + data.Name = restfulx.QueryParam(rc, "name") + list := p.ProductTemplateApp.FindList(data) + rc.ResData = list +} + +// GetProductTemplate 获取Template +func (p *ProductTemplateApi) GetProductTemplate(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.ProductTemplateApp.FindOne(id) +} + +// InsertProductTemplate 添加Template +func (p *ProductTemplateApi) InsertProductTemplate(rc *restfulx.ReqCtx) { + var data entity.ProductTemplate + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("tm_") + p.ProductTemplateApp.Insert(data) + // 向超级表中添加字段 + if data.Classify == entity.ATTRIBUTES_TSL { + err := global.TdDb.AddSTableField(data.Pid+"_"+entity.ATTRIBUTES_TSL, data.Key, data.Type, 0) + biz.ErrIsNil(err, "添加字段失败") + } + if data.Classify == entity.TELEMETRY_TSL { + len := 0 + if data.Type == "string" { + len = int(data.Define["length"].(int64)) + } + err := global.TdDb.AddSTableField(data.Pid+"_"+entity.TELEMETRY_TSL, data.Key, data.Type, len) + biz.ErrIsNil(err, "添加字段失败") + } + // todo 已经创建的表,超级表字段更新时,需要同步设备表字段 +} + +// UpdateProductTemplate 修改Template +func (p *ProductTemplateApi) UpdateProductTemplate(rc *restfulx.ReqCtx) { + var data entity.ProductTemplate + restfulx.BindJsonAndValid(rc, &data) + one := p.ProductTemplateApp.FindOne(data.Id) + if data.Classify == entity.ATTRIBUTES_TSL { + // 删除原来的key + global.TdDb.DelSTableField(data.Pid+"_"+entity.ATTRIBUTES_TSL, one.Key) + // 添加修改完成的key + err := global.TdDb.AddSTableField(data.Pid+"_"+entity.ATTRIBUTES_TSL, data.Key, data.Type, 0) + biz.ErrIsNil(err, "添加字段失败") + } + if data.Classify == entity.TELEMETRY_TSL { + len := 0 + if data.Type == "string" { + len = int(data.Define["length"].(int64)) + } + global.TdDb.DelSTableField(data.Pid+"_"+entity.TELEMETRY_TSL, one.Key) + err := global.TdDb.AddSTableField(data.Pid+"_"+entity.TELEMETRY_TSL, data.Key, data.Type, len) + log.Println(err) + biz.ErrIsNil(err, "添加字段失败") + } + + p.ProductTemplateApp.Update(data) +} + +// DeleteProductTemplate 删除Template +func (p *ProductTemplateApi) DeleteProductTemplate(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + data := p.ProductTemplateApp.FindOne(id) + // 向超级表中添加字段 + if data.Classify == entity.ATTRIBUTES_TSL { + err := global.TdDb.DelSTableField(data.Pid+"_"+entity.ATTRIBUTES_TSL, data.Key) + biz.ErrIsNil(err, "删除字段失败") + } + if data.Classify == entity.TELEMETRY_TSL { + err := global.TdDb.DelSTableField(data.Pid+"_"+entity.TELEMETRY_TSL, data.Key) + biz.ErrIsNil(err, "删除字段失败") + } + ids := strings.Split(id, ",") + p.ProductTemplateApp.Delete(ids) +} diff --git a/apps/device/entity/device.go b/apps/device/entity/device.go new file mode 100644 index 0000000000000000000000000000000000000000..f1099cea559eb7a2bab862e23a2d038aa4e5f866 --- /dev/null +++ b/apps/device/entity/device.go @@ -0,0 +1,63 @@ +package entity + +import ( + "database/sql/driver" + "encoding/json" + "errors" + "pandax/pkg/global" + "time" +) + +// DeviceGroup 设备分组 +type DeviceGroup struct { + global.BaseAuthModel + Name string `json:"name" gorm:"type:varchar(128);comment:设备分组名称" validate:"required"` + Pid string `json:"pid" gorm:"type:varchar(64);comment:设备分组类型"` + Path string `json:"path" gorm:"type:varchar(255);comment:设备分组路径"` + Description string `json:"description" gorm:"type:varchar(255);comment:设备分组说明"` + Sort int64 `json:"sort" gorm:"type:int;comment:排序"` + Status string `gorm:"status;type:varchar(1);comment:状态" json:"status"` + Ext Ext `json:"ext" gorm:"type:json;comment:扩展"` //可扩展的kv map,承载设备组的外围信息 + Children []DeviceGroup `json:"children" gorm:"-"` //子节点 +} + +type DeviceGroupLabel struct { + Id string `gorm:"-" json:"id"` + Name string `gorm:"-" json:"name"` + Children []DeviceGroupLabel `gorm:"-" json:"children"` +} + +type Device struct { + global.BaseAuthModel + Name string `json:"name" gorm:"type:varchar(128);comment:设备名称" validate:"required,alphanum"` // mqtt 用户名英文 + ParentId string `json:"parentId" gorm:"type:varchar(64);comment:父设备"` + DeviceType string `json:"deviceType" gorm:"type:varchar(64);comment:设备类型"` + Token string `json:"token" gorm:"type:varchar(128);comment:设备token"` + Alias string `json:"alias" gorm:"type:varchar(128);comment:设备别名" ` + Pid string `json:"pid" gorm:"comment:产品Id" validate:"required"` + Gid string `json:"gid" gorm:"comment:分组Id" validate:"required"` + Description string `json:"description" gorm:"type:varchar(255);comment:说明"` + Status string `json:"status" gorm:"type:varchar(1);comment:状态"` //0 正常 1禁用 + LinkStatus string `json:"linkStatus" gorm:"type:varchar(10);comment:连接状态"` //inactive未激活 online在线 offline离线 + LastAt time.Time `gorm:"column:last_time;comment:最后一次在线时间" json:"lastTime"` + OtaVersion string `json:"otaVersion" gorm:"type:varchar(64);comment:固件版本" ` //上一次固件升级的版本 + Ext Ext `json:"ext" gorm:"type:json;comment:扩展"` //可扩展的kv map,承载设备组的外围信息 +} +type DeviceRes struct { + Device + DeviceGroup DeviceGroup `json:"deviceGroup" gorm:"foreignKey:Gid;references:Id"` + Product Product `json:"product" gorm:"foreignKey:Pid;references:Id"` +} + +type Ext map[string]interface{} + +func (a Ext) Value() (driver.Value, error) { + return json.Marshal(a) +} +func (a *Ext) Scan(value interface{}) error { + b, ok := value.([]byte) + if !ok { + return errors.New("type assertion to []byte failed") + } + return json.Unmarshal(b, &a) +} diff --git a/apps/device/entity/device_exp.go b/apps/device/entity/device_exp.go new file mode 100644 index 0000000000000000000000000000000000000000..d0a00c9861f7c4c23e32cfbc87ebe9a4d2fb6fac --- /dev/null +++ b/apps/device/entity/device_exp.go @@ -0,0 +1,42 @@ +package entity + +import "time" + +// 说明 +// 设备上报属性,遥测,连接事件存储到时序数据库中 +// 其他存在MySQL中 + +// DeviceAlarm 设备告警表 需要更改告警状态不能存在时序数据库中 +type DeviceAlarm struct { + Id string `json:"id" gorm:"primary_key;"` + Time time.Time `gorm:"comment:告警时间" json:"time"` + Name string `gorm:"type:varchar(64);comment:告警名称" json:"name"` + DeviceId string `gorm:"type:varchar(64);comment:所属设备" json:"deviceId"` + ProductId string `gorm:"type:varchar(64);comment:所属产品" json:"productId"` + Type string `gorm:"type:varchar(64);comment:告警类型" json:"type"` + Level string `gorm:"type:varchar(64);comment:告警级别" json:"level"` // 危险 重要 次要 警告 不确定 + State string `gorm:"type:varchar(1);comment:告警状态" json:"state"` // 告警中 0 已确认 1 已清除 2 已关闭 3 + Details string `gorm:"type:varchar(255);comment:告警详情" json:"details"` +} + +type DeviceCmdLog struct { + Id string `json:"id" gorm:"primary_key;"` + DeviceId string `gorm:"type:varchar(64);comment:所属设备" json:"deviceId"` + CmdName string `gorm:"type:varchar(64);comment:命令名称" json:"cmdName"` + CmdContent string `gorm:"type:longtext;comment:命令内容" json:"cmdContent"` + State string `gorm:"type:varchar(1);comment:命令状态" json:"state"` + Type string `gorm:"type:varchar(1);comment:命令类型" json:"type"` // 0 自定义 1 命令 + ResponseContent string `gorm:"type:longtext;comment:响应内容" json:"responseContent"` + RequestTime string `gorm:"comment:命令下发时间" json:"requestTime"` + ResponseTime string `gorm:"comment:命令响应时间" json:"responseTime"` +} + +func (DeviceCmdLog) TableName() string { + return "device_cmd_log" +} + +// DeviceStatistics 设备统计表 +// 每小时、每天、每周、每月的平均值、最大值、最小值等。可以使用定时任务或实时计算框架来更新数据统计表。 +type DeviceStatistics struct { + Time time.Time `gorm:"comment:时间" json:"time"` +} diff --git a/apps/device/entity/device_vo.go b/apps/device/entity/device_vo.go new file mode 100644 index 0000000000000000000000000000000000000000..4dbbcef30b4e1ea1469d23b7791ac8a7c2c39056 --- /dev/null +++ b/apps/device/entity/device_vo.go @@ -0,0 +1,34 @@ +package entity + +type DeviceStatusVo struct { + Name string `json:"name"` + Key string `json:"key"` + Type string `json:"type"` + Define any `json:"define"` + Value any `json:"value"` + Time any `json:"time"` +} + +type VisualClass struct { + ClassId string `json:"classId"` + Name string `json:"name"` + Attrs []VisualTwinAttr `json:"attrs"` +} + +type VisualTwinAttr struct { + Key string `json:"key"` + Name string `json:"name"` + Type string `json:"type"` + Rw string `json:"rw"` //属性的操作权限 +} + +type VisualTwin struct { + TwinId string `json:"twinId"` + Name string `json:"name"` +} + +// 发送数据 +type VisualTwinSendAttrs struct { + TwinId string `json:"twinId"` + Attrs map[string]interface{} `json:"attrs"` +} diff --git a/apps/device/entity/product.go b/apps/device/entity/product.go new file mode 100644 index 0000000000000000000000000000000000000000..56429f12c0822dd153b003330d359b8342d51d60 --- /dev/null +++ b/apps/device/entity/product.go @@ -0,0 +1,91 @@ +package entity + +import ( + "database/sql/driver" + "encoding/json" + "errors" + "pandax/pkg/global" +) + +const ( + DIRECT_DEVICE = "direct" //直连设备 + GATEWAY_DEVICE = "gateway" //网关设备 + GATEWAYS_DEVICE = "gatewayS" //网关子设备 + MONITOR_DEVICE = "monitor" //监控设备 +) + +const ( + ATTRIBUTES_TSL = "attributes" + TELEMETRY_TSL = "telemetry" + COMMANDS_TSL = "commands" + TAGS_TSL = "tags" +) + +type ProductCategory struct { + global.BaseAuthModel + Name string `json:"name" gorm:"type:varchar(128);comment:产品类型名称" validate:"required"` + Pid string `json:"pid" gorm:"type:varchar(64);comment:父产品类型"` + Path string `json:"path" gorm:"type:varchar(255);comment:产品类型路径"` + Description string `json:"description" gorm:"type:varchar(255);comment:产品类型说明"` + Sort int64 `json:"sort" gorm:"type:int;comment:排序"` + Status string `gorm:"status;type:varchar(1);comment:状态" json:"status"` + Children []ProductCategory `json:"children" gorm:"-"` //子节点 +} + +type ProductCategoryLabel struct { + Id string `gorm:"-" json:"id"` + Name string `gorm:"-" json:"name"` + Children []ProductCategoryLabel `gorm:"-" json:"children"` +} + +type Product struct { + global.BaseAuthModel + Name string `json:"name" gorm:"type:varchar(128);comment:产品名称" validate:"required"` + PhotoUrl string `json:"photoUrl" gorm:"type:varchar(255);comment:图片地址"` + Description string `json:"description" gorm:"type:varchar(255);comment:产品说明"` + ProductCategoryId string `json:"productCategoryId" gorm:"type:varchar(64);comment:产品类型Id" validate:"required"` + ProtocolName string `json:"protocolName" gorm:"type:varchar(64);comment:协议名称"` //MQTT COAP WebSocket LwM2M + DeviceType string `json:"deviceType" gorm:"type:varchar(64);comment:设备类型"` // 直连设备 网关设备 网关子设备 监控设备 + SelfLearn bool `json:"selfLearn" gorm:"default:0;comment:自学习开关"` + RuleChainId string `json:"ruleChainId" gorm:"type:varchar(64);comment:规则链Id"` //可空,如果空就走根规则链 + Status string `gorm:"status;type:varchar(1);comment:状态" json:"status"` +} + +type ProductRes struct { + Product + ProductCategory ProductCategory `json:"productCategory"` +} + +type ProductTemplate struct { + global.BaseModel + Pid string `json:"pid" gorm:"type:varchar(64);comment:产品Id" validate:"required"` + Classify string `json:"classify" gorm:"type:varchar(64);comment:模型归类" validate:"required"` // 属性 遥测 命令 事件 + Name string `json:"name" gorm:"type:varchar(64);comment:名称" validate:"required"` + Key string `json:"key" gorm:"type:varchar(64);comment:标识" validate:"required"` + Description string `json:"description" gorm:"type:varchar(255);comment:属性说明"` + Type string `json:"type" gorm:"type:varchar(64);comment:数据类型"` //["int32","float","double","array","bool","enum","date","struct","string"] + Define Define `json:"define" gorm:"type:json;comment:数据约束"` +} + +type ProductOta struct { + global.BaseModel + Pid string `json:"pid" gorm:"comment:产品Id" validate:"required"` + Name string `json:"name" gorm:"type:varchar(64);comment:固件名称" validate:"required"` + Version string `json:"version" gorm:"type:varchar(64);comment:固件版本" validate:"required"` + IsLatest bool `json:"isLatest" gorm:"comment:是最新固件"` + Url string `json:"url" gorm:"type:varchar(128);comment:下载地址" validate:"required"` + Description string `json:"description" gorm:"type:varchar(255);comment:说明"` +} + +type Define map[string]interface{} + +func (a Define) Value() (driver.Value, error) { + return json.Marshal(a) +} +func (a *Define) Scan(value interface{}) error { + b, ok := value.([]byte) + if !ok { + return errors.New("type assertion to []byte failed") + } + return json.Unmarshal(b, &a) +} diff --git a/apps/device/router/device.go b/apps/device/router/device.go new file mode 100644 index 0000000000000000000000000000000000000000..8b24c906dc64fa7f133809763b13fbfdf52ef29a --- /dev/null +++ b/apps/device/router/device.go @@ -0,0 +1,113 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitDeviceRouter(container *restful.Container) { + s := &api.DeviceApi{ + DeviceApp: services.DeviceModelDao, + ProductApp: services.ProductModelDao, + ProductTemplateApp: services.ProductTemplateModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device").Produces(restful.MIME_JSON) + tags := []string{"device"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Device分页列表").Handle(s.GetDeviceList) + }). + Doc("获取Device分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("pid", "产品ID").Required(false).DataType("string")). + Param(ws.QueryParameter("gid", "分组Id").Required(false).DataType("string")). + Param(ws.QueryParameter("deviceType", "设备类型").Required(false).DataType("string")). + Param(ws.QueryParameter("parentId", "父ID").Required(false).DataType("string")). + Param(ws.QueryParameter("linkStatus", "连接状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/list/all").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Device列表").Handle(s.GetDeviceListAll) + }). + Doc("获取Device列表"). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("pid", "产品ID").Required(false).DataType("string")). + Param(ws.QueryParameter("deviceType", "设备类型").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes([]entity.Device{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Device信息").Handle(s.GetDevice) + }). + Doc("获取Device信息"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.Device{}). // on the response + Returns(200, "OK", entity.Device{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.GET("/{id}/status").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Device状态信息").Handle(s.GetDeviceStatus) + }). + Doc("获取Device状态信息"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Param(ws.QueryParameter("classify", "分类").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes([]entity.DeviceStatusVo{}). // on the response + Returns(200, "OK", []entity.DeviceStatusVo{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.GET("/{id}/attribute/down").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Device属性下发").Handle(s.DownAttribute) + }). + Doc("获取Device属性下发"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Param(ws.QueryParameter("key", "属性KEY").Required(false).DataType("string")). + Param(ws.QueryParameter("value", "属性Value").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加Device信息").Handle(s.InsertDevice) + }). + Doc("添加Device信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.Device{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改Device信息").Handle(s.UpdateDevice) + }). + Doc("修改Device信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.Device{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除Device信息").Handle(s.DeleteDevice) + }). + Doc("删除Device信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + ws.Route(ws.GET("/twin").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Device孪生体").Handle(s.ScreenTwinData) + }). + Doc("获取Device孪生体"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes([]entity.VisualClass{}). // on the response + Returns(200, "OK", []entity.VisualClass{})) + + container.Add(ws) +} diff --git a/apps/device/router/device_alarm.go b/apps/device/router/device_alarm.go new file mode 100644 index 0000000000000000000000000000000000000000..a1de1110482ce4893012ddbd9a638d4308642701 --- /dev/null +++ b/apps/device/router/device_alarm.go @@ -0,0 +1,52 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitDeviceAlarmRouter(container *restful.Container) { + s := &api.DeviceAlarmApi{ + DeviceAlarmApp: services.DeviceAlarmModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/alarm").Produces(restful.MIME_JSON) + tags := []string{"alarm"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取告警分页列表").Handle(s.GetDeviceAlarmList) + }). + Doc("获取告警分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("deviceId", "设备Id").Required(false).DataType("string")). + Param(ws.QueryParameter("type", "告警类型").Required(false).DataType("string")). + Param(ws.QueryParameter("level", "告警等级").Required(false).DataType("string")). + Param(ws.QueryParameter("state", "告警状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改告警信息").Handle(s.UpdateDeviceAlarm) + }). + Doc("修改告警信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.DeviceAlarm{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除告警信息").Handle(s.DeleteDeviceAlarm) + }). + Doc("删除告警信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/router/device_cmd.go b/apps/device/router/device_cmd.go new file mode 100644 index 0000000000000000000000000000000000000000..dcc292bc84c81e6af5a6c64227e5a1caba0da22b --- /dev/null +++ b/apps/device/router/device_cmd.go @@ -0,0 +1,51 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitDeviceCmdLogRouter(container *restful.Container) { + s := &api.DeviceCmdLogApi{ + DeviceCmdLogApp: services.DeviceCmdLogModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/cmd").Produces(restful.MIME_JSON) + tags := []string{"cmd"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取命令下发分页列表").Handle(s.GetDeviceCmdLogList) + }). + Doc("获取命令下发分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("deviceId", "设备Id").Required(false).DataType("string")). + Param(ws.QueryParameter("type", "命令下发分类").Required(false).DataType("string")). + Param(ws.QueryParameter("state", "命令下发状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("命令下发").Handle(s.InsertDeviceCmdLog) + }). + Doc("命令下发"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.DeviceCmdLog{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除命令下发信息").Handle(s.DeleteDeviceCmdLog) + }). + Doc("删除命令下发信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/router/device_group.go b/apps/device/router/device_group.go new file mode 100644 index 0000000000000000000000000000000000000000..b65bad298d7e6d30a42cdfba8a8923aee15c3e48 --- /dev/null +++ b/apps/device/router/device_group.go @@ -0,0 +1,85 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/restfulx" + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +func InitDeviceGroupRouter(container *restful.Container) { + s := &api.DeviceGroupApi{ + DeviceGroupApp: services.DeviceGroupModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/group").Produces(restful.MIME_JSON) + tags := []string{"DeviceGroup"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取DeviceGroup列表").Handle(s.GetDeviceGroupList) + }). + Doc("获取DeviceGroup列表"). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.DeviceGroup{})) + + ws.Route(ws.GET("/list/all").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取DeviceGroup所有列表").Handle(s.GetDeviceGroupAllList) + }). + Doc("获取DeviceGroup分页列表"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.DeviceGroup{})) + + ws.Route(ws.GET("/list/tree").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取DeviceGroup树").Handle(s.GetDeviceGroupTree) + }). + Doc("获取DeviceGroup树"). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.DeviceGroup{})) + + ws.Route(ws.GET("/list/tree/label").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取DeviceGroup树").Handle(s.GetDeviceGroupTreeLabel) + }). + Doc("获取DeviceGroup树"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.DeviceGroupLabel{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取DeviceGroup信息").Handle(s.GetDeviceGroup) + }). + Doc("获取DeviceGroup信息"). + Param(ws.PathParameter("", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.DeviceGroup{}). // on the response + Returns(200, "OK", entity.DeviceGroup{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加DeviceGroup信息").Handle(s.InsertDeviceGroup) + }). + Doc("添加DeviceGroup信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.DeviceGroup{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改DeviceGroup信息").Handle(s.UpdateDeviceGroup) + }). + Doc("修改DeviceGroup信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.DeviceGroup{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除DeviceGroup信息").Handle(s.DeleteDeviceGroup) + }). + Doc("删除DeviceGroup信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/router/product.go b/apps/device/router/product.go new file mode 100644 index 0000000000000000000000000000000000000000..5dd22b9e733c9d8a1c2e935708dcc4276acda208 --- /dev/null +++ b/apps/device/router/product.go @@ -0,0 +1,86 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitProductRouter(container *restful.Container) { + s := &api.ProductApi{ + ProductApp: services.ProductModelDao, + DeviceApp: services.DeviceModelDao, + TemplateApp: services.ProductTemplateModelDao, + OtaAPP: services.ProductOtaModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/product").Produces(restful.MIME_JSON) + tags := []string{"product"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Product分页列表").Handle(s.GetProductList) + }). + Doc("获取Product分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("productCategoryId", "产品分类Id").Required(false).DataType("string")). + Param(ws.QueryParameter("protocolName", "协议名").Required(false).DataType("string")). + Param(ws.QueryParameter("deviceType", "设备类型").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/list/all").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Product分页列表").Handle(s.GetProductListAll) + }). + Doc("获取Product分页列表"). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("productCategoryId", "产品分类Id").Required(false).DataType("string")). + Param(ws.QueryParameter("protocolName", "协议名").Required(false).DataType("string")). + Param(ws.QueryParameter("deviceType", "设备类型").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.Product{}). + Returns(200, "OK", entity.Product{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Product信息").Handle(s.GetProduct) + }). + Doc("获取Product信息"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.Product{}). // on the response + Returns(200, "OK", entity.Product{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加Product信息").Handle(s.InsertProduct) + }). + Doc("添加Product信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.Product{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改Product信息").Handle(s.UpdateProduct) + }). + Doc("修改Product信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.Product{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除Product信息").Handle(s.DeleteProduct) + }). + Doc("删除Product信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/router/product_category.go b/apps/device/router/product_category.go new file mode 100644 index 0000000000000000000000000000000000000000..15ac48d4b19eb3e9c8cd0fb6d3d8051fb6da2cad --- /dev/null +++ b/apps/device/router/product_category.go @@ -0,0 +1,85 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/restfulx" + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" +) + +func InitProductCategoryRouter(container *restful.Container) { + s := &api.ProductCategoryApi{ + ProductCategoryApp: services.ProductCategoryModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/product/category").Produces(restful.MIME_JSON) + tags := []string{"ProductCategory"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取ProductCategory列表").Handle(s.GetProductCategoryList) + }). + Doc("获取ProductCategory列表"). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.ProductCategory{})) + + ws.Route(ws.GET("/list/all").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取ProductCategory所有列表").Handle(s.GetProductCategoryAllList) + }). + Doc("获取ProductCategory分页列表"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.ProductCategory{})) + + ws.Route(ws.GET("/list/tree").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取ProductCategory树").Handle(s.GetProductCategoryTree) + }). + Doc("获取ProductCategory树"). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Param(ws.QueryParameter("status", "状态").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.ProductCategory{})) + + ws.Route(ws.GET("/list/tree/label").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取ProductCategory树").Handle(s.GetProductCategoryTreeLabel) + }). + Doc("获取ProductCategory树"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.ProductCategoryLabel{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取ProductCategory信息").Handle(s.GetProductCategory) + }). + Doc("获取ProductCategory信息"). + Param(ws.PathParameter("", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.ProductCategory{}). // on the response + Returns(200, "OK", entity.ProductCategory{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加ProductCategory信息").Handle(s.InsertProductCategory) + }). + Doc("添加ProductCategory信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.ProductCategory{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改ProductCategory信息").Handle(s.UpdateProductCategory) + }). + Doc("修改ProductCategory信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.ProductCategory{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除ProductCategory信息").Handle(s.DeleteProductCategory) + }). + Doc("删除ProductCategory信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/router/product_ota.go b/apps/device/router/product_ota.go new file mode 100644 index 0000000000000000000000000000000000000000..24663a54a13dd6cb4fc61746be7159edce11e1b6 --- /dev/null +++ b/apps/device/router/product_ota.go @@ -0,0 +1,67 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitProductOtaRouter(container *restful.Container) { + s := &api.ProductOtaApi{ + ProductOtaApp: services.ProductOtaModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/ota").Produces(restful.MIME_JSON) + tags := []string{"ota"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Ota分页列表").Handle(s.GetProductOtaList) + }). + Doc("获取Ota分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("pid", "产品Id").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Ota信息").Handle(s.GetProductOta) + }). + Doc("获取Ota信息"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.ProductOta{}). // on the response + Returns(200, "OK", entity.ProductOta{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加Ota信息").Handle(s.InsertProductOta) + }). + Doc("添加Ota信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.ProductOta{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改Ota信息").Handle(s.UpdateProductOta) + }). + Doc("修改Ota信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.ProductOta{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除Ota信息").Handle(s.DeleteProductOta) + }). + Doc("删除Ota信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/router/product_template.go b/apps/device/router/product_template.go new file mode 100644 index 0000000000000000000000000000000000000000..4c0ac9cf46093eb07f2b97c3b261e52d15461efe --- /dev/null +++ b/apps/device/router/product_template.go @@ -0,0 +1,78 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/device/api" + "pandax/apps/device/entity" + "pandax/apps/device/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitProductTemplateRouter(container *restful.Container) { + s := &api.ProductTemplateApi{ + ProductTemplateApp: services.ProductTemplateModelDao, + } + + ws := new(restful.WebService) + ws.Path("/device/template").Produces(restful.MIME_JSON) + tags := []string{"template"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Template分页列表").Handle(s.GetProductTemplateList) + }). + Doc("获取Template分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("pid", "产品ID").Required(false).DataType("string")). + Param(ws.QueryParameter("classify", "分类").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/list/all").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Template列表").Handle(s.GetProductTemplateListAll) + }). + Doc("获取Template列表"). + Param(ws.QueryParameter("pid", "产品ID").Required(false).DataType("string")). + Param(ws.QueryParameter("classify", "分类").Required(false).DataType("string")). + Param(ws.QueryParameter("name", "名称").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", []entity.ProductTemplate{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取Template信息").Handle(s.GetProductTemplate) + }). + Doc("获取Template信息"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.ProductTemplate{}). // on the response + Returns(200, "OK", entity.ProductTemplate{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加Template信息").Handle(s.InsertProductTemplate) + }). + Doc("添加Template信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.ProductTemplate{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改Template信息").Handle(s.UpdateProductTemplate) + }). + Doc("修改Template信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.ProductTemplate{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除Template信息").Handle(s.DeleteProductTemplate) + }). + Doc("删除Template信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/device/services/device.go b/apps/device/services/device.go new file mode 100644 index 0000000000000000000000000000000000000000..adfcd064157446e44698b0b9940c5f56aab7f3a1 --- /dev/null +++ b/apps/device/services/device.go @@ -0,0 +1,169 @@ +package services + +import ( + "context" + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/device/entity" + "pandax/pkg/global" + "pandax/pkg/tool" + "time" +) + +type ( + DeviceModel interface { + Insert(data entity.Device) *entity.Device + FindOne(id string) *entity.DeviceRes + FindListPage(page, pageSize int, data entity.Device) (*[]entity.DeviceRes, int64) + FindList(data entity.Device) *[]entity.DeviceRes + Update(data entity.Device) *entity.Device + UpdateStatus(id, linkStatus string) + Delete(ids []string) + } + + deviceModelImpl struct { + table string + } +) + +var DeviceModelDao DeviceModel = &deviceModelImpl{ + table: `devices`, +} + +func (m *deviceModelImpl) Insert(data entity.Device) *entity.Device { + //1 检查设备名称是否存在 + list := m.FindList(entity.Device{Name: data.Name}) + biz.IsTrue(list != nil && len(*list) == 0, "设备名称已经存在") + //2 创建认证TOKEN IOTHUB使用 + etoken := getDeviceToken(&data) + if data.DeviceType != global.GATEWAYS && data.DeviceType != global.MONITOR { + data.Token = etoken.Token + } + //3 添加设备 + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加设备失败") + return &data +} + +func getDeviceToken(data *entity.Device) *tool.DeviceAuth { + now := time.Now() + etoken := &tool.DeviceAuth{ + DeviceId: data.Id, + User: data.Owner, + Name: data.Name, + DeviceType: data.DeviceType, + ProductId: data.Pid, + } + //设备有效期360天 + etoken.CreatedAt = now.Unix() + etoken.ExpiredAt = now.Add(time.Hour * 24 * 365).Unix() + if data.Token == "" { + etoken.Token = etoken.MD5ID() + } else { + etoken.Token = data.Token + } + biz.ErrIsNil(global.RedisDb.Set(data.Id, etoken.GetMarshal(), time.Hour*24*365), "Redis 存储失败") + return etoken +} + +func (m *deviceModelImpl) FindOne(id string) *entity.DeviceRes { + resData := new(entity.DeviceRes) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Preload("Product").Preload("DeviceGroup").Error + biz.ErrIsNil(err, "查询设备失败") + return resData +} + +func (m *deviceModelImpl) FindListPage(page, pageSize int, data entity.Device) (*[]entity.DeviceRes, int64) { + list := make([]entity.DeviceRes, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Alias != "" { + db = db.Where("alias = ?", data.Alias) + } + if data.Gid != "" { + db = db.Where("gid = ?", data.Gid) + } + if data.OrgId != "" { + db = db.Where("org_id = ?", data.OrgId) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + if data.LinkStatus != "" { + db = db.Where("Link_status = ?", data.LinkStatus) + } + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + if data.ParentId != "" { + db = db.Where("parent_id = ?", data.ParentId) + } + err := db.Count(&total).Error + err = db.Order("create_time").Preload("Product").Preload("DeviceGroup").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询设备分页列表失败") + return &list, total +} + +func (m *deviceModelImpl) FindList(data entity.Device) *[]entity.DeviceRes { + list := make([]entity.DeviceRes, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Alias != "" { + db = db.Where("alias = ?", data.Alias) + } + if data.Gid != "" { + db = db.Where("gid = ?", data.Gid) + } + if data.OrgId != "" { + db = db.Where("org_id = ?", data.OrgId) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.DeviceType != "" { + db = db.Where("device_type = ?", data.DeviceType) + } + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + if data.LinkStatus != "" { + db = db.Where("Link_status = ?", data.LinkStatus) + } + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + if data.ParentId != "" { + db = db.Where("parent_id = ?", data.ParentId) + } + db.Preload("Product").Preload("DeviceGroup") + biz.ErrIsNil(db.Order("create_time").Find(&list).Error, "查询设备列表失败") + return &list +} + +func (m *deviceModelImpl) Update(data entity.Device) *entity.Device { + getDeviceToken(&data) + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改设备失败") + return &data +} +func (m *deviceModelImpl) UpdateStatus(id, linkStatus string) { + global.Db.Table(m.table).Where("id", id).Update("link_status", linkStatus).Update("last_time", time.Now()) +} + +func (m *deviceModelImpl) Delete(ids []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.Device{}, "id in (?)", ids).Error, "删除设备失败") + for _, id := range ids { + // 删除所有缓存 + global.RedisDb.Del(context.Background(), id) + } +} diff --git a/apps/device/services/device_alarm.go b/apps/device/services/device_alarm.go new file mode 100644 index 0000000000000000000000000000000000000000..0b2428d51d2de905b6456821c1e66a2a99f1a6a4 --- /dev/null +++ b/apps/device/services/device_alarm.go @@ -0,0 +1,85 @@ +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/device/entity" + "pandax/pkg/global" +) + +type ( + DeviceAlarmModel interface { + Insert(data entity.DeviceAlarm) error + FindOne(id string) *entity.DeviceAlarm + FindOneByType(deviceId, ty, state string) *entity.DeviceAlarm + FindListPage(page, pageSize int, data entity.DeviceAlarm) (*[]entity.DeviceAlarm, int64) + Update(data entity.DeviceAlarm) error + Delete(ids []string) + } + + alarmModelImpl struct { + table string + } +) + +var DeviceAlarmModelDao DeviceAlarmModel = &alarmModelImpl{ + table: `device_alarms`, +} + +func (m *alarmModelImpl) Insert(data entity.DeviceAlarm) error { + err := global.Db.Table(m.table).Create(&data).Error + return err +} + +func (m *alarmModelImpl) FindOne(id string) *entity.DeviceAlarm { + resData := new(entity.DeviceAlarm) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询设备告警失败") + return resData +} + +func (m *alarmModelImpl) FindOneByType(deviceId, ty, state string) *entity.DeviceAlarm { + resData := new(entity.DeviceAlarm) + db := global.Db.Table(m.table).Where("device_id = ?", deviceId).Where("type = ? ", ty).Where("state = ? ", state) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询设备告警失败") + return resData +} + +func (m *alarmModelImpl) FindListPage(page, pageSize int, data entity.DeviceAlarm) (*[]entity.DeviceAlarm, int64) { + list := make([]entity.DeviceAlarm, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + if data.DeviceId != "" { + db = db.Where("device_id = ?", data.DeviceId) + } + if data.ProductId != "" { + db = db.Where("product_id = ?", data.ProductId) + } + if data.Level != "" { + db = db.Where("level = ?", data.Level) + } + if data.Type != "" { + db = db.Where("type like ?", "%"+data.Type+"%") + } + if data.State != "" { + db = db.Where("state = ?", data.State) + } + err := db.Count(&total).Error + err = db.Order("time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询设备告警分页列表失败") + return &list, total +} + +func (m *alarmModelImpl) Update(data entity.DeviceAlarm) error { + err := global.Db.Table(m.table). + Where("type = ?", data.Type). + Where("device_id = ?", data.DeviceId). + Updates(&data).Error + return err +} + +func (m *alarmModelImpl) Delete(id []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.DeviceAlarm{}, "id in (?)", id).Error, "删除设备告警失败") +} diff --git a/apps/device/services/device_cmd_log.go b/apps/device/services/device_cmd_log.go new file mode 100644 index 0000000000000000000000000000000000000000..674a4c351e1047091aa773cde0948944c2b1d954 --- /dev/null +++ b/apps/device/services/device_cmd_log.go @@ -0,0 +1,83 @@ +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/device/entity" + "pandax/pkg/global" + "time" +) + +type ( + DeviceCmdLogModel interface { + Insert(data entity.DeviceCmdLog) error + FindOne(id string) *entity.DeviceCmdLog + FindListPage(page, pageSize int, data entity.DeviceCmdLog) (*[]entity.DeviceCmdLog, int64) + Update(data entity.DeviceCmdLog) error + UpdateResp(id, responseContent, responseTime string) error + Delete(ids []string) + } + + cmdLogModelImpl struct { + table string + } +) + +var DeviceCmdLogModelDao DeviceCmdLogModel = &cmdLogModelImpl{ + table: `device_cmd_log`, +} + +func (m *cmdLogModelImpl) Insert(data entity.DeviceCmdLog) error { + err := global.Db.Table(m.table).Create(&data).Error + return err +} + +func (m *cmdLogModelImpl) FindOne(id string) *entity.DeviceCmdLog { + resData := new(entity.DeviceCmdLog) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询设备指令下发失败") + return resData +} + +func (m *cmdLogModelImpl) FindListPage(page, pageSize int, data entity.DeviceCmdLog) (*[]entity.DeviceCmdLog, int64) { + list := make([]entity.DeviceCmdLog, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + if data.DeviceId != "" { + db = db.Where("device_id = ?", data.DeviceId) + } + if data.CmdName != "" { + db = db.Where("cmd_name like ?", "%"+data.CmdName+"%") + } + if data.Type != "" { + db = db.Where("type = ?", data.Type) + } + if data.State != "" { + db = db.Where("state = ?", data.State) + } + err := db.Count(&total).Error + err = db.Order("request_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询设备指令下发分页列表失败") + return &list, total +} + +func (m *cmdLogModelImpl) Update(data entity.DeviceCmdLog) error { + err := global.Db.Table(m.table). + Where("id = ?", data.Id). + Updates(&data).Error + return err +} + +func (m *cmdLogModelImpl) UpdateResp(id, responseContent, state string) error { + responseTime := time.Now().Format("2006-01-02 15:04:05") + err := global.Db.Table(m.table). + Where("id = ?", id). + Update("response_content", responseContent). + Update("response_time", responseTime).Update("state", state).Error + return err +} + +func (m *cmdLogModelImpl) Delete(id []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.DeviceCmdLog{}, "id in (?)", id).Error, "删除设备指令下发失败") +} diff --git a/apps/device/services/device_group.go b/apps/device/services/device_group.go new file mode 100644 index 0000000000000000000000000000000000000000..86663083e0a8e6a79e9957e762b6045d13443e8d --- /dev/null +++ b/apps/device/services/device_group.go @@ -0,0 +1,188 @@ +package services + +import ( + "errors" + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/device/entity" + "pandax/pkg/global" +) + +type ( + DeviceGroupModel interface { + Insert(data entity.DeviceGroup) *entity.DeviceGroup + FindOne(id string) *entity.DeviceGroup + FindListPage(page, pageSize int, data entity.DeviceGroup) (*[]entity.DeviceGroup, int64) + FindList(data entity.DeviceGroup) *[]entity.DeviceGroup + Update(data entity.DeviceGroup) *entity.DeviceGroup + Delete(ids []string) + SelectDeviceGroup(data entity.DeviceGroup) []entity.DeviceGroup + SelectDeviceGroupLabel(data entity.DeviceGroup) []entity.DeviceGroupLabel + } + + deviceGroupModelImpl struct { + table string + } +) + +var DeviceGroupModelDao DeviceGroupModel = &deviceGroupModelImpl{ + table: `device_groups`, +} + +func (m *deviceGroupModelImpl) Insert(data entity.DeviceGroup) *entity.DeviceGroup { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加设备分组失败") + + path := "/" + data.Id + if data.Pid != "0" { + vsg := m.FindOne(data.Pid) + path = vsg.Path + path + } else { + path = "/0" + path + } + data.Path = path + biz.ErrIsNil(global.Db.Table(m.table).Model(&data).Updates(&data).Error, "修改设备分组信息失败") + return &data +} + +func (m *deviceGroupModelImpl) FindOne(id string) *entity.DeviceGroup { + resData := new(entity.DeviceGroup) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询设备分组失败") + return resData +} + +func (m *deviceGroupModelImpl) FindListPage(page, pageSize int, data entity.DeviceGroup) (*[]entity.DeviceGroup, int64) { + list := make([]entity.DeviceGroup, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Path != "" { + db = db.Where("path like %?%", "%"+data.Path+"%") + } + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + err := db.Count(&total).Error + err = db.Order("sort").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询设备分组分页列表失败") + return &list, total +} + +func (m *deviceGroupModelImpl) FindList(data entity.DeviceGroup) *[]entity.DeviceGroup { + list := make([]entity.DeviceGroup, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Path != "" { + db = db.Where("path like %?%", "%"+data.Path+"%") + } + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + biz.ErrIsNil(db.Order("sort").Find(&list).Error, "查询设备分组列表失败") + return &list +} + +func (m *deviceGroupModelImpl) Update(data entity.DeviceGroup) *entity.DeviceGroup { + one := m.FindOne(data.Id) + + path := "/" + data.Id + if data.Pid != "0" { + vsg := m.FindOne(data.Pid) + path = vsg.Path + path + } else { + path = "/0" + path + } + data.Path = path + + if data.Path != "" && data.Path != one.Path { + biz.ErrIsNil(errors.New("上级分组不允许修改!"), "上级分组不允许修改") + } + + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改设备分组失败") + return &data +} + +func (m *deviceGroupModelImpl) Delete(s []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.DeviceGroup{}, "id in (?)", s).Error, "删除设备分组失败") +} + +func (m *deviceGroupModelImpl) SelectDeviceGroup(data entity.DeviceGroup) []entity.DeviceGroup { + list := m.FindList(data) + sd := make([]entity.DeviceGroup, 0) + li := *list + for i := 0; i < len(li); i++ { + if li[i].Pid != "0" { + continue + } + info := DiGuiDeviceGroup(list, li[i]) + sd = append(sd, info) + } + return sd +} + +func (m *deviceGroupModelImpl) SelectDeviceGroupLabel(data entity.DeviceGroup) []entity.DeviceGroupLabel { + deptlist := m.FindList(data) + + dl := make([]entity.DeviceGroupLabel, 0) + deptl := *deptlist + for i := 0; i < len(deptl); i++ { + if deptl[i].Pid != "0" { + continue + } + e := entity.DeviceGroupLabel{} + e.Id = deptl[i].Id + e.Name = deptl[i].Name + deptsInfo := DiGuiDeviceGroupLabel(deptlist, e) + + dl = append(dl, deptsInfo) + } + return dl +} + +func DiGuiDeviceGroup(sglist *[]entity.DeviceGroup, menu entity.DeviceGroup) entity.DeviceGroup { + list := *sglist + + min := make([]entity.DeviceGroup, 0) + for j := 0; j < len(list); j++ { + + if menu.Id != list[j].Pid { + continue + } + mi := entity.DeviceGroup{} + mi.Id = list[j].Id + mi.Pid = list[j].Pid + mi.Path = list[j].Path + mi.Name = list[j].Name + mi.Sort = list[j].Sort + mi.Status = list[j].Status + mi.Description = list[j].Description + ms := DiGuiDeviceGroup(sglist, mi) + min = append(min, ms) + } + menu.Children = min + return menu +} +func DiGuiDeviceGroupLabel(sglist *[]entity.DeviceGroup, dept entity.DeviceGroupLabel) entity.DeviceGroupLabel { + list := *sglist + + min := make([]entity.DeviceGroupLabel, 0) + for j := 0; j < len(list); j++ { + if dept.Id != list[j].Pid { + continue + } + sg := entity.DeviceGroupLabel{list[j].Id, list[j].Name, []entity.DeviceGroupLabel{}} + ms := DiGuiDeviceGroupLabel(sglist, sg) + min = append(min, ms) + + } + dept.Children = min + return dept +} diff --git a/apps/device/services/product.go b/apps/device/services/product.go new file mode 100644 index 0000000000000000000000000000000000000000..289a0b1d1a2121f7a5dc5c65eb0a2dfdda7880f6 --- /dev/null +++ b/apps/device/services/product.go @@ -0,0 +1,152 @@ +package services + +import ( + "context" + "github.com/XM-GO/PandaKit/biz" + "log" + "pandax/apps/device/entity" + ruleEntity "pandax/apps/rule/entity" + ruleService "pandax/apps/rule/services" + "pandax/pkg/global" + "time" +) + +type ( + ProductModel interface { + Insert(data entity.Product) *entity.Product + FindOne(id string) *entity.ProductRes + FindListPage(page, pageSize int, data entity.Product) (*[]entity.ProductRes, int64) + FindList(data entity.Product) *[]entity.ProductRes + Update(data entity.Product) *entity.Product + Delete(ids []string) + } + + productModelImpl struct { + table string + } +) + +var ProductModelDao ProductModel = &productModelImpl{ + table: `products`, +} + +func (m *productModelImpl) Insert(data entity.Product) *entity.Product { + // 添加产品及规则链到redis中 + if data.DeviceType != global.MONITOR { + setProductRule(&data) + } + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加产品失败") + return &data +} + +// 向redis中添加产品对应的规则链 +func setProductRule(data *entity.Product) { + var rule *ruleEntity.RuleChain + if data.RuleChainId == "" { + rule = ruleService.RuleChainModelDao.FindOneByRoot() + } else { + rule = ruleService.RuleChainModelDao.FindOne(data.RuleChainId) + } + data.RuleChainId = rule.Id + biz.ErrIsNil(global.RedisDb.Set(data.Id, rule.RuleDataJson, time.Hour*24*365), "Redis 存储失败") +} + +func (m *productModelImpl) FindOne(id string) *entity.ProductRes { + resData := new(entity.ProductRes) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.Preload("ProductCategory").First(resData).Error + biz.ErrIsNil(err, "查询产品失败") + return resData +} + +func (m *productModelImpl) FindListPage(page, pageSize int, data entity.Product) (*[]entity.ProductRes, int64) { + list := make([]entity.ProductRes, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + if data.DeviceType != "" { + db = db.Where("device_type = ?", data.DeviceType) + } + if data.Id != "" { + db = db.Where("id = ?", data.Id) + } + if data.ProductCategoryId != "" { + db = db.Where("product_category_id = ?", data.ProductCategoryId) + } + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.ProtocolName != "" { + db = db.Where("protocol_name like ?", "%"+data.ProtocolName+"%") + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.OrgId != "" { + db = db.Where("org_id = ?", data.OrgId) + } + if data.RuleChainId != "" { + db = db.Where("rule_chain_id = ?", data.RuleChainId) + } + err := db.Count(&total).Error + err = db.Order("create_time").Preload("ProductCategory").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询产品分页列表失败") + return &list, total +} + +func (m *productModelImpl) FindList(data entity.Product) *[]entity.ProductRes { + list := make([]entity.ProductRes, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + if data.DeviceType != "" { + db = db.Where("device_type = ?", data.DeviceType) + } + if data.Id != "" { + db = db.Where("id = ?", data.Id) + } + if data.ProductCategoryId != "" { + db = db.Where("product_category_id = ?", data.ProductCategoryId) + } + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.ProtocolName != "" { + db = db.Where("protocol_name like ?", "%"+data.ProtocolName+"%") + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.OrgId != "" { + db = db.Where("org_id = ?", data.OrgId) + } + if data.RuleChainId != "" { + db = db.Where("rule_chain_id = ?", data.RuleChainId) + } + biz.ErrIsNil(db.Order("create_time").Preload("ProductCategory").Find(&list).Error, "查询产品列表失败") + return &list +} + +func (m *productModelImpl) Update(data entity.Product) *entity.Product { + setProductRule(&data) + // go的一些默认值 int 0 bool false 保存失败需要先转成map + err := global.Db.Table(m.table).Where("id = ?", data.Id).Updates(data).Error + log.Println("update", err) + //biz.ErrIsNil(, "修改产品失败") + return &data +} + +func (m *productModelImpl) Delete(ids []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.Product{}, "id in (?)", ids).Error, "删除产品失败") + for _, id := range ids { + // 删除所有缓存 + global.RedisDb.Del(context.Background(), id) + } +} diff --git a/apps/device/services/product_category.go b/apps/device/services/product_category.go new file mode 100644 index 0000000000000000000000000000000000000000..2aa5af8aa1980318e393c8a435f796bfb7adb91a --- /dev/null +++ b/apps/device/services/product_category.go @@ -0,0 +1,190 @@ +package services + +import ( + "errors" + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/device/entity" + "pandax/pkg/global" +) + +type ( + ProductCategoryModel interface { + Insert(data entity.ProductCategory) *entity.ProductCategory + FindOne(id string) *entity.ProductCategory + FindListPage(page, pageSize int, data entity.ProductCategory) (*[]entity.ProductCategory, int64) + FindList(data entity.ProductCategory) *[]entity.ProductCategory + Update(data entity.ProductCategory) *entity.ProductCategory + Delete(ids []string) + SelectProductCategory(data entity.ProductCategory) []entity.ProductCategory + SelectProductCategoryLabel(data entity.ProductCategory) []entity.ProductCategoryLabel + } + + productCategoryModelImpl struct { + table string + } +) + +var ProductCategoryModelDao ProductCategoryModel = &productCategoryModelImpl{ + table: `product_categories`, +} + +func (m *productCategoryModelImpl) Insert(data entity.ProductCategory) *entity.ProductCategory { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加产品分组失败") + + path := "/" + data.Id + if data.Pid != "0" { + vsg := m.FindOne(data.Pid) + path = vsg.Path + path + } else { + path = "/0" + path + } + data.Path = path + biz.ErrIsNil(global.Db.Table(m.table).Model(&data).Updates(&data).Error, "修改产品分组信息失败") + return &data +} + +func (m *productCategoryModelImpl) FindOne(id string) *entity.ProductCategory { + resData := new(entity.ProductCategory) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询产品分组失败") + return resData +} + +func (m *productCategoryModelImpl) FindListPage(page, pageSize int, data entity.ProductCategory) (*[]entity.ProductCategory, int64) { + list := make([]entity.ProductCategory, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Path != "" { + db = db.Where("path like %?%", "%"+data.Path+"%") + } + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + err := db.Count(&total).Error + err = db.Order("sort").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询产品分组分页列表失败") + return &list, total +} + +func (m *productCategoryModelImpl) FindList(data entity.ProductCategory) *[]entity.ProductCategory { + list := make([]entity.ProductCategory, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Path != "" { + db = db.Where("path like %?%", "%"+data.Path+"%") + } + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + biz.ErrIsNil(db.Order("sort").Find(&list).Error, "查询产品分组列表失败") + return &list +} + +func (m *productCategoryModelImpl) Update(data entity.ProductCategory) *entity.ProductCategory { + one := m.FindOne(data.Id) + + path := "/" + data.Id + if data.Pid != "0" { + vsg := m.FindOne(data.Pid) + path = vsg.Path + path + } else { + path = "/0" + path + } + data.Path = path + + if data.Path != "" && data.Path != one.Path { + biz.ErrIsNil(errors.New("上级分组不允许修改!"), "上级分组不允许修改") + } + + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改产品分组失败") + return &data +} + +func (m *productCategoryModelImpl) Delete(s []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.ProductCategory{}, "id in (?)", s).Error, "删除产品分组失败") +} + +func (m *productCategoryModelImpl) SelectProductCategory(data entity.ProductCategory) []entity.ProductCategory { + list := m.FindList(data) + sd := make([]entity.ProductCategory, 0) + li := *list + for i := 0; i < len(li); i++ { + if li[i].Pid != "0" { + continue + } + info := DiGuiProductCategory(list, li[i]) + sd = append(sd, info) + } + return sd +} + +func (m *productCategoryModelImpl) SelectProductCategoryLabel(data entity.ProductCategory) []entity.ProductCategoryLabel { + list := m.FindList(data) + + dl := make([]entity.ProductCategoryLabel, 0) + deptl := *list + for i := 0; i < len(deptl); i++ { + if deptl[i].Pid != "0" { + continue + } + e := entity.ProductCategoryLabel{} + e.Id = deptl[i].Id + e.Name = deptl[i].Name + deptsInfo := DiGuiProductCategoryLabel(list, e) + + dl = append(dl, deptsInfo) + } + return dl +} + +func DiGuiProductCategory(sglist *[]entity.ProductCategory, menu entity.ProductCategory) entity.ProductCategory { + list := *sglist + + min := make([]entity.ProductCategory, 0) + for j := 0; j < len(list); j++ { + + if menu.Id != list[j].Pid { + continue + } + mi := entity.ProductCategory{} + mi.Id = list[j].Id + mi.Pid = list[j].Pid + mi.Path = list[j].Path + mi.Name = list[j].Name + mi.Sort = list[j].Sort + mi.Status = list[j].Status + mi.Description = list[j].Description + ms := DiGuiProductCategory(sglist, mi) + min = append(min, ms) + } + menu.Children = min + return menu +} +func DiGuiProductCategoryLabel(sglist *[]entity.ProductCategory, dept entity.ProductCategoryLabel) entity.ProductCategoryLabel { + list := *sglist + + min := make([]entity.ProductCategoryLabel, 0) + for j := 0; j < len(list); j++ { + if dept.Id != list[j].Pid { + continue + } + sg := entity.ProductCategoryLabel{} + sg.Id = list[j].Id + sg.Name = list[j].Name + ms := DiGuiProductCategoryLabel(sglist, sg) + min = append(min, ms) + + } + dept.Children = min + return dept +} diff --git a/apps/device/services/product_ota.go b/apps/device/services/product_ota.go new file mode 100644 index 0000000000000000000000000000000000000000..00e53f247359e0129cff48b4a7f04e17c84e54a9 --- /dev/null +++ b/apps/device/services/product_ota.go @@ -0,0 +1,127 @@ +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "log" + "pandax/apps/device/entity" + "pandax/pkg/global" +) + +type ( + ProductOtaModel interface { + Insert(data entity.ProductOta) *entity.ProductOta + FindOne(id string) *entity.ProductOta + FindListPage(page, pageSize int, data entity.ProductOta) (*[]entity.ProductOta, int64) + FindList(data entity.ProductOta) *[]entity.ProductOta + Update(data entity.ProductOta) *entity.ProductOta + Delete(ids []string) + } + + otaModelImpl struct { + table string + } +) + +var ProductOtaModelDao ProductOtaModel = &otaModelImpl{ + table: `product_ota`, +} + +func (m *otaModelImpl) Insert(data entity.ProductOta) *entity.ProductOta { + m.checkLatest(data) + + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加产品固件失败") + return &data +} + +func (m *otaModelImpl) checkLatest(data entity.ProductOta) { + // 将原来的最新版更改为旧版本 + if data.IsLatest == true { + latest := m.getLatest() + m.updateLatest(latest.Id, false) + } +} + +func (m *otaModelImpl) FindOne(id string) *entity.ProductOta { + resData := new(entity.ProductOta) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询产品固件失败") + return resData +} + +func (m *otaModelImpl) FindListPage(page, pageSize int, data entity.ProductOta) (*[]entity.ProductOta, int64) { + list := make([]entity.ProductOta, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Description != "" { + db = db.Where("description = ?", data.Description) + } + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + if data.Id != "" { + db = db.Where("id = ?", data.Id) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Url != "" { + db = db.Where("url = ?", data.Url) + } + if data.Version != "" { + db = db.Where("version = ?", data.Version) + } + err := db.Count(&total).Error + err = db.Order("create_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询产品固件分页列表失败") + return &list, total +} + +func (m *otaModelImpl) FindList(data entity.ProductOta) *[]entity.ProductOta { + list := make([]entity.ProductOta, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Description != "" { + db = db.Where("description = ?", data.Description) + } + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + if data.Id != "" { + db = db.Where("id = ?", data.Id) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Version != "" { + db = db.Where("version = ?", data.Version) + } + biz.ErrIsNil(db.Order("create_time").Find(&list).Error, "查询产品固件列表失败") + return &list +} + +func (m *otaModelImpl) getLatest() *entity.ProductOta { + resData := new(entity.ProductOta) + db := global.Db.Table(m.table).Where("is_latest = ?", true) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询产品固件失败") + return resData +} + +func (m *otaModelImpl) Update(data entity.ProductOta) *entity.ProductOta { + m.checkLatest(data) + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改产品固件失败") + return &data +} +func (m *otaModelImpl) updateLatest(id string, IsLatest bool) { + log.Println(id, IsLatest) + err := global.Db.Table(m.table).Where("id = ?", id).Update("is_latest", IsLatest).Error + global.Log.Error("更新失败", err) +} + +func (m *otaModelImpl) Delete(ids []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.ProductOta{}, "id in (?)", ids).Error, "删除产品固件失败") +} diff --git a/apps/device/services/product_template.go b/apps/device/services/product_template.go new file mode 100644 index 0000000000000000000000000000000000000000..0bffa31c67738683c1337a55e9866207fe7e4ece --- /dev/null +++ b/apps/device/services/product_template.go @@ -0,0 +1,114 @@ +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/device/entity" + "pandax/pkg/global" + "strings" +) + +type ( + ProductTemplateModel interface { + Insert(data entity.ProductTemplate) *entity.ProductTemplate + FindOne(id string) *entity.ProductTemplate + FindListPage(page, pageSize int, data entity.ProductTemplate) (*[]entity.ProductTemplate, int64) + FindListAttrs(data entity.ProductTemplate) *[]entity.ProductTemplate + FindList(data entity.ProductTemplate) *[]entity.ProductTemplate + Update(data entity.ProductTemplate) *entity.ProductTemplate + Delete(ids []string) + } + + templateModelImpl struct { + table string + } +) + +var ProductTemplateModelDao ProductTemplateModel = &templateModelImpl{ + table: `product_templates`, +} + +func (m *templateModelImpl) Insert(data entity.ProductTemplate) *entity.ProductTemplate { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加产品模型失败") + return &data +} + +func (m *templateModelImpl) FindOne(id string) *entity.ProductTemplate { + resData := new(entity.ProductTemplate) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询产品模型失败") + return resData +} + +func (m *templateModelImpl) FindListPage(page, pageSize int, data entity.ProductTemplate) (*[]entity.ProductTemplate, int64) { + list := make([]entity.ProductTemplate, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Classify != "" { + db = db.Where("classify in (?)", strings.Split(data.Classify, ",")) + } + if data.Key != "" { + db = db.Where("key = ?", data.Key) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Type != "" { + db = db.Where("type = ?", data.Type) + } + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + err := db.Count(&total).Error + err = db.Order("create_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询产品模型分页列表失败") + return &list, total +} + +func (m *templateModelImpl) FindListAttrs(data entity.ProductTemplate) *[]entity.ProductTemplate { + list := make([]entity.ProductTemplate, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + db = db.Where("classify in (?)", []string{"attributes", "telemetry"}) + err := db.Order("create_time").Find(&list).Error + biz.ErrIsNil(err, "查询产品模型分页列表失败") + return &list +} + +func (m *templateModelImpl) FindList(data entity.ProductTemplate) *[]entity.ProductTemplate { + list := make([]entity.ProductTemplate, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Classify != "" { + db = db.Where("classify in (?)", strings.Split(data.Classify, ",")) + } + if data.Key != "" { + db = db.Where("key = ?", data.Key) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Type != "" { + db = db.Where("type = ?", data.Type) + } + if data.Pid != "" { + db = db.Where("pid = ?", data.Pid) + } + biz.ErrIsNil(db.Order("create_time").Find(&list).Error, "查询产品模型列表失败") + return &list +} + +func (m *templateModelImpl) Update(data entity.ProductTemplate) *entity.ProductTemplate { + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改产品模型失败") + return &data +} + +func (m *templateModelImpl) Delete(ids []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.ProductTemplate{}, "id in (?)", ids).Error, "删除产品模型失败") +} diff --git a/apps/device/tsl/convert.go b/apps/device/tsl/convert.go new file mode 100644 index 0000000000000000000000000000000000000000..cb39f5d7dd5f8f5004ac4c2172f3cd460f2e43a8 --- /dev/null +++ b/apps/device/tsl/convert.go @@ -0,0 +1,168 @@ +package tsl + +import ( + "strconv" + "time" +) + +func (t DefineAttribute) ConvertAttributeValue(v interface{}) interface{} { + if *t.Rw == "w" { + return "" + } + if v == nil { + return t.DefaultValue + } + return v +} + +func (t ValueType) ConvertValue(v interface{}) interface{} { + var transfer Transfer + switch t.Type { + case TypeInt: + transfer = TInt(t.DefineBase) + case TypeFloat: + transfer = TFloat(t.DefineBase) + case TypeString: + transfer = TText(t.DefineBase) + case TypeBool: + transfer = TBoolean(t.DefineBase) + case TypeDate: + transfer = TDate(t.DefineBase) + case TypeEnum: + transfer = TEnum(t.DefineBase) + case TypeStruct: + transfer = TStruct(t.DefineBase) + default: + return nil + } + return transfer.Convert(v) +} + +type Transfer interface { + Convert(interface{}) interface{} +} + +type TInt DefineBase + +func (tInt TInt) Convert(v interface{}) interface{} { + number, ok := v.(int64) + if !ok { + floatNumber, floatNumberOk := v.(float64) + if !floatNumberOk { + return 0 + } + number = int64(floatNumber) + } + if tInt.Min != nil && int64(*tInt.Min) > number { + return *tInt.Min + } + if tInt.Max != nil && int64(*tInt.Max) > number { + return *tInt.Max + } + return number +} + +type TFloat DefineBase + +func (tFloat TFloat) Convert(v interface{}) interface{} { + number, ok := v.(float64) + if !ok { + return 0 + } + if tFloat.Min != nil && *tFloat.Min > number { + number = *tFloat.Min + } + if tFloat.Max != nil && *tFloat.Max > number { + number = *tFloat.Max + } + defaultDecimal := 2 + if tFloat.Decimals != nil { + defaultDecimal = *tFloat.Decimals + } + number64, _ := strconv.ParseFloat(strconv.FormatFloat(number, 'f', defaultDecimal, 64), 32) + return number64 +} + +type TText DefineBase + +func (tText TText) Convert(v interface{}) interface{} { + text, ok := v.(string) + if !ok { + return "" + } + if tText.MaxLength != nil && *tText.MaxLength > 0 && len(text) > *tText.MaxLength { + return text[:*tText.MaxLength-1] + } else { + return text + } +} + +type TBoolean DefineBase + +func (tBoolean TBoolean) Convert(v interface{}) interface{} { + b, ok := v.(bool) + if !ok { + return "" + } + if b { + return tBoolean.DefineBool[1].Value + } else { + return tBoolean.DefineBool[0].Value + } + return "" +} + +type TDate DefineBase + +const layout = "2006-01-02 15:04:05" + +func (TDate TDate) Convert(v interface{}) interface{} { + str, ok := v.(string) + if !ok { + return time.Time{} + } + t, err := time.Parse(layout, str) + if err != nil { + return time.Time{} + } else { + return t + } +} + +type TEnum DefineBase + +func (tEnum TEnum) Convert(v interface{}) interface{} { + tE, ok := v.(string) + if !ok { + return "" + } + if tEnum.Enums == nil { + return "" + } + for _, node := range tEnum.Enums { + if node.Value == tE { + return node.Key + } + } + return "" +} + +type TStruct DefineBase + +func (tStruct TStruct) Convert(v interface{}) interface{} { + m, ok := v.(map[string]interface{}) + if !ok { + return nil + } + result := make(map[string]interface{}) + if tStruct.Struct != nil { + for k, value := range m { + for _, t := range tStruct.Struct { + if t.Name == k { + result[t.Name] = t.ValueType.ConvertValue(value) + } + } + } + } + return result +} diff --git a/apps/device/tsl/tsl.go b/apps/device/tsl/tsl.go new file mode 100644 index 0000000000000000000000000000000000000000..bd3a304773f81ba219c944b6f8f02dfe65922412 --- /dev/null +++ b/apps/device/tsl/tsl.go @@ -0,0 +1,72 @@ +package tsl + +const ( + TypeEnum = "enum" // 枚举类型 + TypeInt = "int64" + TypeString = "string" + TypeBool = "bool" + TypeFloat = "float64" + TypeDate = "date" + TypeStruct = "struct" +) + +// DefineAttribute 属性拓展 +type DefineAttribute struct { + DefaultValue *string `json:"defaultValue"` // 属性时 + Rw *string `json:"rw"` +} + +// DefineBase 基础类型参数 +type DefineBase struct { + Max *float64 `json:"max" ` // 最大,数字类型:int64、float64 + Min *float64 `json:"min" ` // 最小,数字类型:int64、float64 + Step *float64 `json:"step"` // 小数位数,数字类型:int64、float64 + Decimals *int `json:"decimals"` // 小数位数,数字类型:float64 + Unit *string `json:"unit"` // 单位,数字类型: int64、float64 + + MaxLength *int `json:"maxLength"` // 最大长度,字符类型:string + + DefineBool []DefineBool `json:"boolDefine"` + Enums []DefineEnum `json:"enumDefine"` // 枚举类型:enum + Struct []DefineStruct `json:"structDefine" ` // 对象类型:Struct +} + +type DefineBool struct { + Key string `json:"key"` // 键 0、1 + Value string `json:"value"` // 枚举值 +} + +type DefineEnum struct { + Key string `json:"key"` // 键 0、1 + Value string `json:"value"` // 枚举值 +} + +// DefineStruct 扩展类型参数:对象型 +type DefineStruct struct { + Key string `json:"key"` //参数标识 + Name string `json:"name"` // 参数名称 + ValueType ValueType `json:"valueType"` // 参数值 + Desc string `json:"desc"` // 描述 +} + +type ValueType struct { + Type string `json:"type" dc:"数据类型" v:"required#请选择数据类型"` // 类型 + DefineBase // 参数 +} + +// DefineCommands 命令 +type DefineCommands struct { + Key string `json:"key" dc:"功能标识" v:"required|regex:^[A-Za-z_]+[\\w]*$#请输入功能标识|标识由字母、数字和下划线组成,且不能以数字开头"` + Name string `json:"name" dc:"功能名称" v:"required#请输入功能名称"` // 功能名称 + Inputs []DefineCommandsInput `json:"inputs" dc:"输入参数"` // 输入参数 + Output ValueType `json:"output" dc:"输出参数"` // 输出参数 + Desc string `json:"desc" dc:"描述"` // 描述 +} + +// DefineCommandsInput 命令:输入参数 +type DefineCommandsInput struct { + Key string `json:"key"` + Name string `json:"name"` // 输入参数名称 + ValueType ValueType `json:"valueType"` // 参数值 + Desc string `json:"desc"` // 描述 +} diff --git a/apps/flow/api/flow_work_classify.go b/apps/flow/api/flow_work_classify.go index f8efc111bb318be6be726d02322f5555a5ecf177..1c5731a19c1039a7ef1273519cb8646fd297ca92 100644 --- a/apps/flow/api/flow_work_classify.go +++ b/apps/flow/api/flow_work_classify.go @@ -45,7 +45,7 @@ func (p *FlowWorkClassifyApi) GetFlowWorkClassify(rc *restfulx.ReqCtx) { func (p *FlowWorkClassifyApi) InsertFlowWorkClassify(rc *restfulx.ReqCtx) { var data entity.FlowWorkClassify restfulx.BindQuery(rc, &data) - + data.Creator = int(rc.LoginAccount.UserId) p.FlowWorkClassifyApp.Insert(data) } diff --git a/apps/flow/api/flow_work_info.go b/apps/flow/api/flow_work_info.go new file mode 100644 index 0000000000000000000000000000000000000000..a2be5479a13a1ea3d0444764b2a1a4c39c7a2dc7 --- /dev/null +++ b/apps/flow/api/flow_work_info.go @@ -0,0 +1,66 @@ +package api + +// ========================================================================== +// 生成日期:2023-03-29 20:01:11 +0800 CST +// 生成路径: apps/flow/api/rulechain.go +// 生成人:panda +// ========================================================================== +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + + "github.com/XM-GO/PandaKit/utils" + "pandax/apps/flow/entity" + "pandax/apps/flow/services" +) + +type FlowWorkInfoApi struct { + FlowWorkInfoApp services.FlowWorkInfoModel +} + +// GetFlowWorkInfoList WorkInfo列表数据 +func (p *FlowWorkInfoApi) GetFlowWorkInfoList(rc *restfulx.ReqCtx) { + data := entity.FlowWorkInfo{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.Name = restfulx.QueryParam(rc, "name") + data.Icon = restfulx.QueryParam(rc, "icon") + + list, total := p.FlowWorkInfoApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// GetFlowWorkInfo 获取WorkInfo +func (p *FlowWorkInfoApi) GetFlowWorkInfo(rc *restfulx.ReqCtx) { + id := restfulx.PathParamInt(rc, "id") + rc.ResData = p.FlowWorkInfoApp.FindOne(int64(id)) +} + +// InsertFlowWorkInfo 添加WorkInfo +func (p *FlowWorkInfoApi) InsertFlowWorkInfo(rc *restfulx.ReqCtx) { + var data entity.FlowWorkInfo + restfulx.BindQuery(rc, &data) + data.Creator = int(rc.LoginAccount.UserId) + p.FlowWorkInfoApp.Insert(data) +} + +// UpdateFlowWorkInfo 修改WorkInfo +func (p *FlowWorkInfoApi) UpdateFlowWorkInfo(rc *restfulx.ReqCtx) { + var data entity.FlowWorkInfo + restfulx.BindQuery(rc, &data) + + p.FlowWorkInfoApp.Update(data) +} + +// DeleteFlowWorkInfo 删除WorkInfo +func (p *FlowWorkInfoApi) DeleteFlowWorkInfo(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := utils.IdsStrToIdsIntGroup(id) + p.FlowWorkInfoApp.Delete(ids) +} diff --git a/apps/flow/api/flow_work_templates.go b/apps/flow/api/flow_work_templates.go new file mode 100644 index 0000000000000000000000000000000000000000..07de6c14bcf04f8837697d170bbbfea81b3150ff --- /dev/null +++ b/apps/flow/api/flow_work_templates.go @@ -0,0 +1,64 @@ +package api + +// ========================================================================== +// 生成日期:2023-03-29 19:46:55 +0800 CST +// 生成路径: apps/flow/api/flow_work_templates.go +// 生成人:panda +// ========================================================================== +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + + "github.com/XM-GO/PandaKit/utils" + "pandax/apps/flow/entity" + "pandax/apps/flow/services" +) + +type FlowWorkTemplatesApi struct { + FlowWorkTemplatesApp services.FlowWorkTemplatesModel +} + +// GetFlowWorkTemplatesList WorkTemplates列表数据 +func (p *FlowWorkTemplatesApi) GetFlowWorkTemplatesList(rc *restfulx.ReqCtx) { + data := entity.FlowWorkTemplates{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.Name = restfulx.QueryParam(rc, "name") + + list, total := p.FlowWorkTemplatesApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +// GetFlowWorkTemplates 获取WorkTemplates +func (p *FlowWorkTemplatesApi) GetFlowWorkTemplates(rc *restfulx.ReqCtx) { + id := restfulx.PathParamInt(rc, "id") + rc.ResData = p.FlowWorkTemplatesApp.FindOne(int64(id)) +} + +// InsertFlowWorkTemplates 添加WorkTemplates +func (p *FlowWorkTemplatesApi) InsertFlowWorkTemplates(rc *restfulx.ReqCtx) { + var data entity.FlowWorkTemplates + restfulx.BindQuery(rc, &data) + data.Creator = int(rc.LoginAccount.UserId) + p.FlowWorkTemplatesApp.Insert(data) +} + +// UpdateFlowWorkTemplates 修改WorkTemplates +func (p *FlowWorkTemplatesApi) UpdateFlowWorkTemplates(rc *restfulx.ReqCtx) { + var data entity.FlowWorkTemplates + restfulx.BindQuery(rc, &data) + p.FlowWorkTemplatesApp.Update(data) +} + +// DeleteFlowWorkTemplates 删除WorkTemplates +func (p *FlowWorkTemplatesApi) DeleteFlowWorkTemplates(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + ids := utils.IdsStrToIdsIntGroup(id) + p.FlowWorkTemplatesApp.Delete(ids) +} diff --git a/apps/flow/entity/work_classify.go b/apps/flow/entity/work_classify.go index d966c0b95662cd7ca9141fe07d1fe9b17ccfd2f4..0608adbadcd2e476b1a10c3fa4d596946887e550 100644 --- a/apps/flow/entity/work_classify.go +++ b/apps/flow/entity/work_classify.go @@ -5,8 +5,8 @@ import "github.com/XM-GO/PandaKit/model" // FlowWorkClassify 工作流流程分类 type FlowWorkClassify struct { model.BaseAutoModel - Name string `gorm:"column:name; type: varchar(128)" json:"name"` // 分类名称 - Creator int `gorm:"column:creator; type: int(11)" json:"creator"` // 创建者 + Name string `gorm:"column:name; type: varchar(128)" json:"name"` // 分类名称 + Creator int `gorm:"column:creator; type: int" json:"creator"` // 创建者 } func (FlowWorkClassify) TableName() string { diff --git a/apps/flow/entity/work_info.go b/apps/flow/entity/work_info.go index 6a83b9a1665a86a1251ce742b3db4d3be1bccb5f..9216c055aca4749f780df3e678211ceeb8c2a107 100644 --- a/apps/flow/entity/work_info.go +++ b/apps/flow/entity/work_info.go @@ -1,23 +1,21 @@ package entity import ( - "encoding/json" "github.com/XM-GO/PandaKit/model" ) // FlowWorkInfo 工作流信息 type FlowWorkInfo struct { model.BaseAutoModel - Name string `gorm:"column:name; type:varchar(128)" json:"name"` // 流程名称 - Icon string `gorm:"column:icon; type:varchar(128)" json:"icon" ` // 流程标签 - Structure json.RawMessage `gorm:"column:structure; type:json" json:"structure" ` // 流程结构 - Classify int `gorm:"column:classify; type:int(11)" json:"classify"` // 分类ID - Templates json.RawMessage `gorm:"column:templates; type:json" json:"templates"` // 模版 - Task json.RawMessage `gorm:"column:task; type:json" json:"task"` // 任务ID, array, 可执行多个任务,可以当成通知任务,每个节点都会去执行 - SubmitCount int `gorm:"column:submit_count; type:int(11); default:0" json:"submitCount"` // 提交统计 - Creator int `gorm:"column:creator; type:int(11)" json:"creator"` // 创建者 - Notice json.RawMessage `gorm:"column:notice; type:json" json:"notice"` // 绑定通知 - Remarks string `gorm:"column:remarks; type:varchar(1024)" json:"remarks"` // 流程备注 + Name string `gorm:"column:name; type:varchar(128)" json:"name"` // 流程名称 + Icon string `gorm:"column:icon; type:varchar(128)" json:"icon" ` // 流程标签 + Structure model.JSONB `gorm:"column:structure; type:json" json:"structure" ` // 流程结构 + FormStructure model.JSONB `gorm:"column:structure; type:json" json:"structure" ` // 表单结构 + Classify int `gorm:"column:classify; type:int" json:"classify"` // 分类ID + SubmitCount int `gorm:"column:submit_count; type:int; default:0" json:"submitCount"` // 提交统计 + Creator int `gorm:"column:creator; type:int" json:"creator"` // 创建者 + Cc int `gorm:"column:cc; type:int" json:"cc"` // 抄送人 + Remarks string `gorm:"column:remarks; type:varchar(1024)" json:"remarks"` // 流程备注 } func (FlowWorkInfo) TableName() string { diff --git a/apps/flow/entity/work_order.go b/apps/flow/entity/work_order.go index bced08e70d1b550edc45bf04eb8ce4eadfa90b97..e2256e10a8643a460386ba8cca7ae5a2ce708fc2 100644 --- a/apps/flow/entity/work_order.go +++ b/apps/flow/entity/work_order.go @@ -8,17 +8,17 @@ import ( // FlowWorkOrder 工作流工单 type FlowWorkOrder struct { model.BaseAutoModel - Title string `gorm:"column:title; type:varchar(128)" json:"title"` // 工单标题 - Priority int `gorm:"column:priority; type:int(11)" json:"priority"` // 工单优先级 1,正常 2,紧急 3,非常紧急 - Process int `gorm:"column:process; type:int(11)" json:"process"` // 流程ID - Classify int `gorm:"column:classify; type:int(11)" json:"classify"` // 分类ID - IsEnd int `gorm:"column:is_end; type:int(11); default:0" json:"is_end"` // 是否结束, 0 未结束,1 已结束 - IsDenied int `gorm:"column:is_denied; type:int(11); default:0" json:"is_denied"` // 是否被拒绝, 0 没有,1 有 - State json.RawMessage `gorm:"column:state; type:json" json:"state"` // 状态信息 - RelatedPerson json.RawMessage `gorm:"column:related_person; type:json" json:"related_person"` // 工单所有处理人 - Creator int `gorm:"column:creator; type:int(11)" json:"creator"` // 创建人 - UrgeCount int `gorm:"column:urge_count; type:int(11); default:0" json:"urge_count"` // 催办次数 - UrgeLastTime int `gorm:"column:urge_last_time; type:int(11); default:0" json:"urge_last_time"` // 上一次催促时间 + Title string `gorm:"column:title; type:varchar(128)" json:"title"` // 工单标题 + Priority int `gorm:"column:priority; type:int" json:"priority"` // 工单优先级 1,正常 2,紧急 3,非常紧急 + Process int `gorm:"column:process; type:int" json:"process"` // 流程ID + Classify int `gorm:"column:classify; type:int" json:"classify"` // 分类ID + IsEnd int `gorm:"column:is_end; type:int; default:0" json:"is_end"` // 是否结束, 0 未结束,1 已结束 + IsDenied int `gorm:"column:is_denied; type:int; default:0" json:"is_denied"` // 是否被拒绝, 0 没有,1 有 + State json.RawMessage `gorm:"column:state; type:json" json:"state"` // 状态信息 + RelatedPerson json.RawMessage `gorm:"column:related_person; type:json" json:"related_person"` // 工单所有处理人 + Creator int `gorm:"column:creator; type:int" json:"creator"` // 创建人 + UrgeCount int `gorm:"column:urge_count; type:int; default:0" json:"urge_count"` // 催办次数 + UrgeLastTime int `gorm:"column:urge_last_time; type:int; default:0" json:"urge_last_time"` // 上一次催促时间 } func (FlowWorkOrder) TableName() string { diff --git a/apps/flow/entity/work_order_templates.go b/apps/flow/entity/work_order_templates.go index 92d9f7319b0cce8e9be414d018a2908c886c5fb3..ae1a011502f7e0e2f2c7aae2b58864a29905fdfa 100644 --- a/apps/flow/entity/work_order_templates.go +++ b/apps/flow/entity/work_order_templates.go @@ -1,16 +1,15 @@ package entity import ( - "encoding/json" "github.com/XM-GO/PandaKit/model" ) // FlowWorkOrderTemplate 工单绑定模版数据 type FlowWorkOrderTemplate struct { model.BaseAutoModel - WorkOrder int `gorm:"column:work_order; type: int(11)" json:"work_order"` // 工单ID - FormStructure json.RawMessage `gorm:"column:form_structure; type: json" json:"form_structure"` // 表单结构 - FormData json.RawMessage `gorm:"column:form_data; type: json" json:"form_data"` // 表单数据 + WorkOrder int `gorm:"column:work_order; type: int" json:"work_order"` // 工单ID + FormStructure model.JSONB `gorm:"column:form_structure; type: json" json:"form_structure"` // 表单结构 + FormData model.JSONB `gorm:"column:form_data; type: json" json:"form_data"` // 表单数据 } func (FlowWorkOrderTemplate) TableName() string { diff --git a/apps/flow/entity/work_stage.go b/apps/flow/entity/work_stage.go index 2849dac9c8ca7948686444e60aba7b502401b49d..ab11f9f7d2b78471e8447663342cbd2f2b201aaf 100644 --- a/apps/flow/entity/work_stage.go +++ b/apps/flow/entity/work_stage.go @@ -7,17 +7,17 @@ import ( // FlowWorkStage 工作流工序(流转历史) type FlowWorkStage struct { model.BaseAutoModel - Title string `gorm:"column:title; type: varchar(128)" json:"title"` // 工单标题 - WorkOrder int `gorm:"column:work_order; type: int(11)" json:"work_order"` // 工单ID - State string `gorm:"column:state; type: varchar(128)" json:"state"` // 工单状态 - Source string `gorm:"column:source; type: varchar(128)" json:"source"` // 源节点ID - Target string `gorm:"column:target; type: varchar(128)" json:"target"` // 目标节点ID - Stage string `gorm:"column:stage; type: varchar(128)" json:"stage"` // 流转ID - Status int `gorm:"column:status; type: int(11)" json:"status"` // 流转状态 1 同意, 0 拒绝, 2 其他 - Processor string `gorm:"column:processor; type: varchar(45)" json:"processor"` // 处理人 - ProcessorId int `gorm:"column:processor_id; type: int(11)" json:"processor_id"` // 处理人ID - CostDuration int64 `gorm:"column:cost_duration; type: int(11)" json:"cost_duration"` // 处理时长 - Remarks string `gorm:"column:remarks; type: longtext" json:"remarks"` // 备注 + Title string `gorm:"column:title; type: varchar(128)" json:"title"` // 工单标题 + WorkOrder int `gorm:"column:work_order; type: int" json:"work_order"` // 工单ID + State string `gorm:"column:state; type: varchar(128)" json:"state"` // 工单状态 + Source string `gorm:"column:source; type: varchar(128)" json:"source"` // 源节点ID + Target string `gorm:"column:target; type: varchar(128)" json:"target"` // 目标节点ID + Stage string `gorm:"column:stage; type: varchar(128)" json:"stage"` // 流转ID + Status int `gorm:"column:status; type: int" json:"status"` // 流转状态 1 同意, 0 拒绝, 2 其他 + Processor string `gorm:"column:processor; type: varchar(45)" json:"processor"` // 处理人 + ProcessorId int `gorm:"column:processor_id; type: int" json:"processor_id"` // 处理人ID + CostDuration int64 `gorm:"column:cost_duration; type: int" json:"cost_duration"` // 处理时长 + Remarks string `gorm:"column:remarks; type: text" json:"remarks"` // 备注 } func (FlowWorkStage) TableName() string { diff --git a/apps/flow/entity/work_task.go b/apps/flow/entity/work_task.go deleted file mode 100644 index 0fc0bb523545d35ecb38367f8dcd1e01f344c02c..0000000000000000000000000000000000000000 --- a/apps/flow/entity/work_task.go +++ /dev/null @@ -1,33 +0,0 @@ -package entity - -import ( - "github.com/XM-GO/PandaKit/model" -) - -// FlowWorkTask 工作流任务 -type FlowWorkTask struct { - model.BaseAutoModel - Name string `gorm:"column:name; type: varchar(256)" json:"name"` // 任务名称 - TaskType string `gorm:"column:task_type; type: varchar(45)" json:"task_type"` // 任务类型 - Content string `gorm:"column:content; type: longtext" json:"content"` // 任务内容 - Creator int `gorm:"column:creator; type: int(11)" json:"creator"` // 创建者 - Remarks string `gorm:"column:remarks; type: longtext" json:"remarks"` // 备注 -} - -func (FlowWorkTask) TableName() string { - return "flow_work_task" -} - -// FlowWorkTaskHistory 工作流任务执行历史 -type FlowWorkTaskHistory struct { - model.BaseAutoModel - Task int `gorm:"column:task; type: int(11)" json:"task"` // 任务ID - Name string `gorm:"column:name; type: varchar(256)" json:"name"` // 任务名称 - TaskType int `gorm:"column:task_type; type: int(11)" json:"task_type"` // 任务类型, python, shell - ExecutionTime string `gorm:"column:execution_time; type: varchar(128)" json:"execution_time"` // 执行时间 - Result string `gorm:"column:result; type: longtext" json:"result"` // 任务返回 -} - -func (FlowWorkTaskHistory) TableName() string { - return "flow_work_task_history" -} diff --git a/apps/flow/entity/work_templates.go b/apps/flow/entity/work_templates.go index 409e3a08fd1c32b704c1b8cee66f804df8c678d0..434d9be1ea6960c36003065f0712a003a0729219 100644 --- a/apps/flow/entity/work_templates.go +++ b/apps/flow/entity/work_templates.go @@ -1,17 +1,16 @@ package entity import ( - "encoding/json" "github.com/XM-GO/PandaKit/model" ) // FlowWorkTemplates 工作流表单模板 type FlowWorkTemplates struct { model.BaseAutoModel - Name string `gorm:"column:name; type: varchar(128)" json:"name" binding:"required"` // 模板名称 - FormStructure json.RawMessage `gorm:"column:form_structure; type: json" json:"form_structure" binding:"required"` // 表单结构 - Creator int `gorm:"column:creator; type: int(11)" json:"creator"` // 创建者 - Remarks string `gorm:"column:remarks; type: longtext" json:"remarks"` // 备注 + Name string `gorm:"column:name; type: varchar(128)" json:"name" binding:"required"` // 模板名称 + FormStructure model.JSONB `gorm:"column:form_structure; type: json" json:"form_structure"` // 表单结构 + Creator int `gorm:"column:creator; type: int" json:"creator"` // 创建者 + Remarks string `gorm:"column:remarks; type: text" json:"remarks"` // 备注 } func (FlowWorkTemplates) TableName() string { diff --git a/apps/flow/router/flow_work_info.go b/apps/flow/router/flow_work_info.go new file mode 100644 index 0000000000000000000000000000000000000000..18c5d35cbd4858d15d2dbb52518f5496b7464b97 --- /dev/null +++ b/apps/flow/router/flow_work_info.go @@ -0,0 +1,70 @@ +// ========================================================================== +// 生成日期:2023-03-29 20:01:11 +0800 CST +// 生成路径: apps/flow/router/rulechain.go +// 生成人:panda +// ========================================================================== +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/flow/api" + "pandax/apps/flow/entity" + "pandax/apps/flow/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitFlowWorkInfoRouter(container *restful.Container) { + s := &api.FlowWorkInfoApi{ + FlowWorkInfoApp: services.FlowWorkInfoModelDao, + } + + ws := new(restful.WebService) + ws.Path("/flow/workinfo").Produces(restful.MIME_JSON) + tags := []string{"workinfo"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取WorkInfo分页列表").Handle(s.GetFlowWorkInfoList) + }). + Doc("获取WorkInfo分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取WorkInfo信息").Handle(s.GetFlowWorkInfo) + }). + Doc("获取WorkInfo信息"). + Param(ws.PathParameter("id", "Id").DataType("int")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.FlowWorkInfo{}). // on the response + Returns(200, "OK", entity.FlowWorkInfo{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加WorkInfo信息").Handle(s.InsertFlowWorkInfo) + }). + Doc("添加WorkInfo信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.FlowWorkInfo{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改WorkInfo信息").Handle(s.UpdateFlowWorkInfo) + }). + Doc("修改WorkInfo信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.FlowWorkInfo{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除WorkInfo信息").Handle(s.DeleteFlowWorkInfo) + }). + Doc("删除WorkInfo信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/flow/router/flow_work_templates.go b/apps/flow/router/flow_work_templates.go new file mode 100644 index 0000000000000000000000000000000000000000..8937bf69b7da3ba4f3bd4a5b66b818d0490f8eb5 --- /dev/null +++ b/apps/flow/router/flow_work_templates.go @@ -0,0 +1,70 @@ +// ========================================================================== +// 生成日期:2023-03-29 19:46:55 +0800 CST +// 生成路径: apps/flow/router/flow_work_templates.go +// 生成人:panda +// ========================================================================== +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "pandax/apps/flow/api" + "pandax/apps/flow/entity" + "pandax/apps/flow/services" + + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" +) + +func InitFlowWorkTemplatesRouter(container *restful.Container) { + s := &api.FlowWorkTemplatesApi{ + FlowWorkTemplatesApp: services.FlowWorkTemplatesModelDao, + } + + ws := new(restful.WebService) + ws.Path("/flow/worktemplates").Produces(restful.MIME_JSON) + tags := []string{"worktemplates"} + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取WorkTemplates分页列表").Handle(s.GetFlowWorkTemplatesList) + }). + Doc("获取WorkTemplates分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取WorkTemplates信息").Handle(s.GetFlowWorkTemplates) + }). + Doc("获取WorkTemplates信息"). + Param(ws.PathParameter("id", "Id").DataType("int")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.FlowWorkTemplates{}). // on the response + Returns(200, "OK", entity.FlowWorkTemplates{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加WorkTemplates信息").Handle(s.InsertFlowWorkTemplates) + }). + Doc("添加WorkTemplates信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.FlowWorkTemplates{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改WorkTemplates信息").Handle(s.UpdateFlowWorkTemplates) + }). + Doc("修改WorkTemplates信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.FlowWorkTemplates{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除WorkTemplates信息").Handle(s.DeleteFlowWorkTemplates) + }). + Doc("删除WorkTemplates信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + container.Add(ws) +} diff --git a/apps/flow/services/flow_work_info.go b/apps/flow/services/flow_work_info.go new file mode 100644 index 0000000000000000000000000000000000000000..3bacbbe6d3f07c87c215cb4729ec59ad6b37fcbf --- /dev/null +++ b/apps/flow/services/flow_work_info.go @@ -0,0 +1,101 @@ +// ========================================================================== +// 生成日期:2023-03-29 20:01:11 +0800 CST +// 生成路径: apps/flow/services/rulechain.go +// 生成人:panda +// ========================================================================== + +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/flow/entity" + "pandax/pkg/global" +) + +type ( + FlowWorkInfoModel interface { + Insert(data entity.FlowWorkInfo) *entity.FlowWorkInfo + FindOne(id int64) *entity.FlowWorkInfo + FindListPage(page, pageSize int, data entity.FlowWorkInfo) (*[]entity.FlowWorkInfo, int64) + FindList(data entity.FlowWorkInfo) *[]entity.FlowWorkInfo + Update(data entity.FlowWorkInfo) *entity.FlowWorkInfo + Delete(ids []int64) + } + + workinfoModelImpl struct { + table string + } +) + +var FlowWorkInfoModelDao FlowWorkInfoModel = &workinfoModelImpl{ + table: `flow_work_info`, +} + +func (m *workinfoModelImpl) Insert(data entity.FlowWorkInfo) *entity.FlowWorkInfo { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加流程失败") + return &data +} + +func (m *workinfoModelImpl) FindOne(id int64) *entity.FlowWorkInfo { + resData := new(entity.FlowWorkInfo) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询流程失败") + return resData +} + +func (m *workinfoModelImpl) FindListPage(page, pageSize int, data entity.FlowWorkInfo) (*[]entity.FlowWorkInfo, int64) { + list := make([]entity.FlowWorkInfo, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + db.Where("delete_time IS NULL") + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Creator != 0 { + db = db.Where("creator = ?", data.Creator) + } + if data.Remarks != "" { + db = db.Where("remarks like ?", "%"+data.Remarks+"%") + } + if data.Classify != 0 { + db = db.Where("classify = ?", data.Classify) + } + err := db.Count(&total).Error + err = db.Order("create_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询流程分页列表失败") + return &list, total +} + +func (m *workinfoModelImpl) FindList(data entity.FlowWorkInfo) *[]entity.FlowWorkInfo { + list := make([]entity.FlowWorkInfo, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + db.Where("delete_time IS NULL") + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Creator != 0 { + db = db.Where("creator = ?", data.Creator) + } + if data.Remarks != "" { + db = db.Where("remarks like ?", "%"+data.Remarks+"%") + } + if data.Classify != 0 { + db = db.Where("classify = ?", data.Classify) + } + biz.ErrIsNil(db.Order("create_time").Find(&list).Error, "查询流程列表失败") + return &list +} + +func (m *workinfoModelImpl) Update(data entity.FlowWorkInfo) *entity.FlowWorkInfo { + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改流程失败") + return &data +} + +func (m *workinfoModelImpl) Delete(ids []int64) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.FlowWorkInfo{}, "id in (?)", ids).Error, "删除流程失败") +} diff --git a/apps/flow/services/flow_work_templates.go b/apps/flow/services/flow_work_templates.go new file mode 100644 index 0000000000000000000000000000000000000000..745765d99bb4473388375bc814dc7511d287f543 --- /dev/null +++ b/apps/flow/services/flow_work_templates.go @@ -0,0 +1,106 @@ +// ========================================================================== +// 生成日期:2023-03-29 19:46:55 +0800 CST +// 生成路径: apps/flow/services/flow_work_templates.go +// 生成人:panda +// ========================================================================== + +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/flow/entity" + "pandax/pkg/global" +) + +type ( + FlowWorkTemplatesModel interface { + Insert(data entity.FlowWorkTemplates) *entity.FlowWorkTemplates + FindOne(id int64) *entity.FlowWorkTemplates + FindListPage(page, pageSize int, data entity.FlowWorkTemplates) (*[]entity.FlowWorkTemplates, int64) + FindList(data entity.FlowWorkTemplates) *[]entity.FlowWorkTemplates + Update(data entity.FlowWorkTemplates) *entity.FlowWorkTemplates + Delete(ids []int64) + } + + worktemplatesModelImpl struct { + table string + } +) + +var FlowWorkTemplatesModelDao FlowWorkTemplatesModel = &worktemplatesModelImpl{ + table: `flow_work_templates`, +} + +func (m *worktemplatesModelImpl) Insert(data entity.FlowWorkTemplates) *entity.FlowWorkTemplates { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加工作流模板失败") + return &data +} + +func (m *worktemplatesModelImpl) FindOne(id int64) *entity.FlowWorkTemplates { + resData := new(entity.FlowWorkTemplates) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询工作流模板失败") + return resData +} + +func (m *worktemplatesModelImpl) FindListPage(page, pageSize int, data entity.FlowWorkTemplates) (*[]entity.FlowWorkTemplates, int64) { + list := make([]entity.FlowWorkTemplates, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Remarks != "" { + db = db.Where("remarks = ?", data.Remarks) + } + db.Where("delete_time IS NULL") + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Creator != 0 { + db = db.Where("creator = ?", data.Creator) + } + if data.Remarks != "" { + db = db.Where("name like ?", "%"+data.Remarks+"%") + } + err := db.Count(&total).Error + err = db.Order("create_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询工作流模板分页列表失败") + return &list, total +} + +func (m *worktemplatesModelImpl) FindList(data entity.FlowWorkTemplates) *[]entity.FlowWorkTemplates { + list := make([]entity.FlowWorkTemplates, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Remarks != "" { + db = db.Where("remarks = ?", data.Remarks) + } + db.Where("delete_time IS NULL") + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + if data.Creator != 0 { + db = db.Where("creator = ?", data.Creator) + } + if data.Remarks != "" { + db = db.Where("name like ?", "%"+data.Remarks+"%") + } + biz.ErrIsNil(db.Order("create_time").Find(&list).Error, "查询工作流模板列表失败") + return &list +} + +func (m *worktemplatesModelImpl) Update(data entity.FlowWorkTemplates) *entity.FlowWorkTemplates { + err := global.Db.Table(m.table).Updates(&data).Error + if err != nil { + global.Log.Error(err) + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改工作流模板失败") + } + + return &data +} + +func (m *worktemplatesModelImpl) Delete(ids []int64) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.FlowWorkTemplates{}, "id in (?)", ids).Error, "删除工作流模板失败") +} diff --git a/apps/job/api/from/job.go b/apps/job/api/from/job.go index 7f1a38538f84885bb9fd9f3e0dedfd76235d8f91..c9a877f0c8f98fb3d67c7a40da1f7054b502210e 100644 --- a/apps/job/api/from/job.go +++ b/apps/job/api/from/job.go @@ -1,6 +1,6 @@ package from type JobStatus struct { - JobId int64 `json:"jobId"` + JobId string `json:"jobId"` Status string `json:"status"` } diff --git a/apps/job/api/job.go b/apps/job/api/job.go index ec2f32ede399e440f15ba9912e1ea4c8161ed523..e2b73ab15702bb097f14794ffaf85934dad27bf5 100644 --- a/apps/job/api/job.go +++ b/apps/job/api/job.go @@ -4,11 +4,13 @@ import ( "github.com/XM-GO/PandaKit/biz" "github.com/XM-GO/PandaKit/model" "github.com/XM-GO/PandaKit/restfulx" - "github.com/XM-GO/PandaKit/utils" + "github.com/kakuilan/kgo" + "log" "pandax/apps/job/api/from" "pandax/apps/job/entity" "pandax/apps/job/jobs" "pandax/apps/job/services" + "strings" ) type JobApi struct { @@ -18,8 +20,8 @@ type JobApi struct { func (j *JobApi) CreateJob(rc *restfulx.ReqCtx) { var job entity.SysJob restfulx.BindQuery(rc, &job) - - job.CreateBy = rc.LoginAccount.UserName + job.Id = kgo.KStr.Uniqid("") + job.Owner = rc.LoginAccount.UserName j.JobApp.Insert(job) } @@ -27,10 +29,9 @@ func (j *JobApi) GetJobList(rc *restfulx.ReqCtx) { pageNum := restfulx.QueryInt(rc, "pageNum", 1) pageSize := restfulx.QueryInt(rc, "pageSize", 10) jobName := restfulx.QueryParam(rc, "jobName") - jobGroup := restfulx.QueryParam(rc, "jobGroup") status := restfulx.QueryParam(rc, "status") - list, total := j.JobApp.FindListPage(pageNum, pageSize, entity.SysJob{JobName: jobName, JobGroup: jobGroup, Status: status}) + list, total := j.JobApp.FindListPage(pageNum, pageSize, entity.SysJob{JobName: jobName, Status: status}) rc.ResData = model.ResultPage{ Total: total, PageNum: int64(pageNum), @@ -40,8 +41,8 @@ func (j *JobApi) GetJobList(rc *restfulx.ReqCtx) { } func (j *JobApi) GetJob(rc *restfulx.ReqCtx) { - jobId := restfulx.PathParamInt(rc, "jobId") - rc.ResData = j.JobApp.FindOne(int64(jobId)) + jobId := restfulx.PathParam(rc, "jobId") + rc.ResData = j.JobApp.FindOne(jobId) } func (l *JobApi) UpdateJob(rc *restfulx.ReqCtx) { @@ -52,52 +53,43 @@ func (l *JobApi) UpdateJob(rc *restfulx.ReqCtx) { func (l *JobApi) DeleteJob(rc *restfulx.ReqCtx) { jobIds := restfulx.PathParam(rc, "jobId") - group := utils.IdsStrToIdsIntGroup(jobIds) + group := strings.Split(jobIds, ",") l.JobApp.Delete(group) } func (l *JobApi) StopJobForService(rc *restfulx.ReqCtx) { - jobId := restfulx.PathParamInt(rc, "jobId") - job := l.JobApp.FindOne(int64(jobId)) + jobId := restfulx.PathParam(rc, "jobId") + job := l.JobApp.FindOne(jobId) jobs.Remove(jobs.Crontab, job.EntryId) } func (l *JobApi) StartJobForService(rc *restfulx.ReqCtx) { - jobId := restfulx.PathParamInt(rc, "jobId") - job := l.JobApp.FindOne(int64(jobId)) + jobId := restfulx.PathParam(rc, "jobId") + job := l.JobApp.FindOne(jobId) biz.IsTrue(job.Status == "0", "以关闭的任务不能开启") biz.IsTrue(job.EntryId == 0, "任务不能重复启动") var err error - if job.JobType == "1" { - var j = &jobs.HttpJob{} - j.InvokeTarget = job.InvokeTarget - j.CronExpression = job.CronExpression - j.JobId = job.JobId - j.Name = job.JobName - j.JobGroup = job.JobGroup - j.MisfirePolicy = job.MisfirePolicy - job.EntryId, err = jobs.AddJob(jobs.Crontab, j) - biz.ErrIsNil(err, "添加JOB失败") - } else { - var j = &jobs.ExecJob{} - j.InvokeTarget = job.InvokeTarget - j.CronExpression = job.CronExpression - j.JobId = job.JobId - j.Name = job.JobName - j.JobGroup = job.JobGroup - j.Args = job.Args - j.MisfirePolicy = job.MisfirePolicy - job.EntryId, err = jobs.AddJob(jobs.Crontab, j) - biz.ErrIsNil(err, "添加JOB失败") - } + var j = &jobs.ExecJob{} + j.InvokeTarget = job.TargetInvoke + j.CronExpression = job.CronExpression + j.JobId = job.Id + j.Name = job.JobName + j.Args = job.TargetArgs + j.MisfirePolicy = job.MisfirePolicy + job.EntryId, err = jobs.AddJob(jobs.Crontab, j) + log.Println(err) + biz.ErrIsNil(err, "添加JOB失败") + l.JobApp.Update(*job) } func (l *JobApi) UpdateStatusJob(rc *restfulx.ReqCtx) { var job from.JobStatus restfulx.BindQuery(rc, &job) - - l.JobApp.Update(entity.SysJob{JobId: job.JobId, Status: job.Status}) + sjob := entity.SysJob{} + sjob.Id = job.JobId + sjob.Status = job.Status + l.JobApp.Update(sjob) } diff --git a/apps/log/api/log_job.go b/apps/job/api/log_job.go similarity index 56% rename from apps/log/api/log_job.go rename to apps/job/api/log_job.go index 7c6d957861d3f6f973b3c4576b31ab4ea1bb8dc6..01122c596c4b0a1db4cbdd30f0bba20c07259eba 100644 --- a/apps/log/api/log_job.go +++ b/apps/job/api/log_job.go @@ -4,23 +4,22 @@ import ( "github.com/XM-GO/PandaKit/model" "github.com/XM-GO/PandaKit/restfulx" "github.com/XM-GO/PandaKit/utils" - "pandax/apps/log/entity" - "pandax/apps/log/services" + "pandax/apps/job/entity" + "pandax/apps/job/services" ) -type LogJobApi struct { - LogJobApp services.LogJobModel +type JobLogApi struct { + JobLogApp services.JobLogModel } // GetJobLogList Job日志列表 -func (l *LogJobApi) GetJobLogList(rc *restfulx.ReqCtx) { +func (l *JobLogApi) GetJobLogList(rc *restfulx.ReqCtx) { pageNum := restfulx.QueryInt(rc, "pageNum", 1) pageSize := restfulx.QueryInt(rc, "pageSize", 10) name := restfulx.QueryParam(rc, "name") - jobGroup := restfulx.QueryParam(rc, "jobGroup") status := restfulx.QueryParam(rc, "status") - list, total := l.LogJobApp.FindListPage(pageNum, pageSize, entity.LogJob{Name: name, JobGroup: jobGroup, Status: status}) + list, total := l.JobLogApp.FindListPage(pageNum, pageSize, entity.JobLog{Name: name, Status: status}) rc.ResData = model.ResultPage{ Total: total, PageNum: int64(pageNum), @@ -30,13 +29,13 @@ func (l *LogJobApi) GetJobLogList(rc *restfulx.ReqCtx) { } // DeleteJobLog 批量删除登录日志 -func (l *LogJobApi) DeleteJobLog(rc *restfulx.ReqCtx) { +func (l *JobLogApi) DeleteJobLog(rc *restfulx.ReqCtx) { logIds := restfulx.QueryParam(rc, "logId") group := utils.IdsStrToIdsIntGroup(logIds) - l.LogJobApp.Delete(group) + l.JobLogApp.Delete(group) } // DeleteAll 清空登录日志 -func (l *LogJobApi) DeleteAll(rc *restfulx.ReqCtx) { - l.LogJobApp.DeleteAll() +func (l *JobLogApi) DeleteAll(rc *restfulx.ReqCtx) { + l.JobLogApp.DeleteAll() } diff --git a/apps/job/entity/job.go b/apps/job/entity/job.go index 74e65c24db4957cb34146652a3cc873eb46774f7..ba529709cd9e52e1e1be415ed6fa3f4b3174be85 100644 --- a/apps/job/entity/job.go +++ b/apps/job/entity/job.go @@ -1,20 +1,17 @@ package entity -import "github.com/XM-GO/PandaKit/model" +import ( + "pandax/pkg/global" +) type SysJob struct { - JobId int64 `json:"jobId" gorm:"primaryKey;autoIncrement"` // 编码 - JobName string `json:"jobName" gorm:"type:varchar(255);"` // 名称 - JobGroup string `json:"jobGroup" gorm:"type:varchar(255);"` // 任务分组 - JobType string `json:"jobType" gorm:"type:varchar(1);"` // 任务类型 - CronExpression string `json:"cronExpression" gorm:"type:varchar(255);"` // cron表达式 - InvokeTarget string `json:"invokeTarget" gorm:"type:varchar(255);"` // 调用目标 - Args string `json:"args" gorm:"type:varchar(255);"` // 目标参数 - MisfirePolicy string `json:"misfirePolicy" gorm:"type:varchar(1);"` // 执行策略 - Concurrent string `json:"concurrent" gorm:"type:varchar(1);"` // 是否并发 - Status string `json:"status" gorm:"type:varchar(1);"` // 状态 - EntryId int `json:"entryId" gorm:"type:int;"` // job启动时返回的id - CreateBy string `json:"createBy" gorm:"type:varchar(128);comment:创建人"` - UpdateBy string `json:"updateBy" gorm:"type:varchar(128);comment:更新者"` - model.BaseModel + global.BaseAuthModel + JobName string `json:"jobName" gorm:"type:varchar(255);"` // 名称 + TargetInvoke string `json:"targetInvoke" gorm:"type:varchar(64);comment:目标类型"` //调用目标 设备还是产品 + TargetArgs string `json:"targetArgs" gorm:"type:varchar(64);comment:目标Id"` //目标传参 设备或者产品id + JobContent string `json:"jobContent" gorm:"type:json;comment:任务内容"` //目标传参 要执行的内容 + CronExpression string `json:"cronExpression" gorm:"type:varchar(255);"` // cron表达式 + MisfirePolicy string `json:"misfirePolicy" gorm:"type:varchar(1);"` // 执行策略 + Status string `json:"status" gorm:"type:varchar(1);"` // 状态 + EntryId int `json:"entryId" gorm:"type:int;"` // job启动时返回的id } diff --git a/apps/log/entity/log_job.go b/apps/job/entity/log_job.go similarity index 55% rename from apps/log/entity/log_job.go rename to apps/job/entity/log_job.go index 5fa45f35d5b361b6ba4799a5ab75e3308f5fae0f..462c2612b900213a97e98040e4591616a31c0d27 100644 --- a/apps/log/entity/log_job.go +++ b/apps/job/entity/log_job.go @@ -1,16 +1,14 @@ package entity import ( - "github.com/XM-GO/PandaKit/model" + "pandax/pkg/global" ) -type LogJob struct { - LogId int64 `json:"logId" gorm:"primary_key;AUTO_INCREMENT"` //主键 +type JobLog struct { + global.BaseAuthModel Name string `json:"name" gorm:"type:varchar(128);comment:任务名称"` - JobGroup string `json:"jobGroup" gorm:"type:varchar(128);comment:分组"` EntryId int `json:"entryId" gorm:"type:int;comment:任务id"` - InvokeTarget string `json:"invokeTarget" gorm:"type:varchar(128);comment:调用方法"` + TargetInvoke string `json:"targetInvoke" gorm:"type:varchar(128);comment:调用方法"` LogInfo string `json:"logInfo" gorm:"type:varchar(255);comment:日志信息"` Status string `json:"status" gorm:"type:varchar(1);comment:状态"` - model.BaseModel } diff --git a/apps/job/jobs/examples.go b/apps/job/jobs/examples.go index 23d3b386d729fffb565fa03d7407a1ad000c9088..7bafdbb26137352a5a669434773f8724ad0c9bf4 100644 --- a/apps/job/jobs/examples.go +++ b/apps/job/jobs/examples.go @@ -1,36 +1,23 @@ package jobs import ( - "fmt" - "time" + "log" ) -// 需要将定义的struct 添加到字典中; -// 字典 key 可以配置到 自动任务 调用目标 中; -func InitJob() { - jobList = map[string]JobsExec{ - "cronHandle": CronHandle{}, - // ... - } +type CronDeviceHandle struct { } -// 新添加的job 必须按照以下格式定义,并实现Exec函数 -type CronHandle struct { +func (t CronDeviceHandle) Exec(arg any, content any) error { + log.Println("执行设备任务", arg, content) + + return nil } -func (t CronHandle) Exec(arg any) error { - str := time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec success" - // TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化; - switch arg.(type) { +type CronProductHandle struct { +} - case string: - if arg.(string) != "" { - fmt.Println(str, arg.(string)) - } else { - fmt.Println(str, "arg is nil") - } - break - } +func (t CronProductHandle) Exec(arg any, content any) error { + log.Println("执行产品任务", arg, content) return nil } diff --git a/apps/job/jobs/jobbase.go b/apps/job/jobs/jobbase.go index 962c813c18efb459c1979c47d12c6d098416adb2..806d6bf3c9e5c454710690c8966b502ef7f654ec 100644 --- a/apps/job/jobs/jobbase.go +++ b/apps/job/jobs/jobbase.go @@ -2,14 +2,14 @@ package jobs import ( "fmt" + "github.com/kakuilan/kgo" "pandax/apps/job/entity" "pandax/apps/job/services" + "pandax/pkg/global" - logEntity "pandax/apps/log/entity" - logServices "pandax/apps/log/services" + logEntity "pandax/apps/job/entity" + logServices "pandax/apps/job/services" - "github.com/XM-GO/PandaKit/httpclient" - "pandax/pkg/global" "sync" "time" @@ -24,21 +24,24 @@ var lock sync.Mutex var Crontab = new(cron.Cron) +func InitJob() { + jobList = map[string]JobsExec{ + "cronDevice": CronDeviceHandle{}, + "cronProduct": CronProductHandle{}, + } + // 启动调度任务 + Setup() +} + type JobCore struct { InvokeTarget string Name string - JobGroup string - JobId int64 + JobId string EntryId int CronExpression string // 任务表达式 - MisfirePolicy string // 错误执行策略 + MisfirePolicy string Args string -} - -// 任务类型 http -type HttpJob struct { - cron *cron.Cron - JobCore + Content string } type ExecJob struct { @@ -48,25 +51,20 @@ type ExecJob struct { func (e *ExecJob) Run() { startTime := time.Now() + jobLog := logEntity.JobLog{Name: e.Name, EntryId: e.EntryId, TargetInvoke: e.InvokeTarget, Status: "0"} + jobLog.Id = kgo.KStr.Uniqid("") var obj = jobList[e.InvokeTarget] - if obj == nil { - if e.MisfirePolicy == "2" { - Remove(e.cron, e.EntryId) - } - return - } - err := CallExec(obj.(JobsExec), e.Args) + + err := CallExec(obj.(JobsExec), e.Args, e.Content) if err != nil { - if e.MisfirePolicy == "2" { - Remove(e.cron, e.EntryId) - return - } + jobLog.LogInfo = fmt.Sprintf("任务运行错误: %s", err.Error()) + Remove(e.cron, e.EntryId) + } else { + latencyTime := time.Now().Sub(startTime) + jobLog.LogInfo = fmt.Sprintf("任务运行成功,总耗时 %f", latencyTime.Seconds()) } // 执行时间 - latencyTime := time.Now().Sub(startTime) - - logInfo := fmt.Sprintf("任务运行总耗时 %f", latencyTime.Seconds()) - logServices.LogJobModelDao.Insert(logEntity.LogJob{Name: e.Name, JobGroup: e.JobGroup, EntryId: e.EntryId, InvokeTarget: e.InvokeTarget, LogInfo: logInfo, Status: "0"}) + logServices.JobLogModelDao.Insert(jobLog) // 执行一次 if e.MisfirePolicy == "1" { Remove(e.cron, e.EntryId) @@ -74,73 +72,12 @@ func (e *ExecJob) Run() { return } -//http 任务接口 -func (h *HttpJob) Run() { - - startTime := time.Now() - var count = 0 -LOOP: - if count < retryCount { - _, err := httpclient.NewRequest(h.InvokeTarget).Get().BodyToString() - if err != nil { - time.Sleep(time.Duration(count+1) * 5 * time.Second) - count = count + 1 - goto LOOP - } - } - // 执行时间 - latencyTime := time.Now().Sub(startTime) - - logInfo := fmt.Sprintf("任务运行总耗时 %f", latencyTime.Seconds()) - logServices.LogJobModelDao.Insert(logEntity.LogJob{Name: h.Name, JobGroup: h.JobGroup, EntryId: h.EntryId, InvokeTarget: h.InvokeTarget, LogInfo: logInfo, Status: "0"}) - if h.MisfirePolicy == "1" { - Remove(h.cron, h.EntryId) - } - return -} - func Setup() { Crontab = NewWithSeconds() - // 获取系统job SYSTEM是系统 - jl := services.JobModelDao.FindList(entity.SysJob{JobGroup: "SYSTEM"}) - jobList := *jl - if len(jobList) == 0 { - global.Log.Info(time.Now().Format(timeFormat), " [INFO] JobCore total:0") - return - } err := services.JobModelDao.RemoveAllEntryID() if err != nil { global.Log.Info(time.Now().Format(timeFormat), " [ERROR] JobCore remove entry_id error", err) } - sysJob := entity.SysJob{} - for i := 0; i < len(jobList); i++ { - //去除禁用的 - if jobList[i].Status != "0" { - continue - } - if jobList[i].JobType == "1" { - j := &HttpJob{} - j.InvokeTarget = jobList[i].InvokeTarget - j.CronExpression = jobList[i].CronExpression - j.JobId = jobList[i].JobId - j.Name = jobList[i].JobName - j.JobGroup = jobList[i].JobGroup - j.MisfirePolicy = jobList[i].MisfirePolicy - sysJob.EntryId, err = AddJob(Crontab, j) - } else if jobList[i].JobType == "2" { - j := &ExecJob{} - j.InvokeTarget = jobList[i].InvokeTarget - j.CronExpression = jobList[i].CronExpression - j.JobId = jobList[i].JobId - j.Name = jobList[i].JobName - j.JobGroup = jobList[i].JobGroup - j.Args = jobList[i].Args - j.MisfirePolicy = jobList[i].MisfirePolicy - sysJob.EntryId, err = AddJob(Crontab, j) - } - sysJob.JobId = jobList[i].JobId - services.JobModelDao.Update(sysJob) - } // 其中任务 Crontab.Start() global.Log.Info(time.Now().Format(timeFormat), " [INFO] JobCore start success.") @@ -149,7 +86,7 @@ func Setup() { select {} } -// 添加任务 AddJob(invokeTarget string, jobId int, jobName string, cronExpression string) +// AddJob 添加任务 func AddJob(c *cron.Cron, job Job) (int, error) { if job == nil { return 0, nil @@ -157,17 +94,6 @@ func AddJob(c *cron.Cron, job Job) (int, error) { return job.addJob(c) } -func (h *HttpJob) addJob(c *cron.Cron) (int, error) { - id, err := c.AddJob(h.CronExpression, h) - if err != nil { - return 0, err - } - h.cron = c - EntryId := int(id) - h.EntryId = EntryId - return EntryId, nil -} - func (h *ExecJob) addJob(c *cron.Cron) (int, error) { id, err := c.AddJob(h.CronExpression, h) if err != nil { diff --git a/apps/job/jobs/type.go b/apps/job/jobs/type.go index 645c3da5eaba43172192ea58c751ab4717be24c5..81d8e3d8b6c3942faf4e4344e8151210b80444da 100644 --- a/apps/job/jobs/type.go +++ b/apps/job/jobs/type.go @@ -8,9 +8,9 @@ type Job interface { } type JobsExec interface { - Exec(arg any) error + Exec(arg any, content any) error } -func CallExec(e JobsExec, arg any) error { - return e.Exec(arg) +func CallExec(e JobsExec, arg any, content any) error { + return e.Exec(arg, content) } diff --git a/apps/job/router/job.go b/apps/job/router/job.go index 9595f93a87eecc23f72bf73ff644cf41512e9c93..36cad32a2b55b27b4606c02c88464c2711cb41d3 100644 --- a/apps/job/router/job.go +++ b/apps/job/router/job.go @@ -27,7 +27,6 @@ func InitJobRouter(container *restful.Container) { Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). Param(ws.QueryParameter("jobName", "jobName").DataType("string")). - Param(ws.QueryParameter("jobGroup", "jobGroup").DataType("string")). Param(ws.QueryParameter("status", "status").DataType("string")). Metadata(restfulspec.KeyOpenAPITags, tags). Writes(model.ResultPage{}). @@ -68,17 +67,17 @@ func InitJobRouter(container *restful.Container) { restfulx.NewReqCtx(request, response).WithLog("停止一个job").Handle(s.StopJobForService) }). Doc("停止一个job"). - Param(ws.PathParameter("jobId", "Id").DataType("int")). + Param(ws.PathParameter("jobId", "Id").DataType("string")). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/start/{jobId}").To(func(request *restful.Request, response *restful.Response) { restfulx.NewReqCtx(request, response).WithLog("开启一个job").Handle(s.StartJobForService) }). Doc("开启一个job"). - Param(ws.PathParameter("jobId", "Id").DataType("int")). + Param(ws.PathParameter("jobId", "Id").DataType("string")). Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/changeStatus").To(func(request *restful.Request, response *restful.Response) { + ws.Route(ws.PUT("/changeStatus").To(func(request *restful.Request, response *restful.Response) { restfulx.NewReqCtx(request, response).WithLog("修改状态").Handle(s.UpdateStatusJob) }). Doc("修改状态"). diff --git a/apps/log/router/job_log.go b/apps/job/router/job_log.go similarity index 85% rename from apps/log/router/job_log.go rename to apps/job/router/job_log.go index 70b2e69b6a0b0af5764b99126ccb0bb08f055a5d..d9c4ef497e3b5a3877901814ea20d315b418a139 100644 --- a/apps/log/router/job_log.go +++ b/apps/job/router/job_log.go @@ -5,19 +5,19 @@ import ( "github.com/XM-GO/PandaKit/restfulx" restfulspec "github.com/emicklei/go-restful-openapi/v2" "github.com/emicklei/go-restful/v3" - "pandax/apps/log/api" - "pandax/apps/log/services" + "pandax/apps/job/api" + "pandax/apps/job/services" ) func InitJobLogRouter(container *restful.Container) { // Job日志 - s := &api.LogJobApi{ - LogJobApp: services.LogJobModelDao, + s := &api.JobLogApi{ + JobLogApp: services.JobLogModelDao, } ws := new(restful.WebService) - ws.Path("/log/logJob").Produces(restful.MIME_JSON) - tags := []string{"logJob"} + ws.Path("/job/log").Produces(restful.MIME_JSON) + tags := []string{"JobLog"} ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { restfulx.NewReqCtx(request, response).WithLog("获取操作日志列表").Handle(s.GetJobLogList) @@ -27,7 +27,6 @@ func InitJobLogRouter(container *restful.Container) { Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). Param(ws.QueryParameter("status", "status").DataType("string")). Param(ws.QueryParameter("name", "name").DataType("string")). - Param(ws.QueryParameter("jobGroup", "jobGroup").DataType("string")). Metadata(restfulspec.KeyOpenAPITags, tags). Writes(model.ResultPage{}). Returns(200, "OK", model.ResultPage{})) diff --git a/apps/job/services/job.go b/apps/job/services/job.go index 5dc8af1673a7bb3ab72322f12d156891f8fd7c73..cf79a574ac32e966c9f68e34266eae63d3546490 100644 --- a/apps/job/services/job.go +++ b/apps/job/services/job.go @@ -9,11 +9,11 @@ import ( type ( JobModel interface { Insert(data entity.SysJob) *entity.SysJob - FindOne(jobId int64) *entity.SysJob + FindOne(jobId string) *entity.SysJob FindListPage(page, pageSize int, data entity.SysJob) (*[]entity.SysJob, int64) FindList(data entity.SysJob) *[]entity.SysJob Update(data entity.SysJob) *entity.SysJob - Delete(jobId []int64) + Delete(jobId []string) FindByEntryId(entryId int64) *entity.SysJob RemoveAllEntryID() error RemoveEntryID(EntryID int) error @@ -25,7 +25,7 @@ type ( ) var JobModelDao JobModel = &jobModelImpl{ - table: `sys_jobs`, + table: `jobs`, } func (m *jobModelImpl) Insert(data entity.SysJob) *entity.SysJob { @@ -33,9 +33,9 @@ func (m *jobModelImpl) Insert(data entity.SysJob) *entity.SysJob { return &data } -func (m *jobModelImpl) FindOne(jobId int64) *entity.SysJob { +func (m *jobModelImpl) FindOne(jobId string) *entity.SysJob { resData := new(entity.SysJob) - err := global.Db.Table(m.table).Where("job_id = ?", jobId).First(resData).Error + err := global.Db.Table(m.table).Where("id = ?", jobId).First(resData).Error biz.ErrIsNil(err, "查询任务信息失败") return resData } @@ -52,10 +52,7 @@ func (m *jobModelImpl) FindListPage(page, pageSize int, data entity.SysJob) (*[] if data.Status != "" { db = db.Where("status = ?", data.Status) } - if data.JobGroup != "" { - db = db.Where("job_group = ?", data.JobGroup) - } - err := db.Where("delete_time IS NULL").Count(&total).Error + err := db.Count(&total).Error err = db.Order("create_time desc").Limit(pageSize).Offset(offset).Find(&list).Error biz.ErrIsNil(err, "查询任务分页信息失败") @@ -72,9 +69,6 @@ func (m *jobModelImpl) FindList(data entity.SysJob) *[]entity.SysJob { if data.Status != "" { db = db.Where("status = ?", data.Status) } - if data.JobGroup != "" { - db = db.Where("job_group = ?", data.JobGroup) - } err := db.Order("create_time desc").Find(&list).Error if err != nil { global.Log.Error("查询任务分页信息失败:" + err.Error()) @@ -87,8 +81,8 @@ func (m *jobModelImpl) Update(data entity.SysJob) *entity.SysJob { return &data } -func (m *jobModelImpl) Delete(jobIds []int64) { - err := global.Db.Table(m.table).Delete(&entity.SysJob{}, "job_id in (?)", jobIds).Error +func (m *jobModelImpl) Delete(jobIds []string) { + err := global.Db.Table(m.table).Delete(&entity.SysJob{}, "id in (?)", jobIds).Error biz.ErrIsNil(err, "删除操作日志信息失败") return } diff --git a/apps/log/services/log_job.go b/apps/job/services/log_job.go similarity index 43% rename from apps/log/services/log_job.go rename to apps/job/services/log_job.go index e3aa6e688c8208f4084ebff00b4d73cedc8b4018..5b4019861f28fc7b8ed281ccad802da049e6132e 100644 --- a/apps/log/services/log_job.go +++ b/apps/job/services/log_job.go @@ -2,34 +2,34 @@ package services import ( "github.com/XM-GO/PandaKit/biz" - "pandax/apps/log/entity" + "pandax/apps/job/entity" "pandax/pkg/global" ) type ( - LogJobModel interface { - Insert(data entity.LogJob) *entity.LogJob - FindListPage(page, pageSize int, data entity.LogJob) (*[]entity.LogJob, int64) + JobLogModel interface { + Insert(data entity.JobLog) *entity.JobLog + FindListPage(page, pageSize int, data entity.JobLog) (*[]entity.JobLog, int64) Delete(infoId []int64) DeleteAll() } - logJobModelImpl struct { + JobLogModelImpl struct { table string } ) -var LogJobModelDao LogJobModel = &logJobModelImpl{ - table: `log_jobs`, +var JobLogModelDao JobLogModel = &JobLogModelImpl{ + table: `job_logs`, } -func (m *logJobModelImpl) Insert(data entity.LogJob) *entity.LogJob { +func (m *JobLogModelImpl) Insert(data entity.JobLog) *entity.JobLog { global.Db.Table(m.table).Create(&data) return &data } -func (m *logJobModelImpl) FindListPage(page, pageSize int, data entity.LogJob) (*[]entity.LogJob, int64) { - list := make([]entity.LogJob, 0) +func (m *JobLogModelImpl) FindListPage(page, pageSize int, data entity.JobLog) (*[]entity.JobLog, int64) { + list := make([]entity.JobLog, 0) var total int64 = 0 offset := pageSize * (page - 1) db := global.Db.Table(m.table) @@ -37,25 +37,22 @@ func (m *logJobModelImpl) FindListPage(page, pageSize int, data entity.LogJob) ( if data.Status != "" { db = db.Where("status = ?", data.Status) } - if data.JobGroup != "" { - db = db.Where("job_group = ?", data.JobGroup) - } if data.Name != "" { db = db.Where("name like ?", "%"+data.Name+"%") } - err := db.Where("delete_time IS NULL").Count(&total).Error - err = db.Order("log_id desc").Limit(pageSize).Offset(offset).Find(&list).Error + err := db.Count(&total).Error + err = db.Order("create_time desc").Limit(pageSize).Offset(offset).Find(&list).Error biz.ErrIsNil(err, "查询登录分页日志信息失败") return &list, total } -func (m *logJobModelImpl) Delete(logIds []int64) { - err := global.Db.Table(m.table).Delete(&entity.LogJob{}, "log_id in (?)", logIds).Error +func (m *JobLogModelImpl) Delete(logIds []int64) { + err := global.Db.Table(m.table).Delete(&entity.JobLog{}, "id in (?)", logIds).Error biz.ErrIsNil(err, "删除登录日志信息失败") return } -func (m *logJobModelImpl) DeleteAll() { +func (m *JobLogModelImpl) DeleteAll() { global.Db.Exec("DELETE FROM log_jobs") } diff --git a/apps/rule/api/rulechain.go b/apps/rule/api/rulechain.go new file mode 100644 index 0000000000000000000000000000000000000000..07f40355131a110e7a4cc5185361236b0d97cebe --- /dev/null +++ b/apps/rule/api/rulechain.go @@ -0,0 +1,106 @@ +package api + +import ( + "context" + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/kakuilan/kgo" + "pandax/apps/rule/entity" + "pandax/apps/rule/services" + "pandax/pkg/rule_engine" + "pandax/pkg/rule_engine/message" + "pandax/pkg/rule_engine/nodes" + "strings" +) + +type RuleChainApi struct { + RuleChainApp services.RuleChainModel +} + +func (r *RuleChainApi) GetNodeLabels(rc *restfulx.ReqCtx) { + rc.ResData = nodes.GetCategory() +} +func (r *RuleChainApi) RuleChainTest(rc *restfulx.ReqCtx) { + code := restfulx.QueryParam(rc, "code") + instance, _ := rule_engine.NewRuleChainInstance([]byte(code)) + newMessage := message.NewMessage() + newMessage.SetMetadata(message.NewMetadata()) + instance.StartRuleChain(context.Background(), newMessage) + rc.ResData = []map[string]interface{}{} +} + +// GetRuleChainList WorkInfo列表数据 +func (p *RuleChainApi) GetRuleChainList(rc *restfulx.ReqCtx) { + data := entity.RuleChain{} + pageNum := restfulx.QueryInt(rc, "pageNum", 1) + pageSize := restfulx.QueryInt(rc, "pageSize", 10) + data.RuleName = restfulx.QueryParam(rc, "ruleName") + list, total := p.RuleChainApp.FindListPage(pageNum, pageSize, data) + + rc.ResData = model.ResultPage{ + Total: total, + PageNum: int64(pageNum), + PageSize: int64(pageNum), + Data: list, + } +} + +func (p *RuleChainApi) GetRuleChainListLabel(rc *restfulx.ReqCtx) { + data := entity.RuleChain{} + data.RuleName = restfulx.QueryParam(rc, "ruleName") + list := p.RuleChainApp.FindListBaseLabel(data) + rc.ResData = list +} + +// GetRuleChain 获取规则链 +func (p *RuleChainApi) GetRuleChain(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + rc.ResData = p.RuleChainApp.FindOne(id) +} + +// InsertRuleChain 添加规则链 +func (p *RuleChainApi) InsertRuleChain(rc *restfulx.ReqCtx) { + var data entity.RuleChain + restfulx.BindJsonAndValid(rc, &data) + data.Id = kgo.KStr.Uniqid("rule_") + data.Owner = rc.LoginAccount.UserName + p.RuleChainApp.Insert(data) +} + +// UpdateRuleChain 修改规则链 +func (p *RuleChainApi) UpdateRuleChain(rc *restfulx.ReqCtx) { + var data entity.RuleChain + restfulx.BindJsonAndValid(rc, &data) + + p.RuleChainApp.Update(data) +} + +// DeleteRuleChain 删除规则链 +func (p *RuleChainApi) DeleteRuleChain(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + one := p.RuleChainApp.FindOne(id) + biz.IsTrue(!(one.Root == "1"), "主链不可被删除") + ids := strings.Split(id, ",") + p.RuleChainApp.Delete(ids) +} + +// CloneRuleChain 克隆规则链 +func (p *RuleChainApi) CloneRuleChain(rc *restfulx.ReqCtx) { + id := restfulx.PathParam(rc, "id") + one := p.RuleChainApp.FindOne(id) + one.RuleName = one.RuleName + "-克隆" + one.Id = kgo.KStr.Uniqid("rule_") + one.Root = "0" + p.RuleChainApp.Insert(*one) +} + +// UpdateRuleRoot 修改根链 +func (p *RuleChainApi) UpdateRuleRoot(rc *restfulx.ReqCtx) { + var rule entity.RuleChain + restfulx.BindJsonAndValid(rc, &rule) + // 修改主链为普通链 + p.RuleChainApp.UpdateByRoot() + // 修改当前链为主链 + p.RuleChainApp.Update(rule) +} diff --git a/apps/rule/entity/rulechain.go b/apps/rule/entity/rulechain.go new file mode 100644 index 0000000000000000000000000000000000000000..3d91aabbba6b9648e959ed60a928afc88544cb04 --- /dev/null +++ b/apps/rule/entity/rulechain.go @@ -0,0 +1,42 @@ +package entity + +import ( + "pandax/pkg/global" + "time" +) + +type RuleChainBaseLabel struct { + Id string `json:"id"` + Root string `json:"root"` + RuleName string `json:"ruleName"` +} + +type RuleChainBase struct { + global.BaseAuthModel + Root string `json:"root" gorm:"comment:是否根节点,1 根链 0 普通链"` + RuleName string `gorm:"ruleName;type:varchar(50);comment:名称" json:"ruleName"` + RuleBase64 string `gorm:"ruleBase64;type:longtext;comment:Base64缩略图" json:"ruleBase64"` //缩略图 base64 + RuleRemark string `gorm:"ruleRemark;type:varchar(256);comment:说明" json:"ruleRemark"` +} + +type RuleChain struct { + RuleChainBase + RuleDataJson string `gorm:"ruleDataJson;type:longtext;comment:Json数据" json:"ruleDataJson"` +} + +func (RuleChain) TableName() string { + return "rule_chain" +} + +type RuleChainMsgLog struct { + MessageId string `json:"message_id"` + MsgType string `json:"msg_type"` + DeviceName string `json:"device_name"` + Ts time.Time `json:"ts"` + Content string `json:"content"` + CreatedAt time.Time // 创建时间 +} + +func (RuleChainMsgLog) TableName() string { + return "rule_chain_msg_log" +} diff --git a/apps/rule/entity/rulechain_data.go b/apps/rule/entity/rulechain_data.go new file mode 100644 index 0000000000000000000000000000000000000000..91371bd4906bc1f92a625f0b157c4864aa144090 --- /dev/null +++ b/apps/rule/entity/rulechain_data.go @@ -0,0 +1,24 @@ +package entity + +import ( + "encoding/json" +) + +type RuleDataJson struct { + LfData struct { + GlobalColor string `json:"globalColor"` + DataCode map[string]interface{} `json:"dataCode"` + OpenRule bool `json:"openRule"` + Setting map[string]interface{} `json:"setting"` + } `json:"lfData"` +} + +// 序列化 +func (m *RuleDataJson) MarshalBinary() (data []byte, err error) { + return json.Marshal(m) +} + +// 反序列化 +func (m *RuleDataJson) UnmarshalBinary(data []byte) error { + return json.Unmarshal(data, m) +} diff --git a/apps/rule/router/rulechain.go b/apps/rule/router/rulechain.go new file mode 100644 index 0000000000000000000000000000000000000000..8a50b413bcd7070e3194c2d4eae02461960b750d --- /dev/null +++ b/apps/rule/router/rulechain.go @@ -0,0 +1,102 @@ +package router + +import ( + "github.com/XM-GO/PandaKit/model" + "github.com/XM-GO/PandaKit/restfulx" + restfulspec "github.com/emicklei/go-restful-openapi/v2" + "github.com/emicklei/go-restful/v3" + "pandax/apps/rule/api" + "pandax/apps/rule/entity" + "pandax/apps/rule/services" +) + +func InitRuleChainRouter(container *restful.Container) { + s := &api.RuleChainApi{ + RuleChainApp: services.RuleChainModelDao, + } + + ws := new(restful.WebService) + ws.Path("/rule/chain").Produces(restful.MIME_JSON) + tags := []string{"rulechain"} + + ws.Route(ws.GET("/nodeLabels").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithNeedCasbin(false).WithLog("获取所有节点标签").Handle(s.GetNodeLabels) + }). + Doc("获取所有节点标签"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/test").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithNeedCasbin(false).WithLog("测试规则引擎").Handle(s.RuleChainTest) + }). + Doc("测试规则引擎"). + Param(ws.QueryParameter("code", "流程代码").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags)) + + ws.Route(ws.GET("/list").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取规则引擎分页列表").Handle(s.GetRuleChainList) + }). + Doc("获取规则引擎分页列表"). + Param(ws.QueryParameter("pageNum", "页数").Required(true).DataType("int")). + Param(ws.QueryParameter("pageSize", "每页条数").Required(true).DataType("int")). + Param(ws.QueryParameter("ruleName", "规则名").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(model.ResultPage{}). + Returns(200, "OK", model.ResultPage{})) + + ws.Route(ws.GET("/list/label").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取规则引擎Label列表").Handle(s.GetRuleChainListLabel) + }). + Doc("获取规则引擎Label列表"). + Param(ws.QueryParameter("ruleName", "规则名").Required(false).DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Returns(200, "OK", entity.RuleChainBaseLabel{})) + + ws.Route(ws.GET("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("获取规则引擎信息").Handle(s.GetRuleChain) + }). + Doc("获取规则引擎信息"). + Param(ws.PathParameter("id", "Id").DataType("string")). + Metadata(restfulspec.KeyOpenAPITags, tags). + Writes(entity.RuleChain{}). // on the response + Returns(200, "OK", entity.RuleChain{}). + Returns(404, "Not Found", nil)) + + ws.Route(ws.POST("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("添加规则引擎信息").Handle(s.InsertRuleChain) + }). + Doc("添加规则引擎信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.RuleChain{})) + + ws.Route(ws.PUT("").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改规则引擎信息").Handle(s.UpdateRuleChain) + }). + Doc("修改规则引擎信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Reads(entity.RuleChain{})) + + ws.Route(ws.DELETE("/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("删除规则引擎信息").Handle(s.DeleteRuleChain) + }). + Doc("删除规则引擎信息"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "多id 1,2,3").DataType("string"))) + + ws.Route(ws.POST("/clone/{id}").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("克隆规则引擎").Handle(s.CloneRuleChain) + }). + Doc("克隆规则引擎"). + Metadata(restfulspec.KeyOpenAPITags, tags). + Param(ws.PathParameter("id", "id").DataType("string"))) + + ws.Route(ws.PUT("/changeRoot").To(func(request *restful.Request, response *restful.Response) { + restfulx.NewReqCtx(request, response).WithLog("修改规则链").Handle(s.UpdateRuleRoot) + }). + Doc("修改规则链"). + Metadata(restfulspec.KeyOpenAPITags, tags)) + + container.Add(ws) + +} diff --git a/apps/rule/services/rulechain.go b/apps/rule/services/rulechain.go new file mode 100644 index 0000000000000000000000000000000000000000..35088ba665e54a50efd8a708f15f655919fee847 --- /dev/null +++ b/apps/rule/services/rulechain.go @@ -0,0 +1,130 @@ +// ========================================================================== +// 生成日期:2023-03-29 20:01:11 +0800 CST +// 生成路径: apps/visual/services/rulechain.go +// 生成人:panda +// ========================================================================== + +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "log" + "pandax/apps/rule/entity" + "pandax/pkg/events" + "pandax/pkg/global" +) + +type ( + RuleChainModel interface { + Insert(data entity.RuleChain) *entity.RuleChain + FindOne(id string) *entity.RuleChain + FindOneByRoot() *entity.RuleChain + UpdateByRoot() + FindListPage(page, pageSize int, data entity.RuleChain) (*[]entity.RuleChainBase, int64) + FindList(data entity.RuleChain) *[]entity.RuleChain + FindListBaseLabel(data entity.RuleChain) *[]entity.RuleChainBaseLabel + Update(data entity.RuleChain) *entity.RuleChain + Delete(ids []string) + } + + ruleChainModelImpl struct { + table string + } +) + +var RuleChainModelDao RuleChainModel = &ruleChainModelImpl{ + table: `rule_chain`, +} + +func (m *ruleChainModelImpl) Insert(data entity.RuleChain) *entity.RuleChain { + err := global.Db.Table(m.table).Create(&data).Error + log.Println(err) + biz.ErrIsNil(err, "添加规则链失败") + return &data +} + +func (m *ruleChainModelImpl) FindOne(id string) *entity.RuleChain { + resData := new(entity.RuleChain) + db := global.Db.Table(m.table).Where("id = ?", id) + err := db.First(resData).Error + + biz.ErrIsNil(err, "查询规则链失败") + return resData +} + +func (m *ruleChainModelImpl) FindOneByRoot() *entity.RuleChain { + resData := new(entity.RuleChain) + db := global.Db.Table(m.table).Where("root = ?", 1) + err := db.First(resData).Error + biz.ErrIsNil(err, "查询规则链失败") + return resData +} + +// UpdateByRoot 修改主链为普通链 +func (m *ruleChainModelImpl) UpdateByRoot() { + biz.ErrIsNil(global.Db.Table(m.table).Where("root = ?", "1").Update("root", "0").Error, "修改规则链失败") +} + +func (m *ruleChainModelImpl) FindListPage(page, pageSize int, data entity.RuleChain) (*[]entity.RuleChainBase, int64) { + list := make([]entity.RuleChainBase, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.RuleName != "" { + db = db.Where("rule_name like ?", "%"+data.RuleName+"%") + } + if data.RuleRemark != "" { + db = db.Where("rule_remark like ?", "%"+data.RuleRemark+"%") + } + err := db.Count(&total).Error + err = db.Order("create_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询规则链分页列表失败") + return &list, total +} + +func (m *ruleChainModelImpl) FindList(data entity.RuleChain) *[]entity.RuleChain { + list := make([]entity.RuleChain, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.RuleName != "" { + db = db.Where("rule_name like ?", "%"+data.RuleName+"%") + } + if data.RuleRemark != "" { + db = db.Where("rule_remark like ?", "%"+data.RuleRemark+"%") + } + biz.ErrIsNil(db.Order("create_time").Find(&list).Error, "查询规则链列表失败") + return &list +} + +func (m *ruleChainModelImpl) FindListBaseLabel(data entity.RuleChain) *[]entity.RuleChainBaseLabel { + list := make([]entity.RuleChainBaseLabel, 0) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Owner != "" { + db = db.Where("owner = ?", data.Owner) + } + if data.RuleName != "" { + db = db.Where("rule_name like ?", "%"+data.RuleName+"%") + } + biz.ErrIsNil(db.Find(&list).Error, "查询规则链列表失败") + return &list +} + +func (m *ruleChainModelImpl) Update(data entity.RuleChain) *entity.RuleChain { + if data.RuleDataJson != "" { + go global.EventEmitter.Emit(events.ProductChainRuleEvent, data.Id, data.RuleDataJson) + } + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改规则链失败") + return &data +} + +func (m *ruleChainModelImpl) Delete(ids []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.RuleChain{}, "id in (?)", ids).Error, "删除规则链失败") +} diff --git a/apps/rule/services/rulechain_log.go b/apps/rule/services/rulechain_log.go new file mode 100644 index 0000000000000000000000000000000000000000..2ac79a76dde999fc5ffff9f07cfe3dbdd3f76d50 --- /dev/null +++ b/apps/rule/services/rulechain_log.go @@ -0,0 +1,61 @@ +// ========================================================================== +// 生成日期:2023-03-29 20:01:11 +0800 CST +// 生成路径: apps/visual/services/rulechain.go +// 生成人:panda +// ========================================================================== + +package services + +import ( + "github.com/XM-GO/PandaKit/biz" + "pandax/apps/rule/entity" + "pandax/pkg/global" +) + +type ( + RuleChainMsgLogModel interface { + Insert(data entity.RuleChainMsgLog) *entity.RuleChainMsgLog + FindListPage(page, pageSize int, data entity.RuleChainMsgLog) (*[]entity.RuleChainMsgLog, int64) + Delete(ids []string) + } + + ruleChainLogModelImpl struct { + table string + } +) + +var RuleChainMsgLogModelDao RuleChainMsgLogModel = &ruleChainLogModelImpl{ + table: `rule_chain_msg_log`, +} + +func (m *ruleChainLogModelImpl) Insert(data entity.RuleChainMsgLog) *entity.RuleChainMsgLog { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加规则链失败") + return &data +} + +func (m *ruleChainLogModelImpl) FindListPage(page, pageSize int, data entity.RuleChainMsgLog) (*[]entity.RuleChainMsgLog, int64) { + list := make([]entity.RuleChainMsgLog, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + db.Where("delete_time IS NULL") + if data.DeviceName != "" { + db = db.Where("device_name = ?", data.DeviceName) + } + if data.MessageId != "" { + db = db.Where("message_id = ?", data.MessageId) + } + if data.MsgType != "" { + db = db.Where("msg_type = ?", data.MsgType) + } + err := db.Count(&total).Error + err = db.Order("create_at").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询规则链分页列表失败") + return &list, total +} + +func (m *ruleChainLogModelImpl) Delete(ids []string) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.RuleChainMsgLog{}, "id in (?)", ids).Error, "删除规则链失败") +} diff --git a/apps/system/api/api.go b/apps/system/api/api.go index 21ab44894744341bd7e39fa5a223def5288a9d20..63e2a540df164252feb558927ceedb28b67f0531 100644 --- a/apps/system/api/api.go +++ b/apps/system/api/api.go @@ -8,7 +8,6 @@ import ( entity "pandax/apps/system/entity" services "pandax/apps/system/services" "pandax/pkg/global" - "strconv" ) type SystemApiApi struct { @@ -61,7 +60,6 @@ func (s *SystemApiApi) GetAllApis(rc *restfulx.ReqCtx) { func (s *SystemApiApi) GetPolicyPathByRoleId(rc *restfulx.ReqCtx) { roleKey := rc.Request.QueryParameter("roleKey") - tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} - rc.ResData = ca.GetPolicyPathByRoleId(tenantId, roleKey) + rc.ResData = ca.GetPolicyPathByRoleId(roleKey) } diff --git a/apps/system/api/role.go b/apps/system/api/role.go index a6ba174dba5203a20af75dbb00c9fbbcbaf97fb1..19075444f71f5c8cee3aa90db2c2191f33338e60 100644 --- a/apps/system/api/role.go +++ b/apps/system/api/role.go @@ -11,7 +11,6 @@ import ( entity "pandax/apps/system/entity" services "pandax/apps/system/services" "pandax/pkg/global" - "strconv" ) type RoleApi struct { @@ -63,9 +62,8 @@ func (r *RoleApi) InsertRole(rc *restfulx.ReqCtx) { role.RoleId = insert.RoleId r.RoleMenuApp.Insert(insert.RoleId, role.MenuIds) //添加权限 - tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} - ca.UpdateCasbin(tenantId, role.RoleKey, role.ApiIds) + ca.UpdateCasbin(role.RoleKey, role.ApiIds) } // UpdateRole 修改用户角色 @@ -80,9 +78,8 @@ func (r *RoleApi) UpdateRole(rc *restfulx.ReqCtx) { // 添加角色菜单绑定 r.RoleMenuApp.Insert(role.RoleId, role.MenuIds) //修改api权限 - tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} - ca.UpdateCasbin(tenantId, role.RoleKey, role.ApiIds) + ca.UpdateCasbin(role.RoleKey, role.ApiIds) } // UpdateRoleStatus 修改用户角色状态 diff --git a/apps/system/api/upload.go b/apps/system/api/upload.go index d0176e5cc8fe709aa734d481ff83da72008766bf..8e5261787aa14dad37ab2fa5882f802cd7844f92 100644 --- a/apps/system/api/upload.go +++ b/apps/system/api/upload.go @@ -3,33 +3,26 @@ package api import ( "fmt" "github.com/XM-GO/PandaKit/biz" - filek "github.com/XM-GO/PandaKit/file" "github.com/XM-GO/PandaKit/restfulx" - "github.com/kakuilan/kgo" "net/http" "os" + "pandax/pkg/tool" "path" - "strings" - "time" ) type UploadApi struct{} const filePath = "uploads/file" +// UploadImage 图片上传 // UploadImage 图片上传 func (up *UploadApi) UploadImage(rc *restfulx.ReqCtx) { - _, fileHeader, err := rc.Request.Request.FormFile("imagefile") + _, fileHeader, err := rc.Request.Request.FormFile("file") biz.ErrIsNil(err, "请传入文件") - ext := path.Ext(fileHeader.Filename) - // 读取文件名并加密 - name := strings.TrimSuffix(fileHeader.Filename, ext) - name = kgo.KStr.Md5(name, 32) - // 拼接新文件名 - filename := name + "_" + time.Now().Format("20060102150405") + ext - filek.SaveUploadedFile(fileHeader, fmt.Sprintf("%s/%s", filePath, filename)) + local := &tool.Local{Path: filePath} + link, fileName, err := local.UploadFile(fileHeader) biz.ErrIsNil(err, "文件上传失败") - rc.ResData = map[string]string{"fileName": name} + rc.ResData = map[string]string{"fileName": fileName, "filePath": link} } func (up *UploadApi) GetImage(rc *restfulx.ReqCtx) { diff --git a/config.yml b/config.yml index eef67499a1c9a70510cb578f1ecb970ede0e0204..4d59861deb40b365e1c8332c9b9628fa658f6b04 100644 --- a/config.yml +++ b/config.yml @@ -5,8 +5,12 @@ app: server: # debug release test model: release - port: 7788 + port: 8889 + # iothub使用的rpc端口 9000 9001 可能与minio端口冲突 + grpc-port: 9001 cors: true + # 数据上报 队列池 + queue-num: 1000 # 接口限流 rate: enable: true @@ -23,39 +27,70 @@ jwt: key: PandaX # 过期时间单位秒 7天 expire-time: 604800 - +#数据上报并发识别任务数量限制 +queue: + enable: false + num: 3000 redis: host: 127.0.0.1 + password: root port: 6379 mysql: host: 127.0.0.1:3306 username: root - password: 123456 - db-name: pandax + password: '!MyEMS1' + db-name: pandax_iot config: charset=utf8&loc=Local&parseTime=true +# mini0 +oss: + endpoint: 127.0.0.1:9000 + accessKey: minioadmin + secretKey: minioadmin + bucketName: pandaxiot + useSSL: false -postgresql: - username: postgres - password: 123456 - host: 127.0.0.1 - port: 5432 - db-name: pandax - max-idle-conns: 10 - max-open-conns: 10 +taos: + username: "root" + password: "taosdata" + host: "127.0.0.1:6041" + database: "iot" + config: "" + +mqtt: + broker: 127.0.0.1:1883 + qos: 1 + username: pandax + password: pandax casbin: model-path: './resource/rbac_model.conf' gen: # 代码生成读取的数据库名称 - dbname: pandax + dbname: pandax_iot # 代码生成是使用前端代码存放位置,需要指定到src文件夹,相对路径 frontpath: ../PandaUi/src log: # 日志等级, trace, debug, info, warn, error, fatal level: info -# file: -# path: ./ -# name: panda_log.log \ No newline at end of file + file: + path: ./ + name: panda_log.log + +# 视频服务器使用的全局配置 +global: + http: + listenaddr: :8801 # 网关地址,用于访问API + listenaddrtls: :8443 # 用于HTTPS方式访问API的端口配置 + +gb28181: + #sip服务器地址 默认 自动适配设备网段 + sipip: "" + serial: "34020000002000000001" + realm: "3402000000" + password: "pandax" + #sip服务器端口 + port: + sip: udp:5060 \ No newline at end of file diff --git a/go.mod b/go.mod index f74e611e48c650100b9bf5c90fb2ab5743b0ce48..c2f6a16e38f201673cdf04b7f14c8074f88950d2 100644 --- a/go.mod +++ b/go.mod @@ -3,42 +3,83 @@ module pandax go 1.18 require ( - github.com/XM-GO/PandaKit v0.0.0-20220902065259-efd83b5ba4b2 + github.com/Shopify/sarama v1.38.1 + github.com/XM-GO/PandaKit v0.0.0-20230628055017-c47e7aa81cd4 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/didip/tollbooth v4.0.2+incompatible + github.com/dop251/goja v0.0.0-20230304130813-e2f543bf4b4c + github.com/eclipse/paho.mqtt.golang v1.4.2 github.com/emicklei/go-restful-openapi/v2 v2.9.0 github.com/emicklei/go-restful/v3 v3.9.0 github.com/go-openapi/spec v0.20.6 - github.com/gorilla/websocket v1.4.2 + github.com/google/uuid v1.3.0 + github.com/gorilla/websocket v1.5.0 + github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/kakuilan/kgo v0.1.8 + github.com/mitchellh/mapstructure v1.5.0 github.com/mssola/user_agent v0.5.3 + github.com/nats-io/nats.go v1.25.0 github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.5.0 - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 + github.com/taosdata/driver-go/v3 v3.5.0 + github.com/xuri/excelize/v2 v2.7.1 + golang.org/x/crypto v0.11.0 google.golang.org/grpc v1.48.0 + google.golang.org/protobuf v1.28.0 gorm.io/gorm v1.22.3 + m7s.live/engine/v4 v4.13.8 + m7s.live/plugin/gb28181/v4 v4.3.9 + m7s.live/plugin/jessica/v4 v4.2.1 + m7s.live/plugin/rtmp/v4 v4.2.4 ) require ( github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible // indirect + github.com/bluenviron/mediacommon v0.7.0 // indirect github.com/brianvoe/gofakeit/v6 v6.0.2 // indirect github.com/casbin/casbin/v2 v2.37.4 // indirect github.com/casbin/gorm-adapter/v3 v3.4.6 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cnotch/ipchub v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/denisbrodbeck/machineid v1.0.1 // indirect github.com/denisenkom/go-mssqldb v0.11.0 // indirect - github.com/go-ole/go-ole v1.2.5 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/eapache/go-resiliency v1.3.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/ghettovoice/gosip v0.0.0-20230802091127-d58873a3fe44 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.15 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.8.0 // indirect github.com/go-redis/redis v6.15.9+incompatible // indirect - github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/gobwas/httphead v0.1.0 // indirect + github.com/gobwas/pool v0.2.1 // indirect + github.com/gobwas/ws v1.2.1 // indirect github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-querystring v1.0.0 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.10.1 // indirect @@ -48,40 +89,85 @@ require ( github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect github.com/jackc/pgtype v1.9.0 // indirect github.com/jackc/pgx/v4 v4.14.0 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.2 // indirect - github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect github.com/lib/pq v1.10.4 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/mailru/easyjson v0.7.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mcuadros/go-defaults v1.2.0 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/minio/md5-simd v1.1.2 // indirect + github.com/minio/minio-go/v7 v7.0.36 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mojocn/base64Captcha v1.3.5 // indirect - github.com/mozillazg/go-httpheader v0.2.1 // indirect - github.com/nxadm/tail v1.4.8 // indirect + github.com/nats-io/nats-server/v2 v2.9.15 // indirect + github.com/nats-io/nkeys v0.4.4 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + github.com/onsi/ginkgo/v2 v2.2.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pierrec/lz4/v4 v4.1.17 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtp v1.8.0 // indirect + github.com/pion/webrtc/v3 v3.1.56 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect + github.com/q191201771/naza v0.30.8 // indirect github.com/qiniu/go-sdk/v7 v7.11.0 // indirect - github.com/richardlehane/mscfb v1.0.3 // indirect - github.com/richardlehane/msoleps v1.0.1 // indirect + github.com/quic-go/qtls-go1-18 v0.2.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.0 // indirect + github.com/quic-go/qtls-go1-20 v0.1.0 // indirect + github.com/quic-go/quic-go v0.32.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/richardlehane/mscfb v1.0.4 // indirect + github.com/richardlehane/msoleps v1.0.3 // indirect + github.com/rs/xid v1.4.0 // indirect + github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect + github.com/shirou/gopsutil/v3 v3.22.11 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/tencentyun/cos-go-sdk-v5 v0.7.33 // indirect - github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 // indirect - github.com/xuri/excelize/v2 v2.4.1 // indirect - golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect - golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect + github.com/tevino/abool v1.2.0 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect + github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect + github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect + github.com/yapingcat/gomedia v0.0.0-20230727105416-c491e66c9d2a // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect + golang.org/x/image v0.5.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect - google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect gorm.io/driver/mysql v1.2.0 // indirect gorm.io/driver/postgres v1.2.3 // indirect gorm.io/driver/sqlserver v1.2.1 // indirect gorm.io/plugin/dbresolver v1.1.0 // indirect + m7s.live/plugin/ps/v4 v4.0.9 // indirect ) diff --git a/go.sum b/go.sum index a0cb2822038746b342e26a80ccfbb2bb0276bc91..920c02afacc76a861a2f6443a84774d6b25e2dd4 100644 --- a/go.sum +++ b/go.sum @@ -7,15 +7,20 @@ github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030I github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +github.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A= +github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g= +github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/XM-GO/PandaKit v0.0.0-20220902065259-efd83b5ba4b2 h1:5wn9dKcH0JbmeObnxPMjOhA5nxcrCWR6O8WPXGQtLt4= -github.com/XM-GO/PandaKit v0.0.0-20220902065259-efd83b5ba4b2/go.mod h1:YKo/VaBJAHZA0tYYZqataeAaTJcduMncf7BfZgdS01s= +github.com/XM-GO/PandaKit v0.0.0-20230628055017-c47e7aa81cd4 h1:SlGUf970WIctMhu8ZZBNsZfY1bdCbGGo9wLm5V0ceeM= +github.com/XM-GO/PandaKit v0.0.0-20230628055017-c47e7aa81cd4/go.mod h1:iyVx5byF4Z//dBpXMy22ZtgSnQAN/U9qjwGyU02QfSA= github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible h1:ht2+VfbXtNLGhCsnTMc6/N26nSTBK6qdhktjYyjJQkk= github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/bluenviron/mediacommon v0.7.0 h1:dJWLLL9oDbAqfK8KuNfnDUQwNbeMAtGeRjZc9Vo95js= +github.com/bluenviron/mediacommon v0.7.0/go.mod h1:wuLJdxcITiSPgY1MvQqrX+qPlKmNfeV9wNvXth5M98I= github.com/brianvoe/gofakeit/v6 v6.0.2 h1:MDvplMAKJMcKZDwQvsIbhT7BV/8UF/3EEy2n14ynUyA= github.com/brianvoe/gofakeit/v6 v6.0.2/go.mod h1:palrJUk4Fyw38zIFB/uBZqsgzW5VsNllhHKKwAebzew= github.com/casbin/casbin/v2 v2.37.4 h1:RWSKPjaZ8JlOBlcW1bI/FTII8OPxvQ9jVy9JwyNL6DQ= @@ -24,6 +29,11 @@ github.com/casbin/gorm-adapter/v3 v3.4.6 h1:JuLN3/CBTPPlvNyQqY3uXt4Zqnt+hs2sM353 github.com/casbin/gorm-adapter/v3 v3.4.6/go.mod h1:6mIYgpByH/uSkfCv4G/vr/12cVZc3rXBQ9KrqS9oTUU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -31,6 +41,14 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cnotch/apirouter v0.0.0-20200731232942-89e243a791f3/go.mod h1:5deJPLON/x/s2dLOQfuKS0lenhOIT4xX0pvtN/OEIuY= +github.com/cnotch/ipchub v1.1.0 h1:hH0lh2mU3AZXPiqMwA0pdtqrwo7PFIMRGush9OobMUs= +github.com/cnotch/ipchub v1.1.0/go.mod h1:2PbeBs2q2VxxTVCn1eYCDwpAWuVXbq1+N0FU7GimOH4= +github.com/cnotch/loader v0.0.0-20200405015128-d9d964d09439/go.mod h1:oWpDagHB6p+Kqqq7RoRZKyC4XAXft50hR8pbTxdbYYs= +github.com/cnotch/queue v0.0.0-20200326024423-6e88bdbf2ad4/go.mod h1:zOssjAlNusOxvtaqT+EMA+Iyi8rrtKr4/XfzN1Fgoeg= +github.com/cnotch/queue v0.0.0-20201224060551-4191569ce8f6/go.mod h1:zOssjAlNusOxvtaqT+EMA+Iyi8rrtKr4/XfzN1Fgoeg= +github.com/cnotch/scheduler v0.0.0-20200522024700-1d2da93eefc5/go.mod h1:F4GE3SZkJZ8an1Y0ZCqvSM3jeozNuKzoC67erG1PhIo= +github.com/cnotch/xlog v0.0.0-20201208005456-cfda439cd3a0/go.mod h1:RW9oHsR79ffl3sR3yMGgxYupMn2btzdtJUwoxFPUE5E= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -41,30 +59,60 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= +github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI= github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/didip/tollbooth v4.0.2+incompatible h1:fVSa33JzSz0hoh2NxpwZtksAzAgd7zjmGO20HCZtF4M= github.com/didip/tollbooth v4.0.2+incompatible/go.mod h1:A9b0665CE6l1KmzpDws2++elm/CsuWBMa5Jv4WY0PEY= +github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca h1:cTTdXpkQ1aVbOOmHwdwtYuwUZcQtcMrleD1UXLWhAq8= +github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca/go.mod h1:W+3LQaEkN8qAwwcw0KC546sUEnX86GIT8CcMLZC4mG0= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230304130813-e2f543bf4b4c h1:/utv6nmTctV6OVgfk5+O6lEMEWL+6KJy4h9NZ5fnkQQ= +github.com/dop251/goja v0.0.0-20230304130813-e2f543bf4b4c/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.3.0 h1:RRL0nge+cWGlxXbUzJ7yMcq6w2XBEr19dCN6HECGaT0= +github.com/eapache/go-resiliency v1.3.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= +github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 h1:8yY/I9ndfrgrXUbOGObLHKBR4Fl3nZXwM2c7OYTT8hM= +github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4= +github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= github.com/emicklei/go-restful-openapi/v2 v2.9.0 h1:djsWqjhI0EVYfkLCCX6jZxUkLmYUq2q9tt09ZbixfyE= github.com/emicklei/go-restful-openapi/v2 v2.9.0/go.mod h1:VKNgZyYviM1hnyrjD9RDzP2RuE94xTXxV+u6MGN4v4k= github.com/emicklei/go-restful/v3 v3.7.3/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emitter-io/address v1.0.0/go.mod h1:GfZb5+S/o8694B1GMGK2imUYQyn2skszMvGNA5D84Ug= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/ghettovoice/gosip v0.0.0-20230802091127-d58873a3fe44 h1:m4/46V6uAJ95CLimMRHJjiH5psW1JuL+iLeUBzF2r70= +github.com/ghettovoice/gosip v0.0.0-20230802091127-d58873a3fe44/go.mod h1:rlD1yLOErWYohWTryG/2bTTpmzB79p52ntLA/uIFXeI= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -77,18 +125,36 @@ github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k= github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk= github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/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 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.1.0-rc.1/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= +github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= +github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= @@ -97,8 +163,9 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= @@ -113,6 +180,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -120,18 +189,32 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8 h1:4Jk58quTZmzJcTrLlbB5L1Q6qXu49EIjCReWxcBFWKo= +github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8/go.mod h1:medl9/CfYoQlqAXtAARmMW5dAX2UOdwwkhaszYPk0AM= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -184,6 +267,18 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE/Tq8= +github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -198,7 +293,16 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kakuilan/kgo v0.1.8 h1:b9UfGYNbUpWjPheOEgu/MsWUVDNWbcSit6BbNsBAPl0= github.com/kakuilan/kgo v0.1.8/go.mod h1:S9driqss6OluzqiOfUx7xN8nw0H6bFu5v7c19P09RRc= +github.com/kelindar/process v0.0.0-20170730150328-69a29e249ec3/go.mod h1:+lTCLnZFXOkqwD8sLPl6u4erAc0cP8wFegQHfipz7KE= +github.com/kelindar/rate v1.0.0/go.mod h1:AjT4G+hTItNwt30lucEGZIz8y7Uk5zPho6vurIZ+1Es= +github.com/kelindar/tcp v1.0.0/go.mod h1:JB5hj1cshLU60XrLij2BBxW3JQ4hOye8vqbyvuKb52k= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= +github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -210,6 +314,7 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -217,15 +322,40 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk56oZtc= +github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfulPaGDWIVeCWY= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.36 h1:KPzAl8C6jcRFEUsGUHR6deRivvKATPNZThzi7D9y/sc= +github.com/minio/minio-go/v7 v7.0.36/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -236,32 +366,98 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= -github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= -github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/mssola/user_agent v0.5.3 h1:lBRPML9mdFuIZgI2cmlQ+atbpJdLdeVl2IDodjBR578= github.com/mssola/user_agent v0.5.3/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= +github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= +github.com/nats-io/nats-server/v2 v2.9.15 h1:MuwEJheIwpvFgqvbs20W8Ish2azcygjf4Z0liVu2I4c= +github.com/nats-io/nats-server/v2 v2.9.15/go.mod h1:QlCTy115fqpx4KSOPFIxSV7DdI6OxtZsGOL1JLdeRlE= +github.com/nats-io/nats.go v1.25.0 h1:t5/wCPGciR7X3Mu8QOi4jiJaXaWM8qtkLu4lzGZvYHE= +github.com/nats-io/nats.go v1.25.0/go.mod h1:D2WALIhz7V8M0pH8Scx8JZXlg6Oqz5VG+nQkK8nJdvg= +github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA= +github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.5/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= +github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc= +github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/dtls/v2 v2.2.6/go.mod h1:t8fWJCIquY5rlQZwA2yWxUS1+OCrAdXrhVKXB5oD/wY= +github.com/pion/ice/v2 v2.3.1/go.mod h1:aq2kc6MtYNcn4XmMhobAv6hTNJiHzvD0yXRz80+bnP8= +github.com/pion/interceptor v0.1.12/go.mod h1:bDtgAD9dRkBZpWHGKaoKb42FhDHTG2rX8Ii9LRALLVA= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= +github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/rtp v1.8.0 h1:SYD7040IR+NqrGBOc2GDU5iDjAR+0m5rnX/EWCUMNhw= +github.com/pion/rtp v1.8.0/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= +github.com/pion/sctp v1.8.6/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= +github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pion/srtp/v2 v2.0.12/go.mod h1:C3Ep44hlOo2qEYaq4ddsmK5dL63eLehXFbHaZ9F5V9Y= +github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= +github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= +github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pion/transport/v2 v2.0.2/go.mod h1:vrz6bUbFr/cjdwbnxq8OdDDzHf7JJfGsIRkxfpZoTA0= +github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= +github.com/pion/udp/v2 v2.0.1/go.mod h1:B7uvTMP00lzWdyMr/1PVZXtV3wpPIxBRd4Wl6AksXn8= +github.com/pion/webrtc/v3 v3.1.56 h1:ScaiqKQN3liQwT+kJwOBaYP6TwSfixzdUnZmzHAo0a0= +github.com/pion/webrtc/v3 v3.1.56/go.mod h1:7VhbA6ihqJlz6R/INHjyh1b8HpiV9Ct4UQvE1OB/xoM= +github.com/pixelbender/go-sdp v1.1.0/go.mod h1:6IBlz9+BrUHoFTea7gcp4S54khtOhjCW/nVDLhmZBAs= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/q191201771/naza v0.30.8 h1:Lhh29o65C4PmTDj2l+eKfsw9dddpgWZk4bFICtcnSaA= +github.com/q191201771/naza v0.30.8/go.mod h1:n+dpJjQSh90PxBwxBNuifOwQttywvSIN5TkWSSYCeBk= github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk= github.com/qiniu/go-sdk/v7 v7.11.0 h1:Cdx/1E3ybv0OFKnkGwoDN/t6bCCntjrWhwWuRaqI3XQ= github.com/qiniu/go-sdk/v7 v7.11.0/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w= github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs= -github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= -github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= -github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= +github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= +github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= +github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= +github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= +github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= +github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= +github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= +github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -270,11 +466,17 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= +github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/shirou/gopsutil/v3 v3.22.11 h1:kxsPKS+Eeo+VnEQ2XCaGJepeP6KY53QoRTETx3+1ndM= +github.com/shirou/gopsutil/v3 v3.22.11/go.mod h1:xl0EeL4vXJ+hQMAGN8B9VFpxukEMA0XdevQOe5MZ1oY= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -286,37 +488,67 @@ github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= -github.com/tencentyun/cos-go-sdk-v5 v0.7.33 h1:5jmJU7U/1nf/7ZPDkrUL8KlF1oDUzTHsdtLNY6x0hq4= -github.com/tencentyun/cos-go-sdk-v5 v0.7.33/go.mod h1:4E4+bQ2gBVJcgEC9Cufwylio4mXOct2iu05WjgEBx1o= -github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o= -github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= -github.com/xuri/excelize/v2 v2.4.1 h1:veeeFLAJwsNEBPBlDepzPIYS1eLyBVcXNZUW79exZ1E= -github.com/xuri/excelize/v2 v2.4.1/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/taosdata/driver-go/v3 v3.5.0 h1:30crN+E+ACURmq28kn3Y8B3jfL5knaC1fc1rLvgyXqs= +github.com/taosdata/driver-go/v3 v3.5.0/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU= +github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0= +github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= +github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c= +github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.7.1 h1:gm8q0UCAyaTt3MEF5wWMjVdmthm2EHAWesGSKS9tdVI= +github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZOmcF4nTpY= +github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= +github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +github.com/yapingcat/gomedia v0.0.0-20230727105416-c491e66c9d2a h1:x60q0A7QmoUTzixNz7zVTdEA9JC0oYqm8S51PdbTWgs= +github.com/yapingcat/gomedia v0.0.0-20230727105416-c491e66c9d2a/go.mod h1:WSZ59bidJOO40JSJmLqlkBJrjZCtjbKKkygEMfzY/kc= +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.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= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -325,82 +557,145 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +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-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= -golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= +golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= 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-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +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-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= 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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/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-20220704084225-05e143d24a9e/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.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/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -412,14 +707,19 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -451,22 +751,30 @@ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscL google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI= gorm.io/driver/mysql v1.1.2/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= gorm.io/driver/mysql v1.2.0 h1:l8+9VwjjyzEkw0PNPBOr2JHhLOGVk7XEnl5hk42bcvs= @@ -487,3 +795,13 @@ gorm.io/plugin/dbresolver v1.1.0/go.mod h1:tpImigFAEejCALOttyhWqsy4vfa2Uh/vAUVnL honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +m7s.live/engine/v4 v4.13.8 h1:pDl8YWxip5aTidw2Q4NuU+8A6irBraLRfoeBi42S6iQ= +m7s.live/engine/v4 v4.13.8/go.mod h1:k/6iFSuJxmhJL8VO45NAga8BbgZHLLfRXOwCcCzk2s8= +m7s.live/plugin/gb28181/v4 v4.3.9 h1:EDvozinlQbXsby5L+1/cxnmo+HnlQlm8JJ6rYEwOvO4= +m7s.live/plugin/gb28181/v4 v4.3.9/go.mod h1:6lqP8AwhJOvaoOprdqhX9vbEB4Jg9eD/hT8kXpOJoJQ= +m7s.live/plugin/jessica/v4 v4.2.1 h1:GbQ8V2ElHT7Q/0y1cyXCzw/DvTnqkpP1kCOpVd+0d6Y= +m7s.live/plugin/jessica/v4 v4.2.1/go.mod h1:62tI6vio/PkJhuIbkrIKZm9jAEHwkzXe4Uk1EJaK5iQ= +m7s.live/plugin/ps/v4 v4.0.9 h1:79iHz546EdjhH2Op5IMXsjO0SK9tUk9AFSWKo0VON3w= +m7s.live/plugin/ps/v4 v4.0.9/go.mod h1:v59bPt1T+IxuRLRchQ+PwKkLxTRuEY4tbo13lNX6JPc= +m7s.live/plugin/rtmp/v4 v4.2.4 h1:wGuK64ga+w9mjZgV2tgF8llbQ12+3/pvHKuzmEDo/k0= +m7s.live/plugin/rtmp/v4 v4.2.4/go.mod h1:+RzS8WC4AhPEb+CD9T4H+5CoApQCw2X3tNjEaqBVnwk= diff --git a/iothub/README.md b/iothub/README.md new file mode 100644 index 0000000000000000000000000000000000000000..57386a7c41d560cbad7c67846b867881bc09c98e --- /dev/null +++ b/iothub/README.md @@ -0,0 +1,112 @@ + +## 原始数据上报格式 +```text +010304026C00883BF0 +``` +iothub将原始数据序列化成,在规则链中 msg就是以下数据。 +```json +{ + "rowdata": "010304026C00883BF0" +} +``` +需要在规则链中通过函数键 进行解析脚本 +```js +/*直连设备:tempVal是产品物模型中所定义属性的标识符*/ +var tempVal = msg.rowdata; +/*物模型温度标识符*/ +msg.temperature = (parseInt('0x'+tempVal.substr(10, 4))*0.1).toFixed(2); +/*物模型湿度标识符*/ +msg.humidity = (parseInt('0x'+tempVal.substr(6, 4))*0.1).toFixed(2); +return {msg: msg, metadata: metadata, msgType: msgType}; +``` +## 属性上报格式 +```json +{ + "attribute1": "value1", + "attribute2": 0 +} +``` + +## 遥测上报格式 + +```json +{ + "ts": 1689837909000, + "values": { + "telemetry1": "value1", + "telemetry2": 0 + } +} +``` +如果边缘无法获取时间 +```json +{ + "telemetry1": "value1", + "telemetry2": 0 +} +``` + +## 网关子设备属性上报格式 +devA 为设备ID +```json +{ + "devA": { + "attribute1": "value1", + "attribute2": 0 + }, + "devB": { + "attribute1": "value1", + "attribute2": 0 + } +} +``` + +## 网关子设备遥测上报格式 +devA 为设备ID +```json +{ + "devA": [ + { + "ts": 1689837909000, + "values": { + "telemetry1": "value1", + "telemetry2": 0 + } + } + ] +} +``` + +## 网关子设备连接或断开上报格式 +```json +{ + "devA": "online", + "devB": "offline" +} +``` +## 命令下发格式 +下发的ID和相应的ID相同 +```json +{ + "id": "2343", + "cmd": "restart", + "content": { + "firmware_address": "http://xxx.yyy.com", + "version": "latest", + "secret": "****", + "http_method": "GET" + } +} +``` + +## 命令响应的格式 +success 返回结果必传 content代表输出参数可选 +```json +{ + "id": "2343", + "success": true, + "content": { + "aa": "2" + } +} +``` diff --git a/iothub/grpc_server.go b/iothub/grpc_server.go new file mode 100644 index 0000000000000000000000000000000000000000..eed0bf8093ded03ef1d9a22a6cb55b785c80b4c8 --- /dev/null +++ b/iothub/grpc_server.go @@ -0,0 +1,52 @@ +package iothub + +import ( + "context" + "fmt" + "google.golang.org/grpc" + "net" + "pandax/pkg/global" +) + +const DefaultPort = ":9001" + +type Server struct { + Addr string + srv *grpc.Server +} + +func NewServer(addr string) *Server { + if addr == "" { + addr = DefaultPort + } + return &Server{ + Addr: addr, + srv: grpc.NewServer(), + } +} + +func (s *Server) GetServe() *grpc.Server { + return s.srv +} + +func (s *Server) Type() string { + return "GRPC" +} + +func (s *Server) Start(ctx context.Context) error { + l, err := net.Listen("tcp", s.Addr) + if err != nil { + return fmt.Errorf("error listen addr: %w", err) + } + go func() { + if err := s.srv.Serve(l); err != nil { + global.Log.Error(fmt.Sprintf("error http serve: %s", err)) + } + }() + return nil +} + +func (s *Server) Stop(ctx context.Context) error { + s.srv.Stop() + return nil +} diff --git a/iothub/hook.go b/iothub/hook.go new file mode 100644 index 0000000000000000000000000000000000000000..c60dcd449306bafca0469555a79444036e556f8f --- /dev/null +++ b/iothub/hook.go @@ -0,0 +1,369 @@ +package iothub + +import ( + "context" + "encoding/json" + "fmt" + exhook "pandax/iothub/protobuf" + "pandax/pkg/global" + "pandax/pkg/mqtt" + "pandax/pkg/rule_engine/message" + "pandax/pkg/tdengine" + "pandax/pkg/tool" + "strconv" + "sync" + "time" +) + +// 创建设备 设备需要一个账号密码 账号使用 namespace.devicename +// 需要创建一个应用事件表? 例如边缘kuiper掉线事件记录或设备事件 type 事件分类 + +type HookService struct { + exhook.UnimplementedHookProviderServer + cache sync.Map + wg sync.WaitGroup // 优雅关闭 + ch chan struct{} // 并发限制 + messageCh chan *DeviceEventInfo +} + +func InitEmqxHook(addr string) *HookService { + s := NewServer(addr) + service := NewHookService() + exhook.RegisterHookProviderServer(s.GetServe(), service) + err := s.Start(context.TODO()) + if err != nil { + global.Log.Panic("grpc服务启动错误", err) + } else { + global.Log.Infof("IOTHUB HOOK Start SUCCESS,Grpc Server listen: %s", addr) + } + // 开启线程处理消息 + go service.MessageWork() + // 初始化 MQTT客户端 + global.MqttClient = mqtt.InitMqtt(global.Conf.Mqtt.Broker, global.Conf.Mqtt.Username, global.Conf.Mqtt.Password) + return service +} + +func NewHookService() *HookService { + hs := &HookService{ + cache: sync.Map{}, + messageCh: make(chan *DeviceEventInfo), + } + // 并发限制,代表服务器处理能力 + if global.Conf.Queue.Enable && global.Conf.Queue.Num > 0 { + hs.ch = make(chan struct{}, global.Conf.Queue.Num) + } + return hs +} + +func (s *HookService) OnProviderLoaded(ctx context.Context, in *exhook.ProviderLoadedRequest) (*exhook.LoadedResponse, error) { + hooks := []*exhook.HookSpec{ + {Name: "client.connect"}, + {Name: "client.connack"}, + {Name: "client.connected"}, + {Name: "client.disconnected"}, + {Name: "client.authenticate"}, + {Name: "client.authorize"}, + {Name: "client.subscribe"}, + {Name: "client.unsubscribe"}, + {Name: "session.created"}, + {Name: "session.subscribed"}, + {Name: "session.unsubscribed"}, + {Name: "session.resumed"}, + {Name: "session.discarded"}, + {Name: "session.takenover"}, + {Name: "session.terminated"}, + {Name: "message.publish"}, + {Name: "message.delivered"}, + {Name: "message.acked"}, + {Name: "message.dropped"}, + } + return &exhook.LoadedResponse{Hooks: hooks}, nil +} + +func (s *HookService) OnProviderUnloaded(ctx context.Context, in *exhook.ProviderUnloadedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnClientConnect(ctx context.Context, in *exhook.ClientConnectRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnClientConnack(ctx context.Context, in *exhook.ClientConnackRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnClientConnected(ctx context.Context, in *exhook.ClientConnectedRequest) (*exhook.EmptySuccess, error) { + global.Log.Info(fmt.Sprintf("Client %s Connected ", in.Clientinfo.GetNode())) + ts := time.Now().Format("2006-01-02 15:04:05.000") + username := GetUserName(in.Clientinfo) + ci := &tdengine.ConnectInfo{ + ClientID: in.Clientinfo.Clientid, + DeviceId: username, + PeerHost: in.Clientinfo.Peerhost, + Protocol: in.Clientinfo.Protocol, + SocketPort: strconv.Itoa(int(in.Clientinfo.Sockport)), + Type: message.ConnectMes, + Ts: ts, + } + v, err := EncodeData(*ci) + if err != nil { + return nil, err + } + // 添加设备上线记录 + data := &DeviceEventInfo{ + DeviceId: username, + Datas: string(v), + Type: message.ConnectMes, + } + // todo 设备如果是网关设备,如何处理子设备上线 + s.messageCh <- data + + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnClientDisconnected(ctx context.Context, in *exhook.ClientDisconnectedRequest) (*exhook.EmptySuccess, error) { + global.Log.Info(fmt.Sprintf("%s断开连接", in.Clientinfo.Username)) + devicename := GetUserName(in.Clientinfo) + + ts := time.Now().Format("2006-01-02 15:04:05.000") + ci := &tdengine.ConnectInfo{ + ClientID: in.Clientinfo.Clientid, + DeviceId: devicename, + PeerHost: in.Clientinfo.Peerhost, + Protocol: in.Clientinfo.Protocol, + SocketPort: strconv.Itoa(int(in.Clientinfo.Sockport)), + Type: message.DisConnectMes, + Ts: ts, + } + v, err := EncodeData(*ci) + if err != nil { + return nil, err + } + + // 添加设备下线记录 + data := &DeviceEventInfo{ + DeviceId: devicename, + Datas: string(v), + Type: message.DisConnectMes, + } + // todo 网关掉线子设备全部离线状态,更改设备下线状态 + + s.messageCh <- data + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnClientAuthenticate(ctx context.Context, in *exhook.ClientAuthenticateRequest) (*exhook.ValuedResponse, error) { + global.Log.Info(fmt.Sprintf("账号%s,密码%s,开始认证", in.Clientinfo.Username, in.Clientinfo.Password)) + res := &exhook.ValuedResponse{} + res.Type = exhook.ValuedResponse_STOP_AND_RETURN + res.Value = &exhook.ValuedResponse_BoolResult{BoolResult: false} + + username := GetUserName(in.Clientinfo) + pw := GetPassword(in.Clientinfo) + if username == "" || pw == "" { + global.Log.Warn(fmt.Sprintf("invalid username %s or password %s", username, pw)) + return res, nil + } + authRes := s.auth(username, pw) + res.Value = &exhook.ValuedResponse_BoolResult{BoolResult: authRes} + + return res, nil +} + +func (s *HookService) OnClientAuthorize(ctx context.Context, in *exhook.ClientAuthorizeRequest) (*exhook.ValuedResponse, error) { + reply := &exhook.ValuedResponse{} + reply.Type = exhook.ValuedResponse_STOP_AND_RETURN + reply.Value = &exhook.ValuedResponse_BoolResult{BoolResult: true} + return reply, nil +} + +func (s *HookService) OnClientSubscribe(ctx context.Context, in *exhook.ClientSubscribeRequest) (*exhook.EmptySuccess, error) { + global.Log.Info(fmt.Sprintf("%s订阅了%v", in.Clientinfo.Username, in.TopicFilters)) + // 验证topic 是否是规定的topic,可做topic白名单 + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnClientUnsubscribe(ctx context.Context, in *exhook.ClientUnsubscribeRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionCreated(ctx context.Context, in *exhook.SessionCreatedRequest) (*exhook.EmptySuccess, error) { + + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionSubscribed(ctx context.Context, in *exhook.SessionSubscribedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionUnsubscribed(ctx context.Context, in *exhook.SessionUnsubscribedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionResumed(ctx context.Context, in *exhook.SessionResumedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionDiscarded(ctx context.Context, in *exhook.SessionDiscardedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionTakenover(ctx context.Context, in *exhook.SessionTakenoverRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnSessionTerminated(ctx context.Context, in *exhook.SessionTerminatedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnMessagePublish(ctx context.Context, in *exhook.MessagePublishRequest) (*exhook.ValuedResponse, error) { + res := &exhook.ValuedResponse{} + res.Type = exhook.ValuedResponse_STOP_AND_RETURN + res.Value = &exhook.ValuedResponse_BoolResult{BoolResult: false} + + if in.Message.From == mqtt.DefaultDownStreamClientId { + res.Value = &exhook.ValuedResponse_BoolResult{BoolResult: true} + return res, nil + } + // 获取topic类型 + ts := time.Now().Format("2006-01-02 15:04:05.000") + eventType := IotHubTopic.GetMessageType(in.Message.Topic) + datas := string(in.GetMessage().GetPayload()) + data := &DeviceEventInfo{ + Type: eventType, + Datas: datas, + DeviceId: in.Message.Headers["username"], + } + // 如果是网关子设备单独处理 + if eventType == message.GATEWAY { + subData := make(map[string]interface{}) + err := json.Unmarshal(in.GetMessage().GetPayload(), &subData) + if err != nil { + global.Log.Warn(fmt.Sprintf("子网关上报数据格式错误")) + res.Value = &exhook.ValuedResponse_BoolResult{BoolResult: false} + return res, nil + } + // key就是deviceId + for key, value := range subData { + etoken := &tool.DeviceAuth{} + err = global.RedisDb.Get(key, etoken) + if err != nil { + global.Log.Infof("%s设备不存在", key) + continue + } + data.DeviceId = key + if in.Message.Topic == AttributesGatewayTopic { + data.Type = message.AttributesMes + marshal, _ := json.Marshal(value) + attributesData := updateDeviceAttributesData(string(marshal)) + if attributesData == nil { + continue + } + bytes, _ := json.Marshal(attributesData) + data.Datas = string(bytes) + // 子设备发送到队列里 + s.messageCh <- data + } + if in.Message.Topic == TelemetryGatewayTopic { + data.Type = message.TelemetryMes + // 数据处理 如果上传的数据没有时间戳 添加时间戳更改格式化 + telData := make([]map[string]interface{}, 0) + // 解析子设备遥测数据结构 + marshal, _ := json.Marshal(value) + err := json.Unmarshal(marshal, &telData) + if err != nil { + global.Log.Infof("%s子设备遥测数据结构错误", key) + continue + } + for _, da := range telData { + td, _ := json.Marshal(da) + telemetryData := updateDeviceTelemetryData(string(td)) + if telemetryData == nil { + continue + } + bytes, _ := json.Marshal(telemetryData) + data.Datas = string(bytes) + // 子设备发送到队列里 + s.messageCh <- data + } + } + if in.Message.Topic == ConnectGatewayTopic { + data.Type = message.ConnectMes + ci := &tdengine.ConnectInfo{ + ClientID: in.Message.From, + Protocol: in.Message.Headers["protocol"], + PeerHost: in.Message.Headers["peerhost"], + DeviceId: key, + Type: message.ConnectMes, + Ts: ts, + } + v, _ := EncodeData(*ci) + data.Datas = string(v) + // 子设备发送到队列里 + s.messageCh <- data + } + if in.Message.Topic == DisconnectGatewayTopic { + data.Type = message.DisConnectMes + ci := &tdengine.ConnectInfo{ + ClientID: in.Message.From, + DeviceId: key, + Protocol: in.Message.Headers["protocol"], + PeerHost: in.Message.Headers["peerhost"], + Type: message.DisConnectMes, + Ts: ts, + } + v, _ := EncodeData(*ci) + data.Datas = string(v) + // 子设备发送到队列里 + s.messageCh <- data + } + } + res.Value = &exhook.ValuedResponse_Message{Message: in.Message} + return res, nil + } + + switch eventType { + case message.RowMes: + data.Datas = fmt.Sprintf(`{"ts": "%s","rowdata": "%s"}`, ts, data.Datas) + case message.AttributesMes: + attributesData := updateDeviceAttributesData(data.Datas) + if attributesData == nil { + return res, nil + } + bytes, _ := json.Marshal(attributesData) + data.Datas = string(bytes) + case message.TelemetryMes: + // 数据处理 如果上传的数据没有时间戳 添加时间戳更改格式化 + telemetryData := updateDeviceTelemetryData(data.Datas) + if telemetryData == nil { + return res, nil + } + bytes, _ := json.Marshal(telemetryData) + data.Datas = string(bytes) + case message.RpcRequestMes: + // 获取请求id + id := getRequestIdFromTopic(RpcReqReg, in.Message.Topic) + data.RequestId = id + } + + //TODO 如果设备消息;量过大,推荐采用NATS队列处理 + s.messageCh <- data + + res.Value = &exhook.ValuedResponse_Message{Message: in.Message} + return res, nil +} + +func (s *HookService) OnMessageDelivered(ctx context.Context, in *exhook.MessageDeliveredRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnMessageDropped(ctx context.Context, in *exhook.MessageDroppedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} + +func (s *HookService) OnMessageAcked(ctx context.Context, in *exhook.MessageAckedRequest) (*exhook.EmptySuccess, error) { + return &exhook.EmptySuccess{}, nil +} +func (s *HookService) Stop() { + s.wg.Wait() +} diff --git a/iothub/hook_base.go b/iothub/hook_base.go new file mode 100644 index 0000000000000000000000000000000000000000..0a6cf3d04e7a534d30aa4df38d2497d7dedaa697 --- /dev/null +++ b/iothub/hook_base.go @@ -0,0 +1,121 @@ +package iothub + +import ( + "encoding/json" + exhook "pandax/iothub/protobuf" + "pandax/pkg/global" + "pandax/pkg/tool" + "regexp" + "strings" + "time" +) + +func (s *HookService) auth(username, password string) bool { + // 根据token,去查设备Id以及设备类型 + if username == "pandax" && password == "pandax" { + return true + } + etoken := &tool.DeviceAuth{} + err := global.RedisDb.Get(username, etoken) + if err != nil { + global.Log.Infof("invalid username %s", username) + return false + } + // 判断token是否过期了, 设备过期 + if etoken.ExpiredAt < time.Now().Unix() { + global.Log.Infof("设备%s: Token失效", username) + return false + } + if etoken.Token != password { + global.Log.Infof("invalid password %s", password) + return false + } + return true +} + +// 解析遥测数据类型 返回标准带时间戳格式 +func updateDeviceTelemetryData(data string) map[string]interface{} { + tel := make(map[string]interface{}) + err := json.Unmarshal([]byte(data), &tel) + if err != nil { + global.Log.Error("上传遥测数据结构错误") + return nil + } + if _, ok := tel["ts"]; ok { + if _, ok := tel["values"]; ok { + marshal, err := json.Marshal(tel["values"]) + if err != nil { + global.Log.Error("上传遥测数据values数据结构错误") + return nil + } + resTel := make(map[string]interface{}) + json.Unmarshal(marshal, &resTel) + resTel["ts"] = tel["ts"] + return resTel + } + } + tel["ts"] = time.Now().Format("2006-01-02 15:04:05.000") + return tel +} + +func updateDeviceAttributesData(data string) map[string]interface{} { + tel := make(map[string]interface{}) + err := json.Unmarshal([]byte(data), &tel) + if err != nil { + global.Log.Error("上传属性数据结构错误") + return nil + } + tel["ts"] = time.Now().Format("2006-01-02 15:04:05.000") + return tel +} +func GetUserName(Clientinfo *exhook.ClientInfo) string { + // coap 协议 用户名最大支持5个字符 + protocol := Clientinfo.GetProtocol() + var username string + if protocol == "coap" { + username = Clientinfo.GetClientid() + } else if protocol == "lwm2m" { + username = SplitLwm2mClientID(Clientinfo.GetClientid(), 0) + } else { + username = Clientinfo.GetUsername() + } + return username +} + +func SplitLwm2mClientID(lwm2mClientID string, index int) string { + // LwM2M client id should be username@password + idArray := strings.Split(lwm2mClientID, "@") + if len(idArray) < 2 || index > (len(idArray)+1) { + return "" + } + return idArray[index] +} + +func GetPassword(Clientinfo *exhook.ClientInfo) string { + protocol := Clientinfo.GetProtocol() + var pw string + if protocol == "lwm2m" { + pw = SplitLwm2mClientID(Clientinfo.GetClientid(), 1) + } else { + pw = Clientinfo.GetPassword() + } + return pw +} + +// encode data +func EncodeData(jsonData interface{}) ([]byte, error) { + byteData, err := json.Marshal(jsonData) + if nil != err { + return nil, err + } + return byteData, nil +} + +func getRequestIdFromTopic(reg, topic string) (requestId string) { + re := regexp.MustCompile(reg) + res := re.FindStringSubmatch(topic) + if len(res) > 1 { + return res[1] + } + return "" +} diff --git a/iothub/hook_message_work.go b/iothub/hook_message_work.go new file mode 100644 index 0000000000000000000000000000000000000000..dc5c8b886717fb4b57b734ba9bb68c97bcdf28df --- /dev/null +++ b/iothub/hook_message_work.go @@ -0,0 +1,138 @@ +package iothub + +import ( + "context" + "encoding/json" + "fmt" + "pandax/apps/device/services" + ruleEntity "pandax/apps/rule/entity" + "pandax/pkg/global" + "pandax/pkg/mqtt" + "pandax/pkg/rule_engine" + "pandax/pkg/rule_engine/message" + "pandax/pkg/tool" + "pandax/pkg/websocket" + "strconv" +) + +// 消息处理模块 +func (s *HookService) MessageWork() { + for { + select { + case msg := <-s.messageCh: + s.handleOne(msg) // 处理消息 + } + } +} + +func (s *HookService) handleOne(msg *DeviceEventInfo) { + if s.ch != nil { // 用于并发限制 + s.ch <- struct{}{} + } + s.wg.Add(1) + go func() { + defer s.wg.Done() + etoken := &tool.DeviceAuth{} + err := global.RedisDb.Get(msg.DeviceId, etoken) + if err != nil { + return + } + switch msg.Type { + case message.RowMes, message.AttributesMes, message.TelemetryMes: + // 发送websocket到云组态 + go SendZtWebsocket(msg.DeviceId, msg.Datas) + // 业务逻辑执行 + // 获取规则链代码 + chain := getRuleChain(etoken) + dataCode := chain.LfData.DataCode + code, err := json.Marshal(dataCode) + //新建规则链实体 + instance, errs := rule_engine.NewRuleChainInstance(code) + if len(errs) > 0 { + global.Log.Error("规则链初始化失败", errs[0]) + return + } + ruleMessage := buildRuleMessage(etoken, msg, msg.Type) + err = instance.StartRuleChain(context.Background(), ruleMessage) + if err != nil { + global.Log.Error("规则链执行失败", errs) + } + // Rpc请求 + case message.RpcRequestMes: + var datas = mqtt.RpcPayload{} + err := json.Unmarshal([]byte(msg.Datas), &datas) + if err != nil { + global.Log.Error("RPC请求数据解析错误,请检查数据格式") + return + } + RequestId, err := strconv.Atoi(msg.RequestId) + if err != nil { + global.Log.Error("RPC请求请求iD非整型") + return + } + var rpc = &mqtt.RpcRequest{Client: global.MqttClient, RequestId: RequestId} + err = rpc.RespondTpc(datas) + if err != nil { + global.Log.Error("处理响应失败") + return + } + //services.DeviceCmdLogModelDao.UpdateResp(id, content, state) + case message.DisConnectMes, message.ConnectMes: + // 更改设备在线状态 + if msg.Type == message.ConnectMes { + services.DeviceModelDao.UpdateStatus(msg.DeviceId, global.ONLINE) + } else { + services.DeviceModelDao.UpdateStatus(msg.DeviceId, global.OFFLINE) + } + // 添加设备连接历史 + data := make(map[string]any) + err := json.Unmarshal([]byte(msg.Datas), &data) + if err != nil { + global.Log.Error("设备连接数据格式解析错误") + return + } + err = global.TdDb.InsertEvent(data) + if err != nil { + global.Log.Error("连接事件数据添加错误", err) + } + } + }() +} + +func getRuleChain(etoken *tool.DeviceAuth) *ruleEntity.RuleDataJson { + ruleData := ruleEntity.RuleDataJson{} + err := global.RedisDb.Get(etoken.ProductId, &ruleData) + if err != nil { + return nil + } + return &ruleData +} + +func buildRuleMessage(etoken *tool.DeviceAuth, dei *DeviceEventInfo, msgType string) message.Message { + metadataVals := map[string]interface{}{ + "deviceId": etoken.DeviceId, + "deviceName": etoken.Name, + "deviceType": etoken.DeviceType, + "productId": etoken.ProductId, + } + metadata := message.NewDefaultMetadata(metadataVals) + msgVals := make(map[string]interface{}) + json.Unmarshal([]byte(dei.Datas), &msgVals) + return message.NewMessageWithDetail(etoken.User, msgType, msgVals, metadata) +} + +func SendZtWebsocket(deviceId, message string) { + msgVals := make(map[string]interface{}) + if err := json.Unmarshal([]byte(message), &msgVals); err != nil { + return + } + twinData := map[string]interface{}{ + "twinId": deviceId, + "attrs": msgVals, + } + data, _ := json.Marshal(twinData) + for stageid, _ := range websocket.Wsp { + CJNR := fmt.Sprintf(`{"MESSAGETYPE":"01","MESSAGECONTENT": %s}`, string(data)) + websocket.SendMessage(CJNR, stageid) + } +} diff --git a/iothub/iothub_session.go b/iothub/iothub_session.go new file mode 100644 index 0000000000000000000000000000000000000000..67c8e3064585c0355f0ee614277da0442d1041d0 --- /dev/null +++ b/iothub/iothub_session.go @@ -0,0 +1,8 @@ +package iothub + +type DeviceEventInfo struct { + DeviceId string `json:"deviceId"` + Datas string `json:"datas"` + Type string `json:"type"` + RequestId string `json:"requestId"` +} diff --git a/iothub/protobuf/exhook.pb.go b/iothub/protobuf/exhook.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..e1ad700eb05f8d87619f3243ad22dece28a4fb92 --- /dev/null +++ b/iothub/protobuf/exhook.pb.go @@ -0,0 +1,3455 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------ + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.18.1 +// source: protobuf/exhook.proto + +// The exhook proto version should be fixed as `v2` in EMQX v5.x +// to make sure the exhook proto version is compatible + +package exhook + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ClientAuthorizeRequest_AuthorizeReqType int32 + +const ( + ClientAuthorizeRequest_PUBLISH ClientAuthorizeRequest_AuthorizeReqType = 0 + ClientAuthorizeRequest_SUBSCRIBE ClientAuthorizeRequest_AuthorizeReqType = 1 +) + +// Enum value maps for ClientAuthorizeRequest_AuthorizeReqType. +var ( + ClientAuthorizeRequest_AuthorizeReqType_name = map[int32]string{ + 0: "PUBLISH", + 1: "SUBSCRIBE", + } + ClientAuthorizeRequest_AuthorizeReqType_value = map[string]int32{ + "PUBLISH": 0, + "SUBSCRIBE": 1, + } +) + +func (x ClientAuthorizeRequest_AuthorizeReqType) Enum() *ClientAuthorizeRequest_AuthorizeReqType { + p := new(ClientAuthorizeRequest_AuthorizeReqType) + *p = x + return p +} + +func (x ClientAuthorizeRequest_AuthorizeReqType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ClientAuthorizeRequest_AuthorizeReqType) Descriptor() protoreflect.EnumDescriptor { + return file_protobuf_exhook_proto_enumTypes[0].Descriptor() +} + +func (ClientAuthorizeRequest_AuthorizeReqType) Type() protoreflect.EnumType { + return &file_protobuf_exhook_proto_enumTypes[0] +} + +func (x ClientAuthorizeRequest_AuthorizeReqType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ClientAuthorizeRequest_AuthorizeReqType.Descriptor instead. +func (ClientAuthorizeRequest_AuthorizeReqType) EnumDescriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{7, 0} +} + +// The responded value type +// - contiune: Use the responded value and execute the next hook +// - ignore: Ignore the responded value +// - stop_and_return: Use the responded value and stop the chain executing +type ValuedResponse_ResponsedType int32 + +const ( + ValuedResponse_CONTINUE ValuedResponse_ResponsedType = 0 + ValuedResponse_IGNORE ValuedResponse_ResponsedType = 1 + ValuedResponse_STOP_AND_RETURN ValuedResponse_ResponsedType = 2 +) + +// Enum value maps for ValuedResponse_ResponsedType. +var ( + ValuedResponse_ResponsedType_name = map[int32]string{ + 0: "CONTINUE", + 1: "IGNORE", + 2: "STOP_AND_RETURN", + } + ValuedResponse_ResponsedType_value = map[string]int32{ + "CONTINUE": 0, + "IGNORE": 1, + "STOP_AND_RETURN": 2, + } +) + +func (x ValuedResponse_ResponsedType) Enum() *ValuedResponse_ResponsedType { + p := new(ValuedResponse_ResponsedType) + *p = x + return p +} + +func (x ValuedResponse_ResponsedType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValuedResponse_ResponsedType) Descriptor() protoreflect.EnumDescriptor { + return file_protobuf_exhook_proto_enumTypes[1].Descriptor() +} + +func (ValuedResponse_ResponsedType) Type() protoreflect.EnumType { + return &file_protobuf_exhook_proto_enumTypes[1] +} + +func (x ValuedResponse_ResponsedType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ValuedResponse_ResponsedType.Descriptor instead. +func (ValuedResponse_ResponsedType) EnumDescriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{22, 0} +} + +type ProviderLoadedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Broker *BrokerInfo `protobuf:"bytes,1,opt,name=broker,proto3" json:"broker,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ProviderLoadedRequest) Reset() { + *x = ProviderLoadedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProviderLoadedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProviderLoadedRequest) ProtoMessage() {} + +func (x *ProviderLoadedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProviderLoadedRequest.ProtoReflect.Descriptor instead. +func (*ProviderLoadedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{0} +} + +func (x *ProviderLoadedRequest) GetBroker() *BrokerInfo { + if x != nil { + return x.Broker + } + return nil +} + +func (x *ProviderLoadedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ProviderUnloadedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ProviderUnloadedRequest) Reset() { + *x = ProviderUnloadedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProviderUnloadedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProviderUnloadedRequest) ProtoMessage() {} + +func (x *ProviderUnloadedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProviderUnloadedRequest.ProtoReflect.Descriptor instead. +func (*ProviderUnloadedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{1} +} + +func (x *ProviderUnloadedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientConnectRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conninfo *ConnInfo `protobuf:"bytes,1,opt,name=conninfo,proto3" json:"conninfo,omitempty"` + // MQTT CONNECT packet's properties (MQTT v5.0) + // + // It should be empty on MQTT v3.1.1/v3.1 or others protocol + Props []*Property `protobuf:"bytes,2,rep,name=props,proto3" json:"props,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientConnectRequest) Reset() { + *x = ClientConnectRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientConnectRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientConnectRequest) ProtoMessage() {} + +func (x *ClientConnectRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientConnectRequest.ProtoReflect.Descriptor instead. +func (*ClientConnectRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{2} +} + +func (x *ClientConnectRequest) GetConninfo() *ConnInfo { + if x != nil { + return x.Conninfo + } + return nil +} + +func (x *ClientConnectRequest) GetProps() []*Property { + if x != nil { + return x.Props + } + return nil +} + +func (x *ClientConnectRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientConnackRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conninfo *ConnInfo `protobuf:"bytes,1,opt,name=conninfo,proto3" json:"conninfo,omitempty"` + ResultCode string `protobuf:"bytes,2,opt,name=result_code,json=resultCode,proto3" json:"result_code,omitempty"` + Props []*Property `protobuf:"bytes,3,rep,name=props,proto3" json:"props,omitempty"` + Meta *RequestMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientConnackRequest) Reset() { + *x = ClientConnackRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientConnackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientConnackRequest) ProtoMessage() {} + +func (x *ClientConnackRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientConnackRequest.ProtoReflect.Descriptor instead. +func (*ClientConnackRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{3} +} + +func (x *ClientConnackRequest) GetConninfo() *ConnInfo { + if x != nil { + return x.Conninfo + } + return nil +} + +func (x *ClientConnackRequest) GetResultCode() string { + if x != nil { + return x.ResultCode + } + return "" +} + +func (x *ClientConnackRequest) GetProps() []*Property { + if x != nil { + return x.Props + } + return nil +} + +func (x *ClientConnackRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientConnectedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientConnectedRequest) Reset() { + *x = ClientConnectedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientConnectedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientConnectedRequest) ProtoMessage() {} + +func (x *ClientConnectedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientConnectedRequest.ProtoReflect.Descriptor instead. +func (*ClientConnectedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{4} +} + +func (x *ClientConnectedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *ClientConnectedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientDisconnectedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientDisconnectedRequest) Reset() { + *x = ClientDisconnectedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientDisconnectedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientDisconnectedRequest) ProtoMessage() {} + +func (x *ClientDisconnectedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientDisconnectedRequest.ProtoReflect.Descriptor instead. +func (*ClientDisconnectedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{5} +} + +func (x *ClientDisconnectedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *ClientDisconnectedRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *ClientDisconnectedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientAuthenticateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Result bool `protobuf:"varint,2,opt,name=result,proto3" json:"result,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientAuthenticateRequest) Reset() { + *x = ClientAuthenticateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientAuthenticateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientAuthenticateRequest) ProtoMessage() {} + +func (x *ClientAuthenticateRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientAuthenticateRequest.ProtoReflect.Descriptor instead. +func (*ClientAuthenticateRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{6} +} + +func (x *ClientAuthenticateRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *ClientAuthenticateRequest) GetResult() bool { + if x != nil { + return x.Result + } + return false +} + +func (x *ClientAuthenticateRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientAuthorizeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Type ClientAuthorizeRequest_AuthorizeReqType `protobuf:"varint,2,opt,name=type,proto3,enum=emqx.exhook.v2.ClientAuthorizeRequest_AuthorizeReqType" json:"type,omitempty"` + Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` + Result bool `protobuf:"varint,4,opt,name=result,proto3" json:"result,omitempty"` + Meta *RequestMeta `protobuf:"bytes,5,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientAuthorizeRequest) Reset() { + *x = ClientAuthorizeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientAuthorizeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientAuthorizeRequest) ProtoMessage() {} + +func (x *ClientAuthorizeRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientAuthorizeRequest.ProtoReflect.Descriptor instead. +func (*ClientAuthorizeRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{7} +} + +func (x *ClientAuthorizeRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *ClientAuthorizeRequest) GetType() ClientAuthorizeRequest_AuthorizeReqType { + if x != nil { + return x.Type + } + return ClientAuthorizeRequest_PUBLISH +} + +func (x *ClientAuthorizeRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientAuthorizeRequest) GetResult() bool { + if x != nil { + return x.Result + } + return false +} + +func (x *ClientAuthorizeRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientSubscribeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Props []*Property `protobuf:"bytes,2,rep,name=props,proto3" json:"props,omitempty"` + TopicFilters []*TopicFilter `protobuf:"bytes,3,rep,name=topic_filters,json=topicFilters,proto3" json:"topic_filters,omitempty"` + Meta *RequestMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientSubscribeRequest) Reset() { + *x = ClientSubscribeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientSubscribeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientSubscribeRequest) ProtoMessage() {} + +func (x *ClientSubscribeRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientSubscribeRequest.ProtoReflect.Descriptor instead. +func (*ClientSubscribeRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{8} +} + +func (x *ClientSubscribeRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *ClientSubscribeRequest) GetProps() []*Property { + if x != nil { + return x.Props + } + return nil +} + +func (x *ClientSubscribeRequest) GetTopicFilters() []*TopicFilter { + if x != nil { + return x.TopicFilters + } + return nil +} + +func (x *ClientSubscribeRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ClientUnsubscribeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Props []*Property `protobuf:"bytes,2,rep,name=props,proto3" json:"props,omitempty"` + TopicFilters []*TopicFilter `protobuf:"bytes,3,rep,name=topic_filters,json=topicFilters,proto3" json:"topic_filters,omitempty"` + Meta *RequestMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *ClientUnsubscribeRequest) Reset() { + *x = ClientUnsubscribeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientUnsubscribeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientUnsubscribeRequest) ProtoMessage() {} + +func (x *ClientUnsubscribeRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientUnsubscribeRequest.ProtoReflect.Descriptor instead. +func (*ClientUnsubscribeRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{9} +} + +func (x *ClientUnsubscribeRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *ClientUnsubscribeRequest) GetProps() []*Property { + if x != nil { + return x.Props + } + return nil +} + +func (x *ClientUnsubscribeRequest) GetTopicFilters() []*TopicFilter { + if x != nil { + return x.TopicFilters + } + return nil +} + +func (x *ClientUnsubscribeRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionCreatedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionCreatedRequest) Reset() { + *x = SessionCreatedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionCreatedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionCreatedRequest) ProtoMessage() {} + +func (x *SessionCreatedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionCreatedRequest.ProtoReflect.Descriptor instead. +func (*SessionCreatedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{10} +} + +func (x *SessionCreatedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionCreatedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionSubscribedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Subopts *SubOpts `protobuf:"bytes,3,opt,name=subopts,proto3" json:"subopts,omitempty"` + Meta *RequestMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionSubscribedRequest) Reset() { + *x = SessionSubscribedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionSubscribedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionSubscribedRequest) ProtoMessage() {} + +func (x *SessionSubscribedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionSubscribedRequest.ProtoReflect.Descriptor instead. +func (*SessionSubscribedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{11} +} + +func (x *SessionSubscribedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionSubscribedRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *SessionSubscribedRequest) GetSubopts() *SubOpts { + if x != nil { + return x.Subopts + } + return nil +} + +func (x *SessionSubscribedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionUnsubscribedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionUnsubscribedRequest) Reset() { + *x = SessionUnsubscribedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionUnsubscribedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionUnsubscribedRequest) ProtoMessage() {} + +func (x *SessionUnsubscribedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionUnsubscribedRequest.ProtoReflect.Descriptor instead. +func (*SessionUnsubscribedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{12} +} + +func (x *SessionUnsubscribedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionUnsubscribedRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *SessionUnsubscribedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionResumedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionResumedRequest) Reset() { + *x = SessionResumedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionResumedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionResumedRequest) ProtoMessage() {} + +func (x *SessionResumedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionResumedRequest.ProtoReflect.Descriptor instead. +func (*SessionResumedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{13} +} + +func (x *SessionResumedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionResumedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionDiscardedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionDiscardedRequest) Reset() { + *x = SessionDiscardedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionDiscardedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionDiscardedRequest) ProtoMessage() {} + +func (x *SessionDiscardedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionDiscardedRequest.ProtoReflect.Descriptor instead. +func (*SessionDiscardedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{14} +} + +func (x *SessionDiscardedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionDiscardedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionTakenoverRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionTakenoverRequest) Reset() { + *x = SessionTakenoverRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionTakenoverRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionTakenoverRequest) ProtoMessage() {} + +func (x *SessionTakenoverRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionTakenoverRequest.ProtoReflect.Descriptor instead. +func (*SessionTakenoverRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{15} +} + +func (x *SessionTakenoverRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionTakenoverRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type SessionTerminatedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *SessionTerminatedRequest) Reset() { + *x = SessionTerminatedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionTerminatedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionTerminatedRequest) ProtoMessage() {} + +func (x *SessionTerminatedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionTerminatedRequest.ProtoReflect.Descriptor instead. +func (*SessionTerminatedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{16} +} + +func (x *SessionTerminatedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *SessionTerminatedRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *SessionTerminatedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type MessagePublishRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Meta *RequestMeta `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *MessagePublishRequest) Reset() { + *x = MessagePublishRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessagePublishRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessagePublishRequest) ProtoMessage() {} + +func (x *MessagePublishRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessagePublishRequest.ProtoReflect.Descriptor instead. +func (*MessagePublishRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{17} +} + +func (x *MessagePublishRequest) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *MessagePublishRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type MessageDeliveredRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Message *Message `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *MessageDeliveredRequest) Reset() { + *x = MessageDeliveredRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageDeliveredRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageDeliveredRequest) ProtoMessage() {} + +func (x *MessageDeliveredRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageDeliveredRequest.ProtoReflect.Descriptor instead. +func (*MessageDeliveredRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{18} +} + +func (x *MessageDeliveredRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *MessageDeliveredRequest) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *MessageDeliveredRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type MessageDroppedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *MessageDroppedRequest) Reset() { + *x = MessageDroppedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageDroppedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageDroppedRequest) ProtoMessage() {} + +func (x *MessageDroppedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageDroppedRequest.ProtoReflect.Descriptor instead. +func (*MessageDroppedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{19} +} + +func (x *MessageDroppedRequest) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *MessageDroppedRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *MessageDroppedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type MessageAckedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clientinfo *ClientInfo `protobuf:"bytes,1,opt,name=clientinfo,proto3" json:"clientinfo,omitempty"` + Message *Message `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Meta *RequestMeta `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *MessageAckedRequest) Reset() { + *x = MessageAckedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageAckedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageAckedRequest) ProtoMessage() {} + +func (x *MessageAckedRequest) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageAckedRequest.ProtoReflect.Descriptor instead. +func (*MessageAckedRequest) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{20} +} + +func (x *MessageAckedRequest) GetClientinfo() *ClientInfo { + if x != nil { + return x.Clientinfo + } + return nil +} + +func (x *MessageAckedRequest) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *MessageAckedRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type LoadedResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hooks []*HookSpec `protobuf:"bytes,1,rep,name=hooks,proto3" json:"hooks,omitempty"` +} + +func (x *LoadedResponse) Reset() { + *x = LoadedResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LoadedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LoadedResponse) ProtoMessage() {} + +func (x *LoadedResponse) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LoadedResponse.ProtoReflect.Descriptor instead. +func (*LoadedResponse) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{21} +} + +func (x *LoadedResponse) GetHooks() []*HookSpec { + if x != nil { + return x.Hooks + } + return nil +} + +type ValuedResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type ValuedResponse_ResponsedType `protobuf:"varint,1,opt,name=type,proto3,enum=emqx.exhook.v2.ValuedResponse_ResponsedType" json:"type,omitempty"` + // Types that are assignable to Value: + // *ValuedResponse_BoolResult + // *ValuedResponse_Message + Value isValuedResponse_Value `protobuf_oneof:"value"` +} + +func (x *ValuedResponse) Reset() { + *x = ValuedResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValuedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValuedResponse) ProtoMessage() {} + +func (x *ValuedResponse) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValuedResponse.ProtoReflect.Descriptor instead. +func (*ValuedResponse) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{22} +} + +func (x *ValuedResponse) GetType() ValuedResponse_ResponsedType { + if x != nil { + return x.Type + } + return ValuedResponse_CONTINUE +} + +func (m *ValuedResponse) GetValue() isValuedResponse_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *ValuedResponse) GetBoolResult() bool { + if x, ok := x.GetValue().(*ValuedResponse_BoolResult); ok { + return x.BoolResult + } + return false +} + +func (x *ValuedResponse) GetMessage() *Message { + if x, ok := x.GetValue().(*ValuedResponse_Message); ok { + return x.Message + } + return nil +} + +type isValuedResponse_Value interface { + isValuedResponse_Value() +} + +type ValuedResponse_BoolResult struct { + // Boolean result, used on the 'client.authenticate', 'client.authorize' hooks + BoolResult bool `protobuf:"varint,3,opt,name=bool_result,json=boolResult,proto3,oneof"` +} + +type ValuedResponse_Message struct { + // Message result, used on the 'message.*' hooks + Message *Message `protobuf:"bytes,4,opt,name=message,proto3,oneof"` +} + +func (*ValuedResponse_BoolResult) isValuedResponse_Value() {} + +func (*ValuedResponse_Message) isValuedResponse_Value() {} + +type EmptySuccess struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *EmptySuccess) Reset() { + *x = EmptySuccess{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmptySuccess) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptySuccess) ProtoMessage() {} + +func (x *EmptySuccess) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmptySuccess.ProtoReflect.Descriptor instead. +func (*EmptySuccess) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{23} +} + +type BrokerInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Sysdescr string `protobuf:"bytes,2,opt,name=sysdescr,proto3" json:"sysdescr,omitempty"` + Uptime int64 `protobuf:"varint,3,opt,name=uptime,proto3" json:"uptime,omitempty"` + Datetime string `protobuf:"bytes,4,opt,name=datetime,proto3" json:"datetime,omitempty"` +} + +func (x *BrokerInfo) Reset() { + *x = BrokerInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BrokerInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BrokerInfo) ProtoMessage() {} + +func (x *BrokerInfo) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BrokerInfo.ProtoReflect.Descriptor instead. +func (*BrokerInfo) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{24} +} + +func (x *BrokerInfo) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *BrokerInfo) GetSysdescr() string { + if x != nil { + return x.Sysdescr + } + return "" +} + +func (x *BrokerInfo) GetUptime() int64 { + if x != nil { + return x.Uptime + } + return 0 +} + +func (x *BrokerInfo) GetDatetime() string { + if x != nil { + return x.Datetime + } + return "" +} + +type HookSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The registered hooks name + // + // Available value: + // "client.connect", "client.connack" + // "client.connected", "client.disconnected" + // "client.authenticate", "client.authorize" + // "client.subscribe", "client.unsubscribe" + // + // "session.created", "session.subscribed" + // "session.unsubscribed", "session.resumed" + // "session.discarded", "session.takenover" + // "session.terminated" + // + // "message.publish", "message.delivered" + // "message.acked", "message.dropped" + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The topic filters for message hooks + Topics []string `protobuf:"bytes,2,rep,name=topics,proto3" json:"topics,omitempty"` +} + +func (x *HookSpec) Reset() { + *x = HookSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HookSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HookSpec) ProtoMessage() {} + +func (x *HookSpec) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HookSpec.ProtoReflect.Descriptor instead. +func (*HookSpec) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{25} +} + +func (x *HookSpec) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *HookSpec) GetTopics() []string { + if x != nil { + return x.Topics + } + return nil +} + +type ConnInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node string `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + Clientid string `protobuf:"bytes,2,opt,name=clientid,proto3" json:"clientid,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + Peerhost string `protobuf:"bytes,4,opt,name=peerhost,proto3" json:"peerhost,omitempty"` + Sockport uint32 `protobuf:"varint,5,opt,name=sockport,proto3" json:"sockport,omitempty"` + ProtoName string `protobuf:"bytes,6,opt,name=proto_name,json=protoName,proto3" json:"proto_name,omitempty"` + ProtoVer string `protobuf:"bytes,7,opt,name=proto_ver,json=protoVer,proto3" json:"proto_ver,omitempty"` + Keepalive uint32 `protobuf:"varint,8,opt,name=keepalive,proto3" json:"keepalive,omitempty"` +} + +func (x *ConnInfo) Reset() { + *x = ConnInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnInfo) ProtoMessage() {} + +func (x *ConnInfo) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnInfo.ProtoReflect.Descriptor instead. +func (*ConnInfo) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{26} +} + +func (x *ConnInfo) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *ConnInfo) GetClientid() string { + if x != nil { + return x.Clientid + } + return "" +} + +func (x *ConnInfo) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *ConnInfo) GetPeerhost() string { + if x != nil { + return x.Peerhost + } + return "" +} + +func (x *ConnInfo) GetSockport() uint32 { + if x != nil { + return x.Sockport + } + return 0 +} + +func (x *ConnInfo) GetProtoName() string { + if x != nil { + return x.ProtoName + } + return "" +} + +func (x *ConnInfo) GetProtoVer() string { + if x != nil { + return x.ProtoVer + } + return "" +} + +func (x *ConnInfo) GetKeepalive() uint32 { + if x != nil { + return x.Keepalive + } + return 0 +} + +type ClientInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node string `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + Clientid string `protobuf:"bytes,2,opt,name=clientid,proto3" json:"clientid,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` + Peerhost string `protobuf:"bytes,5,opt,name=peerhost,proto3" json:"peerhost,omitempty"` + Sockport uint32 `protobuf:"varint,6,opt,name=sockport,proto3" json:"sockport,omitempty"` + Protocol string `protobuf:"bytes,7,opt,name=protocol,proto3" json:"protocol,omitempty"` + Mountpoint string `protobuf:"bytes,8,opt,name=mountpoint,proto3" json:"mountpoint,omitempty"` + IsSuperuser bool `protobuf:"varint,9,opt,name=is_superuser,json=isSuperuser,proto3" json:"is_superuser,omitempty"` + Anonymous bool `protobuf:"varint,10,opt,name=anonymous,proto3" json:"anonymous,omitempty"` + // common name of client TLS cert + Cn string `protobuf:"bytes,11,opt,name=cn,proto3" json:"cn,omitempty"` + // subject of client TLS cert + Dn string `protobuf:"bytes,12,opt,name=dn,proto3" json:"dn,omitempty"` +} + +func (x *ClientInfo) Reset() { + *x = ClientInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientInfo) ProtoMessage() {} + +func (x *ClientInfo) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. +func (*ClientInfo) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{27} +} + +func (x *ClientInfo) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *ClientInfo) GetClientid() string { + if x != nil { + return x.Clientid + } + return "" +} + +func (x *ClientInfo) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *ClientInfo) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *ClientInfo) GetPeerhost() string { + if x != nil { + return x.Peerhost + } + return "" +} + +func (x *ClientInfo) GetSockport() uint32 { + if x != nil { + return x.Sockport + } + return 0 +} + +func (x *ClientInfo) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *ClientInfo) GetMountpoint() string { + if x != nil { + return x.Mountpoint + } + return "" +} + +func (x *ClientInfo) GetIsSuperuser() bool { + if x != nil { + return x.IsSuperuser + } + return false +} + +func (x *ClientInfo) GetAnonymous() bool { + if x != nil { + return x.Anonymous + } + return false +} + +func (x *ClientInfo) GetCn() string { + if x != nil { + return x.Cn + } + return "" +} + +func (x *ClientInfo) GetDn() string { + if x != nil { + return x.Dn + } + return "" +} + +type Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node string `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Qos uint32 `protobuf:"varint,3,opt,name=qos,proto3" json:"qos,omitempty"` + From string `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"` + Topic string `protobuf:"bytes,5,opt,name=topic,proto3" json:"topic,omitempty"` + Payload []byte `protobuf:"bytes,6,opt,name=payload,proto3" json:"payload,omitempty"` + Timestamp uint64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // The key of header can be: + // - username: + // * Readonly + // * The username of sender client + // * Value type: utf8 string + // - protocol: + // * Readonly + // * The protocol name of sender client + // * Value type: string enum with "mqtt", "mqtt-sn", ... + // - peerhost: + // * Readonly + // * The peerhost of sender client + // * Value type: ip address string + // - allow_publish: + // * Writable + // * Whether to allow the message to be published by emqx + // * Value type: string enum with "true", "false", default is "true" + // + // Notes: All header may be missing, which means that the message does not + // carry these headers. We can guarantee that clients coming from MQTT, + // MQTT-SN, CoAP, LwM2M and other natively supported protocol clients will + // carry these headers, but there is no guarantee that messages published + // by other means will do, e.g. messages published by HTTP-API + Headers map[string]string `protobuf:"bytes,8,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Message) Reset() { + *x = Message{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{28} +} + +func (x *Message) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *Message) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Message) GetQos() uint32 { + if x != nil { + return x.Qos + } + return 0 +} + +func (x *Message) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *Message) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *Message) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +func (x *Message) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *Message) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +type Property struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Property) Reset() { + *x = Property{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Property) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Property) ProtoMessage() {} + +func (x *Property) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Property.ProtoReflect.Descriptor instead. +func (*Property) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{29} +} + +func (x *Property) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Property) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type TopicFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Qos uint32 `protobuf:"varint,2,opt,name=qos,proto3" json:"qos,omitempty"` +} + +func (x *TopicFilter) Reset() { + *x = TopicFilter{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicFilter) ProtoMessage() {} + +func (x *TopicFilter) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicFilter.ProtoReflect.Descriptor instead. +func (*TopicFilter) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{30} +} + +func (x *TopicFilter) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TopicFilter) GetQos() uint32 { + if x != nil { + return x.Qos + } + return 0 +} + +type SubOpts struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The QoS level + Qos uint32 `protobuf:"varint,1,opt,name=qos,proto3" json:"qos,omitempty"` + // The group name for shared subscription + Share string `protobuf:"bytes,2,opt,name=share,proto3" json:"share,omitempty"` + // The Retain Handling option (MQTT v5.0) + // + // 0 = Send retained messages at the time of the subscribe + // 1 = Send retained messages at subscribe only if the subscription does + // not currently exist + // 2 = Do not send retained messages at the time of the subscribe + Rh uint32 `protobuf:"varint,3,opt,name=rh,proto3" json:"rh,omitempty"` + // The Retain as Published option (MQTT v5.0) + // + // If 1, Application Messages forwarded using this subscription keep the + // RETAIN flag they were published with. + // If 0, Application Messages forwarded using this subscription have the + // RETAIN flag set to 0. + // Retained messages sent when the subscription is established have the RETAIN flag set to 1. + Rap uint32 `protobuf:"varint,4,opt,name=rap,proto3" json:"rap,omitempty"` + // The No Local option (MQTT v5.0) + // + // If the value is 1, Application Messages MUST NOT be forwarded to a + // connection with a ClientID equal to the ClientID of the publishing + Nl uint32 `protobuf:"varint,5,opt,name=nl,proto3" json:"nl,omitempty"` +} + +func (x *SubOpts) Reset() { + *x = SubOpts{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubOpts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubOpts) ProtoMessage() {} + +func (x *SubOpts) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubOpts.ProtoReflect.Descriptor instead. +func (*SubOpts) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{31} +} + +func (x *SubOpts) GetQos() uint32 { + if x != nil { + return x.Qos + } + return 0 +} + +func (x *SubOpts) GetShare() string { + if x != nil { + return x.Share + } + return "" +} + +func (x *SubOpts) GetRh() uint32 { + if x != nil { + return x.Rh + } + return 0 +} + +func (x *SubOpts) GetRap() uint32 { + if x != nil { + return x.Rap + } + return 0 +} + +func (x *SubOpts) GetNl() uint32 { + if x != nil { + return x.Nl + } + return 0 +} + +type RequestMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node string `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Sysdescr string `protobuf:"bytes,3,opt,name=sysdescr,proto3" json:"sysdescr,omitempty"` + ClusterName string `protobuf:"bytes,4,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` +} + +func (x *RequestMeta) Reset() { + *x = RequestMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_exhook_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestMeta) ProtoMessage() {} + +func (x *RequestMeta) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_exhook_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestMeta.ProtoReflect.Descriptor instead. +func (*RequestMeta) Descriptor() ([]byte, []int) { + return file_protobuf_exhook_proto_rawDescGZIP(), []int{32} +} + +func (x *RequestMeta) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *RequestMeta) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RequestMeta) GetSysdescr() string { + if x != nil { + return x.Sysdescr + } + return "" +} + +func (x *RequestMeta) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +var File_protobuf_exhook_proto protoreflect.FileDescriptor + +var file_protobuf_exhook_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x78, 0x68, 0x6f, 0x6f, + 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x22, 0x7c, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x32, 0x0a, 0x06, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, + 0x32, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x62, 0x72, + 0x6f, 0x6b, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x4a, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, + 0x61, 0x22, 0xad, 0x01, 0x0a, 0x14, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x63, 0x6f, + 0x6e, 0x6e, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, + 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x6e, 0x69, 0x6e, 0x66, 0x6f, + 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, + 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, + 0x61, 0x22, 0xce, 0x01, 0x0a, 0x14, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x63, 0x6f, + 0x6e, 0x6e, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, + 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x6e, 0x69, 0x6e, 0x66, 0x6f, + 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, + 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x70, + 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x22, 0x85, 0x01, 0x0a, 0x16, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, + 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, + 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, + 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0xa0, 0x01, 0x0a, 0x19, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, + 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0xa0, 0x01, + 0x0a, 0x19, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, + 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x22, 0xb0, 0x02, 0x0a, 0x16, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, + 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, + 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x22, 0x2e, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x52, 0x65, 0x71, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x53, 0x48, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, + 0x45, 0x10, 0x01, 0x22, 0xf7, 0x01, 0x0a, 0x16, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, + 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x72, + 0x6f, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x6d, 0x71, 0x78, + 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x12, 0x40, 0x0a, 0x0d, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x76, 0x32, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0c, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0xf9, 0x01, + 0x0a, 0x18, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, + 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, + 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x12, 0x40, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x5f, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x54, + 0x6f, 0x70, 0x69, 0x63, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0c, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x84, 0x01, 0x0a, 0x15, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, + 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, + 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x22, 0xd0, 0x01, 0x0a, 0x18, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, + 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, + 0x31, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6f, 0x70, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, + 0x32, 0x2e, 0x53, 0x75, 0x62, 0x4f, 0x70, 0x74, 0x73, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6f, 0x70, + 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, + 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x22, 0x9f, 0x01, 0x0a, 0x1a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, + 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x6f, 0x70, 0x69, 0x63, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x84, 0x01, 0x0a, 0x15, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, + 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, + 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x86, 0x01, 0x0a, + 0x17, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, + 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x86, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x54, 0x61, 0x6b, 0x65, 0x6e, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, + 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, + 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x9f, + 0x01, 0x0a, 0x18, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, + 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x22, 0x7b, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0xb9, 0x01, + 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x93, 0x01, 0x0a, 0x15, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x2f, + 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, + 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, + 0xb5, 0x01, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6d, + 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, + 0x6e, 0x66, 0x6f, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x40, 0x0a, 0x0e, 0x4c, 0x6f, 0x61, 0x64, 0x65, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x68, 0x6f, 0x6f, + 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, + 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x0e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, + 0x0a, 0x0b, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x33, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x54, 0x49, + 0x4e, 0x55, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, + 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x52, 0x45, + 0x54, 0x55, 0x52, 0x4e, 0x10, 0x02, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, + 0x76, 0x0a, 0x0a, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x79, 0x73, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x73, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, + 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x36, 0x0a, 0x08, 0x48, 0x6f, 0x6f, 0x6b, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x22, + 0xe8, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x65, 0x65, 0x72, + 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, + 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x76, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x56, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, + 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x22, 0xc9, 0x02, 0x0a, 0x0a, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x65, 0x65, 0x72, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x70, 0x65, + 0x72, 0x75, 0x73, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x53, + 0x75, 0x70, 0x65, 0x72, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6e, 0x6f, 0x6e, + 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6e, 0x6f, + 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x6e, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x63, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x6e, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x64, 0x6e, 0x22, 0x9d, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x6f, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x03, 0x71, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x6d, + 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x34, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x33, 0x0a, 0x0b, + 0x54, 0x6f, 0x70, 0x69, 0x63, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x71, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x71, 0x6f, + 0x73, 0x22, 0x63, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, + 0x71, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x71, 0x6f, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x72, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x02, 0x72, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x61, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x03, 0x72, 0x61, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x6e, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x02, 0x6e, 0x6c, 0x22, 0x7a, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x79, 0x73, 0x64, 0x65, 0x73, 0x63, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x73, 0x64, 0x65, 0x73, 0x63, 0x72, 0x12, + 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x32, 0xc7, 0x0f, 0x0a, 0x0c, 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x12, 0x5b, 0x0a, 0x10, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x12, 0x25, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, + 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x5d, 0x0a, 0x12, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x12, 0x27, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, + 0x57, 0x0a, 0x0f, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x12, 0x24, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, + 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0f, 0x4f, 0x6e, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x61, 0x63, 0x6b, 0x12, 0x24, 0x2e, 0x65, 0x6d, + 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, + 0x00, 0x12, 0x5b, 0x0a, 0x11, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x26, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x61, + 0x0a, 0x14, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x29, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, + 0x00, 0x12, 0x63, 0x0a, 0x14, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x65, 0x6d, 0x71, 0x78, + 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x11, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x26, 0x2e, 0x65, 0x6d, + 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, + 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x11, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x26, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x4f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x6e, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x28, 0x2e, 0x65, 0x6d, 0x71, 0x78, + 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, + 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x10, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x25, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, + 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x5f, + 0x0a, 0x13, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x64, 0x12, 0x28, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, + 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, + 0x63, 0x0a, 0x15, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, + 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x10, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x25, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, + 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, + 0x5d, 0x0a, 0x12, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x63, + 0x61, 0x72, 0x64, 0x65, 0x64, 0x12, 0x27, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, + 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x69, + 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x5d, + 0x0a, 0x12, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x6b, 0x65, 0x6e, + 0x6f, 0x76, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x6b, + 0x65, 0x6e, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, + 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x5f, 0x0a, + 0x13, 0x4f, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x28, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x5b, + 0x0a, 0x10, 0x4f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x12, 0x25, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, + 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x65, 0x6d, 0x71, 0x78, + 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x12, 0x4f, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, + 0x64, 0x12, 0x27, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, + 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x10, 0x4f, 0x6e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x12, 0x25, + 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, + 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0e, 0x4f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x41, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x23, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, + 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x41, 0x63, 0x6b, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x65, + 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x00, 0x42, 0x49, 0x0a, 0x0e, + 0x69, 0x6f, 0x2e, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0x42, 0x0f, + 0x45, 0x6d, 0x71, 0x78, 0x45, 0x78, 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x13, 0x65, 0x6d, 0x71, 0x78, 0x2e, 0x69, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, + 0x65, 0x78, 0x68, 0x6f, 0x6f, 0x6b, 0xaa, 0x02, 0x0e, 0x45, 0x6d, 0x71, 0x78, 0x2e, 0x45, 0x78, + 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protobuf_exhook_proto_rawDescOnce sync.Once + file_protobuf_exhook_proto_rawDescData = file_protobuf_exhook_proto_rawDesc +) + +func file_protobuf_exhook_proto_rawDescGZIP() []byte { + file_protobuf_exhook_proto_rawDescOnce.Do(func() { + file_protobuf_exhook_proto_rawDescData = protoimpl.X.CompressGZIP(file_protobuf_exhook_proto_rawDescData) + }) + return file_protobuf_exhook_proto_rawDescData +} + +var file_protobuf_exhook_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_protobuf_exhook_proto_msgTypes = make([]protoimpl.MessageInfo, 34) +var file_protobuf_exhook_proto_goTypes = []interface{}{ + (ClientAuthorizeRequest_AuthorizeReqType)(0), // 0: emqx.exhook.v2.ClientAuthorizeRequest.AuthorizeReqType + (ValuedResponse_ResponsedType)(0), // 1: emqx.exhook.v2.ValuedResponse.ResponsedType + (*ProviderLoadedRequest)(nil), // 2: emqx.exhook.v2.ProviderLoadedRequest + (*ProviderUnloadedRequest)(nil), // 3: emqx.exhook.v2.ProviderUnloadedRequest + (*ClientConnectRequest)(nil), // 4: emqx.exhook.v2.ClientConnectRequest + (*ClientConnackRequest)(nil), // 5: emqx.exhook.v2.ClientConnackRequest + (*ClientConnectedRequest)(nil), // 6: emqx.exhook.v2.ClientConnectedRequest + (*ClientDisconnectedRequest)(nil), // 7: emqx.exhook.v2.ClientDisconnectedRequest + (*ClientAuthenticateRequest)(nil), // 8: emqx.exhook.v2.ClientAuthenticateRequest + (*ClientAuthorizeRequest)(nil), // 9: emqx.exhook.v2.ClientAuthorizeRequest + (*ClientSubscribeRequest)(nil), // 10: emqx.exhook.v2.ClientSubscribeRequest + (*ClientUnsubscribeRequest)(nil), // 11: emqx.exhook.v2.ClientUnsubscribeRequest + (*SessionCreatedRequest)(nil), // 12: emqx.exhook.v2.SessionCreatedRequest + (*SessionSubscribedRequest)(nil), // 13: emqx.exhook.v2.SessionSubscribedRequest + (*SessionUnsubscribedRequest)(nil), // 14: emqx.exhook.v2.SessionUnsubscribedRequest + (*SessionResumedRequest)(nil), // 15: emqx.exhook.v2.SessionResumedRequest + (*SessionDiscardedRequest)(nil), // 16: emqx.exhook.v2.SessionDiscardedRequest + (*SessionTakenoverRequest)(nil), // 17: emqx.exhook.v2.SessionTakenoverRequest + (*SessionTerminatedRequest)(nil), // 18: emqx.exhook.v2.SessionTerminatedRequest + (*MessagePublishRequest)(nil), // 19: emqx.exhook.v2.MessagePublishRequest + (*MessageDeliveredRequest)(nil), // 20: emqx.exhook.v2.MessageDeliveredRequest + (*MessageDroppedRequest)(nil), // 21: emqx.exhook.v2.MessageDroppedRequest + (*MessageAckedRequest)(nil), // 22: emqx.exhook.v2.MessageAckedRequest + (*LoadedResponse)(nil), // 23: emqx.exhook.v2.LoadedResponse + (*ValuedResponse)(nil), // 24: emqx.exhook.v2.ValuedResponse + (*EmptySuccess)(nil), // 25: emqx.exhook.v2.EmptySuccess + (*BrokerInfo)(nil), // 26: emqx.exhook.v2.BrokerInfo + (*HookSpec)(nil), // 27: emqx.exhook.v2.HookSpec + (*ConnInfo)(nil), // 28: emqx.exhook.v2.ConnInfo + (*ClientInfo)(nil), // 29: emqx.exhook.v2.ClientInfo + (*Message)(nil), // 30: emqx.exhook.v2.Message + (*Property)(nil), // 31: emqx.exhook.v2.Property + (*TopicFilter)(nil), // 32: emqx.exhook.v2.TopicFilter + (*SubOpts)(nil), // 33: emqx.exhook.v2.SubOpts + (*RequestMeta)(nil), // 34: emqx.exhook.v2.RequestMeta + nil, // 35: emqx.exhook.v2.Message.HeadersEntry +} +var file_protobuf_exhook_proto_depIdxs = []int32{ + 26, // 0: emqx.exhook.v2.ProviderLoadedRequest.broker:type_name -> emqx.exhook.v2.BrokerInfo + 34, // 1: emqx.exhook.v2.ProviderLoadedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 34, // 2: emqx.exhook.v2.ProviderUnloadedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 28, // 3: emqx.exhook.v2.ClientConnectRequest.conninfo:type_name -> emqx.exhook.v2.ConnInfo + 31, // 4: emqx.exhook.v2.ClientConnectRequest.props:type_name -> emqx.exhook.v2.Property + 34, // 5: emqx.exhook.v2.ClientConnectRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 28, // 6: emqx.exhook.v2.ClientConnackRequest.conninfo:type_name -> emqx.exhook.v2.ConnInfo + 31, // 7: emqx.exhook.v2.ClientConnackRequest.props:type_name -> emqx.exhook.v2.Property + 34, // 8: emqx.exhook.v2.ClientConnackRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 9: emqx.exhook.v2.ClientConnectedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 10: emqx.exhook.v2.ClientConnectedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 11: emqx.exhook.v2.ClientDisconnectedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 12: emqx.exhook.v2.ClientDisconnectedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 13: emqx.exhook.v2.ClientAuthenticateRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 14: emqx.exhook.v2.ClientAuthenticateRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 15: emqx.exhook.v2.ClientAuthorizeRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 0, // 16: emqx.exhook.v2.ClientAuthorizeRequest.type:type_name -> emqx.exhook.v2.ClientAuthorizeRequest.AuthorizeReqType + 34, // 17: emqx.exhook.v2.ClientAuthorizeRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 18: emqx.exhook.v2.ClientSubscribeRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 31, // 19: emqx.exhook.v2.ClientSubscribeRequest.props:type_name -> emqx.exhook.v2.Property + 32, // 20: emqx.exhook.v2.ClientSubscribeRequest.topic_filters:type_name -> emqx.exhook.v2.TopicFilter + 34, // 21: emqx.exhook.v2.ClientSubscribeRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 22: emqx.exhook.v2.ClientUnsubscribeRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 31, // 23: emqx.exhook.v2.ClientUnsubscribeRequest.props:type_name -> emqx.exhook.v2.Property + 32, // 24: emqx.exhook.v2.ClientUnsubscribeRequest.topic_filters:type_name -> emqx.exhook.v2.TopicFilter + 34, // 25: emqx.exhook.v2.ClientUnsubscribeRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 26: emqx.exhook.v2.SessionCreatedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 27: emqx.exhook.v2.SessionCreatedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 28: emqx.exhook.v2.SessionSubscribedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 33, // 29: emqx.exhook.v2.SessionSubscribedRequest.subopts:type_name -> emqx.exhook.v2.SubOpts + 34, // 30: emqx.exhook.v2.SessionSubscribedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 31: emqx.exhook.v2.SessionUnsubscribedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 32: emqx.exhook.v2.SessionUnsubscribedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 33: emqx.exhook.v2.SessionResumedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 34: emqx.exhook.v2.SessionResumedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 35: emqx.exhook.v2.SessionDiscardedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 36: emqx.exhook.v2.SessionDiscardedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 37: emqx.exhook.v2.SessionTakenoverRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 38: emqx.exhook.v2.SessionTakenoverRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 39: emqx.exhook.v2.SessionTerminatedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 34, // 40: emqx.exhook.v2.SessionTerminatedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 30, // 41: emqx.exhook.v2.MessagePublishRequest.message:type_name -> emqx.exhook.v2.Message + 34, // 42: emqx.exhook.v2.MessagePublishRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 43: emqx.exhook.v2.MessageDeliveredRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 30, // 44: emqx.exhook.v2.MessageDeliveredRequest.message:type_name -> emqx.exhook.v2.Message + 34, // 45: emqx.exhook.v2.MessageDeliveredRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 30, // 46: emqx.exhook.v2.MessageDroppedRequest.message:type_name -> emqx.exhook.v2.Message + 34, // 47: emqx.exhook.v2.MessageDroppedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 29, // 48: emqx.exhook.v2.MessageAckedRequest.clientinfo:type_name -> emqx.exhook.v2.ClientInfo + 30, // 49: emqx.exhook.v2.MessageAckedRequest.message:type_name -> emqx.exhook.v2.Message + 34, // 50: emqx.exhook.v2.MessageAckedRequest.meta:type_name -> emqx.exhook.v2.RequestMeta + 27, // 51: emqx.exhook.v2.LoadedResponse.hooks:type_name -> emqx.exhook.v2.HookSpec + 1, // 52: emqx.exhook.v2.ValuedResponse.type:type_name -> emqx.exhook.v2.ValuedResponse.ResponsedType + 30, // 53: emqx.exhook.v2.ValuedResponse.message:type_name -> emqx.exhook.v2.Message + 35, // 54: emqx.exhook.v2.Message.headers:type_name -> emqx.exhook.v2.Message.HeadersEntry + 2, // 55: emqx.exhook.v2.HookProvider.OnProviderLoaded:input_type -> emqx.exhook.v2.ProviderLoadedRequest + 3, // 56: emqx.exhook.v2.HookProvider.OnProviderUnloaded:input_type -> emqx.exhook.v2.ProviderUnloadedRequest + 4, // 57: emqx.exhook.v2.HookProvider.OnClientConnect:input_type -> emqx.exhook.v2.ClientConnectRequest + 5, // 58: emqx.exhook.v2.HookProvider.OnClientConnack:input_type -> emqx.exhook.v2.ClientConnackRequest + 6, // 59: emqx.exhook.v2.HookProvider.OnClientConnected:input_type -> emqx.exhook.v2.ClientConnectedRequest + 7, // 60: emqx.exhook.v2.HookProvider.OnClientDisconnected:input_type -> emqx.exhook.v2.ClientDisconnectedRequest + 8, // 61: emqx.exhook.v2.HookProvider.OnClientAuthenticate:input_type -> emqx.exhook.v2.ClientAuthenticateRequest + 9, // 62: emqx.exhook.v2.HookProvider.OnClientAuthorize:input_type -> emqx.exhook.v2.ClientAuthorizeRequest + 10, // 63: emqx.exhook.v2.HookProvider.OnClientSubscribe:input_type -> emqx.exhook.v2.ClientSubscribeRequest + 11, // 64: emqx.exhook.v2.HookProvider.OnClientUnsubscribe:input_type -> emqx.exhook.v2.ClientUnsubscribeRequest + 12, // 65: emqx.exhook.v2.HookProvider.OnSessionCreated:input_type -> emqx.exhook.v2.SessionCreatedRequest + 13, // 66: emqx.exhook.v2.HookProvider.OnSessionSubscribed:input_type -> emqx.exhook.v2.SessionSubscribedRequest + 14, // 67: emqx.exhook.v2.HookProvider.OnSessionUnsubscribed:input_type -> emqx.exhook.v2.SessionUnsubscribedRequest + 15, // 68: emqx.exhook.v2.HookProvider.OnSessionResumed:input_type -> emqx.exhook.v2.SessionResumedRequest + 16, // 69: emqx.exhook.v2.HookProvider.OnSessionDiscarded:input_type -> emqx.exhook.v2.SessionDiscardedRequest + 17, // 70: emqx.exhook.v2.HookProvider.OnSessionTakenover:input_type -> emqx.exhook.v2.SessionTakenoverRequest + 18, // 71: emqx.exhook.v2.HookProvider.OnSessionTerminated:input_type -> emqx.exhook.v2.SessionTerminatedRequest + 19, // 72: emqx.exhook.v2.HookProvider.OnMessagePublish:input_type -> emqx.exhook.v2.MessagePublishRequest + 20, // 73: emqx.exhook.v2.HookProvider.OnMessageDelivered:input_type -> emqx.exhook.v2.MessageDeliveredRequest + 21, // 74: emqx.exhook.v2.HookProvider.OnMessageDropped:input_type -> emqx.exhook.v2.MessageDroppedRequest + 22, // 75: emqx.exhook.v2.HookProvider.OnMessageAcked:input_type -> emqx.exhook.v2.MessageAckedRequest + 23, // 76: emqx.exhook.v2.HookProvider.OnProviderLoaded:output_type -> emqx.exhook.v2.LoadedResponse + 25, // 77: emqx.exhook.v2.HookProvider.OnProviderUnloaded:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 78: emqx.exhook.v2.HookProvider.OnClientConnect:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 79: emqx.exhook.v2.HookProvider.OnClientConnack:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 80: emqx.exhook.v2.HookProvider.OnClientConnected:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 81: emqx.exhook.v2.HookProvider.OnClientDisconnected:output_type -> emqx.exhook.v2.EmptySuccess + 24, // 82: emqx.exhook.v2.HookProvider.OnClientAuthenticate:output_type -> emqx.exhook.v2.ValuedResponse + 24, // 83: emqx.exhook.v2.HookProvider.OnClientAuthorize:output_type -> emqx.exhook.v2.ValuedResponse + 25, // 84: emqx.exhook.v2.HookProvider.OnClientSubscribe:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 85: emqx.exhook.v2.HookProvider.OnClientUnsubscribe:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 86: emqx.exhook.v2.HookProvider.OnSessionCreated:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 87: emqx.exhook.v2.HookProvider.OnSessionSubscribed:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 88: emqx.exhook.v2.HookProvider.OnSessionUnsubscribed:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 89: emqx.exhook.v2.HookProvider.OnSessionResumed:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 90: emqx.exhook.v2.HookProvider.OnSessionDiscarded:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 91: emqx.exhook.v2.HookProvider.OnSessionTakenover:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 92: emqx.exhook.v2.HookProvider.OnSessionTerminated:output_type -> emqx.exhook.v2.EmptySuccess + 24, // 93: emqx.exhook.v2.HookProvider.OnMessagePublish:output_type -> emqx.exhook.v2.ValuedResponse + 25, // 94: emqx.exhook.v2.HookProvider.OnMessageDelivered:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 95: emqx.exhook.v2.HookProvider.OnMessageDropped:output_type -> emqx.exhook.v2.EmptySuccess + 25, // 96: emqx.exhook.v2.HookProvider.OnMessageAcked:output_type -> emqx.exhook.v2.EmptySuccess + 76, // [76:97] is the sub-list for method output_type + 55, // [55:76] is the sub-list for method input_type + 55, // [55:55] is the sub-list for extension type_name + 55, // [55:55] is the sub-list for extension extendee + 0, // [0:55] is the sub-list for field type_name +} + +func init() { file_protobuf_exhook_proto_init() } +func file_protobuf_exhook_proto_init() { + if File_protobuf_exhook_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protobuf_exhook_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProviderLoadedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProviderUnloadedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientConnectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientConnackRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientConnectedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientDisconnectedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientAuthenticateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientAuthorizeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientSubscribeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientUnsubscribeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionCreatedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionSubscribedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionUnsubscribedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionResumedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionDiscardedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionTakenoverRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionTerminatedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessagePublishRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageDeliveredRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageDroppedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageAckedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LoadedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValuedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmptySuccess); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BrokerInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HookSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Property); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicFilter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubOpts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_exhook_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_protobuf_exhook_proto_msgTypes[22].OneofWrappers = []interface{}{ + (*ValuedResponse_BoolResult)(nil), + (*ValuedResponse_Message)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protobuf_exhook_proto_rawDesc, + NumEnums: 2, + NumMessages: 34, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_protobuf_exhook_proto_goTypes, + DependencyIndexes: file_protobuf_exhook_proto_depIdxs, + EnumInfos: file_protobuf_exhook_proto_enumTypes, + MessageInfos: file_protobuf_exhook_proto_msgTypes, + }.Build() + File_protobuf_exhook_proto = out.File + file_protobuf_exhook_proto_rawDesc = nil + file_protobuf_exhook_proto_goTypes = nil + file_protobuf_exhook_proto_depIdxs = nil +} diff --git a/iothub/protobuf/exhook.proto b/iothub/protobuf/exhook.proto new file mode 100644 index 0000000000000000000000000000000000000000..5c39fdc54ab3cdd6cb4fdaf5204060a4e66e2974 --- /dev/null +++ b/iothub/protobuf/exhook.proto @@ -0,0 +1,499 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------ + +syntax = "proto3"; + +option csharp_namespace = "Emqx.Exhook.V2"; +option go_package = "emqx.io/grpc/exhook"; +option java_multiple_files = true; +option java_package = "io.emqx.exhook"; +option java_outer_classname = "EmqxExHookProto"; + +// The exhook proto version should be fixed as `v2` in EMQX v5.x +// to make sure the exhook proto version is compatible +package emqx.exhook.v2; + +service HookProvider { + + rpc OnProviderLoaded(ProviderLoadedRequest) returns (LoadedResponse) {}; + + rpc OnProviderUnloaded(ProviderUnloadedRequest) returns (EmptySuccess) {}; + + rpc OnClientConnect(ClientConnectRequest) returns (EmptySuccess) {}; + + rpc OnClientConnack(ClientConnackRequest) returns (EmptySuccess) {}; + + rpc OnClientConnected(ClientConnectedRequest) returns (EmptySuccess) {}; + + rpc OnClientDisconnected(ClientDisconnectedRequest) returns (EmptySuccess) {}; + + rpc OnClientAuthenticate(ClientAuthenticateRequest) returns (ValuedResponse) {}; + + rpc OnClientAuthorize(ClientAuthorizeRequest) returns (ValuedResponse) {}; + + rpc OnClientSubscribe(ClientSubscribeRequest) returns (EmptySuccess) {}; + + rpc OnClientUnsubscribe(ClientUnsubscribeRequest) returns (EmptySuccess) {}; + + rpc OnSessionCreated(SessionCreatedRequest) returns (EmptySuccess) {}; + + rpc OnSessionSubscribed(SessionSubscribedRequest) returns (EmptySuccess) {}; + + rpc OnSessionUnsubscribed(SessionUnsubscribedRequest) returns (EmptySuccess) {}; + + rpc OnSessionResumed(SessionResumedRequest) returns (EmptySuccess) {}; + + rpc OnSessionDiscarded(SessionDiscardedRequest) returns (EmptySuccess) {}; + + rpc OnSessionTakenover(SessionTakenoverRequest) returns (EmptySuccess) {}; + + rpc OnSessionTerminated(SessionTerminatedRequest) returns (EmptySuccess) {}; + + rpc OnMessagePublish(MessagePublishRequest) returns (ValuedResponse) {}; + + rpc OnMessageDelivered(MessageDeliveredRequest) returns (EmptySuccess) {}; + + rpc OnMessageDropped(MessageDroppedRequest) returns (EmptySuccess) {}; + + rpc OnMessageAcked(MessageAckedRequest) returns (EmptySuccess) {}; +} + +//------------------------------------------------------------------------------ +// Request +//------------------------------------------------------------------------------ + +message ProviderLoadedRequest { + + BrokerInfo broker = 1; + + RequestMeta meta = 2; +} + +message ProviderUnloadedRequest { + + RequestMeta meta = 1; +} + +message ClientConnectRequest { + + ConnInfo conninfo = 1; + + // MQTT CONNECT packet's properties (MQTT v5.0) + // + // It should be empty on MQTT v3.1.1/v3.1 or others protocol + repeated Property props = 2; + + RequestMeta meta = 3; +} + +message ClientConnackRequest { + + ConnInfo conninfo = 1; + + string result_code = 2; + + repeated Property props = 3; + + RequestMeta meta = 4; +} + +message ClientConnectedRequest { + + ClientInfo clientinfo = 1; + + RequestMeta meta = 2; +} + +message ClientDisconnectedRequest { + + ClientInfo clientinfo = 1; + + string reason = 2; + + RequestMeta meta = 3; +} + +message ClientAuthenticateRequest { + + ClientInfo clientinfo = 1; + + bool result = 2; + + RequestMeta meta = 3; +} + +message ClientAuthorizeRequest { + + ClientInfo clientinfo = 1; + + enum AuthorizeReqType { + + PUBLISH = 0; + + SUBSCRIBE = 1; + } + + AuthorizeReqType type = 2; + + string topic = 3; + + bool result = 4; + + RequestMeta meta = 5; +} + +message ClientSubscribeRequest { + + ClientInfo clientinfo = 1; + + repeated Property props = 2; + + repeated TopicFilter topic_filters = 3; + + RequestMeta meta = 4; +} + +message ClientUnsubscribeRequest { + + ClientInfo clientinfo = 1; + + repeated Property props = 2; + + repeated TopicFilter topic_filters = 3; + + RequestMeta meta = 4; +} + +message SessionCreatedRequest { + + ClientInfo clientinfo = 1; + + RequestMeta meta = 2; +} + +message SessionSubscribedRequest { + + ClientInfo clientinfo = 1; + + string topic = 2; + + SubOpts subopts = 3; + + RequestMeta meta = 4; +} + +message SessionUnsubscribedRequest { + + ClientInfo clientinfo = 1; + + string topic = 2; + + RequestMeta meta = 3; +} + +message SessionResumedRequest { + + ClientInfo clientinfo = 1; + + RequestMeta meta = 2; +} + +message SessionDiscardedRequest { + + ClientInfo clientinfo = 1; + + RequestMeta meta = 2; +} + +message SessionTakenoverRequest { + + ClientInfo clientinfo = 1; + + RequestMeta meta = 2; +} + +message SessionTerminatedRequest { + + ClientInfo clientinfo = 1; + + string reason = 2; + + RequestMeta meta = 3; +} + +message MessagePublishRequest { + + Message message = 1; + + RequestMeta meta = 2; +} + +message MessageDeliveredRequest { + + ClientInfo clientinfo = 1; + + Message message = 2; + + RequestMeta meta = 3; +} + +message MessageDroppedRequest { + + Message message = 1; + + string reason = 2; + + RequestMeta meta = 3; +} + +message MessageAckedRequest { + + ClientInfo clientinfo = 1; + + Message message = 2; + + RequestMeta meta = 3; +} + +//------------------------------------------------------------------------------ +// Response +//------------------------------------------------------------------------------ + +// Responsed by `ProviderLoadedRequest` + +message LoadedResponse { + + repeated HookSpec hooks = 1; +} + +// Responsed by `ClientAuthenticateRequest` `ClientAuthorizeRequest` `MessagePublishRequest` + +message ValuedResponse { + + // The responded value type + // - contiune: Use the responded value and execute the next hook + // - ignore: Ignore the responded value + // - stop_and_return: Use the responded value and stop the chain executing + enum ResponsedType { + + CONTINUE = 0; + + IGNORE = 1; + + STOP_AND_RETURN = 2; + } + + ResponsedType type = 1; + + oneof value { + + // Boolean result, used on the 'client.authenticate', 'client.authorize' hooks + bool bool_result = 3; + + // Message result, used on the 'message.*' hooks + Message message = 4; + } +} + +// no Response by other Requests + +message EmptySuccess { } + +//------------------------------------------------------------------------------ +// Basic data types +//------------------------------------------------------------------------------ + +message BrokerInfo { + + string version = 1; + + string sysdescr = 2; + + int64 uptime = 3; + + string datetime = 4; +} + + +message HookSpec { + + // The registered hooks name + // + // Available value: + // "client.connect", "client.connack" + // "client.connected", "client.disconnected" + // "client.authenticate", "client.authorize" + // "client.subscribe", "client.unsubscribe" + // + // "session.created", "session.subscribed" + // "session.unsubscribed", "session.resumed" + // "session.discarded", "session.takenover" + // "session.terminated" + // + // "message.publish", "message.delivered" + // "message.acked", "message.dropped" + string name = 1; + + // The topic filters for message hooks + repeated string topics = 2; +} + +message ConnInfo { + + string node = 1; + + string clientid = 2; + + string username = 3; + + string peerhost = 4; + + uint32 sockport = 5; + + string proto_name = 6; + + string proto_ver = 7; + + uint32 keepalive = 8; +} + +message ClientInfo { + + string node = 1; + + string clientid = 2; + + string username = 3; + + string password = 4; + + string peerhost = 5; + + uint32 sockport = 6; + + string protocol = 7; + + string mountpoint = 8; + + bool is_superuser = 9; + + bool anonymous = 10; + + // common name of client TLS cert + string cn = 11; + + // subject of client TLS cert + string dn = 12; +} + +message Message { + + string node = 1; + + string id = 2; + + uint32 qos = 3; + + string from = 4; + + string topic = 5; + + bytes payload = 6; + + uint64 timestamp = 7; + + // The key of header can be: + // - username: + // * Readonly + // * The username of sender client + // * Value type: utf8 string + // - protocol: + // * Readonly + // * The protocol name of sender client + // * Value type: string enum with "mqtt", "mqtt-sn", ... + // - peerhost: + // * Readonly + // * The peerhost of sender client + // * Value type: ip address string + // - allow_publish: + // * Writable + // * Whether to allow the message to be published by emqx + // * Value type: string enum with "true", "false", default is "true" + // + // Notes: All header may be missing, which means that the message does not + // carry these headers. We can guarantee that clients coming from MQTT, + // MQTT-SN, CoAP, LwM2M and other natively supported protocol clients will + // carry these headers, but there is no guarantee that messages published + // by other means will do, e.g. messages published by HTTP-API + map headers = 8; +} + +message Property { + + string name = 1; + + string value = 2; +} + +message TopicFilter { + + string name = 1; + + uint32 qos = 2; +} + +message SubOpts { + + // The QoS level + uint32 qos = 1; + + // The group name for shared subscription + string share = 2; + + // The Retain Handling option (MQTT v5.0) + // + // 0 = Send retained messages at the time of the subscribe + // 1 = Send retained messages at subscribe only if the subscription does + // not currently exist + // 2 = Do not send retained messages at the time of the subscribe + uint32 rh = 3; + + // The Retain as Published option (MQTT v5.0) + // + // If 1, Application Messages forwarded using this subscription keep the + // RETAIN flag they were published with. + // If 0, Application Messages forwarded using this subscription have the + // RETAIN flag set to 0. + // Retained messages sent when the subscription is established have the RETAIN flag set to 1. + uint32 rap = 4; + + // The No Local option (MQTT v5.0) + // + // If the value is 1, Application Messages MUST NOT be forwarded to a + // connection with a ClientID equal to the ClientID of the publishing + uint32 nl = 5; +} + +message RequestMeta { + + string node = 1; + + string version = 2; + + string sysdescr = 3; + + string cluster_name = 4; +} \ No newline at end of file diff --git a/iothub/protobuf/exhook_grpc.pb.go b/iothub/protobuf/exhook_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..486ecec46ca0c92d723094022095de8fa09a0fbb --- /dev/null +++ b/iothub/protobuf/exhook_grpc.pb.go @@ -0,0 +1,825 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.18.1 +// source: protobuf/exhook.proto + +package exhook + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// HookProviderClient is the client API for HookProvider service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HookProviderClient interface { + OnProviderLoaded(ctx context.Context, in *ProviderLoadedRequest, opts ...grpc.CallOption) (*LoadedResponse, error) + OnProviderUnloaded(ctx context.Context, in *ProviderUnloadedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnClientConnect(ctx context.Context, in *ClientConnectRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnClientConnack(ctx context.Context, in *ClientConnackRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnClientConnected(ctx context.Context, in *ClientConnectedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnClientDisconnected(ctx context.Context, in *ClientDisconnectedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnClientAuthenticate(ctx context.Context, in *ClientAuthenticateRequest, opts ...grpc.CallOption) (*ValuedResponse, error) + OnClientAuthorize(ctx context.Context, in *ClientAuthorizeRequest, opts ...grpc.CallOption) (*ValuedResponse, error) + OnClientSubscribe(ctx context.Context, in *ClientSubscribeRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnClientUnsubscribe(ctx context.Context, in *ClientUnsubscribeRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionCreated(ctx context.Context, in *SessionCreatedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionSubscribed(ctx context.Context, in *SessionSubscribedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionUnsubscribed(ctx context.Context, in *SessionUnsubscribedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionResumed(ctx context.Context, in *SessionResumedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionDiscarded(ctx context.Context, in *SessionDiscardedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionTakenover(ctx context.Context, in *SessionTakenoverRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnSessionTerminated(ctx context.Context, in *SessionTerminatedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnMessagePublish(ctx context.Context, in *MessagePublishRequest, opts ...grpc.CallOption) (*ValuedResponse, error) + OnMessageDelivered(ctx context.Context, in *MessageDeliveredRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnMessageDropped(ctx context.Context, in *MessageDroppedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) + OnMessageAcked(ctx context.Context, in *MessageAckedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) +} + +type hookProviderClient struct { + cc grpc.ClientConnInterface +} + +func NewHookProviderClient(cc grpc.ClientConnInterface) HookProviderClient { + return &hookProviderClient{cc} +} + +func (c *hookProviderClient) OnProviderLoaded(ctx context.Context, in *ProviderLoadedRequest, opts ...grpc.CallOption) (*LoadedResponse, error) { + out := new(LoadedResponse) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnProviderLoaded", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnProviderUnloaded(ctx context.Context, in *ProviderUnloadedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnProviderUnloaded", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientConnect(ctx context.Context, in *ClientConnectRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientConnect", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientConnack(ctx context.Context, in *ClientConnackRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientConnack", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientConnected(ctx context.Context, in *ClientConnectedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientConnected", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientDisconnected(ctx context.Context, in *ClientDisconnectedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientDisconnected", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientAuthenticate(ctx context.Context, in *ClientAuthenticateRequest, opts ...grpc.CallOption) (*ValuedResponse, error) { + out := new(ValuedResponse) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientAuthenticate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientAuthorize(ctx context.Context, in *ClientAuthorizeRequest, opts ...grpc.CallOption) (*ValuedResponse, error) { + out := new(ValuedResponse) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientAuthorize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientSubscribe(ctx context.Context, in *ClientSubscribeRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientSubscribe", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnClientUnsubscribe(ctx context.Context, in *ClientUnsubscribeRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnClientUnsubscribe", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionCreated(ctx context.Context, in *SessionCreatedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionCreated", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionSubscribed(ctx context.Context, in *SessionSubscribedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionSubscribed", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionUnsubscribed(ctx context.Context, in *SessionUnsubscribedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionUnsubscribed", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionResumed(ctx context.Context, in *SessionResumedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionResumed", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionDiscarded(ctx context.Context, in *SessionDiscardedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionDiscarded", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionTakenover(ctx context.Context, in *SessionTakenoverRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionTakenover", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnSessionTerminated(ctx context.Context, in *SessionTerminatedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnSessionTerminated", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnMessagePublish(ctx context.Context, in *MessagePublishRequest, opts ...grpc.CallOption) (*ValuedResponse, error) { + out := new(ValuedResponse) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnMessagePublish", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnMessageDelivered(ctx context.Context, in *MessageDeliveredRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnMessageDelivered", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnMessageDropped(ctx context.Context, in *MessageDroppedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnMessageDropped", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookProviderClient) OnMessageAcked(ctx context.Context, in *MessageAckedRequest, opts ...grpc.CallOption) (*EmptySuccess, error) { + out := new(EmptySuccess) + err := c.cc.Invoke(ctx, "/emqx.exhook.v2.HookProvider/OnMessageAcked", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HookProviderServer is the server API for HookProvider service. +// All implementations must embed UnimplementedHookProviderServer +// for forward compatibility +type HookProviderServer interface { + OnProviderLoaded(context.Context, *ProviderLoadedRequest) (*LoadedResponse, error) + OnProviderUnloaded(context.Context, *ProviderUnloadedRequest) (*EmptySuccess, error) + OnClientConnect(context.Context, *ClientConnectRequest) (*EmptySuccess, error) + OnClientConnack(context.Context, *ClientConnackRequest) (*EmptySuccess, error) + OnClientConnected(context.Context, *ClientConnectedRequest) (*EmptySuccess, error) + OnClientDisconnected(context.Context, *ClientDisconnectedRequest) (*EmptySuccess, error) + OnClientAuthenticate(context.Context, *ClientAuthenticateRequest) (*ValuedResponse, error) + OnClientAuthorize(context.Context, *ClientAuthorizeRequest) (*ValuedResponse, error) + OnClientSubscribe(context.Context, *ClientSubscribeRequest) (*EmptySuccess, error) + OnClientUnsubscribe(context.Context, *ClientUnsubscribeRequest) (*EmptySuccess, error) + OnSessionCreated(context.Context, *SessionCreatedRequest) (*EmptySuccess, error) + OnSessionSubscribed(context.Context, *SessionSubscribedRequest) (*EmptySuccess, error) + OnSessionUnsubscribed(context.Context, *SessionUnsubscribedRequest) (*EmptySuccess, error) + OnSessionResumed(context.Context, *SessionResumedRequest) (*EmptySuccess, error) + OnSessionDiscarded(context.Context, *SessionDiscardedRequest) (*EmptySuccess, error) + OnSessionTakenover(context.Context, *SessionTakenoverRequest) (*EmptySuccess, error) + OnSessionTerminated(context.Context, *SessionTerminatedRequest) (*EmptySuccess, error) + OnMessagePublish(context.Context, *MessagePublishRequest) (*ValuedResponse, error) + OnMessageDelivered(context.Context, *MessageDeliveredRequest) (*EmptySuccess, error) + OnMessageDropped(context.Context, *MessageDroppedRequest) (*EmptySuccess, error) + OnMessageAcked(context.Context, *MessageAckedRequest) (*EmptySuccess, error) + mustEmbedUnimplementedHookProviderServer() +} + +// UnimplementedHookProviderServer must be embedded to have forward compatible implementations. +type UnimplementedHookProviderServer struct { +} + +func (UnimplementedHookProviderServer) OnProviderLoaded(context.Context, *ProviderLoadedRequest) (*LoadedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnProviderLoaded not implemented") +} +func (UnimplementedHookProviderServer) OnProviderUnloaded(context.Context, *ProviderUnloadedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnProviderUnloaded not implemented") +} +func (UnimplementedHookProviderServer) OnClientConnect(context.Context, *ClientConnectRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientConnect not implemented") +} +func (UnimplementedHookProviderServer) OnClientConnack(context.Context, *ClientConnackRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientConnack not implemented") +} +func (UnimplementedHookProviderServer) OnClientConnected(context.Context, *ClientConnectedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientConnected not implemented") +} +func (UnimplementedHookProviderServer) OnClientDisconnected(context.Context, *ClientDisconnectedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientDisconnected not implemented") +} +func (UnimplementedHookProviderServer) OnClientAuthenticate(context.Context, *ClientAuthenticateRequest) (*ValuedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientAuthenticate not implemented") +} +func (UnimplementedHookProviderServer) OnClientAuthorize(context.Context, *ClientAuthorizeRequest) (*ValuedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientAuthorize not implemented") +} +func (UnimplementedHookProviderServer) OnClientSubscribe(context.Context, *ClientSubscribeRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientSubscribe not implemented") +} +func (UnimplementedHookProviderServer) OnClientUnsubscribe(context.Context, *ClientUnsubscribeRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnClientUnsubscribe not implemented") +} +func (UnimplementedHookProviderServer) OnSessionCreated(context.Context, *SessionCreatedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionCreated not implemented") +} +func (UnimplementedHookProviderServer) OnSessionSubscribed(context.Context, *SessionSubscribedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionSubscribed not implemented") +} +func (UnimplementedHookProviderServer) OnSessionUnsubscribed(context.Context, *SessionUnsubscribedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionUnsubscribed not implemented") +} +func (UnimplementedHookProviderServer) OnSessionResumed(context.Context, *SessionResumedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionResumed not implemented") +} +func (UnimplementedHookProviderServer) OnSessionDiscarded(context.Context, *SessionDiscardedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionDiscarded not implemented") +} +func (UnimplementedHookProviderServer) OnSessionTakenover(context.Context, *SessionTakenoverRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionTakenover not implemented") +} +func (UnimplementedHookProviderServer) OnSessionTerminated(context.Context, *SessionTerminatedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnSessionTerminated not implemented") +} +func (UnimplementedHookProviderServer) OnMessagePublish(context.Context, *MessagePublishRequest) (*ValuedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnMessagePublish not implemented") +} +func (UnimplementedHookProviderServer) OnMessageDelivered(context.Context, *MessageDeliveredRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnMessageDelivered not implemented") +} +func (UnimplementedHookProviderServer) OnMessageDropped(context.Context, *MessageDroppedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnMessageDropped not implemented") +} +func (UnimplementedHookProviderServer) OnMessageAcked(context.Context, *MessageAckedRequest) (*EmptySuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnMessageAcked not implemented") +} +func (UnimplementedHookProviderServer) mustEmbedUnimplementedHookProviderServer() {} + +// UnsafeHookProviderServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HookProviderServer will +// result in compilation errors. +type UnsafeHookProviderServer interface { + mustEmbedUnimplementedHookProviderServer() +} + +func RegisterHookProviderServer(s grpc.ServiceRegistrar, srv HookProviderServer) { + s.RegisterService(&HookProvider_ServiceDesc, srv) +} + +func _HookProvider_OnProviderLoaded_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ProviderLoadedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnProviderLoaded(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnProviderLoaded", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnProviderLoaded(ctx, req.(*ProviderLoadedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnProviderUnloaded_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ProviderUnloadedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnProviderUnloaded(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnProviderUnloaded", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnProviderUnloaded(ctx, req.(*ProviderUnloadedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientConnect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientConnectRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientConnect(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientConnect", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientConnect(ctx, req.(*ClientConnectRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientConnack_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientConnackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientConnack(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientConnack", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientConnack(ctx, req.(*ClientConnackRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientConnected_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientConnectedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientConnected(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientConnected", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientConnected(ctx, req.(*ClientConnectedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientDisconnected_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientDisconnectedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientDisconnected(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientDisconnected", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientDisconnected(ctx, req.(*ClientDisconnectedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientAuthenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientAuthenticateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientAuthenticate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientAuthenticate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientAuthenticate(ctx, req.(*ClientAuthenticateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientAuthorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientAuthorizeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientAuthorize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientAuthorize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientAuthorize(ctx, req.(*ClientAuthorizeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientSubscribeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientSubscribe(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientSubscribe", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientSubscribe(ctx, req.(*ClientSubscribeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnClientUnsubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientUnsubscribeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnClientUnsubscribe(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnClientUnsubscribe", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnClientUnsubscribe(ctx, req.(*ClientUnsubscribeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionCreated_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionCreatedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionCreated(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionCreated", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionCreated(ctx, req.(*SessionCreatedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionSubscribed_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionSubscribedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionSubscribed(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionSubscribed", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionSubscribed(ctx, req.(*SessionSubscribedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionUnsubscribed_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionUnsubscribedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionUnsubscribed(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionUnsubscribed", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionUnsubscribed(ctx, req.(*SessionUnsubscribedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionResumed_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionResumedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionResumed(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionResumed", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionResumed(ctx, req.(*SessionResumedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionDiscarded_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionDiscardedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionDiscarded(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionDiscarded", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionDiscarded(ctx, req.(*SessionDiscardedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionTakenover_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionTakenoverRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionTakenover(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionTakenover", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionTakenover(ctx, req.(*SessionTakenoverRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnSessionTerminated_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionTerminatedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnSessionTerminated(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnSessionTerminated", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnSessionTerminated(ctx, req.(*SessionTerminatedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnMessagePublish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MessagePublishRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnMessagePublish(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnMessagePublish", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnMessagePublish(ctx, req.(*MessagePublishRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnMessageDelivered_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MessageDeliveredRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnMessageDelivered(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnMessageDelivered", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnMessageDelivered(ctx, req.(*MessageDeliveredRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnMessageDropped_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MessageDroppedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnMessageDropped(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnMessageDropped", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnMessageDropped(ctx, req.(*MessageDroppedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookProvider_OnMessageAcked_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MessageAckedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookProviderServer).OnMessageAcked(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/emqx.exhook.v2.HookProvider/OnMessageAcked", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookProviderServer).OnMessageAcked(ctx, req.(*MessageAckedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HookProvider_ServiceDesc is the grpc.ServiceDesc for HookProvider service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HookProvider_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "emqx.exhook.v2.HookProvider", + HandlerType: (*HookProviderServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "OnProviderLoaded", + Handler: _HookProvider_OnProviderLoaded_Handler, + }, + { + MethodName: "OnProviderUnloaded", + Handler: _HookProvider_OnProviderUnloaded_Handler, + }, + { + MethodName: "OnClientConnect", + Handler: _HookProvider_OnClientConnect_Handler, + }, + { + MethodName: "OnClientConnack", + Handler: _HookProvider_OnClientConnack_Handler, + }, + { + MethodName: "OnClientConnected", + Handler: _HookProvider_OnClientConnected_Handler, + }, + { + MethodName: "OnClientDisconnected", + Handler: _HookProvider_OnClientDisconnected_Handler, + }, + { + MethodName: "OnClientAuthenticate", + Handler: _HookProvider_OnClientAuthenticate_Handler, + }, + { + MethodName: "OnClientAuthorize", + Handler: _HookProvider_OnClientAuthorize_Handler, + }, + { + MethodName: "OnClientSubscribe", + Handler: _HookProvider_OnClientSubscribe_Handler, + }, + { + MethodName: "OnClientUnsubscribe", + Handler: _HookProvider_OnClientUnsubscribe_Handler, + }, + { + MethodName: "OnSessionCreated", + Handler: _HookProvider_OnSessionCreated_Handler, + }, + { + MethodName: "OnSessionSubscribed", + Handler: _HookProvider_OnSessionSubscribed_Handler, + }, + { + MethodName: "OnSessionUnsubscribed", + Handler: _HookProvider_OnSessionUnsubscribed_Handler, + }, + { + MethodName: "OnSessionResumed", + Handler: _HookProvider_OnSessionResumed_Handler, + }, + { + MethodName: "OnSessionDiscarded", + Handler: _HookProvider_OnSessionDiscarded_Handler, + }, + { + MethodName: "OnSessionTakenover", + Handler: _HookProvider_OnSessionTakenover_Handler, + }, + { + MethodName: "OnSessionTerminated", + Handler: _HookProvider_OnSessionTerminated_Handler, + }, + { + MethodName: "OnMessagePublish", + Handler: _HookProvider_OnMessagePublish_Handler, + }, + { + MethodName: "OnMessageDelivered", + Handler: _HookProvider_OnMessageDelivered_Handler, + }, + { + MethodName: "OnMessageDropped", + Handler: _HookProvider_OnMessageDropped_Handler, + }, + { + MethodName: "OnMessageAcked", + Handler: _HookProvider_OnMessageAcked_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "protobuf/exhook.proto", +} diff --git a/iothub/reverse_control.go b/iothub/reverse_control.go new file mode 100644 index 0000000000000000000000000000000000000000..ef5d0c59b259828b6dcd351ab557384ec5fd57c2 --- /dev/null +++ b/iothub/reverse_control.go @@ -0,0 +1,25 @@ +package iothub + +// 指令下发 +/*func Control(assets, thingModel, device_name, parameter string, operation bool) error { + topic := fmt.Sprintf("control/%s/%s", assets, device_name) + log.Println(topic) + payload := fmt.Sprintf(`{"method":"control","data":{"parameter": "%s","operation":%t}}`, parameter, operation) + //Publish(*global.GVA_MQTT, topic, 1, payload) + return nil +} + +func ControlState(assets, thingModel, device_name string) (map[string]interface{}, error) { + topic := fmt.Sprintf("control/%s/%s", assets, device_name) + payload := fmt.Sprintf(`{"method":"state","data":{}}`) + if Publish(*global.GVA_MQTT, topic, 1, payload) != nil { + return nil, errors.New("下发获取状态参数指令失败") + } + select { + case state := <-controlState: + return state, nil + case <-time.After(10 * time.Second): + return nil, errors.New("请求指令状态超时") + } +} +*/ diff --git a/iothub/topic.go b/iothub/topic.go new file mode 100644 index 0000000000000000000000000000000000000000..fa0ac23575712f442f721decd90d9b622dfea990 --- /dev/null +++ b/iothub/topic.go @@ -0,0 +1,48 @@ +package iothub + +import ( + "pandax/pkg/rule_engine/message" + "strings" +) + +const ( + // Topic 上行 + RowTopic = `v1/devices/me/row` + TelemetryTopic = `v1/devices/me/telemetry` + AttributesTopic = `v1/devices/me/attributes` + + //网关子设备 + AttributesGatewayTopic = "v1/gateway/attributes" + TelemetryGatewayTopic = "v1/gateway/telemetry" + ConnectGatewayTopic = "v1/gateway/connect" + DisconnectGatewayTopic = "v1/gateway/disconnect" + + RpcReqReg = `v1/devices/me/rpc/request/(.*?)$` +) + +var IotHubTopic = NewIotHubTopic() + +type TopicMeg map[string]string + +// 消息的来源类型 +func NewIotHubTopic() TopicMeg { + return map[string]string{ + AttributesTopic: message.AttributesMes, + RowTopic: message.RowMes, + TelemetryTopic: message.TelemetryMes, + AttributesGatewayTopic: message.GATEWAY, + TelemetryGatewayTopic: message.GATEWAY, + ConnectGatewayTopic: message.GATEWAY, + DisconnectGatewayTopic: message.GATEWAY, + } +} + +func (iht TopicMeg) GetMessageType(topic string) string { + if meg, ok := iht[topic]; ok { + return meg + } + if strings.Contains(topic, "v1/devices/me/rpc/request") { + return message.RpcRequestMes + } + return "" +} diff --git a/main.go b/main.go index 2c9a3f8f6939fac0e4728e922d6e1f8952350036..09a8ff7e30f0d333c9667ea6cd8929213e8998a0 100644 --- a/main.go +++ b/main.go @@ -2,19 +2,25 @@ package main import ( "context" - "pandax/pkg/config" - + "fmt" "github.com/XM-GO/PandaKit/logger" + "github.com/XM-GO/PandaKit/rediscli" "github.com/XM-GO/PandaKit/restfulx" "github.com/XM-GO/PandaKit/starter" "github.com/spf13/cobra" "log" + "m7s.live/engine/v4" + _ "m7s.live/plugin/gb28181/v4" + _ "m7s.live/plugin/jessica/v4" + _ "m7s.live/plugin/rtmp/v4" "os" "os/signal" - "pandax/apps/job/jobs" + "pandax/iothub" + "pandax/pkg/config" "pandax/pkg/global" "pandax/pkg/initialize" "pandax/pkg/middleware" + "pandax/pkg/tdengine" "syscall" ) @@ -23,49 +29,62 @@ var ( ) var rootCmd = &cobra.Command{ - Use: "panda is the main component in the panda.", - Short: `panda is go gin frame`, + Use: "pandax is the main component in the panda.", + Short: `pandax is go go-restful frame`, PreRun: func(cmd *cobra.Command, args []string) { if configFile != "" { global.Conf = config.InitConfig(configFile) + log.Println(global.Conf.Log.Level) global.Log = logger.InitLog(global.Conf.Log.File.GetFilename(), global.Conf.Log.Level) dbGorm := starter.DbGorm{Type: global.Conf.Server.DbType} if global.Conf.Server.DbType == "mysql" { dbGorm.Dsn = global.Conf.Mysql.Dsn() dbGorm.MaxIdleConns = global.Conf.Mysql.MaxIdleConns dbGorm.MaxOpenConns = global.Conf.Mysql.MaxOpenConns - } else { - dbGorm.Dsn = global.Conf.Postgresql.PgDsn() - dbGorm.MaxIdleConns = global.Conf.Postgresql.MaxIdleConns - dbGorm.MaxOpenConns = global.Conf.Postgresql.MaxOpenConns } global.Db = dbGorm.GormInit() + global.Log.Infof("%s连接成功", global.Conf.Server.DbType) + client, err := rediscli.NewRedisClient(global.Conf.Redis.Host, global.Conf.Redis.Password, global.Conf.Redis.Port) + if err != nil { + global.Log.Panic("Redis连接错误") + } else { + global.Log.Info("Redis连接成功") + } + global.RedisDb = client + tDengine, err := tdengine.NewTdengine(global.Conf.Taos.Username, global.Conf.Taos.Password, global.Conf.Taos.Host, global.Conf.Taos.Database) + if err != nil { + global.Log.Panic("Tdengine连接错误") + } else { + global.Log.Info("Tdengine连接成功") + } + global.TdDb = tDengine initialize.InitTable() + // 初始化事件监听 + initialize.InitEvents() } else { global.Log.Panic("请配置config") } }, Run: func(cmd *cobra.Command, args []string) { - restfulx.UseAfterHandlerInterceptor(middleware.OperationHandler) // 前置 函数 restfulx.UseBeforeHandlerInterceptor(middleware.PermissionHandler) // 后置 函数 restfulx.UseAfterHandlerInterceptor(middleware.LogHandler) - go func() { - // 启动系统调度任务 - jobs.InitJob() - jobs.Setup() - }() + restfulx.UseAfterHandlerInterceptor(middleware.OperationHandler) app := initialize.InitRouter() global.Log.Info("路由初始化完成") app.Start(context.TODO()) + //开启IOTHUB + hs := iothub.InitEmqxHook(fmt.Sprintf(":%d", global.Conf.Server.GrpcPort)) + //开启视频服务 + go engine.Run(context.Background(), "config.yml") stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGTERM, os.Interrupt) <-stop - + hs.Stop() if err := app.Stop(context.TODO()); err != nil { - log.Fatal("fatal app stop: %s", err) + log.Fatalf("fatal app stop: %s", err) os.Exit(-3) } }, diff --git a/pandax b/pandax deleted file mode 100644 index 6d5ec8e492c9aa0be5edf338a0a584bac85954fa..0000000000000000000000000000000000000000 Binary files a/pandax and /dev/null differ diff --git a/pkg/config/config.go b/pkg/config/config.go index c30a8906ea61b1bdae0b23a7f9b5997fe10ff74c..7b8eacc97590396801b4703aa2464c38e8a74e67 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -34,15 +34,18 @@ var startConfigParam *CmdConfigParam // yaml配置文件映射对象 type Config struct { - App *App `yaml:"app"` - Server *Server `yaml:"server"` - Jwt *Jwt `yaml:"jwt"` - Redis *Redis `yaml:"redis"` - Mysql *Mysql `yaml:"mysql"` - Postgresql *Postgresql `yaml:"postgresql"` - Casbin *Casbin `yaml:"casbin"` - Gen *Gen `yaml:"gen"` - Log *Log `yaml:"log"` + App *App `yaml:"app"` + Server *Server `yaml:"server"` + Queue *Queue `yaml:"queue"` + Jwt *Jwt `yaml:"jwt"` + Redis *Redis `yaml:"redis"` + Mysql *Mysql `yaml:"mysql"` + Oss *Oss `yaml:"oss"` + Taos *Taos `yaml:"taos"` + Mqtt *Mqtt `yaml:"mqtt"` + Casbin *Casbin `yaml:"casbin"` + Gen *Gen `yaml:"gen"` + Log *Log `yaml:"log"` } // 配置文件内容校验 diff --git a/pkg/config/mqtt.go b/pkg/config/mqtt.go new file mode 100644 index 0000000000000000000000000000000000000000..f7835f8c41d5dd66d0f4c56d292c60cfad109453 --- /dev/null +++ b/pkg/config/mqtt.go @@ -0,0 +1,8 @@ +package config + +type Mqtt struct { + Broker string `mapstructure:"broker" json:"broker" yaml:"broker"` + Qos int `mapstructure:"qos" json:"qos" yaml:"qos"` + Username string `mapstructure:"username" json:"username" yaml:"username"` + Password string `mapstructure:"password" json:"password" yaml:"password"` +} diff --git a/pkg/config/oss.go b/pkg/config/oss.go new file mode 100644 index 0000000000000000000000000000000000000000..80e36152c1074e2f218ab1e1fd97e6210ccc4508 --- /dev/null +++ b/pkg/config/oss.go @@ -0,0 +1,9 @@ +package config + +type Oss struct { + Endpoint string `yaml:"endpoint"` + AccessKey string `yaml:"accessKey"` + SecretKey string `yaml:"secretKey"` + BucketName string `yaml:"bucketName"` + UseSSL bool `yaml:"useSSL"` +} diff --git a/pkg/config/queue.go b/pkg/config/queue.go new file mode 100644 index 0000000000000000000000000000000000000000..b0b0aaab9220d71de677ffe46940f70c19548e82 --- /dev/null +++ b/pkg/config/queue.go @@ -0,0 +1,6 @@ +package config + +type Queue struct { + Enable bool `yaml:" enable"` + Num int64 `yaml:" num"` //并发数 +} diff --git a/pkg/config/server.go b/pkg/config/server.go index 2424a617e29bfeec2b1157ab03e06cbe5a0bccb7..2a8a830f25ffccbb9e660b53d52df4729fcd4f60 100644 --- a/pkg/config/server.go +++ b/pkg/config/server.go @@ -4,6 +4,7 @@ import "fmt" type Server struct { Port int `yaml:"port"` + GrpcPort int `yaml:"grpc-port"` Model string `yaml:"model"` Cors bool `yaml:"cors"` Rate *Rate `yaml:"rate"` diff --git a/pkg/config/taos.go b/pkg/config/taos.go new file mode 100644 index 0000000000000000000000000000000000000000..4e1b63e81a2e911154540caee2b517f574e78beb --- /dev/null +++ b/pkg/config/taos.go @@ -0,0 +1,9 @@ +package config + +type Taos struct { + Host string `yaml:"host"` // 服务器地址:端口 + Username string `yaml:"username"` // 数据库用户名 + Password string `yaml:"password"` // 数据库密码 + Database string `yaml:"database"` + Config string `yaml:"config"` +} diff --git a/pkg/events/event.go b/pkg/events/event.go new file mode 100644 index 0000000000000000000000000000000000000000..f7d324b6305de9a5941485c4166d69f4f41d8f91 --- /dev/null +++ b/pkg/events/event.go @@ -0,0 +1,116 @@ +package events + +import ( + "reflect" + "sync" +) + +type Handler func(args ...interface{}) + +const ( + ProductChainRuleEvent = "ProductChainRuleEvent" + ProductTSLEvent = "ProductTSLEvent" // 产品属性改变, 设备td表也要跟着变 +) + +// EventInterface Events接口 +type EventInterface interface { + Emit(event string, data ...interface{}) + On(event string, fn interface{}) + Once(event string, fn interface{}) + Off(event string, fn interface{}) +} + +type EventEmitter struct { + events sync.Map +} + +type subscriber struct { + callback reflect.Value + once bool +} + +// Emit 发送消息 +func (e *EventEmitter) Emit(event string, data ...interface{}) { + sub, ok1 := e.events.Load(event) + subAll, ok2 := e.events.Load("*") + + if !ok1 && !ok2 { + return + } + + //整理参数 + args := make([]reflect.Value, 0) + args = append(args, reflect.ValueOf(event)) + for _, v := range data { + args = append(args, reflect.ValueOf(v)) + } + + if ok1 { + subscribers := sub.(*sync.Map) + //args := make([]reflect.Value, 1+len(data)) + subscribers.Range(func(key, value interface{}) bool { + handler := value.(*subscriber) + handler.callback.Call(args[1:]) + //处理仅订阅一次 + if handler.once { + subscribers.Delete(key) + } + return true + }) + } + + //处理全局订阅* + if ok2 { + subscribers := subAll.(*sync.Map) + subscribers.Range(func(key, value interface{}) bool { + handler := value.(*subscriber) + handler.callback.Call(args) + //处理仅订阅一次 + if handler.once { + subscribers.Delete(key) + } + return true + }) + } +} + +// On 监听 +func (e *EventEmitter) On(event string, fn interface{}) { + callback := reflect.ValueOf(fn) + val, ok := e.events.Load(event) + if !ok { + val = new(sync.Map) + e.events.Store(event, val) + } + subscribers := val.(*sync.Map) + subscribers.Store(callback.Pointer(), &subscriber{ + callback: callback, + once: false, + }) +} + +// Once 监听一次 +func (e *EventEmitter) Once(event string, fn interface{}) { + callback := reflect.ValueOf(fn) + val, ok := e.events.Load(event) + if !ok { + val = new(sync.Map) + e.events.Store(event, val) + } + subscribers := val.(*sync.Map) + subscribers.Store(callback.Pointer(), &subscriber{ + callback: callback, + once: true, + }) +} + +// Off 取消监听 +func (e *EventEmitter) Off(event string, fn interface{}) { + callback := reflect.ValueOf(fn) + val, ok := e.events.Load(event) + if !ok { + return + } + subscribers := val.(*sync.Map) + subscribers.Delete(callback.Pointer()) +} diff --git a/pkg/global/const_device.go b/pkg/global/const_device.go new file mode 100644 index 0000000000000000000000000000000000000000..d4f0ddf8cee4a67d9fdea39f3e7c45b582951dcc --- /dev/null +++ b/pkg/global/const_device.go @@ -0,0 +1,40 @@ +package global + +// 告警等级 +const ( + CRITICAL = "CRITICAL" // 危险 + MAJOR = "MAJOR" // 重要 + MINOR = "MINOR" // 次要 + WARNING = "WARNING" // 警告 + INDETERMINATE = "INDETERMINATE" // 不确定 +) + +// 告警状态 +const ( + ALARMING = "0" // 告警中 + CONFIRMED = "1" // 已确认 + CLEARED = "2" // 已清除 + CLOSED = "3" // 已关闭 +) + +// 设备状态 +const ( + INACTIVE = "inactive" //未激活 + ONLINE = "online" //在线 + OFFLINE = "offline" // 离线 +) + +// 设备类型 +const ( + DIRECT = "direct" //直连设备 + GATEWAY = "gateway" //网关设备 + GATEWAYS = "gatewayS" // 网关子设备 + MONITOR = "monitor" // 监控设备 +) + +// 设备命令状态 +const ( + CMDSUCCESS = "0" //执行成功 + CMDFAIL = "1" //执行失败 + CMDRUNNING = "2" // 执行中 +) diff --git a/pkg/global/global.go b/pkg/global/global.go index eeee04c4b23540cadf90a4da3ceccff1a8412b64..251a26bbb5802c07efcb25763a2dd7a8b1859ffe 100644 --- a/pkg/global/global.go +++ b/pkg/global/global.go @@ -1,13 +1,21 @@ package global import ( + "github.com/XM-GO/PandaKit/rediscli" "github.com/sirupsen/logrus" "gorm.io/gorm" "pandax/pkg/config" + "pandax/pkg/events" + "pandax/pkg/mqtt" + "pandax/pkg/tdengine" ) var ( - Log *logrus.Logger // 日志 - Db *gorm.DB // gorm - Conf *config.Config + Log *logrus.Logger // 日志 + Db *gorm.DB // gorm + RedisDb *rediscli.RedisDB + TdDb *tdengine.TdEngine + Conf *config.Config + MqttClient *mqtt.IothubMqttClient ) +var EventEmitter = events.EventEmitter{} diff --git a/pkg/global/global_model.go b/pkg/global/global_model.go new file mode 100644 index 0000000000000000000000000000000000000000..1e19cc90563af9afdb91fd406c292a00a7595261 --- /dev/null +++ b/pkg/global/global_model.go @@ -0,0 +1,17 @@ +package global + +import "time" + +type BaseModel struct { + Id string `json:"id" gorm:"primary_key;"` + CreatedAt time.Time `gorm:"column:create_time" json:"createTime" form:"create_time"` + UpdatedAt time.Time `gorm:"column:update_time" json:"updateTime" form:"update_time"` +} + +type BaseAuthModel struct { + Id string `json:"id" gorm:"primary_key;"` + Owner string `json:"owner" gorm:"type:varchar(64);comment:创建者,所有者"` + OrgId string `json:"orgId" gorm:"type:varchar(64);comment:机构ID"` + CreatedAt time.Time `gorm:"column:create_time" json:"createTime" form:"create_time"` + UpdatedAt time.Time `gorm:"column:update_time" json:"updateTime" form:"update_time"` +} diff --git a/pkg/initialize/event.go b/pkg/initialize/event.go new file mode 100644 index 0000000000000000000000000000000000000000..2b3391281f90d0e969877698c259bc1fb2dfacd5 --- /dev/null +++ b/pkg/initialize/event.go @@ -0,0 +1,28 @@ +package initialize + +import ( + "pandax/apps/device/entity" + "pandax/apps/device/services" + "pandax/pkg/events" + "pandax/pkg/global" + "time" +) + +// 初始化事件监听 +func InitEvents() { + // 监听规则链改变 更新所有绑定改规则链的产品 + global.EventEmitter.On(events.ProductChainRuleEvent, func(ruleId, codeData string) { + global.Log.Infof("规则链%s变更", ruleId) + list := services.ProductModelDao.FindList(entity.Product{ + RuleChainId: ruleId, + }) + if list != nil { + for _, product := range *list { + err := global.RedisDb.Set(product.Id, codeData, time.Hour*24*365) + if err != nil { + global.Log.Errorf("事件监听执行错误:%s", err.Error()) + } + } + } + }) +} diff --git a/pkg/initialize/router.go b/pkg/initialize/router.go index 8f4f98471b708334dbc57bf22ee5d6ee0d443a79..3d1820c0708bfc6c21eaa178c14ff129658a6b40 100644 --- a/pkg/initialize/router.go +++ b/pkg/initialize/router.go @@ -1,15 +1,16 @@ package initialize import ( + "pandax/apps/job/jobs" + ruleRouter "pandax/apps/rule/router" "pandax/pkg/global" "pandax/pkg/transport" devRouter "pandax/apps/develop/router" + deviceRouter "pandax/apps/device/router" jobRouter "pandax/apps/job/router" logRouter "pandax/apps/log/router" - resRouter "pandax/apps/resource/router" sysRouter "pandax/apps/system/router" - "pandax/pkg/middleware" ) @@ -19,6 +20,8 @@ func InitRouter() *transport.HttpServer { server := transport.NewHttpServer(serverConfig.GetPort()) container := server.Container + // 防止XSS + container.Filter(middleware.EscapeHTML) // 是否允许跨域 if serverConfig.Cors { container.Filter(middleware.Cors(container).Filter) @@ -29,7 +32,6 @@ func InitRouter() *transport.HttpServer { } // 设置路由组 { - sysRouter.InitSysTenantRouter(container) sysRouter.InitSystemRouter(container) sysRouter.InitDeptRouter(container) sysRouter.InitConfigRouter(container) @@ -43,13 +45,8 @@ func InitRouter() *transport.HttpServer { //本地图片上传接口 sysRouter.InitUploadRouter(container) } - // 任务 - { - jobRouter.InitJobRouter(container) - } //日志系统 { - logRouter.InitJobLogRouter(container) logRouter.InitOperLogRouter(container) logRouter.InitLoginLogRouter(container) } @@ -58,13 +55,30 @@ func InitRouter() *transport.HttpServer { devRouter.InitGenTableRouter(container) devRouter.InitGenRouter(container) } - // 资源管理 + //设备 { - resRouter.InitResOssRouter(container) - resRouter.InitResEmailsRouter(container) + deviceRouter.InitProductCategoryRouter(container) + deviceRouter.InitDeviceGroupRouter(container) + deviceRouter.InitProductRouter(container) + deviceRouter.InitProductTemplateRouter(container) + deviceRouter.InitProductOtaRouter(container) + deviceRouter.InitDeviceRouter(container) + deviceRouter.InitDeviceAlarmRouter(container) + deviceRouter.InitDeviceCmdLogRouter(container) + } + { + jobRouter.InitJobRouter(container) + jobRouter.InitJobLogRouter(container) + } + { + ruleRouter.InitRuleChainRouter(container) } - // api接口 middleware.SwaggerConfig(container) + // 开启调度任务 + go func() { + jobs.InitJob() + }() + return server } diff --git a/pkg/initialize/table.go b/pkg/initialize/table.go index 7f434bbfd8993902a92d9f1acb1d1c41a1d2d425..16f88cb34555db6bf54d8cd7e1a91e6ec0f0ece9 100644 --- a/pkg/initialize/table.go +++ b/pkg/initialize/table.go @@ -7,7 +7,7 @@ import ( jobEntity "pandax/apps/job/entity" logEntity "pandax/apps/log/entity" resSourceEntity "pandax/apps/resource/entity" - "pandax/apps/system/entity" + systemEntity "pandax/apps/system/entity" "pandax/pkg/global" ) @@ -18,22 +18,22 @@ func InitTable() { biz.ErrIsNil( global.Db.AutoMigrate( //casbin.CasbinRule{}, - entity.SysDept{}, - entity.SysApi{}, - entity.SysConfig{}, - entity.SysDictType{}, - entity.SysDictData{}, + systemEntity.SysDept{}, + systemEntity.SysApi{}, + systemEntity.SysConfig{}, + systemEntity.SysDictType{}, + systemEntity.SysDictData{}, + systemEntity.SysUser{}, + systemEntity.SysTenants{}, + systemEntity.SysRole{}, + systemEntity.SysMenu{}, + systemEntity.SysPost{}, + systemEntity.SysRoleMenu{}, + systemEntity.SysRoleDept{}, + systemEntity.SysNotice{}, + logEntity.LogLogin{}, logEntity.LogOper{}, - logEntity.LogJob{}, - entity.SysUser{}, - entity.SysTenants{}, - entity.SysRole{}, - entity.SysMenu{}, - entity.SysPost{}, - entity.SysRoleMenu{}, - entity.SysRoleDept{}, - entity.SysNotice{}, jobEntity.SysJob{}, devEntity.DevGenTable{}, devEntity.DevGenTableColumn{}, @@ -46,9 +46,11 @@ func InitTable() { flowEntity.FlowWorkOrder{}, flowEntity.FlowWorkOrderTemplate{}, flowEntity.FlowWorkStage{}, - flowEntity.FlowWorkTask{}, - flowEntity.FlowWorkTaskHistory{}, ), "初始化表失败") } + err := global.TdDb.CreateEventTable() + if err != nil { + global.Log.Panic(err) + } } diff --git a/pkg/middleware/escape_html.go b/pkg/middleware/escape_html.go new file mode 100644 index 0000000000000000000000000000000000000000..52a0a19c716b88ec74eefcc41ea177cc5df92ac5 --- /dev/null +++ b/pkg/middleware/escape_html.go @@ -0,0 +1,17 @@ +package middleware + +import ( + "github.com/emicklei/go-restful/v3" + "html" +) + +// 防止XSS攻击 +func EscapeHTML(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { + // 获取请求参数中的HTML标签 + for _, p := range req.Request.URL.Query() { + escaped := html.EscapeString(p[0]) + // 将转义后的参数重新设置到请求参数中 + req.Request.URL.Query().Set(p[0], escaped) + } + chain.ProcessFilter(req, resp) +} diff --git a/pkg/middleware/permission.go b/pkg/middleware/permission.go index c86e504b4fbbe15775f391fac688f105a16eb878..ee5ec89e07996bd6d4b11c8a703bf674e76ad133 100644 --- a/pkg/middleware/permission.go +++ b/pkg/middleware/permission.go @@ -7,7 +7,6 @@ import ( "github.com/XM-GO/PandaKit/token" "github.com/dgrijalva/jwt-go" "pandax/pkg/global" - "strconv" ) func PermissionHandler(rc *restfulx.ReqCtx) error { @@ -38,8 +37,7 @@ func PermissionHandler(rc *restfulx.ReqCtx) error { ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} e := ca.Casbin() // 判断策略中是否存在 - tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) - success, err := e.Enforce(tenantId, loginAccount.RoleKey, rc.Request.Request.URL.Path, rc.Request.Request.Method) + success, err := e.Enforce(loginAccount.RoleKey, rc.Request.Request.URL.Path, rc.Request.Request.Method) if !success { return biz.CasbinErr } diff --git a/pkg/mqtt/mqtt.go b/pkg/mqtt/mqtt.go new file mode 100644 index 0000000000000000000000000000000000000000..ff0f88dd55bb5ff95086aede9c7aac56de72e8a4 --- /dev/null +++ b/pkg/mqtt/mqtt.go @@ -0,0 +1,77 @@ +package mqtt + +import ( + "errors" + "fmt" + mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/sirupsen/logrus" + "time" +) + +const DefaultDownStreamClientId = `@panda.iothub.internal.clientId` + +type IothubMqttClient struct { + Client mqtt.Client +} + +var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) { + logrus.Infof("Connected") +} + +var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) { + logrus.Infof("Connect lost: %v", err) +} + +func InitMqtt(broker, username, password string) *IothubMqttClient { + server := fmt.Sprintf("tcp://%s", broker) + client := GetMqttClinent(server, username, password) + return &IothubMqttClient{ + Client: client, + } +} + +func GetMqttClinent(server, username, password string) mqtt.Client { + opts := mqtt.NewClientOptions().AddBroker(server) + time.Now().Unix() + // 默认下行ID iothub会过滤掉改Id + opts.SetClientID(DefaultDownStreamClientId) + if username != "" { + opts.SetUsername(username) + } + if password != "" { + opts.SetPassword(password) + } + opts.OnConnect = connectHandler + opts.OnConnectionLost = connectLostHandler + client := mqtt.NewClient(opts) + if token := client.Connect(); token.Wait() && token.Error() != nil { + panic(token.Error()) + } + return client +} + +// 订阅 +func (imc *IothubMqttClient) Sub(topic string, qos byte, handler mqtt.MessageHandler) { + if token := imc.Client.Subscribe(topic, qos, handler); token.Wait() && token.Error() != nil { + logrus.Infof(token.Error().Error()) + } +} + +// 取消订阅 +func (imc *IothubMqttClient) UnSub(topic string) { + if token := imc.Client.Unsubscribe(topic); token.Wait() && token.Error() != nil { + logrus.Infof(token.Error().Error()) + } +} + +// 发布 +func (imc *IothubMqttClient) Pub(topic string, qos byte, payload string) error { + token := imc.Client.Publish(topic, qos, false, payload) + if token.WaitTimeout(2*time.Second) == false { + return errors.New("推送消息超时") + } + if token.Error() != nil { + return token.Error() + } + return nil +} diff --git a/pkg/mqtt/rpc.go b/pkg/mqtt/rpc.go new file mode 100644 index 0000000000000000000000000000000000000000..138102e25509eeb3bec4048444929163ec97a4ac --- /dev/null +++ b/pkg/mqtt/rpc.go @@ -0,0 +1,88 @@ +package mqtt + +import ( + "encoding/json" + "fmt" + mqtt "github.com/eclipse/paho.mqtt.golang" + "math/rand" + "time" +) + +const ( + RpcRespTopic = `v1/devices/me/rpc/response/%d` + RpcReqTopic = `v1/devices/me/rpc/request/%d` +) + +type RpcRequest struct { + Client *IothubMqttClient + RequestId int + Mode string //单向、双向 单项只发送不等待响应 双向需要等到响应 + Timeout int // 设置双向时,等待的超时时间 +} + +type RpcPayload struct { + Method string `json:"method"` + Params string `json:"params"` +} + +func (rpc RpcRequest) RequestCmd(rpcPayload RpcPayload) error { + topic := fmt.Sprintf(RpcReqTopic, rpc.RequestId) + payload, err := json.Marshal(rpcPayload) + if err != nil { + return err + } + err = rpc.Client.Pub(topic, 0, string(payload)) + if err != nil { + return err + } + if rpc.Mode == "single" { + return nil + } + respTopic := fmt.Sprintf(RpcRespTopic, rpc.RequestId) + rpc.Client.Sub(respTopic, 0, mqMessagePubHandler) + if rpc.Timeout == 0 { + rpc.Timeout = 30 + } + go func() { + select { + case <-time.After(time.Duration(rpc.Timeout) * time.Second): + rpc.Client.UnSub(respTopic) + } + }() + return nil +} + +func (rpc RpcRequest) RequestAttributes(rpcPayload RpcPayload) error { + topic := fmt.Sprintf(RpcReqTopic, rpc.RequestId) + if rpcPayload.Method == "" { + rpcPayload.Method = "setAttributes" + } + payload, err := json.Marshal(rpcPayload) + if err != nil { + return err + } + return rpc.Client.Pub(topic, 0, string(payload)) +} + +// 响应数据处理 +var mqMessagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { + //log.Println(fmt.Sprintf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())) +} + +// RespondTpc 处理设备端请求服务端方法 +func (rpc RpcRequest) RespondTpc(reqPayload RpcPayload) error { + topic := fmt.Sprintf(RpcRespTopic, rpc.RequestId) + if reqPayload.Params == "getCurrentTime" { + unix := time.Now().Unix() + msg := fmt.Sprintf("%d", unix) + return rpc.Client.Pub(topic, 0, msg) + } + + return nil +} + +func (rpc *RpcRequest) GetRequestId() { + rand.Seed(time.Now().UnixNano()) + // 生成随机整数 + rpc.RequestId = rand.Intn(10000) + 1 // 生成0到99之间的随机整数 +} diff --git a/pkg/rule_engine/instance.go b/pkg/rule_engine/instance.go new file mode 100644 index 0000000000000000000000000000000000000000..34197df05850ad34bb11f2aff5936e6553db2b97 --- /dev/null +++ b/pkg/rule_engine/instance.go @@ -0,0 +1,49 @@ +package rule_engine + +import ( + "context" + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/manifest" + "pandax/pkg/rule_engine/message" + "pandax/pkg/rule_engine/nodes" +) + +type ruleChainInstance struct { + firstRuleNodeId string + nodes map[string]nodes.Node +} + +func NewRuleChainInstance(data []byte) (*ruleChainInstance, []error) { + errors := make([]error, 0) + + manifest, err := manifest.New(data) + if err != nil { + errors = append(errors, err) + logrus.WithError(err).Errorf("invalidi manifest file") + return nil, errors + } + return newInstanceWithManifest(manifest) +} + +// newWithManifest create rule chain by user's manifest file +func newInstanceWithManifest(m *manifest.Manifest) (*ruleChainInstance, []error) { + errs := make([]error, 0) + nodes, err := nodes.GetNodes(m) + if err != nil { + errs = append(errs, err) + return nil, errs + } + r := &ruleChainInstance{ + firstRuleNodeId: m.FirstRuleNodeId, + nodes: nodes, + } + return r, errs +} + +// StartRuleChain TODO 是否需要添加context +func (c *ruleChainInstance) StartRuleChain(context context.Context, message message.Message) error { + if node, found := c.nodes[c.firstRuleNodeId]; found { + node.Handle(message) + } + return nil +} diff --git a/pkg/rule_engine/instance_test.go b/pkg/rule_engine/instance_test.go new file mode 100644 index 0000000000000000000000000000000000000000..13556b4127edbc8b0ccdcb13535aa45612fe8e34 --- /dev/null +++ b/pkg/rule_engine/instance_test.go @@ -0,0 +1,75 @@ +package rule_engine + +import ( + "context" + "io/ioutil" + "pandax/pkg/rule_engine/message" + "pandax/pkg/rule_engine/nodes" + "testing" +) + +func TestNewRuleChainInstance(t *testing.T) { + buf, err := ioutil.ReadFile("./manifest/manifest_sample.json") + if err != nil { + t.Error(err) + } + instance, errs := NewRuleChainInstance(buf) + if len(errs) > 0 { + t.Error(errs[0]) + } + + metadata := message.NewDefaultMetadata(map[string]interface{}{ + "deviceName": "ws432", + "deviceId": "d_1928b99619910dae5a001fa7", + "deviceType": "direct", + "productId": "p_3ba460634520cf4590dc90e5", + }) + msg := message.NewMessageWithDetail("1", message.TelemetryMes, map[string]interface{}{"temperature": 60.4, "humidity": 32.5}, metadata) + t.Log("开始执行力流程") + err = instance.StartRuleChain(context.Background(), msg) + if err != nil { + t.Log(err) + } +} + +func TestScriptEngine(t *testing.T) { + metadata := message.NewDefaultMetadata(map[string]interface{}{"device": "aa"}) + msg := message.NewMessageWithDetail("1", message.UpEventMes, map[string]interface{}{"aa": 5}, metadata) + const baseScript = ` + function nextRelation(metadata, msg) { + return ['one','nine']; + } + if(metadata.device === 'aa') { + return ['six']; + } + if(msgType === 'Post telemetry') { + return ['two']; + } + return nextRelation(metadata, msg); + ` + scriptEngine := nodes.NewScriptEngine(msg, "Switch", baseScript) + SwitchResults, err := scriptEngine.ScriptOnSwitch() + + if err != nil { + t.Error(err) + } + t.Log(SwitchResults) +} + +func TestScriptOnMessage(t *testing.T) { + metadata := message.NewDefaultMetadata(map[string]interface{}{"device": "aa"}) + msg := message.NewMessageWithDetail("1", message.UpEventMes, map[string]interface{}{"aa": 5}, metadata) + + const baseScript = ` + msg.bb = "33" + metadata.event = 55 + return {msg: msg, metadata: metadata, msgType: msgType}; + ` + scriptEngine := nodes.NewScriptEngine(msg, "Transform", baseScript) + ScriptOnMessageResults, err := scriptEngine.ScriptOnMessage() + + if err != nil { + t.Error(err) + } + t.Log(ScriptOnMessageResults.GetMetadata()) +} diff --git a/pkg/rule_engine/manifest/manifest.go b/pkg/rule_engine/manifest/manifest.go new file mode 100644 index 0000000000000000000000000000000000000000..21b93493ddc95d6a4a26afcbed06b42dcdac6f60 --- /dev/null +++ b/pkg/rule_engine/manifest/manifest.go @@ -0,0 +1,62 @@ +package manifest + +import ( + "encoding/json" + "github.com/sirupsen/logrus" +) + +type Node struct { + Type string `json:"type" yaml:"type"` + Id string `json:"id" yaml:"id"` + Properties map[string]interface{} `json:"properties" yaml:"properties"` //debugMode +} + +type Edge struct { + SourceNodeId string `json:"sourceNodeId" yaml:"sourceNodeId"` + TargetNodeId string `json:"targetNodeId" yaml:"targetNodeId"` + Type string `json:"type" yaml:"type"` //success or fail + Properties map[string]interface{} `json:"properties" yaml:"properties"` //debugMode +} + +type Manifest struct { + FirstRuleNodeId string `json:"firstRuleNodeId" yaml:"firstRuleNodeId"` + Nodes []Node `json:"nodes" yaml:"nodes"` + Edges []Edge `json:"edges" yaml:"edges"` +} + +func New(data []byte) (*Manifest, error) { + firstRuleNodeId := "" + manifest := make(map[string]interface{}) + if err := json.Unmarshal(data, &manifest); err != nil { + logrus.WithError(err).Errorf("invalid node chain manifest file") + return nil, err + } + nodes := make([]Node, 0) + for _, mn := range manifest["nodes"].([]interface{}) { + node := mn.(map[string]interface{}) + if node["type"].(string) == "InputNode" { + firstRuleNodeId = node["id"].(string) + } + nodes = append(nodes, Node{ + Id: node["id"].(string), + Type: node["type"].(string), + Properties: node["properties"].(map[string]interface{}), + }) + } + edges := make([]Edge, 0) + for _, en := range manifest["edges"].([]interface{}) { + edge := en.(map[string]interface{}) + edges = append(edges, Edge{ + Type: edge["type"].(string), + Properties: edge["properties"].(map[string]interface{}), + SourceNodeId: edge["sourceNodeId"].(string), + TargetNodeId: edge["targetNodeId"].(string), + }) + } + m := &Manifest{ + FirstRuleNodeId: firstRuleNodeId, + Nodes: nodes, + Edges: edges, + } + return m, nil +} diff --git a/pkg/rule_engine/manifest/manifest_sample.json b/pkg/rule_engine/manifest/manifest_sample.json new file mode 100644 index 0000000000000000000000000000000000000000..4a314796226b73cb4f03cf4315374055dc75a7e9 --- /dev/null +++ b/pkg/rule_engine/manifest/manifest_sample.json @@ -0,0 +1,208 @@ +{ + "nodes": [ + { + "id": "input", + "type": "InputNode", + "x": 116, + "y": 337, + "properties": { + "debugMode": false + }, + "zIndex": 1013, + "text": { + "x": 126, + "y": 337, + "value": "输入" + } + }, + { + "id": "8bdef3d4-9ea3-4a09-8313-4e534ee1b387", + "type": "SaveTimeSeriesNode", + "x": 751, + "y": 341, + "properties": { + "debugMode": false, + "name": "" + }, + "zIndex": 1002, + "text": { + "x": 761, + "y": 341, + "value": "保存遥测" + } + }, + { + "id": "4d6b6519-35f2-44ce-9b9c-5a7bafe516ac", + "type": "SaveAttributesNode", + "x": 753, + "y": 177, + "properties": { + "debugMode": false, + "name": "" + }, + "zIndex": 1004, + "text": { + "x": 763, + "y": 177, + "value": "保存参数" + } + }, + { + "id": "a8e691c6-947b-44a3-aeff-f5c816c9a004", + "type": "LogNode", + "x": 770, + "y": 497, + "properties": { + "debugMode": false, + "name": "", + "script": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + \n '\\nIncoming metadata:\\n' + JSON.stringify(metadata);\n" + }, + "zIndex": 1006, + "text": { + "x": 780, + "y": 497, + "value": "日志节点" + } + }, + { + "id": "326ff560-9485-459c-b07d-23191385f18b", + "type": "MessageTypeSwitchNode", + "x": 400, + "y": 338, + "properties": { + "debugMode": false + }, + "zIndex": 1010, + "text": { + "x": 410, + "y": 338, + "value": "消息类型切换" + } + } + ], + "edges": [ + { + "id": "ddcf4bc0-c5fc-465a-9c37-b907cd4c6985", + "type": "bezier-link", + "sourceNodeId": "input", + "targetNodeId": "326ff560-9485-459c-b07d-23191385f18b", + "startPoint": { + "x": 176, + "y": 337 + }, + "endPoint": { + "x": 330, + "y": 338 + }, + "properties": { + "lineType": ["True"] + }, + "text": { + "x": 253, + "y": 337.5, + "value": "True" + }, + "zIndex": 1013, + "pointsList": [ + { + "x": 176, + "y": 337 + }, + { + "x": 276, + "y": 337 + }, + { + "x": 230, + "y": 338 + }, + { + "x": 330, + "y": 338 + } + ] + }, + { + "id": "9445ceea-22a6-4af4-9599-cf806b51172d", + "type": "bezier-link", + "sourceNodeId": "326ff560-9485-459c-b07d-23191385f18b", + "targetNodeId": "4d6b6519-35f2-44ce-9b9c-5a7bafe516ac", + "startPoint": { + "x": 470, + "y": 338 + }, + "endPoint": { + "x": 693, + "y": 177 + }, + "properties": { + "lineType": ["Attributes"] + }, + "text": { + "x": 581.5, + "y": 257.5, + "value": "Attributes" + }, + "zIndex": 1014, + "pointsList": [ + { + "x": 470, + "y": 338 + }, + { + "x": 570, + "y": 338 + }, + { + "x": 593, + "y": 177 + }, + { + "x": 693, + "y": 177 + } + ] + }, + { + "id": "a5728c6d-eaa2-4a86-b892-bcdfb7bd432f", + "type": "bezier-link", + "sourceNodeId": "326ff560-9485-459c-b07d-23191385f18b", + "targetNodeId": "8bdef3d4-9ea3-4a09-8313-4e534ee1b387", + "startPoint": { + "x": 470, + "y": 338 + }, + "endPoint": { + "x": 691, + "y": 341 + }, + "properties": { + "lineType": ["Telemetry"] + }, + "text": { + "x": 580.5, + "y": 339.5, + "value": "Telemetry" + }, + "zIndex": 1015, + "pointsList": [ + { + "x": 470, + "y": 338 + }, + { + "x": 570, + "y": 338 + }, + { + "x": 591, + "y": 341 + }, + { + "x": 691, + "y": 341 + } + ] + } + ] +} \ No newline at end of file diff --git a/pkg/rule_engine/message/message.go b/pkg/rule_engine/message/message.go new file mode 100644 index 0000000000000000000000000000000000000000..4379799a5ecad88864796d2b9efe61785211edd8 --- /dev/null +++ b/pkg/rule_engine/message/message.go @@ -0,0 +1,156 @@ +package message + +import ( + "encoding/json" + "github.com/google/uuid" + "time" +) + +// 消息类型 +const ( + ConnectMes = "Connect" + DisConnectMes = "Disconnect" + RpcRequestMes = "RpcRequest" + UpEventMes = "Event" + AlarmMes = "Alarm" + RowMes = "Row" + TelemetryMes = "Telemetry" + AttributesMes = "Attributes" +) + +// 数据类型Originator +const ( + DEVICE = "DEVICE" + GATEWAY = "GATEWAY" + MONITOR = "MONITOR" //监控 +) + +// Message ... +type Message interface { + GetId() string + GetTs() time.Time + GetUserId() string + GetType() string + GetMsg() map[string]interface{} + GetMetadata() Metadata + GetAllMap() map[string]interface{} //msg 和 Metadata的合并 + SetType(string) + SetMsg(map[string]interface{}) + SetUserId(string) + SetMetadata(Metadata) + MarshalBinary() ([]byte, error) +} + +// Metadata ... +type Metadata interface { + Keys() []string + GetKeyValue(key string) interface{} + SetKeyValue(key string, val interface{}) + GetValues() map[string]interface{} +} + +// NewMessage ... +func NewMessage() Message { + return &defaultMessage{ + Id: uuid.New().String(), + Ts: time.Now(), + Msg: map[string]interface{}{}, + } +} + +type defaultMessage struct { + Id string //uuid 消息Id + Ts time.Time //时间戳 + MsgType string //消息类型, attributes(参数),telemetry(遥测),Connect连接事件 + UserId string //客户Id UUID 设备发布人 + Msg map[string]interface{} //数据 数据结构JSON 设备原始数据 msg + Metadata Metadata //消息的元数据 包括设备Id,设备类型,产品ID等 +} + +// NewMessageWithDetail ... +func NewMessageWithDetail(userId, messageType string, msg map[string]interface{}, metadata Metadata) Message { + return &defaultMessage{ + Id: uuid.New().String(), + Ts: time.Now(), + UserId: userId, + MsgType: messageType, + Msg: msg, + Metadata: metadata, + } +} + +func (t *defaultMessage) GetId() string { return t.Id } +func (t *defaultMessage) GetTs() time.Time { return t.Ts } +func (t *defaultMessage) GetUserId() string { return t.UserId } +func (t *defaultMessage) GetType() string { return t.MsgType } +func (t *defaultMessage) GetMsg() map[string]interface{} { return t.Msg } +func (t *defaultMessage) GetMetadata() Metadata { return t.Metadata } +func (t *defaultMessage) GetAllMap() map[string]interface{} { + data := make(map[string]interface{}) + for msgKey, msgValue := range t.GetMsg() { + for metaKey, metaValue := range t.GetMetadata().GetValues() { + if msgKey == metaKey { + data[msgKey] = metaValue + } else { + if _, ok := data[msgKey]; !ok { + data[msgKey] = msgValue + } + if _, ok := data[metaKey]; !ok { + data[metaKey] = metaValue + } + } + } + } + return data +} +func (t *defaultMessage) SetType(msgType string) { t.MsgType = msgType } +func (t *defaultMessage) SetMsg(msg map[string]interface{}) { t.Msg = msg } +func (t *defaultMessage) SetUserId(userId string) { t.UserId = userId } +func (t *defaultMessage) SetMetadata(metadata Metadata) { t.Metadata = metadata } + +func (t *defaultMessage) MarshalBinary() ([]byte, error) { + return json.Marshal(t) +} + +// NewMetadata ... +func NewMetadata() Metadata { + return &defaultMetadata{ + values: make(map[string]interface{}), + } +} + +type defaultMetadata struct { + values map[string]interface{} +} + +func NewDefaultMetadata(vals map[string]interface{}) Metadata { + return &defaultMetadata{ + values: vals, + } +} + +func (t *defaultMetadata) Keys() []string { + keys := make([]string, 0) + for key := range t.values { + keys = append(keys, key) + } + return keys +} + +func (t *defaultMetadata) GetKeyValue(key string) interface{} { + if _, found := t.values[key]; !found { + return nil + } + return t.values[key] +} + +func (t *defaultMetadata) SetKeyValue(key string, val interface{}) { + t.values[key] = val +} + +func (t *defaultMetadata) GetValues() map[string]interface{} { + return t.values +} +func (t *defaultMetadata) SetValues(values map[string]interface{}) { + t.values = values +} diff --git a/pkg/rule_engine/nodes/action_clear_alarm_node.go b/pkg/rule_engine/nodes/action_clear_alarm_node.go new file mode 100644 index 0000000000000000000000000000000000000000..b9bf1fb8c1449481dd53431cd32181be23933c8e --- /dev/null +++ b/pkg/rule_engine/nodes/action_clear_alarm_node.go @@ -0,0 +1,59 @@ +package nodes + +import ( + "encoding/json" + "github.com/sirupsen/logrus" + "log" + "pandax/apps/device/services" + "pandax/pkg/global" + "pandax/pkg/rule_engine/message" +) + +const ClearAlarmNodeName = "ClearAlarmNode" + +type clearAlarmNodeFactory struct{} + +type clearAlarmNode struct { + bareNode + Script string `json:"script" yaml:"script"` + AlarmType string `json:"alarmType" yaml:"alarmType"` +} + +func (f clearAlarmNodeFactory) Name() string { return ClearAlarmNodeName } +func (f clearAlarmNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f clearAlarmNodeFactory) Labels() []string { return []string{"Cleared", "Failure"} } +func (f clearAlarmNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &clearAlarmNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *clearAlarmNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + cleared := n.GetLinkedNode("Cleared") + failure := n.GetLinkedNode("Failure") + + alarm := services.DeviceAlarmModelDao.FindOneByType(msg.GetMetadata().GetKeyValue("deviceId").(string), n.AlarmType, "0") + if alarm.DeviceId != "" { + log.Println("清除告警") + alarm.State = global.CLEARED + marshal, _ := json.Marshal(msg.GetMsg()) + alarm.Details = string(marshal) + err := services.DeviceAlarmModelDao.Update(*alarm) + if err != nil { + if failure != nil { + return failure.Handle(msg) + } + } else { + if cleared != nil { + return cleared.Handle(msg) + } + } + } else { + if failure != nil { + return failure.Handle(msg) + } + } + return nil +} diff --git a/pkg/rule_engine/nodes/action_create_alarm_node.go b/pkg/rule_engine/nodes/action_create_alarm_node.go new file mode 100644 index 0000000000000000000000000000000000000000..68b681fca902e2c4a3c20f0ad808b4caa92b84ac --- /dev/null +++ b/pkg/rule_engine/nodes/action_create_alarm_node.go @@ -0,0 +1,77 @@ +package nodes + +import ( + "encoding/json" + "github.com/kakuilan/kgo" + "github.com/sirupsen/logrus" + "pandax/apps/device/entity" + "pandax/apps/device/services" + "pandax/pkg/global" + "pandax/pkg/rule_engine/message" + "time" +) + +type createAlarmNode struct { + bareNode + AlarmType string `json:"alarmType" yaml:"alarmType"` + AlarmSeverity string `json:"alarmSeverity" yaml:"alarmSeverity"` +} + +type createAlarmNodeFactory struct{} + +func (f createAlarmNodeFactory) Name() string { return "CreateAlarmNode" } +func (f createAlarmNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f createAlarmNodeFactory) Labels() []string { return []string{"Created", "Updated", "Failure"} } +func (f createAlarmNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &createAlarmNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *createAlarmNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + created := n.GetLinkedNode("Created") + updated := n.GetLinkedNode("Updated") + failure := n.GetLinkedNode("Failure") + + alarm := services.DeviceAlarmModelDao.FindOneByType(msg.GetMetadata().GetKeyValue("deviceId").(string), n.AlarmType, "0") + if alarm.DeviceId != "" { + marshal, _ := json.Marshal(msg.GetMsg()) + alarm.Details = string(marshal) + err := services.DeviceAlarmModelDao.Update(*alarm) + if err != nil { + if failure != nil { + return failure.Handle(msg) + } + } else { + if updated != nil { + return updated.Handle(msg) + } + } + } else { + alarm = &entity.DeviceAlarm{} + alarm.Id = kgo.KStr.Uniqid("a") + alarm.DeviceId = msg.GetMetadata().GetKeyValue("deviceId").(string) + alarm.ProductId = msg.GetMetadata().GetKeyValue("productId").(string) + alarm.Name = msg.GetMetadata().GetKeyValue("deviceName").(string) + alarm.Level = n.AlarmSeverity + alarm.State = global.ALARMING + alarm.Type = n.AlarmType + alarm.Time = time.Now() + marshal, _ := json.Marshal(msg.GetMsg()) + alarm.Details = string(marshal) + err := services.DeviceAlarmModelDao.Insert(*alarm) + if err != nil { + if failure != nil { + return failure.Handle(msg) + } + } else { + if created != nil { + return created.Handle(msg) + } + } + } + return nil +} diff --git a/pkg/rule_engine/nodes/action_delay_node.go b/pkg/rule_engine/nodes/action_delay_node.go new file mode 100644 index 0000000000000000000000000000000000000000..2105669e6fd33f4dc1038bfeabb0e6214bf15be5 --- /dev/null +++ b/pkg/rule_engine/nodes/action_delay_node.go @@ -0,0 +1,74 @@ +package nodes + +import ( + "fmt" + "pandax/pkg/rule_engine/message" + "sync" + "time" + + "github.com/sirupsen/logrus" +) + +const DelayNodeName = "DelayNode" + +type delayNode struct { + bareNode + PeriodTs int `json:"periodTs" yaml:"periodTs" jpath:"periodTs"` //周期时间 + MaxPendingMessages int `json:"maxPendingMessages" yaml:"maxPendingMessages" jpath:"maxPendingMessages"` //最大等待消息数 + messageQueue []message.Message `jpath:"-"` + delayTimer *time.Timer `jpath:"-"` + lock sync.Mutex `jpath:"-"` +} + +type delayNodeFactory struct{} + +func (f delayNodeFactory) Name() string { return DelayNodeName } +func (f delayNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f delayNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f delayNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &delayNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + lock: sync.Mutex{}, + } + _, err := decodePath(meta, node) + node.messageQueue = make([]message.Message, node.MaxPendingMessages) + return node, err +} + +func (n *delayNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + if successLabelNode == nil || failureLabelNode == nil { + return fmt.Errorf("no valid label linked node in %s", n.Name()) + } + + // check wethere the time had already been started, queue message if started + if n.delayTimer == nil { + n.messageQueue = append(n.messageQueue, msg) + n.delayTimer = time.NewTimer(time.Duration(n.PeriodTs) * time.Second) + + go func(n *delayNode) error { + defer n.delayTimer.Stop() + for { + <-n.delayTimer.C + n.lock.Lock() + defer n.lock.Unlock() + if len(n.messageQueue) > 0 { + msg := n.messageQueue[0] + n.messageQueue = n.messageQueue[0:] + return successLabelNode.Handle(msg) + } + } + }(n) + return nil + } + n.lock.Lock() + defer n.lock.Unlock() + if len(n.messageQueue) == n.MaxPendingMessages { + return failureLabelNode.Handle(msg) + } + n.messageQueue = append(n.messageQueue, msg) + return nil +} diff --git a/pkg/rule_engine/nodes/action_generator_node.go b/pkg/rule_engine/nodes/action_generator_node.go new file mode 100644 index 0000000000000000000000000000000000000000..4cffe8cf685a1bb664527810b442122c6dec8d76 --- /dev/null +++ b/pkg/rule_engine/nodes/action_generator_node.go @@ -0,0 +1,63 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" + "time" +) + +type messageGeneratorNode struct { + bareNode + Script string `json:"script" yaml:"script"` + PeriodSecond int64 `json:"periodSecond" yaml:"periodSecond"` //周期 + MessageCount int64 `json:"messageCount" yaml:"messageCount"` +} + +type messageGeneratorNodeFactory struct{} + +func (f messageGeneratorNodeFactory) Name() string { return "MessageGeneratorNode" } +func (f messageGeneratorNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f messageGeneratorNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f messageGeneratorNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &messageGeneratorNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *messageGeneratorNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + + ticker := time.NewTicker(time.Duration(n.PeriodSecond) * time.Second) + count := 0 + + go func() { + for { + <-ticker.C + count++ + if int64(count) == n.MessageCount { + ticker.Stop() + return + } + scriptEngine := NewScriptEngine(msg, "Generate", n.Script) + generate, err := scriptEngine.ScriptGenerate() + if err != nil { + if failureLabelNode != nil { + go failureLabelNode.Handle(msg) + } + return + } + msg.SetMsg(generate["msg"].(map[string]interface{})) + msg.SetType(generate["msgType"].(string)) + msg.SetMetadata(message.NewDefaultMetadata(generate["metadata"].(map[string]interface{}))) + if successLabelNode != nil { + go successLabelNode.Handle(msg) + } + } + }() + + return nil +} diff --git a/pkg/rule_engine/nodes/action_log_node.go b/pkg/rule_engine/nodes/action_log_node.go new file mode 100644 index 0000000000000000000000000000000000000000..2939cf5df414e218a20290459988e694ae9c98fd --- /dev/null +++ b/pkg/rule_engine/nodes/action_log_node.go @@ -0,0 +1,59 @@ +package nodes + +import ( + "pandax/apps/rule/entity" + "pandax/apps/rule/services" + "pandax/pkg/global" + "pandax/pkg/rule_engine/message" +) + +type logNode struct { + bareNode + Script string `json:"script"` +} + +type logNodeFactory struct{} + +func (f logNodeFactory) Name() string { return "LogNode" } +func (f logNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f logNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f logNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &logNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *logNode) Handle(msg message.Message) error { + successLableNode := n.GetLinkedNode("Success") + failureLableNode := n.GetLinkedNode("Failure") + + scriptEngine := NewScriptEngine(msg, "ToString", n.Script) + logMessage, err := scriptEngine.ScriptToString() + if err != nil { + if failureLableNode != nil { + return failureLableNode.Handle(msg) + } else { + return err + } + } + services.RuleChainMsgLogModelDao.Insert(entity.RuleChainMsgLog{ + MessageId: msg.GetId(), + MsgType: msg.GetType(), + DeviceName: msg.GetMetadata().GetValues()["deviceName"].(string), + Ts: msg.GetTs(), + Content: logMessage, + }) + global.Log.Info(logMessage) + if err != nil { + if failureLableNode != nil { + return failureLableNode.Handle(msg) + } else { + return err + } + } + if successLableNode != nil { + return successLableNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/action_save_attributes_node.go b/pkg/rule_engine/nodes/action_save_attributes_node.go new file mode 100644 index 0000000000000000000000000000000000000000..d7cbc8065b92534f998956776439cd161ab08eb1 --- /dev/null +++ b/pkg/rule_engine/nodes/action_save_attributes_node.go @@ -0,0 +1,48 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/global" + "pandax/pkg/rule_engine/message" +) + +type saveAttributesNode struct { + bareNode +} + +type saveAttributesNodeFactory struct{} + +func (f saveAttributesNodeFactory) Name() string { return "SaveAttributesNode" } +func (f saveAttributesNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f saveAttributesNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f saveAttributesNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &saveAttributesNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *saveAttributesNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + if msg.GetType() != message.AttributesMes { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return nil + } + } + //deviceId := msg.GetMetadata().GetValues()["deviceId"].(string) + deviceName := msg.GetMetadata().GetValues()["deviceName"].(string) + err := global.TdDb.InsertDevice(deviceName+"_attributes", msg.GetMsg()) + if err != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/action_save_timeseries_node.go b/pkg/rule_engine/nodes/action_save_timeseries_node.go new file mode 100644 index 0000000000000000000000000000000000000000..1cbd4b726bd9bc071587282eeb5f52024e13dd4f --- /dev/null +++ b/pkg/rule_engine/nodes/action_save_timeseries_node.go @@ -0,0 +1,51 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "log" + "pandax/pkg/global" + "pandax/pkg/rule_engine/message" +) + +type saveTimeSeriesNode struct { + bareNode +} + +type saveTimeSeriesNodeFactory struct{} + +func (f saveTimeSeriesNodeFactory) Name() string { return "SaveTimeSeriesNode" } +func (f saveTimeSeriesNodeFactory) Category() string { return NODE_CATEGORY_ACTION } +func (f saveTimeSeriesNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f saveTimeSeriesNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &saveTimeSeriesNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *saveTimeSeriesNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + if msg.GetType() != message.TelemetryMes { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return nil + } + } + //deviceId := msg.GetMetadata().GetValues()["deviceId"].(string) + deviceName := msg.GetMetadata().GetValues()["deviceName"].(string) + log.Println("telemetry", msg.GetMsg()) + err := global.TdDb.InsertDevice(deviceName+"_telemetry", msg.GetMsg()) + log.Println(err) + if err != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/external_ding_node.go b/pkg/rule_engine/nodes/external_ding_node.go new file mode 100644 index 0000000000000000000000000000000000000000..5f2fe38d731c93d967b2bb30ae98f4807f1fd6a7 --- /dev/null +++ b/pkg/rule_engine/nodes/external_ding_node.go @@ -0,0 +1,84 @@ +package nodes + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "github.com/XM-GO/PandaKit/httpclient" + "github.com/sirupsen/logrus" + "net/url" + "pandax/pkg/rule_engine/message" + "time" +) + +type externalDingNode struct { + bareNode + WebHook string `json:"webHook" yaml:"webHook"` + Secret string `json:"secret"` + MsgType string `json:"msgType" yaml:"msgType"` + Content string `json:"content" yaml:"content"` + IsAtAll bool `json:"isAtAll" yaml:"isAtAll"` + AtMobiles []string `json:"atMobiles" yaml:"atMobiles"` +} + +type externalDingNodeFactory struct{} + +func (f externalDingNodeFactory) Name() string { return "DingNode" } +func (f externalDingNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalDingNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalDingNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalDingNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *externalDingNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + //获取消息 + template, err := ParseTemplate(n.Content, msg.GetAllMap()) + if err != nil { + return err + } + sendData := map[string]interface{}{ + "msgtype": "text", + "text": map[string]string{"content": template}, + } + if n.IsAtAll { + sendData["at"] = map[string]interface{}{"isAtAll": n.IsAtAll} + } else { + sendData["at"] = map[string]interface{}{"atMobiles": n.AtMobiles} + } + marshal, _ := json.Marshal(sendData) + + timestamp := time.Now().UnixMilli() + sign := getSign(timestamp, n.Secret) + + url := fmt.Sprintf("%s×tamp=%d&sign=%s", n.WebHook, timestamp, sign) + + postJson := httpclient.NewRequest(url).Header("Content-Type", "application/json").PostJson(string(marshal)) + if postJson.StatusCode != 200 { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return err + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} + +func getSign(timestamp int64, secret string) string { + stringToSign := fmt.Sprintf("%d\n%s", timestamp, secret) + hash := hmac.New(sha256.New, []byte(secret)) + hash.Write([]byte(stringToSign)) + signData := hash.Sum(nil) + return url.QueryEscape(base64.StdEncoding.EncodeToString(signData)) +} diff --git a/pkg/rule_engine/nodes/external_kafka_node.go b/pkg/rule_engine/nodes/external_kafka_node.go new file mode 100644 index 0000000000000000000000000000000000000000..6bff75abdd44d448789b006a7c3e57f8ebec58a7 --- /dev/null +++ b/pkg/rule_engine/nodes/external_kafka_node.go @@ -0,0 +1,85 @@ +package nodes + +import ( + "encoding/json" + "github.com/Shopify/sarama" + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" + "strings" + "time" +) + +type externalKafkaNode struct { + bareNode + Server string `json:"server" yaml:"server"` //kafka集群 "10.130.138.164:9092,10.130.138.165:9093" + Topic string `json:"topic" yaml:"topic"` //topic + KeyPattern string `json:"keyPattern" yaml:"keyPattern"` //metadataKey or messageKey + ProducesBatchSize int64 `json:"producesBatchSize" yaml:"producesBatchSize"` + OtherProperties map[string]interface{} `json:"otherProperties"` //发送的其他参数 + KafkaCli sarama.SyncProducer +} + +type externalKafkaNodeFactory struct{} + +func (f externalKafkaNodeFactory) Name() string { return "KafkaNode" } +func (f externalKafkaNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalKafkaNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalKafkaNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalKafkaNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + _, err := decodePath(meta, node) + if err != nil { + return node, err + } + config := sarama.NewConfig() + config.Producer.Return.Successes = true + config.Producer.Timeout = 5 * time.Second + config.Producer.MaxMessageBytes = int(node.ProducesBatchSize) + p, err := sarama.NewSyncProducer(strings.Split(node.Server, ","), config) + if err != nil { + logrus.Errorf("sarama.NewSyncProducer err, message=%s \n", err) + return node, err + } + node.KafkaCli = p + return node, nil +} + +func (n *externalKafkaNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + defer n.KafkaCli.Close() + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + value := sarama.ByteEncoder("") + if n.KeyPattern == "metadataKey" { + marshal, err := json.Marshal(msg.GetMetadata().GetValues()) + if err != nil { + return err + } + value = marshal + } else { + marshal, err := json.Marshal(msg.GetMsg()) + if err != nil { + return err + } + value = marshal + } + + kafkaM := &sarama.ProducerMessage{ + Topic: n.Topic, + Value: value, + } + _, _, err := n.KafkaCli.SendMessage(kafkaM) + if err != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return err + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + + return nil +} diff --git a/pkg/rule_engine/nodes/external_mqtt_node.go b/pkg/rule_engine/nodes/external_mqtt_node.go new file mode 100644 index 0000000000000000000000000000000000000000..f47835c44acc76c353fca71eb96e269a31f82fb7 --- /dev/null +++ b/pkg/rule_engine/nodes/external_mqtt_node.go @@ -0,0 +1,84 @@ +package nodes + +import ( + "encoding/json" + "fmt" + "pandax/pkg/rule_engine/message" + "time" + + mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/sirupsen/logrus" +) + +type externalMqttNode struct { + bareNode + TopicPattern string `json:"topicPattern"` + Username string `json:"username"` + Password string `json:"password"` + Host string `json:"host"` + Port string `json:"port"` + ConnectTimeoutSec int `json:"connectTimeoutSec"` + ClientId string `json:"clientId"` + CleanSession bool `json:"cleanSession"` + Ssl bool `json:"ssl"` + MqttCli mqtt.Client +} + +type externalMqttNodeFactory struct{} + +func (f externalMqttNodeFactory) Name() string { return "MqttNode" } +func (f externalMqttNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalMqttNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalMqttNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalMqttNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + _, err := decodePath(meta, node) + if err != nil { + return node, err + } + broker := fmt.Sprintf("tcp://%s:%s", node.Host, node.Port) + opts := mqtt.NewClientOptions().AddBroker(broker) + if node.ClientId != "" { + opts.SetClientID(node.ClientId) + } + opts.SetCleanSession(node.CleanSession) + opts.SetConnectTimeout(time.Duration(node.ConnectTimeoutSec) * time.Second) + if node.Username != "" { + opts.SetUsername(node.Username) + } + if node.Password != "" { + opts.SetPassword(node.Password) + } + node.MqttCli = mqtt.NewClient(opts) + + if token := node.MqttCli.Connect(); token.Wait() && token.Error() != nil { + logrus.WithError(token.Error()) + return nil, token.Error() + } + return node, nil +} + +func (n *externalMqttNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + defer n.MqttCli.Disconnect(1000) + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + topic := n.TopicPattern //need fix add msg.metadata in it + sendmqttmsg, err := json.Marshal(msg.GetMsg()) + if err != nil { + return err + } + token := n.MqttCli.Publish(topic, 1, false, sendmqttmsg) + if token.Wait() && token.Error() != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return token.Error() + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/external_nats_node.go b/pkg/rule_engine/nodes/external_nats_node.go new file mode 100644 index 0000000000000000000000000000000000000000..e52c2707a49b6cee5144494be4a0bd1a390cc85f --- /dev/null +++ b/pkg/rule_engine/nodes/external_nats_node.go @@ -0,0 +1,59 @@ +package nodes + +import ( + "github.com/nats-io/nats.go" + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type externalNatsNode struct { + bareNode + Url string `json:"url"` + Subject string `json:"subject"` + Body string + client *nats.Conn +} + +type externalNatsNodeFactory struct{} + +func (f externalNatsNodeFactory) Name() string { return "NatsNode" } +func (f externalNatsNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalNatsNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalNatsNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalNatsNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + _, err := decodePath(meta, node) + if err != nil { + return node, err + } + connect, err := nats.Connect(node.Url) + if err != nil { + return node, err + } + node.client = connect + return node, nil +} + +func (n *externalNatsNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + defer n.client.Close() + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + template, err := ParseTemplate(n.Body, msg.GetAllMap()) + if err != nil { + return err + } + err = n.client.Publish(n.Subject, []byte(template)) + if err != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return err + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/external_restapi_node.go b/pkg/rule_engine/nodes/external_restapi_node.go new file mode 100644 index 0000000000000000000000000000000000000000..cffcd88d68fedd64f06a0f77f6f397bfbd24b1fa --- /dev/null +++ b/pkg/rule_engine/nodes/external_restapi_node.go @@ -0,0 +1,101 @@ +package nodes + +import ( + "encoding/json" + "errors" + "github.com/XM-GO/PandaKit/httpclient" + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type externalRestapiNode struct { + bareNode + RestEndpointUrlPattern string `json:"restEndpointUrlPattern" yaml:"restEndpointUrlPattern"` + RequestMethod string `json:"requestMethod" yaml:"requestMethod"` + Headers map[string]string `json:"headers" yaml:"headers"` +} + +type externalRestapiNodeFactory struct{} + +func (f externalRestapiNodeFactory) Name() string { return "RestapiNode" } +func (f externalRestapiNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalRestapiNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalRestapiNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalRestapiNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *externalRestapiNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + successLableNode := n.GetLinkedNode("Success") + failureLableNode := n.GetLinkedNode("Failure") + if n.RequestMethod == "GET" { + resp := httpclient.NewRequest(n.RestEndpointUrlPattern).Get() + if resp.StatusCode != 200 { + return errors.New("网络请求失败") + } + var response map[string]interface{} + err := json.Unmarshal(resp.Body, &response) + if err != nil && failureLableNode != nil { + return failureLableNode.Handle(msg) + } else { + if successLableNode != nil { + metadata := msg.GetMetadata() + for key, value := range response { + metadata.SetKeyValue(key, value) + } + msg.SetMetadata(metadata) + return successLableNode.Handle(msg) + } + } + } + if n.RequestMethod == "POST" { + binary, _ := msg.MarshalBinary() + req := httpclient.NewRequest(n.RestEndpointUrlPattern) + for key, value := range n.Headers { + req.Header(key, value) + } + resp := req.PostJson(string(binary)) + if resp.StatusCode != 200 { + if failureLableNode != nil { + return failureLableNode.Handle(msg) + } + } else { + if successLableNode != nil { + return successLableNode.Handle(msg) + } + } + } + /*if n.RequestMethod == "PUT" { + binary, _ := msg.MarshalBinary() + req := httpclient.NewRequest(n.RestEndpointUrlPattern) + for key,value := range n.Headers { + req.Header(key,value) + } + _, err := http.HttpPut(n.RestEndpointUrlPattern, n.Headers, nil, binary) + if err != nil { + if failureLableNode != nil { + return failureLableNode.Handle(msg) + } + } else { + if successLableNode != nil { + return successLableNode.Handle(msg) + } + } + } + if n.RequestMethod == "DELETE" { + _, err := http.HttpDelete(n.RestEndpointUrlPattern) + if err != nil { + if failureLableNode != nil { + return failureLableNode.Handle(msg) + } + } else { + if successLableNode != nil { + return successLableNode.Handle(msg) + } + } + }*/ + return nil +} diff --git a/pkg/rule_engine/nodes/external_rule_chain_node.go b/pkg/rule_engine/nodes/external_rule_chain_node.go new file mode 100644 index 0000000000000000000000000000000000000000..c762a783fd78bffc0f3d6f7c49cff5f9ed1060a0 --- /dev/null +++ b/pkg/rule_engine/nodes/external_rule_chain_node.go @@ -0,0 +1,51 @@ +package nodes + +import ( + "pandax/apps/rule/services" + "pandax/pkg/rule_engine/message" + + "errors" + "fmt" + "github.com/sirupsen/logrus" +) + +type externalRuleChainNode struct { + bareNode + RuleId string `json:"ruleId" yaml:"ruleId"` +} + +type externalRuleChainNodeFactory struct{} + +func (f externalRuleChainNodeFactory) Name() string { return "RuleChainNode" } +func (f externalRuleChainNodeFactory) Category() string { return NODE_CATEGORY_FLOWS } +func (f externalRuleChainNodeFactory) Labels() []string { return []string{} } +func (f externalRuleChainNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalRuleChainNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + + return decodePath(meta, node) +} + +func (n *externalRuleChainNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + data := services.RuleChainModelDao.FindOne(n.RuleId) + if data == nil { + return errors.New(fmt.Sprintf("节点 %s ,获取规则链失败", n.Name())) + } + + /*code, _ := json.Marshal(data.RuleDataJson.LfData.DataCode) + m, err := manifest.New(code) + if err != nil { + logrus.WithError(err).Errorf("invalidi manifest file") + return err + } + nodes, err := GetNodes(m) + if err != nil { + return errors.New(fmt.Sprintf("节点 %s ,构建节点失败", n.Name())) + } + if node, found := nodes[m.FirstRuleNodeId]; found { + go node.Handle(msg) + }*/ + return nil +} diff --git a/pkg/rule_engine/nodes/external_send_email_node.go b/pkg/rule_engine/nodes/external_send_email_node.go new file mode 100644 index 0000000000000000000000000000000000000000..a5b4ede5894ae0a66d93e58b6a4fb96f845809e2 --- /dev/null +++ b/pkg/rule_engine/nodes/external_send_email_node.go @@ -0,0 +1,89 @@ +package nodes + +import ( + "crypto/tls" + "fmt" + "github.com/sirupsen/logrus" + "net/smtp" + "pandax/pkg/rule_engine/message" + "strings" + + "github.com/jordan-wright/email" +) + +type externalSendEmailNode struct { + bareNode + Host string `json:"host"` // 服务器地址 + Port int `json:"port"` // 服务器端口 + From string `json:"from"` // 邮箱账号 + Nickname string `json:"nickname"` // 发件人 + Secret string `json:"secret"` // 邮箱密码 + IsSSL bool `json:"isSsl"` // 是否开启ssl + + To string `json:"to"` //收件人 + Subject string `json:"subject"` //主题 + Body string `json:"body"` //内容 +} + +type externalSendEmailNodeFactory struct{} + +func (f externalSendEmailNodeFactory) Name() string { return "SendEmailNode" } +func (f externalSendEmailNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalSendEmailNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalSendEmailNodeFactory) Create(id string, meta Metadata) (Node, error) { + + node := &externalSendEmailNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *externalSendEmailNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + + tos := strings.Split(n.To, ",") + if tos[len(tos)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除 + tos = tos[:len(tos)-1] + } + err := n.send(tos, msg) + if err != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return err + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} + +func (m *externalSendEmailNode) send(to []string, msg message.Message) error { + + auth := smtp.PlainAuth("", m.From, m.Secret, m.Host) + e := email.NewEmail() + if m.Nickname != "" { + e.From = fmt.Sprintf("%s <%s>", m.Nickname, m.From) + } else { + e.From = m.From + } + e.To = to + e.Subject = m.Subject + template, err := ParseTemplate(m.Body, msg.GetMetadata().GetValues()) + if err != nil { + return err + } + e.HTML = []byte(template) + hostAddr := fmt.Sprintf("%s:%d", m.Host, m.Port) + if m.IsSSL { + err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: m.Host}) + } else { + err = e.Send(hostAddr, auth) + } + + return err +} diff --git a/pkg/rule_engine/nodes/external_send_sms_node.go b/pkg/rule_engine/nodes/external_send_sms_node.go new file mode 100644 index 0000000000000000000000000000000000000000..ff854dc9d7e686c7865d3a33756d59325ed32c26 --- /dev/null +++ b/pkg/rule_engine/nodes/external_send_sms_node.go @@ -0,0 +1,37 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type externalSendSmsNode struct { + bareNode + SecretId string `json:"secretId" yaml:"secretId"` + SecretKey string `json:"secretKey" yaml:"secretKey"` + SdkAppId string `json:"sdkAppId" yaml:"sdkAppId"` //应用Id(腾讯) 或 签名名称(阿里) + PhoneNumber string `json:"phoneNumber" yaml:"phoneNumber"` //发送到手机号 + TemplateId string `json:"templateId" yaml:"templateId"` //短信模板Id + TemplateParam map[string]interface{} `json:"templateParam" yaml:"templateParam"` //模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空*/ +} + +type externalSendSmsNodeFactory struct{} + +func (f externalSendSmsNodeFactory) Name() string { return "SendSmsNode" } +func (f externalSendSmsNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalSendSmsNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalSendSmsNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalSendSmsNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *externalSendSmsNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + //failureLabelNode := n.GetLinkedNode("Failure") + + return successLabelNode.Handle(msg) +} diff --git a/pkg/rule_engine/nodes/external_wechat_node.go b/pkg/rule_engine/nodes/external_wechat_node.go new file mode 100644 index 0000000000000000000000000000000000000000..0600ae63b38b8d03d547a67e8d10683ba3152e6d --- /dev/null +++ b/pkg/rule_engine/nodes/external_wechat_node.go @@ -0,0 +1,59 @@ +package nodes + +import ( + "encoding/json" + "github.com/XM-GO/PandaKit/httpclient" + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type externalWechatNode struct { + bareNode + WebHook string `json:"webHook" yaml:"webHook"` + MsgType string `json:"msgType" yaml:"msgType"` + Content string `json:"content" yaml:"content"` + IsAtAll bool `json:"isAtAll" yaml:"isAtAll"` + AtMobiles []string `json:"atMobiles" yaml:"atMobiles"` +} + +type externalWechatNodeFactory struct{} + +func (f externalWechatNodeFactory) Name() string { return "WechatNode" } +func (f externalWechatNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL } +func (f externalWechatNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f externalWechatNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &externalWechatNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *externalWechatNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + template, err := ParseTemplate(n.Content, msg.GetAllMap()) + sendData := map[string]interface{}{ + "msgtype": "text", + "text": map[string]interface{}{"content": template}, + } + if n.IsAtAll { + sendData["text"].(map[string]interface{})["mentioned_mobile_list"] = []string{"@all"} + } else { + sendData["text"].(map[string]interface{})["mentioned_mobile_list"] = n.AtMobiles + } + marshal, _ := json.Marshal(sendData) + postJson := httpclient.NewRequest(n.WebHook).Header("Content-Type", "application/json").PostJson(string(marshal)) + if postJson.StatusCode != 200 { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return err + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/factory.go b/pkg/rule_engine/nodes/factory.go new file mode 100644 index 0000000000000000000000000000000000000000..8360126da5aee1518988610e1b62a1d8dc075018 --- /dev/null +++ b/pkg/rule_engine/nodes/factory.go @@ -0,0 +1,54 @@ +package nodes + +import ( + "fmt" +) + +const ( + NODE_CATEGORY_FILTER = "filter" + NODE_CATEGORY_ACTION = "action" + NODE_CATEGORY_ENRICHMENT = "enrichment" + NODE_CATEGORY_TRANSFORM = "transform" + NODE_CATEGORY_EXTERNAL = "external" + NODE_CATEGORY_OTHERS = "others" + NODE_CATEGORY_FLOWS = "flows" +) + +type Factory interface { + Name() string + Category() string + Labels() []string + Create(id string, meta Metadata) (Node, error) +} + +var ( + // allNodeFactories hold all node's factory + allNodeFactories map[string]Factory = make(map[string]Factory) + + // allNodeCategories hold node's metadata by category + allNodeCategories map[string][]map[string]interface{} = make(map[string][]map[string]interface{}) + allCategories []map[string]interface{} = make([]map[string]interface{}, 0) +) + +func RegisterFactory(f Factory) { + allNodeFactories[f.Name()] = f + + if allNodeCategories[f.Category()] == nil { + allNodeCategories[f.Category()] = []map[string]interface{}{} + } + allNodeCategories[f.Category()] = append(allNodeCategories[f.Category()], map[string]interface{}{"name": f.Name(), "labels": f.Labels()}) + allCategories = append(allCategories, map[string]interface{}{"name": f.Name(), "labels": f.Labels()}) +} + +// NewNode is the only way to create a new node +func NewNode(nodeType string, id string, meta Metadata) (Node, error) { + if f, found := allNodeFactories[nodeType]; found { + return f.Create(id, meta) + } + return nil, fmt.Errorf("invalid node type '%s'", nodeType) +} + +// GetCategoryNodes return specified category's all nodes +func GetCategoryNodes() map[string][]map[string]interface{} { return allNodeCategories } + +func GetCategory() []map[string]interface{} { return allCategories } diff --git a/pkg/rule_engine/nodes/filter_device_type_switch_node.go b/pkg/rule_engine/nodes/filter_device_type_switch_node.go new file mode 100644 index 0000000000000000000000000000000000000000..ea38b28a15ec643a6a5e9f3b8650895595d2db57 --- /dev/null +++ b/pkg/rule_engine/nodes/filter_device_type_switch_node.go @@ -0,0 +1,45 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +//检查关联关系 +//该消息来自与哪个实体或到那个实体 +type deviceTypeSwitchNode struct { + bareNode +} + +type deviceTypeSwitchNodeFactory struct{} + +func (f deviceTypeSwitchNodeFactory) Name() string { return "DeviceTypeSwitchNode" } +func (f deviceTypeSwitchNodeFactory) Category() string { return NODE_CATEGORY_FILTER } +func (f deviceTypeSwitchNodeFactory) Labels() []string { + return []string{message.DEVICE, message.GATEWAY} +} +func (f deviceTypeSwitchNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &deviceTypeSwitchNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *deviceTypeSwitchNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + deviceLabelNode := n.GetLinkedNode(message.DEVICE) + gatewayLabelNode := n.GetLinkedNode(message.GATEWAY) + + if msg.GetMetadata().GetKeyValue("deviceType") == message.DEVICE { + if deviceLabelNode != nil { + return deviceLabelNode.Handle(msg) + } + } + if msg.GetMetadata().GetKeyValue("deviceType") == message.GATEWAY { + if gatewayLabelNode != nil { + return gatewayLabelNode.Handle(msg) + } + } + return nil +} diff --git a/pkg/rule_engine/nodes/filter_message_type_node.go b/pkg/rule_engine/nodes/filter_message_type_node.go new file mode 100644 index 0000000000000000000000000000000000000000..31bfa5ca1ce0fe8d016c4e3ede92c9522a365c41 --- /dev/null +++ b/pkg/rule_engine/nodes/filter_message_type_node.go @@ -0,0 +1,43 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type messageTypeFilterNode struct { + bareNode + MessageTypes []string `json:"messageTypes" yaml:"messageTypes"` +} + +type messageTypeFilterNodeFactory struct{} + +func (f messageTypeFilterNodeFactory) Name() string { return "MessageTypeNode" } +func (f messageTypeFilterNodeFactory) Category() string { return NODE_CATEGORY_FILTER } +func (f messageTypeFilterNodeFactory) Labels() []string { return []string{"True", "False"} } + +func (f messageTypeFilterNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &messageTypeFilterNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + MessageTypes: []string{}, + } + return decodePath(meta, node) +} + +func (n *messageTypeFilterNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + trueLabelNode := n.GetLinkedNode("True") + falseLabelNode := n.GetLinkedNode("False") + messageType := msg.GetType() + + for _, filterType := range n.MessageTypes { + if filterType == messageType && trueLabelNode != nil { + return trueLabelNode.Handle(msg) + } + } + if falseLabelNode != nil { + return falseLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/filter_message_type_switch_node.go b/pkg/rule_engine/nodes/filter_message_type_switch_node.go new file mode 100644 index 0000000000000000000000000000000000000000..18a2ce6a25c6772ce517d14885aa0ffde08b1958 --- /dev/null +++ b/pkg/rule_engine/nodes/filter_message_type_switch_node.go @@ -0,0 +1,46 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type messageTypeSwitchNode struct { + bareNode +} +type messageTypeSwitchNodeFactory struct{} + +func (f messageTypeSwitchNodeFactory) Name() string { return "MessageTypeSwitchNode" } +func (f messageTypeSwitchNodeFactory) Category() string { return NODE_CATEGORY_FILTER } +func (f messageTypeSwitchNodeFactory) Labels() []string { + return []string{ + message.RowMes, + message.AttributesMes, + message.TelemetryMes, + message.RpcRequestMes, + message.AlarmMes, + message.UpEventMes, + message.ConnectMes, + message.ConnectMes, + message.DisConnectMes, + } +} +func (f messageTypeSwitchNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &messageTypeSwitchNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *messageTypeSwitchNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + nodes := n.GetLinkedNodes() + messageType := msg.GetType() + for label, node := range nodes { + if messageType == label { + return node.Handle(msg) + } + } + return nil +} diff --git a/pkg/rule_engine/nodes/filter_script_node.go b/pkg/rule_engine/nodes/filter_script_node.go new file mode 100644 index 0000000000000000000000000000000000000000..aa77322829f9a616a676065783e6f510873a6699 --- /dev/null +++ b/pkg/rule_engine/nodes/filter_script_node.go @@ -0,0 +1,43 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +const ScriptFilterNodeName = "ScriptFilterNode" + +type scriptFilterNode struct { + bareNode + Script string `json:"script" yaml:"script"` +} + +type scriptFilterNodeFactory struct{} + +func (f scriptFilterNodeFactory) Name() string { return ScriptFilterNodeName } +func (f scriptFilterNodeFactory) Category() string { return NODE_CATEGORY_FILTER } +func (f scriptFilterNodeFactory) Labels() []string { return []string{"True", "False"} } +func (f scriptFilterNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &scriptFilterNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *scriptFilterNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + trueLabelNode := n.GetLinkedNode("True") + falseLabelNode := n.GetLinkedNode("False") + scriptEngine := NewScriptEngine(msg, "Filter", n.Script) + isTrue, error := scriptEngine.ScriptOnFilter() + if isTrue == true && error == nil && trueLabelNode != nil { + return trueLabelNode.Handle(msg) + } else { + if falseLabelNode != nil { + return falseLabelNode.Handle(msg) + } + } + + return nil +} diff --git a/pkg/rule_engine/nodes/filter_switch_node.go b/pkg/rule_engine/nodes/filter_switch_node.go new file mode 100644 index 0000000000000000000000000000000000000000..a4f0181c835e92defc2039bf1628fdf5fd1dc748 --- /dev/null +++ b/pkg/rule_engine/nodes/filter_switch_node.go @@ -0,0 +1,54 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type switchFilterNode struct { + bareNode + Script string `json:"script" yaml:"script"` +} + +type switchFilterNodeFactory struct{} + +func (f switchFilterNodeFactory) Name() string { return "SwitchNode" } +func (f switchFilterNodeFactory) Category() string { return NODE_CATEGORY_FILTER } +func (f switchFilterNodeFactory) Labels() []string { + return []string{ + "True", "False", + message.RowMes, + message.AttributesMes, + message.TelemetryMes, + message.RpcRequestMes, + message.AlarmMes, + message.UpEventMes, + message.ConnectMes, + message.DisConnectMes, + } +} +func (f switchFilterNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &switchFilterNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *switchFilterNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + scriptEngine := NewScriptEngine(msg, "Switch", n.Script) + SwitchResults, err := scriptEngine.ScriptOnSwitch() + if err != nil { + return err + } + nodes := n.GetLinkedNodes() + for label, node := range nodes { + for _, switchresult := range SwitchResults { + if label == switchresult { + go node.Handle(msg) + } + } + } + return nil +} diff --git a/pkg/rule_engine/nodes/init.go b/pkg/rule_engine/nodes/init.go new file mode 100644 index 0000000000000000000000000000000000000000..722b9056e5603713ca53e72c47b9d7a95181e1a2 --- /dev/null +++ b/pkg/rule_engine/nodes/init.go @@ -0,0 +1,32 @@ +package nodes + +// init register all node's factory +func init() { + RegisterFactory(inputNodeFactory{}) + RegisterFactory(switchFilterNodeFactory{}) + RegisterFactory(scriptFilterNodeFactory{}) + RegisterFactory(messageTypeFilterNodeFactory{}) + RegisterFactory(messageTypeSwitchNodeFactory{}) + + RegisterFactory(transformDeleteKeyNodeFactory{}) + RegisterFactory(transformRenameKeyNodeFactory{}) + RegisterFactory(transformScriptNodeFactory{}) + + RegisterFactory(createAlarmNodeFactory{}) + RegisterFactory(clearAlarmNodeFactory{}) + RegisterFactory(logNodeFactory{}) + RegisterFactory(saveAttributesNodeFactory{}) + RegisterFactory(saveTimeSeriesNodeFactory{}) + RegisterFactory(delayNodeFactory{}) + + RegisterFactory(externalDingNodeFactory{}) + RegisterFactory(externalWechatNodeFactory{}) + RegisterFactory(externalKafkaNodeFactory{}) + RegisterFactory(externalNatsNodeFactory{}) + RegisterFactory(externalMqttNodeFactory{}) + RegisterFactory(externalRestapiNodeFactory{}) + RegisterFactory(externalSendEmailNodeFactory{}) + RegisterFactory(externalSendSmsNodeFactory{}) + RegisterFactory(externalRuleChainNodeFactory{}) + +} diff --git a/pkg/rule_engine/nodes/input_node.go b/pkg/rule_engine/nodes/input_node.go new file mode 100644 index 0000000000000000000000000000000000000000..89f794e70cc990cb2ffdb9cba7f037509d52372b --- /dev/null +++ b/pkg/rule_engine/nodes/input_node.go @@ -0,0 +1,34 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +const InputNodeName = "InputNode" + +type inputNode struct { + bareNode +} + +type inputNodeFactory struct{} + +func (f inputNodeFactory) Name() string { return "InputNode" } +func (f inputNodeFactory) Category() string { return NODE_CATEGORY_OTHERS } +func (f inputNodeFactory) Labels() []string { return []string{"True"} } +func (f inputNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &inputNode{ + bareNode: newBareNode(InputNodeName, id, meta, f.Labels()), + } + return node, nil +} + +func (n *inputNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + nodes := n.GetLinkedNodes() + for _, node := range nodes { + return node.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/metadata.go b/pkg/rule_engine/nodes/metadata.go new file mode 100644 index 0000000000000000000000000000000000000000..84c38c6b52afe04b6411adfb4bf9380bfdde2598 --- /dev/null +++ b/pkg/rule_engine/nodes/metadata.go @@ -0,0 +1,63 @@ +package nodes + +import ( + "fmt" + "github.com/mitchellh/mapstructure" +) + +const ( + NODE_CONFIG_MESSAGE_TYPE_KEY = "messageTypeKey" + NODE_CONFIG_ORIGINATOR_TYPE_KEY = "originatorTypeKey" +) + +type Metadata interface { + Keys() []string + With(key string, val interface{}) Metadata + Value(key string) (interface{}, error) + DecodePath(rawVal interface{}) error +} + +type nodeMetadata struct { + keypairs map[string]interface{} +} + +func NewMetadata() Metadata { + return &nodeMetadata{ + keypairs: make(map[string]interface{}), + } +} + +func NewMetadataWithString(vals string) Metadata { + return &nodeMetadata{} +} + +func NewMetadataWithValues(vals map[string]interface{}) Metadata { + return &nodeMetadata{ + keypairs: vals, + } +} + +func (c *nodeMetadata) Keys() []string { + keys := []string{} + for key, _ := range c.keypairs { + keys = append(keys, key) + } + return keys +} + +func (c *nodeMetadata) Value(key string) (interface{}, error) { + if val, found := c.keypairs[key]; found { + return val, nil + } + return nil, fmt.Errorf("key '%s' not found", key) +} + +func (c *nodeMetadata) With(key string, val interface{}) Metadata { + c.keypairs[key] = val + return c +} + +func (c *nodeMetadata) DecodePath(rawVal interface{}) error { + //return utils.Map2Struct(c.keypairs, rawVal) + return mapstructure.Decode(c.keypairs, rawVal) +} diff --git a/pkg/rule_engine/nodes/node.go b/pkg/rule_engine/nodes/node.go new file mode 100644 index 0000000000000000000000000000000000000000..ed12f8fee75e2121df279cb0fbdc63d68c8aa769 --- /dev/null +++ b/pkg/rule_engine/nodes/node.go @@ -0,0 +1,109 @@ +package nodes + +import ( + "errors" + "github.com/sirupsen/logrus" + "log" + "pandax/pkg/rule_engine/manifest" + "pandax/pkg/rule_engine/message" +) + +type Node interface { + Name() string + Id() string + Metadata() Metadata + MustLabels() []string + Handle(message.Message) error + + AddLinkedNode(label string, node Node) + GetLinkedNode(label string) Node + GetLinkedNodes() map[string]Node +} + +type bareNode struct { + name string + id string + nodes map[string]Node + meta Metadata + labels []string +} + +func newBareNode(name string, id string, meta Metadata, labels []string) bareNode { + return bareNode{ + name: name, + id: id, + nodes: make(map[string]Node), + meta: meta, + labels: labels, + } +} + +func (n *bareNode) Name() string { return n.name } +func (n *bareNode) WithId(id string) { n.id = id } +func (n *bareNode) Id() string { return n.id } +func (n *bareNode) MustLabels() []string { return n.labels } +func (n *bareNode) AddLinkedNode(label string, node Node) { n.nodes[label] = node } + +func (n *bareNode) GetLinkedNode(label string) Node { + if node, found := n.nodes[label]; found { + return node + } + return nil +} + +func (n *bareNode) GetLinkedNodes() map[string]Node { return n.nodes } + +func (n *bareNode) Metadata() Metadata { return n.meta } + +func (n *bareNode) Handle(message.Message) error { return errors.New("not implemented") } + +func decodePath(meta Metadata, n Node) (Node, error) { + if err := meta.DecodePath(n); err != nil { + return n, err + } + return n, nil +} + +func GetNodes(m *manifest.Manifest) (map[string]Node, error) { + nodes := make(map[string]Node) + // Create All nodes + for _, n := range m.Nodes { + metadata := NewMetadataWithValues(n.Properties) + node, err := NewNode(n.Type, n.Id, metadata) + if err != nil { + log.Println(err) + logrus.Errorf("new node '%s' failure", n.Id) + continue + } + if _, found := nodes[n.Id]; found { + logrus.Errorf("node '%s' already exist in rulechain", n.Id) + continue + } + nodes[n.Id] = node + } + for _, edge := range m.Edges { + originalNode, found := nodes[edge.SourceNodeId] + if !found { + logrus.Errorf("original node '%s' no exist in", originalNode.Name()) + continue + } + targetNode, found := nodes[edge.TargetNodeId] + if !found { + logrus.Errorf("target node '%s' no exist in rulechain", targetNode.Name()) + continue + } + //可以有多个类型 + types := make([]interface{}, 0) + if _, ok := edge.Properties["lineType"]; !ok { + types = append(types, "True") + } else { + types = edge.Properties["lineType"].([]interface{}) + } + for _, ty := range types { + originalNode.AddLinkedNode(ty.(string), targetNode) + } + + } + + return nodes, nil +} diff --git a/pkg/rule_engine/nodes/script_engine.go b/pkg/rule_engine/nodes/script_engine.go new file mode 100644 index 0000000000000000000000000000000000000000..52a453771691f7b64025cb7f1c7323e1b65b014c --- /dev/null +++ b/pkg/rule_engine/nodes/script_engine.go @@ -0,0 +1,123 @@ +package nodes + +import ( + "fmt" + "github.com/dop251/goja" + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type ScriptEngine interface { + ScriptOnMessage() (message.Message, error) + ScriptOnSwitch() ([]string, error) + ScriptOnFilter() (bool, error) + ScriptToString() (string, error) + ScriptGenerate() (map[string]interface{}, error) +} + +type baseScriptEngine struct { + Fun string + Script string + Msg message.Message +} + +func NewScriptEngine(msg message.Message, fun string, script string) ScriptEngine { + return &baseScriptEngine{ + Fun: fun, + Script: fmt.Sprintf("function %s(msg, metadata, msgType) { %s }", fun, script), + Msg: msg, + } +} + +func (bse *baseScriptEngine) ScriptOnMessage() (message.Message, error) { + msg := bse.Msg + vm := goja.New() + _, err := vm.RunString(bse.Script) + if err != nil { + logrus.Info("JS代码有问题") + return nil, err + } + var fn func(map[string]interface{}, map[string]interface{}, string) map[string]interface{} + err = vm.ExportTo(vm.Get(bse.Fun), &fn) + if err != nil { + logrus.Info("Js函数映射到 Go 函数失败!") + return nil, err + } + datas := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType()) + msg.SetMsg(datas["msg"].(map[string]interface{})) + msg.SetMetadata(message.NewDefaultMetadata(datas["metadata"].(map[string]interface{}))) + msg.SetType(datas["msgType"].(string)) + return msg, nil +} + +func (bse *baseScriptEngine) ScriptOnSwitch() ([]string, error) { + msg := bse.Msg + vm := goja.New() + _, err := vm.RunString(bse.Script) + if err != nil { + logrus.Info("JS代码有问题") + return nil, err + } + var fn func(map[string]interface{}, map[string]interface{}, string) []string + err = vm.ExportTo(vm.Get(bse.Fun), &fn) + if err != nil { + logrus.Info("Js函数映射到 Go 函数失败!") + return nil, err + } + datas := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType()) + return datas, nil +} + +func (bse *baseScriptEngine) ScriptOnFilter() (bool, error) { + msg := bse.Msg + vm := goja.New() + _, err := vm.RunString(bse.Script) + if err != nil { + logrus.Info("JS代码有问题") + return false, err + } + var fn func(map[string]interface{}, map[string]interface{}, string) bool + err = vm.ExportTo(vm.Get(bse.Fun), &fn) + if err != nil { + logrus.Info("Js函数映射到 Go 函数失败!") + return false, err + } + datas := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType()) + return datas, nil +} + +func (bse *baseScriptEngine) ScriptToString() (string, error) { + msg := bse.Msg + vm := goja.New() + _, err := vm.RunString(bse.Script) + if err != nil { + logrus.Info("JS代码有问题") + return "", err + } + var fn func(map[string]interface{}, map[string]interface{}, string) string + err = vm.ExportTo(vm.Get(bse.Fun), &fn) + if err != nil { + logrus.Info("Js函数映射到 Go 函数失败!") + return "", err + } + data := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType()) + return data, nil +} + +func (bse *baseScriptEngine) ScriptGenerate() (map[string]interface{}, error) { + msg := bse.Msg + vm := goja.New() + _, err := vm.RunString(bse.Script) + if err != nil { + logrus.Info("JS代码有问题") + return nil, err + } + var fn func(map[string]interface{}, map[string]interface{}, string) map[string]interface{} + err = vm.ExportTo(vm.Get(bse.Fun), &fn) + if err != nil { + logrus.Info("Js函数映射到 Go 函数失败!") + return nil, err + } + datas := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType()) + return datas, nil +} diff --git a/pkg/rule_engine/nodes/template_engine.go b/pkg/rule_engine/nodes/template_engine.go new file mode 100644 index 0000000000000000000000000000000000000000..2ebb5a84a995e2ce889382879f2542a58922994c --- /dev/null +++ b/pkg/rule_engine/nodes/template_engine.go @@ -0,0 +1,19 @@ +package nodes + +import ( + "bytes" + "text/template" +) + +func ParseTemplate(content string, data map[string]interface{}) (string, error) { + tmpl, err := template.New("template").Parse(content) + if err != nil { + return "", err + } + buffer := &bytes.Buffer{} + err = tmpl.Execute(buffer, data) + if err != nil { + return "", err + } + return buffer.String(), nil +} diff --git a/pkg/rule_engine/nodes/transform_delete_key_node.go b/pkg/rule_engine/nodes/transform_delete_key_node.go new file mode 100644 index 0000000000000000000000000000000000000000..f20e418df8b04f7ecc235d0adc26482f4f689086 --- /dev/null +++ b/pkg/rule_engine/nodes/transform_delete_key_node.go @@ -0,0 +1,58 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" + "strings" +) + +type transformDeleteKeyNode struct { + bareNode + FormType string `json:"formType" yaml:"formType"` //msg metadata + Keys string `json:"keys" yaml:"keys"` +} +type transformDeleteKeyNodeFactory struct{} + +func (f transformDeleteKeyNodeFactory) Name() string { return "DeleteKeyNode" } +func (f transformDeleteKeyNodeFactory) Category() string { return NODE_CATEGORY_TRANSFORM } +func (f transformDeleteKeyNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f transformDeleteKeyNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &transformDeleteKeyNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *transformDeleteKeyNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + keys := strings.Split(n.Keys, ",") + if n.FormType == "msg" { + data := msg.GetMsg() + for _, key := range keys { + if _, found := data[key]; found { + delete(data, key) + msg.SetMsg(data) + } + } + } else if n.FormType == "metadata" { + data := msg.GetMetadata() + for _, key := range keys { + if data.GetKeyValue(key) != nil { + values := data.GetValues() + delete(values, key) + msg.SetMetadata(message.NewDefaultMetadata(values)) + } + } + } else { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/transform_rename_key_node.go b/pkg/rule_engine/nodes/transform_rename_key_node.go new file mode 100644 index 0000000000000000000000000000000000000000..ebbc62e48eb57937b404295f0c2635ac9fb682a8 --- /dev/null +++ b/pkg/rule_engine/nodes/transform_rename_key_node.go @@ -0,0 +1,62 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type transformRenameKeyNode struct { + bareNode + FormType string `json:"formType" yaml:"formType"` //msg metadata + Keys []KeyName `json:"keys" yaml:"keys"` +} +type KeyName struct { + OldName string `json:"oldName" yaml:"oldName"` + NewName string `json:"newName" yaml:"newName"` +} +type transformRenameKeyNodeFactory struct{} + +func (f transformRenameKeyNodeFactory) Name() string { return "RenameKeyNode" } +func (f transformRenameKeyNodeFactory) Category() string { return NODE_CATEGORY_TRANSFORM } +func (f transformRenameKeyNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f transformRenameKeyNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &transformRenameKeyNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *transformRenameKeyNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + if n.FormType == "msg" { + data := msg.GetMsg() + for _, key := range n.Keys { + if _, found := data[key.OldName]; found { + data[key.NewName] = data[key.OldName] + delete(data, key.OldName) + msg.SetMsg(data) + } + } + } else if n.FormType == "metadata" { + data := msg.GetMetadata() + for _, key := range n.Keys { + if data.GetKeyValue(key.OldName) != nil { + values := data.GetValues() + values[key.NewName] = values[key.OldName] + delete(values, key.OldName) + msg.SetMetadata(message.NewDefaultMetadata(values)) + } + } + } else { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } + } + if successLabelNode != nil { + return successLabelNode.Handle(msg) + } + return nil +} diff --git a/pkg/rule_engine/nodes/transform_script_node.go b/pkg/rule_engine/nodes/transform_script_node.go new file mode 100644 index 0000000000000000000000000000000000000000..ed860830ee98be2e845100d96e0644c098425543 --- /dev/null +++ b/pkg/rule_engine/nodes/transform_script_node.go @@ -0,0 +1,44 @@ +package nodes + +import ( + "github.com/sirupsen/logrus" + "pandax/pkg/rule_engine/message" +) + +type transformScriptNode struct { + bareNode + Script string `json:"script" yaml:"script"` +} + +type transformScriptNodeFactory struct{} + +func (f transformScriptNodeFactory) Name() string { return "ScriptKeyNode" } +func (f transformScriptNodeFactory) Category() string { return NODE_CATEGORY_TRANSFORM } +func (f transformScriptNodeFactory) Labels() []string { return []string{"Success", "Failure"} } +func (f transformScriptNodeFactory) Create(id string, meta Metadata) (Node, error) { + node := &transformScriptNode{ + bareNode: newBareNode(f.Name(), id, meta, f.Labels()), + } + return decodePath(meta, node) +} + +func (n *transformScriptNode) Handle(msg message.Message) error { + logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType()) + + successLabelNode := n.GetLinkedNode("Success") + failureLabelNode := n.GetLinkedNode("Failure") + + scriptEngine := NewScriptEngine(msg, "Transform", n.Script) + newMessage, err := scriptEngine.ScriptOnMessage() + if err != nil { + if failureLabelNode != nil { + return failureLabelNode.Handle(msg) + } else { + return err + } + } + if successLabelNode != nil { + return successLabelNode.Handle(newMessage) + } + return nil +} diff --git a/pkg/tdengine/TDengineModel.go b/pkg/tdengine/TDengineModel.go new file mode 100644 index 0000000000000000000000000000000000000000..91a3a0a0239dd58ee841fd2d06757cf24ca44b5b --- /dev/null +++ b/pkg/tdengine/TDengineModel.go @@ -0,0 +1,30 @@ +package tdengine + +import "time" + +type TDEngineTablesList struct { + TableName string `json:"tableName" description:"表名"` + DbName string `json:"dbName" description:"数据库名"` + StableName string `json:"stableName" description:"超级表名"` + CreateTime *time.Time `json:"createTime" description:"创建时间"` +} + +type TDEngineTableInfo struct { + Field string `json:"field" description:"字段名"` + Type string `json:"type" description:"类型"` + Length int `json:"length" description:"长度"` + Note string `json:"note" description:"note"` +} + +type TableDataInfo struct { + Filed []string `json:"filed" description:"字段"` + Info []map[string]interface{} `json:"info" description:"数据"` +} + +// 日志 TDengine +type TdLog struct { + Ts string `json:"ts" dc:"时间"` + Device string `json:"device" dc:"设备标识"` + Type string `json:"type" dc:"日志类型"` + Content string `json:"content" dc:"日志内容"` +} diff --git a/pkg/tdengine/tdengine.go b/pkg/tdengine/tdengine.go new file mode 100644 index 0000000000000000000000000000000000000000..12ed0ec729bfca4b997a7130d5ce6864d13fbd8e --- /dev/null +++ b/pkg/tdengine/tdengine.go @@ -0,0 +1,203 @@ +package tdengine + +import ( + "database/sql" + "fmt" + _ "github.com/taosdata/driver-go/v3/taosRestful" + "time" +) + +const ( + TIME_TYPE_PROP = "telemetry" + TIME_TYPE_ATRE = "attributes" + TIME_TYPE_LOGS = "logs" + TIME_TYPE_ALARM = "alarm" + TIME_TYPE_EVENT = "event" +) + +type TdEngine struct { + db *sql.DB + dbName string +} + +func NewTdengine(username, password, host, db string) (*TdEngine, error) { + dsn := fmt.Sprintf("%s:%s@%s(%s)/%s", + username, password, "http", host, db) + open, err := sql.Open("taosRestful", dsn) + return &TdEngine{ + db: open, + dbName: db, + }, err + +} + +// GetTdEngineAllDb 获取所有数据库 +func (s *TdEngine) GetTdEngineAllDb() (data []string, err error) { + rows, err := s.db.Query("show databases;") + if err != nil { + return + } + defer rows.Close() + + for rows.Next() { + var name string + err = rows.Scan(&name) + data = append(data, name) + } + return +} + +// GetListTableByDatabases 获取指定数据库下所有的表列表 +func (s *TdEngine) GetListTableByDatabases() (data []*TDEngineTablesList, err error) { + rows, err := s.db.Query("SELECT table_name AS tableName, db_name AS dbName, create_time AS createTime, stable_name AS stableName FROM information_schema.ins_tables WHERE db_name = '" + s.dbName + "'") + if err != nil { + return + } + defer rows.Close() + + for rows.Next() { + var tableName, db, stableName string + var createTime *time.Time + err = rows.Scan(&tableName, &db, &createTime, &stableName) + if err != nil { + return + } + var tDEngineTablesList = new(TDEngineTablesList) + tDEngineTablesList.TableName = tableName + tDEngineTablesList.DbName = db + tDEngineTablesList.StableName = stableName + tDEngineTablesList.CreateTime = createTime + data = append(data, tDEngineTablesList) + } + return +} + +// GetTdEngineTableInfoByTable 获取指定数据表结构信息 +func (s *TdEngine) GetTdEngineTableInfoByTable(tableName string) (data []*TDEngineTableInfo, err error) { + rows, err := s.db.Query("DESCRIBE " + s.dbName + "." + tableName + ";") + if err != nil { + return + } + defer rows.Close() + + for rows.Next() { + var tDEngineTableInfo = new(TDEngineTableInfo) + err = rows.Scan(&tDEngineTableInfo.Field, &tDEngineTableInfo.Type, &tDEngineTableInfo.Length, &tDEngineTableInfo.Note) + if err != nil { + return + } + data = append(data, tDEngineTableInfo) + } + return +} + +// GetTdEngineTableDataByTable 获取指定数据表数据信息 +func (s *TdEngine) GetTdEngineTableDataByTable(tableName string) (data *TableDataInfo, err error) { + data = new(TableDataInfo) + + rows, err := s.db.Query("SELECT * FROM " + tableName) + if err != nil { + return + } + defer rows.Close() + + //获取查询结果字段 + columns, _ := rows.Columns() + //字段数组 + var filed []string + //封装scanArg + scanArgs := make([]any, len(columns)) + for i := range columns { + filed = append(filed, columns[i]) + scanArgs[i] = &columns[i] + } + data.Filed = append(data.Filed, filed...) + for rows.Next() { + err = rows.Scan(scanArgs...) + if err != nil { + return + } + //封装返回结果 + var resultMap = make(map[string]interface{}) + for i := range columns { + resultMap[filed[i]] = columns[i] + } + data.Info = append(data.Info, resultMap) + } + + return +} + +// GetOne 超级表查询,单条数据 +func (s *TdEngine) GetOne(sql string, args ...any) (rs map[string]interface{}, err error) { + rows, err := s.db.Query(sql, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + columns, _ := rows.Columns() + values := make([]any, len(columns)) + rs = make(map[string]interface{}, len(columns)) + for i := range values { + values[i] = new(any) + } + + for rows.Next() { + err = rows.Scan(values...) + if err != nil { + return nil, err + } + + for i, c := range columns { + //rs[c] = s.Time(values[i]) + rs[c] = values[i] + } + rows.Close() + } + + return +} + +// GetAll 超级表查询,多条数据 +func (s *TdEngine) GetAll(sql string, args ...any) (rs []map[string]interface{}, err error) { + + rows, err := s.db.Query(sql, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + columns, _ := rows.Columns() + + for rows.Next() { + values := make([]any, len(columns)) + for i := range values { + values[i] = new(any) + } + + err = rows.Scan(values...) + if err != nil { + return nil, err + } + + m := make(map[string]interface{}, len(columns)) + for i, c := range columns { + //m[c] = s.Time(gvar.New(values[i])) + m[c] = values[i] + } + rs = append(rs, m) + } + + return +} + +// REST连接时区处理 +func (s *TdEngine) Time(v string) (rs string) { + if t, err := time.Parse("2006-01-02 15:04:05 +0000 UTC", v); err == nil { + rs = t.Local().Format("2006-01-02 15:04:05") + return + } + rs = v + return +} diff --git a/pkg/tdengine/tdengine_event.go b/pkg/tdengine/tdengine_event.go new file mode 100644 index 0000000000000000000000000000000000000000..2fcfe19e3e5cdacabc8210e3f0b460b87373f9b1 --- /dev/null +++ b/pkg/tdengine/tdengine_event.go @@ -0,0 +1,43 @@ +package tdengine + +import ( + "fmt" + "github.com/kakuilan/kgo" + "strings" +) + +type ConnectInfo struct { + Ts string `json:"ts"` + ClientID string `json:"clientId"` + Type string `json:"type"` // 连接类型 + PeerHost string `json:"peerHost"` + SocketPort string `json:"sockPort"` + Protocol string `json:"protocol"` + DeviceId string `json:"deviceId"` +} + +// CreateEventTable 创建设备连接事件表 +func (s *TdEngine) CreateEventTable() (err error) { + sql := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s.device_connect (ts TIMESTAMP,deviceId NCHAR(64), + type NCHAR(64),clientId NCHAR(64),peerHost NCHAR(64),sockPort NCHAR(64),protocol NCHAR(64))`, s.dbName) + _, err = s.db.Exec(sql) + return +} + +func (s *TdEngine) InsertEvent(data map[string]any) (err error) { + if len(data) == 0 { + return + } + var ( + field = []string{} + value = []string{} + ) + for k, v := range data { + field = append(field, k) + value = append(value, "'"+kgo.KConv.ToStr(v)+"'") + } + + sql := "INSERT INTO ? (?) VALUES (?)" + _, err = s.db.Exec(sql, "device_connect", strings.Join(field, ","), strings.Join(value, ",")) + return err +} diff --git a/pkg/tdengine/tdengine_log.go b/pkg/tdengine/tdengine_log.go new file mode 100644 index 0000000000000000000000000000000000000000..161a47e9c4299498a73c35a3387ea933808f1dbc --- /dev/null +++ b/pkg/tdengine/tdengine_log.go @@ -0,0 +1,56 @@ +package tdengine + +import "time" + +// CreateLogStable 添加LOG超级表 +func (s *TdEngine) CreateLogStable() (err error) { + var name string + err = s.db.QueryRow("SELECT stable_name FROM information_schema.ins_stables WHERE stable_name = 'device_log' LIMIT 1").Scan(&name) + if name != "" { + return + } + sql := "CREATE STABLE device_log (ts TIMESTAMP, type VARCHAR(20), content VARCHAR(1000)) TAGS (device VARCHAR(255))" + _, err = s.db.Exec(sql) + return +} + +// InsertLog 写入数据 +func (s *TdEngine) InsertLog(log *TdLog) (err error) { + sql := "INSERT INTO ? USING device_log TAGS ('?') VALUES ('?', '?', '?')" + _, err = s.db.Exec(sql, "log_"+log.Device, log.Device, log.Ts, log.Type, log.Content) + + return +} + +// ClearLog 清理过期数据 +func (s *TdEngine) ClearLog() (err error) { + ts := time.Now().Add(-7 * 24 * time.Hour).Format("2006-01-02") + + sql := "DELETE FROM device_log WHERE ts < '" + ts + "'" + _, err = s.db.Exec(sql) + + return +} + +// GetAllLog 超级表查询,多条数据 +func (s *TdEngine) GetAllLog(sql string, args ...any) (list []TdLog, err error) { + rows, err := s.db.Query(sql, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var log TdLog + + err = rows.Scan(&log.Ts, &log.Type, &log.Content, &log.Device) + if err != nil { + return nil, err + } + log.Ts = s.Time(log.Ts) + + list = append(list, log) + } + + return +} diff --git a/pkg/tdengine/tdengine_table.go b/pkg/tdengine/tdengine_table.go new file mode 100644 index 0000000000000000000000000000000000000000..ff1f2c87899fdb51feba102ed361e2d6e135df70 --- /dev/null +++ b/pkg/tdengine/tdengine_table.go @@ -0,0 +1,162 @@ +package tdengine + +import ( + "errors" + "fmt" + "github.com/kakuilan/kgo" + "strconv" + "strings" +) + +// RunSql 运行 +func (s *TdEngine) RunSql(sql string) (err error) { + _, err = s.db.Exec(sql) + return +} + +// InsertDevice 数据入库 +func (s *TdEngine) InsertDevice(deviceKey string, data map[string]any) (err error) { + + if len(data) == 0 { + return + } + var ( + field = []string{} + value = []string{} + ) + for k, v := range data { + field = append(field, k) + value = append(value, "'"+kgo.KConv.ToStr(v)+"'") + } + + sql := "INSERT INTO ? (?) VALUES (?)" + _, err = s.db.Exec(sql, deviceKey, strings.Join(field, ","), strings.Join(value, ",")) + + return +} + +// CreateStable 创建超级表 rowdata 源数据,在需要数据解析时使用 +func (s *TdEngine) CreateStable(table string) (err error) { + columns := []string{"ts TIMESTAMP,rowdata NCHAR(255)"} + sql := fmt.Sprintf("CREATE STABLE IF NOT EXISTS %s.%s (%s) TAGS (device nchar(64))", s.dbName, table, strings.Join(columns, ",")) + _, err = s.db.Exec(sql) + return +} + +// CreateTable 添加子表 +func (s *TdEngine) CreateTable(stable, table string) (err error) { + sql := fmt.Sprintf("CREATE TABLE %s USING %s TAGS ('%s')", table, stable, table) + _, err = s.db.Exec(sql) + return +} + +func (s *TdEngine) column(dataType, key, name string, maxLength int) string { + column := "" + comment := "" + if name != "" { + comment = "COMMENT '" + name + "'" + } + tdType := "" + switch dataType { + case "int64": + tdType = "INT" + case "long": + tdType = "BIGINT" + case "float64": + tdType = "FLOAT" + case "double": + tdType = "DOUBLE" + case "string": + if maxLength == 0 { + maxLength = 255 + } + tdType = "NCHAR(" + strconv.Itoa(maxLength) + ")" + case "boolean": + tdType = "BOOL" + case "date": + tdType = "TIMESTAMP" + default: + if maxLength == 0 { + maxLength = 255 + } + tdType = "NCHAR(" + strconv.Itoa(maxLength) + ")" + } + column = fmt.Sprintf("%s %s %s", key, tdType, comment) + return column +} + +// 删除超级表 +func (s *TdEngine) DropStable(table string) (err error) { + sql := fmt.Sprintf("DROP STABLE IF EXISTS %s.%s", s.dbName, table) + _, err = s.db.Exec(sql) + return +} + +// 删除子表 +func (s *TdEngine) DropTable(table string) (err error) { + sql := fmt.Sprintf("DROP TABLE IF EXISTS %s.%s", s.dbName, table) + _, err = s.db.Exec(sql) + return +} + +// AddSTableField 添加数据库超级表字段 +func (s *TdEngine) AddSTableField(tableName, fieldName string, dataType string, len int) (err error) { + sql := fmt.Sprintf("ALTER STABLE %s.%s ADD COLUMN %s", s.dbName, tableName, s.column(dataType, fieldName, "", len)) + _, err = s.db.Exec(sql) + return +} + +// AddTableField 添加数据库表字段 +func (s *TdEngine) AddTableField(tableName, fieldName string, dataType string, len int) (err error) { + sql := fmt.Sprintf("ALTER TABLE %s.%s ADD COLUMN %s", s.dbName, tableName, s.column(dataType, fieldName, "", len)) + _, err = s.db.Exec(sql) + return +} + +// DelTableField 删除数据库表字段 +func (s *TdEngine) DelTableField(tableName, fieldName string) (err error) { + sql := fmt.Sprintf("ALTER TABLE %s.%s DROP COLUMN %s", s.dbName, tableName, fieldName) + _, err = s.db.Exec(sql) + return +} + +// DelSTableField 删除数据库超级表字段 +func (s *TdEngine) DelSTableField(tableName, fieldName string) (err error) { + sql := fmt.Sprintf("ALTER STABLE %s.%s DROP COLUMN %s", s.dbName, tableName, fieldName) + _, err = s.db.Exec(sql) + return +} + +// ModifyDatabaseField 修改数据库指定字段长度 +func (s *TdEngine) ModifyDatabaseField(tableName, fieldName string, dataType string, len int) (err error) { + sql := fmt.Sprintf("ALTER STABLE %s.%s MODIFY COLUMN %s", s.dbName, tableName, s.column(dataType, fieldName, "", len)) + _, err = s.db.Exec(sql) + if err != nil { + err = errors.New("设置字段长度失败,长度只能增大不能缩小") + } + return +} + +// AddTag 添加标签 +func (s *TdEngine) AddTag(tableName, tagName string, dataType string, len int) (err error) { + sql := fmt.Sprintf("ALTER STABLE %s.%s ADD TAG %s", s.dbName, tableName, s.column(dataType, tagName, "", len)) + _, err = s.db.Exec(sql) + return +} + +// DelTag 删除标签 +func (s *TdEngine) DelTag(tableName, tagName string) (err error) { + sql := fmt.Sprintf("ALTER STABLE %s.%s DROP TAG %s", s.dbName, tableName, tagName) + _, err = s.db.Exec(sql) + return +} + +// ModifyTag 修改标签 +func (s *TdEngine) ModifyTag(tableName, tagName string, dataType string, len int) (err error) { + sql := fmt.Sprintf("ALTER STABLE %s.%s MODIFY TAG %s", s.dbName, tableName, s.column(dataType, tagName, "", len)) + _, err = s.db.Exec(sql) + if err != nil { + err = errors.New("设置标签长度失败,长度只能增大不能缩小") + } + return +} diff --git a/pkg/tool/base.go b/pkg/tool/base.go new file mode 100644 index 0000000000000000000000000000000000000000..af972430b6ed55342ab9c3e64bf89a1667779aff --- /dev/null +++ b/pkg/tool/base.go @@ -0,0 +1,82 @@ +package tool + +import ( + "log" + "reflect" + "regexp" + "strings" +) + +func ToCamelCase(s string) string { + re := regexp.MustCompile(`[_\W]+`) + words := re.Split(s, -1) + for i := range words { + if i != 0 { + words[i] = strings.Title(words[i]) + } + } + return strings.Join(words, "") +} + +func RegexpKey(str string) []string { + // 定义正则表达式 + re := regexp.MustCompile(`\${([^}]+)}`) + matches := re.FindAllStringSubmatch(str, -1) + // 提取匹配项的内容 + var results []string + for _, match := range matches { + if len(match) >= 2 { + results = append(results, match[1]) + } + } + return results +} + +func RegexpGetSql(str string) string { + // 定义正则表达式 + re := regexp.MustCompile(`\${([^}]+)}`) + return re.ReplaceAllString(str, "?") +} + +func GetStructKeys(obj interface{}) []string { + val := reflect.ValueOf(obj) + typ := val.Type() + + keys := make([]string, 0, typ.NumField()) + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + keys = append(keys, field.Name) + } + + return keys +} + +func GetMapKeys(obj map[string]interface{}) []string { + keys := make([]string, 0, len(obj)) + + for key := range obj { + keys = append(keys, key) + } + + return keys +} + +func CheckInterfaceIsArray(data interface{}) (bool, []map[string]interface{}) { + if data == nil { + return false, nil + } + valueType := reflect.TypeOf(data) + // 判断类型是否为数组或切片 + if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Array { + var maps []map[string]interface{} + for _, item := range data.([]interface{}) { + log.Println("item", item) + if m, ok := item.(map[string]interface{}); ok { + maps = append(maps, m) + } + } + return true, maps + } + return false, nil +} diff --git a/pkg/tool/base_test.go b/pkg/tool/base_test.go new file mode 100644 index 0000000000000000000000000000000000000000..36eef82cb3af672155a8d5a456183a7d70068d8e --- /dev/null +++ b/pkg/tool/base_test.go @@ -0,0 +1,8 @@ +package tool + +import "testing" + +func TestToCamelCase(t *testing.T) { + camelCase := ToCamelCase("hello_world") + t.Log(camelCase) +} diff --git a/pkg/tool/conv.go b/pkg/tool/conv.go new file mode 100644 index 0000000000000000000000000000000000000000..4e6ff8aef97c7d9539f23d3e3a100af9979e2eb2 --- /dev/null +++ b/pkg/tool/conv.go @@ -0,0 +1,80 @@ +package tool + +import ( + "encoding/json" + "strings" +) + +// SnakeString snake string, XxYy to xx_yy , XxYY to xx_y_y +func SnakeString(s string) string { + data := make([]byte, 0, len(s)*2) + j := false + num := len(s) + for i := 0; i < num; i++ { + d := s[i] + if i > 0 && d >= 'A' && d <= 'Z' && j { + data = append(data, '_') + } + if d != '_' { + j = true + } + data = append(data, d) + } + return strings.ToLower(string(data)) +} + +// CamelString camel string, xx_yy to XxYy +func CamelString(s string) string { + data := make([]byte, 0, len(s)) + flag, num := true, len(s)-1 + for i := 0; i <= num; i++ { + d := s[i] + if d == '_' { + flag = true + continue + } else if flag { + if d >= 'a' && d <= 'z' { + d = d - 32 + } + flag = false + } + data = append(data, d) + } + return string(data) +} + +func FirstLowCamelString(s string) string { + data := make([]byte, 0, len(s)) + flag, num := true, len(s)-1 + for i := 0; i <= num; i++ { + d := s[i] + if d == '_' { + flag = true + continue + } else if flag { + if d >= 'a' && d <= 'z' { + d = d - 32 + } + flag = false + } + data = append(data, d) + } + if len(data) > 0 && data[0] >= 65 && data[0] <= 90 { + data[0] = data[0] + 32 + } + return string(data) +} + +func MapToStruct(m map[string]interface{}, s interface{}) error { + data, err := json.Marshal(m) + if err != nil { + return err + } + + err = json.Unmarshal(data, s) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/tool/device.go b/pkg/tool/device.go new file mode 100644 index 0000000000000000000000000000000000000000..9c89129eeaf58380d09d79b1c8c0b469c2808b22 --- /dev/null +++ b/pkg/tool/device.go @@ -0,0 +1,62 @@ +package tool + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "github.com/google/uuid" + "pandax/pkg/global" + "strconv" + "strings" +) + +type DeviceAuth struct { + User string `json:"user"` + DeviceId string `json:"device_id"` + DeviceType string `json:"device_type"` + ProductId string `json:"product_id"` + RuleChainId string `json:"rule_chain_id"` + Name string `json:"name"` + Token string `json:"token"` + CreatedAt int64 `json:"created_at"` + ExpiredAt int64 `json:"expired_at"` +} + +func (entity *DeviceAuth) CreateDeviceToken() (err error) { + + return nil +} + +func (entity *DeviceAuth) GetDeviceToken(key string) error { + if err := global.RedisDb.Get(key, entity); err != nil { + return err + } + return nil +} + +func (token *DeviceAuth) MD5ID() string { + buf := bytes.NewBufferString(token.DeviceId) + buf.WriteString(token.DeviceType) + buf.WriteString(strconv.FormatInt(token.CreatedAt, 10)) + access := base64.URLEncoding.EncodeToString([]byte(uuid.NewMD5(uuid.Must(uuid.NewRandom()), buf.Bytes()).String())) + access = strings.TrimRight(access, "=") + return access +} +func (token *DeviceAuth) GetMarshal() string { + marshal, _ := json.Marshal(*token) + return string(marshal) +} + +func (token *DeviceAuth) GetUnMarshal(data []byte) error { + return json.Unmarshal(data, token) +} + +// 序列化 +func (m *DeviceAuth) MarshalBinary() (data []byte, err error) { + return json.Marshal(m) +} + +// 反序列化 +func (m *DeviceAuth) UnmarshalBinary(data []byte) error { + return json.Unmarshal(data, m) +} diff --git a/pkg/tool/excel.go b/pkg/tool/excel.go new file mode 100644 index 0000000000000000000000000000000000000000..1ae8754c9a8382e970403ffd86ab58af2cc40579 --- /dev/null +++ b/pkg/tool/excel.go @@ -0,0 +1,90 @@ +package tool + +import ( + "fmt" + "github.com/xuri/excelize/v2" +) + +// 读取数据表 +func ReadExcel(filename string) ([]string, []map[string]interface{}) { + ret := make([]map[string]interface{}, 0) + f, err := excelize.OpenFile(filename) + if err != nil { + fmt.Println("读取excel文件出错", err.Error()) + return nil, ret + } + sheets := f.GetSheetMap() + sheet1 := sheets[1] + rows, err := f.GetRows(sheet1) + cols := make([]string, 0) + isHead := true + for _, row := range rows { + if isHead { //取得第一行的所有数据---execel表头 + if len(row) == 0 { + continue + } + for _, colCell := range row { + cols = append(cols, colCell) + } + isHead = false + } else { + theRow := map[string]interface{}{} + for j, colCell := range row { + k := cols[j] + theRow[k] = colCell + } + ret = append(ret, theRow) + } + } + return cols, ret +} + +/* +func ReadExcelByFilter(filename string, data entity.DataSetDataReq) ([]string, []map[string]interface{}) { + dataDs := make([]string, 0) + for _, ds := range data.DataDs { + dataDs = append(dataDs, ds.Value) + } + + ret := make([]map[string]interface{}, 0) + f, err := excelize.OpenFile(filename) + if err != nil { + fmt.Println("读取excel文件出错", err.Error()) + return nil, ret + } + sheets := f.GetSheetMap() + sheet1 := sheets[1] + rows, err := f.GetRows(sheet1) + cols := make([]string, 0) + colsIndex := make([]int, 0) + isHead := true + count := 0 + for _, row := range rows { + if data.ShowNumType == "2" { + if count == int(data.ShowNum) { + break + } + } + if isHead { //取得第一行的所有数据---execel表头 + if len(row) == 0 { + continue + } + for i, colCell := range row { + cols = append(cols, colCell) + colsIndex = append(colsIndex, i) + } + isHead = false + } else { + theRow := map[string]interface{}{} + for j, colCell := range row { + k := cols[j] + theRow[k] = colCell + + } + ret = append(ret, theRow) + } + count++ + } + return cols, ret +} +*/ diff --git a/pkg/tool/local.go b/pkg/tool/local.go new file mode 100644 index 0000000000000000000000000000000000000000..a5a000bb40960d6bafb2484b6bfde7582ff18ac0 --- /dev/null +++ b/pkg/tool/local.go @@ -0,0 +1,85 @@ +package tool + +import ( + "crypto/md5" + "encoding/hex" + "errors" + "io" + "mime/multipart" + "os" + "pandax/pkg/global" + "path" + "strings" + "time" +) + +type Local struct { + Path string +} + +//@object: *Local +//@function: UploadFile +//@description: 上传文件 +//@param: file *multipart.FileHeader +//@return: string, string, error + +func (local *Local) UploadFile(file *multipart.FileHeader) (string, string, error) { + // 读取文件后缀 + ext := path.Ext(file.Filename) + // 读取文件名并加密 + name := strings.TrimSuffix(file.Filename, ext) + name = MD5V([]byte(name)) + // 拼接新文件名 + filename := name + "_" + time.Now().Format("20060102150405") + ext + // 尝试创建此路径 + mkdirErr := os.MkdirAll(local.Path, os.ModePerm) + if mkdirErr != nil { + global.Log.Error("function os.MkdirAll() Filed", mkdirErr.Error()) + return "", "", errors.New("function os.MkdirAll() Filed, err:" + mkdirErr.Error()) + } + // 拼接路径和文件名 + p := local.Path + "/" + filename + + f, openError := file.Open() // 读取文件 + if openError != nil { + global.Log.Error("function file.Open() Filed", openError.Error()) + return "", "", errors.New("function file.Open() Filed, err:" + openError.Error()) + } + defer f.Close() // 创建文件 defer 关闭 + + out, createErr := os.Create(p) + if createErr != nil { + global.Log.Error("function os.Create() Filed", createErr.Error()) + return "", "", errors.New("function os.Create() Filed, err:" + createErr.Error()) + } + defer out.Close() // 创建文件 defer 关闭 + + _, copyErr := io.Copy(out, f) // 传输(拷贝)文件 + if copyErr != nil { + global.Log.Error("function io.Copy() Filed", copyErr.Error()) + return "", "", errors.New("function io.Copy() Filed, err:" + copyErr.Error()) + } + return p, filename, nil +} + +//@object: *Local +//@function: DeleteFile +//@description: 删除文件 +//@param: key string +//@return: error + +func (local *Local) DeleteFile(key string) error { + p := local.Path + "/" + key + if strings.Contains(p, local.Path) { + if err := os.Remove(p); err != nil { + return errors.New("本地文件删除失败, err:" + err.Error()) + } + } + return nil +} + +func MD5V(str []byte) string { + h := md5.New() + h.Write(str) + return hex.EncodeToString(h.Sum(nil)) +} diff --git a/pkg/transport/http_server.go b/pkg/transport/http_server.go index c1f701ec13af652687482528a34a918fc866e338..ab08496f00986f10991bfe407595963121ca2e3a 100644 --- a/pkg/transport/http_server.go +++ b/pkg/transport/http_server.go @@ -37,9 +37,10 @@ func (s *HttpServer) Type() Type { func (s *HttpServer) Start(ctx context.Context) error { global.Log.Infof("HTTP Server listen: %s", s.Addr) go func() { - if err := s.srv.ListenAndServe(); err != nil { + s.srv.ListenAndServe() + /*if err := s.srv.ListenAndServe(); err != nil { global.Log.Errorf("error http serve: %s", err) - } + }*/ }() return nil } diff --git a/pkg/websocket/socket_server.go b/pkg/websocket/socket_server.go new file mode 100644 index 0000000000000000000000000000000000000000..53429703ff74fc0f66fd9182fe823728e958af93 --- /dev/null +++ b/pkg/websocket/socket_server.go @@ -0,0 +1,94 @@ +package websocket + +import ( + "encoding/json" + "fmt" + "github.com/gorilla/websocket" + "net/http" + "pandax/apps/device/entity" + "pandax/pkg/global" + "pandax/pkg/mqtt" + "strings" +) + +var upGrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + CheckOrigin: func(r *http.Request) bool { + return true + }, +} + +type Websocket struct { + Conn *websocket.Conn +} + +func NewWebsocket(writer http.ResponseWriter, r *http.Request, header http.Header) (*Websocket, error) { + ws, err := upGrader.Upgrade(writer, r, header) + if err != nil { + return nil, err + } + ws.SetCloseHandler(func(code int, text string) error { + global.Log.Info(fmt.Sprintf("websocket 连接关闭,code: %d, text: %s", code, text)) + return ws.Close() + }) + + webs := &Websocket{Conn: ws} + return webs, nil +} + +// OnMessage 消息 +// 发送消息消息类型 01:发送的设备数据 02:收到指令回复 03: 心跳回复 +func OnMessage(ws *Websocket, message string) { + if message != "" && strings.Index(message, "ONLINE") != -1 { + screenId := strings.Split(message, "ONLINE")[0] + AddWebSocketByScreenId(screenId, ws) + } + //画布离开 + if message != "" && strings.Index(message, "LEAVE") != -1 { + RemoveWebSocket(strings.Split(message, "LEAVE")[0]) + } + //客户端传来了控制命令 格式 场景控制代码CONTROLCMD控制命令CONTROLCMD传感器id + if message != "" && strings.Index(message, "CONTROLCMD") != -1 { + split := strings.Split(message, "CONTROLCMD") + if len(split) < 2 { + return + } + screenId, controlCMD := split[0], split[1] + + vtsa := new(entity.VisualTwinSendAttrs) + //1. 获取设备孪生 + err := json.Unmarshal([]byte(controlCMD), vtsa) + if err != nil { + global.Log.Error("设备参数下发,孪生体参数解析失败", err) + sendMessages("02", "下发失败", screenId) + return + } + //2. 根据设备下发属性更改 + //topic := fmt.Sprintf(global.AttributesTopic, vtsa.TwinId) + content, _ := json.Marshal(vtsa.Attrs) + var rpc = &mqtt.RpcRequest{Client: global.MqttClient, Mode: "single"} + rpc.GetRequestId() + err = rpc.RequestAttributes(mqtt.RpcPayload{Params: string(content)}) + if err != nil { + global.Log.Error("属性下发失败", err) + sendMessages("02", "下发失败", screenId) + return + } + sendMessages("02", "命令发送成功", screenId) + } + //心跳处理 + if message != "" && strings.Index(message, "HEARTCMD") != -1 { + split := strings.Split(message, "HEARTCMD") + if len(split) < 1 { + return + } + screenId := split[0] + sendMessages("03", "心跳正常", screenId) + } + +} +func sendMessages(messageType, messageContent, screenId string) { + msg := fmt.Sprintf(`{"MESSAGETYPE":"%s","MESSAGECONTENT": "%s"}`, messageType, messageContent) + SendMessage(msg, screenId) +} diff --git a/pkg/websocket/socket_server_pool.go b/pkg/websocket/socket_server_pool.go new file mode 100644 index 0000000000000000000000000000000000000000..bd1145b406185ed2fc925b3896f2f03779c8de45 --- /dev/null +++ b/pkg/websocket/socket_server_pool.go @@ -0,0 +1,37 @@ +package websocket + +import ( + "github.com/gorilla/websocket" + "pandax/pkg/global" +) + +var Wsp = make(map[string]*Websocket) + +// GetWebSocketByScreenId 获取WebSocket +func GetWebSocketByScreenId(screenId string) *Websocket { + return Wsp[screenId] +} + +// AddWebSocketByScreenId 添加WebSocket +func AddWebSocketByScreenId(screenId string, webs *Websocket) { + Wsp[screenId] = webs +} + +// RemoveWebSocket 移除WebSocket +func RemoveWebSocket(screenId string) bool { + if ws, ok := Wsp[screenId]; ok { + ws.Conn.Close() + delete(Wsp, screenId) + global.Log.Info("已经断开websocket:" + screenId) + return true + } + return false +} + +// SendMessage 向特定场景id发送消息,同一场景代码有可能在多台客户机上连接 ,这时就会在多台客户机接受到了数据 +func SendMessage(message, screenId string) { + ws := GetWebSocketByScreenId(screenId) + if ws != nil { + ws.Conn.WriteMessage(websocket.TextMessage, []byte(message)) + } +} diff --git a/resource/pandax-mysql.sql b/resource/pandax-mysql.sql deleted file mode 100644 index 415445939e852a4971a28f9faf0e1cf737f28bab..0000000000000000000000000000000000000000 --- a/resource/pandax-mysql.sql +++ /dev/null @@ -1,1285 +0,0 @@ -/* - Navicat Premium Data Transfer - - Source Server : pandax - Source Server Type : MySQL - Source Server Version : 50562 - - Target Server Type : MySQL - Target Server Version : 50562 - File Encoding : 65001 - - Date: 23/07/2022 10:27:43 -*/ - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - --- ---------------------------- --- Table structure for casbin_rule --- ---------------------------- -DROP TABLE IF EXISTS `casbin_rule`; -CREATE TABLE `casbin_rule` ( - `ptype` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `v0` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `v1` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `v2` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `v3` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `v4` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `v5` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`) USING BTREE, - UNIQUE INDEX `idx_casbin_rule`(`ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2315 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of casbin_rule --- ---------------------------- -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/gen/code/:tableId', 'GET', '', '', 2190); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/gen/configure/:tableId', 'GET', '', '', 2191); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/gen/preview/:tableId', 'GET', '', '', 2189); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table', 'POST', '', '', 2186); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table', 'PUT', '', '', 2187); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table/:tableId', 'DELETE', '', '', 2188); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table/db/list', 'GET', '', '', 2181); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table/info/:tableId', 'GET', '', '', 2183); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table/info/tableName', 'GET', '', '', 2184); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table/list', 'GET', '', '', 2182); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/develop/code/table/tableTree', 'GET', '', '', 2185); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job', 'POST', '', '', 2193); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job', 'PUT', '', '', 2194); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job/:jobId', 'DELETE', '', '', 2196); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job/:jobId', 'GET', '', '', 2195); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job/changeStatus', 'PUT', '', '', 2199); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job/list', 'GET', '', '', 2192); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job/start/:jobId', 'GET', '', '', 2198); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/job/stop/:jobId', 'GET', '', '', 2197); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logJob/:logId', 'DELETE', '', '', 2208); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logJob/all', 'DELETE', '', '', 2207); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logJob/list', 'GET', '', '', 2206); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logLogin/:infoId', 'DELETE', '', '', 2201); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logLogin/all', 'DELETE', '', '', 2202); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logLogin/list', 'GET', '', '', 2200); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logOper/:operId', 'DELETE', '', '', 2204); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logOper/all', 'DELETE', '', '', 2205); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/log/logOper/list', 'GET', '', '', 2203); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email', 'POST', '', '', 2211); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email', 'PUT', '', '', 2212); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email/:mailId', 'DELETE', '', '', 2213); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email/:mailId', 'GET', '', '', 2210); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email/changeStatus', 'PUT', '', '', 2214); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email/debugMail', 'POST', '', '', 2215); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/email/list', 'GET', '', '', 2209); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss', 'POST', '', '', 2231); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss', 'PUT', '', '', 2232); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss/:ossId', 'DELETE', '', '', 2233); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss/:ossId', 'GET', '', '', 2230); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss/changeStatus', 'PUT', '', '', 2234); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss/list', 'GET', '', '', 2229); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/resource/oss/uploadFile', 'POST', '', '', 2235); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api', 'POST', '', '', 2153); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api', 'PUT', '', '', 2154); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api/:id', 'DELETE', '', '', 2155); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api/:id', 'GET', '', '', 2152); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api/all', 'GET', '', '', 2150); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api/getPolicyPathByRoleId', 'GET', '', '', 2151); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/api/list', 'GET', '', '', 2149); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/config', 'POST', '', '', 2159); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/config', 'PUT', '', '', 2160); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/config/:configId', 'DELETE', '', '', 2161); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/config/:configId', 'GET', '', '', 2158); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/config/configKey', 'GET', '', '', 2157); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/config/list', 'GET', '', '', 2156); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept', 'POST', '', '', 2166); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept', 'PUT', '', '', 2167); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept/:deptId', 'DELETE', '', '', 2168); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept/:deptId', 'GET', '', '', 2163); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept/deptTree', 'GET', '', '', 2165); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept/list', 'GET', '', '', 2162); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dept/roleDeptTreeSelect/:roleId', 'GET', '', '', 2164); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/data', 'POST', '', '', 2178); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/data', 'PUT', '', '', 2179); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/data/:dictCode', 'DELETE', '', '', 2180); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/data/:dictCode', 'GET', '', '', 2177); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/data/list', 'GET', '', '', 2175); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/data/type', 'GET', '', '', 2176); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/type', 'POST', '', '', 2171); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/type', 'PUT', '', '', 2172); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/type/:dictId', 'DELETE', '', '', 2173); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/type/:dictId', 'GET', '', '', 2170); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/type/export', 'GET', '', '', 2174); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/dict/type/list', 'GET', '', '', 2169); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu', 'POST', '', '', 2222); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu', 'PUT', '', '', 2223); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/:menuId', 'DELETE', '', '', 2224); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/:menuId', 'GET', '', '', 2221); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/list', 'GET', '', '', 2220); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/menuPaths', 'GET', '', '', 2219); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/menuRole', 'GET', '', '', 2217); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/menuTreeSelect', 'GET', '', '', 2216); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/menu/roleMenuTreeSelect/:roleId', 'GET', '', '', 2218); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/notice', 'POST', '', '', 2226); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/notice', 'PUT', '', '', 2227); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/notice/:noticeId', 'DELETE', '', '', 2228); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/notice/list', 'GET', '', '', 2225); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/post', 'POST', '', '', 2238); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/post', 'PUT', '', '', 2239); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/post/:postId', 'DELETE', '', '', 2240); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/post/:postId', 'GET', '', '', 2237); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/post/list', 'GET', '', '', 2236); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role', 'POST', '', '', 2243); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role', 'PUT', '', '', 2244); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role/:roleId', 'DELETE', '', '', 2245); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role/:roleId', 'GET', '', '', 2242); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role/changeStatus', 'PUT', '', '', 2246); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role/dataScope', 'PUT', '', '', 2247); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role/export', 'GET', '', '', 2248); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/role/list', 'GET', '', '', 2241); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/tenant', 'POST', '', '', 2251); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/tenant', 'PUT', '', '', 2252); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/tenant/:tenantId', 'DELETE', '', '', 2253); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/tenant/:tenantId', 'GET', '', '', 2250); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/tenant/list', 'GET', '', '', 2249); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/tenant/lists', 'GET', '', '', 2254); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user', 'POST', '', '', 2263); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user', 'PUT', '', '', 2264); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/:userId', 'DELETE', '', '', 2257); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/avatar', 'POST', '', '', 2258); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/changeStatus', 'PUT', '', '', 2256); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/export', 'GET', '', '', 2265); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/getById/:userId', 'GET', '', '', 2260); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/getInit', 'GET', '', '', 2261); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/getRoPo', 'GET', '', '', 2262); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/list', 'GET', '', '', 2255); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'admin', '/system/user/pwd', 'PUT', '', '', 2259); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/develop/code/gen/preview/:tableId', 'GET', '', '', 2287); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/develop/code/table/db/list', 'GET', '', '', 2282); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/develop/code/table/info/:tableId', 'GET', '', '', 2284); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/develop/code/table/info/tableName', 'GET', '', '', 2285); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/develop/code/table/list', 'GET', '', '', 2283); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/develop/code/table/tableTree', 'GET', '', '', 2286); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/job/:jobId', 'GET', '', '', 2289); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/job/list', 'GET', '', '', 2288); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/log/logJob/list', 'GET', '', '', 2292); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/log/logLogin/list', 'GET', '', '', 2290); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/log/logOper/list', 'GET', '', '', 2291); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/resource/email/:mailId', 'GET', '', '', 2294); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/resource/email/list', 'GET', '', '', 2293); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/resource/oss/:ossId', 'GET', '', '', 2303); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/resource/oss/list', 'GET', '', '', 2302); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/api/:id', 'GET', '', '', 2269); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/api/all', 'GET', '', '', 2267); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/api/getPolicyPathByRoleId', 'GET', '', '', 2268); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/api/list', 'GET', '', '', 2266); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/config/:configId', 'GET', '', '', 2272); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/config/configKey', 'GET', '', '', 2271); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/config/list', 'GET', '', '', 2270); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dept/:deptId', 'GET', '', '', 2274); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dept/deptTree', 'GET', '', '', 2276); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dept/list', 'GET', '', '', 2273); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dept/roleDeptTreeSelect/:roleId', 'GET', '', '', 2275); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dict/data/:dictCode', 'GET', '', '', 2281); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dict/data/list', 'GET', '', '', 2279); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dict/data/type', 'GET', '', '', 2280); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dict/type/:dictId', 'GET', '', '', 2278); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/dict/type/list', 'GET', '', '', 2277); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/menu/:menuId', 'GET', '', '', 2300); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/menu/list', 'GET', '', '', 2299); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/menu/menuPaths', 'GET', '', '', 2298); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/menu/menuRole', 'GET', '', '', 2296); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/menu/menuTreeSelect', 'GET', '', '', 2295); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/menu/roleMenuTreeSelect/:roleId', 'GET', '', '', 2297); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/notice/list', 'GET', '', '', 2301); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/post/:postId', 'GET', '', '', 2305); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/post/list', 'GET', '', '', 2304); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/role/:roleId', 'GET', '', '', 2307); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/role/list', 'GET', '', '', 2306); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/tenant/:tenantId', 'GET', '', '', 2309); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/tenant/list', 'GET', '', '', 2308); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/tenant/lists', 'GET', '', '', 2310); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/user/getById/:userId', 'GET', '', '', 2312); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/user/getInit', 'GET', '', '', 2313); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/user/getRoPo', 'GET', '', '', 2314); -INSERT INTO `casbin_rule` VALUES ('p', '1', 'manage', '/system/user/list', 'GET', '', '', 2311); - --- ---------------------------- --- Table structure for dev_gen_table_columns --- ---------------------------- -DROP TABLE IF EXISTS `dev_gen_table_columns`; -CREATE TABLE `dev_gen_table_columns` ( - `column_id` bigint(20) NOT NULL AUTO_INCREMENT, - `table_id` bigint(20) NULL DEFAULT NULL, - `table_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `column_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `column_comment` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `column_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `column_key` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `go_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `go_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `json_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `html_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_pk` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_increment` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_required` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_insert` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_edit` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_list` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_query` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `query_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `html_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `dict_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `sort` bigint(20) NULL DEFAULT NULL, - `link_table_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `link_table_class` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `link_table_package` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `link_label_id` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `link_label_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - PRIMARY KEY (`column_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 89 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of dev_gen_table_columns --- ---------------------------- -INSERT INTO `dev_gen_table_columns` VALUES (1, 1, '', 'log_id', '', 'bigint(20)', '', 'int64', 'LogId', 'logId', '', '1', '', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (2, 1, '', 'name', '任务名称', 'varchar(128)', '', 'string', 'Name', 'name', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 2, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (3, 1, '', 'job_group', '分组', 'varchar(128)', '', 'string', 'JobGroup', 'jobGroup', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (4, 1, '', 'entry_id', '任务id', 'int(11)', '', 'int', 'EntryId', 'entryId', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (5, 1, '', 'invoke_target', '调用方法', 'varchar(128)', '', 'string', 'InvokeTarget', 'invokeTarget', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (6, 1, '', 'log_info', '日志信息', 'varchar(255)', '', 'string', 'LogInfo', 'logInfo', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (7, 1, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (8, 1, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 8, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (9, 1, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (10, 1, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 10, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (27, 3, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 13, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (28, 4, '', 'config_value', 'ConfigValue', 'varchar(255)', '', 'string', 'ConfigValue', 'configValue', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (29, 3, '', 'business_type', '0其它 1新增 2修改 3删除', 'varchar(1)', '', 'string', 'BusinessType', 'businessType', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'select', '', 3, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (30, 4, '', 'config_type', '是否系统内置0,1', 'varchar(64)', '', 'string', 'ConfigType', 'configType', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'select', '', 5, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (31, 3, '', 'method', '请求方法', 'varchar(255)', '', 'string', 'Method', 'method', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (32, 4, '', 'is_frontend', '是否前台', 'varchar(1)', '', 'string', 'IsFrontend', 'isFrontend', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (33, 3, '', 'oper_name', '操作人员', 'varchar(255)', '', 'string', 'OperName', 'operName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 5, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (34, 4, '', 'remark', 'Remark', 'varchar(128)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (35, 3, '', 'oper_url', '操作url', 'varchar(255)', '', 'string', 'OperUrl', 'operUrl', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (36, 4, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 8, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (37, 3, '', 'oper_ip', '操作IP', 'varchar(255)', '', 'string', 'OperIp', 'operIp', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (38, 4, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (39, 3, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 11, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (40, 3, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (41, 3, '', 'status', '0=正常,1=异常', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 10, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (42, 3, '', 'oper_id', '', 'bigint(20)', '', 'int64', 'OperId', 'operId', '', '1', '', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (43, 5, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 14, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (44, 5, '', 'category', '', 'varchar(191)', '', 'string', 'Category', 'category', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (45, 5, '', 'app_id', 'AppId', 'varchar(128)', '', 'string', 'AppId', 'appId', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (46, 5, '', 'access_key', 'accessKey', 'varchar(128)', '', 'string', 'AccessKey', 'accessKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (47, 5, '', 'secret_key', 'secretKey', 'varchar(128)', '', 'string', 'SecretKey', 'secretKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (48, 5, '', 'bucket_name', 'bucketName', 'varchar(128)', '', 'string', 'BucketName', 'bucketName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (49, 5, '', 'endpoint', 'endpoint', 'varchar(128)', '', 'string', 'Endpoint', 'endpoint', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (50, 5, '', 'oss_code', 'ossCode', 'varchar(128)', '', 'string', 'OssCode', 'ossCode', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (51, 5, '', 'region', '地址', 'varchar(128)', '', 'string', 'Region', 'region', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (52, 5, '', 'remark', '说明', 'varchar(128)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 10, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (53, 5, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 13, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (54, 5, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 11, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (55, 5, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (56, 5, '', 'oss_id', '主键编码', 'bigint(20)', '', 'int64', 'OssId', 'ossId', '', '1', '1', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (57, 6, '', 'app_id', 'AppId', 'varchar(128)', '', 'string', 'AppId', 'appId', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (58, 6, '', 'category', '', 'varchar(191)', '', 'string', 'Category', 'category', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (59, 6, '', 'endpoint', 'endpoint', 'varchar(128)', '', 'string', 'Endpoint', 'endpoint', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (60, 6, '', 'access_key', 'accessKey', 'varchar(128)', '', 'string', 'AccessKey', 'accessKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (61, 6, '', 'secret_key', 'secretKey', 'varchar(128)', '', 'string', 'SecretKey', 'secretKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (62, 6, '', 'bucket_name', 'bucketName', 'varchar(128)', '', 'string', 'BucketName', 'bucketName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (63, 6, '', 'remark', '说明', 'varchar(128)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 10, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (64, 6, '', 'oss_code', 'ossCode', 'varchar(128)', '', 'string', 'OssCode', 'ossCode', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (65, 6, '', 'region', '地址', 'varchar(128)', '', 'string', 'Region', 'region', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (66, 6, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (67, 6, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 14, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (68, 6, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 11, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (69, 6, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 13, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (70, 6, '', 'oss_id', '主键编码', 'bigint(20)', '', 'int64', 'OssId', 'ossId', '', '1', '1', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (71, 7, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 10, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (72, 7, '', 'host', '主机', 'varchar(191)', '', 'string', 'Host', 'host', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (73, 7, '', 'secret', '密码', 'varchar(191)', '', 'string', 'Secret', 'secret', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (74, 7, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (75, 7, '', 'from', '发件人', 'varchar(191)', '', 'string', 'From', 'from', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (76, 7, '', 'is_ssl', '开启ssl', 'tinyint(1)', '', 'int', 'IsSsl', 'isSsl', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (77, 7, '', 'mail_id', '主键编码', 'bigint(20)', 'Json', 'int64', 'MailId', 'mailId', '', '1', '1', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (82, 9, '', 'expire_time', '过期时间', 'datetime', '', 'Time', 'ExpireTime', 'expireTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 7, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (83, 9, '', 'delete_time', 'DeleteTime', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 3, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (84, 9, '', 'create_time', 'CreateTime', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '0', '0', '1', '0', 'EQ', 'datetime', '', 1, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (85, 9, '', 'update_time', 'UpdateTime', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 2, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (86, 9, '', 'tenant_name', '租户名', 'varchar(255)', '', 'string', 'TenantName', 'tenantName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 5, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (87, 9, '', 'remark', '备注', 'varchar(255)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 6, '', '', '', '', ''); -INSERT INTO `dev_gen_table_columns` VALUES (88, 9, '', 'id', 'Id', 'bigint(20)', '', 'int64', 'Id', 'id', '', '1', '1', '0', '0', '0', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); - --- ---------------------------- --- Table structure for dev_gen_tables --- ---------------------------- -DROP TABLE IF EXISTS `dev_gen_tables`; -CREATE TABLE `dev_gen_tables` ( - `table_id` bigint(20) NOT NULL AUTO_INCREMENT, - `table_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `table_comment` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `class_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `tpl_category` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `package_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `module_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `business_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `function_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `function_author` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `options` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `remark` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `pk_column` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `pk_go_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `pk_json_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`table_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of dev_gen_tables --- ---------------------------- -INSERT INTO `dev_gen_tables` VALUES (1, 'log_jobs', 'LogJobs', 'LogJobs', 'crud', 'admin', 'log-jobs', 'logJobs', 'LogJobs', 'panda', '', '', 'log_id', 'LogId', 'logId', '2022-01-06 14:44:14', '2022-01-06 14:44:14', '2022-01-10 11:58:43'); -INSERT INTO `dev_gen_tables` VALUES (2, 'log_logins', 'LogLogins', 'LogLogins', 'crud', 'log', 'log-logins', 'logLogins', 'logLogins', 'pandax', '', '', 'info_id', 'InfoId', 'infoId', '2022-01-06 14:44:27', '2022-01-26 14:45:46', '2022-07-16 18:24:04'); -INSERT INTO `dev_gen_tables` VALUES (3, 'log_opers', 'LogOpers', 'LogOpers', 'crud', 'admin', 'log-opers', 'logOpers', 'LogOpers', 'panda', '', '', 'oper_id', 'OperId', 'operId', '2022-01-06 15:02:45', '2022-01-06 15:02:45', NULL); -INSERT INTO `dev_gen_tables` VALUES (4, 'sys_configs', 'SysConfigs', 'SysConfigs', 'crud', 'admin', 'sys-configs', 'sysConfigs', 'SysConfigs', 'panda', '', '', 'config_id', 'ConfigId', 'configId', '2022-01-06 15:02:45', '2022-01-06 15:02:45', '2022-01-12 15:56:49'); -INSERT INTO `dev_gen_tables` VALUES (5, 'res_osses', 'ResOsses', 'ResOsses', 'crud', 'resource', 'res-osses', 'oss', 'ResOsses', 'panda', '', '', 'oss_id', 'OssId', 'ossId', '2022-01-13 15:12:14', '2022-01-13 15:39:11', NULL); -INSERT INTO `dev_gen_tables` VALUES (6, 'res_osses', 'ResOsses', 'ResOsses', 'crud', 'admin', 'res-osses', 'resOsses', 'ResOsses', 'panda', '', '', 'oss_id', 'OssId', 'ossId', '2022-01-13 15:12:27', '2022-01-13 15:12:27', '2022-01-13 15:12:41'); -INSERT INTO `dev_gen_tables` VALUES (7, 'res_emails', 'ResEmails', 'ResEmails', 'crud', 'resource', 'res-emails', 'email', 'ResEmails', 'panda', '', '', 'mail_id', 'MailId', 'mailId', '2022-01-14 15:20:27', '2022-01-26 15:56:37', NULL); -INSERT INTO `dev_gen_tables` VALUES (8, 'sys_tenants', '租户', 'SysTenants', 'crud', 'system', 'sys-tenants', 'tenant', 'Tenant', 'panda', '', '', 'tenant_id', 'TenantId', 'tenantId', '2022-07-14 16:52:28', '2022-07-16 16:09:50', '2022-07-16 18:09:40'); -INSERT INTO `dev_gen_tables` VALUES (9, 'sys_tenants', '租户', 'SysTenants', 'crud', 'system', 'sys-tenants', 'tenants', 'Tenants', 'panda', '', '', 'id', 'Id', 'id', '2022-07-16 18:14:53', '2022-07-16 22:45:33', NULL); - --- ---------------------------- --- Table structure for log_jobs --- ---------------------------- -DROP TABLE IF EXISTS `log_jobs`; -CREATE TABLE `log_jobs` ( - `log_id` bigint(20) NOT NULL AUTO_INCREMENT, - `name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务名称', - `job_group` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '分组', - `entry_id` int(11) NULL DEFAULT NULL COMMENT '任务id', - `invoke_target` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '调用方法', - `log_info` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '日志信息', - `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`log_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of log_jobs --- ---------------------------- - --- ---------------------------- --- Table structure for log_logins --- ---------------------------- -DROP TABLE IF EXISTS `log_logins`; -CREATE TABLE `log_logins` ( - `info_id` bigint(20) NOT NULL AUTO_INCREMENT, - `username` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名', - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', - `ipaddr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ip地址', - `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '归属地', - `browser` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '浏览器', - `os` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '系统', - `platform` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '固件', - `login_time` timestamp NULL DEFAULT NULL COMMENT '登录时间', - `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', - `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者', - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`info_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3481 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of log_logins --- ---------------------------- - --- ---------------------------- --- Table structure for log_opers --- ---------------------------- -DROP TABLE IF EXISTS `log_opers`; -CREATE TABLE `log_opers` ( - `oper_id` bigint(20) NOT NULL AUTO_INCREMENT, - `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作的模块', - `business_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '0其它 1新增 2修改 3删除', - `method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法', - `oper_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作人员', - `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作url', - `oper_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作IP', - `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作地点', - `oper_param` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求参数', - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '0=正常,1=异常', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`oper_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 928 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of log_opers --- ---------------------------- -INSERT INTO `log_opers` VALUES (912, '清空操作日志信息', '3', 'DELETE', 'panda', '/log/logOper/all', '127.0.0.1', '内部IP', '', '0', '2022-07-18 11:36:32', '2022-07-18 11:36:32', NULL); -INSERT INTO `log_opers` VALUES (913, '清空登录日志信息', '3', 'DELETE', 'panda', '/log/logLogin/all', '127.0.0.1', '内部IP', '', '0', '2022-07-18 11:37:43', '2022-07-18 11:37:43', NULL); -INSERT INTO `log_opers` VALUES (914, '修改角色信息', '2', 'PUT', 'panda', '/system/role', '222.175.246.74', 'ɽ��ʡ�Ͳ��� ����', '', '0', '2022-07-19 14:03:34', '2022-07-19 14:03:34', NULL); -INSERT INTO `log_opers` VALUES (915, '修改状态', '2', 'PUT', 'admin', '/job/changeStatus', '121.69.84.210', '������ ����ͨ', '', '0', '2022-07-19 15:07:09', '2022-07-19 15:07:09', NULL); -INSERT INTO `log_opers` VALUES (916, '添加通知信息', '1', 'POST', 'admin', '/system/notice', '182.116.65.22', '����ʡ������ ��ͨ', '', '0', '2022-07-19 17:06:20', '2022-07-19 17:06:20', NULL); -INSERT INTO `log_opers` VALUES (917, '修改状态', '2', 'PUT', 'admin', '/job/changeStatus', '121.69.84.210', '������ ����ͨ', '', '0', '2022-07-19 18:04:42', '2022-07-19 18:04:42', NULL); -INSERT INTO `log_opers` VALUES (918, '修改SysTenant信息', '2', 'PUT', 'admin', '/system/tenant', '114.102.130.30', '����ʡ�Ϸ��� ����', '', '0', '2022-07-19 18:45:18', '2022-07-19 18:45:18', NULL); -INSERT INTO `log_opers` VALUES (919, '修改状态', '2', 'PUT', 'admin', '/resource/oss/changeStatus', '180.167.217.166', '�Ϻ��� ����', '', '0', '2022-07-20 00:03:56', '2022-07-20 00:03:56', NULL); -INSERT INTO `log_opers` VALUES (920, '添加SysTenant信息', '1', 'POST', 'admin', '/system/tenant', '119.131.144.47', '�㶫ʡ������ ����', '', '0', '2022-07-20 09:59:02', '2022-07-20 09:59:02', NULL); -INSERT INTO `log_opers` VALUES (921, '修改角色信息', '2', 'PUT', 'admin', '/system/role', '222.129.41.224', '������ ��ͨADSL', '', '0', '2022-07-20 16:39:14', '2022-07-20 16:39:14', NULL); -INSERT INTO `log_opers` VALUES (922, '添加用户信息', '1', 'POST', 'admin', '/system/user', '120.235.110.204', '�㶫ʡ������ �ƶ�', '', '0', '2022-07-21 00:20:54', '2022-07-21 00:20:54', NULL); -INSERT INTO `log_opers` VALUES (923, '修改用户状态', '2', 'PUT', 'admin', '/system/user/changeStatus', '120.235.110.204', '�㶫ʡ������ �ƶ�', '', '0', '2022-07-21 00:21:05', '2022-07-21 00:21:05', NULL); -INSERT INTO `log_opers` VALUES (924, '修改用户状态', '2', 'PUT', 'admin', '/system/user/changeStatus', '120.235.110.204', '�㶫ʡ������ �ƶ�', '', '0', '2022-07-21 00:21:07', '2022-07-21 00:21:07', NULL); -INSERT INTO `log_opers` VALUES (925, '修改用户状态', '2', 'PUT', 'admin', '/system/user/changeStatus', '120.235.110.204', '�㶫ʡ������ �ƶ�', '', '0', '2022-07-21 00:21:07', '2022-07-21 00:21:07', NULL); -INSERT INTO `log_opers` VALUES (926, '添加用户信息', '1', 'POST', 'admin', '/system/user', '103.239.206.29', '�㶫ʡ������ BGP', '', '0', '2022-07-21 13:51:57', '2022-07-21 13:51:57', NULL); -INSERT INTO `log_opers` VALUES (927, '新增表', '1', 'POST', 'admin', '/develop/code/table', '159.138.32.243', '���� ��Ϊ��˾', '', '0', '2022-07-22 11:13:38', '2022-07-22 11:13:38', NULL); - --- ---------------------------- --- Table structure for res_emails --- ---------------------------- -DROP TABLE IF EXISTS `res_emails`; -CREATE TABLE `res_emails` ( - `mail_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键编码', - `category` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `host` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `port` bigint(20) NULL DEFAULT NULL, - `from` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `nickname` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `secret` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `is_ssl` tinyint(1) NULL DEFAULT NULL, - `status` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`mail_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of res_emails --- ---------------------------- -INSERT INTO `res_emails` VALUES (1, '0', 'smtp.163.com', 25, '18610165312@163.com', '熊猫', 'DCXZCAGTCMSEGPZL', 0, '0', '2022-01-14 16:14:37', '2022-01-17 10:27:57', NULL); - --- ---------------------------- --- Table structure for res_osses --- ---------------------------- -DROP TABLE IF EXISTS `res_osses`; -CREATE TABLE `res_osses` ( - `oss_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键编码', - `category` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `app_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'AppId', - `access_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'accessKey', - `secret_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'secretKey', - `bucket_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'bucketName', - `endpoint` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'endpoint', - `oss_code` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ossCode', - `region` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址', - `remark` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '说明', - `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`oss_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of res_osses --- ---------------------------- - --- ---------------------------- --- Table structure for sys_apis --- ---------------------------- -DROP TABLE IF EXISTS `sys_apis`; -CREATE TABLE `sys_apis` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - `path` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api路径', - `description` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api中文描述', - `api_group` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api组', - `method` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '方法', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 124 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_apis --- ---------------------------- -INSERT INTO `sys_apis` VALUES (1, '2021-12-09 09:21:04', '2021-12-09 09:21:04', NULL, '/system/user/list', '查询用户列表(分页)', 'user', 'GET'); -INSERT INTO `sys_apis` VALUES (2, '2021-12-09 09:29:36', '2021-12-09 09:29:36', NULL, '/system/user/changeStatus', '修改用户状态', 'user', 'PUT'); -INSERT INTO `sys_apis` VALUES (3, '2021-12-09 09:34:37', '2021-12-09 09:34:37', NULL, '/system/user/:userId', '删除用户信息', 'user', 'DELETE'); -INSERT INTO `sys_apis` VALUES (4, '2021-12-09 09:36:43', '2021-12-09 09:36:43', NULL, '/system/dept/list', '获取部门列表', 'dept', 'GET'); -INSERT INTO `sys_apis` VALUES (5, '2021-12-09 09:37:31', '2021-12-09 09:37:31', NULL, '/system/dept/:deptId', '获取部门信息', 'dept', 'GET'); -INSERT INTO `sys_apis` VALUES (6, '2021-12-09 18:20:32', '2021-12-09 18:20:32', NULL, '/system/user/avatar', '上传头像', 'user', 'POST'); -INSERT INTO `sys_apis` VALUES (7, '2021-12-09 18:21:10', '2021-12-09 18:21:10', NULL, '/system/user/pwd', '修改密码', 'user', 'PUT'); -INSERT INTO `sys_apis` VALUES (8, '2021-12-09 18:21:54', '2021-12-09 18:21:54', NULL, '/system/user/getById/:userId', '通过id获取用户信息', 'user', 'GET'); -INSERT INTO `sys_apis` VALUES (9, '2021-12-09 18:58:50', '2021-12-09 18:58:50', NULL, '/system/user/getInit', '获取初始化角色岗位信息(添加用户初始化)', 'user', 'GET'); -INSERT INTO `sys_apis` VALUES (10, '2021-12-09 18:59:43', '2021-12-09 18:59:43', NULL, '/system/user/getRoPo', '获取用户角色岗位信息', 'user', 'GET'); -INSERT INTO `sys_apis` VALUES (11, '2021-12-09 19:00:24', '2021-12-09 19:00:24', NULL, '/system/user', '添加用户信息', 'user', 'POST'); -INSERT INTO `sys_apis` VALUES (12, '2021-12-09 19:00:52', '2021-12-09 19:00:52', NULL, '/system/user', '修改用户信息', 'user', 'PUT'); -INSERT INTO `sys_apis` VALUES (13, '2021-12-09 19:02:30', '2021-12-09 19:02:30', NULL, '/system/user/export', '导出用户信息', 'user', 'GET'); -INSERT INTO `sys_apis` VALUES (14, '2021-12-09 19:04:04', '2021-12-09 19:04:04', NULL, '/system/dept/roleDeptTreeSelect/:roleId', '获取角色部门树', 'dept', 'GET'); -INSERT INTO `sys_apis` VALUES (15, '2021-12-09 19:04:48', '2021-12-09 19:04:48', NULL, '/system/dept/deptTree', '获取所有部门树', 'dept', 'GET'); -INSERT INTO `sys_apis` VALUES (16, '2021-12-09 19:07:37', '2021-12-09 19:07:37', NULL, '/system/dept', '添加部门信息', 'dept', 'POST'); -INSERT INTO `sys_apis` VALUES (17, '2021-12-09 19:08:14', '2021-12-09 19:08:14', NULL, '/system/dept', '修改部门信息', 'dept', 'PUT'); -INSERT INTO `sys_apis` VALUES (18, '2021-12-09 19:08:40', '2021-12-09 19:08:40', NULL, '/system/dept/:deptId', '删除部门信息', 'dept', 'DELETE'); -INSERT INTO `sys_apis` VALUES (19, '2021-12-09 19:09:41', '2021-12-09 19:09:41', NULL, '/system/config/list', '获取配置分页列表', 'config', 'GET'); -INSERT INTO `sys_apis` VALUES (20, '2021-12-09 19:10:11', '2021-12-09 19:10:11', NULL, '/system/config/configKey', '获取配置列表通过ConfigKey', 'config', 'GET'); -INSERT INTO `sys_apis` VALUES (21, '2021-12-09 19:10:45', '2021-12-09 19:10:45', NULL, '/system/config/:configId', '获取配置信息', 'config', 'GET'); -INSERT INTO `sys_apis` VALUES (22, '2021-12-09 19:11:22', '2021-12-09 19:11:22', NULL, '/system/config', '添加配置信息', 'config', 'POST'); -INSERT INTO `sys_apis` VALUES (23, '2021-12-09 19:11:41', '2021-12-09 19:11:41', NULL, '/system/config', '修改配置信息', 'config', 'PUT'); -INSERT INTO `sys_apis` VALUES (24, '2021-12-09 19:12:28', '2021-12-09 19:12:28', NULL, '/system/config/:configId', '删除配置信息', 'config', 'DELETE'); -INSERT INTO `sys_apis` VALUES (25, '2021-12-09 19:13:08', '2021-12-09 19:13:08', NULL, '/system/dict/type/list', '获取字典类型分页列表', 'dict', 'GET'); -INSERT INTO `sys_apis` VALUES (26, '2021-12-09 19:13:55', '2021-12-09 19:13:55', NULL, '/system/dict/type/:dictId', '获取字典类型信息', 'dict', 'GET'); -INSERT INTO `sys_apis` VALUES (27, '2021-12-09 19:14:28', '2021-12-09 19:14:28', NULL, '/system/dict/type', '添加字典类型信息', 'dict', 'POST'); -INSERT INTO `sys_apis` VALUES (28, '2021-12-09 19:14:55', '2021-12-09 19:14:55', NULL, '/system/dict/type', '修改字典类型信息', 'dict', 'PUT'); -INSERT INTO `sys_apis` VALUES (29, '2021-12-09 19:15:17', '2021-12-09 19:15:17', NULL, '/system/dict/type/:dictId', '删除字典类型信息', 'dict', 'DELETE'); -INSERT INTO `sys_apis` VALUES (30, '2021-12-09 19:15:50', '2021-12-09 19:15:50', NULL, '/system/dict/type/export', '导出字典类型信息', 'dict', 'GET'); -INSERT INTO `sys_apis` VALUES (31, '2021-12-09 19:16:26', '2021-12-09 19:16:26', NULL, '/system/dict/data/list', '获取字典数据分页列表', 'dict', 'GET'); -INSERT INTO `sys_apis` VALUES (32, '2021-12-09 19:17:01', '2021-12-09 19:17:01', NULL, '/system/dict/data/type', '获取字典数据列表通过字典类型', 'dict', 'GET'); -INSERT INTO `sys_apis` VALUES (33, '2021-12-09 19:17:39', '2021-12-09 19:17:39', NULL, '/system/dict/data/:dictCode', '获取字典数据信息', 'dict', 'GET'); -INSERT INTO `sys_apis` VALUES (34, '2021-12-09 19:18:20', '2021-12-09 19:18:20', NULL, '/system/dict/data', '添加字典数据信息', 'dict', 'POST'); -INSERT INTO `sys_apis` VALUES (35, '2021-12-09 19:18:44', '2021-12-09 19:18:44', NULL, '/system/dict/data', '修改字典数据信息', 'dict', 'PUT'); -INSERT INTO `sys_apis` VALUES (36, '2021-12-09 19:19:16', '2021-12-09 19:19:16', NULL, '/system/dict/data/:dictCode', '删除字典数据信息', 'dict', 'DELETE'); -INSERT INTO `sys_apis` VALUES (37, '2021-12-09 19:21:18', '2021-12-09 19:21:18', NULL, '/system/menu/menuTreeSelect', '获取菜单树', 'menu', 'GET'); -INSERT INTO `sys_apis` VALUES (38, '2021-12-09 19:21:47', '2021-12-09 19:21:47', NULL, '/system/menu/menuRole', '获取角色菜单', 'menu', 'GET'); -INSERT INTO `sys_apis` VALUES (39, '2021-12-09 19:22:42', '2021-12-09 19:22:42', NULL, '/system/menu/roleMenuTreeSelect/:roleId', '获取角色菜单树', 'menu', 'GET'); -INSERT INTO `sys_apis` VALUES (40, '2021-12-09 19:23:17', '2021-12-09 19:23:17', NULL, '/system/menu/menuPaths', '获取角色菜单路径列表', 'menu', 'GET'); -INSERT INTO `sys_apis` VALUES (41, '2021-12-09 19:23:40', '2021-12-09 19:23:40', NULL, '/system/menu/list', '获取菜单列表', 'menu', 'GET'); -INSERT INTO `sys_apis` VALUES (42, '2021-12-09 19:24:09', '2021-12-09 19:24:09', NULL, '/system/menu/:menuId', '获取菜单信息', 'menu', 'GET'); -INSERT INTO `sys_apis` VALUES (43, '2021-12-09 19:24:29', '2021-12-09 19:24:29', NULL, '/system/menu', '添加菜单信息', 'menu', 'POST'); -INSERT INTO `sys_apis` VALUES (44, '2021-12-09 19:24:48', '2021-12-09 19:24:48', NULL, '/system/menu', '修改菜单信息', 'menu', 'PUT'); -INSERT INTO `sys_apis` VALUES (45, '2021-12-09 19:25:10', '2021-12-09 19:25:10', NULL, '/system/menu/:menuId', '删除菜单信息', 'menu', 'DELETE'); -INSERT INTO `sys_apis` VALUES (46, '2021-12-09 19:25:44', '2021-12-09 19:27:06', NULL, '/system/post/list', '获取岗位分页列表', 'post', 'GET'); -INSERT INTO `sys_apis` VALUES (47, '2021-12-09 19:26:55', '2021-12-09 19:26:55', NULL, '/system/post/:postId', '获取岗位信息', 'post', 'GET'); -INSERT INTO `sys_apis` VALUES (48, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post', '添加岗位信息', 'post', 'POST'); -INSERT INTO `sys_apis` VALUES (49, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post', '修改岗位信息', 'post', 'PUT'); -INSERT INTO `sys_apis` VALUES (50, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post/:postId', '删除岗位信息', 'post', 'DELETE'); -INSERT INTO `sys_apis` VALUES (51, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/list', '获取角色分页列表', 'role', 'GET'); -INSERT INTO `sys_apis` VALUES (52, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/:roleId', '获取角色信息', 'role', 'GET'); -INSERT INTO `sys_apis` VALUES (53, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role', '添加角色信息', 'role', 'POST'); -INSERT INTO `sys_apis` VALUES (54, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role', '修改角色信息', 'role', 'PUT'); -INSERT INTO `sys_apis` VALUES (55, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/:roleId', '删除角色信息', 'role', 'DELETE'); -INSERT INTO `sys_apis` VALUES (56, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/changeStatus', '修改角色状态', 'role', 'PUT'); -INSERT INTO `sys_apis` VALUES (57, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/dataScope', '修改角色部门权限', 'role', 'PUT'); -INSERT INTO `sys_apis` VALUES (58, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/export', '导出角色信息', 'role', 'GET'); -INSERT INTO `sys_apis` VALUES (59, '2021-12-09 19:50:57', '2022-01-19 08:58:20', NULL, '/system/api/list', '获取api分页列表1', 'api', 'GET'); -INSERT INTO `sys_apis` VALUES (60, '2021-12-09 19:51:26', '2021-12-09 19:51:26', NULL, '/system/api/all', '获取所有api', 'api', 'GET'); -INSERT INTO `sys_apis` VALUES (61, '2021-12-09 19:51:54', '2021-12-09 19:51:54', NULL, '/system/api/getPolicyPathByRoleId', '获取角色拥有的api权限', 'api', 'GET'); -INSERT INTO `sys_apis` VALUES (62, '2021-12-09 19:52:14', '2021-12-09 19:52:14', NULL, '/system/api/:id', '获取api信息', 'api', 'GET'); -INSERT INTO `sys_apis` VALUES (63, '2021-12-09 19:52:35', '2021-12-09 19:52:35', NULL, '/system/api', '添加api信息', 'api', 'POST'); -INSERT INTO `sys_apis` VALUES (64, '2021-12-09 19:52:50', '2021-12-09 19:52:50', NULL, '/system/api', '修改api信息', 'api', 'PUT'); -INSERT INTO `sys_apis` VALUES (65, '2021-12-09 19:53:07', '2021-12-09 19:53:07', NULL, '/system/api/:id', '删除api信息', 'api', 'DELETE'); -INSERT INTO `sys_apis` VALUES (66, '2021-12-17 10:51:05', '2021-12-17 10:54:22', NULL, '/log/logLogin/list', '获取登录日志', 'log', 'GET'); -INSERT INTO `sys_apis` VALUES (67, '2021-12-17 10:51:43', '2021-12-17 10:54:28', NULL, '/log/logLogin/:infoId', '删除日志', 'log', 'DELETE'); -INSERT INTO `sys_apis` VALUES (68, '2021-12-17 10:53:09', '2021-12-17 10:54:34', NULL, '/log/logLogin/all', '清空所有', 'log', 'DELETE'); -INSERT INTO `sys_apis` VALUES (69, '2021-12-17 10:54:07', '2021-12-17 10:54:07', NULL, '/log/logOper/list', '操作日志列表', 'log', 'GET'); -INSERT INTO `sys_apis` VALUES (70, '2021-12-17 10:53:09', '2021-12-17 10:53:09', NULL, '/log/logOper/:operId', '删除', 'log', 'DELETE'); -INSERT INTO `sys_apis` VALUES (71, '2021-12-17 10:53:09', '2021-12-17 10:53:09', NULL, '/log/logOper/all', '清空', 'log', 'DELETE'); -INSERT INTO `sys_apis` VALUES (72, '2021-12-24 15:41:23', '2021-12-24 15:41:23', NULL, '/job/list', '任务列表', 'job', 'GET'); -INSERT INTO `sys_apis` VALUES (73, '2021-12-24 15:41:54', '2021-12-24 15:41:54', NULL, '/job', '添加', 'job', 'POST'); -INSERT INTO `sys_apis` VALUES (74, '2021-12-24 15:42:11', '2021-12-24 15:42:11', NULL, '/job', '修改任务', 'job', 'PUT'); -INSERT INTO `sys_apis` VALUES (75, '2021-12-24 15:42:37', '2021-12-24 16:32:21', NULL, '/job/:jobId', '获取任务', 'job', 'GET'); -INSERT INTO `sys_apis` VALUES (76, '2021-12-24 15:43:09', '2021-12-24 16:32:05', NULL, '/job/:jobId', '删除job', 'job', 'DELETE'); -INSERT INTO `sys_apis` VALUES (77, '2021-12-24 15:43:35', '2021-12-24 16:31:11', NULL, '/job/stop/:jobId', '停止任务', 'job', 'GET'); -INSERT INTO `sys_apis` VALUES (78, '2021-12-24 15:44:09', '2021-12-24 16:30:38', NULL, '/job/start/:jobId', '开始任务', 'job', 'GET'); -INSERT INTO `sys_apis` VALUES (79, '2021-12-24 15:45:03', '2021-12-24 15:46:36', NULL, '/log/logJob/list', '任务日志列表', 'log', 'GET'); -INSERT INTO `sys_apis` VALUES (80, '2021-12-24 15:45:33', '2021-12-24 15:46:43', NULL, '/log/logJob/all', '清空任务日志', 'log', 'DELETE'); -INSERT INTO `sys_apis` VALUES (81, '2021-12-24 15:46:08', '2021-12-24 16:33:13', NULL, '/log/logJob/:logId', '删除任务日志', 'log', 'DELETE'); -INSERT INTO `sys_apis` VALUES (82, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice/list', '获取通知分页列表', 'notice', 'GET'); -INSERT INTO `sys_apis` VALUES (83, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice', '添加通知信息', 'notice', 'POST'); -INSERT INTO `sys_apis` VALUES (84, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice', '修改通知信息', 'notice', 'PUT'); -INSERT INTO `sys_apis` VALUES (85, '2021-12-24 15:45:33', '2021-12-24 16:33:48', NULL, '/system/notice/:noticeId', '删除通知信息', 'notice', 'DELETE'); -INSERT INTO `sys_apis` VALUES (86, '2021-12-24 22:40:19', '2021-12-24 22:40:19', NULL, '/job/changeStatus', '修改状态', 'job', 'PUT'); -INSERT INTO `sys_apis` VALUES (88, '2022-01-02 13:53:06', '2022-07-18 10:57:58', NULL, '/develop/code/table/db/list', '数据库表列表', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (89, '2022-01-02 13:53:44', '2022-01-02 13:53:44', NULL, '/develop/code/table/list', '表列表', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (90, '2022-01-02 13:54:10', '2022-01-02 13:54:10', NULL, '/develop/code/table/info/:tableId', '表信息', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (91, '2022-01-02 13:54:42', '2022-07-18 10:58:35', NULL, '/develop/code/table/info/tableName', '表名获取表信息', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (92, '2022-01-02 13:55:13', '2022-01-02 13:55:13', NULL, '/develop/code/table/tableTree', '表树', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (93, '2022-01-02 13:56:37', '2022-01-02 13:56:37', NULL, '/develop/code/table', '导入表', 'gen', 'POST'); -INSERT INTO `sys_apis` VALUES (94, '2022-01-02 13:57:36', '2022-01-02 13:57:36', NULL, '/develop/code/table', '修改代码生成信息', 'gen', 'PUT'); -INSERT INTO `sys_apis` VALUES (95, '2022-01-02 13:58:25', '2022-01-02 13:58:25', NULL, '/develop/code/table/:tableId', '删除表数据', 'gen', 'DELETE'); -INSERT INTO `sys_apis` VALUES (96, '2022-01-02 13:59:07', '2022-01-02 13:59:07', NULL, '/develop/code/gen/preview/:tableId', '预览代码', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (97, '2022-01-02 13:59:43', '2022-01-02 13:59:43', NULL, '/develop/code/gen/code/:tableId', '生成代码', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (98, '2022-01-02 14:00:10', '2022-07-17 01:19:42', NULL, '/develop/code/gen/configure/:tableId', '生成api菜单', 'gen', 'GET'); -INSERT INTO `sys_apis` VALUES (99, '2022-01-13 16:44:44', '2022-01-13 16:45:27', NULL, '/resource/oss/list', '获取oss列表', 'oss', 'GET'); -INSERT INTO `sys_apis` VALUES (100, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss/:ossId', '获取oss', 'oss', 'GET'); -INSERT INTO `sys_apis` VALUES (101, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss', '添加oss', 'oss', 'POST'); -INSERT INTO `sys_apis` VALUES (102, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss', '修改oss', 'oss', 'PUT'); -INSERT INTO `sys_apis` VALUES (103, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss/:ossId', '删除oss', 'oss', 'DELETE'); -INSERT INTO `sys_apis` VALUES (104, '2022-01-14 13:19:21', '2022-01-14 13:19:21', NULL, '/resource/oss/changeStatus', '修改状态', 'oss', 'PUT'); -INSERT INTO `sys_apis` VALUES (105, '2022-01-14 13:20:14', '2022-01-14 13:20:14', NULL, '/resource/oss/uploadFile', '调试上传文件', 'oss', 'POST'); -INSERT INTO `sys_apis` VALUES (106, '2022-01-14 15:30:39', '2022-01-14 15:30:39', NULL, '/resource/email/list', '邮件分页列表', 'mail', 'GET'); -INSERT INTO `sys_apis` VALUES (107, '2022-01-14 15:31:20', '2022-01-14 15:31:20', NULL, '/resource/email/:mailId', '获取邮件', 'mail', 'GET'); -INSERT INTO `sys_apis` VALUES (108, '2022-01-14 15:31:54', '2022-01-14 15:31:54', NULL, '/resource/email', '添加邮件配置', 'mail', 'POST'); -INSERT INTO `sys_apis` VALUES (109, '2022-01-14 15:32:21', '2022-01-14 15:32:21', NULL, '/resource/email', '修改邮件配置', 'mail', 'PUT'); -INSERT INTO `sys_apis` VALUES (110, '2022-01-14 15:32:53', '2022-01-14 15:32:53', NULL, '/resource/email/:mailId', '删除邮件', 'mail', 'DELETE'); -INSERT INTO `sys_apis` VALUES (111, '2022-01-14 17:11:42', '2022-01-14 17:11:42', NULL, '/resource/email/changeStatus', '修改状态', 'mail', 'PUT'); -INSERT INTO `sys_apis` VALUES (112, '2022-01-14 17:12:17', '2022-01-14 17:12:17', NULL, '/resource/email/debugMail', '发送邮件调试', 'mail', 'POST'); -INSERT INTO `sys_apis` VALUES (113, '2022-07-15 18:06:27', '2022-07-15 18:06:27', NULL, '/system/tenant/list', '租户列表', 'tenant', 'GET'); -INSERT INTO `sys_apis` VALUES (114, '2022-07-15 18:07:16', '2022-07-15 18:07:16', NULL, '/system/tenant/:tenantId', '获取租户', 'tenant', 'GET'); -INSERT INTO `sys_apis` VALUES (115, '2022-07-15 18:07:43', '2022-07-15 18:07:43', NULL, '/system/tenant', '添加租户', 'tenant', 'POST'); -INSERT INTO `sys_apis` VALUES (116, '2022-07-15 18:08:08', '2022-07-15 18:08:08', NULL, '/system/tenant', '修改租户', 'tenant', 'PUT'); -INSERT INTO `sys_apis` VALUES (117, '2022-07-15 18:08:57', '2022-07-15 18:08:57', NULL, '/system/tenant/:tenantId', '删除租户', 'tenant', 'DELETE'); -INSERT INTO `sys_apis` VALUES (123, '2022-07-18 10:24:03', '2022-07-18 10:24:03', NULL, '/system/tenant/lists', '获取所有租户', 'tenant', 'GET'); - --- ---------------------------- --- Table structure for sys_configs --- ---------------------------- -DROP TABLE IF EXISTS `sys_configs`; -CREATE TABLE `sys_configs` ( - `config_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键编码', - `config_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ConfigName', - `config_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ConfigKey', - `config_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ConfigValue', - `config_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否系统内置0,1', - `is_frontend` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否前台', - `remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Remark', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`config_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_configs --- ---------------------------- -INSERT INTO `sys_configs` VALUES (1, '账号初始密码', 'sys.user.initPassword', '123456', '0', '0', '初始密码', '2021-12-04 13:50:13', '2021-12-04 13:54:52', NULL); - --- ---------------------------- --- Table structure for sys_depts --- ---------------------------- -DROP TABLE IF EXISTS `sys_depts`; -CREATE TABLE `sys_depts` ( - `dept_id` bigint(20) NOT NULL AUTO_INCREMENT, - `tenant_id` int(11) NULL DEFAULT NULL COMMENT '租户id', - `parent_id` int(11) NULL DEFAULT NULL COMMENT '上级部门', - `dept_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门路径', - `dept_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门名称', - `sort` int(4) NULL DEFAULT NULL COMMENT '排序', - `leader` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '负责人', - `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '手机', - `email` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '修改人', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`dept_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_depts --- ---------------------------- -INSERT INTO `sys_depts` VALUES (2, NULL, 0, '/0/2', '熊猫科技', 0, 'xm', '18353366836', '342@qq.com', '0', 'admin', 'admin', '2021-12-01 17:31:53', '2021-12-02 08:56:19', NULL); -INSERT INTO `sys_depts` VALUES (3, NULL, 2, '/0/2/3', '研发部', 1, 'panda', '18353366543', 'ewr@qq.com', '0', 'admin', 'admin', '2021-12-01 17:37:43', '2021-12-02 08:55:56', NULL); -INSERT INTO `sys_depts` VALUES (7, NULL, 2, '/0/2/7', '营销部', 2, 'panda', '18353333333', '342@qq.com', '0', 'panda', 'panda', '2021-12-24 10:46:24', '2021-12-24 10:47:15', NULL); - --- ---------------------------- --- Table structure for sys_dict_data --- ---------------------------- -DROP TABLE IF EXISTS `sys_dict_data`; -CREATE TABLE `sys_dict_data` ( - `dict_code` bigint(20) NOT NULL AUTO_INCREMENT, - `dict_sort` int(11) NULL DEFAULT NULL COMMENT '排序', - `dict_label` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标签', - `dict_value` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '值', - `dict_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '字典类型', - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态(0正常 1停用)', - `css_class` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'CssClass', - `list_class` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ListClass', - `is_default` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'IsDefault', - `create_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `update_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`dict_code`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 39 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_dict_data --- ---------------------------- -INSERT INTO `sys_dict_data` VALUES (1, 0, '男', '0', 'sys_user_sex', '0', '', '', '', 'admin', '', '男', '2021-11-30 14:58:18', '2021-11-30 14:58:18', NULL); -INSERT INTO `sys_dict_data` VALUES (2, 1, '女', '1', 'sys_user_sex', '0', '', '', '', 'admin', '', '女生', '2021-11-30 15:09:11', '2021-11-30 15:10:28', NULL); -INSERT INTO `sys_dict_data` VALUES (3, 2, '未知', '2', 'sys_user_sex', '0', '', '', '', 'admin', '', '未知', '2021-11-30 15:09:11', '2021-11-30 15:10:28', NULL); -INSERT INTO `sys_dict_data` VALUES (4, 0, '正常', '0', 'sys_normal_disable', '0', '', '', '', 'admin', '', '', '2021-12-01 15:58:50', '2021-12-01 15:58:50', NULL); -INSERT INTO `sys_dict_data` VALUES (5, 1, '停用', '1', 'sys_normal_disable', '0', '', '', '', 'admin', '', '', '2021-12-01 15:59:08', '2021-12-01 15:59:08', NULL); -INSERT INTO `sys_dict_data` VALUES (6, 0, '目录', 'M', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:12', '2021-12-02 09:49:12', NULL); -INSERT INTO `sys_dict_data` VALUES (7, 1, '菜单', 'C', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:35', '2021-12-02 09:49:52', NULL); -INSERT INTO `sys_dict_data` VALUES (8, 2, '按钮', 'F', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:35', '2021-12-02 09:49:35', NULL); -INSERT INTO `sys_dict_data` VALUES (9, 0, '显示', '0', 'sys_show_hide', '0', '', '', '', 'admin', '', '', '2021-12-02 09:56:40', '2021-12-02 09:56:40', NULL); -INSERT INTO `sys_dict_data` VALUES (10, 0, '隐藏', '1', 'sys_show_hide', '0', '', '', '', 'admin', '', '', '2021-12-02 09:56:52', '2021-12-02 09:56:52', NULL); -INSERT INTO `sys_dict_data` VALUES (11, 0, '是', '0', 'sys_num_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-02 10:16:16', '2021-12-02 10:16:16', NULL); -INSERT INTO `sys_dict_data` VALUES (12, 1, '否', '1', 'sys_num_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-02 10:16:26', '2021-12-02 10:16:26', NULL); -INSERT INTO `sys_dict_data` VALUES (13, 0, '是', '0', 'sys_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-04 13:48:15', '2021-12-04 13:48:15', NULL); -INSERT INTO `sys_dict_data` VALUES (14, 0, '否', '1', 'sys_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-04 13:48:21', '2021-12-04 13:48:21', NULL); -INSERT INTO `sys_dict_data` VALUES (15, 0, '创建(POST)', 'POST', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:05', '2021-12-09 09:29:52', NULL); -INSERT INTO `sys_dict_data` VALUES (16, 1, '查询(GET)', 'GET', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:24', '2021-12-09 09:29:59', NULL); -INSERT INTO `sys_dict_data` VALUES (17, 2, '修改(PUT)', 'PUT', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:40', '2021-12-09 09:30:06', NULL); -INSERT INTO `sys_dict_data` VALUES (18, 3, '删除(DELETE)', 'DELETE', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:54', '2021-12-09 09:30:13', NULL); -INSERT INTO `sys_dict_data` VALUES (19, 0, '成功', '0', 'sys_common_status', '0', '', '', '', 'admin', '', '', '2021-12-17 11:01:52', '2021-12-17 11:01:52', NULL); -INSERT INTO `sys_dict_data` VALUES (20, 0, '失败', '1', 'sys_common_status', '0', '', '', '', 'admin', '', '', '2021-12-17 11:02:08', '2021-12-17 11:02:08', NULL); -INSERT INTO `sys_dict_data` VALUES (21, 0, '其他', '0', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:07', '2021-12-17 11:30:07', NULL); -INSERT INTO `sys_dict_data` VALUES (22, 0, '新增', '1', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:21', '2021-12-17 11:30:21', NULL); -INSERT INTO `sys_dict_data` VALUES (23, 0, '修改', '2', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:32', '2021-12-17 11:30:32', NULL); -INSERT INTO `sys_dict_data` VALUES (24, 0, '删除', '3', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:40', '2021-12-17 11:30:40', NULL); -INSERT INTO `sys_dict_data` VALUES (25, 0, '默认', 'DEFAULT', 'sys_job_group', '0', '', '', '', 'panda', '', '', '2021-12-24 15:15:31', '2021-12-24 15:15:31', NULL); -INSERT INTO `sys_dict_data` VALUES (26, 1, '系统', 'SYSTEM', 'sys_job_group', '0', '', '', '', 'panda', '', '', '2021-12-24 15:15:50', '2021-12-24 15:15:50', NULL); -INSERT INTO `sys_dict_data` VALUES (27, 0, '发布通知', '1', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:07', '2021-12-26 15:24:07', NULL); -INSERT INTO `sys_dict_data` VALUES (28, 0, '任免通知', '2', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:18', '2021-12-26 15:24:18', NULL); -INSERT INTO `sys_dict_data` VALUES (29, 0, '事物通知', '3', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:46', '2021-12-26 15:24:46', NULL); -INSERT INTO `sys_dict_data` VALUES (30, 0, '审批通知', '4', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:25:08', '2021-12-26 15:25:08', NULL); -INSERT INTO `sys_dict_data` VALUES (31, 0, '阿里云', '0', 'res_oss_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:44:01', '2022-01-13 15:44:01', NULL); -INSERT INTO `sys_dict_data` VALUES (32, 1, '七牛云', '1', 'res_oss_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:44:18', '2022-01-13 15:44:18', NULL); -INSERT INTO `sys_dict_data` VALUES (33, 2, '腾讯云', '2', 'res_oss_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:44:39', '2022-01-13 15:44:39', NULL); -INSERT INTO `sys_dict_data` VALUES (34, 0, '阿里云', '0', 'res_sms_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:47:30', '2022-01-13 15:47:30', NULL); -INSERT INTO `sys_dict_data` VALUES (35, 1, '腾讯云', '1', 'res_sms_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:47:39', '2022-01-13 15:47:39', NULL); -INSERT INTO `sys_dict_data` VALUES (36, 0, '163邮箱', '0', 'res_mail_category', '0', '', '', '', 'panda', '', '', '2022-01-14 15:43:42', '2022-01-14 15:43:42', NULL); -INSERT INTO `sys_dict_data` VALUES (37, 0, 'qq邮箱', '1', 'res_mail_category', '0', '', '', '', 'panda', '', '', '2022-01-14 15:44:08', '2022-01-14 15:44:08', NULL); -INSERT INTO `sys_dict_data` VALUES (38, 0, '企业邮箱', '2', 'res_mail_category', '0', '', '', '', 'panda', '', '', '2022-01-14 15:44:20', '2022-01-14 15:44:20', NULL); - --- ---------------------------- --- Table structure for sys_dict_types --- ---------------------------- -DROP TABLE IF EXISTS `sys_dict_types`; -CREATE TABLE `sys_dict_types` ( - `dict_id` bigint(20) NOT NULL AUTO_INCREMENT, - `dict_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '名称', - `dict_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '类型', - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', - `create_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `update_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`dict_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 33 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_dict_types --- ---------------------------- -INSERT INTO `sys_dict_types` VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '', '性别列表', '2021-11-30 14:02:52', '2021-11-30 14:07:55', '2021-11-30 14:11:54'); -INSERT INTO `sys_dict_types` VALUES (2, '用户性别', 'sys_user_sex', '0', 'admin', '', '用户性别列表', '2021-11-30 14:12:33', '2021-11-30 14:12:33', '2021-11-30 14:14:19'); -INSERT INTO `sys_dict_types` VALUES (3, '的心', 'sfd', '0', 'admin', '', 'fs', '2021-11-30 14:13:22', '2021-11-30 14:13:22', '2021-11-30 14:14:19'); -INSERT INTO `sys_dict_types` VALUES (4, '用户性别', 'sys_user_sex', '0', 'admin', '', '性别字典', '2021-11-30 14:15:25', '2021-11-30 14:15:25', NULL); -INSERT INTO `sys_dict_types` VALUES (5, 'df', 'da', '0', 'admin', '', 'sd', '2021-11-30 15:54:33', '2021-11-30 15:54:33', '2021-11-30 15:54:40'); -INSERT INTO `sys_dict_types` VALUES (6, '系统开关', 'sys_normal_disable', '0', 'admin', '', '开关列表', '2021-12-01 15:57:58', '2021-12-01 15:57:58', NULL); -INSERT INTO `sys_dict_types` VALUES (7, '菜单类型', 'sys_menu_type', '0', 'admin', '', '菜单类型列表', '2021-12-02 09:48:48', '2021-12-02 09:56:12', NULL); -INSERT INTO `sys_dict_types` VALUES (8, '菜单状态', 'sys_show_hide', '0', 'admin', '', '菜单状态列表', '2021-12-02 09:55:59', '2021-12-02 09:55:59', NULL); -INSERT INTO `sys_dict_types` VALUES (9, '数字是否', 'sys_num_yes_no', '0', 'admin', '', '数字是否列表', '2021-12-02 10:13:29', '2021-12-02 10:13:40', '2021-12-02 10:15:07'); -INSERT INTO `sys_dict_types` VALUES (10, '数字是否', 'sys_num_yes_no', '0', 'admin', '', '数字是否', '2021-12-02 10:13:29', '2021-12-02 10:13:29', NULL); -INSERT INTO `sys_dict_types` VALUES (11, '状态是否', 'sys_yes_no', '0', 'admin', '', '状态是否', '2021-12-04 13:47:57', '2021-12-04 13:47:57', NULL); -INSERT INTO `sys_dict_types` VALUES (12, '网络请求方法', 'sys_method_api', '0', 'admin', '', '网络请求方法列表', '2021-12-08 17:21:27', '2021-12-08 17:21:27', NULL); -INSERT INTO `sys_dict_types` VALUES (13, '成功失败', 'sys_common_status', '0', 'admin', '', '是否成功失败', '2021-12-17 10:10:03', '2021-12-17 10:10:03', NULL); -INSERT INTO `sys_dict_types` VALUES (27, '操作分类', 'sys_oper_type', '0', 'admin', '', '操作分类列表', '2021-12-17 11:29:50', '2021-12-17 11:29:50', NULL); -INSERT INTO `sys_dict_types` VALUES (28, '任务组', 'sys_job_group', '0', 'panda', '', '系统任务,开机自启', '2021-12-24 15:14:56', '2021-12-24 15:14:56', NULL); -INSERT INTO `sys_dict_types` VALUES (29, '通知类型', 'sys_notice_type', '0', 'panda', '', '通知类型列表', '2021-12-26 15:23:26', '2021-12-26 15:23:26', NULL); -INSERT INTO `sys_dict_types` VALUES (30, 'oss分类', 'res_oss_category', '0', 'panda', '', 'oss分类列表', '2022-01-13 15:43:29', '2022-01-13 15:43:29', NULL); -INSERT INTO `sys_dict_types` VALUES (31, 'sms分类', 'res_sms_category', '0', 'panda', '', 'sms分类列表', '2021-12-26 15:23:26', '2022-01-13 15:47:13', NULL); -INSERT INTO `sys_dict_types` VALUES (32, 'mail分类', 'res_mail_category', '0', 'panda', '', 'mail分类列表', '2022-01-14 15:43:17', '2022-01-14 15:43:17', NULL); - --- ---------------------------- --- Table structure for sys_jobs --- ---------------------------- -DROP TABLE IF EXISTS `sys_jobs`; -CREATE TABLE `sys_jobs` ( - `job_id` bigint(20) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `job_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `job_type` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `invoke_target` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `args` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `misfire_policy` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `concurrent` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `entry_id` int(11) NULL DEFAULT NULL, - `create_by` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人', - `update_by` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新者', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`job_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of sys_jobs --- ---------------------------- -INSERT INTO `sys_jobs` VALUES (1, 'testcron', 'SYSTEM', '2', ' 0/10 * * * * ?', 'cronHandle', 'aaa', '', '', '1', 0, 'panda', '', '2021-12-24 16:06:09', '2022-01-22 08:11:24', NULL); - --- ---------------------------- --- Table structure for sys_menus --- ---------------------------- -DROP TABLE IF EXISTS `sys_menus`; -CREATE TABLE `sys_menus` ( - `menu_id` bigint(20) NOT NULL AUTO_INCREMENT, - `menu_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `parent_id` int(11) NULL DEFAULT NULL, - `sort` int(4) NULL DEFAULT NULL, - `icon` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `path` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `is_iframe` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `is_link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `menu_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `is_hide` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `is_keep_alive` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `is_affix` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `permission` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `status` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `remark` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`menu_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 95 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_menus --- ---------------------------- -INSERT INTO `sys_menus` VALUES (1, '系统设置', '', 0, 0, 'elementSetting', '/system', 'Layout', '1', '', 'M', '0', '0', '1', '', '0', 'admin', 'panda', '', '2021-12-02 11:04:08', '2021-12-28 13:32:21', NULL); -INSERT INTO `sys_menus` VALUES (3, '用户管理', '', 1, 1, 'elementUser', '/system/user', '/system/user/index', '1', '', 'C', '0', '1', '1', 'system:user:list', '0', 'admin', 'panda', '', '2021-12-02 14:07:56', '2021-12-28 13:32:44', NULL); -INSERT INTO `sys_menus` VALUES (4, '添加用户', '', 3, 1, '', '', '', '', '', 'F', '0', '', '', 'system:user:add', '0', 'admin', '', '', '2021-12-03 13:36:33', '2021-12-03 13:36:33', NULL); -INSERT INTO `sys_menus` VALUES (5, '编辑用户', '', 3, 1, '', '', '', '', '', 'F', '0', '', '', 'system:user:edit', '0', 'admin', '', '', '2021-12-03 13:48:13', '2021-12-03 13:48:13', NULL); -INSERT INTO `sys_menus` VALUES (6, '角色管理', '', 1, 2, 'elementUserFilled', '/system/role', '/system/role/index', '1', '', 'C', '0', '1', '1', 'system:role:list', '0', '', 'panda', '', '2021-12-03 13:51:55', '2022-07-16 10:23:21', NULL); -INSERT INTO `sys_menus` VALUES (7, '菜单管理', '', 1, 2, 'iconfont icon-juxingkaobei', '/system/menu', '/system/menu/index', '1', '', 'C', '0', '1', '1', 'system:menu:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:33:19', NULL); -INSERT INTO `sys_menus` VALUES (8, '部门管理', '', 1, 3, 'iconfont icon-jiliandongxuanzeqi', '/system/dept', '/system/dept/index', '1', '', 'C', '0', '1', '1', 'system:dept:list', '0', 'admin', 'panda', '', '2021-12-03 13:58:36', '2021-12-28 13:40:20', NULL); -INSERT INTO `sys_menus` VALUES (9, '岗位管理', '', 1, 4, 'iconfont icon-neiqianshujuchucun', '/system/post', '/system/post/index', '1', '', 'C', '0', '1', '1', 'system:post:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:40:31', NULL); -INSERT INTO `sys_menus` VALUES (10, '字典管理', '', 1, 5, 'elementCellphone', '/system/dict', '/system/dict/index', '1', '', 'C', '0', '1', '1', 'system:dict:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:40:50', NULL); -INSERT INTO `sys_menus` VALUES (11, '参数管理', '', 1, 6, 'elementDocumentCopy', '/system/config', '/system/config/index', '1', '', 'C', '0', '1', '1', 'system:config:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:41:05', NULL); -INSERT INTO `sys_menus` VALUES (12, '个人中心', '', 0, 10, 'elementAvatar', '/personal', '/personal/index', '1', '', 'M', '0', '0', '0', '', '0', 'admin', 'panda', '', '2021-12-03 14:12:43', '2021-12-28 13:43:17', NULL); -INSERT INTO `sys_menus` VALUES (13, '添加配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:add', '0', 'admin', '', '', '2021-12-06 17:19:19', '2021-12-06 17:19:19', NULL); -INSERT INTO `sys_menus` VALUES (14, '修改配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:edit', '0', 'admin', '', '', '2021-12-06 17:20:30', '2021-12-06 17:20:30', NULL); -INSERT INTO `sys_menus` VALUES (15, '删除配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:delete', '0', 'admin', '', '', '2021-12-06 17:23:52', '2021-12-06 17:23:52', NULL); -INSERT INTO `sys_menus` VALUES (16, '导出配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:export', '0', 'admin', '', '', '2021-12-06 17:24:41', '2021-12-06 17:24:41', NULL); -INSERT INTO `sys_menus` VALUES (17, '新增角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:add', '0', 'admin', '', '', '2021-12-06 17:43:35', '2021-12-06 17:43:35', NULL); -INSERT INTO `sys_menus` VALUES (18, '删除角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:delete', '0', 'admin', '', '', '2021-12-06 17:44:10', '2021-12-06 17:44:10', NULL); -INSERT INTO `sys_menus` VALUES (19, '修改角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:edit', '0', 'admin', '', '', '2021-12-06 17:44:48', '2021-12-06 17:44:48', NULL); -INSERT INTO `sys_menus` VALUES (20, '导出角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:export', '0', 'admin', '', '', '2021-12-06 17:45:25', '2021-12-06 17:45:25', NULL); -INSERT INTO `sys_menus` VALUES (21, '添加菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:add', '0', 'admin', '', '', '2021-12-06 17:46:01', '2021-12-06 17:46:01', NULL); -INSERT INTO `sys_menus` VALUES (22, '修改菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:edit', '0', 'admin', '', '', '2021-12-06 17:46:24', '2021-12-06 17:46:24', NULL); -INSERT INTO `sys_menus` VALUES (23, '删除菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:delete', '0', 'admin', '', '', '2021-12-06 17:46:47', '2021-12-06 17:46:47', NULL); -INSERT INTO `sys_menus` VALUES (24, '添加部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:add', '0', 'admin', '', '', '2021-12-07 09:33:58', '2021-12-07 09:33:58', NULL); -INSERT INTO `sys_menus` VALUES (25, '编辑部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:edit', '0', 'admin', '', '', '2021-12-07 09:34:39', '2021-12-07 09:34:39', NULL); -INSERT INTO `sys_menus` VALUES (26, '删除部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:delete', '0', 'admin', 'admin', '', '2021-12-07 09:35:09', '2021-12-07 09:36:26', NULL); -INSERT INTO `sys_menus` VALUES (27, '导出部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:export', '0', 'admin', '', '', '2021-12-07 09:35:51', '2021-12-07 09:35:51', '2021-12-07 09:36:37'); -INSERT INTO `sys_menus` VALUES (28, '添加岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (29, '编辑岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:edit', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (30, '删除岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:delete', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (31, '导出岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:export', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (32, '添加字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (33, '编辑字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:edit', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (34, '删除字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:delete', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (35, '导出字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:export', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (36, '新增字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO `sys_menus` VALUES (37, '修改字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:edit', '0', 'admin', '', '', '2021-12-07 09:48:04', '2021-12-07 09:48:04', NULL); -INSERT INTO `sys_menus` VALUES (38, '删除字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:delete', '0', 'admin', '', '', '2021-12-07 09:48:42', '2021-12-07 09:48:42', NULL); -INSERT INTO `sys_menus` VALUES (39, 'API管理', '', 1, 2, 'iconfont icon-siweidaotu', '/system/api', '/system/api/index', '1', '', 'C', '0', '1', '1', 'system:api:list', '0', '', 'panda', '', '2021-12-09 09:09:13', '2022-07-16 10:23:42', NULL); -INSERT INTO `sys_menus` VALUES (40, '添加api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:add', '0', 'admin', '', '', '2021-12-09 09:09:54', '2021-12-09 09:09:54', NULL); -INSERT INTO `sys_menus` VALUES (41, '编辑api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:edit', '0', 'admin', '', '', '2021-12-09 09:10:38', '2021-12-09 09:10:38', NULL); -INSERT INTO `sys_menus` VALUES (42, '删除api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:delete', '0', 'admin', '', '', '2021-12-09 09:11:11', '2021-12-09 09:11:11', NULL); -INSERT INTO `sys_menus` VALUES (43, '日志系统', '', 0, 1, 'iconfont icon-biaodan', '/log', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-02 11:04:08', '2021-12-28 13:38:33', NULL); -INSERT INTO `sys_menus` VALUES (44, '系统工具', '', 0, 2, 'iconfont icon-gongju', '/tool', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-16 16:35:15', '2021-12-28 13:38:46', NULL); -INSERT INTO `sys_menus` VALUES (45, '操作日志', '', 43, 1, 'iconfont icon-bolangnengshiyanchang', '/log/operation', '/log/operation/index', '1', '', 'C', '0', '1', '1', 'log:operation:list', '0', 'admin', 'panda', '', '2021-12-16 16:42:03', '2021-12-28 13:39:44', NULL); -INSERT INTO `sys_menus` VALUES (46, '登录日志', '', 43, 2, 'iconfont icon--chaifenlie', '/log/login', '/log/login/index', '1', '', 'C', '0', '1', '1', 'log:login:list', '0', 'admin', 'panda', '', '2021-12-16 16:43:28', '2021-12-28 13:39:58', NULL); -INSERT INTO `sys_menus` VALUES (47, '服务监控', '', 44, 1, 'elementCpu', '/tool/monitor/', '/tool/monitor/index', '1', '', 'C', '0', '1', '1', 'tool:monitor:list', '0', 'admin', 'panda', '', '2021-12-03 14:12:43', '2021-12-28 13:41:25', NULL); -INSERT INTO `sys_menus` VALUES (48, '定时任务', '', 44, 2, 'elementAlarmClock', '/tool/job', '/tool/job/index', '1', '', 'C', '0', '1', '1', 'tool:job:list', '0', 'admin', 'panda', '', '2021-12-16 16:48:45', '2021-12-28 13:41:59', NULL); -INSERT INTO `sys_menus` VALUES (49, '开发工具', '', 0, 3, 'iconfont icon-diannao', '/develop', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', '', '', '2021-12-16 16:53:11', '2021-12-16 16:53:11', NULL); -INSERT INTO `sys_menus` VALUES (50, '表单构建', '', 49, 1, 'iconfont icon-zidingyibuju', '/develop/form', '/develop/form/index', '1', '', 'C', '0', '1', '1', 'develop:form:list', '0', 'admin', 'panda', '', '2021-12-16 16:55:01', '2022-07-12 18:56:18', NULL); -INSERT INTO `sys_menus` VALUES (51, '代码生成', '', 49, 2, 'iconfont icon-zhongduancanshu', '/develop/code', '/develop/code/index', '1', '', 'C', '0', '1', '1', 'develop:code:list', '0', 'admin', '', '', '2021-12-16 16:56:48', '2021-12-16 16:56:48', NULL); -INSERT INTO `sys_menus` VALUES (52, '系统接口', '', 49, 3, 'iconfont icon-wenducanshu-05', '/develop/apis', '/layout/routerView/iframes', '0', 'http://47.104.252.2:8080/swagger/index.html', 'C', '0', '1', '1', 'develop:apis:list', '0', '', 'panda', '', '2021-12-16 16:58:07', '2022-07-13 11:50:34', NULL); -INSERT INTO `sys_menus` VALUES (53, '资源管理', '', 0, 4, 'iconfont icon-juxingkaobei', '/resource', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', '', '', '2021-12-16 17:02:06', '2021-12-16 17:02:06', NULL); -INSERT INTO `sys_menus` VALUES (54, '对象存储', '', 53, 1, 'iconfont icon-chazhaobiaodanliebiao', '/resource/file', '/resource/file/index', '1', '', 'C', '0', '1', '1', 'resource:file:list', '0', 'admin', 'panda', '', '2021-12-16 17:06:04', '2022-01-13 17:30:09', NULL); -INSERT INTO `sys_menus` VALUES (55, '公告通知', '', 44, 3, 'elementTicket', '/tool/notice', '/tool/notice/index', '1', '', 'C', '0', '1', '1', 'tool:notice:list', '0', 'admin', 'panda', '', '2021-12-16 22:09:11', '2021-12-28 13:42:39', NULL); -INSERT INTO `sys_menus` VALUES (56, '任务日志', '', 43, 1, 'iconfont icon--chaifenhang', '/log/job', '/log/job/index', '1', '', 'C', '0', '1', '1', 'log:job:list', '0', 'panda', 'panda', '', '2021-12-24 22:13:45', '2021-12-28 13:39:52', NULL); -INSERT INTO `sys_menus` VALUES (57, '邮件管理', '', 53, 1, 'iconfont icon-shouye_dongtaihui', '/resource/mail', '/resource/mail/index', '1', '', 'C', '0', '1', '1', 'resource:mail:list', '0', 'panda', 'panda', '', '2021-12-28 15:12:37', '2021-12-28 15:12:45', NULL); -INSERT INTO `sys_menus` VALUES (58, '短信管理', '', 53, 3, 'elementChatDotRound', '/resource/message', '/resource/message/index', '1', '', 'C', '0', '1', '1', 'resource:message:list', '0', 'panda', '', '', '2021-12-16 17:06:04', '2021-12-16 17:06:04', NULL); -INSERT INTO `sys_menus` VALUES (59, '删除', '', 45, 1, '', '', '', '', '', 'F', '', '', '', 'log:operation:delete', '0', 'panda', '', '', '2022-01-14 13:28:25', '2022-01-14 13:28:25', NULL); -INSERT INTO `sys_menus` VALUES (60, '清空', '', 45, 1, '', '', '', '', '', 'F', '', '', '', 'log:operation:clean', '0', 'panda', '', '', '2022-01-14 13:29:24', '2022-01-14 13:29:24', NULL); -INSERT INTO `sys_menus` VALUES (61, '删除', '', 56, 1, '', '', '', '', '', 'F', '', '', '', 'log:job:delete', '0', 'panda', '', '', '2022-01-14 13:29:57', '2022-01-14 13:29:57', NULL); -INSERT INTO `sys_menus` VALUES (62, '清空', '', 56, 1, '', '', '', '', '', 'F', '', '', '', 'log:job:clean', '0', 'panda', '', '', '2022-01-14 13:30:15', '2022-01-14 13:30:15', NULL); -INSERT INTO `sys_menus` VALUES (63, '删除', '', 46, 1, '', '', '', '', '', 'F', '', '', '', 'log:login:delete', '0', 'panda', '', '', '2022-01-14 13:30:46', '2022-01-14 13:30:46', NULL); -INSERT INTO `sys_menus` VALUES (64, '清空', '', 46, 1, '', '', '', '', '', 'F', '', '', '', 'log:login:clean', '0', 'panda', '', '', '2022-01-14 13:31:06', '2022-01-14 13:31:06', NULL); -INSERT INTO `sys_menus` VALUES (65, '新增', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:add', '0', 'panda', '', '', '2022-01-14 13:32:48', '2022-01-14 13:32:48', NULL); -INSERT INTO `sys_menus` VALUES (66, '编辑', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:edit', '0', 'panda', '', '', '2022-01-14 13:33:17', '2022-01-14 13:33:17', NULL); -INSERT INTO `sys_menus` VALUES (67, '删除', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:delete', '0', 'panda', '', '', '2022-01-14 13:33:43', '2022-01-14 13:33:43', NULL); -INSERT INTO `sys_menus` VALUES (68, '开关', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:run', '0', 'panda', '', '', '2022-01-14 13:34:27', '2022-01-14 13:34:27', NULL); -INSERT INTO `sys_menus` VALUES (69, '添加', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:add', '0', 'panda', '', '', '2022-01-14 13:35:23', '2022-01-14 13:35:23', NULL); -INSERT INTO `sys_menus` VALUES (70, '编辑', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:edit', '0', 'panda', '', '', '2022-01-14 13:36:04', '2022-01-14 13:36:04', NULL); -INSERT INTO `sys_menus` VALUES (71, '删除', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:delete', '0', 'panda', '', '', '2022-01-14 13:36:26', '2022-01-14 13:36:26', NULL); -INSERT INTO `sys_menus` VALUES (72, '查看', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:view', '0', 'panda', '', '', '2022-01-14 13:36:51', '2022-01-14 13:36:51', NULL); -INSERT INTO `sys_menus` VALUES (73, '导入', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:add', '0', 'panda', '', '', '2022-01-14 13:38:35', '2022-01-14 13:38:35', NULL); -INSERT INTO `sys_menus` VALUES (74, '编辑', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:edit', '0', 'panda', '', '', '2022-01-14 13:41:25', '2022-01-14 13:41:25', NULL); -INSERT INTO `sys_menus` VALUES (75, '删除', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:delete', '0', 'panda', '', '', '2022-01-14 13:41:42', '2022-01-14 13:41:42', NULL); -INSERT INTO `sys_menus` VALUES (76, '预览', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:view', '0', 'panda', '', '', '2022-01-14 13:42:01', '2022-01-14 13:42:01', NULL); -INSERT INTO `sys_menus` VALUES (77, '生成代码', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:code', '0', 'panda', '', '', '2022-01-14 13:42:48', '2022-01-14 13:42:48', NULL); -INSERT INTO `sys_menus` VALUES (78, '添加', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:add', '0', 'panda', '', '', '2022-01-17 11:26:15', '2022-01-17 11:26:15', NULL); -INSERT INTO `sys_menus` VALUES (79, '编辑', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:edit', '0', 'panda', '', '', '2022-01-17 11:26:39', '2022-01-17 11:26:39', NULL); -INSERT INTO `sys_menus` VALUES (80, '删除', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:delete', '0', 'panda', '', '', '2022-01-17 11:26:56', '2022-01-17 11:26:56', NULL); -INSERT INTO `sys_menus` VALUES (81, '调试', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:debug', '0', 'panda', '', '', '2022-01-17 11:27:14', '2022-01-17 11:27:14', NULL); -INSERT INTO `sys_menus` VALUES (82, '调试', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:debug', '0', 'panda', '', '', '2022-01-17 11:27:17', '2022-01-17 11:27:17', '2022-01-17 11:27:25'); -INSERT INTO `sys_menus` VALUES (83, '添加', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:add', '0', 'panda', '', '', '2022-01-17 11:28:06', '2022-01-17 11:28:06', NULL); -INSERT INTO `sys_menus` VALUES (84, '编辑', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:edit', '0', 'panda', '', '', '2022-01-17 11:28:37', '2022-01-17 11:28:37', NULL); -INSERT INTO `sys_menus` VALUES (85, '删除', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:delete', '0', 'panda', '', '', '2022-01-17 11:29:09', '2022-01-17 11:29:09', NULL); -INSERT INTO `sys_menus` VALUES (86, '调试', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:debug', '0', 'panda', '', '', '2022-01-17 11:29:46', '2022-01-17 11:29:46', NULL); -INSERT INTO `sys_menus` VALUES (87, '租户管理', '', 1, 1, 'iconfont icon-quanxian', '/system/tenant', '/system/tenant/index', '1', '', 'C', '0', '1', '1', 'system:tenant:list', '0', 'panda', '', '', '2022-07-15 18:03:35', '2022-07-15 18:03:35', NULL); -INSERT INTO `sys_menus` VALUES (88, '添加', '', 87, 1, '', '', '', '', '', 'F', '', '', '', 'system:tenant:add', '0', 'panda', '', '', '2022-07-15 18:28:58', '2022-07-15 18:28:58', NULL); -INSERT INTO `sys_menus` VALUES (89, '编辑', '', 87, 1, '', '', '', '', '', 'F', '', '', '', 'system:tenant:edit', '0', 'panda', '', '', '2022-07-15 18:29:34', '2022-07-15 18:29:34', NULL); -INSERT INTO `sys_menus` VALUES (90, '删除', '', 87, 1, '', '', '', '', '', 'F', '', '', '', 'system:tenant:delete', '0', 'panda', '', '', '2022-07-15 18:30:00', '2022-07-15 18:30:00', NULL); - --- ---------------------------- --- Table structure for sys_notices --- ---------------------------- -DROP TABLE IF EXISTS `sys_notices`; -CREATE TABLE `sys_notices` ( - `notice_id` bigint(20) NOT NULL AUTO_INCREMENT, - `title` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题', - `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '标题', - `notice_type` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '通知类型', - `dept_id` int(11) NULL DEFAULT NULL COMMENT '部门Id,部门及子部门', - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - `user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - PRIMARY KEY (`notice_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of sys_notices --- ---------------------------- -INSERT INTO `sys_notices` VALUES (1, '关于学习交流的通知', '

发布入群通知 467890197, 交流学习

', '1', 0, '2021-12-26 15:29:25', '2021-12-26 16:19:48', NULL, 'panda'); -INSERT INTO `sys_notices` VALUES (2, 'test', '

sdsad

', '1', 2, '2021-12-26 16:23:13', '2021-12-26 16:23:13', '2021-12-26 16:31:31', 'panda'); -INSERT INTO `sys_notices` VALUES (3, '版本更新通知:任务功能,通知功能完成', '

', '1', 0, '2021-12-26 17:33:47', '2021-12-26 17:33:47', NULL, 'panda'); - --- ---------------------------- --- Table structure for sys_posts --- ---------------------------- -DROP TABLE IF EXISTS `sys_posts`; -CREATE TABLE `sys_posts` ( - `post_id` bigint(20) NOT NULL AUTO_INCREMENT, - `tenant_id` int(11) NULL DEFAULT NULL COMMENT '租户id', - `post_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '岗位名称', - `post_code` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '岗位代码', - `sort` int(4) NULL DEFAULT NULL COMMENT '岗位排序', - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述', - `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`post_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_posts --- ---------------------------- -INSERT INTO `sys_posts` VALUES (1, 1, '首席执行官', 'CEO', 1, '0', '首席执行官', 'panda', '', '2021-12-02 09:21:44', '2022-07-16 17:36:32', NULL); -INSERT INTO `sys_posts` VALUES (3, 1, '首席技术执行官', 'CTO', 1, '0', '', 'admin', '', '2021-12-02 09:21:44', '2021-12-02 09:25:59', '2021-12-02 09:27:41'); -INSERT INTO `sys_posts` VALUES (4, 1, '首席技术执行官', 'CTO', 2, '0', '', 'panda', '', '2021-12-02 09:21:44', '2022-07-16 17:37:42', NULL); -INSERT INTO `sys_posts` VALUES (5, 1, '123', '123', 0, '0', '', 'admin', '', '2021-12-18 00:33:28', '2021-12-18 00:33:28', '2021-12-28 14:11:52'); -INSERT INTO `sys_posts` VALUES (6, 1, 'wr', 'rw', 0, '0', '', 'panda', '', '2022-07-16 16:55:57', '2022-07-16 16:55:57', '2022-07-16 16:56:08'); - --- ---------------------------- --- Table structure for sys_role_depts --- ---------------------------- -DROP TABLE IF EXISTS `sys_role_depts`; -CREATE TABLE `sys_role_depts` ( - `role_id` int(11) NULL DEFAULT NULL, - `dept_id` int(11) NULL DEFAULT NULL, - `id` bigint(20) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_role_depts --- ---------------------------- -INSERT INTO `sys_role_depts` VALUES (1, 2, 1); -INSERT INTO `sys_role_depts` VALUES (1, 3, 2); - --- ---------------------------- --- Table structure for sys_role_menus --- ---------------------------- -DROP TABLE IF EXISTS `sys_role_menus`; -CREATE TABLE `sys_role_menus` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `role_id` int(11) NULL DEFAULT NULL, - `menu_id` int(11) NULL DEFAULT NULL, - `role_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3043 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_role_menus --- ---------------------------- -INSERT INTO `sys_role_menus` VALUES (2870, 1, 1, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2871, 1, 3, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2872, 1, 4, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2873, 1, 5, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2874, 1, 6, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2875, 1, 7, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2876, 1, 8, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2877, 1, 9, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2878, 1, 10, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2879, 1, 11, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2880, 1, 12, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2881, 1, 13, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2882, 1, 14, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2883, 1, 15, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2884, 1, 16, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2885, 1, 17, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2886, 1, 18, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2887, 1, 19, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2888, 1, 20, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2889, 1, 21, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2890, 1, 22, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2891, 1, 23, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2892, 1, 24, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2893, 1, 25, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2894, 1, 26, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2895, 1, 28, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2896, 1, 29, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2897, 1, 30, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2898, 1, 31, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2899, 1, 32, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2900, 1, 33, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2901, 1, 34, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2902, 1, 35, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2903, 1, 36, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2904, 1, 37, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2905, 1, 38, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2906, 1, 39, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2907, 1, 40, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2908, 1, 41, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2909, 1, 42, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2910, 1, 43, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2911, 1, 44, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2912, 1, 45, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2913, 1, 46, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2914, 1, 47, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2915, 1, 48, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2916, 1, 49, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2917, 1, 50, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2918, 1, 51, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2919, 1, 52, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2920, 1, 53, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2921, 1, 54, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2922, 1, 55, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2923, 1, 56, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2924, 1, 57, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2925, 1, 58, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2926, 1, 59, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2927, 1, 60, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2928, 1, 61, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2929, 1, 62, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2930, 1, 63, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2931, 1, 64, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2932, 1, 65, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2933, 1, 66, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2934, 1, 67, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2935, 1, 68, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2936, 1, 69, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2937, 1, 70, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2938, 1, 71, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2939, 1, 72, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2940, 1, 73, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2941, 1, 74, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2942, 1, 75, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2943, 1, 76, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2944, 1, 77, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2945, 1, 78, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2946, 1, 79, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2947, 1, 80, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2948, 1, 81, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2949, 1, 83, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2950, 1, 84, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2951, 1, 85, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2952, 1, 86, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2953, 1, 87, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2954, 1, 88, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2955, 1, 89, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2956, 1, 90, 'admin'); -INSERT INTO `sys_role_menus` VALUES (2957, 2, 1, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2958, 2, 3, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2959, 2, 4, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2960, 2, 5, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2961, 2, 6, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2962, 2, 7, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2963, 2, 8, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2964, 2, 9, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2965, 2, 10, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2966, 2, 11, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2967, 2, 12, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2968, 2, 13, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2969, 2, 14, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2970, 2, 15, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2971, 2, 16, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2972, 2, 17, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2973, 2, 18, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2974, 2, 19, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2975, 2, 20, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2976, 2, 21, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2977, 2, 22, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2978, 2, 23, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2979, 2, 25, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2980, 2, 26, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2981, 2, 28, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2982, 2, 29, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2983, 2, 30, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2984, 2, 31, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2985, 2, 32, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2986, 2, 33, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2987, 2, 34, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2988, 2, 35, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2989, 2, 36, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2990, 2, 37, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2991, 2, 38, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2992, 2, 39, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2993, 2, 40, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2994, 2, 41, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2995, 2, 42, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2996, 2, 43, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2997, 2, 44, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2998, 2, 45, 'manage'); -INSERT INTO `sys_role_menus` VALUES (2999, 2, 46, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3000, 2, 47, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3001, 2, 48, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3002, 2, 49, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3003, 2, 50, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3004, 2, 51, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3005, 2, 52, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3006, 2, 53, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3007, 2, 54, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3008, 2, 55, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3009, 2, 56, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3010, 2, 57, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3011, 2, 58, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3012, 2, 59, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3013, 2, 60, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3014, 2, 61, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3015, 2, 62, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3016, 2, 63, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3017, 2, 64, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3018, 2, 65, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3019, 2, 66, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3020, 2, 67, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3021, 2, 68, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3022, 2, 69, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3023, 2, 70, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3024, 2, 71, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3025, 2, 72, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3026, 2, 73, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3027, 2, 74, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3028, 2, 75, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3029, 2, 76, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3030, 2, 77, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3031, 2, 78, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3032, 2, 79, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3033, 2, 80, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3034, 2, 81, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3035, 2, 83, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3036, 2, 84, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3037, 2, 85, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3038, 2, 86, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3039, 2, 87, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3040, 2, 88, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3041, 2, 89, 'manage'); -INSERT INTO `sys_role_menus` VALUES (3042, 2, 90, 'manage'); - --- ---------------------------- --- Table structure for sys_roles --- ---------------------------- -DROP TABLE IF EXISTS `sys_roles`; -CREATE TABLE `sys_roles` ( - `role_id` bigint(20) NOT NULL AUTO_INCREMENT, - `role_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色名称', - `tenant_id` int(11) NULL DEFAULT NULL, - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', - `role_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色代码', - `data_scope` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', - `role_sort` int(4) NULL DEFAULT NULL COMMENT '角色排序', - `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`role_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_roles --- ---------------------------- -INSERT INTO `sys_roles` VALUES (1, '超管理员', 1, '0', 'admin', '2', 1, 'admin', 'panda', '超级管理', '2021-12-02 16:03:26', '2022-07-18 10:57:14', NULL); -INSERT INTO `sys_roles` VALUES (2, '管理员', 1, '0', 'manage', '', 2, 'panda', 'panda', '', '2021-12-19 16:06:20', '2022-07-19 14:03:34', NULL); - --- ---------------------------- --- Table structure for sys_tenants --- ---------------------------- -DROP TABLE IF EXISTS `sys_tenants`; -CREATE TABLE `sys_tenants` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - `tenant_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '租户名', - `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注', - `expire_time` datetime NULL DEFAULT NULL COMMENT '过期时间', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - --- ---------------------------- --- Records of sys_tenants --- ---------------------------- -INSERT INTO `sys_tenants` VALUES (1, '2022-07-16 18:28:33', '2022-07-16 18:28:33', NULL, '熊猫科技', '鹅鹅鹅', '2099-07-16 00:00:00'); - --- ---------------------------- --- Table structure for sys_users --- ---------------------------- -DROP TABLE IF EXISTS `sys_users`; -CREATE TABLE `sys_users` ( - `user_id` bigint(20) NOT NULL AUTO_INCREMENT, - `nick_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `tenant_id` int(11) NULL DEFAULT NULL, - `role_id` int(11) NULL DEFAULT NULL, - `salt` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `email` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `dept_id` int(11) NULL DEFAULT NULL, - `post_id` int(11) NULL DEFAULT NULL, - `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `create_time` datetime NULL DEFAULT NULL, - `update_time` datetime NULL DEFAULT NULL, - `delete_time` datetime NULL DEFAULT NULL, - `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `password` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `role_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '多角色', - `post_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '多岗位', - PRIMARY KEY (`user_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of sys_users --- ---------------------------- -INSERT INTO `sys_users` VALUES (1, 'pandax', '13818888888', 1, 1, NULL, '', '0', '1@qq.com', 2, 4, 'panda', '1', NULL, '0', '2021-12-03 09:46:55', '2022-02-09 13:28:49', NULL, 'panda', '$2a$10$cKFFTCzGOvaIHHJY2K45Zuwt8TD6oPzYi4s5MzYIBAWCLL6ZhouP2', '1', '1,4'); -INSERT INTO `sys_users` VALUES (3, '测试用户', '18435234356', 1, 2, '', '', '0', '342@163.com', 3, 1, 'test', '', '', '0', '2021-12-06 15:16:53', '2022-05-10 19:19:25', NULL, 'test', '$2a$10$4cHTracxWJLdhMmazvbm1urKyD3v5N2AYxAFtNYh6juU39kgae73e', '2', '1,4'); -INSERT INTO `sys_users` VALUES (4, 'panda', '18353366912', 1, 2, '', '', '0', '2417920382@qq.com', 2, 4, 'panda', '', '', '0', '2021-12-19 15:58:09', '2021-12-19 16:06:54', NULL, 'admin', '$2a$10$cKFFTCzGOvaIHHJY2K45Zuwt8TD6oPzYi4s5MzYIBAWCLL6ZhouP2', '2', '4,1'); -INSERT INTO `sys_users` VALUES (5, 'tenant', '', 1, 1, '', '', '0', '', 3, 1, 'panda', '1', '', '0', '2021-12-03 09:46:55', '2022-02-09 13:28:49', NULL, 'tenant', '$2a$10$ycRsRdsrNQInLB2Ib0maOetsWZ0kFctmF6ytAErWTjOx5cWdeJMcK', '1', '1,4'); - -SET FOREIGN_KEY_CHECKS = 1; diff --git a/resource/pandax-pg.sql b/resource/pandax-pg.sql deleted file mode 100644 index 41689d108f9ab9e53493ad76fa11ca42fbe52f07..0000000000000000000000000000000000000000 --- a/resource/pandax-pg.sql +++ /dev/null @@ -1,1346 +0,0 @@ -/* - Navicat Premium Data Transfer - - Source Server : localhost_pg - Source Server Type : PostgreSQL - Source Server Version : 120001 - Source Host : localhost:5432 - Source Catalog : pandax - Source Schema : public - - Target Server Type : PostgreSQL - Target Server Version : 120001 - File Encoding : 65001 - - Date: 01/01/2022 13:53:04 -*/ - - -CREATE SEQUENCE IF NOT EXISTS "casbin_rule_id_seq"; - --- ---------------------------- --- Table structure for casbin_rule --- ---------------------------- -DROP TABLE IF EXISTS "public"."casbin_rule"; -CREATE SEQUENCE IF NOT EXISTS "casbin_rule_id_seq"; -CREATE TABLE "public"."casbin_rule" ( - "ptype" varchar(100) COLLATE "pg_catalog"."default", - "v0" varchar(100) COLLATE "pg_catalog"."default", - "v1" varchar(100) COLLATE "pg_catalog"."default", - "v2" varchar(100) COLLATE "pg_catalog"."default", - "v3" varchar(100) COLLATE "pg_catalog"."default", - "v4" varchar(100) COLLATE "pg_catalog"."default", - "v5" varchar(100) COLLATE "pg_catalog"."default", - "id" int8 NOT NULL DEFAULT nextval('casbin_rule_id_seq'::regclass) -) -; - --- ---------------------------- --- Records of casbin_rule --- ---------------------------- -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/gen/code/:tableId', 'GET', '', '', 2190); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/gen/configure/:tableId', 'GET', '', '', 2191); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/gen/preview/:tableId', 'GET', '', '', 2189); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table', 'POST', '', '', 2186); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table', 'PUT', '', '', 2187); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table/:tableId', 'DELETE', '', '', 2188); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table/db/list', 'GET', '', '', 2181); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table/info/:tableId', 'GET', '', '', 2183); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table/info/tableName', 'GET', '', '', 2184); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table/list', 'GET', '', '', 2182); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/develop/code/table/tableTree', 'GET', '', '', 2185); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job', 'POST', '', '', 2193); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job', 'PUT', '', '', 2194); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job/:jobId', 'DELETE', '', '', 2196); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job/:jobId', 'GET', '', '', 2195); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job/changeStatus', 'PUT', '', '', 2199); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job/list', 'GET', '', '', 2192); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job/start/:jobId', 'GET', '', '', 2198); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/job/stop/:jobId', 'GET', '', '', 2197); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logJob/:logId', 'DELETE', '', '', 2208); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logJob/all', 'DELETE', '', '', 2207); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logJob/list', 'GET', '', '', 2206); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logLogin/:infoId', 'DELETE', '', '', 2201); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logLogin/all', 'DELETE', '', '', 2202); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logLogin/list', 'GET', '', '', 2200); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logOper/:operId', 'DELETE', '', '', 2204); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logOper/all', 'DELETE', '', '', 2205); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/log/logOper/list', 'GET', '', '', 2203); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email', 'POST', '', '', 2211); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email', 'PUT', '', '', 2212); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email/:mailId', 'DELETE', '', '', 2213); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email/:mailId', 'GET', '', '', 2210); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email/changeStatus', 'PUT', '', '', 2214); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email/debugMail', 'POST', '', '', 2215); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/email/list', 'GET', '', '', 2209); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss', 'POST', '', '', 2231); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss', 'PUT', '', '', 2232); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss/:ossId', 'DELETE', '', '', 2233); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss/:ossId', 'GET', '', '', 2230); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss/changeStatus', 'PUT', '', '', 2234); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss/list', 'GET', '', '', 2229); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/resource/oss/uploadFile', 'POST', '', '', 2235); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api', 'POST', '', '', 2153); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api', 'PUT', '', '', 2154); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api/:id', 'DELETE', '', '', 2155); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api/:id', 'GET', '', '', 2152); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api/all', 'GET', '', '', 2150); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api/getPolicyPathByRoleId', 'GET', '', '', 2151); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/api/list', 'GET', '', '', 2149); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/config', 'POST', '', '', 2159); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/config', 'PUT', '', '', 2160); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/config/:configId', 'DELETE', '', '', 2161); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/config/:configId', 'GET', '', '', 2158); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/config/configKey', 'GET', '', '', 2157); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/config/list', 'GET', '', '', 2156); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept', 'POST', '', '', 2166); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept', 'PUT', '', '', 2167); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept/:deptId', 'DELETE', '', '', 2168); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept/:deptId', 'GET', '', '', 2163); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept/deptTree', 'GET', '', '', 2165); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept/list', 'GET', '', '', 2162); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dept/roleDeptTreeSelect/:roleId', 'GET', '', '', 2164); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/data', 'POST', '', '', 2178); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/data', 'PUT', '', '', 2179); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/data/:dictCode', 'DELETE', '', '', 2180); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/data/:dictCode', 'GET', '', '', 2177); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/data/list', 'GET', '', '', 2175); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/data/type', 'GET', '', '', 2176); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/type', 'POST', '', '', 2171); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/type', 'PUT', '', '', 2172); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/type/:dictId', 'DELETE', '', '', 2173); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/type/:dictId', 'GET', '', '', 2170); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/type/export', 'GET', '', '', 2174); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/dict/type/list', 'GET', '', '', 2169); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu', 'POST', '', '', 2222); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu', 'PUT', '', '', 2223); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/:menuId', 'DELETE', '', '', 2224); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/:menuId', 'GET', '', '', 2221); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/list', 'GET', '', '', 2220); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/menuPaths', 'GET', '', '', 2219); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/menuRole', 'GET', '', '', 2217); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/menuTreeSelect', 'GET', '', '', 2216); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/menu/roleMenuTreeSelect/:roleId', 'GET', '', '', 2218); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/notice', 'POST', '', '', 2226); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/notice', 'PUT', '', '', 2227); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/notice/:noticeId', 'DELETE', '', '', 2228); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/notice/list', 'GET', '', '', 2225); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/post', 'POST', '', '', 2238); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/post', 'PUT', '', '', 2239); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/post/:postId', 'DELETE', '', '', 2240); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/post/:postId', 'GET', '', '', 2237); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/post/list', 'GET', '', '', 2236); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role', 'POST', '', '', 2243); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role', 'PUT', '', '', 2244); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role/:roleId', 'DELETE', '', '', 2245); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role/:roleId', 'GET', '', '', 2242); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role/changeStatus', 'PUT', '', '', 2246); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role/dataScope', 'PUT', '', '', 2247); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role/export', 'GET', '', '', 2248); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/role/list', 'GET', '', '', 2241); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/tenant', 'POST', '', '', 2251); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/tenant', 'PUT', '', '', 2252); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/tenant/:tenantId', 'DELETE', '', '', 2253); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/tenant/:tenantId', 'GET', '', '', 2250); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/tenant/list', 'GET', '', '', 2249); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/tenant/lists', 'GET', '', '', 2254); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user', 'POST', '', '', 2263); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user', 'PUT', '', '', 2264); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/:userId', 'DELETE', '', '', 2257); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/avatar', 'POST', '', '', 2258); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/changeStatus', 'PUT', '', '', 2256); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/export', 'GET', '', '', 2265); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/getById/:userId', 'GET', '', '', 2260); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/getInit', 'GET', '', '', 2261); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/getRoPo', 'GET', '', '', 2262); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/list', 'GET', '', '', 2255); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'admin', '/system/user/pwd', 'PUT', '', '', 2259); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/develop/code/gen/preview/:tableId', 'GET', '', '', 2287); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/develop/code/table/db/list', 'GET', '', '', 2282); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/develop/code/table/info/:tableId', 'GET', '', '', 2284); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/develop/code/table/info/tableName', 'GET', '', '', 2285); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/develop/code/table/list', 'GET', '', '', 2283); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/develop/code/table/tableTree', 'GET', '', '', 2286); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/job/:jobId', 'GET', '', '', 2289); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/job/list', 'GET', '', '', 2288); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/log/logJob/list', 'GET', '', '', 2292); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/log/logLogin/list', 'GET', '', '', 2290); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/log/logOper/list', 'GET', '', '', 2291); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/resource/email/:mailId', 'GET', '', '', 2294); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/resource/email/list', 'GET', '', '', 2293); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/resource/oss/:ossId', 'GET', '', '', 2303); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/resource/oss/list', 'GET', '', '', 2302); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/api/:id', 'GET', '', '', 2269); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/api/all', 'GET', '', '', 2267); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/api/getPolicyPathByRoleId', 'GET', '', '', 2268); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/api/list', 'GET', '', '', 2266); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/config/:configId', 'GET', '', '', 2272); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/config/configKey', 'GET', '', '', 2271); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/config/list', 'GET', '', '', 2270); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dept/:deptId', 'GET', '', '', 2274); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dept/deptTree', 'GET', '', '', 2276); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dept/list', 'GET', '', '', 2273); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dept/roleDeptTreeSelect/:roleId', 'GET', '', '', 2275); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dict/data/:dictCode', 'GET', '', '', 2281); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dict/data/list', 'GET', '', '', 2279); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dict/data/type', 'GET', '', '', 2280); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dict/type/:dictId', 'GET', '', '', 2278); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/dict/type/list', 'GET', '', '', 2277); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/menu/:menuId', 'GET', '', '', 2300); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/menu/list', 'GET', '', '', 2299); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/menu/menuPaths', 'GET', '', '', 2298); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/menu/menuRole', 'GET', '', '', 2296); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/menu/menuTreeSelect', 'GET', '', '', 2295); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/menu/roleMenuTreeSelect/:roleId', 'GET', '', '', 2297); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/notice/list', 'GET', '', '', 2301); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/post/:postId', 'GET', '', '', 2305); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/post/list', 'GET', '', '', 2304); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/role/:roleId', 'GET', '', '', 2307); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/role/list', 'GET', '', '', 2306); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/tenant/:tenantId', 'GET', '', '', 2309); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/tenant/list', 'GET', '', '', 2308); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/tenant/lists', 'GET', '', '', 2310); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/user/getById/:userId', 'GET', '', '', 2312); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/user/getInit', 'GET', '', '', 2313); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/user/getRoPo', 'GET', '', '', 2314); -INSERT INTO "public"."casbin_rule" VALUES ('p', '1', 'manage', '/system/user/list', 'GET', '', '', 2311); - - --- ---------------------------- --- Table structure for dev_gen_table_columns --- ---------------------------- -DROP TABLE IF EXISTS "public"."dev_gen_table_columns"; -CREATE SEQUENCE IF NOT EXISTS "dev_gen_table_columns_column_id_seq"; -CREATE TABLE "public"."dev_gen_table_columns" ( - "column_id" int8 NOT NULL DEFAULT nextval('dev_gen_table_columns_column_id_seq'::regclass), - "table_id" int8, - "table_name" text COLLATE "pg_catalog"."default", - "column_name" text COLLATE "pg_catalog"."default", - "column_comment" text COLLATE "pg_catalog"."default", - "column_type" text COLLATE "pg_catalog"."default", - "column_key" text COLLATE "pg_catalog"."default", - "go_type" text COLLATE "pg_catalog"."default", - "go_field" text COLLATE "pg_catalog"."default", - "json_field" text COLLATE "pg_catalog"."default", - "html_field" text COLLATE "pg_catalog"."default", - "is_pk" text COLLATE "pg_catalog"."default", - "is_increment" text COLLATE "pg_catalog"."default", - "is_required" text COLLATE "pg_catalog"."default", - "is_insert" text COLLATE "pg_catalog"."default", - "is_edit" text COLLATE "pg_catalog"."default", - "is_list" text COLLATE "pg_catalog"."default", - "is_query" text COLLATE "pg_catalog"."default", - "query_type" text COLLATE "pg_catalog"."default", - "html_type" text COLLATE "pg_catalog"."default", - "dict_type" text COLLATE "pg_catalog"."default", - "sort" int8, - "link_table_name" text COLLATE "pg_catalog"."default", - "link_table_class" text COLLATE "pg_catalog"."default", - "link_table_package" text COLLATE "pg_catalog"."default", - "link_label_id" text COLLATE "pg_catalog"."default", - "link_label_name" text COLLATE "pg_catalog"."default" -) -; - --- ---------------------------- --- Records of dev_gen_table_columns --- ---------------------------- - --- ---------------------------- --- Table structure for dev_gen_tables --- ---------------------------- -DROP TABLE IF EXISTS "public"."dev_gen_tables"; -CREATE SEQUENCE IF NOT EXISTS "dev_gen_tables_table_id_seq"; -CREATE TABLE "public"."dev_gen_tables" ( - "table_id" int8 NOT NULL DEFAULT nextval('dev_gen_tables_table_id_seq'::regclass), - "table_name" text COLLATE "pg_catalog"."default", - "table_comment" text COLLATE "pg_catalog"."default", - "class_name" text COLLATE "pg_catalog"."default", - "tpl_category" text COLLATE "pg_catalog"."default", - "package_name" text COLLATE "pg_catalog"."default", - "module_name" text COLLATE "pg_catalog"."default", - "business_name" text COLLATE "pg_catalog"."default", - "function_name" text COLLATE "pg_catalog"."default", - "function_author" text COLLATE "pg_catalog"."default", - "options" text COLLATE "pg_catalog"."default", - "remark" text COLLATE "pg_catalog"."default", - "pk_column" text COLLATE "pg_catalog"."default", - "pk_go_field" text COLLATE "pg_catalog"."default", - "pk_json_field" text COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; - --- ---------------------------- --- Records of dev_gen_tables --- ---------------------------- - - --- ---------------------------- --- Table structure for log_jobs --- ---------------------------- -DROP TABLE IF EXISTS "public"."log_jobs"; -CREATE SEQUENCE IF NOT EXISTS "log_jobs_log_id_seq"; -CREATE TABLE "public"."log_jobs" ( - "log_id" int8 NOT NULL DEFAULT nextval('log_jobs_log_id_seq'::regclass), - "name" varchar(128) COLLATE "pg_catalog"."default", - "job_group" varchar(128) COLLATE "pg_catalog"."default", - "entry_id" int8, - "invoke_target" varchar(128) COLLATE "pg_catalog"."default", - "log_info" varchar(255) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."log_jobs"."name" IS '任务名称'; -COMMENT ON COLUMN "public"."log_jobs"."job_group" IS '分组'; -COMMENT ON COLUMN "public"."log_jobs"."entry_id" IS '任务id'; -COMMENT ON COLUMN "public"."log_jobs"."invoke_target" IS '调用方法'; -COMMENT ON COLUMN "public"."log_jobs"."log_info" IS '日志信息'; -COMMENT ON COLUMN "public"."log_jobs"."status" IS '状态'; - --- ---------------------------- --- Records of log_jobs --- ---------------------------- - --- ---------------------------- --- Table structure for log_logins --- ---------------------------- -DROP TABLE IF EXISTS "public"."log_logins"; -CREATE SEQUENCE IF NOT EXISTS "log_logins_info_id_seq"; -CREATE TABLE "public"."log_logins" ( - "info_id" int8 NOT NULL DEFAULT nextval('log_logins_info_id_seq'::regclass), - "username" varchar(128) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "ipaddr" varchar(255) COLLATE "pg_catalog"."default", - "login_location" varchar(255) COLLATE "pg_catalog"."default", - "browser" varchar(255) COLLATE "pg_catalog"."default", - "os" varchar(255) COLLATE "pg_catalog"."default", - "platform" varchar(255) COLLATE "pg_catalog"."default", - "login_time" timestamp(6), - "create_by" varchar(128) COLLATE "pg_catalog"."default", - "update_by" varchar(128) COLLATE "pg_catalog"."default", - "remark" varchar(255) COLLATE "pg_catalog"."default", - "msg" varchar(255) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."log_logins"."username" IS '用户名'; -COMMENT ON COLUMN "public"."log_logins"."status" IS '状态'; -COMMENT ON COLUMN "public"."log_logins"."ipaddr" IS 'ip地址'; -COMMENT ON COLUMN "public"."log_logins"."login_location" IS '归属地'; -COMMENT ON COLUMN "public"."log_logins"."browser" IS '浏览器'; -COMMENT ON COLUMN "public"."log_logins"."os" IS '系统'; -COMMENT ON COLUMN "public"."log_logins"."platform" IS '固件'; -COMMENT ON COLUMN "public"."log_logins"."login_time" IS '登录时间'; -COMMENT ON COLUMN "public"."log_logins"."create_by" IS '创建人'; -COMMENT ON COLUMN "public"."log_logins"."update_by" IS '更新者'; - --- ---------------------------- --- Records of log_logins --- ---------------------------- -INSERT INTO "public"."log_logins" VALUES (1, 'panda', '0', '127.0.0.1', '内部IP', 'Chrome 96.0.4664.110', 'Windows 10', 'Windows', '2022-01-01 12:32:51.697576', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36', '登录成功', '2022-01-01 04:32:51.699189+00', '2022-01-01 04:32:51.699189+00', NULL); -INSERT INTO "public"."log_logins" VALUES (2, 'panda', '0', '127.0.0.1', '内部IP', 'Chrome 96.0.4664.110', 'Windows 10', 'Windows', '2022-01-01 13:50:11.578926', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36', '登录成功', '2022-01-01 05:50:11.580002+00', '2022-01-01 05:50:11.580002+00', NULL); - --- ---------------------------- --- Table structure for log_opers --- ---------------------------- -DROP TABLE IF EXISTS "public"."log_opers"; -CREATE SEQUENCE IF NOT EXISTS "log_opers_oper_id_seq"; -CREATE TABLE "public"."log_opers" ( - "oper_id" int8 NOT NULL DEFAULT nextval('log_opers_oper_id_seq'::regclass), - "title" varchar(128) COLLATE "pg_catalog"."default", - "business_type" varchar(1) COLLATE "pg_catalog"."default", - "method" varchar(255) COLLATE "pg_catalog"."default", - "oper_name" varchar(255) COLLATE "pg_catalog"."default", - "oper_url" varchar(255) COLLATE "pg_catalog"."default", - "oper_ip" varchar(255) COLLATE "pg_catalog"."default", - "oper_location" varchar(255) COLLATE "pg_catalog"."default", - "oper_param" varchar(255) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."log_opers"."title" IS '操作的模块'; -COMMENT ON COLUMN "public"."log_opers"."business_type" IS '0其它 1新增 2修改 3删除'; -COMMENT ON COLUMN "public"."log_opers"."method" IS '请求方法'; -COMMENT ON COLUMN "public"."log_opers"."oper_name" IS '操作人员'; -COMMENT ON COLUMN "public"."log_opers"."oper_url" IS '操作url'; -COMMENT ON COLUMN "public"."log_opers"."oper_ip" IS '操作IP'; -COMMENT ON COLUMN "public"."log_opers"."oper_location" IS '操作地点'; -COMMENT ON COLUMN "public"."log_opers"."oper_param" IS '请求参数'; -COMMENT ON COLUMN "public"."log_opers"."status" IS '0=正常,1=异常'; - --- ---------------------------- --- Records of log_opers --- ---------------------------- -INSERT INTO "public"."log_opers" VALUES (1, '删除部门信息', '3', 'DELETE', 'admin', '/system/dept/7', '127.0.0.1', '内部IP', '', '0', '2022-01-01 03:50:22.688828+00', '2022-01-01 03:50:22.688828+00', NULL); - --- ---------------------------- --- Table structure for sys_apis --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_apis"; -CREATE SEQUENCE IF NOT EXISTS "sys_apis_id_seq"; -CREATE TABLE "public"."sys_apis" ( - "id" int8 NOT NULL DEFAULT nextval('sys_apis_id_seq'::regclass), - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6), - "path" text COLLATE "pg_catalog"."default", - "description" text COLLATE "pg_catalog"."default", - "api_group" text COLLATE "pg_catalog"."default", - "method" text COLLATE "pg_catalog"."default" -) -; -COMMENT ON COLUMN "public"."sys_apis"."path" IS 'api路径'; -COMMENT ON COLUMN "public"."sys_apis"."description" IS 'api中文描述'; -COMMENT ON COLUMN "public"."sys_apis"."api_group" IS 'api组'; -COMMENT ON COLUMN "public"."sys_apis"."method" IS '方法'; - --- ---------------------------- --- Records of sys_apis --- ---------------------------- -INSERT INTO "public"."sys_apis" VALUES (1, '2021-12-09 09:21:04', '2021-12-09 09:21:04', NULL, '/system/user/list', '查询用户列表(分页)', 'user', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (2, '2021-12-09 09:29:36', '2021-12-09 09:29:36', NULL, '/system/user/changeStatus', '修改用户状态', 'user', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (3, '2021-12-09 09:34:37', '2021-12-09 09:34:37', NULL, '/system/user/:userId', '删除用户信息', 'user', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (4, '2021-12-09 09:36:43', '2021-12-09 09:36:43', NULL, '/system/dept/list', '获取部门列表', 'dept', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (5, '2021-12-09 09:37:31', '2021-12-09 09:37:31', NULL, '/system/dept/:deptId', '获取部门信息', 'dept', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (6, '2021-12-09 18:20:32', '2021-12-09 18:20:32', NULL, '/system/user/avatar', '上传头像', 'user', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (7, '2021-12-09 18:21:10', '2021-12-09 18:21:10', NULL, '/system/user/pwd', '修改密码', 'user', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (8, '2021-12-09 18:21:54', '2021-12-09 18:21:54', NULL, '/system/user/getById/:userId', '通过id获取用户信息', 'user', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (9, '2021-12-09 18:58:50', '2021-12-09 18:58:50', NULL, '/system/user/getInit', '获取初始化角色岗位信息(添加用户初始化)', 'user', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (10, '2021-12-09 18:59:43', '2021-12-09 18:59:43', NULL, '/system/user/getRoPo', '获取用户角色岗位信息', 'user', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (11, '2021-12-09 19:00:24', '2021-12-09 19:00:24', NULL, '/system/user', '添加用户信息', 'user', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (12, '2021-12-09 19:00:52', '2021-12-09 19:00:52', NULL, '/system/user', '修改用户信息', 'user', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (13, '2021-12-09 19:02:30', '2021-12-09 19:02:30', NULL, '/system/user/export', '导出用户信息', 'user', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (14, '2021-12-09 19:04:04', '2021-12-09 19:04:04', NULL, '/system/dept/roleDeptTreeSelect/:roleId', '获取角色部门树', 'dept', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (15, '2021-12-09 19:04:48', '2021-12-09 19:04:48', NULL, '/system/dept/deptTree', '获取所有部门树', 'dept', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (16, '2021-12-09 19:07:37', '2021-12-09 19:07:37', NULL, '/system/dept', '添加部门信息', 'dept', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (17, '2021-12-09 19:08:14', '2021-12-09 19:08:14', NULL, '/system/dept', '修改部门信息', 'dept', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (18, '2021-12-09 19:08:40', '2021-12-09 19:08:40', NULL, '/system/dept/:deptId', '删除部门信息', 'dept', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (19, '2021-12-09 19:09:41', '2021-12-09 19:09:41', NULL, '/system/config/list', '获取配置分页列表', 'config', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (20, '2021-12-09 19:10:11', '2021-12-09 19:10:11', NULL, '/system/config/configKey', '获取配置列表通过ConfigKey', 'config', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (21, '2021-12-09 19:10:45', '2021-12-09 19:10:45', NULL, '/system/config/:configId', '获取配置信息', 'config', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (22, '2021-12-09 19:11:22', '2021-12-09 19:11:22', NULL, '/system/config', '添加配置信息', 'config', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (23, '2021-12-09 19:11:41', '2021-12-09 19:11:41', NULL, '/system/config', '修改配置信息', 'config', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (24, '2021-12-09 19:12:28', '2021-12-09 19:12:28', NULL, '/system/config/:configId', '删除配置信息', 'config', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (25, '2021-12-09 19:13:08', '2021-12-09 19:13:08', NULL, '/system/dict/type/list', '获取字典类型分页列表', 'dict', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (26, '2021-12-09 19:13:55', '2021-12-09 19:13:55', NULL, '/system/dict/type/:dictId', '获取字典类型信息', 'dict', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (27, '2021-12-09 19:14:28', '2021-12-09 19:14:28', NULL, '/system/dict/type', '添加字典类型信息', 'dict', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (28, '2021-12-09 19:14:55', '2021-12-09 19:14:55', NULL, '/system/dict/type', '修改字典类型信息', 'dict', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (29, '2021-12-09 19:15:17', '2021-12-09 19:15:17', NULL, '/system/dict/type/:dictId', '删除字典类型信息', 'dict', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (30, '2021-12-09 19:15:50', '2021-12-09 19:15:50', NULL, '/system/dict/type/export', '导出字典类型信息', 'dict', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (31, '2021-12-09 19:16:26', '2021-12-09 19:16:26', NULL, '/system/dict/data/list', '获取字典数据分页列表', 'dict', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (32, '2021-12-09 19:17:01', '2021-12-09 19:17:01', NULL, '/system/dict/data/type', '获取字典数据列表通过字典类型', 'dict', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (33, '2021-12-09 19:17:39', '2021-12-09 19:17:39', NULL, '/system/dict/data/:dictCode', '获取字典数据信息', 'dict', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (34, '2021-12-09 19:18:20', '2021-12-09 19:18:20', NULL, '/system/dict/data', '添加字典数据信息', 'dict', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (35, '2021-12-09 19:18:44', '2021-12-09 19:18:44', NULL, '/system/dict/data', '修改字典数据信息', 'dict', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (36, '2021-12-09 19:19:16', '2021-12-09 19:19:16', NULL, '/system/dict/data/:dictCode', '删除字典数据信息', 'dict', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (37, '2021-12-09 19:21:18', '2021-12-09 19:21:18', NULL, '/system/menu/menuTreeSelect', '获取菜单树', 'menu', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (38, '2021-12-09 19:21:47', '2021-12-09 19:21:47', NULL, '/system/menu/menuRole', '获取角色菜单', 'menu', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (39, '2021-12-09 19:22:42', '2021-12-09 19:22:42', NULL, '/system/menu/roleMenuTreeSelect/:roleId', '获取角色菜单树', 'menu', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (40, '2021-12-09 19:23:17', '2021-12-09 19:23:17', NULL, '/system/menu/menuPaths', '获取角色菜单路径列表', 'menu', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (41, '2021-12-09 19:23:40', '2021-12-09 19:23:40', NULL, '/system/menu/list', '获取菜单列表', 'menu', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (42, '2021-12-09 19:24:09', '2021-12-09 19:24:09', NULL, '/system/menu/:menuId', '获取菜单信息', 'menu', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (43, '2021-12-09 19:24:29', '2021-12-09 19:24:29', NULL, '/system/menu', '添加菜单信息', 'menu', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (44, '2021-12-09 19:24:48', '2021-12-09 19:24:48', NULL, '/system/menu', '修改菜单信息', 'menu', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (45, '2021-12-09 19:25:10', '2021-12-09 19:25:10', NULL, '/system/menu/:menuId', '删除菜单信息', 'menu', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (46, '2021-12-09 19:25:44', '2021-12-09 19:27:06', NULL, '/system/post/list', '获取岗位分页列表', 'post', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (47, '2021-12-09 19:26:55', '2021-12-09 19:26:55', NULL, '/system/post/:postId', '获取岗位信息', 'post', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (48, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post', '添加岗位信息', 'post', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (49, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post', '修改岗位信息', 'post', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (50, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post/:postId', '删除岗位信息', 'post', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (51, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/list', '获取角色分页列表', 'role', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (52, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/:roleId', '获取角色信息', 'role', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (53, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role', '添加角色信息', 'role', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (54, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role', '修改角色信息', 'role', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (55, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/:roleId', '删除角色信息', 'role', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (56, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/changeStatus', '修改角色状态', 'role', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (57, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/dataScope', '修改角色部门权限', 'role', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (58, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/export', '导出角色信息', 'role', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (59, '2021-12-09 19:50:57', '2022-01-19 08:58:20', NULL, '/system/api/list', '获取api分页列表1', 'api', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (60, '2021-12-09 19:51:26', '2021-12-09 19:51:26', NULL, '/system/api/all', '获取所有api', 'api', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (61, '2021-12-09 19:51:54', '2021-12-09 19:51:54', NULL, '/system/api/getPolicyPathByRoleId', '获取角色拥有的api权限', 'api', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (62, '2021-12-09 19:52:14', '2021-12-09 19:52:14', NULL, '/system/api/:id', '获取api信息', 'api', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (63, '2021-12-09 19:52:35', '2021-12-09 19:52:35', NULL, '/system/api', '添加api信息', 'api', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (64, '2021-12-09 19:52:50', '2021-12-09 19:52:50', NULL, '/system/api', '修改api信息', 'api', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (65, '2021-12-09 19:53:07', '2021-12-09 19:53:07', NULL, '/system/api/:id', '删除api信息', 'api', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (66, '2021-12-17 10:51:05', '2021-12-17 10:54:22', NULL, '/log/logLogin/list', '获取登录日志', 'log', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (67, '2021-12-17 10:51:43', '2021-12-17 10:54:28', NULL, '/log/logLogin/:infoId', '删除日志', 'log', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (68, '2021-12-17 10:53:09', '2021-12-17 10:54:34', NULL, '/log/logLogin/all', '清空所有', 'log', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (69, '2021-12-17 10:54:07', '2021-12-17 10:54:07', NULL, '/log/logOper/list', '操作日志列表', 'log', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (70, '2021-12-17 10:53:09', '2021-12-17 10:53:09', NULL, '/log/logOper/:operId', '删除', 'log', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (71, '2021-12-17 10:53:09', '2021-12-17 10:53:09', NULL, '/log/logOper/all', '清空', 'log', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (72, '2021-12-24 15:41:23', '2021-12-24 15:41:23', NULL, '/job/list', '任务列表', 'job', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (73, '2021-12-24 15:41:54', '2021-12-24 15:41:54', NULL, '/job', '添加', 'job', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (74, '2021-12-24 15:42:11', '2021-12-24 15:42:11', NULL, '/job', '修改任务', 'job', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (75, '2021-12-24 15:42:37', '2021-12-24 16:32:21', NULL, '/job/:jobId', '获取任务', 'job', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (76, '2021-12-24 15:43:09', '2021-12-24 16:32:05', NULL, '/job/:jobId', '删除job', 'job', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (77, '2021-12-24 15:43:35', '2021-12-24 16:31:11', NULL, '/job/stop/:jobId', '停止任务', 'job', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (78, '2021-12-24 15:44:09', '2021-12-24 16:30:38', NULL, '/job/start/:jobId', '开始任务', 'job', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (79, '2021-12-24 15:45:03', '2021-12-24 15:46:36', NULL, '/log/logJob/list', '任务日志列表', 'log', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (80, '2021-12-24 15:45:33', '2021-12-24 15:46:43', NULL, '/log/logJob/all', '清空任务日志', 'log', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (81, '2021-12-24 15:46:08', '2021-12-24 16:33:13', NULL, '/log/logJob/:logId', '删除任务日志', 'log', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (82, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice/list', '获取通知分页列表', 'notice', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (83, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice', '添加通知信息', 'notice', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (84, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice', '修改通知信息', 'notice', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (85, '2021-12-24 15:45:33', '2021-12-24 16:33:48', NULL, '/system/notice/:noticeId', '删除通知信息', 'notice', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (86, '2021-12-24 22:40:19', '2021-12-24 22:40:19', NULL, '/job/changeStatus', '修改状态', 'job', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (88, '2022-01-02 13:53:06', '2022-07-18 10:57:58', NULL, '/develop/code/table/db/list', '数据库表列表', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (89, '2022-01-02 13:53:44', '2022-01-02 13:53:44', NULL, '/develop/code/table/list', '表列表', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (90, '2022-01-02 13:54:10', '2022-01-02 13:54:10', NULL, '/develop/code/table/info/:tableId', '表信息', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (91, '2022-01-02 13:54:42', '2022-07-18 10:58:35', NULL, '/develop/code/table/info/tableName', '表名获取表信息', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (92, '2022-01-02 13:55:13', '2022-01-02 13:55:13', NULL, '/develop/code/table/tableTree', '表树', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (93, '2022-01-02 13:56:37', '2022-01-02 13:56:37', NULL, '/develop/code/table', '导入表', 'gen', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (94, '2022-01-02 13:57:36', '2022-01-02 13:57:36', NULL, '/develop/code/table', '修改代码生成信息', 'gen', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (95, '2022-01-02 13:58:25', '2022-01-02 13:58:25', NULL, '/develop/code/table/:tableId', '删除表数据', 'gen', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (96, '2022-01-02 13:59:07', '2022-01-02 13:59:07', NULL, '/develop/code/gen/preview/:tableId', '预览代码', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (97, '2022-01-02 13:59:43', '2022-01-02 13:59:43', NULL, '/develop/code/gen/code/:tableId', '生成代码', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (98, '2022-01-02 14:00:10', '2022-07-17 01:19:42', NULL, '/develop/code/gen/configure/:tableId', '生成api菜单', 'gen', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (99, '2022-01-13 16:44:44', '2022-01-13 16:45:27', NULL, '/resource/oss/list', '获取oss列表', 'oss', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (100, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss/:ossId', '获取oss', 'oss', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (101, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss', '添加oss', 'oss', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (102, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss', '修改oss', 'oss', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (103, '2022-01-13 16:44:44', '2022-01-13 16:44:44', NULL, '/resource/oss/:ossId', '删除oss', 'oss', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (104, '2022-01-14 13:19:21', '2022-01-14 13:19:21', NULL, '/resource/oss/changeStatus', '修改状态', 'oss', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (105, '2022-01-14 13:20:14', '2022-01-14 13:20:14', NULL, '/resource/oss/uploadFile', '调试上传文件', 'oss', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (106, '2022-01-14 15:30:39', '2022-01-14 15:30:39', NULL, '/resource/email/list', '邮件分页列表', 'mail', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (107, '2022-01-14 15:31:20', '2022-01-14 15:31:20', NULL, '/resource/email/:mailId', '获取邮件', 'mail', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (108, '2022-01-14 15:31:54', '2022-01-14 15:31:54', NULL, '/resource/email', '添加邮件配置', 'mail', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (109, '2022-01-14 15:32:21', '2022-01-14 15:32:21', NULL, '/resource/email', '修改邮件配置', 'mail', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (110, '2022-01-14 15:32:53', '2022-01-14 15:32:53', NULL, '/resource/email/:mailId', '删除邮件', 'mail', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (111, '2022-01-14 17:11:42', '2022-01-14 17:11:42', NULL, '/resource/email/changeStatus', '修改状态', 'mail', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (112, '2022-01-14 17:12:17', '2022-01-14 17:12:17', NULL, '/resource/email/debugMail', '发送邮件调试', 'mail', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (113, '2022-07-15 18:06:27', '2022-07-15 18:06:27', NULL, '/system/tenant/list', '租户列表', 'tenant', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (114, '2022-07-15 18:07:16', '2022-07-15 18:07:16', NULL, '/system/tenant/:tenantId', '获取租户', 'tenant', 'GET'); -INSERT INTO "public"."sys_apis" VALUES (115, '2022-07-15 18:07:43', '2022-07-15 18:07:43', NULL, '/system/tenant', '添加租户', 'tenant', 'POST'); -INSERT INTO "public"."sys_apis" VALUES (116, '2022-07-15 18:08:08', '2022-07-15 18:08:08', NULL, '/system/tenant', '修改租户', 'tenant', 'PUT'); -INSERT INTO "public"."sys_apis" VALUES (117, '2022-07-15 18:08:57', '2022-07-15 18:08:57', NULL, '/system/tenant/:tenantId', '删除租户', 'tenant', 'DELETE'); -INSERT INTO "public"."sys_apis" VALUES (123, '2022-07-18 10:24:03', '2022-07-18 10:24:03', NULL, '/system/tenant/lists', '获取所有租户', 'tenant', 'GET'); --- ---------------------------- --- Table structure for sys_configs --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_configs"; -CREATE SEQUENCE IF NOT EXISTS "sys_configs_config_id_seq"; -CREATE TABLE "public"."sys_configs" ( - "config_id" int8 NOT NULL DEFAULT nextval('sys_configs_config_id_seq'::regclass), - "config_name" varchar(128) COLLATE "pg_catalog"."default", - "config_key" varchar(128) COLLATE "pg_catalog"."default", - "config_value" varchar(255) COLLATE "pg_catalog"."default", - "config_type" varchar(64) COLLATE "pg_catalog"."default", - "is_frontend" varchar(1) COLLATE "pg_catalog"."default", - "remark" varchar(128) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_configs"."config_id" IS '主键编码'; -COMMENT ON COLUMN "public"."sys_configs"."config_name" IS 'ConfigName'; -COMMENT ON COLUMN "public"."sys_configs"."config_key" IS 'ConfigKey'; -COMMENT ON COLUMN "public"."sys_configs"."config_value" IS 'ConfigValue'; -COMMENT ON COLUMN "public"."sys_configs"."config_type" IS '是否系统内置0,1'; -COMMENT ON COLUMN "public"."sys_configs"."is_frontend" IS '是否前台'; -COMMENT ON COLUMN "public"."sys_configs"."remark" IS 'Remark'; - --- ---------------------------- --- Records of sys_configs --- ---------------------------- -INSERT INTO "public"."sys_configs" VALUES (1, '账号初始密码', 'sys.user.initPassword', '123456', '0', '0', '初始密码', '2021-12-04 13:50:13+00', '2021-12-04 13:54:52+00', NULL); - --- ---------------------------- --- Table structure for sys_depts --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_depts"; -CREATE SEQUENCE IF NOT EXISTS "sys_depts_dept_id_seq"; -CREATE TABLE "public"."sys_depts" ( - "dept_id" int8 NOT NULL DEFAULT nextval('sys_depts_dept_id_seq'::regclass), - "tenant_id" int8 NULL DEFAULT NULL, - "parent_id" int8 NULL DEFAULT NULL, - "dept_path" varchar(255) COLLATE "pg_catalog"."default", - "dept_name" varchar(128) COLLATE "pg_catalog"."default", - "sort" int8, - "leader" varchar(64) COLLATE "pg_catalog"."default", - "phone" varchar(11) COLLATE "pg_catalog"."default", - "email" varchar(64) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "create_by" varchar(64) COLLATE "pg_catalog"."default", - "update_by" varchar(64) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_depts"."parent_id" IS '上级部门'; -COMMENT ON COLUMN "public"."sys_depts"."dept_path" IS '部门路径'; -COMMENT ON COLUMN "public"."sys_depts"."dept_name" IS '部门名称'; -COMMENT ON COLUMN "public"."sys_depts"."sort" IS '排序'; -COMMENT ON COLUMN "public"."sys_depts"."leader" IS '负责人'; -COMMENT ON COLUMN "public"."sys_depts"."phone" IS '手机'; -COMMENT ON COLUMN "public"."sys_depts"."email" IS '邮箱'; -COMMENT ON COLUMN "public"."sys_depts"."status" IS '状态'; -COMMENT ON COLUMN "public"."sys_depts"."create_by" IS '创建人'; -COMMENT ON COLUMN "public"."sys_depts"."update_by" IS '修改人'; - --- ---------------------------- --- Records of sys_depts --- ---------------------------- -INSERT INTO "public"."sys_depts" VALUES (2,1, 0, '/0/2', '熊猫科技', 0, 'xm', '18353366836', '342@qq.com', '0', 'admin', 'admin', '2021-12-01 17:31:53+00', '2021-12-02 08:56:19+00', NULL); -INSERT INTO "public"."sys_depts" VALUES (3,1, 2, '/0/2/3', '研发部', 1, 'panda', '18353366543', 'ewr@qq.com', '0', 'admin', 'admin', '2021-12-01 17:37:43+00', '2021-12-02 08:55:56+00', NULL); -INSERT INTO "public"."sys_depts" VALUES (7,1, 2, '/0/2/7', '营销部', 2, 'panda', '18353333333', '342@qq.com', '0', 'panda', 'panda', '2021-12-24 10:46:24+00', '2021-12-24 10:47:15+00', NULL); - --- ---------------------------- --- Table structure for sys_dict_data --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_dict_data"; -CREATE SEQUENCE IF NOT EXISTS "sys_dict_data_dict_code_seq"; -CREATE TABLE "public"."sys_dict_data" ( - "dict_code" int8 NOT NULL DEFAULT nextval('sys_dict_data_dict_code_seq'::regclass), - "dict_sort" int8, - "dict_label" varchar(64) COLLATE "pg_catalog"."default", - "dict_value" varchar(64) COLLATE "pg_catalog"."default", - "dict_type" varchar(64) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "css_class" varchar(128) COLLATE "pg_catalog"."default", - "list_class" varchar(128) COLLATE "pg_catalog"."default", - "is_default" varchar(8) COLLATE "pg_catalog"."default", - "create_by" text COLLATE "pg_catalog"."default", - "update_by" text COLLATE "pg_catalog"."default", - "remark" varchar(256) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_dict_data"."dict_sort" IS '排序'; -COMMENT ON COLUMN "public"."sys_dict_data"."dict_label" IS '标签'; -COMMENT ON COLUMN "public"."sys_dict_data"."dict_value" IS '值'; -COMMENT ON COLUMN "public"."sys_dict_data"."dict_type" IS '字典类型'; -COMMENT ON COLUMN "public"."sys_dict_data"."status" IS '状态(0正常 1停用)'; -COMMENT ON COLUMN "public"."sys_dict_data"."css_class" IS 'CssClass'; -COMMENT ON COLUMN "public"."sys_dict_data"."list_class" IS 'ListClass'; -COMMENT ON COLUMN "public"."sys_dict_data"."is_default" IS 'IsDefault'; -COMMENT ON COLUMN "public"."sys_dict_data"."remark" IS '备注'; - --- ---------------------------- --- Records of sys_dict_data --- ---------------------------- -INSERT INTO "public"."sys_dict_data" VALUES (1, 0, '男', '0', 'sys_user_sex', '0', '', '', '', 'admin', '', '男', '2021-11-30 14:58:18+00', '2021-11-30 14:58:18+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (2, 1, '女', '1', 'sys_user_sex', '0', '', '', '', 'admin', '', '女生', '2021-11-30 15:09:11+00', '2021-11-30 15:10:28+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (3, 2, '未知', '2', 'sys_user_sex', '0', '', '', '', 'admin', '', '未知', '2021-11-30 15:09:11+00', '2021-11-30 15:10:28+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (4, 0, '正常', '0', 'sys_normal_disable', '0', '', '', '', 'admin', '', '', '2021-12-01 15:58:50+00', '2021-12-01 15:58:50+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (5, 1, '停用', '1', 'sys_normal_disable', '0', '', '', '', 'admin', '', '', '2021-12-01 15:59:08+00', '2021-12-01 15:59:08+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (6, 0, '目录', 'M', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:12+00', '2021-12-02 09:49:12+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (7, 1, '菜单', 'C', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:35+00', '2021-12-02 09:49:52+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (8, 2, '按钮', 'F', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:35+00', '2021-12-02 09:49:35+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (9, 0, '显示', '0', 'sys_show_hide', '0', '', '', '', 'admin', '', '', '2021-12-02 09:56:40+00', '2021-12-02 09:56:40+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (10, 0, '隐藏', '1', 'sys_show_hide', '0', '', '', '', 'admin', '', '', '2021-12-02 09:56:52+00', '2021-12-02 09:56:52+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (11, 0, '是', '0', 'sys_num_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-02 10:16:16+00', '2021-12-02 10:16:16+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (12, 1, '否', '1', 'sys_num_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-02 10:16:26+00', '2021-12-02 10:16:26+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (13, 0, '是', '0', 'sys_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-04 13:48:15+00', '2021-12-04 13:48:15+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (14, 0, '否', '1', 'sys_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-04 13:48:21+00', '2021-12-04 13:48:21+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (15, 0, '创建(POST)', 'POST', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:05+00', '2021-12-09 09:29:52+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (16, 1, '查询(GET)', 'GET', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:24+00', '2021-12-09 09:29:59+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (17, 2, '修改(PUT)', 'PUT', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:40+00', '2021-12-09 09:30:06+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (18, 3, '删除(DELETE)', 'DELETE', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:54+00', '2021-12-09 09:30:13+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (19, 0, '成功', '0', 'sys_common_status', '0', '', '', '', 'admin', '', '', '2021-12-17 11:01:52+00', '2021-12-17 11:01:52+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (20, 0, '失败', '1', 'sys_common_status', '0', '', '', '', 'admin', '', '', '2021-12-17 11:02:08+00', '2021-12-17 11:02:08+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (21, 0, '其他', '0', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:07+00', '2021-12-17 11:30:07+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (22, 0, '新增', '1', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:21+00', '2021-12-17 11:30:21+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (23, 0, '修改', '2', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:32+00', '2021-12-17 11:30:32+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (24, 0, '删除', '3', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:40+00', '2021-12-17 11:30:40+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (25, 0, '默认', 'DEFAULT', 'sys_job_group', '0', '', '', '', 'panda', '', '', '2021-12-24 15:15:31+00', '2021-12-24 15:15:31+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (26, 1, '系统', 'SYSTEM', 'sys_job_group', '0', '', '', '', 'panda', '', '', '2021-12-24 15:15:50+00', '2021-12-24 15:15:50+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (27, 0, '发布通知', '1', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:07+00', '2021-12-26 15:24:07+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (28, 0, '任免通知', '2', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:18+00', '2021-12-26 15:24:18+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (29, 0, '事物通知', '3', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:46+00', '2021-12-26 15:24:46+00', NULL); -INSERT INTO "public"."sys_dict_data" VALUES (30, 0, '审批通知', '4', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:25:08+00', '2021-12-26 15:25:08+00', NULL); - --- ---------------------------- --- Table structure for sys_dict_types --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_dict_types"; -CREATE SEQUENCE IF NOT EXISTS "sys_dict_types_dict_id_seq"; -CREATE TABLE "public"."sys_dict_types" ( - "dict_id" int8 NOT NULL DEFAULT nextval('sys_dict_types_dict_id_seq'::regclass), - "dict_name" varchar(64) COLLATE "pg_catalog"."default", - "dict_type" varchar(64) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "create_by" text COLLATE "pg_catalog"."default", - "update_by" text COLLATE "pg_catalog"."default", - "remark" varchar(256) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_dict_types"."dict_name" IS '名称'; -COMMENT ON COLUMN "public"."sys_dict_types"."dict_type" IS '类型'; -COMMENT ON COLUMN "public"."sys_dict_types"."status" IS '状态'; -COMMENT ON COLUMN "public"."sys_dict_types"."remark" IS '备注'; - --- ---------------------------- --- Records of sys_dict_types --- ---------------------------- -INSERT INTO "public"."sys_dict_types" VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '', '性别列表', '2021-11-30 14:02:52+00', '2021-11-30 14:07:55+00', '2021-11-30 14:11:54+00'); -INSERT INTO "public"."sys_dict_types" VALUES (2, '用户性别', 'sys_user_sex', '0', 'admin', '', '用户性别列表', '2021-11-30 14:12:33+00', '2021-11-30 14:12:33+00', '2021-11-30 14:14:19+00'); -INSERT INTO "public"."sys_dict_types" VALUES (3, '的心', 'sfd', '0', 'admin', '', 'fs', '2021-11-30 14:13:22+00', '2021-11-30 14:13:22+00', '2021-11-30 14:14:19+00'); -INSERT INTO "public"."sys_dict_types" VALUES (4, '用户性别', 'sys_user_sex', '0', 'admin', '', '性别字典', '2021-11-30 14:15:25+00', '2021-11-30 14:15:25+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (5, 'df', 'da', '0', 'admin', '', 'sd', '2021-11-30 15:54:33+00', '2021-11-30 15:54:33+00', '2021-11-30 15:54:40+00'); -INSERT INTO "public"."sys_dict_types" VALUES (6, '系统开关', 'sys_normal_disable', '0', 'admin', '', '开关列表', '2021-12-01 15:57:58+00', '2021-12-01 15:57:58+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (7, '菜单类型', 'sys_menu_type', '0', 'admin', '', '菜单类型列表', '2021-12-02 09:48:48+00', '2021-12-02 09:56:12+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (8, '菜单状态', 'sys_show_hide', '0', 'admin', '', '菜单状态列表', '2021-12-02 09:55:59+00', '2021-12-02 09:55:59+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (9, '数字是否', 'sys_num_yes_no', '0', 'admin', '', '数字是否列表', '2021-12-02 10:13:29+00', '2021-12-02 10:13:40+00', '2021-12-02 10:15:07+00'); -INSERT INTO "public"."sys_dict_types" VALUES (10, '数字是否', 'sys_num_yes_no', '0', 'admin', '', '数字是否', '2021-12-02 10:13:29+00', '2021-12-02 10:13:29+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (11, '状态是否', 'sys_yes_no', '0', 'admin', '', '状态是否', '2021-12-04 13:47:57+00', '2021-12-04 13:47:57+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (12, '网络请求方法', 'sys_method_api', '0', 'admin', '', '网络请求方法列表', '2021-12-08 17:21:27+00', '2021-12-08 17:21:27+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (13, '成功失败', 'sys_common_status', '0', 'admin', '', '是否成功失败', '2021-12-17 10:10:03+00', '2021-12-17 10:10:03+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (27, '操作分类', 'sys_oper_type', '0', 'admin', '', '操作分类列表', '2021-12-17 11:29:50+00', '2021-12-17 11:29:50+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (28, '任务组', 'sys_job_group', '0', 'panda', '', '系统任务,开机自启', '2021-12-24 15:14:56+00', '2021-12-24 15:14:56+00', NULL); -INSERT INTO "public"."sys_dict_types" VALUES (29, '通知类型', 'sys_notice_type', '0', 'panda', '', '通知类型列表', '2021-12-26 15:23:26+00', '2021-12-26 15:23:26+00', NULL); - --- ---------------------------- --- Table structure for sys_jobs --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_jobs"; -CREATE SEQUENCE IF NOT EXISTS "sys_jobs_job_id_seq"; -CREATE TABLE "public"."sys_jobs" ( - "job_id" int8 NOT NULL DEFAULT nextval('sys_jobs_job_id_seq'::regclass), - "job_name" varchar(255) COLLATE "pg_catalog"."default", - "job_group" varchar(255) COLLATE "pg_catalog"."default", - "job_type" varchar(1) COLLATE "pg_catalog"."default", - "cron_expression" varchar(255) COLLATE "pg_catalog"."default", - "invoke_target" varchar(255) COLLATE "pg_catalog"."default", - "args" varchar(255) COLLATE "pg_catalog"."default", - "misfire_policy" varchar(1) COLLATE "pg_catalog"."default", - "concurrent" varchar(1) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "entry_id" int8, - "create_by" varchar(128) COLLATE "pg_catalog"."default", - "update_by" varchar(128) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_jobs"."create_by" IS '创建人'; -COMMENT ON COLUMN "public"."sys_jobs"."update_by" IS '更新者'; - --- ---------------------------- --- Records of sys_jobs --- ---------------------------- -INSERT INTO "public"."sys_jobs" VALUES (1, 'testcron', 'SYSTEM', '2', ' 0/10 * * * * ?', 'cronHandle', 'aaa', '', '', '1', 0, 'panda', '', '2021-12-24 16:06:09+00', '2021-12-24 22:44:09+00', NULL); - --- ---------------------------- --- Table structure for sys_menus --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_menus"; -CREATE SEQUENCE IF NOT EXISTS "sys_menus_menu_id_seq"; -CREATE TABLE "public"."public"."sys_menus" ( - "menu_id" int8 NOT NULL DEFAULT nextval('sys_menus_menu_id_seq'::regclass), - "menu_name" varchar(128) COLLATE "pg_catalog"."default", - "title" varchar(64) COLLATE "pg_catalog"."default", - "parent_id" int8, - "sort" int8, - "icon" varchar(128) COLLATE "pg_catalog"."default", - "path" varchar(128) COLLATE "pg_catalog"."default", - "component" varchar(255) COLLATE "pg_catalog"."default", - "is_iframe" varchar(1) COLLATE "pg_catalog"."default", - "is_link" varchar(255) COLLATE "pg_catalog"."default", - "menu_type" varchar(1) COLLATE "pg_catalog"."default", - "is_hide" varchar(1) COLLATE "pg_catalog"."default", - "is_keep_alive" varchar(1) COLLATE "pg_catalog"."default", - "is_affix" varchar(1) COLLATE "pg_catalog"."default", - "permission" varchar(32) COLLATE "pg_catalog"."default", - "status" text COLLATE "pg_catalog"."default", - "create_by" varchar(128) COLLATE "pg_catalog"."default", - "update_by" varchar(128) COLLATE "pg_catalog"."default", - "remark" text COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; - --- ---------------------------- --- Records of sys_menus --- ---------------------------- -INSERT INTO "public"."sys_menus" VALUES (1, '系统设置', '', 0, 0, 'elementSetting', '/system', 'Layout', '1', '', 'M', '0', '0', '1', '', '0', 'admin', 'panda', '', '2021-12-02 11:04:08', '2021-12-28 13:32:21', NULL); -INSERT INTO "public"."sys_menus" VALUES (3, '用户管理', '', 1, 1, 'elementUser', '/system/user', '/system/user/index', '1', '', 'C', '0', '1', '1', 'system:user:list', '0', 'admin', 'panda', '', '2021-12-02 14:07:56', '2021-12-28 13:32:44', NULL); -INSERT INTO "public"."sys_menus" VALUES (4, '添加用户', '', 3, 1, '', '', '', '', '', 'F', '0', '', '', 'system:user:add', '0', 'admin', '', '', '2021-12-03 13:36:33', '2021-12-03 13:36:33', NULL); -INSERT INTO "public"."sys_menus" VALUES (5, '编辑用户', '', 3, 1, '', '', '', '', '', 'F', '0', '', '', 'system:user:edit', '0', 'admin', '', '', '2021-12-03 13:48:13', '2021-12-03 13:48:13', NULL); -INSERT INTO "public"."sys_menus" VALUES (6, '角色管理', '', 1, 2, 'elementUserFilled', '/system/role', '/system/role/index', '1', '', 'C', '0', '1', '1', 'system:role:list', '0', '', 'panda', '', '2021-12-03 13:51:55', '2022-07-16 10:23:21', NULL); -INSERT INTO "public"."sys_menus" VALUES (7, '菜单管理', '', 1, 2, 'iconfont icon-juxingkaobei', '/system/menu', '/system/menu/index', '1', '', 'C', '0', '1', '1', 'system:menu:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:33:19', NULL); -INSERT INTO "public"."sys_menus" VALUES (8, '部门管理', '', 1, 3, 'iconfont icon-jiliandongxuanzeqi', '/system/dept', '/system/dept/index', '1', '', 'C', '0', '1', '1', 'system:dept:list', '0', 'admin', 'panda', '', '2021-12-03 13:58:36', '2021-12-28 13:40:20', NULL); -INSERT INTO "public"."sys_menus" VALUES (9, '岗位管理', '', 1, 4, 'iconfont icon-neiqianshujuchucun', '/system/post', '/system/post/index', '1', '', 'C', '0', '1', '1', 'system:post:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:40:31', NULL); -INSERT INTO "public"."sys_menus" VALUES (10, '字典管理', '', 1, 5, 'elementCellphone', '/system/dict', '/system/dict/index', '1', '', 'C', '0', '1', '1', 'system:dict:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:40:50', NULL); -INSERT INTO "public"."sys_menus" VALUES (11, '参数管理', '', 1, 6, 'elementDocumentCopy', '/system/config', '/system/config/index', '1', '', 'C', '0', '1', '1', 'system:config:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:41:05', NULL); -INSERT INTO "public"."sys_menus" VALUES (12, '个人中心', '', 0, 10, 'elementAvatar', '/personal', '/personal/index', '1', '', 'M', '0', '0', '0', '', '0', 'admin', 'panda', '', '2021-12-03 14:12:43', '2021-12-28 13:43:17', NULL); -INSERT INTO "public"."sys_menus" VALUES (13, '添加配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:add', '0', 'admin', '', '', '2021-12-06 17:19:19', '2021-12-06 17:19:19', NULL); -INSERT INTO "public"."sys_menus" VALUES (14, '修改配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:edit', '0', 'admin', '', '', '2021-12-06 17:20:30', '2021-12-06 17:20:30', NULL); -INSERT INTO "public"."sys_menus" VALUES (15, '删除配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:delete', '0', 'admin', '', '', '2021-12-06 17:23:52', '2021-12-06 17:23:52', NULL); -INSERT INTO "public"."sys_menus" VALUES (16, '导出配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:export', '0', 'admin', '', '', '2021-12-06 17:24:41', '2021-12-06 17:24:41', NULL); -INSERT INTO "public"."sys_menus" VALUES (17, '新增角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:add', '0', 'admin', '', '', '2021-12-06 17:43:35', '2021-12-06 17:43:35', NULL); -INSERT INTO "public"."sys_menus" VALUES (18, '删除角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:delete', '0', 'admin', '', '', '2021-12-06 17:44:10', '2021-12-06 17:44:10', NULL); -INSERT INTO "public"."sys_menus" VALUES (19, '修改角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:edit', '0', 'admin', '', '', '2021-12-06 17:44:48', '2021-12-06 17:44:48', NULL); -INSERT INTO "public"."sys_menus" VALUES (20, '导出角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:export', '0', 'admin', '', '', '2021-12-06 17:45:25', '2021-12-06 17:45:25', NULL); -INSERT INTO "public"."sys_menus" VALUES (21, '添加菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:add', '0', 'admin', '', '', '2021-12-06 17:46:01', '2021-12-06 17:46:01', NULL); -INSERT INTO "public"."sys_menus" VALUES (22, '修改菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:edit', '0', 'admin', '', '', '2021-12-06 17:46:24', '2021-12-06 17:46:24', NULL); -INSERT INTO "public"."sys_menus" VALUES (23, '删除菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:delete', '0', 'admin', '', '', '2021-12-06 17:46:47', '2021-12-06 17:46:47', NULL); -INSERT INTO "public"."sys_menus" VALUES (24, '添加部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:add', '0', 'admin', '', '', '2021-12-07 09:33:58', '2021-12-07 09:33:58', NULL); -INSERT INTO "public"."sys_menus" VALUES (25, '编辑部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:edit', '0', 'admin', '', '', '2021-12-07 09:34:39', '2021-12-07 09:34:39', NULL); -INSERT INTO "public"."sys_menus" VALUES (26, '删除部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:delete', '0', 'admin', 'admin', '', '2021-12-07 09:35:09', '2021-12-07 09:36:26', NULL); -INSERT INTO "public"."sys_menus" VALUES (27, '导出部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:export', '0', 'admin', '', '', '2021-12-07 09:35:51', '2021-12-07 09:35:51', '2021-12-07 09:36:37'); -INSERT INTO "public"."sys_menus" VALUES (28, '添加岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (29, '编辑岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:edit', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (30, '删除岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:delete', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (31, '导出岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:export', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (32, '添加字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (33, '编辑字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:edit', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (34, '删除字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:delete', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (35, '导出字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:export', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (36, '新增字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (37, '修改字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:edit', '0', 'admin', '', '', '2021-12-07 09:48:04', '2021-12-07 09:48:04', NULL); -INSERT INTO "public"."sys_menus" VALUES (38, '删除字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:delete', '0', 'admin', '', '', '2021-12-07 09:48:42', '2021-12-07 09:48:42', NULL); -INSERT INTO "public"."sys_menus" VALUES (39, 'API管理', '', 1, 2, 'iconfont icon-siweidaotu', '/system/api', '/system/api/index', '1', '', 'C', '0', '1', '1', 'system:api:list', '0', '', 'panda', '', '2021-12-09 09:09:13', '2022-07-16 10:23:42', NULL); -INSERT INTO "public"."sys_menus" VALUES (40, '添加api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:add', '0', 'admin', '', '', '2021-12-09 09:09:54', '2021-12-09 09:09:54', NULL); -INSERT INTO "public"."sys_menus" VALUES (41, '编辑api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:edit', '0', 'admin', '', '', '2021-12-09 09:10:38', '2021-12-09 09:10:38', NULL); -INSERT INTO "public"."sys_menus" VALUES (42, '删除api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:delete', '0', 'admin', '', '', '2021-12-09 09:11:11', '2021-12-09 09:11:11', NULL); -INSERT INTO "public"."sys_menus" VALUES (43, '日志系统', '', 0, 1, 'iconfont icon-biaodan', '/log', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-02 11:04:08', '2021-12-28 13:38:33', NULL); -INSERT INTO "public"."sys_menus" VALUES (44, '系统工具', '', 0, 2, 'iconfont icon-gongju', '/tool', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-16 16:35:15', '2021-12-28 13:38:46', NULL); -INSERT INTO "public"."sys_menus" VALUES (45, '操作日志', '', 43, 1, 'iconfont icon-bolangnengshiyanchang', '/log/operation', '/log/operation/index', '1', '', 'C', '0', '1', '1', 'log:operation:list', '0', 'admin', 'panda', '', '2021-12-16 16:42:03', '2021-12-28 13:39:44', NULL); -INSERT INTO "public"."sys_menus" VALUES (46, '登录日志', '', 43, 2, 'iconfont icon--chaifenlie', '/log/login', '/log/login/index', '1', '', 'C', '0', '1', '1', 'log:login:list', '0', 'admin', 'panda', '', '2021-12-16 16:43:28', '2021-12-28 13:39:58', NULL); -INSERT INTO "public"."sys_menus" VALUES (47, '服务监控', '', 44, 1, 'elementCpu', '/tool/monitor/', '/tool/monitor/index', '1', '', 'C', '0', '1', '1', 'tool:monitor:list', '0', 'admin', 'panda', '', '2021-12-03 14:12:43', '2021-12-28 13:41:25', NULL); -INSERT INTO "public"."sys_menus" VALUES (48, '定时任务', '', 44, 2, 'elementAlarmClock', '/tool/job', '/tool/job/index', '1', '', 'C', '0', '1', '1', 'tool:job:list', '0', 'admin', 'panda', '', '2021-12-16 16:48:45', '2021-12-28 13:41:59', NULL); -INSERT INTO "public"."sys_menus" VALUES (49, '开发工具', '', 0, 3, 'iconfont icon-diannao', '/develop', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', '', '', '2021-12-16 16:53:11', '2021-12-16 16:53:11', NULL); -INSERT INTO "public"."sys_menus" VALUES (50, '表单构建', '', 49, 1, 'iconfont icon-zidingyibuju', '/develop/form', '/develop/form/index', '1', '', 'C', '0', '1', '1', 'develop:form:list', '0', 'admin', 'panda', '', '2021-12-16 16:55:01', '2022-07-12 18:56:18', NULL); -INSERT INTO "public"."sys_menus" VALUES (51, '代码生成', '', 49, 2, 'iconfont icon-zhongduancanshu', '/develop/code', '/develop/code/index', '1', '', 'C', '0', '1', '1', 'develop:code:list', '0', 'admin', '', '', '2021-12-16 16:56:48', '2021-12-16 16:56:48', NULL); -INSERT INTO "public"."sys_menus" VALUES (52, '系统接口', '', 49, 3, 'iconfont icon-wenducanshu-05', '/develop/apis', '/layout/routerView/iframes', '0', 'http://47.104.252.2:8080/swagger/index.html', 'C', '0', '1', '1', 'develop:apis:list', '0', '', 'panda', '', '2021-12-16 16:58:07', '2022-07-13 11:50:34', NULL); -INSERT INTO "public"."sys_menus" VALUES (53, '资源管理', '', 0, 4, 'iconfont icon-juxingkaobei', '/resource', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', '', '', '2021-12-16 17:02:06', '2021-12-16 17:02:06', NULL); -INSERT INTO "public"."sys_menus" VALUES (54, '对象存储', '', 53, 1, 'iconfont icon-chazhaobiaodanliebiao', '/resource/file', '/resource/file/index', '1', '', 'C', '0', '1', '1', 'resource:file:list', '0', 'admin', 'panda', '', '2021-12-16 17:06:04', '2022-01-13 17:30:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (55, '公告通知', '', 44, 3, 'elementTicket', '/tool/notice', '/tool/notice/index', '1', '', 'C', '0', '1', '1', 'tool:notice:list', '0', 'admin', 'panda', '', '2021-12-16 22:09:11', '2021-12-28 13:42:39', NULL); -INSERT INTO "public"."sys_menus" VALUES (56, '任务日志', '', 43, 1, 'iconfont icon--chaifenhang', '/log/job', '/log/job/index', '1', '', 'C', '0', '1', '1', 'log:job:list', '0', 'panda', 'panda', '', '2021-12-24 22:13:45', '2021-12-28 13:39:52', NULL); -INSERT INTO "public"."sys_menus" VALUES (57, '邮件管理', '', 53, 1, 'iconfont icon-shouye_dongtaihui', '/resource/mail', '/resource/mail/index', '1', '', 'C', '0', '1', '1', 'resource:mail:list', '0', 'panda', 'panda', '', '2021-12-28 15:12:37', '2021-12-28 15:12:45', NULL); -INSERT INTO "public"."sys_menus" VALUES (58, '短信管理', '', 53, 3, 'elementChatDotRound', '/resource/message', '/resource/message/index', '1', '', 'C', '0', '1', '1', 'resource:message:list', '0', 'panda', '', '', '2021-12-16 17:06:04', '2021-12-16 17:06:04', NULL); -INSERT INTO "public"."sys_menus" VALUES (59, '删除', '', 45, 1, '', '', '', '', '', 'F', '', '', '', 'log:operation:delete', '0', 'panda', '', '', '2022-01-14 13:28:25', '2022-01-14 13:28:25', NULL); -INSERT INTO "public"."sys_menus" VALUES (60, '清空', '', 45, 1, '', '', '', '', '', 'F', '', '', '', 'log:operation:clean', '0', 'panda', '', '', '2022-01-14 13:29:24', '2022-01-14 13:29:24', NULL); -INSERT INTO "public"."sys_menus" VALUES (61, '删除', '', 56, 1, '', '', '', '', '', 'F', '', '', '', 'log:job:delete', '0', 'panda', '', '', '2022-01-14 13:29:57', '2022-01-14 13:29:57', NULL); -INSERT INTO "public"."sys_menus" VALUES (62, '清空', '', 56, 1, '', '', '', '', '', 'F', '', '', '', 'log:job:clean', '0', 'panda', '', '', '2022-01-14 13:30:15', '2022-01-14 13:30:15', NULL); -INSERT INTO "public"."sys_menus" VALUES (63, '删除', '', 46, 1, '', '', '', '', '', 'F', '', '', '', 'log:login:delete', '0', 'panda', '', '', '2022-01-14 13:30:46', '2022-01-14 13:30:46', NULL); -INSERT INTO "public"."sys_menus" VALUES (64, '清空', '', 46, 1, '', '', '', '', '', 'F', '', '', '', 'log:login:clean', '0', 'panda', '', '', '2022-01-14 13:31:06', '2022-01-14 13:31:06', NULL); -INSERT INTO "public"."sys_menus" VALUES (65, '新增', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:add', '0', 'panda', '', '', '2022-01-14 13:32:48', '2022-01-14 13:32:48', NULL); -INSERT INTO "public"."sys_menus" VALUES (66, '编辑', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:edit', '0', 'panda', '', '', '2022-01-14 13:33:17', '2022-01-14 13:33:17', NULL); -INSERT INTO "public"."sys_menus" VALUES (67, '删除', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:delete', '0', 'panda', '', '', '2022-01-14 13:33:43', '2022-01-14 13:33:43', NULL); -INSERT INTO "public"."sys_menus" VALUES (68, '开关', '', 48, 1, '', '', '', '', '', 'F', '', '', '', 'tool:job:run', '0', 'panda', '', '', '2022-01-14 13:34:27', '2022-01-14 13:34:27', NULL); -INSERT INTO "public"."sys_menus" VALUES (69, '添加', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:add', '0', 'panda', '', '', '2022-01-14 13:35:23', '2022-01-14 13:35:23', NULL); -INSERT INTO "public"."sys_menus" VALUES (70, '编辑', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:edit', '0', 'panda', '', '', '2022-01-14 13:36:04', '2022-01-14 13:36:04', NULL); -INSERT INTO "public"."sys_menus" VALUES (71, '删除', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:delete', '0', 'panda', '', '', '2022-01-14 13:36:26', '2022-01-14 13:36:26', NULL); -INSERT INTO "public"."sys_menus" VALUES (72, '查看', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:view', '0', 'panda', '', '', '2022-01-14 13:36:51', '2022-01-14 13:36:51', NULL); -INSERT INTO "public"."sys_menus" VALUES (73, '导入', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:add', '0', 'panda', '', '', '2022-01-14 13:38:35', '2022-01-14 13:38:35', NULL); -INSERT INTO "public"."sys_menus" VALUES (74, '编辑', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:edit', '0', 'panda', '', '', '2022-01-14 13:41:25', '2022-01-14 13:41:25', NULL); -INSERT INTO "public"."sys_menus" VALUES (75, '删除', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:delete', '0', 'panda', '', '', '2022-01-14 13:41:42', '2022-01-14 13:41:42', NULL); -INSERT INTO "public"."sys_menus" VALUES (76, '预览', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:view', '0', 'panda', '', '', '2022-01-14 13:42:01', '2022-01-14 13:42:01', NULL); -INSERT INTO "public"."sys_menus" VALUES (77, '生成代码', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:code', '0', 'panda', '', '', '2022-01-14 13:42:48', '2022-01-14 13:42:48', NULL); -INSERT INTO "public"."sys_menus" VALUES (78, '添加', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:add', '0', 'panda', '', '', '2022-01-17 11:26:15', '2022-01-17 11:26:15', NULL); -INSERT INTO "public"."sys_menus" VALUES (79, '编辑', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:edit', '0', 'panda', '', '', '2022-01-17 11:26:39', '2022-01-17 11:26:39', NULL); -INSERT INTO "public"."sys_menus" VALUES (80, '删除', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:delete', '0', 'panda', '', '', '2022-01-17 11:26:56', '2022-01-17 11:26:56', NULL); -INSERT INTO "public"."sys_menus" VALUES (81, '调试', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:debug', '0', 'panda', '', '', '2022-01-17 11:27:14', '2022-01-17 11:27:14', NULL); -INSERT INTO "public"."sys_menus" VALUES (82, '调试', '', 54, 1, '', '', '', '', '', 'F', '', '', '', 'resource:file:debug', '0', 'panda', '', '', '2022-01-17 11:27:17', '2022-01-17 11:27:17', '2022-01-17 11:27:25'); -INSERT INTO "public"."sys_menus" VALUES (83, '添加', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:add', '0', 'panda', '', '', '2022-01-17 11:28:06', '2022-01-17 11:28:06', NULL); -INSERT INTO "public"."sys_menus" VALUES (84, '编辑', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:edit', '0', 'panda', '', '', '2022-01-17 11:28:37', '2022-01-17 11:28:37', NULL); -INSERT INTO "public"."sys_menus" VALUES (85, '删除', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:delete', '0', 'panda', '', '', '2022-01-17 11:29:09', '2022-01-17 11:29:09', NULL); -INSERT INTO "public"."sys_menus" VALUES (86, '调试', '', 57, 1, '', '', '', '', '', 'F', '', '', '', 'resource:mail:debug', '0', 'panda', '', '', '2022-01-17 11:29:46', '2022-01-17 11:29:46', NULL); -INSERT INTO "public"."sys_menus" VALUES (87, '租户管理', '', 1, 1, 'iconfont icon-quanxian', '/system/tenant', '/system/tenant/index', '1', '', 'C', '0', '1', '1', 'system:tenant:list', '0', 'panda', '', '', '2022-07-15 18:03:35', '2022-07-15 18:03:35', NULL); -INSERT INTO "public"."sys_menus" VALUES (88, '添加', '', 87, 1, '', '', '', '', '', 'F', '', '', '', 'system:tenant:add', '0', 'panda', '', '', '2022-07-15 18:28:58', '2022-07-15 18:28:58', NULL); -INSERT INTO "public"."sys_menus" VALUES (89, '编辑', '', 87, 1, '', '', '', '', '', 'F', '', '', '', 'system:tenant:edit', '0', 'panda', '', '', '2022-07-15 18:29:34', '2022-07-15 18:29:34', NULL); -INSERT INTO "public"."sys_menus" VALUES (90, '删除', '', 87, 1, '', '', '', '', '', 'F', '', '', '', 'system:tenant:delete', '0', 'panda', '', '', '2022-07-15 18:30:00', '2022-07-15 18:30:00', NULL); - --- ---------------------------- --- Table structure for sys_notices --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_notices"; -CREATE SEQUENCE IF NOT EXISTS "sys_notices_notice_id_seq"; -CREATE TABLE "public"."sys_notices" ( - "notice_id" int8 NOT NULL DEFAULT nextval('sys_notices_notice_id_seq'::regclass), - "title" varchar(128) COLLATE "pg_catalog"."default", - "content" text COLLATE "pg_catalog"."default", - "notice_type" varchar(1) COLLATE "pg_catalog"."default", - "dept_id" int8, - "user_name" varchar(64) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_notices"."title" IS '标题'; -COMMENT ON COLUMN "public"."sys_notices"."content" IS '标题'; -COMMENT ON COLUMN "public"."sys_notices"."notice_type" IS '通知类型'; -COMMENT ON COLUMN "public"."sys_notices"."dept_id" IS '部门Id,部门及子部门'; -COMMENT ON COLUMN "public"."sys_notices"."user_name" IS '发布人'; - --- ---------------------------- --- Records of sys_notices --- ---------------------------- -INSERT INTO "public"."sys_notices" VALUES (1, '关于学习交流的通知', '

发布入群通知 467890197, 交流学习

', '1', 0, 'panda', '2021-12-26 15:29:25+00', '2021-12-26 16:19:48+00', NULL); -INSERT INTO "public"."sys_notices" VALUES (2, 'test', '

sdsad

', '1', 2, 'panda', '2021-12-26 16:23:13+00', '2021-12-26 16:23:13+00', '2021-12-26 16:31:31+00'); -INSERT INTO "public"."sys_notices" VALUES (3, '版本更新通知:任务功能,通知功能完成', '

', '1', 0, 'panda', '2021-12-26 17:33:47+00', '2021-12-26 17:33:47+00', NULL); - --- ---------------------------- --- Table structure for sys_posts --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_posts"; -CREATE SEQUENCE IF NOT EXISTS "sys_posts_post_id_seq"; -CREATE TABLE "public"."sys_posts" ( - "post_id" int8 NOT NULL DEFAULT nextval('sys_posts_post_id_seq'::regclass), - "tenant_id" int8 NULL DEFAULT NULL, - "post_name" varchar(128) COLLATE "pg_catalog"."default", - "post_code" varchar(128) COLLATE "pg_catalog"."default", - "sort" int8, - "status" varchar(1) COLLATE "pg_catalog"."default", - "remark" varchar(255) COLLATE "pg_catalog"."default", - "create_by" varchar(128) COLLATE "pg_catalog"."default", - "update_by" varchar(128) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_posts"."post_name" IS '岗位名称'; -COMMENT ON COLUMN "public"."sys_posts"."post_code" IS '岗位代码'; -COMMENT ON COLUMN "public"."sys_posts"."sort" IS '岗位排序'; -COMMENT ON COLUMN "public"."sys_posts"."status" IS '状态'; -COMMENT ON COLUMN "public"."sys_posts"."remark" IS '描述'; - --- ---------------------------- --- Records of sys_posts --- ---------------------------- -INSERT INTO "public"."sys_posts" VALUES (1, 1,'首席执行官', 'CEO', 0, '0', '首席执行官', 'admin', '', '2021-12-02 09:21:44+00', '2021-12-02 09:24:25+00', NULL); -INSERT INTO "public"."sys_posts" VALUES (3, 1,'首席技术执行官', 'CTO', 1, '0', '', 'admin', '', '2021-12-02 09:21:44+00', '2021-12-02 09:25:59+00', '2021-12-02 09:27:41+00'); -INSERT INTO "public"."sys_posts" VALUES (4, 1,'首席技术执行官', 'CTO', 1, '0', '', 'admin', '', '2021-12-02 09:21:44+00', '2021-12-02 09:25:59+00', NULL); -INSERT INTO "public"."sys_posts" VALUES (5, 1,'123', '123', 0, '0', '', 'admin', '', '2021-12-18 00:33:28+00', '2021-12-18 00:33:28+00', '2021-12-28 14:11:52+00'); - --- ---------------------------- --- Table structure for sys_role_depts --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_role_depts"; -CREATE SEQUENCE IF NOT EXISTS "sys_role_depts_id_seq"; -CREATE TABLE "public"."sys_role_depts" ( - "role_id" int8, - "dept_id" int8, - "id" int8 NOT NULL DEFAULT nextval('sys_role_depts_id_seq'::regclass) -) -; - --- ---------------------------- --- Records of sys_role_depts --- ---------------------------- -INSERT INTO "public"."sys_role_depts" VALUES (1, 2, 1); -INSERT INTO "public"."sys_role_depts" VALUES (1, 3, 2); - --- ---------------------------- --- Table structure for sys_role_menus --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_role_menus"; -CREATE SEQUENCE IF NOT EXISTS "sys_role_menus_id_seq"; -CREATE TABLE "public"."sys_role_menus" ( - "id" int8 NOT NULL DEFAULT nextval('sys_role_menus_id_seq'::regclass) - "role_id" int8, - "menu_id" int8, - "role_name" varchar(128) COLLATE "pg_catalog"."default", - -) -; - --- ---------------------------- --- Records of sys_role_menus --- ---------------------------- -INSERT INTO "public"."sys_role_menus" VALUES (2870, 1, 1, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2871, 1, 3, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2872, 1, 4, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2873, 1, 5, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2874, 1, 6, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2875, 1, 7, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2876, 1, 8, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2877, 1, 9, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2878, 1, 10, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2879, 1, 11, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2880, 1, 12, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2881, 1, 13, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2882, 1, 14, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2883, 1, 15, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2884, 1, 16, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2885, 1, 17, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2886, 1, 18, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2887, 1, 19, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2888, 1, 20, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2889, 1, 21, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2890, 1, 22, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2891, 1, 23, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2892, 1, 24, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2893, 1, 25, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2894, 1, 26, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2895, 1, 28, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2896, 1, 29, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2897, 1, 30, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2898, 1, 31, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2899, 1, 32, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2900, 1, 33, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2901, 1, 34, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2902, 1, 35, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2903, 1, 36, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2904, 1, 37, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2905, 1, 38, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2906, 1, 39, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2907, 1, 40, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2908, 1, 41, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2909, 1, 42, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2910, 1, 43, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2911, 1, 44, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2912, 1, 45, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2913, 1, 46, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2914, 1, 47, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2915, 1, 48, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2916, 1, 49, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2917, 1, 50, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2918, 1, 51, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2919, 1, 52, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2920, 1, 53, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2921, 1, 54, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2922, 1, 55, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2923, 1, 56, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2924, 1, 57, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2925, 1, 58, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2926, 1, 59, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2927, 1, 60, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2928, 1, 61, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2929, 1, 62, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2930, 1, 63, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2931, 1, 64, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2932, 1, 65, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2933, 1, 66, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2934, 1, 67, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2935, 1, 68, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2936, 1, 69, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2937, 1, 70, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2938, 1, 71, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2939, 1, 72, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2940, 1, 73, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2941, 1, 74, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2942, 1, 75, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2943, 1, 76, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2944, 1, 77, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2945, 1, 78, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2946, 1, 79, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2947, 1, 80, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2948, 1, 81, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2949, 1, 83, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2950, 1, 84, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2951, 1, 85, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2952, 1, 86, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2953, 1, 87, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2954, 1, 88, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2955, 1, 89, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2956, 1, 90, 'admin'); -INSERT INTO "public"."sys_role_menus" VALUES (2957, 2, 1, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2958, 2, 3, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2959, 2, 4, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2960, 2, 5, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2961, 2, 6, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2962, 2, 7, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2963, 2, 8, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2964, 2, 9, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2965, 2, 10, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2966, 2, 11, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2967, 2, 12, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2968, 2, 13, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2969, 2, 14, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2970, 2, 15, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2971, 2, 16, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2972, 2, 17, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2973, 2, 18, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2974, 2, 19, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2975, 2, 20, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2976, 2, 21, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2977, 2, 22, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2978, 2, 23, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2979, 2, 25, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2980, 2, 26, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2981, 2, 28, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2982, 2, 29, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2983, 2, 30, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2984, 2, 31, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2985, 2, 32, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2986, 2, 33, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2987, 2, 34, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2988, 2, 35, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2989, 2, 36, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2990, 2, 37, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2991, 2, 38, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2992, 2, 39, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2993, 2, 40, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2994, 2, 41, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2995, 2, 42, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2996, 2, 43, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2997, 2, 44, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2998, 2, 45, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (2999, 2, 46, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3000, 2, 47, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3001, 2, 48, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3002, 2, 49, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3003, 2, 50, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3004, 2, 51, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3005, 2, 52, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3006, 2, 53, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3007, 2, 54, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3008, 2, 55, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3009, 2, 56, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3010, 2, 57, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3011, 2, 58, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3012, 2, 59, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3013, 2, 60, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3014, 2, 61, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3015, 2, 62, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3016, 2, 63, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3017, 2, 64, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3018, 2, 65, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3019, 2, 66, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3020, 2, 67, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3021, 2, 68, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3022, 2, 69, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3023, 2, 70, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3024, 2, 71, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3025, 2, 72, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3026, 2, 73, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3027, 2, 74, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3028, 2, 75, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3029, 2, 76, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3030, 2, 77, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3031, 2, 78, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3032, 2, 79, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3033, 2, 80, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3034, 2, 81, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3035, 2, 83, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3036, 2, 84, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3037, 2, 85, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3038, 2, 86, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3039, 2, 87, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3040, 2, 88, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3041, 2, 89, 'manage'); -INSERT INTO "public"."sys_role_menus" VALUES (3042, 2, 90, 'manage'); - --- ---------------------------- --- Table structure for sys_roles --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_roles"; -CREATE SEQUENCE IF NOT EXISTS "sys_roles_role_id_seq"; -CREATE TABLE "public"."sys_roles" ( - "role_id" int8 NOT NULL DEFAULT nextval('sys_roles_role_id_seq'::regclass), - "role_name" varchar(128) COLLATE "pg_catalog"."default", - "tenant_id" int8 NULL DEFAULT NULL, - "status" varchar(1) COLLATE "pg_catalog"."default", - "role_key" varchar(128) COLLATE "pg_catalog"."default", - "role_sort" int8, - "data_scope" varchar(1) COLLATE "pg_catalog"."default", - "flag" varchar(128) COLLATE "pg_catalog"."default", - "create_by" varchar(128) COLLATE "pg_catalog"."default", - "update_by" varchar(128) COLLATE "pg_catalog"."default", - "remark" varchar(255) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_roles"."role_name" IS '角色名称'; -COMMENT ON COLUMN "public"."sys_roles"."status" IS '状态'; -COMMENT ON COLUMN "public"."sys_roles"."role_key" IS '角色代码'; -COMMENT ON COLUMN "public"."sys_roles"."role_sort" IS '角色排序'; -COMMENT ON COLUMN "public"."sys_roles"."data_scope" IS '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)'; -COMMENT ON COLUMN "public"."sys_roles"."flag" IS '删除标识'; - --- ---------------------------- --- Records of sys_roles --- ---------------------------- -INSERT INTO "public"."sys_roles" VALUES (1, '超管理员',1, '0', 'admin', 2, '1', '', 'admin', 'panda', '', '2021-12-02 16:03:26+00', '2021-12-28 15:16:11+00', NULL); -INSERT INTO "public"."sys_roles" VALUES (2, '管理员',1, '0', 'manage', 2, '', '', 'panda', 'panda', '', '2021-12-19 16:06:20+00', '2021-12-28 15:16:23+00', NULL); - - --- ---------------------------- --- Table structure for sys_tenants --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_tenants"; -CREATE TABLE "public"."sys_tenants" ( - "id" int8 NOT NULL DEFAULT nextval('sys_tenants_id_seq'::regclass), - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6), - "tenant_name" varchar(255) COLLATE "pg_catalog"."default", - "remark" varchar(255) COLLATE "pg_catalog"."default", - "expire_time" timestamptz(6) -) -; -COMMENT ON COLUMN "public"."sys_tenants"."tenant_name" IS '租户名'; -COMMENT ON COLUMN "public"."sys_tenants"."remark" IS '备注'; -COMMENT ON COLUMN "public"."sys_tenants"."expire_time" IS '过期时间'; - --- ---------------------------- --- Records of sys_tenants --- ---------------------------- -INSERT INTO "public"."sys_tenants" VALUES (1, '2022-07-16 18:28:33+00', '2022-07-16 18:28:33+00', NULL, '熊猫科技', '鹅鹅鹅', '2099-07-16 00:00:00+00'); - --- ---------------------------- --- Table structure for sys_users --- ---------------------------- -DROP TABLE IF EXISTS "public"."sys_users"; -CREATE SEQUENCE IF NOT EXISTS "sys_users_user_id_seq"; -CREATE TABLE "public"."sys_users" ( - "user_id" int8 NOT NULL DEFAULT nextval('sys_users_user_id_seq'::regclass), - "nick_name" varchar(128) COLLATE "pg_catalog"."default", - "phone" varchar(11) COLLATE "pg_catalog"."default", - "tenant_id" int8 NULL DEFAULT NULL, - "role_id" int8, - "salt" varchar(255) COLLATE "pg_catalog"."default", - "avatar" varchar(255) COLLATE "pg_catalog"."default", - "sex" varchar(255) COLLATE "pg_catalog"."default", - "email" varchar(128) COLLATE "pg_catalog"."default", - "dept_id" int8, - "post_id" int8, - "role_ids" varchar(255) COLLATE "pg_catalog"."default", - "post_ids" varchar(255) COLLATE "pg_catalog"."default", - "create_by" varchar(128) COLLATE "pg_catalog"."default", - "update_by" varchar(128) COLLATE "pg_catalog"."default", - "remark" varchar(255) COLLATE "pg_catalog"."default", - "status" varchar(1) COLLATE "pg_catalog"."default", - "create_time" timestamptz(6), - "update_time" timestamptz(6), - "delete_time" timestamptz(6), - "username" varchar(64) COLLATE "pg_catalog"."default", - "password" varchar(128) COLLATE "pg_catalog"."default" -) -; - --- ---------------------------- --- Records of sys_users --- ---------------------------- -INSERT INTO "public"."sys_users" VALUES (1, 'pandax', '13818888888',1, 1, NULL, '', '0', '1@qq.com', 2, 1, '1', '1', 'admin', '1', NULL, '0', '2021-12-03 09:46:55+00', '2021-12-03 10:51:34+00', NULL, 'panda', '$2a$10$EXMJ5huCCTlCmP2ITFkAJ.4Mgmq3JcZGUvtE.KLX8j7FmhiiTEEya'); -INSERT INTO "public"."sys_users" VALUES (4, 'panda', '18353366912',1, 2, '', '', '0', '2417920382@qq.com', 2, 4, '2', '4,1', 'panda', '', '', '0', '2021-12-19 15:58:09+00', '2021-12-19 16:06:54+00', NULL, 'admin', '$2a$10$cKFFTCzGOvaIHHJY2K45Zuwt8TD6oPzYi4s5MzYIBAWCLL6ZhouP2'); - --- ---------------------------- --- Indexes structure for table casbin_rule --- ---------------------------- -CREATE UNIQUE INDEX "idx_casbin_rule" ON "public"."casbin_rule" USING btree ( - "ptype" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST, - "v0" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST, - "v1" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST, - "v2" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST, - "v3" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST, - "v4" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST, - "v5" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST -); - --- ---------------------------- --- Primary Key structure for table casbin_rule --- ---------------------------- -ALTER TABLE "public"."casbin_rule" ADD CONSTRAINT "casbin_rule_pkey" PRIMARY KEY ("id"); - --- ---------------------------- --- Primary Key structure for table log_jobs --- ---------------------------- -ALTER TABLE "public"."log_jobs" ADD CONSTRAINT "log_jobs_pkey" PRIMARY KEY ("log_id"); - --- ---------------------------- --- Primary Key structure for table log_logins --- ---------------------------- -ALTER TABLE "public"."log_logins" ADD CONSTRAINT "log_logins_pkey" PRIMARY KEY ("info_id"); - --- ---------------------------- --- Primary Key structure for table log_opers --- ---------------------------- -ALTER TABLE "public"."log_opers" ADD CONSTRAINT "log_opers_pkey" PRIMARY KEY ("oper_id"); - --- ---------------------------- --- Primary Key structure for table sys_apis --- ---------------------------- -ALTER TABLE "public"."sys_apis" ADD CONSTRAINT "sys_apis_pkey" PRIMARY KEY ("id"); - --- ---------------------------- --- Primary Key structure for table sys_configs --- ---------------------------- -ALTER TABLE "public"."sys_configs" ADD CONSTRAINT "sys_configs_pkey" PRIMARY KEY ("config_id"); - --- ---------------------------- --- Primary Key structure for table sys_depts --- ---------------------------- -ALTER TABLE "public"."sys_depts" ADD CONSTRAINT "sys_depts_pkey" PRIMARY KEY ("dept_id"); - --- ---------------------------- --- Primary Key structure for table sys_dict_data --- ---------------------------- -ALTER TABLE "public"."sys_dict_data" ADD CONSTRAINT "sys_dict_data_pkey" PRIMARY KEY ("dict_code"); - --- ---------------------------- --- Primary Key structure for table sys_dict_types --- ---------------------------- -ALTER TABLE "public"."sys_dict_types" ADD CONSTRAINT "sys_dict_types_pkey" PRIMARY KEY ("dict_id"); - --- ---------------------------- --- Primary Key structure for table sys_jobs --- ---------------------------- -ALTER TABLE "public"."sys_jobs" ADD CONSTRAINT "sys_jobs_pkey" PRIMARY KEY ("job_id"); - --- ---------------------------- --- Primary Key structure for table sys_menus --- ---------------------------- -ALTER TABLE "public"."sys_menus" ADD CONSTRAINT "sys_menus_pkey" PRIMARY KEY ("menu_id"); - --- ---------------------------- --- Primary Key structure for table sys_notices --- ---------------------------- -ALTER TABLE "public"."sys_notices" ADD CONSTRAINT "sys_notices_pkey" PRIMARY KEY ("notice_id"); - --- ---------------------------- --- Primary Key structure for table sys_posts --- ---------------------------- -ALTER TABLE "public"."sys_posts" ADD CONSTRAINT "sys_posts_pkey" PRIMARY KEY ("post_id"); - --- ---------------------------- --- Primary Key structure for table sys_role_depts --- ---------------------------- -ALTER TABLE "public"."sys_role_depts" ADD CONSTRAINT "sys_role_depts_pkey" PRIMARY KEY ("id"); - --- ---------------------------- --- Primary Key structure for table sys_role_menus --- ---------------------------- -ALTER TABLE "public"."sys_role_menus" ADD CONSTRAINT "sys_role_menus_pkey" PRIMARY KEY ("id"); - --- ---------------------------- --- Primary Key structure for table sys_roles --- ---------------------------- -ALTER TABLE "public"."sys_roles" ADD CONSTRAINT "sys_roles_pkey" PRIMARY KEY ("role_id"); - --- ---------------------------- --- Primary Key structure for table sys_users --- ---------------------------- -ALTER TABLE "public"."sys_users" ADD CONSTRAINT "sys_users_pkey" PRIMARY KEY ("user_id"); - --- ---------------------------- --- Primary Key structure for table dev_gen_table_columns --- ---------------------------- -ALTER TABLE "public"."dev_gen_table_columns" ADD CONSTRAINT "dev_gen_table_columns_pkey" PRIMARY KEY ("column_id"); - --- ---------------------------- --- Primary Key structure for table dev_gen_tables --- ---------------------------- -ALTER TABLE "public"."dev_gen_tables" ADD CONSTRAINT "dev_gen_tables_pkey" PRIMARY KEY ("table_id"); - --- ---------------------------- --- Primary Key structure for table sys_tenants --- ---------------------------- -ALTER TABLE "public"."sys_tenants" ADD CONSTRAINT "sys_tenants_pkey" PRIMARY KEY ("id"); diff --git a/resource/pandax_iot.sql b/resource/pandax_iot.sql new file mode 100644 index 0000000000000000000000000000000000000000..a9eb0ae4c3e4620029f029a8ba2c0d58194cafef --- /dev/null +++ b/resource/pandax_iot.sql @@ -0,0 +1,1927 @@ +/* + Navicat Premium Data Transfer + + Source Server : localhost_mysql-8.0 + Source Server Type : MySQL + Source Server Version : 80023 + Source Host : localhost:3306 + Source Schema : pandax_iot + + Target Server Type : MySQL + Target Server Version : 80023 + File Encoding : 65001 + + Date: 10/08/2023 17:46:50 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for casbin_rule +-- ---------------------------- +DROP TABLE IF EXISTS `casbin_rule`; +CREATE TABLE `casbin_rule` ( + `ptype` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v0` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v1` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v2` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v3` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v4` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v5` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `id` int(0) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_casbin_rule`(`ptype`, `v0`, `v1`, `v2`, `v3`, `v4`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6801 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of casbin_rule +-- ---------------------------- +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/api/list', 'GET', '', '', '', 3788); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/api/all', 'GET', '', '', '', 3789); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/api/getPolicyPathByRoleId', 'GET', '', '', '', 3790); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/api/:id', 'GET', '', '', '', 3791); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/config/list', 'GET', '', '', '', 3792); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/config/configKey', 'GET', '', '', '', 3793); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/config/:configId', 'GET', '', '', '', 3794); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dept/list', 'GET', '', '', '', 3795); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dept/:deptId', 'GET', '', '', '', 3796); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dept/roleDeptTreeSelect/:roleId', 'GET', '', '', '', 3797); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dept/deptTree', 'GET', '', '', '', 3798); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dict/type/list', 'GET', '', '', '', 3799); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dict/type/:dictId', 'GET', '', '', '', 3800); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dict/data/list', 'GET', '', '', '', 3801); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dict/data/type', 'GET', '', '', '', 3802); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/dict/data/:dictCode', 'GET', '', '', '', 3803); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/develop/code/table/db/list', 'GET', '', '', '', 3804); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/develop/code/table/list', 'GET', '', '', '', 3805); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/develop/code/table/info/:tableId', 'GET', '', '', '', 3806); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/develop/code/table/info/tableName', 'GET', '', '', '', 3807); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/develop/code/table/tableTree', 'GET', '', '', '', 3808); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/develop/code/gen/preview/:tableId', 'GET', '', '', '', 3809); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/job/list', 'GET', '', '', '', 3810); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/job/:jobId', 'GET', '', '', '', 3811); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/log/logLogin/list', 'GET', '', '', '', 3812); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/log/logOper/list', 'GET', '', '', '', 3813); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/log/logJob/list', 'GET', '', '', '', 3814); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/resource/email/list', 'GET', '', '', '', 3815); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/resource/email/:mailId', 'GET', '', '', '', 3816); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/menu/menuTreeSelect', 'GET', '', '', '', 3817); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/menu/menuRole', 'GET', '', '', '', 3818); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/menu/roleMenuTreeSelect/:roleId', 'GET', '', '', '', 3819); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/menu/menuPaths', 'GET', '', '', '', 3820); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/menu/list', 'GET', '', '', '', 3821); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/menu/:menuId', 'GET', '', '', '', 3822); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/notice/list', 'GET', '', '', '', 3823); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/resource/oss/list', 'GET', '', '', '', 3824); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/resource/oss/:ossId', 'GET', '', '', '', 3825); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/post/list', 'GET', '', '', '', 3826); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/post/:postId', 'GET', '', '', '', 3827); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/role/list', 'GET', '', '', '', 3828); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/role/:roleId', 'GET', '', '', '', 3829); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/tenant/list', 'GET', '', '', '', 3830); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/tenant/:tenantId', 'GET', '', '', '', 3831); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/tenant/lists', 'GET', '', '', '', 3832); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/user/list', 'GET', '', '', '', 3833); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/user/getById/:userId', 'GET', '', '', '', 3834); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/user/getInit', 'GET', '', '', '', 3835); +INSERT INTO `casbin_rule` VALUES ('p', 'manage', '/system/user/getRoPo', 'GET', '', '', '', 3836); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api/list', 'GET', '', '', '', 6635); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api/all', 'GET', '', '', '', 6636); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api/getPolicyPathByRoleId', 'GET', '', '', '', 6637); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api/:id', 'GET', '', '', '', 6638); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api', 'POST', '', '', '', 6639); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api', 'PUT', '', '', '', 6640); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/api/:id', 'DELETE', '', '', '', 6641); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/config/list', 'GET', '', '', '', 6642); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/config/configKey', 'GET', '', '', '', 6643); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/config/:configId', 'GET', '', '', '', 6644); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/config', 'POST', '', '', '', 6645); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/config', 'PUT', '', '', '', 6646); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/config/:configId', 'DELETE', '', '', '', 6647); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept/list', 'GET', '', '', '', 6648); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept/:deptId', 'GET', '', '', '', 6649); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept/roleDeptTreeSelect/:roleId', 'GET', '', '', '', 6650); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept/deptTree', 'GET', '', '', '', 6651); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept', 'POST', '', '', '', 6652); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept', 'PUT', '', '', '', 6653); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dept/:deptId', 'DELETE', '', '', '', 6654); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group/list', 'GET', '', '', '', 6655); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group/list/all', 'GET', '', '', '', 6656); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group/list/tree', 'GET', '', '', '', 6657); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group/:id', 'GET', '', '', '', 6658); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group', 'POST', '', '', '', 6659); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group', 'PUT', '', '', '', 6660); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group/:id', 'DELETE', '', '', '', 6661); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/list', 'GET', '', '', '', 6662); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/:id', 'GET', '', '', '', 6663); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device', 'POST', '', '', '', 6664); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/:id', 'DELETE', '', '', '', 6665); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device', 'PUT', '', '', '', 6666); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/group/list/tree/label', 'GET', '', '', '', 6667); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/list/all', 'GET', '', '', '', 6668); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/:id/status', 'GET', '', '', '', 6669); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/alarm/list', 'GET', '', '', '', 6670); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/alarm', 'PUT', '', '', '', 6671); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/alarm/:id', 'DELETE', '', '', '', 6672); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/cmd/list', 'GET', '', '', '', 6673); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/cmd', 'POST', '', '', '', 6674); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/cmd/:id', 'DELETE', '', '', '', 6675); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/:id/attribute/down', 'GET', '', '', '', 6676); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/type/list', 'GET', '', '', '', 6677); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/type/:dictId', 'GET', '', '', '', 6678); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/type', 'POST', '', '', '', 6679); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/type', 'PUT', '', '', '', 6680); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/type/:dictId', 'DELETE', '', '', '', 6681); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/type/export', 'GET', '', '', '', 6682); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/data/list', 'GET', '', '', '', 6683); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/data/type', 'GET', '', '', '', 6684); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/data/:dictCode', 'GET', '', '', '', 6685); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/data', 'POST', '', '', '', 6686); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/data', 'PUT', '', '', '', 6687); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/dict/data/:dictCode', 'DELETE', '', '', '', 6688); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table/db/list', 'GET', '', '', '', 6689); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table/list', 'GET', '', '', '', 6690); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table/info/:tableId', 'GET', '', '', '', 6691); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table/info/tableName', 'GET', '', '', '', 6692); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table/tableTree', 'GET', '', '', '', 6693); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table', 'POST', '', '', '', 6694); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table', 'PUT', '', '', '', 6695); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/table/:tableId', 'DELETE', '', '', '', 6696); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/gen/preview/:tableId', 'GET', '', '', '', 6697); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/gen/code/:tableId', 'GET', '', '', '', 6698); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/develop/code/gen/configure/:tableId', 'GET', '', '', '', 6699); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/list', 'GET', '', '', '', 6700); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job', 'POST', '', '', '', 6701); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job', 'PUT', '', '', '', 6702); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/:jobId', 'GET', '', '', '', 6703); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/:jobId', 'DELETE', '', '', '', 6704); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/stop/:jobId', 'GET', '', '', '', 6705); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/start/:jobId', 'GET', '', '', '', 6706); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/log/list', 'GET', '', '', '', 6707); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/log/all', 'DELETE', '', '', '', 6708); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/log/:logId', 'DELETE', '', '', '', 6709); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/job/changeStatus', 'PUT', '', '', '', 6710); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/log/logLogin/list', 'GET', '', '', '', 6711); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/log/logLogin/:infoId', 'DELETE', '', '', '', 6712); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/log/logLogin/all', 'DELETE', '', '', '', 6713); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/log/logOper/list', 'GET', '', '', '', 6714); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/log/logOper/:operId', 'DELETE', '', '', '', 6715); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/log/logOper/all', 'DELETE', '', '', '', 6716); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/menuTreeSelect', 'GET', '', '', '', 6717); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/menuRole', 'GET', '', '', '', 6718); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/roleMenuTreeSelect/:roleId', 'GET', '', '', '', 6719); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/menuPaths', 'GET', '', '', '', 6720); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/list', 'GET', '', '', '', 6721); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/:menuId', 'GET', '', '', '', 6722); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu', 'POST', '', '', '', 6723); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu', 'PUT', '', '', '', 6724); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/menu/:menuId', 'DELETE', '', '', '', 6725); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/notice/list', 'GET', '', '', '', 6726); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/notice', 'POST', '', '', '', 6727); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/notice', 'PUT', '', '', '', 6728); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/notice/:noticeId', 'DELETE', '', '', '', 6729); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/ota/list', 'GET', '', '', '', 6730); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/ota', 'POST', '', '', '', 6731); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/ota', 'PUT', '', '', '', 6732); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/ota/:id', 'DELETE', '', '', '', 6733); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/ota/:id', 'GET', '', '', '', 6734); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/post/list', 'GET', '', '', '', 6735); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/post/:postId', 'GET', '', '', '', 6736); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/post', 'POST', '', '', '', 6737); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/post', 'PUT', '', '', '', 6738); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/post/:postId', 'DELETE', '', '', '', 6739); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category/list', 'GET', '', '', '', 6740); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category/list/all', 'GET', '', '', '', 6741); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category/list/tree', 'GET', '', '', '', 6742); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category/:id', 'GET', '', '', '', 6743); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category', 'POST', '', '', '', 6744); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category', 'PUT', '', '', '', 6745); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category/:id', 'DELETE', '', '', '', 6746); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/:id', 'DELETE', '', '', '', 6747); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/:id', 'GET', '', '', '', 6748); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product', 'PUT', '', '', '', 6749); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/list', 'GET', '', '', '', 6750); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product', 'POST', '', '', '', 6751); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/category/list/tree/label', 'GET', '', '', '', 6752); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/product/list/all', 'GET', '', '', '', 6753); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role/list', 'GET', '', '', '', 6754); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role/:roleId', 'GET', '', '', '', 6755); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role', 'POST', '', '', '', 6756); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role', 'PUT', '', '', '', 6757); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role/:roleId', 'DELETE', '', '', '', 6758); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role/changeStatus', 'PUT', '', '', '', 6759); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role/dataScope', 'PUT', '', '', '', 6760); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/role/export', 'GET', '', '', '', 6761); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain/changeRoot', 'PUT', '', '', '', 6762); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain/list', 'GET', '', '', '', 6763); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain/:ruleId', 'DELETE', '', '', '', 6764); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain', 'PUT', '', '', '', 6765); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain', 'POST', '', '', '', 6766); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain/:ruleId', 'GET', '', '', '', 6767); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain/list/label', 'GET', '', '', '', 6768); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/rule/chain/clone/:ruleId', 'POST', '', '', '', 6769); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen', 'PUT', '', '', '', 6770); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/:screenId', 'GET', '', '', '', 6771); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/list', 'GET', '', '', '', 6772); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/:screenId', 'DELETE', '', '', '', 6773); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen', 'POST', '', '', '', 6774); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/changeStatus', 'PUT', '', '', '', 6775); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group/list', 'GET', '', '', '', 6776); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group/list/tree', 'GET', '', '', '', 6777); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group/list/all', 'GET', '', '', '', 6778); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group/:id', 'GET', '', '', '', 6779); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group', 'POST', '', '', '', 6780); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group', 'PUT', '', '', '', 6781); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/visual/screen/group/:id', 'DELETE', '', '', '', 6782); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/template/list', 'GET', '', '', '', 6783); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/template', 'PUT', '', '', '', 6784); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/template/:id', 'GET', '', '', '', 6785); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/template/:id', 'DELETE', '', '', '', 6786); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/template', 'POST', '', '', '', 6787); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/device/template/list/all', 'GET', '', '', '', 6788); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/upload/up/oss', 'POST', '', '', '', 6789); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/list', 'GET', '', '', '', 6790); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/changeStatus', 'PUT', '', '', '', 6791); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/:userId', 'DELETE', '', '', '', 6792); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/avatar', 'POST', '', '', '', 6793); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/pwd', 'PUT', '', '', '', 6794); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/getById/:userId', 'GET', '', '', '', 6795); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/getInit', 'GET', '', '', '', 6796); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/getRoPo', 'GET', '', '', '', 6797); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user', 'POST', '', '', '', 6798); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user', 'PUT', '', '', '', 6799); +INSERT INTO `casbin_rule` VALUES ('p', 'admin', '/system/user/export', 'GET', '', '', '', 6800); + +-- ---------------------------- +-- Table structure for dev_gen_table_columns +-- ---------------------------- +DROP TABLE IF EXISTS `dev_gen_table_columns`; +CREATE TABLE `dev_gen_table_columns` ( + `column_id` bigint(0) NOT NULL AUTO_INCREMENT, + `table_id` bigint(0) NULL DEFAULT NULL, + `table_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `column_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `column_comment` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `column_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `column_key` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `go_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `go_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `json_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `html_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_pk` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_increment` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_required` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_insert` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_edit` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_list` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `is_query` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `query_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `html_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `dict_type` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `sort` bigint(0) NULL DEFAULT NULL, + `link_table_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `link_table_class` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `link_table_package` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `link_label_id` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `link_label_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`column_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 138 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of dev_gen_table_columns +-- ---------------------------- +INSERT INTO `dev_gen_table_columns` VALUES (1, 1, '', 'log_id', '', 'bigint(20)', '', 'int64', 'LogId', 'logId', '', '1', '', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (2, 1, '', 'name', '任务名称', 'varchar(128)', '', 'string', 'Name', 'name', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (3, 1, '', 'job_group', '分组', 'varchar(128)', '', 'string', 'JobGroup', 'jobGroup', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (4, 1, '', 'entry_id', '任务id', 'int(11)', '', 'int', 'EntryId', 'entryId', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (5, 1, '', 'invoke_target', '调用方法', 'varchar(128)', '', 'string', 'InvokeTarget', 'invokeTarget', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (6, 1, '', 'log_info', '日志信息', 'varchar(255)', '', 'string', 'LogInfo', 'logInfo', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (7, 1, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (8, 1, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (9, 1, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (10, 1, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (27, 3, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 13, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (28, 4, '', 'config_value', 'ConfigValue', 'varchar(255)', '', 'string', 'ConfigValue', 'configValue', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (29, 3, '', 'business_type', '0其它 1新增 2修改 3删除', 'varchar(1)', '', 'string', 'BusinessType', 'businessType', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'select', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (30, 4, '', 'config_type', '是否系统内置0,1', 'varchar(64)', '', 'string', 'ConfigType', 'configType', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'select', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (31, 3, '', 'method', '请求方法', 'varchar(255)', '', 'string', 'Method', 'method', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (32, 4, '', 'is_frontend', '是否前台', 'varchar(1)', '', 'string', 'IsFrontend', 'isFrontend', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (33, 3, '', 'oper_name', '操作人员', 'varchar(255)', '', 'string', 'OperName', 'operName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (34, 4, '', 'remark', 'Remark', 'varchar(128)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (35, 3, '', 'oper_url', '操作url', 'varchar(255)', '', 'string', 'OperUrl', 'operUrl', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (36, 4, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (37, 3, '', 'oper_ip', '操作IP', 'varchar(255)', '', 'string', 'OperIp', 'operIp', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (38, 4, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (39, 3, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 11, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (40, 3, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (41, 3, '', 'status', '0=正常,1=异常', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (42, 3, '', 'oper_id', '', 'bigint(20)', '', 'int64', 'OperId', 'operId', '', '1', '', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (43, 5, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 14, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (44, 5, '', 'category', '', 'varchar(191)', '', 'string', 'Category', 'category', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (45, 5, '', 'app_id', 'AppId', 'varchar(128)', '', 'string', 'AppId', 'appId', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (46, 5, '', 'access_key', 'accessKey', 'varchar(128)', '', 'string', 'AccessKey', 'accessKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (47, 5, '', 'secret_key', 'secretKey', 'varchar(128)', '', 'string', 'SecretKey', 'secretKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (48, 5, '', 'bucket_name', 'bucketName', 'varchar(128)', '', 'string', 'BucketName', 'bucketName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (49, 5, '', 'endpoint', 'endpoint', 'varchar(128)', '', 'string', 'Endpoint', 'endpoint', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (50, 5, '', 'oss_code', 'ossCode', 'varchar(128)', '', 'string', 'OssCode', 'ossCode', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (51, 5, '', 'region', '地址', 'varchar(128)', '', 'string', 'Region', 'region', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (52, 5, '', 'remark', '说明', 'varchar(128)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (53, 5, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 13, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (54, 5, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 11, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (55, 5, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (56, 5, '', 'oss_id', '主键编码', 'bigint(20)', '', 'int64', 'OssId', 'ossId', '', '1', '1', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (57, 6, '', 'app_id', 'AppId', 'varchar(128)', '', 'string', 'AppId', 'appId', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (58, 6, '', 'category', '', 'varchar(191)', '', 'string', 'Category', 'category', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (59, 6, '', 'endpoint', 'endpoint', 'varchar(128)', '', 'string', 'Endpoint', 'endpoint', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (60, 6, '', 'access_key', 'accessKey', 'varchar(128)', '', 'string', 'AccessKey', 'accessKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (61, 6, '', 'secret_key', 'secretKey', 'varchar(128)', '', 'string', 'SecretKey', 'secretKey', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (62, 6, '', 'bucket_name', 'bucketName', 'varchar(128)', '', 'string', 'BucketName', 'bucketName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (63, 6, '', 'remark', '说明', 'varchar(128)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (64, 6, '', 'oss_code', 'ossCode', 'varchar(128)', '', 'string', 'OssCode', 'ossCode', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (65, 6, '', 'region', '地址', 'varchar(128)', '', 'string', 'Region', 'region', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (66, 6, '', 'create_time', '', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (67, 6, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 14, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (68, 6, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 11, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (69, 6, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 13, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (70, 6, '', 'oss_id', '主键编码', 'bigint(20)', '', 'int64', 'OssId', 'ossId', '', '1', '1', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (71, 7, '', 'delete_time', '', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (72, 7, '', 'host', '主机', 'varchar(191)', '', 'string', 'Host', 'host', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (73, 7, '', 'secret', '密码', 'varchar(191)', '', 'string', 'Secret', 'secret', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (74, 7, '', 'update_time', '', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (75, 7, '', 'from', '发件人', 'varchar(191)', '', 'string', 'From', 'from', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (76, 7, '', 'is_ssl', '开启ssl', 'tinyint(1)', '', 'int', 'IsSsl', 'isSsl', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (77, 7, '', 'mail_id', '主键编码', 'bigint(20)', 'Json', 'int64', 'MailId', 'mailId', '', '1', '1', '0', '1', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (82, 9, '', 'expire_time', '过期时间', 'datetime', '', 'Time', 'ExpireTime', 'expireTime', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (83, 9, '', 'delete_time', 'DeleteTime', 'datetime', '', 'Time', 'DeleteTime', 'deleteTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (84, 9, '', 'create_time', 'CreateTime', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '0', '0', '1', '0', 'EQ', 'datetime', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (85, 9, '', 'update_time', 'UpdateTime', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (86, 9, '', 'tenant_name', '租户名', 'varchar(255)', '', 'string', 'TenantName', 'tenantName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (87, 9, '', 'remark', '备注', 'varchar(255)', '', 'string', 'Remark', 'remark', '', '0', '', '0', '1', '1', '1', '0', 'EQ', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (88, 9, '', 'id', 'Id', 'bigint(20)', '', 'int64', 'Id', 'id', '', '1', '1', '0', '0', '0', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (89, 10, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', 'sys_normal_disable', 16, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (90, 10, '', 'product_category_name', '产品类型名称', 'varchar(64)', '', 'string', 'ProductCategoryName', 'productCategoryName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (91, 10, '', 'device_type', '设备类型', 'varchar(64)', '', 'string', 'DeviceType', 'deviceType', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'select', '', 12, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (92, 10, '', 'id', 'Id', 'varchar(191)', '', 'string', 'Id', 'id', '', '1', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (93, 10, '', 'rule_chain_id', '规则链Id', 'varchar(64)', '', 'string', 'RuleChainId', 'ruleChainId', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 15, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (94, 10, '', 'product_category_id', '产品类型Id', 'varchar(191)', '', 'string', 'ProductCategoryId', 'productCategoryId', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (95, 10, '', 'create_time', 'CreateTime', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '0', '0', '1', '0', 'EQ', 'datetime', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (96, 10, '', 'owner', '创建者,所有者', 'varchar(64)', '', 'string', 'Owner', 'owner', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (97, 10, '', 'protocol_name', '协议名称', 'varchar(64)', '', 'string', 'ProtocolName', 'protocolName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 11, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (98, 10, '', 'description', '产品说明', 'varchar(255)', '', 'string', 'Description', 'description', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (99, 10, '', 'name', '产品名称', 'varchar(128)', '', 'string', 'Name', 'name', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (100, 10, '', 'photo_url', '图片地址', 'varchar(255)', '', 'string', 'PhotoUrl', 'photoUrl', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (101, 10, '', 'org_id', '机构ID', 'varchar(64)', '', 'string', 'OrgId', 'orgId', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (102, 10, '', 'update_time', 'UpdateTime', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (103, 10, '', 'direct_connection', '是否直连', 'tinyint(1)', '', '', 'DirectConnection', 'directConnection', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 13, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (104, 10, '', 'self_learn', '自学习开关', 'tinyint(1)', '', '', 'SelfLearn', 'selfLearn', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 14, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (105, 11, '', 'update_time', 'UpdateTime', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (106, 11, '', 'alias', '设备别名', 'varchar(128)', '', 'string', 'Alias', 'alias', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (107, 11, '', 'ext', '拓展', 'json', '', '', 'Ext', 'ext', '', '0', '', '0', '1', '1', '1', '1', 'EQ', '', '', 14, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (108, 11, '', 'id', 'Id', 'varchar(191)', '', 'string', 'Id', 'id', '', '1', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (109, 11, '', 'token', '设备token', 'varchar(128)', '', 'string', 'Token', 'token', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (110, 11, '', 'gid', '分组Id', 'varchar(191)', '', 'string', 'Gid', 'gid', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (111, 11, '', 'ota_version', '固件版本', 'varchar(64)', '', 'string', 'OtaVersion', 'otaVersion', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 13, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (112, 11, '', 'org_id', '机构ID', 'varchar(64)', '', 'string', 'OrgId', 'orgId', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (113, 11, '', 'name', '设备名称', 'varchar(128)', '', 'string', 'Name', 'name', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (114, 11, '', 'owner', '创建者,所有者', 'varchar(64)', '', 'string', 'Owner', 'owner', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (115, 11, '', 'description', '产品说明', 'varchar(255)', '', 'string', 'Description', 'description', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 11, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (116, 11, '', 'status', '状态', 'varchar(1)', '', 'string', 'Status', 'status', '', '0', '', '1', '1', '1', '1', '1', 'EQ', 'radio', 'sys_normal_disable', 12, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (117, 11, '', 'pid', '产品Id', 'varchar(191)', '', 'string', 'Pid', 'pid', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 9, 'products', 'Product', 'product', 'id', 'Id'); +INSERT INTO `dev_gen_table_columns` VALUES (118, 11, '', 'create_time', 'CreateTime', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '0', '0', '1', '0', 'EQ', 'datetime', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (119, 13, '', 'description', '说明', 'varchar(255)', '', 'string', 'Description', 'description', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (120, 12, '', 'define', '数据约束', 'json', '', '', 'Define', 'define', '', '0', '', '0', '1', '1', '1', '1', 'EQ', '', '', 11, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (121, 13, '', 'pid', '产品Id', 'varchar(191)', '', 'string', 'Pid', 'pid', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (122, 12, '', 'update_time', 'UpdateTime', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (123, 13, '', 'id', 'Id', 'varchar(191)', '', 'string', 'Id', 'id', '', '1', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (124, 12, '', 'classify', '模型归类', 'varchar(64)', '', 'string', 'Classify', 'classify', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (125, 13, '', 'update_time', 'UpdateTime', 'datetime', '', 'Time', 'UpdateTime', 'updateTime', '', '0', '', '0', '0', '0', '0', '0', 'EQ', 'datetime', '', 3, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (126, 12, '', 'key', '标识', 'varchar(64)', '', 'string', 'Key', 'key', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (127, 13, '', 'name', '固件名称', 'varchar(64)', '', 'string', 'Name', 'name', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 6, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (128, 12, '', 'p_name', '产品名称', 'varchar(64)', '', 'string', 'PName', 'pName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (129, 13, '', 'p_name', '产品名称', 'varchar(191)', '', 'string', 'PName', 'pName', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 5, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (130, 12, '', 'name', '名称', 'varchar(64)', '', 'string', 'Name', 'name', '', '0', '', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (131, 13, '', 'create_time', 'CreateTime', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '0', '0', '1', '0', 'EQ', 'datetime', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (132, 12, '', 'type', '数据类型', 'varchar(64)', '', 'string', 'Type', 'type', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'select', '', 10, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (133, 13, '', 'url', '下载地址', 'varchar(128)', '', 'string', 'Url', 'url', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (134, 12, '', 'description', '属性说明', 'varchar(255)', '', 'string', 'Description', 'description', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (135, 13, '', 'version', '固件版本', 'varchar(64)', '', 'string', 'Version', 'version', '', '0', '', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (136, 12, '', 'pid', '产品Id', 'varchar(64)', '', 'string', 'Pid', 'pid', '', '0', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 4, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (137, 12, '', 'create_time', 'CreateTime', 'datetime', '', 'Time', 'CreateTime', 'createTime', '', '0', '', '0', '0', '0', '1', '0', 'EQ', 'datetime', '', 2, '', '', '', '', ''); +INSERT INTO `dev_gen_table_columns` VALUES (138, 12, '', 'id', 'Id', 'varchar(191)', '', 'string', 'Id', 'id', '', '1', '', '0', '0', '0', '1', '1', 'EQ', 'input', '', 1, '', '', '', '', ''); + +-- ---------------------------- +-- Table structure for dev_gen_tables +-- ---------------------------- +DROP TABLE IF EXISTS `dev_gen_tables`; +CREATE TABLE `dev_gen_tables` ( + `table_id` bigint(0) NOT NULL AUTO_INCREMENT, + `table_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `table_comment` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `class_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `tpl_category` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `package_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `module_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `business_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `function_name` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `function_author` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `options` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `remark` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `pk_column` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `pk_go_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `pk_json_field` varchar(191) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`table_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of dev_gen_tables +-- ---------------------------- +INSERT INTO `dev_gen_tables` VALUES (1, 'log_jobs', 'LogJobs', 'LogJobs', 'crud', 'admin', 'log-jobs', 'logJobs', 'LogJobs', 'panda', '', '', 'log_id', 'LogId', 'logId', '2022-01-06 14:44:14', '2022-01-06 14:44:14', '2022-01-10 11:58:43'); +INSERT INTO `dev_gen_tables` VALUES (2, 'log_logins', 'LogLogins', 'LogLogins', 'crud', 'log', 'log-logins', 'logLogins', 'logLogins', 'pandax', '', '', 'info_id', 'InfoId', 'infoId', '2022-01-06 14:44:27', '2022-01-26 14:45:46', '2022-07-16 18:24:04'); +INSERT INTO `dev_gen_tables` VALUES (3, 'log_opers', 'LogOpers', 'LogOpers', 'crud', 'admin', 'log-opers', 'logOpers', 'LogOpers', 'panda', '', '', 'oper_id', 'OperId', 'operId', '2022-01-06 15:02:45', '2022-01-06 15:02:45', NULL); +INSERT INTO `dev_gen_tables` VALUES (4, 'sys_configs', 'SysConfigs', 'SysConfigs', 'crud', 'admin', 'sys-configs', 'sysConfigs', 'SysConfigs', 'panda', '', '', 'config_id', 'ConfigId', 'configId', '2022-01-06 15:02:45', '2022-01-06 15:02:45', '2022-01-12 15:56:49'); +INSERT INTO `dev_gen_tables` VALUES (5, 'res_osses', 'ResOsses', 'ResOsses', 'crud', 'resource', 'res-osses', 'oss', 'ResOsses', 'panda', '', '', 'oss_id', 'OssId', 'ossId', '2022-01-13 15:12:14', '2022-01-13 15:39:11', NULL); +INSERT INTO `dev_gen_tables` VALUES (6, 'res_osses', 'ResOsses', 'ResOsses', 'crud', 'admin', 'res-osses', 'resOsses', 'ResOsses', 'panda', '', '', 'oss_id', 'OssId', 'ossId', '2022-01-13 15:12:27', '2022-01-13 15:12:27', '2022-01-13 15:12:41'); +INSERT INTO `dev_gen_tables` VALUES (7, 'res_emails', 'ResEmails', 'ResEmails', 'crud', 'resource', 'res-emails', 'email', 'ResEmails', 'panda', '', '', 'mail_id', 'MailId', 'mailId', '2022-01-14 15:20:27', '2022-01-26 15:56:37', NULL); +INSERT INTO `dev_gen_tables` VALUES (8, 'sys_tenants', '租户', 'SysTenants', 'crud', 'system', 'sys-tenants', 'tenant', 'Tenant', 'panda', '', '', 'tenant_id', 'TenantId', 'tenantId', '2022-07-14 16:52:28', '2022-07-16 16:09:50', '2022-07-16 18:09:40'); +INSERT INTO `dev_gen_tables` VALUES (9, 'sys_tenants', '租户', 'SysTenants', 'crud', 'system', 'sys-tenants', 'tenants', 'Tenants', 'panda', '', '', 'id', 'Id', 'id', '2022-07-16 18:14:53', '2022-07-16 22:45:33', NULL); +INSERT INTO `dev_gen_tables` VALUES (10, 'products', '产品', 'Product', 'crud', 'device', 'product', 'product', 'Product', 'panda', '', '', 'id', 'Id', 'id', '2023-06-30 08:57:48', '2023-06-30 09:35:47', NULL); +INSERT INTO `dev_gen_tables` VALUES (11, 'devices', '设备', 'Device', 'crud', 'device', 'device', 'device', 'Device', 'panda', '', '', 'id', 'Id', 'id', '2023-06-30 09:19:43', '2023-06-30 09:35:20', NULL); +INSERT INTO `dev_gen_tables` VALUES (12, 'product_templates', '产品模型', 'ProductTemplate', 'crud', 'device', 'product-template', 'template', 'Template', '熊猫', '', '', 'id', 'Id', 'id', '2023-06-30 09:31:58', '2023-06-30 09:33:09', NULL); +INSERT INTO `dev_gen_tables` VALUES (13, 'product_ota', '产品固件', 'ProductOta', 'crud', 'device', 'product-ota', 'ota', 'Ota', 'panda', '', '', 'id', 'Id', 'id', '2023-06-30 09:31:58', '2023-06-30 09:34:09', NULL); + +-- ---------------------------- +-- Table structure for device_alarms +-- ---------------------------- +DROP TABLE IF EXISTS `device_alarms`; +CREATE TABLE `device_alarms` ( + `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '告警名称', + `device_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `product_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '告警类型', + `level` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '告警级别', + `state` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '告警状态', + `details` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '详情', + `time` datetime(0) NULL DEFAULT NULL COMMENT '告警时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of device_alarms +-- ---------------------------- +INSERT INTO `device_alarms` VALUES ('af3b39f8d8ca220fee001fcf', 'ws432', 'd_1928b99619910dae5a001fa7', 'p_3ba460634520cf4590dc90e5', '高温报警', 'MAJOR', '0', '{\"humidity\":43.6,\"temperature\":26.6,\"ts\":\"2023-08-07 16:26:09.443\"}', '2023-08-03 11:19:56'); +INSERT INTO `device_alarms` VALUES ('e765e9ef022812a8b89dfb4c', '', 'd_1928b99619910dae5a001fa7', 'p_3ba460634520cf4590dc90e5', '高温报警', 'MAJOR', '3', '{\"humidity\":43.6,\"temperature\":18.6,\"ts\":\"2023-08-03 11:16:38.617\"}', '2023-08-03 11:11:44'); + +-- ---------------------------- +-- Table structure for device_cmd_log +-- ---------------------------- +DROP TABLE IF EXISTS `device_cmd_log`; +CREATE TABLE `device_cmd_log` ( + `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `device_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `cmd_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `cmd_content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL, + `state` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `response_content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL, + `request_time` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `response_time` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of device_cmd_log +-- ---------------------------- +INSERT INTO `device_cmd_log` VALUES ('cmd_de8489c9bf0da8f79e9573f5', 'd_1928b99619910dae5a001fa7', 'restart', '{\"aa\":444}', '0', '{\"aa\":\"7\"}', '2023-08-04 15:19:20', '2023-08-04 15:57:52', ''); + +-- ---------------------------- +-- Table structure for device_groups +-- ---------------------------- +DROP TABLE IF EXISTS `device_groups`; +CREATE TABLE `device_groups` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备分组名称', + `pid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上级设备分组类型', + `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备分组路径', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备分组说明', + `sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `ext` json NULL COMMENT '扩展', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of device_groups +-- ---------------------------- +INSERT INTO `device_groups` VALUES ('dg1eb2f39c5fff5665faf4f75a', 'panda', '', '2023-06-30 08:52:16', '2023-06-30 08:53:47', '1号楼', '0', '/0/dg1eb2f39c5fff5665faf4f75a', '1号楼,位于园区东南角,安保人:张三,电话:11111', 1, 'null', '0'); +INSERT INTO `device_groups` VALUES ('dg636752d3ee809180e330a773', 'panda', '', '2023-06-30 08:52:37', '2023-06-30 08:52:37', '一层', 'dg1eb2f39c5fff5665faf4f75a', '/0/dg1eb2f39c5fff5665faf4f75a/dg636752d3ee809180e330a773', '', 1, 'null', '0'); + +-- ---------------------------- +-- Table structure for devices +-- ---------------------------- +DROP TABLE IF EXISTS `devices`; +CREATE TABLE `devices` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备名称', + `token` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备token', + `alias` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备别名', + `pid` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品Id', + `gid` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '分组Id', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品说明', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + `ota_version` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '固件版本', + `ext` json NULL COMMENT '拓展', + `parent_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '父Id,子设备时,父设备为网关', + `device_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备类型', + `link_status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '连接状态', + `last_time` datetime(0) NULL DEFAULT NULL COMMENT '最后一次在线时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `fk_devices_product`(`pid`) USING BTREE, + INDEX `fk_devices_device_group`(`gid`) USING BTREE, + CONSTRAINT `fk_devices_device_group` FOREIGN KEY (`gid`) REFERENCES `device_groups` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `fk_devices_product` FOREIGN KEY (`pid`) REFERENCES `products` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of devices +-- ---------------------------- +INSERT INTO `devices` VALUES ('d_147501f13b5012ab3ca29f2d', 'panda', '', '2023-08-09 13:39:56', '2023-08-09 13:39:56', '34020000001320000180', '', '摄像头设备', 'p_9989d74427791986d497a078', 'dg636752d3ee809180e330a773', '', '0', '', 'null', '', 'monitor', 'inactive', '2023-08-09 13:39:56'); +INSERT INTO `devices` VALUES ('d_1928b99619910dae5a001fa7', 'panda', '', '2023-07-26 22:23:16', '2023-08-02 14:11:44', 'ws432', 'YWRlMTA0MmYtMzc2MS0zZTljLThjNjAtMzNhMzg4ZjdkOGQ3', '温湿度器', 'p_3ba460634520cf4590dc90e5', 'dg636752d3ee809180e330a773', '设备说明1', '0', '', '{\"location\": {\"lat\": 37.037581, \"lng\": 118.18431, \"address\": \"山东省滨州市博兴县曹王镇曹纯路\"}}', '', 'direct', 'offline', '2023-08-07 19:17:46'); +INSERT INTO `devices` VALUES ('d_36034a1475d7c6666f0cca4e', 'panda', '', '2023-07-31 14:23:13', '2023-07-31 14:23:13', 'ctr453', '', '智能控制器453', 'p_bf52caf91f7cdd2abb52eaaf', 'dg636752d3ee809180e330a773', '', '0', '', 'null', 'd_a377f18263b5915adac41736', 'gatewayS', 'inactive', '2023-07-31 14:23:13'); +INSERT INTO `devices` VALUES ('d_a377f18263b5915adac41736', 'panda', '', '2023-07-31 14:22:18', '2023-07-31 14:22:18', 'gateway4353', 'ZTg0ZDNkZDItOWQ1Mi0zYjM2LTg1NWQtYTI0NmE0NDcyOTM2', '智能网关4353', 'p_cdbb1eccd902018d51fe062e', 'dg636752d3ee809180e330a773', '', '0', '', 'null', '', 'gateway', 'inactive', '2023-07-31 14:22:18'); + +-- ---------------------------- +-- Table structure for job_logs +-- ---------------------------- +DROP TABLE IF EXISTS `job_logs`; +CREATE TABLE `job_logs` ( + `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务名称', + `entry_id` int(0) NULL DEFAULT NULL COMMENT '任务id', + `target_invoke` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '调用方法', + `log_info` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日志信息', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of job_logs +-- ---------------------------- +INSERT INTO `job_logs` VALUES ('094df20a1fd5889e5a25d8f2', '', '', '2023-08-08 17:45:00', '2023-08-08 17:45:00', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.008060', '0'); +INSERT INTO `job_logs` VALUES ('0c3da48e05bf8d79a4785c45', '', '', '2023-08-08 17:43:10', '2023-08-08 17:43:10', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000708', '0'); +INSERT INTO `job_logs` VALUES ('3dcfdc94bc3a956fbcd3d553', '', '', '2023-08-08 17:44:20', '2023-08-08 17:44:20', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000540', '0'); +INSERT INTO `job_logs` VALUES ('59ae02808f4f125253df3743', '', '', '2023-08-08 17:43:20', '2023-08-08 17:43:20', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000607', '0'); +INSERT INTO `job_logs` VALUES ('64185fd4c7c885d1506c68d2', '', '', '2023-08-08 17:44:50', '2023-08-08 17:44:50', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000518', '0'); +INSERT INTO `job_logs` VALUES ('85002a29cd6a74ec0a065a65', '', '', '2023-08-08 17:43:30', '2023-08-08 17:43:30', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000501', '0'); +INSERT INTO `job_logs` VALUES ('9089dfb3498293dd21a93a58', '', '', '2023-08-08 17:44:00', '2023-08-08 17:44:00', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000501', '0'); +INSERT INTO `job_logs` VALUES ('9ab3f4fca02b53e4cca3cf1d', '', '', '2023-08-08 17:46:00', '2023-08-08 17:46:00', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.001264', '0'); +INSERT INTO `job_logs` VALUES ('9dcabdb5eac73c294924faf0', '', '', '2023-08-08 17:44:40', '2023-08-08 17:44:40', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000046', '0'); +INSERT INTO `job_logs` VALUES ('a3cfa85b48260b5c8602b95c', '', '', '2023-08-08 17:43:40', '2023-08-08 17:43:40', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.001122', '0'); +INSERT INTO `job_logs` VALUES ('a64229d33b26e3eb955da680', '', '', '2023-08-08 17:44:10', '2023-08-08 17:44:10', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000520', '0'); +INSERT INTO `job_logs` VALUES ('a99d0dfa020786c06f97256a', '', '', '2023-08-08 17:45:10', '2023-08-08 17:45:10', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000502', '0'); +INSERT INTO `job_logs` VALUES ('b8bdec5545242e9b692633ea', '', '', '2023-08-08 17:45:20', '2023-08-08 17:45:20', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000652', '0'); +INSERT INTO `job_logs` VALUES ('c80d4dce2f42d62a8afb5eaa', '', '', '2023-08-08 17:45:50', '2023-08-08 17:45:50', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000403', '0'); +INSERT INTO `job_logs` VALUES ('c8f91d33d9a3f6107be387b3', '', '', '2023-08-08 17:43:00', '2023-08-08 17:43:00', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000513', '0'); +INSERT INTO `job_logs` VALUES ('e0bb27da67b1f0fd8e238e35', '', '', '2023-08-08 17:44:30', '2023-08-08 17:44:30', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000000', '0'); +INSERT INTO `job_logs` VALUES ('e84620fbf2797094a137faeb', '', '', '2023-08-08 17:43:50', '2023-08-08 17:43:50', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000133', '0'); +INSERT INTO `job_logs` VALUES ('eb8e3ace8aa129a6e4493b56', '', '', '2023-08-08 17:45:30', '2023-08-08 17:45:30', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000500', '0'); +INSERT INTO `job_logs` VALUES ('fd1cd987758b1c06c4220f0e', '', '', '2023-08-08 17:45:40', '2023-08-08 17:45:40', 'adsa', 1, 'cronDevice', '任务运行成功,总耗时 0.000498', '0'); + +-- ---------------------------- +-- Table structure for jobs +-- ---------------------------- +DROP TABLE IF EXISTS `jobs`; +CREATE TABLE `jobs` ( + `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `target_invoke` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '调用目标', + `target_args` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '目标传参', + `job_content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '目标传参 要执行的内容', + `cron_expression` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'cron表达式', + `misfire_policy` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '执行策略', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + `entry_id` int(0) NULL DEFAULT NULL COMMENT 'job启动时返回的id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of jobs +-- ---------------------------- +INSERT INTO `jobs` VALUES ('a40b9f83306669d12cd0e1ea', 'panda', '', '2023-08-08 17:29:30', '2023-08-08 17:42:58', 'adsa', 'cronDevice', 'd_1928b99619910dae5a001fa7', '{\"设备下发\":\"asdas\"}', ' 0/10 * * * * ?', '1', '0', 0); + +-- ---------------------------- +-- Table structure for log_logins +-- ---------------------------- +DROP TABLE IF EXISTS `log_logins`; +CREATE TABLE `log_logins` ( + `info_id` bigint(0) NOT NULL AUTO_INCREMENT, + `username` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', + `ipaddr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ip地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '归属地', + `browser` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '浏览器', + `os` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '系统', + `platform` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '固件', + `login_time` timestamp(0) NULL DEFAULT NULL COMMENT '登录时间', + `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', + `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`info_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3540 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of log_logins +-- ---------------------------- +INSERT INTO `log_logins` VALUES (3523, 'panda', '0', '127.0.0.1:61880', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-07-25 10:46:01', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-07-25 10:46:01', '2023-07-25 10:46:01', NULL); +INSERT INTO `log_logins` VALUES (3524, 'panda', '0', '127.0.0.1:53100', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-07-26 21:21:00', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-07-26 21:21:00', '2023-07-26 21:21:00', NULL); +INSERT INTO `log_logins` VALUES (3525, 'panda', '0', '127.0.0.1:55348', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-07-27 20:34:36', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-07-27 20:34:36', '2023-07-27 20:34:36', NULL); +INSERT INTO `log_logins` VALUES (3526, 'panda', '0', '127.0.0.1:58682', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-07-31 14:14:38', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-07-31 14:14:38', '2023-07-31 14:14:38', NULL); +INSERT INTO `log_logins` VALUES (3527, 'panda', '0', '127.0.0.1:52377', 'XX XX', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-01 08:24:28', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-01 08:24:28', '2023-08-01 08:24:28', NULL); +INSERT INTO `log_logins` VALUES (3528, 'panda', '0', '127.0.0.1:51682', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-02 08:21:19', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-02 08:21:19', '2023-08-02 08:21:19', NULL); +INSERT INTO `log_logins` VALUES (3529, 'panda', '0', '127.0.0.1:49982', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-02 09:47:12', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-02 09:47:12', '2023-08-02 09:47:12', NULL); +INSERT INTO `log_logins` VALUES (3530, 'panda', '0', '127.0.0.1:56861', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-03 08:17:42', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-03 08:17:42', '2023-08-03 08:17:42', NULL); +INSERT INTO `log_logins` VALUES (3531, 'panda', '0', '127.0.0.1:56861', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-03 08:24:36', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-03 08:24:36', '2023-08-03 08:24:36', NULL); +INSERT INTO `log_logins` VALUES (3532, 'admin', '0', '127.0.0.1:56861', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-03 08:26:21', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-03 08:26:21', '2023-08-03 08:26:21', NULL); +INSERT INTO `log_logins` VALUES (3533, 'panda', '0', '127.0.0.1:57293', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-03 08:27:21', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-03 08:27:21', '2023-08-03 08:27:21', NULL); +INSERT INTO `log_logins` VALUES (3534, 'panda', '0', '127.0.0.1:62465', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-04 08:46:42', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-04 08:46:42', '2023-08-04 08:46:42', NULL); +INSERT INTO `log_logins` VALUES (3535, 'panda', '0', '127.0.0.1:57804', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-07 09:06:15', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-07 09:06:15', '2023-08-07 09:06:15', NULL); +INSERT INTO `log_logins` VALUES (3536, 'panda', '0', '127.0.0.1:52602', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-08 08:36:14', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-08 08:36:14', '2023-08-08 08:36:14', NULL); +INSERT INTO `log_logins` VALUES (3537, 'panda', '0', '127.0.0.1:50210', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-08 14:36:22', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-08 14:36:22', '2023-08-08 14:36:22', NULL); +INSERT INTO `log_logins` VALUES (3538, 'panda', '0', '127.0.0.1:56174', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-09 10:54:00', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-09 10:54:00', '2023-08-09 10:54:00', NULL); +INSERT INTO `log_logins` VALUES (3539, 'panda', '0', '127.0.0.1:59626', '您的IP或者域名无法解析,请核实后再查询!', 'Chrome 113.0.0.0', 'Windows 10', 'Windows', '2023-08-10 08:54:22', '0', '0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', '登录成功', '2023-08-10 08:54:22', '2023-08-10 08:54:22', NULL); + +-- ---------------------------- +-- Table structure for log_opers +-- ---------------------------- +DROP TABLE IF EXISTS `log_opers`; +CREATE TABLE `log_opers` ( + `oper_id` bigint(0) NOT NULL AUTO_INCREMENT, + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作的模块', + `business_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '0其它 1新增 2修改 3删除', + `method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法', + `oper_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作人员', + `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作url', + `oper_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作IP', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作地点', + `oper_param` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求参数', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '0=正常,1=异常', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`oper_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1412 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of log_opers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for product_categories +-- ---------------------------- +DROP TABLE IF EXISTS `product_categories`; +CREATE TABLE `product_categories` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品类型名称', + `pid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上级产品类型', + `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品类型路径', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品类型说明', + `sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of product_categories +-- ---------------------------- +INSERT INTO `product_categories` VALUES ('pc_8e12a1ec7ba3bffc1337e163', 'panda', '', '2023-08-09 11:04:37', '2023-08-09 11:04:37', '海康摄像头', 'pc_d31572a0ceaa070f18cb669a', '/0/pc_d31572a0ceaa070f18cb669a/pc_8e12a1ec7ba3bffc1337e163', '', 1, '0'); +INSERT INTO `product_categories` VALUES ('pc_d31572a0ceaa070f18cb669a', 'panda', '', '2023-08-09 11:04:00', '2023-08-09 11:04:00', '视频产品', '0', '/0/pc_d31572a0ceaa070f18cb669a', '', 1, '0'); +INSERT INTO `product_categories` VALUES ('pc61058315302171445335c3d5', 'panda', '', '2023-06-29 17:50:30', '2023-06-29 17:50:31', ' 测试', '0', '/0/pc61058315302171445335c3d5', '', 1, '0'); +INSERT INTO `product_categories` VALUES ('pcd2e673d2cd92e860cff5d958', 'panda', '', '2023-06-29 17:52:18', '2023-06-29 17:52:18', '啊实打实', 'pc61058315302171445335c3d5', '/0/pc61058315302171445335c3d5/pcd2e673d2cd92e860cff5d958', '', 2, '0'); + +-- ---------------------------- +-- Table structure for product_ota +-- ---------------------------- +DROP TABLE IF EXISTS `product_ota`; +CREATE TABLE `product_ota` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `pid` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品Id', + `is_latest` tinyint(0) NULL DEFAULT NULL COMMENT '最新版本', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '固件名称', + `version` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '固件版本', + `url` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '下载地址', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '说明', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of product_ota +-- ---------------------------- +INSERT INTO `product_ota` VALUES ('ota-412f4f51b5eafb04889cc1bb', '2023-07-06 16:39:02', '2023-07-06 17:00:02', 'pcebf4ce28fd75d1a783c3d06', 1, '测试新版本', 'v1.2', 'http://127.0.0.1:9000/pandaxiot/uploads/2023-07-06/quick-start.sh', ''); +INSERT INTO `product_ota` VALUES ('ota-702a22874a03c54d08c36dc0', '2023-07-06 16:15:28', '2023-07-06 16:39:02', 'pcebf4ce28fd75d1a783c3d06', 0, '固件1', 'v1.0', 'http://127.0.0.1:9000/pandaxiot/uploads/2023-07-06/quick-start.sh', '这是固件'); + +-- ---------------------------- +-- Table structure for product_templates +-- ---------------------------- +DROP TABLE IF EXISTS `product_templates`; +CREATE TABLE `product_templates` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `pid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品Id', + `classify` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型归类', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标识', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '属性说明', + `type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据类型', + `define` json NULL COMMENT '数据约束', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of product_templates +-- ---------------------------- +INSERT INTO `product_templates` VALUES ('tm_14732f0fa234453e328bbd30', '2023-08-01 09:09:51', '2023-08-01 10:26:05', 'p_3ba460634520cf4590dc90e5', 'telemetry', '开关', 'open', '', 'bool', '{\"boolDefine\": [{\"key\": \"0\", \"value\": \"开\"}, {\"key\": \"1\", \"value\": \"关1\"}]}'); +INSERT INTO `product_templates` VALUES ('tm_377e0b1cc9812ab11464e2b4', '2023-08-01 09:22:54', '2023-08-01 09:23:09', 'p_3ba460634520cf4590dc90e5', 'telemetry', '测试参数', 'test', '', 'enum', '{\"enumDefine\": [{\"key\": \"0\", \"value\": \"开\"}, {\"key\": \"1\", \"value\": \"关\"}]}'); +INSERT INTO `product_templates` VALUES ('tm_43fa702e0c3aa6bb91d79e95', '2023-07-26 22:21:59', '2023-07-26 22:21:59', 'p_3ba460634520cf4590dc90e5', 'attributes', '编号', 'num', '', 'string', '{\"rw\": \"rw\", \"default_value\": \"23332442\"}'); +INSERT INTO `product_templates` VALUES ('tm_925cec0662102b40fe33b7bb', '2023-07-26 22:20:45', '2023-07-26 22:20:45', 'p_3ba460634520cf4590dc90e5', 'telemetry', '湿度', 'humidity', '', 'float64', '{\"max\": \"100\", \"min\": \"1\", \"step\": 0.01, \"unit\": \"G\"}'); +INSERT INTO `product_templates` VALUES ('tm_ac52beea237bb9009f1029af', '2023-07-26 22:20:08', '2023-07-26 22:20:08', 'p_3ba460634520cf4590dc90e5', 'telemetry', '温度', 'temperature', '', 'float64', '{\"max\": \"100\", \"min\": \"1\", \"step\": 0.01, \"unit\": \"度\"}'); +INSERT INTO `product_templates` VALUES ('tm_e815087669adc6f9fcf6bcf4', '2023-08-01 14:14:47', '2023-08-01 14:14:47', 'p_3ba460634520cf4590dc90e5', 'commands', '重启', 'restart', '设备重启指令', '', '{\"input\": [{\"key\": \"aa\", \"name\": \"重启参数\", \"type\": \"int64\", \"define\": {\"max\": 100, \"min\": 1, \"step\": 1, \"unit\": \"KW\"}}], \"output\": []}'); +INSERT INTO `product_templates` VALUES ('tm-4991928839c4dec5c08109f5', '2023-07-21 10:38:02', '2023-07-21 10:38:02', 'p03d9a6fb450e8443456f41b0', 'telemetry', '电流', 'i', '', 'float64', '{\"max\": \"100\", \"min\": \"1\", \"step\": \"1\", \"unit\": \"A\"}'); +INSERT INTO `product_templates` VALUES ('tm-9e922dad5c325348c123103d', '2023-07-21 10:37:05', '2023-07-21 10:37:05', 'p03d9a6fb450e8443456f41b0', 'attributes', '序列号', 'ns', '', 'string', '{\"rw\": \"r\", \"default_value\": \"NS42342\"}'); +INSERT INTO `product_templates` VALUES ('tm-a2998852fd8c1507cfc8d0e1', '2023-07-21 10:37:39', '2023-07-21 10:57:49', 'p03d9a6fb450e8443456f41b0', 'telemetry', '电压', 'u', '', 'float64', '{\"max\": 100, \"min\": 1, \"step\": 1, \"unit\": \"V\"}'); + +-- ---------------------------- +-- Table structure for products +-- ---------------------------- +DROP TABLE IF EXISTS `products`; +CREATE TABLE `products` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品名称', + `photo_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图片地址', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品说明', + `product_category_id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '产品类型Id', + `protocol_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '协议名称', + `device_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设备类型', + `self_learn` tinyint(1) NULL DEFAULT 0 COMMENT '自学习开关', + `rule_chain_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '规则链Id', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + PRIMARY KEY (`id`) USING BTREE, + INDEX `fk_products_product_category`(`product_category_id`) USING BTREE, + CONSTRAINT `fk_products_product_category` FOREIGN KEY (`product_category_id`) REFERENCES `product_categories` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of products +-- ---------------------------- +INSERT INTO `products` VALUES ('p_3ba460634520cf4590dc90e5', 'panda', '', '2023-07-26 22:17:27', '2023-08-03 10:13:45', '测试产品', '', '', 'pcd2e673d2cd92e860cff5d958', 'MQTT', 'direct', 0, 'rule_a37571bb6c45378b57803793', '0'); +INSERT INTO `products` VALUES ('p_9989d74427791986d497a078', 'panda', '', '2023-08-09 11:07:38', '2023-08-09 11:07:38', '★视频监控产品', '', '视频', 'pc_8e12a1ec7ba3bffc1337e163', 'MQTT', 'monitor', 0, '', '0'); +INSERT INTO `products` VALUES ('p_bf52caf91f7cdd2abb52eaaf', 'panda', '', '2023-07-31 14:16:29', '2023-07-31 14:16:29', '智能控制器', '', '', 'pcd2e673d2cd92e860cff5d958', 'MQTT', 'gatewayS', 0, 'rulee765e9ef022812a8b89dfb4c', '0'); +INSERT INTO `products` VALUES ('p_cdbb1eccd902018d51fe062e', 'panda', '', '2023-07-31 14:15:35', '2023-07-31 14:15:35', '网关设备', '', '网关设备', 'pcd2e673d2cd92e860cff5d958', 'MQTT', 'gateway', 0, 'rulee765e9ef022812a8b89dfb4c', '0'); + +-- ---------------------------- +-- Table structure for rule_chain +-- ---------------------------- +DROP TABLE IF EXISTS `rule_chain`; +CREATE TABLE `rule_chain` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `root` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否根节点1 根链 0 普通链', + `rule_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `rule_base64` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT 'Base64缩略图', + `rule_remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '说明', + `rule_data_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT 'Json数据', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of rule_chain +-- ---------------------------- +INSERT INTO `rule_chain` VALUES ('rule_a37571bb6c45378b57803793', 'panda', '', '2023-07-21 16:17:51', '2023-08-03 11:08:22', '0', '高温告警规则', 'data:image/png;base64,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KE/Z/PCHP6xKKRs6XXTRRRnKUgMBAgTes4AVee+ZsOMBBHkNxK0bWpDXPc694SolyJs/f35MmjSp+tGVRzM9WtuVdRlrq0CzB3n1fXr55ZfjmWee2bYTYO33hg8fHlOnTo3x48drK4G0Arfeeuu2TY3e//73V6/icBAg0JwCq1atiu9973vV5Pbff//41V/91eacqFkRIECgmwUEeQ0EF+Q1ELdNkDd0xMfixBNP7J4LukpagTlz5nR5gFfDEuSlvW1aLsirdeL555+Pp59+eluoUfv62WefLczLfbv26upKiP3ggw9WBmUTmMsuuyz69Cnrgh0ECDSbwJtvvhnXX399Na2yevzKK69stimaDwECBHpEoFcEebNmzYqVr9wbEw5b3K3Igrzu4X72xdEx7KBzomxL7yDQrAKCvGbtTNfMq6zI6ztqckt+Q2HevHnx1FNPRVn5IMzrmvvBKM0rsHHjxrjpppvijTfeqCb54Q9/OI466qjmnbCZEejFAmVzmm984xuVQL9+/eJzn/tcL9ZQOgECBLYL9Iog74UXXog5M++KyROf69beL1uxLvoO2hwHHbhPt163t13siaePikmTP2YFSW9rfIvVW76h8PaLT8aUMd37DrLFy1dHv722xOgR+7eYWGtNd+bCTTFgzAkt+w2FNWvWVDsDLl26dafzcliZ11r3oNl2XqD+fahlg6zzzjuv8x92JgEC3SYgyOs2ahciQKDFBHpFkLdp06b49rf+OT4w6fnYe6+3uq1Fy1e/EX36bxHkNVB83fpB8fDjR8VVV302vKS9gdCGfs8C5RsK8x59KM4a172PcC1etTr6DRTkvecG7mKAu5/bEhOnnN7S31AojzCVMG/RokXbqr3gggti9OjRjeYzPoFuFSjBdVmVV0KCcnz84x+PQw45pFvn4GIECOxa4K233oprr722OrFsUHP11Vfv+kPOIECAQC8Q6BVBXuljWQ2z4NlHum1VXp++Ectff726hazIa9yfpLIab+y4U1t2FUzjZIzcbALlGwrXfevauOCogbHfoO4L85asWRV9+4cVeQ28IdZs2BI/eHpjfOaqq1v+GwrlPr3//vujbIhRjhJulJDDQYAAAQIEultg7dq1ccMNN1SX3WeffeKKK67o7im4HgECBJpSoNcEeUX/x/fdFW+sfCGOHPtKQ1fmlRCvz4DNUR6t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x9wJNJ3A3XffHS+//HI1r4985CNx+OGHN90cTYgAAQI9KSDI60l91yZAgAABAk0ocM0112yb1ec///kmnKEpEehZgWuvvTbeeuutahKf/OQnY7/99uvZCbk6gUQC9a93KDtDlx2iHQQIECCwXUCQ524gQIAAAQIEdhAou3KW3TnL8YlPfCKGDRtGiACBOoHbb789Fi1aVH3lox/9aIwbN44PAQJdJFC/oczFF18cBx54YBeNbBgCBAjkEBDk5eijKggQIECAQJcJ/OAHP4ilS5dW49m1tstYDZRI4Oc//3k89dRTVUVTp06NadOmJapOKQR6VuC73/1urF69upqEbyb1bC9cnQCB5hQQ5DVnX8yKAAECBAj0mMC9994bL774opCixzrgws0uUB/kfeADH4jjjz++2adsfgRaRqB+VfinP/3p2HfffVtm7iZKgACB7hAQ5HWHsmsQIECAAIEWEnjooYfi6aefrmY8fvz4alWegwCB7QI//elP49/+7d+qL3zwgx+MY445Bg8BAl0kUP8OyquvvjoGDRrURSMbhgABAjkEBHk5+qgKAgQIECDQZQLPPPNMPPjgg9V4w4cPj8suu6zLxjYQgQwC9913X7zwwgtVKWeddVZMmDAhQ1lqINAUAt/4xjdi8+bN1Vw+97nPRb9+/ZpiXiZBgACBZhEQ5DVLJ8yDAAECBAg0iUDZ6KI82lQ7LrnkkhgxYkSTzM40CPS8wB133BELFy6sJnLuuefG2LFje35SZkAgiYAgL0kjlUGAQMMEBHkNozUwAQIECBBoXYHbbrstXn311aqA4447Lk499dSWK2bTpk2xYMGCWLNmTbzzzjs7nf+WLVtarr7MEy4rcIYOHVoFZP3792+6Uq+77rpYv359Na/zzz8/xowZ03RzNCECrSpw/fXXx5tvvllN/8orr4y99967VUsxbwIECDREQJDXEFaDEiBAgACB1haYPXt2PProo1URJUi59NJLq2ClVY5Zs2bF7JlPxKghA2P4wM3RJ7owqOsbEX23RJ9/f9qrT6ugtNA834k+sWJDv1i8ZmOcMGVqTJkypWlm/9prr8WPfvSjaj4lYChBg4MAga4TsGtt11kaiQCBnAKCvJx9VRUBAgQIEHhPAitWrKjCirfffrsaZ/LkyXHyySe/pzG768Mz7r0nNqxYEieNjthvUONithLk9e2/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5QQr8dwQTScgyGu6lpgQAQIECBAgQIAAAQIECLSyQHln3oIFC2LNmjWxefPmVi4l3dz79Nl5sNq3b98YOnRojB071jvx0nU/R0GCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjoLq0AABUoSURBVAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIeAIC9HH1VBgAABAgQIECBAgAABAgQIECCQXECQl7zByiNAgAABAgQIECBAgAABAgQIEMghIMjL0UdVECBAgAABAgQIECBAgAABAgQIJBcQ5CVvsPIIECBAgAABAgQIECBAgAABAgRyCAjycvRRFQQIECBAgAABAgQIECBAgAABAskFBHnJG6w8AgQIECBAgAABAgQIECBAgACBHAKCvBx9VAUBAgQIECBAgAABAgQIECBAgEByAUFe8gYrjwABAgQIECBAgAABAgQIECBAIIfAtiAvRzmqIECAAAECBAgQIECAAAECBAgQIJBXoE/e0lRGgAABAgQIECBAgAABAgQIECBAII+AIC9PL1VCgAABAgQIECBAgAABAgQIECCQWECQl7i5SiNAgAABAgQIECBAgAABAgQIEMgjIMjL00uVECBAgAABAgQIECBAgAABAgQIJBb436ya7dpojYnCAAAAAElFTkSuQmCC', '根链1', '{\"lfData\":{\"globalColor\":\"#D49BEF\",\"dataCode\":{\"nodes\":[{\"id\":\"input\",\"type\":\"InputNode\",\"x\":116,\"y\":337,\"properties\":{\"debugMode\":false},\"zIndex\":1013,\"text\":{\"x\":126,\"y\":337,\"value\":\"输入\"}},{\"id\":\"b6365013-18f2-4361-85ed-d9db4b8144b5\",\"type\":\"SaveAttributesNode\",\"x\":624,\"y\":249,\"properties\":{\"debugMode\":false,\"name\":\"\"},\"zIndex\":1012,\"text\":{\"x\":634,\"y\":249,\"value\":\"保存参数\"}},{\"id\":\"0c2710b5-9714-4563-944c-8b1a78536814\",\"type\":\"SaveTimeSeriesNode\",\"x\":624,\"y\":409,\"properties\":{\"debugMode\":false,\"name\":\"\"},\"zIndex\":1014,\"text\":{\"x\":634,\"y\":409,\"value\":\"保存遥测\"}},{\"id\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"type\":\"MessageTypeSwitchNode\",\"x\":406,\"y\":338,\"properties\":{\"debugMode\":false},\"zIndex\":1002,\"text\":{\"x\":416,\"y\":338,\"value\":\"消息类型切换\"}},{\"id\":\"594f9c98-daaf-4348-a4c7-208feb413ff8\",\"type\":\"ScriptFilterNode\",\"x\":813,\"y\":308,\"properties\":{\"debugMode\":false,\"name\":\"验证温度大于20\",\"script\":\"return msg.temperature > 20;\"},\"zIndex\":1015,\"text\":{\"x\":823,\"y\":308,\"value\":\"验证温度大于20\"}},{\"id\":\"62882142-b992-490b-ad01-bd5f965c8570\",\"type\":\"CreateAlarmNode\",\"x\":1049,\"y\":212,\"properties\":{\"debugMode\":false,\"name\":\"创建设备告警信息\",\"alarmType\":\"高温报警\",\"alarmSeverity\":\"MAJOR\"},\"zIndex\":1002,\"text\":{\"x\":1059,\"y\":212,\"value\":\"创建设备告警信息\"}},{\"id\":\"b14a20cc-0369-4f91-8157-c98a25c19a04\",\"type\":\"ClearAlarmNode\",\"x\":1041,\"y\":431,\"properties\":{\"debugMode\":false,\"name\":\"清除告警\",\"alarmType\":\"高温报警\"},\"zIndex\":1006,\"text\":{\"x\":1051,\"y\":431,\"value\":\"清除告警\"}}],\"edges\":[{\"id\":\"ba8d0084-9b85-437e-be3b-d83c644e8e09\",\"type\":\"bezier-link\",\"sourceNodeId\":\"input\",\"targetNodeId\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"startPoint\":{\"x\":176,\"y\":337},\"endPoint\":{\"x\":336,\"y\":338},\"properties\":{\"lineType\":[\"True\"]},\"text\":{\"x\":256,\"y\":337.5,\"value\":\"True\"},\"zIndex\":1003,\"pointsList\":[{\"x\":176,\"y\":337},{\"x\":276,\"y\":337},{\"x\":236,\"y\":338},{\"x\":336,\"y\":338}]},{\"id\":\"13cf5637-f995-4b56-9c41-530040418cdd\",\"type\":\"bezier-link\",\"sourceNodeId\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"targetNodeId\":\"0c2710b5-9714-4563-944c-8b1a78536814\",\"startPoint\":{\"x\":476,\"y\":338},\"endPoint\":{\"x\":564,\"y\":409},\"properties\":{\"lineType\":[\"Telemetry\"]},\"text\":{\"x\":520,\"y\":373.5,\"value\":\"Telemetry\"},\"zIndex\":1005,\"pointsList\":[{\"x\":476,\"y\":338},{\"x\":576,\"y\":338},{\"x\":464,\"y\":409},{\"x\":564,\"y\":409}]},{\"id\":\"0117eae6-8d1b-4eeb-96d6-6c42cddba1b4\",\"type\":\"bezier-link\",\"sourceNodeId\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"targetNodeId\":\"b6365013-18f2-4361-85ed-d9db4b8144b5\",\"startPoint\":{\"x\":476,\"y\":338},\"endPoint\":{\"x\":564,\"y\":249},\"properties\":{\"lineType\":[\"Attributes\"]},\"text\":{\"x\":520,\"y\":293.5,\"value\":\"Attributes\"},\"zIndex\":1006,\"pointsList\":[{\"x\":476,\"y\":338},{\"x\":576,\"y\":338},{\"x\":464,\"y\":249},{\"x\":564,\"y\":249}]},{\"id\":\"5c2bc46c-10c8-4a96-a1c2-3f50f19777e4\",\"type\":\"bezier-link\",\"sourceNodeId\":\"0c2710b5-9714-4563-944c-8b1a78536814\",\"targetNodeId\":\"594f9c98-daaf-4348-a4c7-208feb413ff8\",\"startPoint\":{\"x\":684,\"y\":409},\"endPoint\":{\"x\":733,\"y\":308},\"properties\":{\"lineType\":[\"Success\"]},\"text\":{\"x\":708.5,\"y\":358.5,\"value\":\"Success\"},\"zIndex\":1016,\"pointsList\":[{\"x\":684,\"y\":409},{\"x\":784,\"y\":409},{\"x\":633,\"y\":308},{\"x\":733,\"y\":308}]},{\"id\":\"9a80d1c4-b0f6-4a57-89a4-af4fa9d459c4\",\"type\":\"bezier-link\",\"sourceNodeId\":\"594f9c98-daaf-4348-a4c7-208feb413ff8\",\"targetNodeId\":\"62882142-b992-490b-ad01-bd5f965c8570\",\"startPoint\":{\"x\":893,\"y\":308},\"endPoint\":{\"x\":969,\"y\":212},\"properties\":{\"lineType\":[\"True\"]},\"text\":{\"x\":931,\"y\":260,\"value\":\"True\"},\"zIndex\":1003,\"pointsList\":[{\"x\":893,\"y\":308},{\"x\":993,\"y\":308},{\"x\":869,\"y\":212},{\"x\":969,\"y\":212}]},{\"id\":\"2f659b99-c508-4e3e-a98c-fe87b9a79da1\",\"type\":\"bezier-link\",\"sourceNodeId\":\"594f9c98-daaf-4348-a4c7-208feb413ff8\",\"targetNodeId\":\"b14a20cc-0369-4f91-8157-c98a25c19a04\",\"startPoint\":{\"x\":893,\"y\":308},\"endPoint\":{\"x\":981,\"y\":431},\"properties\":{\"lineType\":[\"False\"]},\"text\":{\"x\":937,\"y\":369.5,\"value\":\"False\"},\"zIndex\":1007,\"pointsList\":[{\"x\":893,\"y\":308},{\"x\":993,\"y\":308},{\"x\":881,\"y\":431},{\"x\":981,\"y\":431}]}]},\"openRule\":false,\"setting\":{\"describe\":\"\",\"grid\":{\"size\":20,\"open\":false,\"type\":\"mesh\",\"config\":{\"color\":\"#cccccc\",\"thickness\":1}},\"backgroundColor\":\"#ffffff\"}}}'); +INSERT INTO `rule_chain` VALUES ('rulee765e9ef022812a8b89dfb4c', 'panda', '', '2023-07-21 16:17:51', '2023-08-03 10:19:33', '1', 'Root Rule Chain', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABPIAAAMvCAYAAABY+f5KAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3QeUXVd9L/7fjLqtYhWrWc2SJRckW5IlcMPgApaxE2KbLAjEhgcs0kghCayX/FMg5JG3QhJSgBC/UA0hCeCSUFwxNnHBliVhyRaWVWz1Xq1mlfmvfYY7vjOa0YykuXfuuedz1pqlkebcfX77s7e8lr7e++yGJf9vR1O4CBAgQIAAAQIECBAgQIAAAQIECBCoaYGGFOS97oNn1HSRiiNAgAABAgQIECBAgAABAgQIECBQZIHn/nVnCPKKPAP0nQABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgQIAAAQIECBAgQKDoAoK8os8A/SdAgAABAgQIECBAgAABAgQIEMiFgCAvF8OkSAIECBAgQIAAAQIECBAgQIAAgaILCPKKPgP0nwABAgQIECBAgAABAgQIECBAIBcCgrxcDJMiCRAgQIAAAQIECBAgQIAAAQIEii4gyCv6DNB/AgQIECBAgAABAgQIECBAgACBXAgI8nIxTIokQIAAAQIECBAgQIAAAQIECBAouoAgr+gzQP8JECBAgAABAgQIECBAgAABAgRyISDIy8UwKZIAAQIECBAgUB2Bw4cPx+rVq2PXrl1x9OjR4z60qampOkV5SpcEevXqFUOGDIkJEyZE7969u/QZNxEgQIAAAQL5EhDk5Wu8VEuAAAECBAgQqJjAwoULY+H8RTFi6KgYNGBoRDR027MaekVEY0T06r42u624ummoKXa/sj22btsUs2bNjFmzZtVNz3SEAAECBAgQaBYQ5JkJBAgQIECAAAEC8cMHH45Xdu6P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AAECBAgQIECAQM0ICPJqZigUQoAAAQIECHSXQFNTU9x5552tTqa97LLLYvr06d31CO0QIECAAAECBAgQqLqAIK/q5B5IgAABAgQIVFLgwIED8fWvfz2OHj3a8ph58+bFhAkTKvlYbRMgQIAAAQIECBCouIAgr+LEHkCAAAECBAhUS2DTpk1xzz33tHrcO97xjhg2bFi1SvAcAgQIECBAgAABAhUTEORVjFbDBAgQIECAQDUFVq9eHffee2/LIwcMGBDvete7ok+fPtUsw7MIECBAgAABAgQIVExAkFcxWg0TIECAAAEC1RJIB1qkgy1K16hRo+Ltb397tR7vOQQIECBAgAABAgSqIiDIqwqzhxAgQIAAAQKVEnjuuefisccea2l+xIgRcfPNN1fqcdolQIAAAQIECBAg0GMCgrweo/dgAgQIECBA4FQFFi1aFE899VRLM4MHD86207oIECBAgAABAgQI1KOAIK8eR1WfCBAgQIBAAQQWLlwYTz/9dEtP0zvxbr311gL0XBcJECBAgAABAgSKKiDIK+rI6zcBAgQIEMixwJIlS+Lxxx9v6UGvXr3iAx/4QI57pHQCBAgQIECAAAECnQsI8jo3cgcBAgQIECBQQwI/+9nP4tFHH21V0Yc+9KEaqlApBAgQIECAAAECBCojIMirjKtWCRAgQIAAgQoIrFixIh566KFWLb///e+P3r17V+BpmiRAgAABAgQIECBQWwKCvNoaD9UQIECAAAECHQjs2rUrli9f3uqnF110kRDPjCFAgAABAgQIECiMgCCvMEOtowQIECBAgAABAgQIECBAgAABAnkWEOTlefTUToAAAQIECBAgQIAAAQIECBAgUBgBQV5hhlpHCRAgQIBAbQl89icRq3dF/PVbI8q/r60qVUOAAAECBAgQIECgdgQEebUzFiohQIAAAQI1LTB/XcSf/jDiw2+IuGHaqZcqyDt1Qy0QIECAAAECBAgUS0CQV6zx1lsCBAgQIHDSAil4e3xNxGl9Ij4zL2JQv+am9hyM+Mi9ETed/1rA971lEXctbX3f8R58Kivy2nv+SXfSBwkQIECAAAECBAjUsIAgr4YHR2kECBAgQKBWBFJY9scPRsybGvFvz0Z85NKIOWcJ8mplfNRBgAABAgQIECBQDAFBXjHGWS8JECBAgMApCZSvsPvkI81NpXfbrd8T8eHvRezY3/xnQwdEvOGsiHuXv/a4Wy6IuGRcxGeeiJg6POKRlyL+8PKIVTuOfUde+tTT65o/mz6XtvG2t+KutILv9y499vmfvSFi/e7mbcAHDje3lZ6XtgOX2lqxvfUzTgnHhwkQIECAAAECBAhUSUCQVyVojyFAgAABAnkW+Nj9EROGNAdrKdT74oKIFJiNHdS1rbWl9+ulMC21ka6278j7zvOvBW6lgPADsyOunHjs1t3yz7YN+tJn/+yHEX9xdXN96fcfva95FeGTa18LD/M8HmonQIAAAQIECBAopoAgr5jjrtcECBAgQKDLAuWhWgri2v6+K+/IS0FeWpH36euaw7X2grzSCbalwlJYl673zjyxIC8FjX/z2LHdS6vyRp3evFLvrMFdf39fl6HcSIAAAQIECBAgQKDCAoK8CgNrngABAgQI5F0gBWpptVzba8qw5jAsXZ0ddnEyQV5pFeDJBHmdHbRRCvvmntW8RdhFgAABAgQIECBAIA8Cgrw8jJIaCRAgQIBADwmUVtsNG9A68ErB3P95NOL/uzLi3BHdE+SlcO2TVzcfolHefvp9CvXSVf5evnOGNf++va216b19aVtu6b14//x0xG/MjfjBixFXTGxeFXiiJ+v20BB4LAECBAgQIECAAIEWAUGeyUCAAAECBAh0KNA2UCu/sTxcK63aS4ddpHfnpat0CEb5YRfH21r7wtaI/YcjSgdRlA6oSG2V3rGXDq9Iz7hwVMS+Q6+Fi22fX37YRf/erwWE5YdzlP+5KUCAAAECBAgQIEAgDwKCvDyMkhoJECBAgAABAgQIECBAgAABAgQKLyDIK/wUAECAAAECBAgQIECAAAECBAgQIJAHAUFeHkZJjQQIECBAgAABAgQIECBAgAABAoUXEOQVfgoAIECAAAECBAgQIECAAAECBAgQyIOAIC8Po6RGAgQIECBQBwL79++P559/vlVPpk+fHv369auD3ukCAQIECBAgQIAAgcoLCPIqb+wJBAgQIECg8AK7d++Of//3f2/lcOONN8bYsWMLbwOAAAECBAgQIECAQFcFBHldlXIfAQIECBAgcFICaSXeHXfc0eqz8+bNiwkTJpxUez5EgAABAgQIECBAoKgCgryijrx+EyBAgACBKggcPnw4vvSlL7V60jXXXBNTpkypwtM9ggABAgQIECBAgEB9CQjy6ms89YYAAQIECNSUwO23396qniuvvDLOO++8mqpRMQQIECBAgAABAgTyIiDIy8tIqZMAAQIECORM4Itf/GIcOXKkperLLrss0uEWLgIECBAgQIAAAQIETk5AkHdybj5FgAABAgQIHEcgvRMvvRuvdM2dOzdmzZrFjAABAgQIECBAgACBUxAQ5J0Cno8SIECAAAECxwqk02nTKbWl6/Wvf33MnDkTFQECBAgQIECAAAECpyggyDtFQB8nQIAAAQIEXhO48847Y+vWrS1/cPnll8frXvc6RAQIECBAgAABAgQIdIOAIK8bEDVBgAABAgQIRNxzzz2xadOmFoqrr746zjnnHDQECBAgQIAAAQIECHSTgCCvmyA1Q4AAAQIEiipw8ODB+OY3vxmvvvpqC8G8efNiwoQJRSXRbwIECBAgQIAAAQIVERDkVYRVowQIECBAoBgC69ati+9973utOvuLv/iLMXr06GIA6CUBAgQIECBAgACBKgoI8qqI7VEECBAgQKCeBBYtWhRPPfVUS5caGhriXe96VwwaNKieuqkvBAgQIECAAAECBGpGQJBXM0OhEAIECBAgkB+BH//4x7F06dKWggcOHJiFeI2NjfnphEoJECBAgAABAgQI5ExAkJezAVMuAQIECBDoaYH7778/XnrppZYy0jbatJ3WRYAAAQIECBAgQIBAZQUEeZX11ToBAgQIEKgbgZ07d8YjjzzS6mTayZMnx7XXXls3fdQRAgQIECBAgAABArUsIMir5dFRGwECBAgQqBGB9evXx6OPPhq7d+9uqejCCy+MSy65pEYqVAYBAgQIECBAgACB+hcQ5NX/GOshAQIECBA4JYEXX3wx0jvxDh8+3NJOCvBSkOciQIAAAQIECBAgQKB6AoK86ll7EgECBAgQyJXAwYMH4+mnn47nn3++pe5+/frFG9/4xkhbal0ECBAgQIAAAQIECFRXQJBXXW9PI0CAAAECuRBYvXp1FuJt27atpd7hw4fH5ZdfHulwCxcBAgQIECBAgAABAtUXEORV39wTCRAgQIBATQvMnz8/FixY0KrG173udTFnzpxIK/JcBAgQIECAAAECBAj0jIAgr2fcPZUAAQIECNScwObNmyOFeGvXrm2pbdCgQTF37tw455xzaq5eBREgQIAAAQIECBAomoAgr2gjrr8ECBAgQKAdgSVLlmRbaQ8dOtTy0xTe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CRAgQIAAAQIE8iggyMvjqKmZAAECBAj0gEDbMK+hoSFuuOEGYV4PjIVHEiBAgAABAgQIFFNAkFfMcddrAgQIECBwUgKrVq2KBx54oNVnb7zxRmHeSWn6EAECBAgQIECAAIETExDknZiXuwkQIECAQOEF1q5dG9///veFeYWfCQAIECBAgAABAgSqLSDIq7a45xEgQIAAgToQ2Lx5c9x9993CvDoYS10gQIAAAQIECBDIj4AgLz9jpVICBAgQIFBTAjt37oz//M//FObV1KgohgABAgQIECBAoJ4FBHn1PLr6RoAAAQIEKiywd+/e+MY3vtHqKbfccksMHz68wk/WPAECBAgQIECAAIHiCQjyijfmekyAAAECBLpV4NVXX42vfOUrrdp897vfHQMHDuzW52iMAAECBAgQIECAQNEFBHlFnwH6T4AAAQIEukng9ttvb2mpX79+8c53vjP69+/fTa1rhgABAgQIECBAgAABQZ45QIAAAQIECHSLQNtttmPGjInrr78+evfu3S3ta4QAAQIECBAgQIBA0QUEeUWfAfpPgAABAgS6UWDTpk1xzz33tLQ4adKkeMtb3hINDQ3d+BRNESBAgAABAgQIECimgCCvmOOu1wQIECBAoGICK1eujAcffLCl/WnTpsWb3/zmij1PwwQIECBAgAABAgSKIiDIK8pI6ycBAgQIEKiiwOLFi+OJJ55oeeLs2bNjzpw5VazAowgQIECAAAECBAjUn4Agr/7GVI8IECBAgEBNCDz55JPx7LPPttTyxje+Mc4///yaqE0RBAgQIECAAAECBPIoIMjL46ipmQABAgQI5EQgbbFNW21L13XXXRcTJ07MSfXKJECAAAECBAgQIFBbAoK82hoP1RAgQIAAgboSOHjwYNx3332xcePGrF+nn356zJs3L4YPH15X/dQZAgQIECBAgAABAtUQEORVQ9kzCBAgQIBAgQW2b98e9957b7zyyiuZwsiRIyOtzBswYECBVXSdAAECBAgQIECAwIkLCPJO3MwnCBAgQIAAAQIECBAgQIAAAQIECFRdQJBXdXIPJECAAAECBAgQIECAAAECBAgQIHDiAoK8EzfzCQIECBAgQIAAAQIECBAgQIAAAQJVFxDkVZ3cAwkQIECAQH0LfOz+iAlDIj78hvrup94RIECAAAECBAgQqLaAIK/a4p5HgAABAgRyIrB+T8SHvxexY/+xBd9yQcdBnSAvJwOsTAIECBAgQIAAgdwJCPJyN2QKJkCAAAEC1Rf43rKIu5ZGfGZexKB+x39+tYO8E6mt+nKeSIAAAQIECBAgQKD7BAR53WepJQIECBAgULcCJxKWCfLqdhroGAECBAgQIECAQA8LCPJ6eAA8ngABAgQI5EGgbZC352DER+6NWLG9ufq5Z0X89Vubvy8P8jq7b8RpEcu2NbczZVjERy+P+KMHm7fzDh0Q8dkbIsYOeq3dp9c1f5/uTasDv7oo4jvPvyaYtvxeMi7iM09ETB0e8chLER+8uPmeD8yOuGFa873z1zXf8+nrXms/D+OgRgIECBAgQIAAgWILCPKKPf56T4AAAQIEuiTQNshLYd2bJr0WjJWHd22/P959izdFfPLqiHNHNAeD2/e/Ft6ldtKVAsLP/qT5+9IBGun3q3c1/6xtbSmk+9MfNtfW3v2pnWqvGuwSspsIECBAgAABAgQIdCIgyDNFCBAgQIAAgU4FysOyPa+2fwhGaVVeKSS7OR2I0c5hGW3v6yhsK4V1f/qm1qv/SsWWVuU9+nLr9/e1t9ouHdzx0fsiPnJpxNjBr30/56xOu+4GAgQIECBAgAABAjUjIMirmaFQCAECBAgQqF2BtkFeKRRrLwgrD/K6cl9Xg7ybzn9tBWC5VHsr8trbNluq6+yhzVtuS1uBa1ddZQQIECBAgAABAgRaCwjyzAgCBAgQIECgU4H2ttamD5XCsC8vjJgxMiIFe2231nblvnRP+XbZtr9PP1u08bVTc1M96UrbZ7sa5KWVel+YH7H/UMS7L2w/FOwUwg0ECBAgQIAAAQIEelBAkNeD+B5NgAABAgTyItDZYRfpkInSyrrjHXbR0X2dBXnp56nd0mEX5YdrpG2zpS285YddtD3IonTwRmorHZQxqF9e9NVJgAABAgQIECBAoFlAkGcmECBAgAABAoUQKAV5HW3RLQSCThIgQIAAAQIECORaQJCX6+FTPAECBAgQINBVgbSq8IsLXjsVt6ufcx8BAgQIECBAgACBWhEQ5NXKSKiDAAECBAgQqIhAaSXeut0Rn7y6+T1+LgIECBAgQIAAAQJ5FBDk5XHU1EyAAAECBAgQIECAAAECBAgQIFA4AUFe4YZchwkQIECAQH4EnnzyyXj22WdbCr7yyivjvPPOy08HVEqAAAECBAgQIECgGwUEed2IqSkCBAgQIECg+wUeeOCBWLVqVdZwQ0NDzJs3L8aPH9/9D9IiAQIECBAgQIAAgRoXEOTV+AApjwABAgQIFF1g//79cd9998XmzZszioEDB2Zh3rBhw4pOo/8ECBAgQIAAAQIFExDkFWzAdZcAAQIECORRYNu2bXHvvffG3r17s/JHjx4d1113XfTr1y+P3VEzAQIECBAgQIAAgZMSEOSdFJsPESBAgAABAtUWePnll7OVeaVr8uTJce2111a7DM8jQIAAAQIECBAg0GMCgrweo/dgAgQIECBA4EQFli5dGj/+8Y9bPnbhhRfGJZdccqLNuJ8AAQIECBAgQIBALgUEebkcNkUTIECAAIHiCsyfPz8WLFjQAjB37tyYNWtWcUH0nAABAgQIECBAoDACgrzCDLWOEiBAgACB+hH40Y9+FMuWLWvpUFqVl1bnuQgQIECAAAECBAjUs4Agr55HV98IECBAgECdCjQ1NcX3v//9WLduXUsPr7nmmpgyZUqd9li3CBAgQIAAAQIECEQI8swCAgQIECBAIJcCBw8ejHvuuSd27tzZUv873vGOGDZsWC77o2gCBAgQIECAAAECnQkI8joT8nMCBAgQIECgZgVeeeWV+Na3vhWHDh1qqfFDH/pQzdarMAIECBAgQIAAAQKnIiDIOxU9nyVAgAABAgR6XGD79u3x7W9/u1Ud73//+6N37949XpsCCBAgQIAAAQIECHSngCCvOzW1RYAAAQIECPSIwMaNG+O//uu/Wj37ve99b/Tr169H6vFQAgQIECBAgAABApUQEORVQlWbBAgQIECAQNUFNm/eHHfffXer577nPe+J008/veq1eCABAgQIECBAgACBSggI8iqhqk0CBAgQIECgRwR27NiRvTOv/HrXu94VgwcP7pF6PJQAAQIECBAgQIBAdwoI8rpTU1sECBAgQIBAjwu0F+bdcsstMXz48B6vTQEECBAgQIAAAQIETkVAkHcqej5LgAABAgQI1KRAe2HeL/3SL8XIkSNrsl5FESBAgAABAgQIEOiKgCCvK0ruIUCAAAECBHInkMK873znO3H06NGW2m+88cYYO3Zs7vqiYAIECBAgQIAAAQJJQJBnHhAgQIAAAQJ1K5DCvHSa7cGDB1v6eP3118f48ePrts86RoAAAQIECBAgUL8Cgrz6HVs9I0CA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IECAwKoJCHmrRu+JCRAgQIAAAQKrL/CbXz8+jh0+NG7dNlb0nXlTxFvacHocfOkVIW+F1j69E+8PB8bYtHnruOuj96zQs3hYAgQIECBAYDUFhLzV1PfcBAgQIECAAIErQGB6Z96fn949tr5j47hq46mxNE5fuqmWxhhLp8cU8qY/L750ZPbfV1+1+dI9R+CRLqHoea/29Fg3Dh9bPw4eOTFu3HWTd+IF7sGIBAgQIEDgzQoIeW9Wzt8jQIAAAQIECCyQwPSdefv37x9HjhwZp06dWqBX1n8p69a9/ncYLi0tjc2bN4/t27f7Trz+ur0CAgQIECDwugJCngMhQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQvxCEEAAAFj0lEQVQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgICQ5wYIECBAgAABAgQIECBAgAABAgQIBASEvMCSjEiAAAECBAgQIECAAAECBAgQIEBAyHMDBAgQIECAAAECBAgQIECAAAECBAICQl5gSUYkQIAAAQIECBAgQIAAAQIECBAgIOS5AQIECBAgQIAAAQIECBAgQIAAAQIBASEvsCQjEiBAgAABAgQIECBAgAABAgQIEBDy3AABAgQIECBAgAABAgQIECBAgACBgICQF1iSEQkQIECAAAECBAgQIECAAAECBAgIeW6AAAECBAgQIECAAAECBAgQIECAQEBAyAssyYgECBAgQIAAAQIECBAgQIAAAQIEhDw3QIAAAQIECBAgQIAAAQIECBAgQCAgIOQFlmREAgQIECBAgAABAgQIECBAgAABAkKeGyBAgAABAgQIECBAgAABAgQIECAQEBDyAksyIgECBAgQIECAAAECBAgQIECAAAEhzw0QIECAAAECBAgQIECAAAECBAgQCAgIeYElGZEAAQIECBAgQIAAAQIECBAgQICAkOcGCBAgQIAAAQIECBAgQIAAAQIECAQEhLzAkoxIgAABAgQIECBAgAABAgQIECBAQMhzAwQIECBAgAABAgQIECBAgAABAgQCAkJeYElGJECAAAECBAgQIECAAAECBAgQICDkuQECBAgQIECAAAECBAgQIECAAAECAQEhL7AkIxIgQIAAAQIECBAgQIAAAQIECBAQ8twAAQIECBAgQIAAAQIECBAgQIAAgYCAkBdYkhEJECBAgAABAgQIECBAgAABAgQICHlugAABAgQIECBAgAABAgQIECBAgEBAQMgLLMmIBAgQIECAAAECBAgQIECAAAECBIQ8N0CAAAECBAgQIECAAAECBAgQIEAgICDkBZZkRAIECBAgQIAAAQIECBAgQIAAAQJCnhsgQIAAAQIECBAgQIAAAQIECBAgEBAQ8gJLMiIBAgQIECBAgAABAgQIECBAgAABIc8NECBAgAABAgQIECBAgAABAgQIEAgICHmBJRmRAAECBAgQIECAAAECBAgQIECAgJDnBggQIECAAAECBAgQIECAAAECBAgEBIS8wJKMSIAAAQIECBAgQIAAAQIECBAgQEDIcwMECBAgQIAAAQIECBAgQIAAAQIEAgJCXmBJRiRAgAABAgQIECBAgAABAgQIECAg5LkBAgQIECBAgAABAgQIECBAgAABAgEBIS+wJCMSIECAAAECBAgQIECAAAECBAgQEPLcAAECBAgQIECAAAECBAgQIECAAIGAgJAXWJIRCRAgQIAAAQIECBAgQIAAAQIECAh5boAAAQIECBAgQIAAAQIECBAgQIBAQEDICyzJiAQIECBAgAABAgQIECBAgAABAgSEPDdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQEPICSzIiAQIECBAgQIAAAQIECBAgQIAAASHPDRAgQIAAAQIECBAgQIAAAQIECBAICAh5gSUZkQABAgQIECBAgAABAgQIECBAgMCZkIeCAAECBAgQIECAAAECBAgQIECAAIErW2DdlT2e6QgQIECAAAECBAgQIECAAAECBAgQmASEPHdAgAABAgQIECBAgAABAgQIECBAICAg5AWWZEQCBAgQIECAAAECBAgQIECAAAECQp4bIECAAAECBAgQIECAAAECBAgQIBAQ+D/tyO+BuOA5SAAAAABJRU5ErkJggg==', '根链1', '{\"lfData\":{\"globalColor\":\"#D49BEF\",\"dataCode\":{\"nodes\":[{\"id\":\"input\",\"type\":\"InputNode\",\"x\":116,\"y\":337,\"properties\":{\"debugMode\":false},\"zIndex\":1013,\"text\":{\"x\":126,\"y\":337,\"value\":\"输入\"}},{\"id\":\"b6365013-18f2-4361-85ed-d9db4b8144b5\",\"type\":\"SaveAttributesNode\",\"x\":702,\"y\":238,\"properties\":{\"debugMode\":false,\"name\":\"\"},\"zIndex\":1012,\"text\":{\"x\":712,\"y\":238,\"value\":\"保存参数\"}},{\"id\":\"0c2710b5-9714-4563-944c-8b1a78536814\",\"type\":\"SaveTimeSeriesNode\",\"x\":700,\"y\":437,\"properties\":{\"debugMode\":false,\"name\":\"\"},\"zIndex\":1014,\"text\":{\"x\":710,\"y\":437,\"value\":\"保存遥测\"}},{\"id\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"type\":\"MessageTypeSwitchNode\",\"x\":386,\"y\":332,\"properties\":{\"debugMode\":false},\"zIndex\":1002,\"text\":{\"x\":396,\"y\":332,\"value\":\"消息类型切换\"}}],\"edges\":[{\"id\":\"ba8d0084-9b85-437e-be3b-d83c644e8e09\",\"type\":\"bezier-link\",\"sourceNodeId\":\"input\",\"targetNodeId\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"startPoint\":{\"x\":176,\"y\":337},\"endPoint\":{\"x\":316,\"y\":332},\"properties\":{\"lineType\":[\"True\"]},\"text\":{\"x\":246,\"y\":334.5,\"value\":\"True\"},\"zIndex\":1003,\"pointsList\":[{\"x\":176,\"y\":337},{\"x\":276,\"y\":337},{\"x\":216,\"y\":332},{\"x\":316,\"y\":332}]},{\"id\":\"13cf5637-f995-4b56-9c41-530040418cdd\",\"type\":\"bezier-link\",\"sourceNodeId\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"targetNodeId\":\"0c2710b5-9714-4563-944c-8b1a78536814\",\"startPoint\":{\"x\":456,\"y\":332},\"endPoint\":{\"x\":640,\"y\":437},\"properties\":{\"lineType\":[\"Telemetry\"]},\"text\":{\"x\":548,\"y\":384.5,\"value\":\"Telemetry\"},\"zIndex\":1005,\"pointsList\":[{\"x\":456,\"y\":332},{\"x\":556,\"y\":332},{\"x\":540,\"y\":437},{\"x\":640,\"y\":437}]},{\"id\":\"0117eae6-8d1b-4eeb-96d6-6c42cddba1b4\",\"type\":\"bezier-link\",\"sourceNodeId\":\"74b514b9-9591-4ab2-b6f9-c6f2f005047f\",\"targetNodeId\":\"b6365013-18f2-4361-85ed-d9db4b8144b5\",\"startPoint\":{\"x\":456,\"y\":332},\"endPoint\":{\"x\":642,\"y\":238},\"properties\":{\"lineType\":[\"Attributes\"]},\"text\":{\"x\":549,\"y\":285,\"value\":\"Attributes\"},\"zIndex\":1006,\"pointsList\":[{\"x\":456,\"y\":332},{\"x\":556,\"y\":332},{\"x\":542,\"y\":238},{\"x\":642,\"y\":238}]}]},\"openRule\":false,\"setting\":{\"describe\":\"\",\"grid\":{\"size\":20,\"open\":false,\"type\":\"mesh\",\"config\":{\"color\":\"#cccccc\",\"thickness\":1}},\"backgroundColor\":\"#ffffff\"}}}'); + +-- ---------------------------- +-- Table structure for rule_chain_msg_log +-- ---------------------------- +DROP TABLE IF EXISTS `rule_chain_msg_log`; +CREATE TABLE `rule_chain_msg_log` ( + `message_id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `msg_type` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `device_name` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `ts` datetime(0) NULL DEFAULT NULL, + `content` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `created_at` datetime(0) NULL DEFAULT NULL +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of rule_chain_msg_log +-- ---------------------------- + +-- ---------------------------- +-- Table structure for sys_apis +-- ---------------------------- +DROP TABLE IF EXISTS `sys_apis`; +CREATE TABLE `sys_apis` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + `path` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api路径', + `description` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api中文描述', + `api_group` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api组', + `method` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '方法', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 193 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_apis +-- ---------------------------- +INSERT INTO `sys_apis` VALUES (1, '2021-12-09 09:21:04', '2021-12-09 09:21:04', NULL, '/system/user/list', '查询用户列表(分页)', 'user', 'GET'); +INSERT INTO `sys_apis` VALUES (2, '2021-12-09 09:29:36', '2021-12-09 09:29:36', NULL, '/system/user/changeStatus', '修改用户状态', 'user', 'PUT'); +INSERT INTO `sys_apis` VALUES (3, '2021-12-09 09:34:37', '2021-12-09 09:34:37', NULL, '/system/user/:userId', '删除用户信息', 'user', 'DELETE'); +INSERT INTO `sys_apis` VALUES (4, '2021-12-09 09:36:43', '2021-12-09 09:36:43', NULL, '/system/dept/list', '获取部门列表', 'dept', 'GET'); +INSERT INTO `sys_apis` VALUES (5, '2021-12-09 09:37:31', '2021-12-09 09:37:31', NULL, '/system/dept/:deptId', '获取部门信息', 'dept', 'GET'); +INSERT INTO `sys_apis` VALUES (6, '2021-12-09 18:20:32', '2021-12-09 18:20:32', NULL, '/system/user/avatar', '上传头像', 'user', 'POST'); +INSERT INTO `sys_apis` VALUES (7, '2021-12-09 18:21:10', '2021-12-09 18:21:10', NULL, '/system/user/pwd', '修改密码', 'user', 'PUT'); +INSERT INTO `sys_apis` VALUES (8, '2021-12-09 18:21:54', '2021-12-09 18:21:54', NULL, '/system/user/getById/:userId', '通过id获取用户信息', 'user', 'GET'); +INSERT INTO `sys_apis` VALUES (9, '2021-12-09 18:58:50', '2021-12-09 18:58:50', NULL, '/system/user/getInit', '获取初始化角色岗位信息(添加用户初始化)', 'user', 'GET'); +INSERT INTO `sys_apis` VALUES (10, '2021-12-09 18:59:43', '2021-12-09 18:59:43', NULL, '/system/user/getRoPo', '获取用户角色岗位信息', 'user', 'GET'); +INSERT INTO `sys_apis` VALUES (11, '2021-12-09 19:00:24', '2021-12-09 19:00:24', NULL, '/system/user', '添加用户信息', 'user', 'POST'); +INSERT INTO `sys_apis` VALUES (12, '2021-12-09 19:00:52', '2021-12-09 19:00:52', NULL, '/system/user', '修改用户信息', 'user', 'PUT'); +INSERT INTO `sys_apis` VALUES (13, '2021-12-09 19:02:30', '2021-12-09 19:02:30', NULL, '/system/user/export', '导出用户信息', 'user', 'GET'); +INSERT INTO `sys_apis` VALUES (14, '2021-12-09 19:04:04', '2021-12-09 19:04:04', NULL, '/system/dept/roleDeptTreeSelect/:roleId', '获取角色部门树', 'dept', 'GET'); +INSERT INTO `sys_apis` VALUES (15, '2021-12-09 19:04:48', '2021-12-09 19:04:48', NULL, '/system/dept/deptTree', '获取所有部门树', 'dept', 'GET'); +INSERT INTO `sys_apis` VALUES (16, '2021-12-09 19:07:37', '2021-12-09 19:07:37', NULL, '/system/dept', '添加部门信息', 'dept', 'POST'); +INSERT INTO `sys_apis` VALUES (17, '2021-12-09 19:08:14', '2021-12-09 19:08:14', NULL, '/system/dept', '修改部门信息', 'dept', 'PUT'); +INSERT INTO `sys_apis` VALUES (18, '2021-12-09 19:08:40', '2021-12-09 19:08:40', NULL, '/system/dept/:deptId', '删除部门信息', 'dept', 'DELETE'); +INSERT INTO `sys_apis` VALUES (19, '2021-12-09 19:09:41', '2021-12-09 19:09:41', NULL, '/system/config/list', '获取配置分页列表', 'config', 'GET'); +INSERT INTO `sys_apis` VALUES (20, '2021-12-09 19:10:11', '2021-12-09 19:10:11', NULL, '/system/config/configKey', '获取配置列表通过ConfigKey', 'config', 'GET'); +INSERT INTO `sys_apis` VALUES (21, '2021-12-09 19:10:45', '2021-12-09 19:10:45', NULL, '/system/config/:configId', '获取配置信息', 'config', 'GET'); +INSERT INTO `sys_apis` VALUES (22, '2021-12-09 19:11:22', '2021-12-09 19:11:22', NULL, '/system/config', '添加配置信息', 'config', 'POST'); +INSERT INTO `sys_apis` VALUES (23, '2021-12-09 19:11:41', '2021-12-09 19:11:41', NULL, '/system/config', '修改配置信息', 'config', 'PUT'); +INSERT INTO `sys_apis` VALUES (24, '2021-12-09 19:12:28', '2021-12-09 19:12:28', NULL, '/system/config/:configId', '删除配置信息', 'config', 'DELETE'); +INSERT INTO `sys_apis` VALUES (25, '2021-12-09 19:13:08', '2021-12-09 19:13:08', NULL, '/system/dict/type/list', '获取字典类型分页列表', 'dict', 'GET'); +INSERT INTO `sys_apis` VALUES (26, '2021-12-09 19:13:55', '2021-12-09 19:13:55', NULL, '/system/dict/type/:dictId', '获取字典类型信息', 'dict', 'GET'); +INSERT INTO `sys_apis` VALUES (27, '2021-12-09 19:14:28', '2021-12-09 19:14:28', NULL, '/system/dict/type', '添加字典类型信息', 'dict', 'POST'); +INSERT INTO `sys_apis` VALUES (28, '2021-12-09 19:14:55', '2021-12-09 19:14:55', NULL, '/system/dict/type', '修改字典类型信息', 'dict', 'PUT'); +INSERT INTO `sys_apis` VALUES (29, '2021-12-09 19:15:17', '2021-12-09 19:15:17', NULL, '/system/dict/type/:dictId', '删除字典类型信息', 'dict', 'DELETE'); +INSERT INTO `sys_apis` VALUES (30, '2021-12-09 19:15:50', '2021-12-09 19:15:50', NULL, '/system/dict/type/export', '导出字典类型信息', 'dict', 'GET'); +INSERT INTO `sys_apis` VALUES (31, '2021-12-09 19:16:26', '2021-12-09 19:16:26', NULL, '/system/dict/data/list', '获取字典数据分页列表', 'dict', 'GET'); +INSERT INTO `sys_apis` VALUES (32, '2021-12-09 19:17:01', '2021-12-09 19:17:01', NULL, '/system/dict/data/type', '获取字典数据列表通过字典类型', 'dict', 'GET'); +INSERT INTO `sys_apis` VALUES (33, '2021-12-09 19:17:39', '2021-12-09 19:17:39', NULL, '/system/dict/data/:dictCode', '获取字典数据信息', 'dict', 'GET'); +INSERT INTO `sys_apis` VALUES (34, '2021-12-09 19:18:20', '2021-12-09 19:18:20', NULL, '/system/dict/data', '添加字典数据信息', 'dict', 'POST'); +INSERT INTO `sys_apis` VALUES (35, '2021-12-09 19:18:44', '2021-12-09 19:18:44', NULL, '/system/dict/data', '修改字典数据信息', 'dict', 'PUT'); +INSERT INTO `sys_apis` VALUES (36, '2021-12-09 19:19:16', '2021-12-09 19:19:16', NULL, '/system/dict/data/:dictCode', '删除字典数据信息', 'dict', 'DELETE'); +INSERT INTO `sys_apis` VALUES (37, '2021-12-09 19:21:18', '2021-12-09 19:21:18', NULL, '/system/menu/menuTreeSelect', '获取菜单树', 'menu', 'GET'); +INSERT INTO `sys_apis` VALUES (38, '2021-12-09 19:21:47', '2021-12-09 19:21:47', NULL, '/system/menu/menuRole', '获取角色菜单', 'menu', 'GET'); +INSERT INTO `sys_apis` VALUES (39, '2021-12-09 19:22:42', '2021-12-09 19:22:42', NULL, '/system/menu/roleMenuTreeSelect/:roleId', '获取角色菜单树', 'menu', 'GET'); +INSERT INTO `sys_apis` VALUES (40, '2021-12-09 19:23:17', '2021-12-09 19:23:17', NULL, '/system/menu/menuPaths', '获取角色菜单路径列表', 'menu', 'GET'); +INSERT INTO `sys_apis` VALUES (41, '2021-12-09 19:23:40', '2021-12-09 19:23:40', NULL, '/system/menu/list', '获取菜单列表', 'menu', 'GET'); +INSERT INTO `sys_apis` VALUES (42, '2021-12-09 19:24:09', '2021-12-09 19:24:09', NULL, '/system/menu/:menuId', '获取菜单信息', 'menu', 'GET'); +INSERT INTO `sys_apis` VALUES (43, '2021-12-09 19:24:29', '2021-12-09 19:24:29', NULL, '/system/menu', '添加菜单信息', 'menu', 'POST'); +INSERT INTO `sys_apis` VALUES (44, '2021-12-09 19:24:48', '2021-12-09 19:24:48', NULL, '/system/menu', '修改菜单信息', 'menu', 'PUT'); +INSERT INTO `sys_apis` VALUES (45, '2021-12-09 19:25:10', '2021-12-09 19:25:10', NULL, '/system/menu/:menuId', '删除菜单信息', 'menu', 'DELETE'); +INSERT INTO `sys_apis` VALUES (46, '2021-12-09 19:25:44', '2021-12-09 19:27:06', NULL, '/system/post/list', '获取岗位分页列表', 'post', 'GET'); +INSERT INTO `sys_apis` VALUES (47, '2021-12-09 19:26:55', '2021-12-09 19:26:55', NULL, '/system/post/:postId', '获取岗位信息', 'post', 'GET'); +INSERT INTO `sys_apis` VALUES (48, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post', '添加岗位信息', 'post', 'POST'); +INSERT INTO `sys_apis` VALUES (49, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post', '修改岗位信息', 'post', 'PUT'); +INSERT INTO `sys_apis` VALUES (50, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/post/:postId', '删除岗位信息', 'post', 'DELETE'); +INSERT INTO `sys_apis` VALUES (51, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/list', '获取角色分页列表', 'role', 'GET'); +INSERT INTO `sys_apis` VALUES (52, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/:roleId', '获取角色信息', 'role', 'GET'); +INSERT INTO `sys_apis` VALUES (53, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role', '添加角色信息', 'role', 'POST'); +INSERT INTO `sys_apis` VALUES (54, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role', '修改角色信息', 'role', 'PUT'); +INSERT INTO `sys_apis` VALUES (55, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/:roleId', '删除角色信息', 'role', 'DELETE'); +INSERT INTO `sys_apis` VALUES (56, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/changeStatus', '修改角色状态', 'role', 'PUT'); +INSERT INTO `sys_apis` VALUES (57, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/dataScope', '修改角色部门权限', 'role', 'PUT'); +INSERT INTO `sys_apis` VALUES (58, '2021-12-09 19:25:44', '2021-12-09 19:25:44', NULL, '/system/role/export', '导出角色信息', 'role', 'GET'); +INSERT INTO `sys_apis` VALUES (59, '2021-12-09 19:50:57', '2022-01-19 08:58:20', NULL, '/system/api/list', '获取api分页列表1', 'api', 'GET'); +INSERT INTO `sys_apis` VALUES (60, '2021-12-09 19:51:26', '2021-12-09 19:51:26', NULL, '/system/api/all', '获取所有api', 'api', 'GET'); +INSERT INTO `sys_apis` VALUES (61, '2021-12-09 19:51:54', '2021-12-09 19:51:54', NULL, '/system/api/getPolicyPathByRoleId', '获取角色拥有的api权限', 'api', 'GET'); +INSERT INTO `sys_apis` VALUES (62, '2021-12-09 19:52:14', '2021-12-09 19:52:14', NULL, '/system/api/:id', '获取api信息', 'api', 'GET'); +INSERT INTO `sys_apis` VALUES (63, '2021-12-09 19:52:35', '2021-12-09 19:52:35', NULL, '/system/api', '添加api信息', 'api', 'POST'); +INSERT INTO `sys_apis` VALUES (64, '2021-12-09 19:52:50', '2021-12-09 19:52:50', NULL, '/system/api', '修改api信息', 'api', 'PUT'); +INSERT INTO `sys_apis` VALUES (65, '2021-12-09 19:53:07', '2021-12-09 19:53:07', NULL, '/system/api/:id', '删除api信息', 'api', 'DELETE'); +INSERT INTO `sys_apis` VALUES (66, '2021-12-17 10:51:05', '2021-12-17 10:54:22', NULL, '/log/logLogin/list', '获取登录日志', 'log', 'GET'); +INSERT INTO `sys_apis` VALUES (67, '2021-12-17 10:51:43', '2021-12-17 10:54:28', NULL, '/log/logLogin/:infoId', '删除日志', 'log', 'DELETE'); +INSERT INTO `sys_apis` VALUES (68, '2021-12-17 10:53:09', '2021-12-17 10:54:34', NULL, '/log/logLogin/all', '清空所有', 'log', 'DELETE'); +INSERT INTO `sys_apis` VALUES (69, '2021-12-17 10:54:07', '2021-12-17 10:54:07', NULL, '/log/logOper/list', '操作日志列表', 'log', 'GET'); +INSERT INTO `sys_apis` VALUES (70, '2021-12-17 10:53:09', '2021-12-17 10:53:09', NULL, '/log/logOper/:operId', '删除', 'log', 'DELETE'); +INSERT INTO `sys_apis` VALUES (71, '2021-12-17 10:53:09', '2021-12-17 10:53:09', NULL, '/log/logOper/all', '清空', 'log', 'DELETE'); +INSERT INTO `sys_apis` VALUES (72, '2021-12-24 15:41:23', '2021-12-24 15:41:23', NULL, '/job/list', '任务列表', 'job', 'GET'); +INSERT INTO `sys_apis` VALUES (73, '2021-12-24 15:41:54', '2021-12-24 15:41:54', NULL, '/job', '添加', 'job', 'POST'); +INSERT INTO `sys_apis` VALUES (74, '2021-12-24 15:42:11', '2021-12-24 15:42:11', NULL, '/job', '修改任务', 'job', 'PUT'); +INSERT INTO `sys_apis` VALUES (75, '2021-12-24 15:42:37', '2021-12-24 16:32:21', NULL, '/job/:jobId', '获取任务', 'job', 'GET'); +INSERT INTO `sys_apis` VALUES (76, '2021-12-24 15:43:09', '2021-12-24 16:32:05', NULL, '/job/:jobId', '删除job', 'job', 'DELETE'); +INSERT INTO `sys_apis` VALUES (77, '2021-12-24 15:43:35', '2021-12-24 16:31:11', NULL, '/job/stop/:jobId', '停止任务', 'job', 'GET'); +INSERT INTO `sys_apis` VALUES (78, '2021-12-24 15:44:09', '2021-12-24 16:30:38', NULL, '/job/start/:jobId', '开始任务', 'job', 'GET'); +INSERT INTO `sys_apis` VALUES (79, '2021-12-24 15:45:03', '2023-08-08 14:15:59', NULL, '/job/log/list', '任务日志列表', 'job', 'GET'); +INSERT INTO `sys_apis` VALUES (80, '2021-12-24 15:45:33', '2023-08-08 14:16:07', NULL, '/job/log/all', '清空任务日志', 'job', 'DELETE'); +INSERT INTO `sys_apis` VALUES (81, '2021-12-24 15:46:08', '2023-08-08 14:16:15', NULL, '/job/log/:logId', '删除任务日志', 'job', 'DELETE'); +INSERT INTO `sys_apis` VALUES (82, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice/list', '获取通知分页列表', 'notice', 'GET'); +INSERT INTO `sys_apis` VALUES (83, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice', '添加通知信息', 'notice', 'POST'); +INSERT INTO `sys_apis` VALUES (84, '2021-12-24 15:45:33', '2021-12-24 15:45:33', NULL, '/system/notice', '修改通知信息', 'notice', 'PUT'); +INSERT INTO `sys_apis` VALUES (85, '2021-12-24 15:45:33', '2021-12-24 16:33:48', NULL, '/system/notice/:noticeId', '删除通知信息', 'notice', 'DELETE'); +INSERT INTO `sys_apis` VALUES (86, '2021-12-24 22:40:19', '2021-12-24 22:40:19', NULL, '/job/changeStatus', '修改状态', 'job', 'PUT'); +INSERT INTO `sys_apis` VALUES (88, '2022-01-02 13:53:06', '2022-07-18 10:57:58', NULL, '/develop/code/table/db/list', '数据库表列表', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (89, '2022-01-02 13:53:44', '2022-01-02 13:53:44', NULL, '/develop/code/table/list', '表列表', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (90, '2022-01-02 13:54:10', '2022-01-02 13:54:10', NULL, '/develop/code/table/info/:tableId', '表信息', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (91, '2022-01-02 13:54:42', '2022-07-18 10:58:35', NULL, '/develop/code/table/info/tableName', '表名获取表信息', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (92, '2022-01-02 13:55:13', '2022-01-02 13:55:13', NULL, '/develop/code/table/tableTree', '表树', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (93, '2022-01-02 13:56:37', '2022-01-02 13:56:37', NULL, '/develop/code/table', '导入表', 'gen', 'POST'); +INSERT INTO `sys_apis` VALUES (94, '2022-01-02 13:57:36', '2022-01-02 13:57:36', NULL, '/develop/code/table', '修改代码生成信息', 'gen', 'PUT'); +INSERT INTO `sys_apis` VALUES (95, '2022-01-02 13:58:25', '2022-01-02 13:58:25', NULL, '/develop/code/table/:tableId', '删除表数据', 'gen', 'DELETE'); +INSERT INTO `sys_apis` VALUES (96, '2022-01-02 13:59:07', '2022-01-02 13:59:07', NULL, '/develop/code/gen/preview/:tableId', '预览代码', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (97, '2022-01-02 13:59:43', '2022-01-02 13:59:43', NULL, '/develop/code/gen/code/:tableId', '生成代码', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (98, '2022-01-02 14:00:10', '2022-07-17 01:19:42', NULL, '/develop/code/gen/configure/:tableId', '生成api菜单', 'gen', 'GET'); +INSERT INTO `sys_apis` VALUES (124, '2023-06-29 16:59:08', '2023-06-29 17:00:17', NULL, '/device/product/category/list', '获取产品分类列表', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (125, '2023-06-29 17:00:08', '2023-06-29 17:00:08', NULL, '/device/product/category/list/all', '获取所有列表', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (126, '2023-06-29 17:00:56', '2023-06-29 17:00:56', NULL, '/device/product/category/list/tree', '获取树', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (127, '2023-06-29 17:01:44', '2023-06-29 17:01:44', NULL, '/device/product/category/:id', '查询单个', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (128, '2023-06-29 17:02:16', '2023-06-29 17:02:16', NULL, '/device/product/category', '添加分类', 'product', 'POST'); +INSERT INTO `sys_apis` VALUES (129, '2023-06-29 17:02:42', '2023-06-29 17:02:42', NULL, '/device/product/category', '修改分类', 'product', 'PUT'); +INSERT INTO `sys_apis` VALUES (130, '2023-06-29 17:03:07', '2023-06-29 17:03:07', NULL, '/device/product/category/:id', '删除分类', 'product', 'DELETE'); +INSERT INTO `sys_apis` VALUES (131, '2023-06-29 16:59:08', '2023-06-29 17:00:17', NULL, '/device/group/list', '获取设备分组列表', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (132, '2023-06-29 17:00:08', '2023-06-29 17:00:08', NULL, '/device/group/list/all', '获取所有列表', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (133, '2023-06-29 17:00:56', '2023-06-29 17:00:56', NULL, '/device/group/list/tree', '获取树', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (134, '2023-06-29 17:01:44', '2023-06-29 17:01:44', NULL, '/device/group/:id', '查询单个', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (135, '2023-06-29 17:02:16', '2023-06-29 17:02:16', NULL, '/device/group', '添加分组', 'device', 'POST'); +INSERT INTO `sys_apis` VALUES (136, '2023-06-29 17:02:42', '2023-06-29 17:02:42', NULL, '/device/group', '修改分组', 'device', 'PUT'); +INSERT INTO `sys_apis` VALUES (137, '2023-06-29 17:03:07', '2023-06-29 17:03:07', NULL, '/device/group/:id', '删除分组', 'device', 'DELETE'); +INSERT INTO `sys_apis` VALUES (138, '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL, '/device/product/:id', '删除产品信息', 'product', 'DELETE'); +INSERT INTO `sys_apis` VALUES (139, '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL, '/device/product/:id', '获取产品信息', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (140, '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL, '/device/product', '修改产品信息', 'product', 'PUT'); +INSERT INTO `sys_apis` VALUES (141, '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL, '/device/product/list', '查询产品列表(分页)', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (142, '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL, '/device/product', '添加产品信息', 'product', 'POST'); +INSERT INTO `sys_apis` VALUES (143, '2023-06-30 14:20:03', '2023-06-30 15:26:46', NULL, '/device/list', '查询设备列表(分页)', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (144, '2023-06-30 14:20:03', '2023-06-30 15:26:52', NULL, '/device/:id', '获取设备信息', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (145, '2023-06-30 14:20:03', '2023-06-30 15:26:57', NULL, '/device', '添加设备信息', 'device', 'POST'); +INSERT INTO `sys_apis` VALUES (146, '2023-06-30 14:20:03', '2023-06-30 15:27:04', NULL, '/device/:id', '删除设备信息', 'device', 'DELETE'); +INSERT INTO `sys_apis` VALUES (147, '2023-06-30 14:20:03', '2023-06-30 15:27:09', NULL, '/device', '修改设备信息', 'device', 'PUT'); +INSERT INTO `sys_apis` VALUES (148, '2023-06-30 15:11:25', '2023-08-02 16:06:13', NULL, '/device/group/list/tree/label', '获取设备组label', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (149, '2023-06-30 15:14:08', '2023-06-30 15:14:08', NULL, '/device/product/category/list/tree/label', '', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (150, '2023-07-01 10:44:25', '2023-07-01 10:44:25', NULL, '/upload/up/oss', '上传文件到oss', 'upload', 'POST'); +INSERT INTO `sys_apis` VALUES (151, '2023-07-06 15:31:15', '2023-07-06 15:31:15', NULL, '/device/ota/list', '查询产品固件列表(分页)', 'ota', 'GET'); +INSERT INTO `sys_apis` VALUES (152, '2023-07-06 15:31:15', '2023-07-06 15:31:15', NULL, '/device/ota', '添加产品固件信息', 'ota', 'POST'); +INSERT INTO `sys_apis` VALUES (153, '2023-07-06 15:31:15', '2023-07-06 15:31:15', NULL, '/device/ota', '修改产品固件信息', 'ota', 'PUT'); +INSERT INTO `sys_apis` VALUES (154, '2023-07-06 15:31:15', '2023-07-06 15:31:15', NULL, '/device/ota/:id', '删除产品固件信息', 'ota', 'DELETE'); +INSERT INTO `sys_apis` VALUES (155, '2023-07-06 15:31:15', '2023-07-06 15:31:15', NULL, '/device/ota/:id', '获取产品固件信息', 'ota', 'GET'); +INSERT INTO `sys_apis` VALUES (156, '2023-07-06 15:32:10', '2023-07-06 15:32:10', NULL, '/device/template/list', '查询产品模型列表(分页)', 'template', 'GET'); +INSERT INTO `sys_apis` VALUES (157, '2023-07-06 15:32:10', '2023-07-06 15:32:10', NULL, '/device/template', '修改产品模型信息', 'template', 'PUT'); +INSERT INTO `sys_apis` VALUES (158, '2023-07-06 15:32:10', '2023-07-06 15:32:10', NULL, '/device/template/:id', '获取产品模型信息', 'template', 'GET'); +INSERT INTO `sys_apis` VALUES (159, '2023-07-06 15:32:10', '2023-07-06 15:32:10', NULL, '/device/template/:id', '删除产品模型信息', 'template', 'DELETE'); +INSERT INTO `sys_apis` VALUES (160, '2023-07-06 15:32:10', '2023-07-06 15:32:10', NULL, '/device/template', '添加产品模型信息', 'template', 'POST'); +INSERT INTO `sys_apis` VALUES (161, '2023-07-07 16:35:45', '2023-07-07 16:35:45', NULL, '/device/product/list/all', '获取所有列表', 'product', 'GET'); +INSERT INTO `sys_apis` VALUES (162, '2023-04-13 09:03:47', '2023-04-13 09:03:47', NULL, '/visual/screen', '修改bi大屏信息', 'screen', 'PUT'); +INSERT INTO `sys_apis` VALUES (163, '2023-04-13 09:03:47', '2023-04-13 09:03:47', NULL, '/visual/screen/:screenId', '获取bi大屏信息', 'screen', 'GET'); +INSERT INTO `sys_apis` VALUES (164, '2023-04-13 09:03:47', '2023-04-13 09:03:47', NULL, '/visual/screen/list', '查询bi大屏列表(分页)', 'screen', 'GET'); +INSERT INTO `sys_apis` VALUES (165, '2023-04-13 09:03:47', '2023-04-13 09:03:47', NULL, '/visual/screen/:screenId', '删除bi大屏信息', 'screen', 'DELETE'); +INSERT INTO `sys_apis` VALUES (166, '2023-04-13 09:03:47', '2023-04-13 09:03:47', NULL, '/visual/screen', '添加bi大屏信息', 'screen', 'POST'); +INSERT INTO `sys_apis` VALUES (167, '2023-04-13 10:15:27', '2023-04-13 10:15:27', NULL, '/visual/screen/group/list', '大屏分组列表', 'screen_group', 'GET'); +INSERT INTO `sys_apis` VALUES (168, '2023-04-13 10:16:15', '2023-04-13 10:16:15', NULL, '/visual/screen/group/list/tree', '大屏分组列表树', 'screen_group', 'GET'); +INSERT INTO `sys_apis` VALUES (169, '2023-04-13 10:16:38', '2023-04-13 10:16:38', NULL, '/visual/screen/group/list/all', '获取所有分组', 'screen_group', 'GET'); +INSERT INTO `sys_apis` VALUES (170, '2023-04-13 10:17:34', '2023-04-13 10:17:34', NULL, '/visual/screen/group/:id', '获取分组', 'screen_group', 'GET'); +INSERT INTO `sys_apis` VALUES (171, '2023-04-13 10:18:10', '2023-04-13 10:18:10', NULL, '/visual/screen/group', '添加分组', 'screen_group', 'POST'); +INSERT INTO `sys_apis` VALUES (172, '2023-04-13 10:18:35', '2023-04-13 10:18:35', NULL, '/visual/screen/group', '修改分组', 'screen_group', 'PUT'); +INSERT INTO `sys_apis` VALUES (173, '2023-04-13 10:19:09', '2023-04-13 10:19:09', NULL, '/visual/screen/group/:id', '删除分组', 'screen_group', 'DELETE'); +INSERT INTO `sys_apis` VALUES (174, '2023-04-13 15:49:39', '2023-04-13 15:49:39', NULL, '/visual/screen/changeStatus', '改变状态', 'screen', 'PUT'); +INSERT INTO `sys_apis` VALUES (175, '2023-04-13 15:50:18', '2023-07-21 17:44:48', NULL, '/rule/chain/changeRoot', '改变规则链', 'rulechain', 'PUT'); +INSERT INTO `sys_apis` VALUES (176, '2023-04-11 02:05:25', '2023-04-11 02:05:25', NULL, '/rule/chain/list', '查询规则链列表(分页)', 'rulechain', 'GET'); +INSERT INTO `sys_apis` VALUES (177, '2023-04-11 02:05:25', '2023-04-11 02:05:25', NULL, '/rule/chain/:ruleId', '删除规则链信息', 'rulechain', 'DELETE'); +INSERT INTO `sys_apis` VALUES (178, '2023-04-11 02:05:25', '2023-04-11 02:05:25', NULL, '/rule/chain', '修改规则链信息', 'rulechain', 'PUT'); +INSERT INTO `sys_apis` VALUES (179, '2023-04-11 02:05:25', '2023-04-11 02:05:25', NULL, '/rule/chain', '添加规则链信息', 'rulechain', 'POST'); +INSERT INTO `sys_apis` VALUES (180, '2023-04-11 02:05:25', '2023-04-11 02:05:25', NULL, '/rule/chain/:ruleId', '获取规则链信息', 'rulechain', 'GET'); +INSERT INTO `sys_apis` VALUES (181, '2023-07-24 11:51:10', '2023-07-24 11:51:10', NULL, '/rule/chain/list/label', '获取规则链label列表', 'rulechain', 'GET'); +INSERT INTO `sys_apis` VALUES (182, '2023-07-31 14:14:06', '2023-07-31 14:14:06', NULL, '/device/list/all', '获取所有设备', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (183, '2023-08-02 16:05:24', '2023-08-02 16:05:24', NULL, '/device/:id/status', '获取设备状态', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (184, '2023-08-03 09:50:41', '2023-08-03 09:50:41', NULL, '/rule/chain/clone/:ruleId', '克隆规则链', 'rulechain', 'POST'); +INSERT INTO `sys_apis` VALUES (185, '2023-08-03 14:16:55', '2023-08-03 14:16:55', NULL, '/device/alarm/list', '告警分页列表', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (186, '2023-08-03 14:17:23', '2023-08-03 14:17:23', NULL, '/device/alarm', '修改告警', 'device', 'PUT'); +INSERT INTO `sys_apis` VALUES (187, '2023-08-03 14:18:14', '2023-08-03 14:18:14', NULL, '/device/alarm/:id', '删除告警信息', 'device', 'DELETE'); +INSERT INTO `sys_apis` VALUES (188, '2023-08-04 10:59:57', '2023-08-04 10:59:57', NULL, '/device/cmd/list', '设备命令日志列表', 'device', 'GET'); +INSERT INTO `sys_apis` VALUES (189, '2023-08-04 11:00:18', '2023-08-04 11:00:18', NULL, '/device/cmd', '下发命令', 'device', 'POST'); +INSERT INTO `sys_apis` VALUES (190, '2023-08-04 11:00:46', '2023-08-04 11:00:46', NULL, '/device/cmd/:id', '删除命令记录', 'device', 'DELETE'); +INSERT INTO `sys_apis` VALUES (191, '2023-08-04 14:16:06', '2023-08-04 14:16:06', NULL, '/device/template/list/all', '查询所有tsl', 'template', 'GET'); +INSERT INTO `sys_apis` VALUES (192, '2023-08-04 16:39:06', '2023-08-04 16:39:06', NULL, '/device/:id/attribute/down', '下发设备属性', 'device', 'GET'); + +-- ---------------------------- +-- Table structure for sys_configs +-- ---------------------------- +DROP TABLE IF EXISTS `sys_configs`; +CREATE TABLE `sys_configs` ( + `config_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键编码', + `config_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ConfigName', + `config_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ConfigKey', + `config_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ConfigValue', + `config_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否系统内置0,1', + `is_frontend` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否前台', + `remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Remark', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_configs +-- ---------------------------- +INSERT INTO `sys_configs` VALUES (1, '账号初始密码', 'sys.user.initPassword', '123456', '0', '0', '初始密码', '2021-12-04 13:50:13', '2021-12-04 13:54:52', NULL); + +-- ---------------------------- +-- Table structure for sys_depts +-- ---------------------------- +DROP TABLE IF EXISTS `sys_depts`; +CREATE TABLE `sys_depts` ( + `dept_id` bigint(0) NOT NULL AUTO_INCREMENT, + `parent_id` int(0) NULL DEFAULT NULL COMMENT '上级部门', + `dept_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门路径', + `dept_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门名称', + `sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `leader` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '手机', + `email` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '修改人', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`dept_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_depts +-- ---------------------------- +INSERT INTO `sys_depts` VALUES (2, 0, '/0/2', '熊猫科技', 0, 'xm', '18353366836', '342@qq.com', '0', 'admin', 'admin', '2021-12-01 17:31:53', '2021-12-02 08:56:19', NULL); +INSERT INTO `sys_depts` VALUES (3, 2, '/0/2/3', '研发部', 1, 'panda', '18353366543', 'ewr@qq.com', '0', 'admin', 'admin', '2021-12-01 17:37:43', '2021-12-02 08:55:56', NULL); +INSERT INTO `sys_depts` VALUES (7, 2, '/0/2/7', '营销部', 2, 'panda', '18353333333', '342@qq.com', '0', 'panda', 'panda', '2021-12-24 10:46:24', '2021-12-24 10:47:15', NULL); + +-- ---------------------------- +-- Table structure for sys_dict_data +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `dict_code` bigint(0) NOT NULL AUTO_INCREMENT, + `dict_sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `dict_label` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标签', + `dict_value` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '值', + `dict_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '字典类型', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态(0正常 1停用)', + `css_class` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'CssClass', + `list_class` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ListClass', + `is_default` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'IsDefault', + `create_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `update_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`dict_code`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES (1, 0, '男', '0', 'sys_user_sex', '0', '', '', '', 'admin', '', '男', '2021-11-30 14:58:18', '2021-11-30 14:58:18', NULL); +INSERT INTO `sys_dict_data` VALUES (2, 1, '女', '1', 'sys_user_sex', '0', '', '', '', 'admin', '', '女生', '2021-11-30 15:09:11', '2021-11-30 15:10:28', NULL); +INSERT INTO `sys_dict_data` VALUES (3, 2, '未知', '2', 'sys_user_sex', '0', '', '', '', 'admin', '', '未知', '2021-11-30 15:09:11', '2021-11-30 15:10:28', NULL); +INSERT INTO `sys_dict_data` VALUES (4, 0, '正常', '0', 'sys_normal_disable', '0', '', '', '', 'admin', '', '', '2021-12-01 15:58:50', '2021-12-01 15:58:50', NULL); +INSERT INTO `sys_dict_data` VALUES (5, 1, '停用', '1', 'sys_normal_disable', '0', '', '', '', 'admin', '', '', '2021-12-01 15:59:08', '2021-12-01 15:59:08', NULL); +INSERT INTO `sys_dict_data` VALUES (6, 0, '目录', 'M', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:12', '2021-12-02 09:49:12', NULL); +INSERT INTO `sys_dict_data` VALUES (7, 1, '菜单', 'C', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:35', '2021-12-02 09:49:52', NULL); +INSERT INTO `sys_dict_data` VALUES (8, 2, '按钮', 'F', 'sys_menu_type', '0', '', '', '', 'admin', '', '', '2021-12-02 09:49:35', '2021-12-02 09:49:35', NULL); +INSERT INTO `sys_dict_data` VALUES (9, 0, '显示', '0', 'sys_show_hide', '0', '', '', '', 'admin', '', '', '2021-12-02 09:56:40', '2021-12-02 09:56:40', NULL); +INSERT INTO `sys_dict_data` VALUES (10, 0, '隐藏', '1', 'sys_show_hide', '0', '', '', '', 'admin', '', '', '2021-12-02 09:56:52', '2021-12-02 09:56:52', NULL); +INSERT INTO `sys_dict_data` VALUES (11, 0, '是', '0', 'sys_num_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-02 10:16:16', '2021-12-02 10:16:16', NULL); +INSERT INTO `sys_dict_data` VALUES (12, 1, '否', '1', 'sys_num_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-02 10:16:26', '2021-12-02 10:16:26', NULL); +INSERT INTO `sys_dict_data` VALUES (13, 0, '是', '0', 'sys_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-04 13:48:15', '2021-12-04 13:48:15', NULL); +INSERT INTO `sys_dict_data` VALUES (14, 0, '否', '1', 'sys_yes_no', '0', '', '', '', 'admin', '', '', '2021-12-04 13:48:21', '2021-12-04 13:48:21', NULL); +INSERT INTO `sys_dict_data` VALUES (15, 0, '创建(POST)', 'POST', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:05', '2021-12-09 09:29:52', NULL); +INSERT INTO `sys_dict_data` VALUES (16, 1, '查询(GET)', 'GET', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:24', '2021-12-09 09:29:59', NULL); +INSERT INTO `sys_dict_data` VALUES (17, 2, '修改(PUT)', 'PUT', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:40', '2021-12-09 09:30:06', NULL); +INSERT INTO `sys_dict_data` VALUES (18, 3, '删除(DELETE)', 'DELETE', 'sys_method_api', '0', '', '', '', 'admin', '', '', '2021-12-08 17:22:54', '2021-12-09 09:30:13', NULL); +INSERT INTO `sys_dict_data` VALUES (19, 0, '成功', '0', 'sys_common_status', '0', '', '', '', 'admin', '', '', '2021-12-17 11:01:52', '2021-12-17 11:01:52', NULL); +INSERT INTO `sys_dict_data` VALUES (20, 0, '失败', '1', 'sys_common_status', '0', '', '', '', 'admin', '', '', '2021-12-17 11:02:08', '2021-12-17 11:02:08', NULL); +INSERT INTO `sys_dict_data` VALUES (21, 0, '其他', '0', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:07', '2021-12-17 11:30:07', NULL); +INSERT INTO `sys_dict_data` VALUES (22, 0, '新增', '1', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:21', '2021-12-17 11:30:21', NULL); +INSERT INTO `sys_dict_data` VALUES (23, 0, '修改', '2', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:32', '2021-12-17 11:30:32', NULL); +INSERT INTO `sys_dict_data` VALUES (24, 0, '删除', '3', 'sys_oper_type', '0', '', '', '', 'admin', '', '', '2021-12-17 11:30:40', '2021-12-17 11:30:40', NULL); +INSERT INTO `sys_dict_data` VALUES (25, 0, '默认', 'DEFAULT', 'sys_job_group', '0', '', '', '', 'panda', '', '', '2021-12-24 15:15:31', '2021-12-24 15:15:31', NULL); +INSERT INTO `sys_dict_data` VALUES (26, 1, '系统', 'SYSTEM', 'sys_job_group', '0', '', '', '', 'panda', '', '', '2021-12-24 15:15:50', '2021-12-24 15:15:50', NULL); +INSERT INTO `sys_dict_data` VALUES (27, 0, '发布通知', '1', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:07', '2021-12-26 15:24:07', NULL); +INSERT INTO `sys_dict_data` VALUES (28, 0, '任免通知', '2', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:18', '2021-12-26 15:24:18', NULL); +INSERT INTO `sys_dict_data` VALUES (29, 0, '事物通知', '3', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:24:46', '2021-12-26 15:24:46', NULL); +INSERT INTO `sys_dict_data` VALUES (30, 0, '审批通知', '4', 'sys_notice_type', '0', '', '', '', 'panda', '', '', '2021-12-26 15:25:08', '2021-12-26 15:25:08', NULL); +INSERT INTO `sys_dict_data` VALUES (31, 0, '阿里云', '0', 'res_oss_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:44:01', '2022-01-13 15:44:01', NULL); +INSERT INTO `sys_dict_data` VALUES (32, 1, '七牛云', '1', 'res_oss_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:44:18', '2022-01-13 15:44:18', NULL); +INSERT INTO `sys_dict_data` VALUES (33, 2, '腾讯云', '2', 'res_oss_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:44:39', '2022-01-13 15:44:39', NULL); +INSERT INTO `sys_dict_data` VALUES (34, 0, '阿里云', '0', 'res_sms_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:47:30', '2022-01-13 15:47:30', NULL); +INSERT INTO `sys_dict_data` VALUES (35, 1, '腾讯云', '1', 'res_sms_category', '0', '', '', '', 'panda', '', '', '2022-01-13 15:47:39', '2022-01-13 15:47:39', NULL); +INSERT INTO `sys_dict_data` VALUES (36, 0, '163邮箱', '0', 'res_mail_category', '0', '', '', '', 'panda', '', '', '2022-01-14 15:43:42', '2022-01-14 15:43:42', NULL); +INSERT INTO `sys_dict_data` VALUES (37, 0, 'qq邮箱', '1', 'res_mail_category', '0', '', '', '', 'panda', '', '', '2022-01-14 15:44:08', '2022-01-14 15:44:08', NULL); +INSERT INTO `sys_dict_data` VALUES (38, 0, '企业邮箱', '2', 'res_mail_category', '0', '', '', '', 'panda', '', '', '2022-01-14 15:44:20', '2022-01-14 15:44:20', NULL); +INSERT INTO `sys_dict_data` VALUES (39, 1, '未发布', '0', 'sys_release_type', '0', '', '', '', 'panda', '', '', '2023-07-21 16:11:27', '2023-07-21 16:11:27', NULL); +INSERT INTO `sys_dict_data` VALUES (40, 2, '已发布', '1', 'sys_release_type', '0', '', '', '', 'panda', '', '', '2023-07-21 16:11:44', '2023-07-21 16:11:44', NULL); + +-- ---------------------------- +-- Table structure for sys_dict_types +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_types`; +CREATE TABLE `sys_dict_types` ( + `dict_id` bigint(0) NOT NULL AUTO_INCREMENT, + `dict_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '名称', + `dict_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '类型', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', + `create_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `update_by` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`dict_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_types +-- ---------------------------- +INSERT INTO `sys_dict_types` VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '', '性别列表', '2021-11-30 14:02:52', '2021-11-30 14:07:55', '2021-11-30 14:11:54'); +INSERT INTO `sys_dict_types` VALUES (2, '用户性别', 'sys_user_sex', '0', 'admin', '', '用户性别列表', '2021-11-30 14:12:33', '2021-11-30 14:12:33', '2021-11-30 14:14:19'); +INSERT INTO `sys_dict_types` VALUES (3, '的心', 'sfd', '0', 'admin', '', 'fs', '2021-11-30 14:13:22', '2021-11-30 14:13:22', '2021-11-30 14:14:19'); +INSERT INTO `sys_dict_types` VALUES (4, '用户性别', 'sys_user_sex', '0', 'admin', '', '性别字典', '2021-11-30 14:15:25', '2021-11-30 14:15:25', NULL); +INSERT INTO `sys_dict_types` VALUES (5, 'df', 'da', '0', 'admin', '', 'sd', '2021-11-30 15:54:33', '2021-11-30 15:54:33', '2021-11-30 15:54:40'); +INSERT INTO `sys_dict_types` VALUES (6, '系统开关', 'sys_normal_disable', '0', 'admin', '', '开关列表', '2021-12-01 15:57:58', '2021-12-01 15:57:58', NULL); +INSERT INTO `sys_dict_types` VALUES (7, '菜单类型', 'sys_menu_type', '0', 'admin', '', '菜单类型列表', '2021-12-02 09:48:48', '2021-12-02 09:56:12', NULL); +INSERT INTO `sys_dict_types` VALUES (8, '菜单状态', 'sys_show_hide', '0', 'admin', '', '菜单状态列表', '2021-12-02 09:55:59', '2021-12-02 09:55:59', NULL); +INSERT INTO `sys_dict_types` VALUES (9, '数字是否', 'sys_num_yes_no', '0', 'admin', '', '数字是否列表', '2021-12-02 10:13:29', '2021-12-02 10:13:40', '2021-12-02 10:15:07'); +INSERT INTO `sys_dict_types` VALUES (10, '数字是否', 'sys_num_yes_no', '0', 'admin', '', '数字是否', '2021-12-02 10:13:29', '2021-12-02 10:13:29', NULL); +INSERT INTO `sys_dict_types` VALUES (11, '状态是否', 'sys_yes_no', '0', 'admin', '', '状态是否', '2021-12-04 13:47:57', '2021-12-04 13:47:57', NULL); +INSERT INTO `sys_dict_types` VALUES (12, '网络请求方法', 'sys_method_api', '0', 'admin', '', '网络请求方法列表', '2021-12-08 17:21:27', '2021-12-08 17:21:27', NULL); +INSERT INTO `sys_dict_types` VALUES (13, '成功失败', 'sys_common_status', '0', 'admin', '', '是否成功失败', '2021-12-17 10:10:03', '2021-12-17 10:10:03', NULL); +INSERT INTO `sys_dict_types` VALUES (27, '操作分类', 'sys_oper_type', '0', 'admin', '', '操作分类列表', '2021-12-17 11:29:50', '2021-12-17 11:29:50', NULL); +INSERT INTO `sys_dict_types` VALUES (28, '任务组', 'sys_job_group', '0', 'panda', '', '系统任务,开机自启', '2021-12-24 15:14:56', '2021-12-24 15:14:56', NULL); +INSERT INTO `sys_dict_types` VALUES (29, '通知类型', 'sys_notice_type', '0', 'panda', '', '通知类型列表', '2021-12-26 15:23:26', '2021-12-26 15:23:26', NULL); +INSERT INTO `sys_dict_types` VALUES (30, 'oss分类', 'res_oss_category', '0', 'panda', '', 'oss分类列表', '2022-01-13 15:43:29', '2022-01-13 15:43:29', NULL); +INSERT INTO `sys_dict_types` VALUES (31, 'sms分类', 'res_sms_category', '0', 'panda', '', 'sms分类列表', '2021-12-26 15:23:26', '2022-01-13 15:47:13', NULL); +INSERT INTO `sys_dict_types` VALUES (32, 'mail分类', 'res_mail_category', '0', 'panda', '', 'mail分类列表', '2022-01-14 15:43:17', '2022-01-14 15:43:17', NULL); +INSERT INTO `sys_dict_types` VALUES (33, '发布状态', 'sys_release_type', '0', 'panda', '', '发布状态', '2023-07-21 16:10:38', '2023-07-21 16:10:38', NULL); + +-- ---------------------------- +-- Table structure for sys_menus +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menus`; +CREATE TABLE `sys_menus` ( + `menu_id` bigint(0) NOT NULL AUTO_INCREMENT, + `menu_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `parent_id` int(0) NULL DEFAULT NULL, + `sort` int(0) NULL DEFAULT NULL, + `icon` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `path` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `is_iframe` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `is_link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `menu_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `is_hide` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `is_keep_alive` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `is_affix` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `permission` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `status` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `remark` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`menu_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 161 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_menus +-- ---------------------------- +INSERT INTO `sys_menus` VALUES (1, '系统设置', '', 0, 0, 'elementSetting', '/system', 'Layout', '1', '', 'M', '0', '0', '1', '', '0', 'admin', 'panda', '', '2021-12-02 11:04:08', '2021-12-28 13:32:21', NULL); +INSERT INTO `sys_menus` VALUES (3, '用户管理', '', 1, 1, 'elementUser', '/system/user', '/system/user/index', '1', '', 'C', '0', '1', '1', 'system:user:list', '0', 'admin', 'panda', '', '2021-12-02 14:07:56', '2021-12-28 13:32:44', NULL); +INSERT INTO `sys_menus` VALUES (4, '添加用户', '', 3, 1, '', '', '', '', '', 'F', '0', '', '', 'system:user:add', '0', 'admin', '', '', '2021-12-03 13:36:33', '2021-12-03 13:36:33', NULL); +INSERT INTO `sys_menus` VALUES (5, '编辑用户', '', 3, 1, '', '', '', '', '', 'F', '0', '', '', 'system:user:edit', '0', 'admin', '', '', '2021-12-03 13:48:13', '2021-12-03 13:48:13', NULL); +INSERT INTO `sys_menus` VALUES (6, '角色管理', '', 1, 2, 'elementUserFilled', '/system/role', '/system/role/index', '1', '', 'C', '0', '1', '1', 'system:role:list', '0', '', 'panda', '', '2021-12-03 13:51:55', '2022-07-16 10:23:21', NULL); +INSERT INTO `sys_menus` VALUES (7, '菜单管理', '', 1, 2, 'iconfont icon-juxingkaobei', '/system/menu', '/system/menu/index', '1', '', 'C', '0', '1', '1', 'system:menu:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:33:19', NULL); +INSERT INTO `sys_menus` VALUES (8, '组织管理', '', 1, 3, 'iconfont icon-jiliandongxuanzeqi', '/system/dept', '/system/dept/index', '1', '', 'C', '0', '1', '1', 'system:dept:list', '0', '', 'panda', '', '2021-12-03 13:58:36', '2023-05-30 16:34:36', NULL); +INSERT INTO `sys_menus` VALUES (9, '岗位管理', '', 1, 4, 'iconfont icon-neiqianshujuchucun', '/system/post', '/system/post/index', '1', '', 'C', '0', '1', '1', 'system:post:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:40:31', NULL); +INSERT INTO `sys_menus` VALUES (10, '字典管理', '', 1, 5, 'elementCellphone', '/system/dict', '/system/dict/index', '1', '', 'C', '0', '1', '1', 'system:dict:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:40:50', NULL); +INSERT INTO `sys_menus` VALUES (11, '参数管理', '', 1, 6, 'elementDocumentCopy', '/system/config', '/system/config/index', '1', '', 'C', '0', '1', '1', 'system:config:list', '0', 'admin', 'panda', '', '2021-12-03 13:54:44', '2021-12-28 13:41:05', NULL); +INSERT INTO `sys_menus` VALUES (12, '个人中心', '', 0, 10, 'elementAvatar', '/personal', '/personal/index', '1', '', 'M', '1', '0', '0', '', '0', 'admin', 'panda', '', '2021-12-03 14:12:43', '2023-06-27 10:09:26', NULL); +INSERT INTO `sys_menus` VALUES (13, '添加配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:add', '0', 'admin', '', '', '2021-12-06 17:19:19', '2021-12-06 17:19:19', NULL); +INSERT INTO `sys_menus` VALUES (14, '修改配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:edit', '0', 'admin', '', '', '2021-12-06 17:20:30', '2021-12-06 17:20:30', NULL); +INSERT INTO `sys_menus` VALUES (15, '删除配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:delete', '0', 'admin', '', '', '2021-12-06 17:23:52', '2021-12-06 17:23:52', NULL); +INSERT INTO `sys_menus` VALUES (16, '导出配置', '', 11, 1, '', '', '', '', '', 'F', '', '', '', 'system:config:export', '0', 'admin', '', '', '2021-12-06 17:24:41', '2021-12-06 17:24:41', NULL); +INSERT INTO `sys_menus` VALUES (17, '新增角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:add', '0', 'admin', '', '', '2021-12-06 17:43:35', '2021-12-06 17:43:35', NULL); +INSERT INTO `sys_menus` VALUES (18, '删除角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:delete', '0', 'admin', '', '', '2021-12-06 17:44:10', '2021-12-06 17:44:10', NULL); +INSERT INTO `sys_menus` VALUES (19, '修改角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:edit', '0', 'admin', '', '', '2021-12-06 17:44:48', '2021-12-06 17:44:48', NULL); +INSERT INTO `sys_menus` VALUES (20, '导出角色', '', 6, 1, '', '', '', '', '', 'F', '', '', '', 'system:role:export', '0', 'admin', '', '', '2021-12-06 17:45:25', '2021-12-06 17:45:25', NULL); +INSERT INTO `sys_menus` VALUES (21, '添加菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:add', '0', 'admin', '', '', '2021-12-06 17:46:01', '2021-12-06 17:46:01', NULL); +INSERT INTO `sys_menus` VALUES (22, '修改菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:edit', '0', 'admin', '', '', '2021-12-06 17:46:24', '2021-12-06 17:46:24', NULL); +INSERT INTO `sys_menus` VALUES (23, '删除菜单', '', 7, 1, '', '', '', '', '', 'F', '', '', '', 'system:menu:delete', '0', 'admin', '', '', '2021-12-06 17:46:47', '2021-12-06 17:46:47', NULL); +INSERT INTO `sys_menus` VALUES (24, '添加部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:add', '0', 'admin', '', '', '2021-12-07 09:33:58', '2021-12-07 09:33:58', NULL); +INSERT INTO `sys_menus` VALUES (25, '编辑部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:edit', '0', 'admin', '', '', '2021-12-07 09:34:39', '2021-12-07 09:34:39', NULL); +INSERT INTO `sys_menus` VALUES (26, '删除部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:delete', '0', 'admin', 'admin', '', '2021-12-07 09:35:09', '2021-12-07 09:36:26', NULL); +INSERT INTO `sys_menus` VALUES (27, '导出部门', '', 8, 1, '', '', '', '', '', 'F', '', '', '', 'system:dept:export', '0', 'admin', '', '', '2021-12-07 09:35:51', '2021-12-07 09:35:51', '2021-12-07 09:36:37'); +INSERT INTO `sys_menus` VALUES (28, '添加岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (29, '编辑岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:edit', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (30, '删除岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:delete', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (31, '导出岗位', '', 9, 1, '', '', '', '', '', 'F', '', '', '', 'system:post:export', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (32, '添加字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (33, '编辑字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:edit', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (34, '删除字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:delete', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (35, '导出字典类型', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictT:export', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (36, '新增字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:add', '0', 'admin', '', '', '2021-12-07 09:35:09', '2021-12-07 09:35:09', NULL); +INSERT INTO `sys_menus` VALUES (37, '修改字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:edit', '0', 'admin', '', '', '2021-12-07 09:48:04', '2021-12-07 09:48:04', NULL); +INSERT INTO `sys_menus` VALUES (38, '删除字典数据', '', 10, 1, '', '', '', '', '', 'F', '', '', '', 'system:dictD:delete', '0', 'admin', '', '', '2021-12-07 09:48:42', '2021-12-07 09:48:42', NULL); +INSERT INTO `sys_menus` VALUES (39, 'API管理', '', 1, 2, 'iconfont icon-siweidaotu', '/system/api', '/system/api/index', '1', '', 'C', '0', '1', '1', 'system:api:list', '0', '', 'panda', '', '2021-12-09 09:09:13', '2022-07-16 10:23:42', NULL); +INSERT INTO `sys_menus` VALUES (40, '添加api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:add', '0', 'admin', '', '', '2021-12-09 09:09:54', '2021-12-09 09:09:54', NULL); +INSERT INTO `sys_menus` VALUES (41, '编辑api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:edit', '0', 'admin', '', '', '2021-12-09 09:10:38', '2021-12-09 09:10:38', NULL); +INSERT INTO `sys_menus` VALUES (42, '删除api', '', 39, 1, '', '/system/api', '', '', '', 'F', '', '', '', 'system:api:delete', '0', 'admin', '', '', '2021-12-09 09:11:11', '2021-12-09 09:11:11', NULL); +INSERT INTO `sys_menus` VALUES (43, '日志系统', '', 0, 11, 'iconfont icon-biaodan', '/log', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-02 11:04:08', '2023-06-30 08:57:08', NULL); +INSERT INTO `sys_menus` VALUES (44, '运维监控', '', 0, 9, 'iconfont icon-gongju', '/tool', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-16 16:35:15', '2023-06-27 10:09:16', NULL); +INSERT INTO `sys_menus` VALUES (45, '操作日志', '', 43, 1, 'iconfont icon-bolangnengshiyanchang', '/log/operation', '/log/operation/index', '1', '', 'C', '0', '1', '1', 'log:operation:list', '0', 'admin', 'panda', '', '2021-12-16 16:42:03', '2021-12-28 13:39:44', NULL); +INSERT INTO `sys_menus` VALUES (46, '登录日志', '', 43, 2, 'iconfont icon--chaifenlie', '/log/login', '/log/login/index', '1', '', 'C', '0', '1', '1', 'log:login:list', '0', 'admin', 'panda', '', '2021-12-16 16:43:28', '2021-12-28 13:39:58', NULL); +INSERT INTO `sys_menus` VALUES (47, '服务监控', '', 44, 1, 'elementCpu', '/tool/monitor/', '/tool/monitor/index', '1', '', 'C', '0', '1', '1', 'tool:monitor:list', '0', 'admin', 'panda', '', '2021-12-03 14:12:43', '2021-12-28 13:41:25', NULL); +INSERT INTO `sys_menus` VALUES (49, '开发工具', '', 0, 10, 'iconfont icon-zhongduancanshu', '/develop', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'admin', 'panda', '', '2021-12-16 16:53:11', '2023-06-29 16:29:23', NULL); +INSERT INTO `sys_menus` VALUES (50, '表单构建', '', 49, 1, 'iconfont icon-zidingyibuju', '/develop/form', '/develop/form/index', '1', '', 'C', '0', '1', '1', 'develop:form:list', '0', 'admin', 'panda', '', '2021-12-16 16:55:01', '2022-07-12 18:56:18', NULL); +INSERT INTO `sys_menus` VALUES (51, '代码生成', '', 49, 2, 'iconfont icon-zhongduancanshu', '/develop/code', '/develop/code/index', '1', '', 'C', '0', '1', '1', 'develop:code:list', '0', 'admin', '', '', '2021-12-16 16:56:48', '2021-12-16 16:56:48', NULL); +INSERT INTO `sys_menus` VALUES (52, '系统接口', '', 49, 3, 'iconfont icon-wenducanshu-05', '/develop/apis', '/layout/routerView/iframes', '0', 'http://47.104.252.2:8080/swagger/index.html', 'C', '0', '1', '1', 'develop:apis:list', '0', '', 'panda', '', '2021-12-16 16:58:07', '2022-07-13 11:50:34', NULL); +INSERT INTO `sys_menus` VALUES (54, '对象存储', '', 53, 1, 'iconfont icon-chazhaobiaodanliebiao', '/resource/file', '/resource/file/index', '1', '', 'C', '0', '1', '1', 'resource:file:list', '0', 'admin', 'panda', '', '2021-12-16 17:06:04', '2022-01-13 17:30:09', NULL); +INSERT INTO `sys_menus` VALUES (55, '公告通知', '', 44, 3, 'elementTicket', '/tool/notice', '/tool/notice/index', '1', '', 'C', '0', '1', '1', 'tool:notice:list', '0', 'admin', 'panda', '', '2021-12-16 22:09:11', '2021-12-28 13:42:39', NULL); +INSERT INTO `sys_menus` VALUES (59, '删除', '', 45, 1, '', '', '', '', '', 'F', '', '', '', 'log:operation:delete', '0', 'panda', '', '', '2022-01-14 13:28:25', '2022-01-14 13:28:25', NULL); +INSERT INTO `sys_menus` VALUES (60, '清空', '', 45, 1, '', '', '', '', '', 'F', '', '', '', 'log:operation:clean', '0', 'panda', '', '', '2022-01-14 13:29:24', '2022-01-14 13:29:24', NULL); +INSERT INTO `sys_menus` VALUES (63, '删除', '', 46, 1, '', '', '', '', '', 'F', '', '', '', 'log:login:delete', '0', 'panda', '', '', '2022-01-14 13:30:46', '2022-01-14 13:30:46', NULL); +INSERT INTO `sys_menus` VALUES (64, '清空', '', 46, 1, '', '', '', '', '', 'F', '', '', '', 'log:login:clean', '0', 'panda', '', '', '2022-01-14 13:31:06', '2022-01-14 13:31:06', NULL); +INSERT INTO `sys_menus` VALUES (69, '添加', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:add', '0', 'panda', '', '', '2022-01-14 13:35:23', '2022-01-14 13:35:23', NULL); +INSERT INTO `sys_menus` VALUES (70, '编辑', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:edit', '0', 'panda', '', '', '2022-01-14 13:36:04', '2022-01-14 13:36:04', NULL); +INSERT INTO `sys_menus` VALUES (71, '删除', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:delete', '0', 'panda', '', '', '2022-01-14 13:36:26', '2022-01-14 13:36:26', NULL); +INSERT INTO `sys_menus` VALUES (72, '查看', '', 55, 1, '', '', '', '', '', 'F', '', '', '', 'tool:notice:view', '0', 'panda', '', '', '2022-01-14 13:36:51', '2022-01-14 13:36:51', NULL); +INSERT INTO `sys_menus` VALUES (73, '导入', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:add', '0', 'panda', '', '', '2022-01-14 13:38:35', '2022-01-14 13:38:35', NULL); +INSERT INTO `sys_menus` VALUES (74, '编辑', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:edit', '0', 'panda', '', '', '2022-01-14 13:41:25', '2022-01-14 13:41:25', NULL); +INSERT INTO `sys_menus` VALUES (75, '删除', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:delete', '0', 'panda', '', '', '2022-01-14 13:41:42', '2022-01-14 13:41:42', NULL); +INSERT INTO `sys_menus` VALUES (76, '预览', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:view', '0', 'panda', '', '', '2022-01-14 13:42:01', '2022-01-14 13:42:01', NULL); +INSERT INTO `sys_menus` VALUES (77, '生成代码', '', 51, 1, '', '', '', '', '', 'F', '', '', '', 'develop:code:code', '0', 'panda', '', '', '2022-01-14 13:42:48', '2022-01-14 13:42:48', NULL); +INSERT INTO `sys_menus` VALUES (95, '设备管理', '', 0, 1, 'iconfont icon-dongtai', '/device/index', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'panda', '', '', '2023-06-29 16:21:31', '2023-06-29 16:21:31', NULL); +INSERT INTO `sys_menus` VALUES (96, '规则链库', '', 0, 2, 'iconfont icon-shuxingtu', '/rule/chain', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'panda', 'panda', '', '2023-06-29 16:33:23', '2023-07-21 14:37:15', NULL); +INSERT INTO `sys_menus` VALUES (97, '组态大屏', '', 0, 3, 'iconfont icon-diannaobangong', '/visual', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'panda', 'panda', '', '2023-06-29 16:34:50', '2023-07-21 14:41:55', NULL); +INSERT INTO `sys_menus` VALUES (98, '产品分类', '', 95, 1, 'iconfont icon-jiliandongxuanzeqi', '/device/product_category', '/device/product_category/index', '1', '', 'C', '0', '1', '1', 'product:category:list', '0', '', 'panda', '', '2023-06-29 16:44:56', '2023-06-29 16:49:55', NULL); +INSERT INTO `sys_menus` VALUES (99, '产品', '', 95, 2, 'iconfont icon-AIshiyanshi', '/device/product', '/device/product/index', '1', '', 'C', '0', '1', '1', 'product:list', '0', '', 'panda', '', '2023-06-29 16:46:16', '2023-06-29 16:50:34', '2023-06-30 14:16:11'); +INSERT INTO `sys_menus` VALUES (100, '设备分组', '', 95, 3, 'iconfont icon-zidingyibuju', '/device/device_group', '/device/device_group/index', '1', '', 'C', '0', '1', '1', 'device:group:list', '0', '', 'panda', '', '2023-06-29 16:48:05', '2023-06-29 16:50:49', NULL); +INSERT INTO `sys_menus` VALUES (101, '设备', '', 95, 4, 'iconfont icon-dongtai', '/device/device', '/device/device/index', '1', '', 'C', '0', '1', '1', 'device:list', '0', '', 'panda', '', '2023-06-29 16:49:03', '2023-06-29 16:50:59', '2023-06-30 14:16:48'); +INSERT INTO `sys_menus` VALUES (102, '添加', '', 98, 1, '', '', '', '', '', 'F', '', '', '', 'product:category:add', '0', 'panda', '', '', '2023-06-29 16:51:38', '2023-06-29 16:51:38', NULL); +INSERT INTO `sys_menus` VALUES (103, '修改', '', 98, 2, '', '', '', '', '', 'F', '', '', '', 'product:category:edit', '0', 'panda', '', '', '2023-06-29 16:52:00', '2023-06-29 16:52:00', NULL); +INSERT INTO `sys_menus` VALUES (104, '删除', '', 98, 3, '', '', '', '', '', 'F', '', '', '', 'product:category:delete', '0', 'panda', '', '', '2023-06-29 16:52:36', '2023-06-29 16:52:36', NULL); +INSERT INTO `sys_menus` VALUES (105, '新增', '', 100, 1, '', '', '', '', '', 'F', '', '', '', 'device:group:add', '0', 'panda', '', '', '2023-06-29 16:53:16', '2023-06-29 16:53:16', NULL); +INSERT INTO `sys_menus` VALUES (106, '修改', '', 100, 2, '', '', '', '', '', 'F', '', '', '', 'device:group:edit', '0', 'panda', '', '', '2023-06-29 16:53:37', '2023-06-29 16:53:37', NULL); +INSERT INTO `sys_menus` VALUES (107, '删除', '', 100, 3, '', '', '', '', '', 'F', '', '', '', 'device:group:delete', '0', 'panda', '', '', '2023-06-29 16:53:56', '2023-06-29 16:53:56', NULL); +INSERT INTO `sys_menus` VALUES (108, '克隆', '', 96, 1, '', '', '', '', '', 'F', '', '', '', 'rulechain:clone', '0', 'panda', '', '', '2023-06-29 16:54:33', '2023-06-29 16:54:33', '2023-07-21 14:41:09'); +INSERT INTO `sys_menus` VALUES (109, '设计', '', 96, 2, '', '', '', '', '', 'F', '', '', '', 'rulechain:design', '0', 'panda', '', '', '2023-06-29 16:55:18', '2023-06-29 16:55:18', '2023-07-21 14:41:14'); +INSERT INTO `sys_menus` VALUES (110, '预览', '', 96, 3, '', '', '', '', '', 'F', '', '', '', 'rulechain:view', '0', 'panda', '', '', '2023-06-29 16:55:39', '2023-06-29 16:55:39', '2023-07-21 14:41:18'); +INSERT INTO `sys_menus` VALUES (111, '修改', '', 96, 4, '', '', '', '', '', 'F', '', '', '', 'rulechain:edit', '0', 'panda', '', '', '2023-06-29 16:55:59', '2023-06-29 16:55:59', '2023-07-21 14:41:30'); +INSERT INTO `sys_menus` VALUES (112, '删除', '', 96, 5, '', '', '', '', '', 'F', '', '', '', 'rulechain:delete', '0', 'panda', '', '', '2023-06-29 16:56:15', '2023-06-29 16:56:15', '2023-07-21 14:41:26'); +INSERT INTO `sys_menus` VALUES (113, '添加', '', 96, 6, '', '', '', '', '', 'F', '', '', '', 'rulechain:add', '0', 'panda', '', '', '2023-06-29 16:56:37', '2023-06-29 16:56:37', '2023-07-21 14:41:21'); +INSERT INTO `sys_menus` VALUES (114, '产品管理', '', 95, 2, 'elementCpu', '/device/product', '/device/product/index', '1', '', 'C', '0', '1', '1', 'device:product:list', '0', '', 'panda', '', '2023-06-30 14:13:39', '2023-07-21 16:03:31', NULL); +INSERT INTO `sys_menus` VALUES (115, '新增产品', '', 114, 1, '', '', '', '', '', 'F', '', '', '', 'device:product:add', '0', 'admin', '', '', '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL); +INSERT INTO `sys_menus` VALUES (116, '修改产品', '', 114, 2, '', '', '', '', '', 'F', '', '', '', 'device:product:edit', '0', 'admin', '', '', '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL); +INSERT INTO `sys_menus` VALUES (117, '删除产品', '', 114, 3, '', '', '', '', '', 'F', '', '', '', 'device:product:delete', '0', 'admin', '', '', '2023-06-30 14:13:39', '2023-06-30 14:13:39', NULL); +INSERT INTO `sys_menus` VALUES (118, '设备管理', '', 95, 4, 'elementSetting', '/device/device', '/device/device/index', '1', '', 'C', '0', '1', '1', 'device:device:list', '0', '', 'panda', '', '2023-06-30 14:20:03', '2023-07-21 16:03:41', NULL); +INSERT INTO `sys_menus` VALUES (119, '修改设备', '', 118, 2, '', '', '', '', '', 'F', '', '', '', 'device:device:edit', '0', 'admin', '', '', '2023-06-30 14:20:03', '2023-06-30 14:20:03', NULL); +INSERT INTO `sys_menus` VALUES (120, '新增设备', '', 118, 1, '', '', '', '', '', 'F', '', '', '', 'device:device:add', '0', 'admin', '', '', '2023-06-30 14:20:03', '2023-06-30 14:20:03', NULL); +INSERT INTO `sys_menus` VALUES (121, '删除设备', '', 118, 3, '', '', '', '', '', 'F', '', '', '', 'device:device:delete', '0', 'admin', '', '', '2023-06-30 14:20:03', '2023-06-30 14:20:03', NULL); +INSERT INTO `sys_menus` VALUES (122, '查看', '', 114, 4, '', '', '', '', '', 'F', '', '', '', 'device:product:view', '0', 'panda', '', '', '2023-07-05 17:14:20', '2023-07-05 17:14:20', NULL); +INSERT INTO `sys_menus` VALUES (131, '查看设备', '', 118, 4, '', '', '', '', '', 'F', '', '', '', 'device:device:view', '0', 'panda', '', '', '2023-07-10 08:50:48', '2023-07-10 08:50:48', NULL); +INSERT INTO `sys_menus` VALUES (132, '规则链', '', 96, 1, 'iconfont icon-shuxingtu', '/rule/chain', '/rule/chain/index', '1', '', 'C', '0', '1', '1', 'rule:chain:list', '0', '', 'panda', '', '2023-07-21 14:38:54', '2023-07-21 14:56:56', NULL); +INSERT INTO `sys_menus` VALUES (133, '克隆', '', 132, 1, '', '', '', '', '', 'F', '', '', '', 'rule:chain:clone', '0', '', 'panda', '', '2023-07-21 14:39:27', '2023-07-21 14:57:05', NULL); +INSERT INTO `sys_menus` VALUES (134, '设计', '', 132, 2, '', '', '', '', '', 'F', '', '', '', 'rule:chain:design', '0', '', 'panda', '', '2023-07-21 14:39:53', '2023-07-21 14:57:13', NULL); +INSERT INTO `sys_menus` VALUES (135, '预览', '', 132, 3, '', '', '', '', '', 'F', '', '', '', 'rule:chain:view', '0', '', 'panda', '', '2023-07-21 14:40:08', '2023-07-21 14:57:20', NULL); +INSERT INTO `sys_menus` VALUES (136, '修改', '', 132, 4, '', '', '', '', '', 'F', '', '', '', 'rule:chain:edit', '0', '', 'panda', '', '2023-07-21 14:40:31', '2023-07-21 14:57:26', NULL); +INSERT INTO `sys_menus` VALUES (137, '删除', '', 132, 5, '', '', '', '', '', 'F', '', '', '', 'rule:chain:delete', '0', '', 'panda', '', '2023-07-21 14:40:47', '2023-07-21 14:57:33', NULL); +INSERT INTO `sys_menus` VALUES (138, '添加', '', 132, 6, '', '', '', '', '', 'F', '', '', '', 'rule:chain:add', '0', '', 'panda', '', '2023-07-21 14:41:04', '2023-07-21 14:57:39', NULL); +INSERT INTO `sys_menus` VALUES (139, '大屏分组', '', 97, 1, 'iconfont icon-wenducanshu-05', '/visual/screen_group', '/visual/screen_group/index', '1', '', 'C', '0', '1', '1', 'screen:group:list', '0', 'panda', '', '', '2023-07-21 14:46:41', '2023-07-21 14:46:41', NULL); +INSERT INTO `sys_menus` VALUES (140, '组态大屏', '', 97, 2, 'iconfont icon-diannaobangong', '/visual/screen', '/visual/screen/index', '1', '', 'C', '0', '1', '1', 'visual:screen:list', '0', 'panda', '', '', '2023-07-21 14:47:46', '2023-07-21 14:47:46', NULL); +INSERT INTO `sys_menus` VALUES (141, '添加', '', 139, 1, '', '', '', '', '', 'F', '', '', '', 'screen:group:add', '0', 'panda', '', '', '2023-07-21 14:50:40', '2023-07-21 14:50:40', NULL); +INSERT INTO `sys_menus` VALUES (142, '编辑', '', 139, 2, '', '', '', '', '', 'F', '', '', '', 'screen:group:edit', '0', 'panda', '', '', '2023-07-21 14:50:56', '2023-07-21 14:50:56', NULL); +INSERT INTO `sys_menus` VALUES (143, '删除', '', 139, 3, '', '', '', '', '', 'F', '', '', '', ' screen:group:delete', '0', 'panda', '', '', '2023-07-21 14:51:22', '2023-07-21 14:51:22', NULL); +INSERT INTO `sys_menus` VALUES (144, '新增组态', '', 140, 1, '', '', '', '', '', 'F', '', '', '', 'visual:screen:add', '0', 'panda', '', '', '2023-07-21 14:53:26', '2023-07-21 14:53:26', NULL); +INSERT INTO `sys_menus` VALUES (145, '修改大屏', '', 140, 2, '', '', '', '', '', 'F', '', '', '', 'visual:screen:edit', '0', 'panda', '', '', '2023-07-21 14:53:50', '2023-07-21 14:53:50', NULL); +INSERT INTO `sys_menus` VALUES (146, '删除大屏', '', 140, 3, '', '', '', '', '', 'F', '', '', '', 'visual:screen:delete', '0', 'panda', '', '', '2023-07-21 14:54:14', '2023-07-21 14:54:14', NULL); +INSERT INTO `sys_menus` VALUES (147, '克隆', '', 140, 4, '', '', '', '', '', 'F', '', '', '', 'visual:screen:clone', '0', 'panda', '', '', '2023-07-21 14:54:30', '2023-07-21 14:54:30', NULL); +INSERT INTO `sys_menus` VALUES (148, '设计', '', 140, 5, '', '', '', '', '', 'F', '', '', '', 'visual:screen:design', '0', 'panda', '', '', '2023-07-21 14:54:57', '2023-07-21 14:54:57', NULL); +INSERT INTO `sys_menus` VALUES (149, '预览', '', 140, 6, '', '', '', '', '', 'F', '', '', '', 'visual:screen:view', '0', 'panda', '', '', '2023-07-21 14:55:27', '2023-07-21 14:55:27', NULL); +INSERT INTO `sys_menus` VALUES (150, '报表管理', '', 0, 4, 'iconfont icon-putong', '/report', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'panda', 'panda', '', '2023-07-24 10:12:26', '2023-07-24 10:13:54', NULL); +INSERT INTO `sys_menus` VALUES (151, '报表设计', '', 150, 1, 'iconfont icon-dayin', '/report', '/layout/routerView/iframes', '0', 'http://101.35.247.125:9001/edit', 'C', '0', '1', '1', 'report:list', '0', 'panda', '', '', '2023-07-24 10:13:47', '2023-07-24 10:13:47', NULL); +INSERT INTO `sys_menus` VALUES (152, '任务中心', '', 0, 5, 'elementAlarmClock', '/job', 'Layout', '1', '', 'M', '0', '1', '1', '', '0', 'panda', '', '', '2023-08-08 14:08:11', '2023-08-08 14:08:11', NULL); +INSERT INTO `sys_menus` VALUES (153, '任务中心', '', 152, 1, 'elementAlarmClock', '/job/job', '/job/job/index', '1', '', 'C', '0', '1', '1', 'job:list', '0', '', 'panda', '', '2023-08-08 14:10:37', '2023-08-08 14:12:49', NULL); +INSERT INTO `sys_menus` VALUES (154, '任务日志', '', 152, 2, 'elementDocument', '/job/log', '/job/log/index', '1', '', 'C', '0', '1', '1', 'job:log:list', '0', 'panda', '', '', '2023-08-08 14:12:37', '2023-08-08 14:12:37', NULL); +INSERT INTO `sys_menus` VALUES (155, '新增', '', 153, 1, '', '', '', '', '', 'F', '', '', '', 'job:add', '0', 'panda', '', '', '2023-08-08 14:20:17', '2023-08-08 14:20:17', NULL); +INSERT INTO `sys_menus` VALUES (156, '编辑', '', 153, 2, '', '', '', '', '', 'F', '', '', '', 'job:edit', '0', 'panda', '', '', '2023-08-08 14:20:44', '2023-08-08 14:20:44', NULL); +INSERT INTO `sys_menus` VALUES (157, '删除', '', 153, 3, '', '', '', '', '', 'F', '', '', '', 'job:delete', '0', 'panda', '', '', '2023-08-08 14:21:03', '2023-08-08 14:21:03', NULL); +INSERT INTO `sys_menus` VALUES (158, '运行启动', '', 153, 4, '', '', '', '', '', 'F', '', '', '', 'job:run', '0', 'panda', '', '', '2023-08-08 14:21:25', '2023-08-08 14:21:25', NULL); +INSERT INTO `sys_menus` VALUES (159, '删除', '', 154, 1, '', '', '', '', '', 'F', '', '', '', 'job:log:delete', '0', 'panda', '', '', '2023-08-08 14:22:05', '2023-08-08 14:22:05', NULL); +INSERT INTO `sys_menus` VALUES (160, '清空', '', 154, 2, '', '', '', '', '', 'F', '', '', '', 'job:log:clean', '0', 'panda', '', '', '2023-08-08 14:22:33', '2023-08-08 14:22:33', NULL); + +-- ---------------------------- +-- Table structure for sys_notices +-- ---------------------------- +DROP TABLE IF EXISTS `sys_notices`; +CREATE TABLE `sys_notices` ( + `notice_id` bigint(0) NOT NULL AUTO_INCREMENT, + `title` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题', + `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '标题', + `notice_type` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '通知类型', + `dept_id` int(0) NULL DEFAULT NULL COMMENT '部门Id,部门及子部门', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + `user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`notice_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_notices +-- ---------------------------- +INSERT INTO `sys_notices` VALUES (1, '关于学习交流的通知', '

发布入群通知 467890197, 交流学习

', '1', 0, '2021-12-26 15:29:25', '2021-12-26 16:19:48', NULL, 'panda'); +INSERT INTO `sys_notices` VALUES (2, 'test', '

sdsad

', '1', 2, '2021-12-26 16:23:13', '2021-12-26 16:23:13', '2021-12-26 16:31:31', 'panda'); +INSERT INTO `sys_notices` VALUES (3, '版本更新通知:任务功能,通知功能完成', '

', '1', 0, '2021-12-26 17:33:47', '2021-12-26 17:33:47', NULL, 'panda'); + +-- ---------------------------- +-- Table structure for sys_posts +-- ---------------------------- +DROP TABLE IF EXISTS `sys_posts`; +CREATE TABLE `sys_posts` ( + `post_id` bigint(0) NOT NULL AUTO_INCREMENT, + `post_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '岗位名称', + `post_code` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '岗位代码', + `sort` int(0) NULL DEFAULT NULL COMMENT '岗位排序', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述', + `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_posts +-- ---------------------------- +INSERT INTO `sys_posts` VALUES (1, '首席执行官', 'CEO', 1, '0', '首席执行官', 'panda', '', '2021-12-02 09:21:44', '2022-07-16 17:36:32', NULL); +INSERT INTO `sys_posts` VALUES (4, '首席技术执行官', 'CTO', 2, '0', '', 'panda', '', '2021-12-02 09:21:44', '2022-07-16 17:37:42', NULL); + +-- ---------------------------- +-- Table structure for sys_role_depts +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_depts`; +CREATE TABLE `sys_role_depts` ( + `role_id` int(0) NULL DEFAULT NULL, + `dept_id` int(0) NULL DEFAULT NULL, + `id` bigint(0) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role_depts +-- ---------------------------- +INSERT INTO `sys_role_depts` VALUES (1, 2, 1); +INSERT INTO `sys_role_depts` VALUES (1, 3, 2); + +-- ---------------------------- +-- Table structure for sys_role_menus +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menus`; +CREATE TABLE `sys_role_menus` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT, + `role_id` int(0) NULL DEFAULT NULL, + `menu_id` int(0) NULL DEFAULT NULL, + `role_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5182 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role_menus +-- ---------------------------- +INSERT INTO `sys_role_menus` VALUES (2957, 2, 1, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2958, 2, 3, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2959, 2, 4, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2960, 2, 5, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2961, 2, 6, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2962, 2, 7, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2963, 2, 8, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2964, 2, 9, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2965, 2, 10, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2966, 2, 11, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2967, 2, 12, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2968, 2, 13, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2969, 2, 14, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2970, 2, 15, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2971, 2, 16, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2972, 2, 17, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2973, 2, 18, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2974, 2, 19, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2975, 2, 20, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2976, 2, 21, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2977, 2, 22, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2978, 2, 23, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2979, 2, 25, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2980, 2, 26, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2981, 2, 28, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2982, 2, 29, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2983, 2, 30, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2984, 2, 31, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2985, 2, 32, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2986, 2, 33, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2987, 2, 34, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2988, 2, 35, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2989, 2, 36, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2990, 2, 37, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2991, 2, 38, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2992, 2, 39, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2993, 2, 40, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2994, 2, 41, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2995, 2, 42, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2996, 2, 43, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2997, 2, 44, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2998, 2, 45, 'manage'); +INSERT INTO `sys_role_menus` VALUES (2999, 2, 46, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3000, 2, 47, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3001, 2, 48, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3002, 2, 49, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3003, 2, 50, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3004, 2, 51, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3005, 2, 52, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3006, 2, 53, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3007, 2, 54, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3008, 2, 55, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3009, 2, 56, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3010, 2, 57, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3011, 2, 58, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3012, 2, 59, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3013, 2, 60, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3014, 2, 61, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3015, 2, 62, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3016, 2, 63, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3017, 2, 64, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3018, 2, 65, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3019, 2, 66, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3020, 2, 67, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3021, 2, 68, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3022, 2, 69, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3023, 2, 70, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3024, 2, 71, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3025, 2, 72, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3026, 2, 73, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3027, 2, 74, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3028, 2, 75, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3029, 2, 76, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3030, 2, 77, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3031, 2, 78, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3032, 2, 79, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3033, 2, 80, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3034, 2, 81, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3035, 2, 83, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3036, 2, 84, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3037, 2, 85, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3038, 2, 86, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3039, 2, 87, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3040, 2, 88, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3041, 2, 89, 'manage'); +INSERT INTO `sys_role_menus` VALUES (3042, 2, 90, 'manage'); +INSERT INTO `sys_role_menus` VALUES (5069, 1, 1, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5070, 1, 3, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5071, 1, 4, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5072, 1, 5, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5073, 1, 6, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5074, 1, 7, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5075, 1, 8, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5076, 1, 9, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5077, 1, 10, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5078, 1, 11, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5079, 1, 12, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5080, 1, 13, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5081, 1, 14, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5082, 1, 15, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5083, 1, 16, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5084, 1, 17, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5085, 1, 18, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5086, 1, 19, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5087, 1, 20, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5088, 1, 21, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5089, 1, 22, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5090, 1, 23, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5091, 1, 24, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5092, 1, 25, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5093, 1, 26, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5094, 1, 28, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5095, 1, 29, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5096, 1, 30, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5097, 1, 31, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5098, 1, 32, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5099, 1, 33, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5100, 1, 34, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5101, 1, 35, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5102, 1, 36, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5103, 1, 37, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5104, 1, 38, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5105, 1, 39, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5106, 1, 40, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5107, 1, 41, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5108, 1, 42, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5109, 1, 43, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5110, 1, 44, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5111, 1, 45, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5112, 1, 46, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5113, 1, 47, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5114, 1, 49, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5115, 1, 50, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5116, 1, 51, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5117, 1, 52, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5118, 1, 55, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5119, 1, 59, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5120, 1, 60, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5121, 1, 63, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5122, 1, 64, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5123, 1, 69, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5124, 1, 70, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5125, 1, 71, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5126, 1, 72, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5127, 1, 73, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5128, 1, 74, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5129, 1, 75, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5130, 1, 76, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5131, 1, 77, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5132, 1, 95, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5133, 1, 96, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5134, 1, 97, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5135, 1, 98, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5136, 1, 100, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5137, 1, 102, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5138, 1, 103, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5139, 1, 104, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5140, 1, 105, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5141, 1, 106, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5142, 1, 107, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5143, 1, 114, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5144, 1, 115, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5145, 1, 116, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5146, 1, 117, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5147, 1, 118, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5148, 1, 119, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5149, 1, 120, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5150, 1, 121, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5151, 1, 122, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5152, 1, 131, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5153, 1, 132, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5154, 1, 133, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5155, 1, 134, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5156, 1, 135, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5157, 1, 136, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5158, 1, 137, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5159, 1, 138, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5160, 1, 139, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5161, 1, 140, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5162, 1, 141, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5163, 1, 142, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5164, 1, 143, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5165, 1, 144, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5166, 1, 145, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5167, 1, 146, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5168, 1, 147, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5169, 1, 148, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5170, 1, 149, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5171, 1, 150, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5172, 1, 151, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5173, 1, 152, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5174, 1, 153, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5175, 1, 154, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5176, 1, 155, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5177, 1, 156, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5178, 1, 157, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5179, 1, 158, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5180, 1, 159, 'admin'); +INSERT INTO `sys_role_menus` VALUES (5181, 1, 160, 'admin'); + +-- ---------------------------- +-- Table structure for sys_roles +-- ---------------------------- +DROP TABLE IF EXISTS `sys_roles`; +CREATE TABLE `sys_roles` ( + `role_id` bigint(0) NOT NULL AUTO_INCREMENT, + `role_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色名称', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', + `role_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色代码', + `data_scope` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `role_sort` int(0) NULL DEFAULT NULL COMMENT '角色排序', + `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`role_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_roles +-- ---------------------------- +INSERT INTO `sys_roles` VALUES (1, '超管理员', '0', 'admin', '2', 1, 'admin', 'panda', '超级管理', '2021-12-02 16:03:26', '2023-08-08 14:36:03', NULL); +INSERT INTO `sys_roles` VALUES (2, '管理员', '0', 'manage', '', 2, 'panda', 'panda', '', '2021-12-19 16:06:20', '2022-07-19 14:03:34', NULL); + +-- ---------------------------- +-- Table structure for sys_users +-- ---------------------------- +DROP TABLE IF EXISTS `sys_users`; +CREATE TABLE `sys_users` ( + `user_id` bigint(0) NOT NULL AUTO_INCREMENT, + `nick_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `role_id` int(0) NULL DEFAULT NULL, + `salt` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `email` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `dept_id` int(0) NULL DEFAULT NULL, + `post_id` int(0) NULL DEFAULT NULL, + `create_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `update_by` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `delete_time` datetime(0) NULL DEFAULT NULL, + `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `password` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `role_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '多角色', + `post_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '多岗位', + PRIMARY KEY (`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_users +-- ---------------------------- +INSERT INTO `sys_users` VALUES (1, 'pandax', '13818888888', 1, NULL, '', '0', '1@qq.com', 2, 4, 'panda', '1', NULL, '0', '2021-12-03 09:46:55', '2022-02-09 13:28:49', NULL, 'panda', '$2a$10$cKFFTCzGOvaIHHJY2K45Zuwt8TD6oPzYi4s5MzYIBAWCLL6ZhouP2', '1', '1,4'); +INSERT INTO `sys_users` VALUES (3, '测试用户', '18435234356', 2, '', '', '0', '342@163.com', 3, 1, 'test', '', '', '0', '2021-12-06 15:16:53', '2022-05-10 19:19:25', NULL, 'test', '$2a$10$4cHTracxWJLdhMmazvbm1urKyD3v5N2AYxAFtNYh6juU39kgae73e', '2', '1,4'); +INSERT INTO `sys_users` VALUES (4, 'panda', '18353366912', 2, '', '', '0', '2417920382@qq.com', 2, 4, 'panda', '', '', '0', '2021-12-19 15:58:09', '2021-12-19 16:06:54', NULL, 'admin', '$2a$10$cKFFTCzGOvaIHHJY2K45Zuwt8TD6oPzYi4s5MzYIBAWCLL6ZhouP2', '2', '4,1'); +INSERT INTO `sys_users` VALUES (5, 'tenant', '', 1, '', '', '0', '', 3, 1, 'panda', '1', '', '0', '2021-12-03 09:46:55', '2022-02-09 13:28:49', NULL, 'tenant', '$2a$10$ycRsRdsrNQInLB2Ib0maOetsWZ0kFctmF6ytAErWTjOx5cWdeJMcK', '1', '1,4'); + +-- ---------------------------- +-- Table structure for visual_data_set_field +-- ---------------------------- +DROP TABLE IF EXISTS `visual_data_set_field`; +CREATE TABLE `visual_data_set_field` ( + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `field_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '字段id', + `table_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '表id', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字段名(描述)', + `group_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '维度/指标标识 d:维度,q:指标', + `origin_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '原始字段名称', + `origin_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '原始字段类型', + `de_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据源查询名', + `de_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据源字段类型:0-文本,1-时间,2-数值,3-数值小数', + `ext_field` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否扩展字段 0否 1是', + PRIMARY KEY (`field_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_data_set_field +-- ---------------------------- +INSERT INTO `visual_data_set_field` VALUES ('2023-04-30 10:36:03', '2023-07-18 02:10:39', '234342', 'pxcea96e8b46ddac0b0ac34c9b', '昵称', 'q', NULL, NULL, 'nickname', '0', NULL); + +-- ---------------------------- +-- Table structure for visual_data_set_table +-- ---------------------------- +DROP TABLE IF EXISTS `visual_data_set_table`; +CREATE TABLE `visual_data_set_table` ( + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `table_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '表id', + `data_source_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据圆ID', + `table_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'db,sql,excel,union', + `info` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '原始表信息', + `create_by` bigint(0) NULL DEFAULT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + PRIMARY KEY (`table_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_data_set_table +-- ---------------------------- +INSERT INTO `visual_data_set_table` VALUES ('2023-04-27 16:46:41', '2023-04-27 16:46:41', 'pxcea96e8b46ddac0b0ac34c9b', 'pxab7d17d7e8db23ee3ac0a897', 'sql', '{\"sql\": \"select nickname from res_emails\"}', 0, 'testSql'); +INSERT INTO `visual_data_set_table` VALUES ('2023-04-27 16:22:42', '2023-04-27 16:22:42', 'pxd6f0fd0c3f365d68c6e9f5fa', 'px9256d7dd9add568796911b25', 'db', '{\"table\": \"res_emails\"}', 0, 'testSet'); +INSERT INTO `visual_data_set_table` VALUES ('2023-04-27 17:14:49', '2023-04-27 17:14:49', 'pxebe07ffb9d98bd22aef895cc', '', 'excel', '{\"filePath\": \"uploads/excel/c7ddb65e42_20230427171333.xlsx\"}', 0, 'testExcel'); +INSERT INTO `visual_data_set_table` VALUES ('2023-04-30 09:46:24', '2023-04-30 09:46:24', 'pxf665b4faeb5915d811263dd2', 'pxab7d17d7e8db23ee3ac0a897', 'sql', '{\"sql\": \"select COUNT(*) from log_jobs group by job_group\"}', 0, '付款'); + +-- ---------------------------- +-- Table structure for visual_data_set_table_function +-- ---------------------------- +DROP TABLE IF EXISTS `visual_data_set_table_function`; +CREATE TABLE `visual_data_set_table_function` ( + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数名称', + `func` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数表达式', + `db_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '所属数据库', + `desc` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '描述' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_data_set_table_function +-- ---------------------------- +INSERT INTO `visual_data_set_table_function` VALUES ('ABS', 'ABS(x)', 'MySQL', '返回x的绝对值'); +INSERT INTO `visual_data_set_table_function` VALUES ('PI', 'PI()', 'MySQL', '返回圆周率π,默认显示6位小数'); +INSERT INTO `visual_data_set_table_function` VALUES ('SQRT', 'SQRT(x)', 'MySQL', '返回非负数的x的二次方根'); +INSERT INTO `visual_data_set_table_function` VALUES ('MOD', 'MOD(x,y)', 'MySQL', '返回x被y除后的余数'); +INSERT INTO `visual_data_set_table_function` VALUES ('CEIL', 'CEIL(x)', 'MySQL', '返回不小于x的最小整数'); +INSERT INTO `visual_data_set_table_function` VALUES ('FLOOR', 'FLOOR(x)', 'MySQL', '返回不大于x的最大整数'); +INSERT INTO `visual_data_set_table_function` VALUES ('ROUND', 'ROUND(x)', 'MySQL', '返回离x最近的整数'); +INSERT INTO `visual_data_set_table_function` VALUES ('ROUND', 'ROUND(x,y)', 'MySQL', '保留x小数点后y位的值,但截断时要进行四舍五入'); +INSERT INTO `visual_data_set_table_function` VALUES ('SIGN', 'SIGN(x)', 'MySQL', '返回参数x的符号,-1表示负数,0表示0,1表示正数'); +INSERT INTO `visual_data_set_table_function` VALUES ('POW', 'POW(x,y)', 'MySQL', '返回x的y次乘方的值'); +INSERT INTO `visual_data_set_table_function` VALUES ('EXP', 'EXP(x)', 'MySQL', '返回e的x乘方后的值'); +INSERT INTO `visual_data_set_table_function` VALUES ('LOG', 'LOG(x)', 'MySQL', '返回x的自然对数,x相对于基数e的对数'); +INSERT INTO `visual_data_set_table_function` VALUES ('LOG10', 'LOG10(x)', 'MySQL', '返回x的基数为10的对数'); +INSERT INTO `visual_data_set_table_function` VALUES ('RADIANS', 'RADIANS(x)', 'MySQL', '返回x由角度转化为弧度的值'); +INSERT INTO `visual_data_set_table_function` VALUES ('DEGREES', 'DEGREES(x)', 'MySQL', '返回x由弧度转化为角度的值'); +INSERT INTO `visual_data_set_table_function` VALUES ('SIN', 'SIN(x)', 'MySQL', '返回x的正弦,其中x为给定的弧度值'); +INSERT INTO `visual_data_set_table_function` VALUES ('ASIN', 'ASIN(x)', 'MySQL', '返回x的反正弦值'); +INSERT INTO `visual_data_set_table_function` VALUES ('COS', 'COS(x)', 'MySQL', '返回x的余弦,其中x为给定的弧度值'); +INSERT INTO `visual_data_set_table_function` VALUES ('ACOS', 'ACOS(x)', 'MySQL', '返回x的反余弦值'); +INSERT INTO `visual_data_set_table_function` VALUES ('TAN', 'TAN(x)', 'MySQL', '返回x的正切,其中x为给定的弧度值'); +INSERT INTO `visual_data_set_table_function` VALUES ('ATAN', 'ATAN(x)', 'MySQL', '返回x的反正切值'); +INSERT INTO `visual_data_set_table_function` VALUES ('COT', 'COT(x)', 'MySQL', '返回给定弧度值x的余切'); +INSERT INTO `visual_data_set_table_function` VALUES ('CHAR_LENGTH', 'CHAR_LENGTH(str)', 'MySQL', '计算字符串字符个数'); +INSERT INTO `visual_data_set_table_function` VALUES ('TRIM', 'TRIM(s)', 'MySQL', '返回字符串s删除了两边空格之后的字符串'); +INSERT INTO `visual_data_set_table_function` VALUES ('LTRIM', 'LTRIM(s)', 'MySQL', '返回字符串s,其左边所有空格被删除'); +INSERT INTO `visual_data_set_table_function` VALUES ('RTRIM', 'RTRIM(s)', 'MySQL', '返回字符串s,其右边所有空格被删除'); +INSERT INTO `visual_data_set_table_function` VALUES ('REPLACE', 'REPLACE(s,s1,s2)', 'MySQL', '返回一个字符串,用字符串s2替代字符串s中所有的字符串s1'); +INSERT INTO `visual_data_set_table_function` VALUES ('SUBSTRING', 'SUBSTRING(s,n,len)', 'MySQL', '获取从字符串s中的第n个位置开始长度为len的字符串'); +INSERT INTO `visual_data_set_table_function` VALUES ('CONCAT', 'CONCAT(s1,s2,...)', 'MySQL', '返回连接参数产生的字符串,一个或多个待拼接的内容,任意一个为NULL则返回值为NULL'); +INSERT INTO `visual_data_set_table_function` VALUES ('INSERT', 'INSERT(s1,x,len,s2)', 'MySQL', '返回字符串s1,其子字符串起始于位置x,被字符串s2取代len个字符'); +INSERT INTO `visual_data_set_table_function` VALUES ('LOWER', 'LOWER(str)', 'MySQL', '将str中的字母全部转换成小写'); +INSERT INTO `visual_data_set_table_function` VALUES ('UPPER', 'UPPER(str)', 'MySQL', '将字符串中的字母全部转换成大写'); +INSERT INTO `visual_data_set_table_function` VALUES ('LEFT', 'LEFT(s,n)', 'MySQL', '返回字符串s从最左边开始的n个字符'); +INSERT INTO `visual_data_set_table_function` VALUES ('RIGHT', 'RIGHT(s,n)', 'MySQL', '返回字符串s从最右边开始的n个字符'); +INSERT INTO `visual_data_set_table_function` VALUES ('REPEAT', 'REPEAT(s,n)', 'MySQL', '返回一个由重复字符串s组成的字符串,字符串s的数目等于n'); +INSERT INTO `visual_data_set_table_function` VALUES ('SPACE', 'SPACE(n)', 'MySQL', '返回一个由n个空格组成的字符串'); +INSERT INTO `visual_data_set_table_function` VALUES ('REVERSE', 'REVERSE(s)', 'MySQL', '将字符串s反转'); +INSERT INTO `visual_data_set_table_function` VALUES ('CURDATE', 'CURDATE()', 'MySQL', '将当前日期按照\"YYYY-MM-DD\"或者\"YYYYMMDD\"格式的值返回,具体格式根据函数用在字符串或是数字语境中而定'); +INSERT INTO `visual_data_set_table_function` VALUES ('CURRENT_DATE', 'CURRENT_DATE()', 'MySQL', '将当前日期按照\"YYYY-MM-DD\"或者\"YYYYMMDD\"格式的值返回,具体格式根据函数用在字符串或是数字语境中而定'); +INSERT INTO `visual_data_set_table_function` VALUES ('NOW', 'NOW()', 'MySQL', '返回当前日期和时间值,格式为\"YYYY_MM-DD HH:MM:SS\"或\"YYYYMMDDHHMMSS\",具体格式根据函数用在字符串或数字语境中而定'); +INSERT INTO `visual_data_set_table_function` VALUES ('SYSDATE', 'SYSDATE()', 'MySQL', '返回当前日期和时间值,格式为\"YYYY_MM-DD HH:MM:SS\"或\"YYYYMMDDHHMMSS\",具体格式根据函数用在字符串或数字语境中而定'); +INSERT INTO `visual_data_set_table_function` VALUES ('LOCALTIME', 'LOCALTIME()', 'MySQL', '返回当前日期和时间值,格式为\"YYYY_MM-DD HH:MM:SS\"或\"YYYYMMDDHHMMSS\",具体格式根据函数用在字符串或数字语境中而定'); +INSERT INTO `visual_data_set_table_function` VALUES ('CURRENT_TIMESTAMP', 'CURRENT_TIMESTAMP()', 'MySQL', '返回当前日期和时间值,格式为\"YYYY_MM-DD HH:MM:SS\"或\"YYYYMMDDHHMMSS\",具体格式根据函数用在字符串或数字语境中而定'); +INSERT INTO `visual_data_set_table_function` VALUES ('UNIX_TIMESTAMP', 'UNIX_TIMESTAMP()', 'MySQL', '返回一个格林尼治标准时间1970-01-01 00:00:00到现在的秒数'); +INSERT INTO `visual_data_set_table_function` VALUES ('UNIX_TIMESTAMP', 'UNIX_TIMESTAMP(date)', 'MySQL', '返回一个格林尼治标准时间1970-01-01 00:00:00到指定时间的秒数'); +INSERT INTO `visual_data_set_table_function` VALUES ('FROM_UNIXTIME', 'FROM_UNIXTIME(date)', 'MySQL', '把UNIX时间戳转换为普通格式的时间'); +INSERT INTO `visual_data_set_table_function` VALUES ('CASE', 'CASE expr WHEN v1 THEN r1 [WHEN v2 THEN v2] [ELSE rn] END', 'MySQL', '如果expr等于某个vn,则返回对应位置THEN后面的结果,如果与所有值都不想等,则返回ELSE后面的rn'); +INSERT INTO `visual_data_set_table_function` VALUES ('IF', 'IF(expr,v1,v2)', 'MySQL', '如果expr是TRUE则返回v1,否则返回v2'); +INSERT INTO `visual_data_set_table_function` VALUES ('IFNULL', 'IFNULL(v1,v2)', 'MySQL', '如果v1不为NULL,则返回v1,否则返回v2'); +INSERT INTO `visual_data_set_table_function` VALUES ('datalength', 'datalength(s)', 'SqlServer', '返回字符串包含字符数,但不包含后面的空格'); +INSERT INTO `visual_data_set_table_function` VALUES ('substring', 'substring(expression,start,length)', 'SqlServer', '取子串'); +INSERT INTO `visual_data_set_table_function` VALUES ('ltrim', 'ltrim(expression)', 'SqlServer', '把字符串头部的空格去掉'); +INSERT INTO `visual_data_set_table_function` VALUES ('rtrim', 'rtrim(expression)', 'SqlServer', '把字符串尾部的空格去掉'); +INSERT INTO `visual_data_set_table_function` VALUES ('upper', 'substring(expression)', 'SqlServer', '转为大写'); +INSERT INTO `visual_data_set_table_function` VALUES ('lower', 'substring(expression)', 'SqlServer', '转为小写'); +INSERT INTO `visual_data_set_table_function` VALUES ('reverse', 'reverse(expression)', 'SqlServer', '反转字符串'); +INSERT INTO `visual_data_set_table_function` VALUES ('pi', 'pi()', 'SqlServer', 'π'); +INSERT INTO `visual_data_set_table_function` VALUES ('abs', 'abs(numeric_expr)', 'SqlServer', '求绝对值'); +INSERT INTO `visual_data_set_table_function` VALUES ('sqrt', 'sqrt(float_expr)', 'SqlServer', '平方根'); +INSERT INTO `visual_data_set_table_function` VALUES ('power', 'power(numeric_expr,power) ', 'SqlServer', '返回power次方'); +INSERT INTO `visual_data_set_table_function` VALUES ('getdate', 'getdate() ', 'SqlServer', '返回日期'); +INSERT INTO `visual_data_set_table_function` VALUES ('getutcdate', 'getutcdate() ', 'SqlServer', '获取utc时间'); +INSERT INTO `visual_data_set_table_function` VALUES ('day', 'day(getdate()) ', 'SqlServer', '取出天'); +INSERT INTO `visual_data_set_table_function` VALUES ('abs', 'abs(x)', 'PostgreSQL', '绝对值'); +INSERT INTO `visual_data_set_table_function` VALUES ('sin', 'sin(x)', 'PostgreSQL', '正弦'); +INSERT INTO `visual_data_set_table_function` VALUES ('sqrt', 'sqrt(double/numeric)', 'PostgreSQL', '平方根'); +INSERT INTO `visual_data_set_table_function` VALUES ('lower', 'lower(string)', 'PostgreSQL', '把字串转化为小写'); +INSERT INTO `visual_data_set_table_function` VALUES ('length', 'length(string text)', 'PostgreSQL', 'string中字符的数目'); +INSERT INTO `visual_data_set_table_function` VALUES ('md5', 'md5(string text)', 'PostgreSQL', '计算给出string的MD5散列,以十六进制返回结果'); +INSERT INTO `visual_data_set_table_function` VALUES ('strpos', 'strpos(string, substring)', 'PostgreSQL', '声明的子字串的位置'); +INSERT INTO `visual_data_set_table_function` VALUES ('to_char', 'to_char(timestamp, text)', 'PostgreSQL', '将时间戳转换为字符串'); +INSERT INTO `visual_data_set_table_function` VALUES ('to_timestamp', 'to_timestamp(double precision)', 'PostgreSQL', '把UNIX纪元转换成时间戳'); + +-- ---------------------------- +-- Table structure for visual_data_source +-- ---------------------------- +DROP TABLE IF EXISTS `visual_data_source`; +CREATE TABLE `visual_data_source` ( + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `source_id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '数据源Id', + `source_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据源类型', + `source_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据源名称', + `source_comment` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据源描述', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数据源状态 1:在线 0连接异常', + `db` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '详细信息', + `create_by` bigint(0) NULL DEFAULT NULL, + PRIMARY KEY (`source_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_data_source +-- ---------------------------- +INSERT INTO `visual_data_source` VALUES ('2023-06-17 14:29:07', '2023-06-17 14:29:07', 'px7ffd02bc7a1fd559d460985d', 'MySQL', 'ddd', '', '0', '{\"host\":\"127.0.0.1\",\"port\":3306,\"dbname\":\"iThings\",\"username\":\"root\",\"password\":\"password\",\"config\":\"charset=utf8\\u0026loc=Local\\u0026parseTime=true\",\"schema\":\"\"}', 0); +INSERT INTO `visual_data_source` VALUES ('2023-04-25 16:08:44', '2023-04-25 16:26:34', 'px9256d7dd9add568796911b25', 'MySQL', 'test', '描述', '1', '{\"host\":\"127.0.0.1\",\"port\":3306,\"dbname\":\"pandax\",\"username\":\"root\",\"password\":\"!MyEMS1\",\"config\":\"charset=utf8\\u0026loc=Local\\u0026parseTime=true\",\"schema\":\"\"}', 0); +INSERT INTO `visual_data_source` VALUES ('2023-04-25 09:21:18', '2023-04-30 09:51:43', 'pxab7d17d7e8db23ee3ac0a897', 'MySQL', 'test', '啊啊', '0', '{\"host\":\"127.0.0.1\",\"port\":3306,\"dbname\":\"pandax\",\"username\":\"root\",\"password\":\"!MyEMS1\",\"config\":\"\",\"schema\":\"\"}', 0); + +-- ---------------------------- +-- Table structure for visual_screen +-- ---------------------------- +DROP TABLE IF EXISTS `visual_screen`; +CREATE TABLE `visual_screen` ( + `id` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + `group_id` int(0) NULL DEFAULT NULL COMMENT '分组Id', + `screen_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `screen_data_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT 'Json数据', + `screen_base64` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT 'Base64缩略图', + `screen_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '说明', + `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '状态', + `create_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + `owner` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者,所有者', + `org_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '机构ID', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_screen +-- ---------------------------- +INSERT INTO `visual_screen` VALUES ('pxaec91a00471c2633dafc430f', 3, '测试大屏', '{\"lfData\":[{\"name\":\"首屏\",\"dataCode\":{\"nodes\":[{\"id\":\"ddd271a7-49a6-4537-be99-3f3359b3978b\",\"type\":\"water-pool\",\"x\":244,\"y\":387,\"properties\":{\"icon\":\"icon_module/svg/pool.svg\",\"name\":\"水池\",\"textColor\":\"#59a5a5\",\"textSize\":20,\"borderWidth\":4,\"borderColor\":\"#1f1f1f\",\"poolType\":\"pool\",\"mainColor\":\"#a0edff\",\"fuColor\":\"rgba(40, 187, 255, 0.5)\",\"metadata\":\"{\\n\\t\\\"value\\\": 21.6\\n}\",\"dataset\":{\"dataType\":\"twin\",\"twin\":{\"classId\":\"p_3ba460634520cf4590dc90e5\",\"twinId\":\"d_1928b99619910dae5a001fa7\",\"attrKey\":\"temperature\",\"attr\":{\"key\":\"temperature\",\"name\":\"温度\",\"type\":\"float64\",\"rw\":\"r\"}}},\"zIndex\":10,\"eventList\":[],\"animation\":{\"open\":false,\"type\":\"bounce\",\"duration\":\"fast\",\"repeat\":\"infinite\",\"mode\":\"twin\",\"datas\":[{\"twin\":{\"classId\":\"p_3ba460634520cf4590dc90e5\",\"twinId\":\"d_1928b99619910dae5a001fa7\",\"attrKey\":\"temperature\",\"attr\":{\"key\":\"temperature\",\"name\":\"温度\",\"type\":\"float64\",\"rw\":\"r\"}},\"filter\":\">\",\"twinValue\":26}]}},\"zIndex\":10},{\"id\":\"3324e2d0-77b4-4c77-a128-e22195b28731\",\"type\":\"marquee\",\"x\":465,\"y\":72,\"properties\":{\"icon\":\"icon_module/svg/marquee.svg\",\"name\":\"跑马灯\",\"text\":\"这是跑马灯\",\"textSize\":18,\"speed\":5,\"zIndex\":10,\"nodeSize\":{\"width\":319,\"height\":33},\"textColor\":\"#BF6FD7\"},\"zIndex\":10},{\"id\":\"fa90d32c-7144-47a4-adf9-55a04e838aea\",\"type\":\"hls\",\"x\":840,\"y\":400,\"properties\":{\"icon\":\"icon_module/svg/hls.svg\",\"name\":\"视频流\",\"imgFit\":\"fill\",\"url\":\"https://gcalic.v.myalicdn.com/gc/wgw05_1/index.m3u8?contentid=2820180516001\",\"zIndex\":10},\"zIndex\":10},{\"id\":\"f8bb48ac-ab00-45e6-a70f-dac4590f26dd\",\"type\":\"drag-edge-node\",\"x\":597,\"y\":324,\"properties\":{\"icon\":\"icon_module/svg/polyline.svg\",\"name\":\"折线\",\"animationsType\":\"WaterDrop\",\"animationStroke\":\"#E3D993\",\"animationSpeed\":10,\"borderWidth\":5,\"borderColor\":\"#75CACD\",\"zIndex\":10,\"pointsList\":[{\"x\":10,\"y\":25},{\"x\":108,\"y\":229},{\"x\":340,\"y\":64},{\"x\":538,\"y\":44}],\"nodeSize\":{\"width\":608,\"height\":430},\"animationOpen\":true},\"zIndex\":10}],\"edges\":[]},\"model\":\"topology\",\"openRule\":false,\"setting\":{\"width\":1254,\"height\":774,\"describe\":\"\",\"grid\":{\"size\":20,\"open\":false,\"type\":\"mesh\",\"config\":{\"color\":\"#cccccc\",\"thickness\":1}},\"backgroundType\":\"adaption\",\"backgroundColor\":\"#ffffff\"}}],\"twin\":{\"data\":{\"twinDataType\":\"WebSocket\",\"url\":\"ws://127.0.0.1:8889/visual/screen/twin\",\"username\":\"\",\"password\":\"\",\"topic\":\"\",\"pubTopic\":\"\"}}}', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABOYAAAMGCAYAAABWH4smAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3XdwZOd55/tfR6CRMwY5TSY5iSJHFBXMMEqUpSsGUbIkWmHlsF7Le+8/t7bq1q317v/Xstdb17pbtiVZVhZNUoFipkiKMiVyODOcPJiAnHPueOv0TA/RABpoAA30Cd+uUs0McM77Ps/nORieefSe87pisVhMfBBAAAEEEEAAAQQQQAABBBBAAAEEEEBgWwVcNOa21ZvJEEAAAQQQQAABBBBAAAEEEEAAAQQQiAvQmONCQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTmsoDOlAgggAACCCCAAAIIIIAAAggggAACCNCY4xpAAAEEEEAAAQQQQAABBBBAAAEEEEAgCwI05rKAzpQIIIAAAggggAACCCCAAAIIIIAAAgjQmOMaQAABBBBAAAEEEEAAAQQQQAABBBBAIAsCNOaygM6UCCCAAAIIIIAAAggggAACCCCAAAII0JjjGkAAAQQQQAABBBBAAAEEEEAAAQQQQCALAjTm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EXgjAQ+Gb/RheasECBAgQIDARwh4/vqIj9ESBAh8iIAw9yEfpDUIvKuAB8N3/eS8bwIECBAgQOBdBTx/vesn530TIPCJAsLcJ36qdiLwRgI/Hwwf/fOn/8fWN1rRWyVAgAABAgQI3ErA89etPg5vhgCBcQFhbvwArE+AAAECBAgQIECAAAECBAgQINAICHONu6kECBAgQIAAAQIECBAgQIAAAQLjAsLc+AFYnwABAgQIECBAgAABAgQIECBAoBEQ5hp3UwkQIECAAAECBAgQIECAAAECBMYFhLnxA7A+AQIECBAgQIAAAQIECBAgQIBAIyDMNe6mEiBAgAABAgQIECBAgAABAgQIjAsIc+MHYH0CBAgQIECAAAECBAgQIECAAIFGQJhr3E0lQIAAAQIECBAgQIAAAQIECBAYFxDmxg/A+gQIECBAgAABAgQIECBAgAABAo2AMNe4m0qAAAECBAgQIECAAAECBAgQIDAuIMyNH4D1CRAgQIAAAQIECBAgQIAAAQIEGgFhrnE3lQABAgQIECBAgAABAgQIECBAYFxAmBs/AOsTIECAAAECBAgQIECAAAECBAg0AsJc424qAQIECBAgQIAAAQIECBAgQIDAuIAwN34A1idAgAABAgQIECBAgAABAgQIEGgEhLnG3VQCBAgQIECAAAECBAgQIECAAIFxAWFu/ACsT4AAAQIECBAgQIAAAQIECBAg0AgIc427qQQIECBAgAABAgQIECBAgAABAuMCwtz4AVifAAECBAgQIECAAAECBAgQIECgERDmGndTCRAgQIAAAQIECBAgQIAAAQIExgWEufEDsD4BAgQIECBAgAABAgQIECBAgEAjIMw17qYSIECAAAECBAgQIECAAAECBAiMCwhz4wdgfQIECBAgQIAAAQIECBAgQIAAgUZAmGvcTSVAgAABAgQIECBAgAABAgQIEBgXEObGD8D6BAgQIECAAAECBAgQIECAAAECjYAw17ibSoAAAQIECBAgQIAAAQIECBAgMC4gzI0fgPUJECBAgAABAgQIECBAgAABAgQaAWGucTeVAAECBAgQIECAAAECBAgQIEBgXECYGz8A6xMgQIAAAQIECBAgQIAAAQIECDQCwlzjbioBAgQIECBAgAABAgQIECBAgMC4gDA3fgDWJ0CAAAECBAgQIECAAAECBAgQaASEucbdVAIECBAgQIAAAQIECBAgQIAAgXEBYW78AKxPgAABAgQIECBAgAABAgQIECDQCAhzjbupBAgQIECAAAECBAgQIECAAAEC4wLC3PgBWJ8AAQIECBAgQIAAAQIECBAgQKAREOYad1MJECBAgAABAgQIECBAgAABAgTGBYS58QOwPgECBAgQIECAAAECBAgQIECAQCMgzDXuphIgQIAAAQIECBAgQIAAAQIECIwLCHPjB2B9AgQIECBAgAABAgQIECBAgACBRkCYa9xNJUCAAAECBAgQIECAAAECBAgQGBcQ5sYPwPoECBAgQIAAAQIECBAgQIAAAQKNgDDXuJtKgAABAgQIECBAgAABAgQIECAwLiDMjR+A9QkQIECAAAECBAgQIECAAAECBBoBYa5xN5UAAQIECBAgQIAAAQIECBAgQGBcQJgbPwDrEyBAgAABAgQIECBAgAABAgQINALCXONuKgECBAgQIECAAAECBAgQIECAwLiAMDd+ANYnQIAAAQIECBAgQIAAAQIECBBoBIS5xt1UAgQIECBAgAABAgQIECBAgACBcQFhbvwArE+AAAECBAgQIECAAAECBAgQINAICHONu6kECBAgQIAAAQIECBAgQIAAAQLjAsLc+AFYnwABAgQIECBAgAABAgQIECBAoBEQ5hp3UwkQIECAAAECBAgQIECAAAECBMYFhLnxA7A+AQIECBAgQIAAAQIECBAgQIBAIyDMNe6mEiBAgAABAgQIECBAgAABAgQIjAsIc+MHYH0CBAgQIECAAAECBAgQIECAAIFGQJhr3E0lQIAAAQIECBAgQIAAAQIECBAYFxDmxg/A+gQIECBAgAABAgQIECBAgAABAo2AMNe4m0qAAAECBAgQIECAAAECBAgQIDAuIMyNH4D1CRAgQIAAAQIECBAgQIAAAQIEGgFhrnE3lQABAgQIECBAgAABAgQIECBAYFxAmBs/AOsTIECAAAECBAgQIECAAAECBAg0AsJc424qAQIECBAgQIAAAQIECBAgQIDAuIAwN34A1idAgAABAgQIECBAgAABAgQIEGgEhLnG3VQCBAgQIECAAAECBAgQIECAAIFxAWFu/ACsT4AAAQIECBAgQIAAAQIECBAg0AgIc427qQQIECBAgAABAgQIECBAgAABAuMCwtz4AVifAAECBAgQIECAAAECBAgQIECgERDmGndTCRAgQIAAAQIECBAgQIAAAQIExgWEufEDsD4BAgQIECBAgAABAgQIECBAgEAjIMw17qYSIECAAAECBAgQIECAAAECBAiMCwhz4wdgfQIECBAgQIAAAQIECBAgQIAAgUZAmGvcTSVAgAABAgQIECBAgAABAgQIEBgXEObGD8D6BAgQIECAAAECBAgQIECAAAECjYAw17ibSoAAAQIECBAgQIAAAQIECBAgMC4gzI0fgPUJECBAgAABAgQIECBAgAABAgQaAWGucTeVAAECBAgQIECAAAECBAgQIEBgXECYGz8A6xMgQIAAAQIECBAgQIAAAQIECDQCwlzjbioBAgQIECBAgAABAgQIECBAgMC4gDA3fgDWJ0CAAAECBAgQIECAAAECBAgQaASEucbdVAIECBAgQIAAAQIECBAgQIAAgXEBYW78AKxPgAABAgQIECBAgAABAgQIECDQCAhzjbupBAgQIECAAAECBAgQIECAAAEC4wLC3PgBWJ8AAQIECBAgQIAAAQIECBAgQKAREOYad1MJECBAgAABAgQIECBAgAABAgTGBYS58QOwPgECBAgQIECAAAECBAgQIECAQCMgzDXuphIgQIAAAQIECBAgQIAAAQIECIwLCHPjB2B9AgQIECBAgAABAgQIECBAgACBRkCYa9xNJUCAAAECBAgQIECAAAECBAgQGBcQ5sYPwPoECBAgQIAAAQIECBAgQIAAAQKNgDDXuJtKgAABAgQIECBAgAABAgQIECAwLiDMjR+A9QkQIECAAAECBAgQIECAAAECBBoBYa5xN5UAAQIECBAgQIAAAQIECBAgQGBcQJgbPwDrEyBAgAABAgQIECBAgAABAgQINALCXONuKgECBAgQIECAAAECBAgQIECAwLiAMDd+ANYnQIAAAQIECBAgQIAAAQIECBBoBIS5xt1UAgQIECBAgAABAgQIECBAgACBcQFhbvwArE+AAAECBAgQIECAAAECBAgQINAICHONu6kECBAgQIAAAQIECBAgQIAAAQLjAsLc+AFYnwABAgQIECBAgAABAgQIECBAoBEQ5hp3UwkQIECAAAECBAgQIECAAAECBMYFhLnxA7A+AQIECBAgQIAAAQIECBAgQIBAIyDMNe6mEiBAgAABAgQIECBAgAABAgQIjAsIc+MHYH0CBAgQIECAAAECBAgQIECAAIFGQJhr3E0lQIAAAQIECBAgQIAAAQIECBAYFxDmxg/A+gQIECBAgAABAgQIECBAgAABAo2AMNe4m0qAAAECBAgQIECAAAECBAgQIDAuIMyNH4D1CRAgQIAAAQIECBAgQIAAAQIEGgFhrnE3lQABAgQIECBAgAABAgQIECBAYFxAmBs/AOsTIECAAAECBAgQIECAAAECBAg0AsJc424qAQIECBAgQIAAAQIECBAgQIDAuIAwN34A1idAgAABAgQIECBAgAABAgQIEGgEhLnG3VQCBAgQIECAAAECBAgQIECAAIFxAWFu/ACsT4AAAQIECBAgQIAAAQIECBAg0AgIc427qQQIECBAgAABAgQIECBAgAABAuMCwtz4AVifAAECBAgQIECAAAECBAgQIECgERDmGndTCRAgQIAAAQIECBAgQIAAAQIExgWEufEDsD4BAgQIECBAgAABAgQIECBAgEAjIMw17qYSIECAAAECBAgQIECAAAECBAiMCwhz4wdgfQIECBAgQIAAAQIECBAgQIAAgUZAmGvcTSVAgAABAgQIECBAgAABAgQIEBgXEObGD8D6BAgQIECAAAECBAgQIECAAAECjYAw17ibSoAAAQIECBAgQIAAAQIECBAgMC4gzI0fgPUJECBAgAABAgQIECBAgAABAgQaAWGucTeVAAECBAgQIECAAAECBAgQIEBgXECYGz8A6xMgQIAAAQIECBAgQIAAAQIECDQCwlzjbioBAgQIECBAgAABAgQIECBAgMC4gDA3fgDWJ0CAAAECBAgQIECAAAECBAgQaASEucbdVAIECBAgQIAAAQIECBAgQIAAgXEBYW78AKxPgAABAgQIECBAgAABAgQIECDQCAhzjbupBAgQIECAAAECBAgQIECAAAEC4wLC3PgBWJ8AAQIECBAgQIAAAQIECBAgQKAREOYad1MJECBAgAABAgQIECBAgAABAgTGBYS58QOwPgECBAgQIECAAAECBAgQIECAQCMgzDXuphIgQIAAAQIECBAgQIAAAQIECIwLCHPjB2B9AgQIECBAgAABAgQIECBAgACBRkCYa9xNJUCAAAECBAgQIECAAAECBAgQGBcQ5sYPwPoECBAgQIAAAQIECBAgQIAAAQKNgDDXuJtKgAABAgQIECBAgAABAgQIECAwLiDMjR+A9QkQIECAAAECBAgQIECAAAECBBoBYa5xN5UAAQIECBAgQIAAAQIECBAgQGBcQJgbPwDrEyBAgAABAgQIECBAgAABAgQINALCXONuKgECBAgQIECAAAECBAgQIECAwLiAMDd+ANYnQIAAAQIECBAgQIAAAQIECBBoBIS5xt1UAgQIECBAgAABAgQIECBAgACBcQFhbvwArE+AAAECBAgQIECAAAECBAgQINAICHONu6kECBAgQIAAAQIECBAgQIAAAQLjAsLc+AFYnwABAgQIECBAgAABAgQIECBAoBEQ5hp3UwkQIECAAAECBAgQIECAAAECBMYFhLnxA7A+AQIECBAgQIAAAQIECBAgQIBAIyDMNe6mEiBAgAABAgQIECBAgAABAgQIjAsIc+MHYH0CBAgQIECAAAECBAgQIECAAIFGQJhr3E0lQIAAAQIECBAgQIAAAQIECBAYFxDmxg/A+gQIECBAgAABAgQIECBAgAABAo2AMNe4m0qAAAECBAgQIECAAAECBAgQIDAuIMyNH4D1CRAgQIAAAQIECBAgQIAAAQIEGgFhrnE3lQABAgQIECBAgAABAgQIECBAYFxAmBs/AOsTIECAAAECBAgQIECAAAECBAg0AsJc424qAQIECBAgQIAAAQIECBAgQIDAuIAwN34A1idAgAABAgQIECBAgAABAgQIEGgEhLnG3VQCBAgQIECAAAECBAgQIECAAIFxAWFu/ACsT4AAAQIECBAgQIAAAQIECBAg0AgIc427qQQIECBAgAABAgQIECBAgAABAuMCwtz4AVifAAECBAgQIECAAAECBAgQIECgERDmGndTCRAgQIAAAQIECBAgQIAAAQIExgWEufEDsD4BAgQIECBAgAABAgQIECBAgEAjIMw17qYSIECAAAECBAgQIECAAAECBAiMCwhz4wdgfQIECBAgQIAAAQIECBAgQIAAgUZAmGvcTSVAgAABAgQIECBAgAABAgQIEBgXEObGD8D6BAgQIECAAAECBAgQIECAAAECjYAw17ibSoAAAQIECBAgQIAAAQIECBAgMC4gzI0fgPUJECBAgAABAgQIECBAgAABAgQaAWGucTeVAAECBAgQIECAAAECBAgQIEBgXECYGz8A6xMgQIAAAQIECBAgQIAAAQIECDQCwlzjbioBAgQIECBAgAABAgQIECBAgMC4gDA3fgDWJ0CAAAECBAgQIECAAAECBAgQaASEucbdVAIECBAgQIAAAQIECBAgQIAAgXEBYW78AKxPgAABAgQIECBAgAABAgQIECDQCAhzjbupBAgQIECAAAECBAgQIECAAAEC4wLC3PgBWJ8AAQIECBAgQIAAAQIECBAgQKAREOYad1MJECBAgAABAgQIECBAgAABAgTGBYS58QOwPgECBAgQIECAAAECBAgQIECAQCMgzDXuphIgQIAAAQIECBAgQIAAAQIECIwLCHPjB2B9AgQIECBAgAABAgQIECBAgACBRkCYa9xNJUCAAAECBAgQIECAAAECBAgQGBcQ5sYPwPoECBAgQIAAAQIECBAgQIAAAQKNgDDXuJtKgAABAgQIECBAgAABAgQIECAwLiDMjR+A9QkQIECAAAECBAgQIECAAAECBBoBYa5xN5UAAQIECBAgQIAAAQIECBAgQGBcQJgbPwDrEyBAgAABAgQIECBAgAABAgQINALCXONuKgECBAgQIECAAAECBAgQIECAwLiAMDd+ANYnQIAAAQIECBAgQIAAAQIECBBoBIS5xt1UAgQIECBAgAABAgQIECBAgACB6Yfl+wAAA9lJREFUcQFhbvwArE+AAAECBAgQIECAAAECBAgQINAICHONu6kECBAgQIAAAQIECBAgQIAAAQLjAsLc+AFYnwABAgQIECBAgAABAgQIECBAoBEQ5hp3UwkQIECAAAECBAgQIECAAAECBMYFhLnxA7A+AQIECBAgQIAAAQIECBAgQIBAIyDMNe6mEiBAgAABAgQIECBAgAABAgQIjAsIc+MHYH0CBAgQIECAAAECBAgQIECAAIFGQJhr3E0lQIAAAQIECBAgQIAAAQIECBAYFxDmxg/A+gQIECBAgAABAgQIECBAgAABAo2AMNe4m0qAAAECBAgQIECAAAECBAgQIDAuIMyNH4D1CRAgQIAAAQIECBAgQIAAAQIEGgFhrnE3lQABAgQIECBAgAABAgQIECBAYFxAmBs/AOsTIECAAAECBAgQIECAAAECBAg0AsJc424qAQIECBAgQIAAAQIECBAgQIDAuIAwN34A1idAgAABAgQIECBAgAABAgQIEGgEhLnG3VQCBAgQIECAAAECBAgQIECAAIFxAWFu/ACsT4AAAQIECBAgQIAAAQIECBAg0AgIc427qQQIECBAgAABAgQIECBAgAABAuMCwtz4AVifAAECBAgQIECAAAECBAgQIECgERDmGndTCRAgQIAAAQIECBAgQIAAAQIExgWEufEDsD4BAgQIECBAgAABAgQIECBAgEAjIMw17qYSIECAAAECBAgQIECAAAECBAiMCwhz4wdgfQIECBAgQIAAAQIECBAgQIAAgUZAmGvcTSVAgAABAgQIECBAgAABAgQIEBgXEObGD8D6BAgQIECAAAECBAgQIECAAAECjYAw17ibSoAAAQIECBAgQIAAAQIECBAgMC4gzI0fgPUJECBAgAABAgQIECBAgAABAgQaAWGucTeVAAECBAgQIECAAAECBAgQIEBgXECYGz8A6xMgQIAAAQIECBAgQIAAAQIECDQCwlzjbioBAgQIECBAgAABAgQIECBAgMC4gDA3fgDWJ0CAAAECBAgQIECAAAECBAgQaASEucbdVAIECBAgQIAAAQIECBAgQIAAgXEBYW78AKxPgAABAgQIECBAgAABAgQIECDQCAhzjbupBAgQIECAAAECBAgQIECAAAEC4wLC3PgBWJ8AAQIECBAgQIAAAQIECBAgQKAREOYad1MJECBAgAABAgQIECBAgAABAgTGBYS58QOwPgECBAgQIECAAAECBAgQIECAQCMgzDXuphIgQIAAAQIECBAgQIAAAQIECIwLCHPjB2B9AgQIECBAgAABAgQIECBAgACBRuA/7CeVn+qyIo4AAAAASUVORK5CYII=', 'da', '0', '2023-07-24 09:51:02', '2023-08-07 16:26:51', 'panda', ''); + +-- ---------------------------- +-- Table structure for visual_screen_group +-- ---------------------------- +DROP TABLE IF EXISTS `visual_screen_group`; +CREATE TABLE `visual_screen_group` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '分组名', + `pid` int(0) NULL DEFAULT NULL COMMENT '父Id', + `path` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路径', + `sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_screen_group +-- ---------------------------- +INSERT INTO `visual_screen_group` VALUES (1, '拓扑图', 0, '/0/1', 1, '0'); +INSERT INTO `visual_screen_group` VALUES (2, '组态设计', 0, '/0/2', 2, '0'); +INSERT INTO `visual_screen_group` VALUES (3, 'BI大屏', 0, '/0/3', 3, '0'); +INSERT INTO `visual_screen_group` VALUES (5, '标准拓扑', 1, '/0/1/5', 1, '0'); +INSERT INTO `visual_screen_group` VALUES (6, '网络拓扑', 1, '/0/1/6', 2, '0'); +INSERT INTO `visual_screen_group` VALUES (7, '报表设计', 0, '/0/7', 4, '0'); + +-- ---------------------------- +-- Table structure for visual_screen_image +-- ---------------------------- +DROP TABLE IF EXISTS `visual_screen_image`; +CREATE TABLE `visual_screen_image` ( + `file_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `file_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of visual_screen_image +-- ---------------------------- +INSERT INTO `visual_screen_image` VALUES ('9b37cd4ca37090649adcee8bf17cfdcc_20230414141350.png', 'uploads/file/9b37cd4ca37090649adcee8bf17cfdcc_20230414141350.png'); +INSERT INTO `visual_screen_image` VALUES ('626213519d0907c2f2ab12919fbd7779_20230414142538.png', 'uploads/file/626213519d0907c2f2ab12919fbd7779_20230414142538.png'); +INSERT INTO `visual_screen_image` VALUES ('dc49aad85da7ae4c37374bf79e29134c_20230414144346.png', 'uploads/file/dc49aad85da7ae4c37374bf79e29134c_20230414144346.png'); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/resource/rbac_model.conf b/resource/rbac_model.conf index 0e41f274dac8a6747e83f3c9fd214c72885d697f..49a59cbb3d478732d3bbd3f775eab29bba5579e2 100644 --- a/resource/rbac_model.conf +++ b/resource/rbac_model.conf @@ -1,11 +1,11 @@ [request_definition] -r = dom, sub, obj, act +r = sub, obj, act [policy_definition] -p = dom, sub, obj, act +p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] -m = r.dom == p.dom && r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && ( r.act == p.act || p.act == '*') \ No newline at end of file +m = r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && ( r.act == p.act || p.act == '*') \ No newline at end of file diff --git a/resource/template/vue/edit-vue.template b/resource/template/vue/edit-vue.template index 541021c4fd6146c521dfbc60898ec85ba0fe3642..9d818dbf2e45fa1852b204489fb4bab45aa55279 100644 --- a/resource/template/vue/edit-vue.template +++ b/resource/template/vue/edit-vue.template @@ -81,7 +81,7 @@