├── LICENSE ├── README-en.md ├── README.md ├── bin ├── .gitignore └── config.toml ├── server ├── .gitignore ├── appStart.go ├── check │ └── parameter.go ├── config.toml ├── convert │ └── ormToProto.go ├── data │ ├── globals.go │ ├── manager.go │ ├── node.go │ ├── nodeFunc.go │ ├── nodeFuncCall.go │ ├── nodeNotify.go │ ├── nodeReport.go │ ├── nodeReportVal.go │ ├── nodeResource.go │ ├── nodeTest.go │ └── topMenu.go ├── db │ ├── globals.go │ ├── manager.go │ ├── node.go │ ├── nodeFunc.go │ ├── nodeFuncCall.go │ ├── nodeNotify.go │ ├── nodeReport.go │ ├── nodeReportVal.go │ ├── nodeResource.go │ └── topMenu.go ├── gateway │ ├── globals.go │ ├── rpc.go │ └── websocket.go ├── go.mod ├── go.sum ├── main.go ├── protoFiles │ └── protoManage │ │ └── manage.pb.go ├── request │ ├── globals.go │ ├── interceptor.go │ ├── manager.go │ ├── node.go │ ├── nodeFunc.go │ ├── nodeFuncCall.go │ ├── nodeNotify.go │ ├── nodeReport.go │ ├── nodeReportVal.go │ ├── nodeResource.go │ ├── rpcStream.go │ ├── topMenu.go │ └── websocket.go ├── test │ └── makeDBData │ │ └── make_test.go └── typedef │ ├── config │ └── config.go │ ├── constant │ └── value.go │ └── orm │ └── orm.go ├── store ├── cache │ └── .gitignore ├── cert │ ├── grpc │ │ ├── ca_cert.pem │ │ ├── server_cert.pem │ │ └── server_key.pem │ └── https │ │ ├── private.key │ │ └── public.pem ├── db │ └── .gitignore ├── image │ ├── group.jpg │ ├── home-en.jpg │ └── home.jpg └── log │ └── .gitignore └── web ├── .gitignore ├── LICENSE ├── index.html ├── package-lock.json ├── package.json ├── public └── mxui.svg ├── src ├── App.vue ├── assets │ └── logo.svg ├── base │ ├── convert.ts │ ├── defaultVal.ts │ ├── filter.ts │ ├── globals.ts │ ├── i18n.ts │ ├── refresh.ts │ ├── request.ts │ └── websocket.ts ├── components │ ├── Empty.vue │ ├── Head.vue │ ├── Load.vue │ ├── Page.vue │ ├── Sidebar.vue │ ├── card │ │ ├── CardViewFrame.vue │ │ ├── NodeCard.vue │ │ ├── NodeFuncCard.vue │ │ └── NodeReportCard.vue │ ├── cardItem │ │ ├── CardBase.vue │ │ ├── CardFuncCall.vue │ │ ├── CardInfo.vue │ │ ├── CardName.vue │ │ ├── CardReportVal.vue │ │ └── CardState.vue │ ├── echarts │ │ ├── NodeFuncReturnCharts.vue │ │ └── NodeReportValLine.vue │ ├── file │ │ └── FileSave.vue │ ├── headButton │ │ ├── AutoRefreshButton.vue │ │ ├── FilterButton.vue │ │ └── SettingButton.vue │ ├── json │ │ └── JsonEdit.vue │ ├── link │ │ └── LinkJump.vue │ ├── media │ │ └── Player.vue │ ├── setting │ │ ├── AutoRefresh.vue │ │ ├── LevelSelect.vue │ │ ├── PasswordReset.vue │ │ ├── SystemSet.vue │ │ ├── TopMenuSet.vue │ │ └── UserSet.vue │ ├── table │ │ ├── NodeFuncCallTable.vue │ │ ├── NodeFuncReturnTable.vue │ │ ├── NodeNotifyTable.vue │ │ ├── NodeReportValTable.vue │ │ └── NodeResourceTable.vue │ ├── tableInfiniteScroll │ │ ├── index.ts │ │ └── tableInfiniteScroll.ts │ ├── toolbar │ │ └── filter │ │ │ ├── FilterViewFrame.vue │ │ │ ├── FilterViewTag.vue │ │ │ ├── NodeFilter.vue │ │ │ ├── NodeFuncFilter.vue │ │ │ ├── NodeNotifyFilter.vue │ │ │ ├── NodeReportFilter.vue │ │ │ ├── NodeResourceFilter.vue │ │ │ └── components │ │ │ ├── FilterDateTimePicker.vue │ │ │ ├── FilterDateTimeRangePicker.vue │ │ │ ├── FilterInput.vue │ │ │ └── FilterSelect.vue │ └── vueForm │ │ └── widgets │ │ └── UploadFile.vue ├── css │ ├── card.css │ ├── color.css │ └── flex.css ├── index.css ├── main.ts ├── proto │ ├── manage.d.ts │ └── manage.js ├── router.ts └── views │ ├── Home.vue │ ├── Login.vue │ ├── NotFound.vue │ ├── Register.vue │ ├── dialog │ ├── DialogViewFrame.vue │ ├── NodeFuncCall.vue │ ├── NodeFuncHistory.vue │ ├── NodeFuncReturn.vue │ └── NodeReportVal.vue │ └── node │ ├── Node.vue │ ├── NodeFunc.vue │ ├── NodeNotify.vue │ ├── NodeReport.vue │ ├── NodeResource.vue │ ├── NodeTest.vue │ └── NodeViewFrame.vue ├── tsconfig.json └── vite.config.ts /README-en.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | [简体中文](./README.md) | English 19 | 20 | 21 | ## About 22 | MXUI is an API visualization platform based on golang + vue3. It can quickly use the back-end API to generate UI components such as forms, tables, charts, file upload and download, audio and video playback and so on. At the same time, it integrates authority management, history, message notification and other functions. It can significantly improve the efficiency of development and testing 23 | 24 | ## Features 25 | - Out of the box, easy deployment, default configuration, no need to install other dependent services 26 | - UI interface generation, network request and API call process can be completed in one minute. Only one function (API) needs to be provided at the back end 27 | - Built in rich UI components, modify or add API to support dynamic loading 28 | - The built-in JSON editor supports two parameter editing modes of form / JSON, and uses JSON schema for parameter verification 29 | - The API access adopts the client mode, without exposing and monitoring ports, with built-in JWT authentication, API authority management and other security settings 30 | - Support file upload, API request, record query, error prompt, message push, background data monitoring (experimental) and other auxiliary functions 31 | - Support multiple types of data sources (sqlite, mysql, postgresql...) 32 | - Multilingual support (i18n) 33 | 34 | 35 | ## Document 36 | - [中文](https://mxui-doc.liyiligang.com) 37 | - [English](https://mxui-doc.liyiligang.com/en) 38 | 39 | ## Preview 40 | - [MXUI](https://mxui.liyiligang.com) 41 | 42 | ## Build 43 | ```bash 44 | # Clone 45 | git clone https://github.com/liyiligang/mxui.git 46 | 47 | # Build server 48 | cd mxui/server/ 49 | go build -o ../bin 50 | 51 | # Build web 52 | cd mxui/web/ 53 | npm run build 54 | ``` 55 | 56 | ## Releases 57 | - [Download](https://github.com/liyiligang/mxui/releases) 58 | 59 | ## Run 60 | ```bash 61 | cd mxui/bin/ 62 | 63 | # windows 64 | mxui.exe 65 | 66 | # linux 67 | ./mxui 68 | ``` 69 | 70 | ## Enter MXUI 71 | ### Browser access: http://localhost:806 Enter the login interface 72 | 73 | 74 | ## Client 75 | After the deployment of the server, you need to introduce the mxui client package into your code, and use the API provided by this package to generate the UI you want 76 | At present, mxui provides golang client support. We encourage and welcome you to develop more programming language clients! 77 | - golang: [mxui-go-client](https://github.com/liyiligang/mxui-go-client) 78 | 79 | ## Contact information 80 | ### QQ Group: 757595139 81 | 82 | 83 | ## Questions or suggestions 84 | - Any use questions or suggestions can be submitted to GitHub issue or contact me through QQ group 85 | - Before submitting the issue, please search whether the relevant content has been proposed 86 | 87 | ## License 88 | [Apache-2.0](LICENSE) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | [English](./README-en.md) | 简体中文 19 | 20 | 21 | ## 简介 22 | MXUI是基于golang+vue3搭建的接口可视化平台, 能够快速的利用后端接口生成表单, 表格, 图表, 文件上传下载,音视频播放等UI组件。同时集成权限管理, 历史记录, 消息通知等功能。能够显著提高开发测试效率 23 | 24 | ## 特性 25 | - 开箱即用, 部署便捷, 默认配置无需安装其他依赖服务 26 | - 一分钟即可完成UI界面生成, 网络请求, 接口调用流程, 仅需后端提供一个函数(接口) 27 | - 内置丰富的UI组件, 修改或新增接口支持动态加载 28 | - 内置json编辑器, 支持表单/json两种参数编辑模式, 并使用json schema做参数校验 29 | - 接口访问采用客户端模式, 无需暴露和监听端口, 内置jwt鉴权, 接口权限管理等安全设置 30 | - 支持文件上传, 接口请求记录查询, 错误提示, 消息推送, 后台数据监控(实验性)等辅助功能 31 | - 支持多种类型的数据源(sqlite, mysql, postgresql...) 32 | - 多语言支持(i18n) 33 | 34 | 35 | ## 查看文档 36 | - [中文](https://mxui-doc.liyiligang.com) 37 | - [English](https://mxui-doc.liyiligang.com/en) 38 | 39 | ## 在线预览 40 | - [MXUI](https://mxui.liyiligang.com) 41 | 42 | ## 编译 43 | ```bash 44 | # 克隆项目 45 | git clone https://github.com/liyiligang/mxui.git 46 | 47 | # 编译服务端 48 | cd mxui/server/ 49 | go build -o ../bin 50 | 51 | # 编译web端 52 | cd mxui/web/ 53 | npm run build 54 | ``` 55 | 56 | ## Releases 57 | - [下载](https://github.com/liyiligang/mxui/releases) 58 | 59 | ## 运行 60 | ```bash 61 | cd mxui/bin/ 62 | 63 | # windows 64 | mxui.exe 65 | 66 | # linux 67 | ./mxui 68 | ``` 69 | 70 | ## 进入MXUI 71 | ### 浏览器访问: http://localhost:806 进入登录界面 72 | 73 | 74 | ## 客户端 75 | 服务端部署完成后, 需要在你的代码里引入MXUI客户端包, 利用此包提供的API就可以生成你想要的UI了 76 | 目前MXUI提供了golang的客户端支持, 我们鼓励且欢迎大家开发更多编程语言的客户端! 77 | - golang: [mxui-go-client](https://github.com/liyiligang/mxui-go-client) 78 | 79 | ## 联系方式 80 | ### QQ交流群: 757595139 81 | 82 | 83 | ## 问题或建议 84 | - 有任何使用问题或者建议都可以提交至 Github issue 或者通过QQ群内联系我 85 | - 在提交 issue 之前,请搜索相关内容是否已被提出 86 | 87 | ## License 88 | [Apache-2.0](LICENSE) -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !config.toml 4 | -------------------------------------------------------------------------------- /bin/config.toml: -------------------------------------------------------------------------------- 1 | Debug = false 2 | 3 | [User] 4 | OpenRegister = true 5 | 6 | [Node] 7 | NodeName = '' 8 | 9 | [File] 10 | SavePath = '../store/cache/' 11 | MaxSize = 200 #Company: M 12 | MaxAge = 5 #File retention time: days 13 | 14 | [Log] 15 | Path = '../store/log/app.log' 16 | Level = 'info' 17 | MaxSize = 200 #Maximum size saved per log file unit: M 18 | MaxNum = 1000 #How many log files can be saved at most 19 | MaxAge = 30 #How many days can the log file be saved at most 20 | 21 | [Token] 22 | Key = 'ChYzvtt8ixVbM%Eo' #Token key 23 | StartDuration = 0 #How long will the token take effect (hours, 0: immediately) 24 | StopDuration = 1000 #How long after the token takes effect (hours, 0: immediate) 25 | 26 | [DB] 27 | Name = 'sqlite' 28 | Connect = '../store/db/mxui.db' 29 | MaxConn = 0 #Maximum number of connections, 0 means unlimited 30 | MaxKeepConn = 2 #Maximum number of connections maintained (long connections) 31 | MaxLifeTime = 21 #Database request timeout (seconds, 0: for immediate rejection) 32 | 33 | [Grpc] 34 | ListenAddr = ':302' 35 | PublicKeyPath = '../store/cert/grpc/server_cert.pem' 36 | PrivateKeyPath = '../store/cert/grpc/server_key.pem' 37 | 38 | [Http] 39 | ShowLog = false 40 | UseHttps = false 41 | ListenAddr = '0.0.0.0:806' 42 | 43 | [Http.Https] 44 | RedirectAddr = '0.0.0.0:806' #Redirect HTTP to HTTPS 45 | PublicKeyPath = '../store/cert/https/public.pem' 46 | PrivateKeyPath = '../store/cert/https/private.key' 47 | 48 | [Http.WebSocket] 49 | ReadWaitTime = 0 #Read request timeout (seconds, 0: Forever timeout, negative: immediate timeout) 50 | WriteWaitTime = 5 #Write request timeout (seconds, 0: Forever timeout, negative: immediate timeout) 51 | PingWaitTime = 0 #Ping request timeout (seconds, 0: timeout forever, negative: timeout immediately) 52 | PongWaitTime = 0 #Pong request timeout (seconds, 0: timeout forever, negative: timeout immediately) 53 | 54 | [Http.Files] 55 | Web = './web' 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /server/config.toml: -------------------------------------------------------------------------------- 1 | Debug = true 2 | 3 | [User] 4 | OpenRegister = true 5 | 6 | [Node] 7 | NodeName = '' 8 | 9 | [Node.Report] 10 | MaxAge = 1 #Report Value retention time: days 11 | 12 | [File] 13 | SavePath = '../store/cache/' 14 | MaxSize = 200 #Company: M 15 | MaxAge = 5 #File retention time: days 16 | 17 | [Log] 18 | Path = '../store/log/app.log' 19 | Level = 'debug' 20 | MaxSize = 200 #Maximum size saved per log file unit: M 21 | MaxNum = 1000 #How many log files can be saved at most 22 | MaxAge = 30 #How many days can the log file be saved at most 23 | 24 | [Token] 25 | Key = 'ChYzvtt8ixVbM%Eo' #Token key 26 | StartDuration = 0 #How long will the token take effect (hours, 0: immediately) 27 | StopDuration = 1000 #How long after the token takes effect (hours, 0: immediate) 28 | 29 | [DB] 30 | ShowLog = false 31 | Name = 'sqlite' 32 | Connect = '../store/db/mxui.db' 33 | MaxConn = 0 #Maximum number of connections, 0 means unlimited 34 | MaxKeepConn = 2 #Maximum number of connections maintained (long connections) 35 | MaxLifeTime = 21 #Database request timeout (seconds, 0: for immediate rejection) 36 | 37 | [Grpc] 38 | ListenAddr = ':302' 39 | PublicKeyPath = '../store/cert/grpc/server_cert.pem' 40 | PrivateKeyPath = '../store/cert/grpc/server_key.pem' 41 | 42 | [Http] 43 | ShowLog = false 44 | ListenAddr = '0.0.0.0:806' 45 | PublicKeyPath = '../store/cert/https/public.pem' 46 | PrivateKeyPath = '../store/cert/https/private.key' 47 | 48 | [Http.WebSocket] 49 | ReadWaitTime = 0 #Read request timeout (seconds, 0: Forever timeout, negative: immediate timeout) 50 | WriteWaitTime = 5 #Write request timeout (seconds, 0: Forever timeout, negative: immediate timeout) 51 | PingWaitTime = 0 #Ping request timeout (seconds, 0: timeout forever, negative: timeout immediately) 52 | PongWaitTime = 0 #Pong request timeout (seconds, 0: timeout forever, negative: timeout immediately) 53 | 54 | [Http.Files] 55 | Web = './web' 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /server/data/globals.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package data 18 | 19 | import ( 20 | "errors" 21 | "github.com/liyiligang/base/component/Jlog" 22 | "github.com/liyiligang/base/component/Jtoken" 23 | "github.com/liyiligang/mxui/db" 24 | "github.com/liyiligang/mxui/gateway" 25 | "github.com/liyiligang/mxui/protoFiles/protoManage" 26 | "github.com/liyiligang/mxui/typedef/config" 27 | "github.com/liyiligang/mxui/typedef/orm" 28 | ) 29 | 30 | type Data struct { 31 | DB *db.Server 32 | Gateway *gateway.Gateway 33 | } 34 | 35 | type TokenData struct { 36 | UserID int64 37 | UserLevel protoManage.Level 38 | } 39 | 40 | func (data *Data) FindSystemInfo(info *protoManage.ReqSystemInitInfo) (*protoManage.AnsSystemInitInfo, error) { 41 | ans := &protoManage.AnsSystemInitInfo{} 42 | ormBase, err := data.DB.FindManagerByLevel(orm.Manager{Level: int32(protoManage.Level_LevelSuper)}) 43 | if err != nil { 44 | return nil, err 45 | } 46 | ans.SystemInit = ormBase.ID != 0 47 | ans.OpenRegister = config.LocalConfig.User.OpenRegister 48 | return ans, nil 49 | } 50 | 51 | func (data *Data) ParseToken(token string) (*TokenData, error) { 52 | claims, err := Jtoken.ParseToken(token, config.LocalConfig.Token.Key) 53 | if err != nil { 54 | return nil, err 55 | } 56 | jtiVal, ok := claims["jti"] 57 | if !ok { 58 | return nil, errors.New("id is not found in claims map") 59 | } 60 | id, ok := jtiVal.(float64) 61 | if !ok { 62 | return nil, errors.New("userID assert fail with float64") 63 | } 64 | levelVal, ok := claims["level"] 65 | if !ok { 66 | return nil, errors.New("level is not found in claims map") 67 | } 68 | level, ok := levelVal.(float64) 69 | if !ok { 70 | return nil, errors.New("level assert fail with float64") 71 | } 72 | return &TokenData{UserID: int64(id), UserLevel: protoManage.Level(level)}, nil 73 | } 74 | 75 | func (data *Data) DataInvalidDeal() { 76 | err := data.NodeResourceDelWithTimer() 77 | if err != nil { 78 | Jlog.Warn("find invalid resource fail", "error", err) 79 | } 80 | err = data.NodeReportValDelByMaxAge(config.LocalConfig.Node.Report.MaxAge) 81 | if err != nil { 82 | Jlog.Warn("delete invalid node report val fail", "error", err) 83 | } 84 | count, err := data.DB.FindNodeReportValCount() 85 | if err != nil { 86 | Jlog.Warn("get report val count fail", "error", err) 87 | } 88 | Jlog.Info("get report val count success", "count", count) 89 | } 90 | -------------------------------------------------------------------------------- /server/data/node.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package data 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/check" 21 | "github.com/liyiligang/mxui/convert" 22 | "github.com/liyiligang/mxui/protoFiles/protoManage" 23 | "github.com/liyiligang/mxui/typedef/orm" 24 | "github.com/pkg/errors" 25 | "gorm.io/gorm" 26 | ) 27 | 28 | func (data *Data) NodeAdd(protoNode *protoManage.Node) error { 29 | if err := check.NodeCheck(protoNode); err != nil { 30 | return err 31 | } 32 | ormNode := &orm.Node{Name: protoNode.Name} 33 | if err := data.DB.AddNode(ormNode); err != nil { 34 | return err 35 | } 36 | convert.OrmBaseToProtoBase(&ormNode.Base, &protoNode.Base) 37 | return nil 38 | } 39 | 40 | func (data *Data) NodeDel(protoNode *protoManage.Node) error { 41 | err := data.NodeFuncDelAllByNodeID(&protoManage.NodeFunc{NodeID: protoNode.Base.ID}) 42 | if err != nil { 43 | return err 44 | } 45 | err = data.NodeReportDelAllByNodeID(&protoManage.NodeReport{NodeID: protoNode.Base.ID}) 46 | if err != nil { 47 | return err 48 | } 49 | err = data.DB.DelNode(orm.Node{Base: orm.Base{ID: protoNode.Base.ID}}) 50 | if err != nil { 51 | return err 52 | } 53 | return nil 54 | } 55 | 56 | func (data *Data) NodeStateUpdate(protoNode *protoManage.Node) error { 57 | return data.DB.UpdateNodeState(orm.Node{Base: orm.Base{ID: protoNode.Base.ID}, State: int32(protoNode.State)}) 58 | } 59 | 60 | func (data *Data) NodeFind(req *protoManage.ReqNodeList) (*protoManage.AnsNodeList, error) { 61 | ormNodeList, err := data.DB.FindNode(req) 62 | if err != nil { 63 | return nil, err 64 | } 65 | protoNodeList := convert.OrmNodeListToProtoNodeList(ormNodeList) 66 | count, err := data.DB.FindNodeCount(req) 67 | if err != nil { 68 | return nil, err 69 | } 70 | return &protoManage.AnsNodeList{ 71 | NodeList: protoNodeList, 72 | Length: count}, nil 73 | } 74 | 75 | func (data *Data) NodeFindByID(protoNode *protoManage.Node) error { 76 | ormNode, err :=data.DB.FindNodeByID(orm.Node{Base: orm.Base{ID: protoNode.Base.ID}}) 77 | if err != nil { 78 | return err 79 | } 80 | convert.OrmNodeToProtoNode(ormNode, protoNode) 81 | return nil 82 | } 83 | 84 | func (data *Data) NodeFindByName(protoNode *protoManage.Node) error { 85 | ormNode, err :=data.DB.FindNodeByName(orm.Node{Name: protoNode.Name}) 86 | if err != nil { 87 | return err 88 | } 89 | convert.OrmNodeToProtoNode(ormNode, protoNode) 90 | return nil 91 | } 92 | 93 | func (data *Data) NodeFindOrAddByName(protoNode *protoManage.Node) error { 94 | err := data.NodeFindByName(protoNode) 95 | if err != nil { 96 | if errors.Is(err, gorm.ErrRecordNotFound) { 97 | return data.NodeAdd(protoNode) 98 | } 99 | return err 100 | } 101 | return nil 102 | } 103 | -------------------------------------------------------------------------------- /server/data/nodeNotify.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package data 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/check" 21 | "github.com/liyiligang/mxui/convert" 22 | "github.com/liyiligang/mxui/protoFiles/protoManage" 23 | "github.com/liyiligang/mxui/typedef/constant" 24 | "github.com/liyiligang/mxui/typedef/orm" 25 | ) 26 | 27 | func (data *Data) NodeNotifyAdd(protoNodeNotify *protoManage.NodeNotify, isSend bool) error { 28 | if err := check.NodeNotifyCheck(protoNodeNotify); err != nil { 29 | return err 30 | } 31 | if protoNodeNotify.SenderType == protoManage.NotifySenderType_NotifySenderTypeNode { 32 | node := protoManage.Node{Base: protoManage.Base{ID: protoNodeNotify.SenderID}} 33 | err := data.NodeFindByID(&node) 34 | if err != nil { 35 | return err 36 | } 37 | protoNodeNotify.SenderName = node.Name 38 | }else if protoNodeNotify.SenderType == protoManage.NotifySenderType_NotifySenderTypeUser{ 39 | manager := protoManage.Manager{} 40 | err := data.ManagerFindByID(protoNodeNotify.SenderID, &manager) 41 | if err != nil { 42 | return err 43 | } 44 | protoNodeNotify.SenderName = manager.NickName 45 | } 46 | if err := data.DB.AddNodeNotify(orm.NodeNotify{ 47 | SenderID: protoNodeNotify.SenderID, 48 | SenderName: protoNodeNotify.SenderName, 49 | SenderType: int64(protoNodeNotify.SenderType), 50 | Message: protoNodeNotify.Message, 51 | State: int32(protoNodeNotify.State), 52 | }); err != nil { 53 | return err 54 | } 55 | if isSend { 56 | return data.Gateway.WsSendOrBroadCastPB(constant.ConstSendBroadcast, protoManage.Order_NodeNotifyAdd, protoNodeNotify) 57 | } 58 | return nil 59 | } 60 | 61 | func (data *Data) NodeNotifyFind(req *protoManage.ReqNodeNotifyList) (*protoManage.AnsNodeNotifyList, error) { 62 | ormNotifyList, err := data.DB.FindNodeNotify(req) 63 | if err != nil { 64 | return nil, err 65 | } 66 | protoNodeNotifyList := convert.OrmNodeNotifyListToProtoNodeNotifyList(ormNotifyList) 67 | count, err := data.DB.FindNodeNotifyCount(req) 68 | if err != nil { 69 | return nil, err 70 | } 71 | return &protoManage.AnsNodeNotifyList{ 72 | Length: count, 73 | NodeNotifyList: protoNodeNotifyList, 74 | }, nil 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /server/data/nodeReportVal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package data 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/convert" 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | "github.com/liyiligang/mxui/typedef/orm" 23 | ) 24 | 25 | func (data *Data) NodeReportValFind(req *protoManage.ReqNodeReportValList) (*protoManage.AnsNodeReportValList, error) { 26 | ormReportValList, err := data.DB.FindNodeReportVal(req) 27 | if err != nil { 28 | return nil, err 29 | } 30 | protoNodeReportValList := convert.OrmNodeReportValListToProtoNodeReportValList(ormReportValList) 31 | return &protoManage.AnsNodeReportValList{NodeReportValList: protoNodeReportValList}, nil 32 | } 33 | 34 | func (data *Data) NodeReportValAdd(protoNodeReportVal *protoManage.NodeReportVal) error { 35 | ormNodeReportVal := &orm.NodeReportVal{ 36 | ReportID: protoNodeReportVal.ReportID, 37 | Value: protoNodeReportVal.Value, 38 | State: int32(protoNodeReportVal.State), 39 | } 40 | return data.DB.AddNodeReportVal(ormNodeReportVal) 41 | } 42 | 43 | func (data *Data) NodeReportValDelByNodeReportID(reportID int64) error { 44 | return data.DB.DelNodeReportValByNodeReportID(orm.NodeReportVal{ 45 | ReportID: reportID, 46 | }) 47 | } 48 | 49 | func (data *Data) NodeReportValDelByNodeID(nodeID int64) error { 50 | return data.DB.DelNodeReportValByNodeID(nodeID) 51 | } 52 | 53 | func (data *Data) NodeReportValDelByMaxAge(maxAge int) error { 54 | return data.DB.DelNodeReportValByMaxAge(maxAge) 55 | } -------------------------------------------------------------------------------- /server/data/nodeTest.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package data 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/protoFiles/protoManage" 21 | ) 22 | 23 | //%u7248%u6743%u6240%u6709 %u4E8C%u96F6%u4E8C%u4E8C %u674E%u6613%u529B%u521A 24 | func (data *Data) NodeTest(userID int64, protoNodeTest *protoManage.ReqNodeTest) error { 25 | return nil 26 | } 27 | 28 | -------------------------------------------------------------------------------- /server/data/topMenu.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package data 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/check" 21 | "github.com/liyiligang/mxui/convert" 22 | "github.com/liyiligang/mxui/protoFiles/protoManage" 23 | "github.com/liyiligang/mxui/typedef/orm" 24 | ) 25 | 26 | func (data *Data) TopLinkFind(req *protoManage.ReqTopLinkList) (*protoManage.AnsTopLinkList, error) { 27 | ormTopLink, err := data.DB.FindTopLink() 28 | if err != nil { 29 | return nil, err 30 | } 31 | protoTopLink := convert.OrmTopLinkListToProtoTopLinkList(ormTopLink) 32 | return &protoManage.AnsTopLinkList{TopLinkList: protoTopLink}, nil 33 | } 34 | 35 | func (data *Data) TopLinkFindByID(protoTopLink *protoManage.TopLink) error { 36 | ormTopLink, err :=data.DB.FindTopLinkByID(orm.TopLink{Base: orm.Base{ID: protoTopLink.Base.ID}}) 37 | if err != nil { 38 | return err 39 | } 40 | convert.OrmTopLinkToProtoTopLink(ormTopLink, protoTopLink) 41 | return nil 42 | } 43 | 44 | func (data *Data) TopLinkAdd(protoTopLink *protoManage.TopLink) error { 45 | if err := check.TopLinkCheck(protoTopLink); err != nil { 46 | return err 47 | } 48 | ormTopLink := orm.TopLink{Name: protoTopLink.Name, 49 | Url:protoTopLink.Url, State: int32(protoTopLink.State)} 50 | err := data.DB.AddTopLink(&ormTopLink) 51 | if err != nil { 52 | return err 53 | } 54 | convert.OrmTopLinkToProtoTopLink(&ormTopLink, protoTopLink) 55 | return nil 56 | } 57 | 58 | func (data *Data) TopLinkDel(protoTopLink *protoManage.TopLink) error { 59 | ormTopLink := orm.TopLink{Base: orm.Base{ID: protoTopLink.Base.ID}} 60 | err := data.DB.DelTopLink(&ormTopLink) 61 | if err != nil { 62 | return err 63 | } 64 | return nil 65 | } 66 | 67 | func (data *Data) TopLinkUpdate(protoTopLink *protoManage.TopLink) error { 68 | if err := check.TopLinkCheck(protoTopLink); err != nil { 69 | return err 70 | } 71 | ormTopLink := orm.TopLink{Base: orm.Base{ID: protoTopLink.Base.ID}, 72 | Name: protoTopLink.Name, Url: protoTopLink.Url, State: int32(protoTopLink.State)} 73 | err := data.DB.UpdateTopLink(&ormTopLink) 74 | if err != nil { 75 | return err 76 | } 77 | convert.OrmTopLinkToProtoTopLink(&ormTopLink, protoTopLink) 78 | return nil 79 | } -------------------------------------------------------------------------------- /server/db/globals.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package db 18 | 19 | import ( 20 | "gorm.io/gorm" 21 | ) 22 | 23 | type Server struct { 24 | Gorm *gorm.DB 25 | } 26 | 27 | func (db *Server) spliceSql(sql string, count int, c string) string { 28 | str := "" 29 | for i :=0; i < count; i++ { 30 | str += sql 31 | if i < count-1 { 32 | str += " "+ c + " " 33 | } 34 | } 35 | return str 36 | } 37 | 38 | -------------------------------------------------------------------------------- /server/db/manager.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package db 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/typedef/orm" 21 | "github.com/pkg/errors" 22 | "gorm.io/gorm" 23 | ) 24 | 25 | func (db *Server) AddManager(manager orm.Manager) error { 26 | return db.Gorm.Create(&manager).Error 27 | } 28 | 29 | func (db *Server) FindManagerByUserNameAndPassword(manager orm.Manager) (*orm.Manager, error) { 30 | err := db.Gorm.Where("Name = ? and Password = ?", manager.Name, manager.Password).First(&manager).Error 31 | return &manager, err 32 | } 33 | 34 | func (db *Server) FindManagerByToken(manager orm.Manager) (*orm.Manager, error) { 35 | err := db.Gorm.Where("id = ? and Token = ?", manager.ID, manager.Token).First(&manager).Error 36 | return &manager, err 37 | } 38 | 39 | func (db *Server) FindManagerByID(manager orm.Manager) (*orm.Manager, error) { 40 | err := db.Gorm.First(&manager, manager.ID).Error 41 | return &manager, err 42 | } 43 | 44 | func (db *Server) IsExistManagerByUserName(manager orm.Manager) error { 45 | err := db.Gorm.Where("Name = ?", manager.Name).First(&manager).Error 46 | if err != nil { 47 | if errors.Is(err, gorm.ErrRecordNotFound) { 48 | return nil 49 | } 50 | return err 51 | } 52 | return errors.New("the user name has been registered") 53 | } 54 | 55 | func (db *Server) IsExistManagerByNickName(manager orm.Manager) error { 56 | err := db.Gorm.Where("NickName = ?", manager.NickName).First(&manager).Error 57 | if err != nil { 58 | if errors.Is(err, gorm.ErrRecordNotFound) { 59 | return nil 60 | } 61 | return err 62 | } 63 | return errors.New("the user nickname has been registered") 64 | } 65 | 66 | func (db *Server) UpdateManagerToken(manager orm.Manager) (*orm.Base, error) { 67 | err := db.Gorm.Model(&manager).Update("Token", manager.Token).Error 68 | return &manager.Base, err 69 | } 70 | 71 | func (db *Server) UpdateManager(manager orm.Manager) (*orm.Base, error) { 72 | err := db.Gorm.Model(&manager).Updates(manager).Error 73 | return &manager.Base, err 74 | } 75 | 76 | func (db *Server) UpdateManagerState(manager orm.Manager) (*orm.Base, error) { 77 | err := db.Gorm.Model(&manager).Update("State", manager.State).Error 78 | return &manager.Base, err 79 | } 80 | 81 | func (db *Server) DelManager(manager orm.Manager) error { 82 | return db.Gorm.Delete(&manager).Error 83 | } 84 | 85 | func (db *Server) FindManager() ([]orm.Manager, error) { 86 | var ormManagerList []orm.Manager 87 | err := db.Gorm.Order("Level desc").Find(&ormManagerList).Error 88 | return ormManagerList, err 89 | } 90 | 91 | func (db *Server) FindManagerLowLevel(manager orm.Manager) ([]orm.Manager, error) { 92 | var ormManagerList []orm.Manager 93 | err := db.Gorm.Where("Level < ?", manager.Level).Find(&ormManagerList).Error 94 | return ormManagerList, err 95 | } 96 | 97 | func (db *Server) FindManagerByLevel(manager orm.Manager) (*orm.Base, error) { 98 | err := db.Gorm.Where("Level = ?", manager.Level).First(&manager).Error 99 | if err != nil { 100 | if errors.Is(err, gorm.ErrRecordNotFound) { 101 | return &manager.Base, nil 102 | } 103 | return nil, err 104 | } 105 | return &manager.Base, err 106 | } 107 | 108 | func (db *Server) FindManagerListByLevel(manager orm.Manager) ([]orm.Manager, error) { 109 | var ormManagerList []orm.Manager 110 | err := db.Gorm.Where("Level = ?", manager.Level).Find(&ormManagerList).Error 111 | return ormManagerList, err 112 | } -------------------------------------------------------------------------------- /server/db/node.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package db 18 | 19 | import ( 20 | "github.com/liyiligang/base/component/Jtool" 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | "github.com/liyiligang/mxui/typedef/orm" 23 | "github.com/pkg/errors" 24 | "gorm.io/gorm" 25 | ) 26 | 27 | func (db *Server) AddNode(node *orm.Node) error { 28 | return db.Gorm.Create(node).Error 29 | } 30 | 31 | func (db *Server) DelNode(node orm.Node) error { 32 | return db.Gorm.Delete(&node).Error 33 | } 34 | 35 | func (db *Server) UpdateNodeState(node orm.Node) error { 36 | return db.Gorm.Model(&node).Update("State", node.State).Error 37 | } 38 | 39 | func (db *Server) FindNode(req *protoManage.ReqNodeList) ([]orm.Node, error) { 40 | tx := db.Gorm.Offset(int(req.Page.Count*req.Page.Num)).Limit(int(req.Page.Count)) 41 | tx = db.SetNodeFilter(tx, req) 42 | var nodeList []orm.Node 43 | err := tx.Find(&nodeList).Error 44 | if errors.Is(err, gorm.ErrRecordNotFound) { 45 | return nodeList, nil 46 | } 47 | return nodeList, err 48 | } 49 | 50 | func (db *Server) FindNodeCount(req *protoManage.ReqNodeList) (int64, error) { 51 | tx := db.Gorm.Model(&orm.Node{}) 52 | tx = db.SetNodeFilter(tx, req) 53 | var count int64 54 | err := tx.Count(&count).Error 55 | return count, err 56 | } 57 | 58 | func (db *Server) FindNodeByID(node orm.Node) (*orm.Node, error) { 59 | err := db.Gorm.Where("id = ?", node.ID).First(&node).Error 60 | return &node, err 61 | } 62 | 63 | func (db *Server) FindNodeByName(node orm.Node) (*orm.Node, error) { 64 | err := db.Gorm.Where("name = ?", node.Name).First(&node).Error 65 | return &node, err 66 | } 67 | 68 | func (db *Server) SetNodeFilter(tx *gorm.DB, req *protoManage.ReqNodeList) *gorm.DB { 69 | sql := db.spliceSql("id = ?", len(req.ID), "or") 70 | var id []interface{} 71 | for _, item := range req.ID { 72 | id = append(id, item) 73 | } 74 | tx.Where(sql, id...) 75 | 76 | sql = db.spliceSql("name like ?", len(req.Name), "or") 77 | var name []interface{} 78 | for _, item := range req.Name { 79 | name = append(name, "%"+item+"%") 80 | } 81 | tx.Where(sql, name...) 82 | 83 | sql = db.spliceSql("state = ?", len(req.State), "or") 84 | var state []interface{} 85 | for _, item := range req.State { 86 | state = append(state, item) 87 | } 88 | tx.Where(sql, state...) 89 | 90 | sql = "" 91 | var senderTime []interface{} 92 | for index, item := range req.UpdateTime { 93 | if item.BeginTime > 0 { 94 | sql += "(updatedAt >= ?" 95 | senderTime = append(senderTime, Jtool.TimeUnixToFormat(item.BeginTime)) 96 | if item.EndTime > 0 { 97 | sql += " and updatedAt <= ?)" 98 | senderTime = append(senderTime, Jtool.TimeUnixToFormat(item.EndTime)) 99 | }else { 100 | sql += ")" 101 | } 102 | }else { 103 | sql += "(updatedAt <= ?)" 104 | senderTime = append(senderTime, Jtool.TimeUnixToFormat(item.EndTime)) 105 | } 106 | if index < len(req.UpdateTime)-1 { 107 | sql += " "+ "or" + " " 108 | } 109 | } 110 | tx.Where(sql, senderTime...) 111 | return tx 112 | } -------------------------------------------------------------------------------- /server/db/nodeFuncCall.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package db 18 | 19 | import ( 20 | "errors" 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | "github.com/liyiligang/mxui/typedef/orm" 23 | "gorm.io/gorm" 24 | ) 25 | 26 | func (db *Server) AddNodeFuncCall(nodeFuncCall *orm.NodeFuncCall) error { 27 | return db.Gorm.Create(nodeFuncCall).Error 28 | } 29 | 30 | func (db *Server) DelNodeFuncCallByNodeFuncID(nodeFuncCall orm.NodeFuncCall) error { 31 | return db.Gorm.Where("funcID = ?", nodeFuncCall.FuncID).Delete(&nodeFuncCall).Error 32 | } 33 | 34 | func (db *Server) DelNodeFuncCallByNodeID(nodeID int64) error { 35 | subQuery1 := db.Gorm.Select("id").Model(&orm.NodeFunc{}).Where("nodeID=?", nodeID) 36 | return db.Gorm.Where("funcID in(?)", subQuery1).Delete(&orm.NodeFuncCall{}).Error 37 | } 38 | 39 | func (db *Server) UpdateNodeFuncCallByID(nodeFuncCall orm.NodeFuncCall) error { 40 | err := db.Gorm.Model(&nodeFuncCall). 41 | Updates(map[string]interface{}{ 42 | "returnVal": nodeFuncCall.ReturnVal, 43 | "returnType": nodeFuncCall.ReturnType, 44 | "state": nodeFuncCall.State}).Error 45 | return err 46 | } 47 | 48 | func (db *Server) FindNodeFuncCall(req *protoManage.ReqNodeFuncCallList) ([]orm.NodeFuncCall, error) { 49 | tx := db.Gorm.Offset(int(req.Page.Count*req.Page.Num)).Limit(int(req.Page.Count)) 50 | tx = db.SetNodeFuncCallFilter(tx, req) 51 | var NodeFuncCallList []orm.NodeFuncCall 52 | err := tx.Order("id desc").Select("id", "updatedAt", 53 | "requesterID", "requesterName", "funcID", "returnType", "state").Find(&NodeFuncCallList).Error 54 | if errors.Is(err, gorm.ErrRecordNotFound) { 55 | return NodeFuncCallList, nil 56 | } 57 | return NodeFuncCallList, err 58 | } 59 | 60 | func (db *Server) FindNodeFuncCallByID(nodeFuncCall orm.NodeFuncCall) (*orm.NodeFuncCall, error) { 61 | err := db.Gorm.First(&nodeFuncCall, nodeFuncCall.ID).Error 62 | return &nodeFuncCall, err 63 | } 64 | 65 | func (db *Server) FindNodeFuncCallParameterByID(nodeFuncCall orm.NodeFuncCall) (*orm.NodeFuncCall, error) { 66 | err := db.Gorm.Select("id", "parameter").Find(&nodeFuncCall). 67 | Where("id = ?", nodeFuncCall.ID).Error 68 | return &nodeFuncCall, err 69 | } 70 | 71 | func (db *Server) FindNodeFuncCallReturnValByID(nodeFuncCall orm.NodeFuncCall) (*orm.NodeFuncCall, error) { 72 | err := db.Gorm.Select("id", "returnVal", "returnType", "state").Find(&nodeFuncCall). 73 | Where("id = ?", nodeFuncCall.ID).Error 74 | return &nodeFuncCall, err 75 | } 76 | 77 | func (db *Server) FindLastNodeFuncCallByNodeFunc(req *protoManage.ReqNodeFuncCallList) ([]orm.NodeFuncCall, error) { 78 | tx := db.Gorm.Offset(int(req.Page.Count*req.Page.Num)).Limit(int(req.Page.Count)) 79 | tx = db.SetNodeFuncCallFilter(tx, req) 80 | subQuery1 := tx.Model(&orm.NodeFunc{}) 81 | subQuery2 := db.Gorm.Select("t.id").Table("(?) as t", subQuery1) 82 | subQuery3 := db.Gorm.Select("max(id)").Table("nodeFuncCall"). 83 | Where("funcID in(?)", subQuery2).Group("funcID") 84 | var nodeFuncCallList []orm.NodeFuncCall 85 | err := db.Gorm.Where("id in(?)", subQuery3).Find(&nodeFuncCallList).Error 86 | return nodeFuncCallList, err 87 | } 88 | 89 | func (db *Server) SetNodeFuncCallFilter(tx *gorm.DB, req *protoManage.ReqNodeFuncCallList) *gorm.DB { 90 | if req.FuncID != 0 { 91 | tx.Where("funcID = ?", req.FuncID) 92 | } 93 | return tx 94 | } -------------------------------------------------------------------------------- /server/db/nodeReportVal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package db 17 | 18 | import ( 19 | "errors" 20 | "github.com/liyiligang/mxui/protoFiles/protoManage" 21 | "github.com/liyiligang/mxui/typedef/orm" 22 | "gorm.io/gorm" 23 | "time" 24 | ) 25 | 26 | func (db *Server) FindNodeReportVal(req *protoManage.ReqNodeReportValList) ([]orm.NodeReportVal, error) { 27 | tx := db.Gorm.Offset(int(req.Page.Count * req.Page.Num)).Limit(int(req.Page.Count)) 28 | tx = db.SetNodeReportValFilter(tx, req) 29 | var NodeReportValList []orm.NodeReportVal 30 | err := tx.Order("id desc").Find(&NodeReportValList).Error 31 | if errors.Is(err, gorm.ErrRecordNotFound) { 32 | return NodeReportValList, nil 33 | } 34 | return NodeReportValList, err 35 | } 36 | 37 | func (db *Server) AddNodeReportVal(nodeReportVal *orm.NodeReportVal) error { 38 | return db.Gorm.Create(nodeReportVal).Error 39 | } 40 | 41 | func (db *Server) DelNodeReportValByNodeReportID(nodeReportVal orm.NodeReportVal) error { 42 | return db.Gorm.Where("reportID = ?", nodeReportVal.ReportID).Delete(&nodeReportVal).Error 43 | } 44 | 45 | func (db *Server) DelNodeReportValByNodeID(nodeID int64) error { 46 | subQuery1 := db.Gorm.Select("id").Model(&orm.NodeReport{}).Where("nodeID=?", nodeID) 47 | return db.Gorm.Where("reportID in(?)", subQuery1).Delete(&orm.NodeReportVal{}).Error 48 | } 49 | 50 | func (db *Server) DelNodeReportValByMaxAge(maxAge int) error { 51 | return db.Gorm.Where("updatedAt<=?", time.Now().Add(-24*time.Hour*time.Duration(maxAge))).Delete(&orm.NodeReportVal{}).Error 52 | } 53 | 54 | func (db *Server) FindLastNodeReportValByNodeReport(req *protoManage.ReqNodeReportValList) ([]orm.NodeReportVal, error) { 55 | tx := db.Gorm.Offset(int(req.Page.Count * req.Page.Num)).Limit(int(req.Page.Count)) 56 | tx = db.SetNodeReportValFilter(tx, req) 57 | subQuery1 := tx.Model(&orm.NodeReport{}) 58 | subQuery2 := db.Gorm.Select("t.id").Table("(?) as t", subQuery1) 59 | subQuery3 := db.Gorm.Select("max(id)").Table("nodeReportVal"). 60 | Where("reportID in(?)", subQuery2).Group("reportID") 61 | var nodeReportValList []orm.NodeReportVal 62 | err := db.Gorm.Where("id in(?)", subQuery3).Find(&nodeReportValList).Error 63 | return nodeReportValList, err 64 | } 65 | 66 | func (db *Server) SetNodeReportValFilter(tx *gorm.DB, req *protoManage.ReqNodeReportValList) *gorm.DB { 67 | if req.ReportID != 0 { 68 | tx.Where("reportID = ?", req.ReportID) 69 | } 70 | if req.ID != 0 { 71 | tx.Where("id > ?", req.ID) 72 | } 73 | return tx 74 | } 75 | 76 | func (db *Server) FindNodeReportValCount() (int64, error) { 77 | var count int64 78 | err := db.Gorm.Model(&orm.NodeReportVal{}).Count(&count).Error 79 | if err != nil { 80 | return 0, err 81 | } 82 | return count, nil 83 | } -------------------------------------------------------------------------------- /server/db/topMenu.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package db 18 | 19 | import "github.com/liyiligang/mxui/typedef/orm" 20 | 21 | func (db *Server) FindTopLink() ([]orm.TopLink, error) { 22 | var ormTopLinkList []orm.TopLink 23 | err := db.Gorm.Find(&ormTopLinkList).Error 24 | return ormTopLinkList, err 25 | } 26 | 27 | func (db *Server) FindTopLinkByID(topLink orm.TopLink) (*orm.TopLink, error) { 28 | err := db.Gorm.Where("id = ?", topLink.ID).First(&topLink).Error 29 | return &topLink, err 30 | } 31 | 32 | func (db *Server) AddTopLink(topLink *orm.TopLink) error { 33 | return db.Gorm.Create(topLink).Error 34 | } 35 | 36 | func (db *Server) DelTopLink(topLink *orm.TopLink) error { 37 | return db.Gorm.Delete(topLink).Error 38 | } 39 | 40 | func (db *Server) UpdateTopLink(topLink *orm.TopLink) error { 41 | return db.Gorm.Model(&topLink).Updates(map[string]interface{}{ 42 | "Name": topLink.Name, "Url": topLink.Url, "State": topLink.State}).Error 43 | } 44 | -------------------------------------------------------------------------------- /server/gateway/globals.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package gateway 18 | 19 | import ( 20 | "github.com/liyiligang/base/component/Jtool" 21 | ) 22 | 23 | type Gateway struct { 24 | WebsocketManage Jtool.ConnManage 25 | RpcManage Jtool.ConnManage 26 | } 27 | -------------------------------------------------------------------------------- /server/gateway/rpc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package gateway 18 | 19 | import ( 20 | "github.com/gogo/protobuf/proto" 21 | "github.com/liyiligang/base/component/Jrpc" 22 | "github.com/liyiligang/base/component/Jtool" 23 | "github.com/liyiligang/mxui/protoFiles/protoManage" 24 | "github.com/liyiligang/mxui/typedef/constant" 25 | "github.com/pkg/errors" 26 | ) 27 | 28 | func (gateway *Gateway) RpcSendOrBroadCastPB(nodeID int64, order protoManage.Order, pb proto.Message) error { 29 | pbByte, err := proto.Marshal(pb) 30 | if err != nil { 31 | return err 32 | } 33 | return gateway.RpcSendOrBroadCastData(nodeID, order, &pbByte) 34 | } 35 | 36 | func (gateway *Gateway) RpcSendOrBroadCastData(nodeID int64, order protoManage.Order, data *[]byte) error { 37 | var err error 38 | if nodeID == constant.ConstSendBroadcast { 39 | err = gateway.rpcBroadCast(order, data) 40 | } else { 41 | err = gateway.rpcSend(nodeID, order, data) 42 | } 43 | return err 44 | } 45 | 46 | func (gateway *Gateway) RpcCloseClient(nodeID int64) error { 47 | conn, ok := gateway.RpcManage.Load(nodeID) 48 | if !ok { 49 | return errors.New("node id " + Jtool.Int64ToString(nodeID) + 50 | " is not found with gateway.RpcManage") 51 | } 52 | stream, ok := conn.(*Jrpc.RpcStream) 53 | if !ok { 54 | return errors.New("conn assert fail with *Jrpc.RpcStream") 55 | } 56 | stream.Close(false) 57 | return nil 58 | } 59 | 60 | func (gateway *Gateway) RpcGetID(nodeID interface{}) (int64, error) { 61 | id, ok := nodeID.(int64) 62 | if !ok { 63 | return 0, errors.New("node id assert fail with int64") 64 | } 65 | return id, nil 66 | } 67 | 68 | func (gateway *Gateway) rpcSend(nodeID int64, order protoManage.Order, data *[]byte) error { 69 | conn, ok := gateway.RpcManage.Load(nodeID) 70 | if !ok { 71 | return errors.New("node id " + Jtool.Int64ToString(nodeID) + 72 | " is not found with gateway.RpcManage") 73 | } 74 | message := &protoManage.Message{Order: order, Message: *data} 75 | conn.(*Jrpc.RpcStream).SendData(message) 76 | return nil 77 | } 78 | 79 | func (gateway *Gateway) rpcBroadCast(order protoManage.Order, data *[]byte) error { 80 | message := &protoManage.Message{Order: order, Message: *data} 81 | gateway.RpcManage.LoadAll(func(key, value interface{}) bool { 82 | value.(*Jrpc.RpcStream).SendData(message) 83 | return true 84 | }) 85 | return nil 86 | } 87 | 88 | -------------------------------------------------------------------------------- /server/gateway/websocket.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package gateway 18 | 19 | import ( 20 | "github.com/gogo/protobuf/proto" 21 | "github.com/liyiligang/base/component/Jtool" 22 | "github.com/liyiligang/base/component/Jweb" 23 | "github.com/liyiligang/mxui/protoFiles/protoManage" 24 | "github.com/liyiligang/mxui/typedef/constant" 25 | "github.com/pkg/errors" 26 | ) 27 | 28 | func (gateway *Gateway) WsSendOrBroadCastPB(userID int64, order protoManage.Order, pb proto.Message) error { 29 | pbByte, err := proto.Marshal(pb) 30 | if err != nil { 31 | return err 32 | } 33 | return gateway.WsSendOrBroadCastData(userID, order, &pbByte) 34 | } 35 | 36 | func (gateway *Gateway) WsSendOrBroadCastData(userID int64, order protoManage.Order, data *[]byte) error { 37 | var err error 38 | if userID == constant.ConstSendBroadcast { 39 | err = gateway.wsBroadCast(order, data) 40 | } else { 41 | err = gateway.wsSend(userID, order, data) 42 | } 43 | return err 44 | } 45 | 46 | func (gateway *Gateway) WsCloseClient(userID int64, msg string) error { 47 | conn, ok := gateway.WebsocketManage.Load(userID) 48 | if !ok { 49 | return errors.New("user id " + Jtool.Int64ToString(userID) + 50 | " is not found with gateway.WebsocketManage") 51 | } 52 | socket, ok := conn.(*Jweb.WebsocketConn) 53 | if !ok { 54 | return errors.New("conn assert fail with *Jrpc.RpcStream") 55 | } 56 | socket.Close(msg, false) 57 | return nil 58 | } 59 | 60 | func (gateway *Gateway) WsGetID(userID interface{}) (int64, error) { 61 | id, ok:= userID.(int64) 62 | if !ok { 63 | return 0, errors.New("user id assert fail with int64") 64 | } 65 | return id, nil 66 | } 67 | 68 | func (gateway *Gateway) wsBroadCast(order protoManage.Order, data *[]byte) error { 69 | stManage := &protoManage.Message{Order: order, Message: *data} 70 | manage, err := stManage.Marshal() 71 | if err != nil { 72 | return err 73 | } 74 | var arrConn []*Jweb.WebsocketConn 75 | gateway.WebsocketManage.LoadAll(func(key, value interface{}) bool { 76 | arrConn = append(arrConn, value.(*Jweb.WebsocketConn)) 77 | return true 78 | }) 79 | return Jweb.BroadCastByte(&manage, arrConn) 80 | } 81 | 82 | func (gateway *Gateway) wsSend(userID int64, order protoManage.Order, data *[]byte) error { 83 | conn, ok := gateway.WebsocketManage.Load(userID) 84 | if !ok { 85 | return errors.New("user id " + Jtool.Int64ToString(userID) + 86 | " is not found with gateway.WebsocketManage") 87 | } 88 | stManage := &protoManage.Message{Order: order, Message: *data} 89 | manage, err := stManage.Marshal() 90 | if err != nil { 91 | return err 92 | } 93 | conn.(*Jweb.WebsocketConn).SendByte(&manage) 94 | return nil 95 | } 96 | -------------------------------------------------------------------------------- /server/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/liyiligang/mxui 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/gin-contrib/gzip v0.0.1 7 | github.com/gin-contrib/static v0.0.1 8 | github.com/gin-gonic/gin v1.7.7 9 | github.com/gogo/protobuf v1.3.2 10 | github.com/golang/protobuf v1.5.2 11 | github.com/liyiligang/base v0.1.8 12 | github.com/pkg/errors v0.9.1 13 | github.com/robfig/cron/v3 v3.0.1 14 | github.com/xeipuuv/gojsonschema v1.2.0 15 | google.golang.org/grpc v1.52.3 16 | gorm.io/gorm v1.22.3 17 | ) 18 | -------------------------------------------------------------------------------- /server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "github.com/liyiligang/base/component/Jlog" 21 | "github.com/liyiligang/mxui/data" 22 | "github.com/liyiligang/mxui/db" 23 | "github.com/liyiligang/mxui/gateway" 24 | "github.com/liyiligang/mxui/request" 25 | "github.com/robfig/cron/v3" 26 | "google.golang.org/grpc" 27 | "net/http" 28 | ) 29 | 30 | type App struct { 31 | HttpServer *http.Server 32 | RpcServer *grpc.Server 33 | DBServer db.Server 34 | Timer *cron.Cron 35 | Data data.Data 36 | Request request.Request 37 | Gateway gateway.Gateway 38 | } 39 | 40 | func InitServer() (*App, error) { 41 | app := App{} 42 | app.InitConfig() 43 | app.InitLogServer() 44 | app.InitSystemDir() 45 | app.initAppDependency() 46 | app.InitTimer() 47 | if err := app.InitBaseServer(); err != nil { 48 | return nil, err 49 | } 50 | Jlog.Info("mxui server is running") 51 | return &app, nil 52 | } 53 | 54 | func (app *App) InitBaseServer() error { 55 | if err := app.InitDBServer(); err != nil { 56 | return err 57 | } 58 | if err := app.InitWebServer(); err != nil { 59 | return err 60 | } 61 | if err := app.InitRpcServer(); err != nil { 62 | return err 63 | } 64 | if err := app.StartTimer(); err != nil { 65 | return err 66 | } 67 | Jlog.Info("all component is start") 68 | return nil 69 | } 70 | 71 | func (app *App) StopBaseServer() error { 72 | if err := app.StartTimer(); err != nil { 73 | return err 74 | } 75 | if err := app.StopDBServer(); err != nil { 76 | return err 77 | } 78 | if err := app.StopWebServer(); err != nil { 79 | return err 80 | } 81 | if err := app.StopRpcServer(); err != nil { 82 | return err 83 | } 84 | Jlog.Info("all component is stop") 85 | return nil 86 | } 87 | 88 | func (app *App) initAppDependency() { 89 | app.Data.DB = &app.DBServer 90 | app.Data.Gateway = &app.Gateway 91 | app.Request.Data = &app.Data 92 | } 93 | 94 | func main() { 95 | _, err := InitServer() 96 | if err != nil { 97 | Jlog.Fatal("mxui server start fail", "error", err) 98 | } 99 | select {} 100 | } 101 | -------------------------------------------------------------------------------- /server/request/globals.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package request 18 | 19 | import ( 20 | "github.com/liyiligang/mxui/data" 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | ) 23 | 24 | type Request struct { 25 | Data *data.Data 26 | } 27 | 28 | func (request *Request) ReqFindSystemInfo(r *HTTPRequest) error { 29 | req := &protoManage.ReqSystemInitInfo{} 30 | err := request.unmarshalWithHttp(r, req) 31 | if err != nil { 32 | return err 33 | } 34 | ans, err := request.Data.FindSystemInfo(req) 35 | if err != nil { 36 | return err 37 | } 38 | err = request.marshalWithHttp(r, ans) 39 | if err != nil { 40 | return err 41 | } 42 | return nil 43 | } -------------------------------------------------------------------------------- /server/request/node.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package request 18 | 19 | import ( 20 | "context" 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | ) 23 | 24 | func (request *Request) RegisterNode(ctx context.Context, node *protoManage.Node) (*protoManage.Node, error) { 25 | err := request.Data.NodeFindOrAddByName(node) 26 | if err != nil { 27 | return nil, err 28 | } 29 | return node, nil 30 | } 31 | 32 | func (request *Request) ReqNodeOffline(nodeID int64) error { 33 | err := request.Data.NodeStateUpdate(&protoManage.Node{Base: protoManage.Base{ID: nodeID}, 34 | State: protoManage.State_StateUnknow}) 35 | if err != nil { 36 | return err 37 | } 38 | err = request.Data.NodeFuncStateUpdateByNodeID(&protoManage.NodeFunc{NodeID: nodeID, State: protoManage.State_StateNot}) 39 | if err != nil { 40 | return err 41 | } 42 | err = request.Data.NodeReportStateUpdateByNodeID(&protoManage.NodeReport{NodeID: nodeID, State: protoManage.State_StateNot}) 43 | if err != nil { 44 | return err 45 | } 46 | return nil 47 | } 48 | 49 | func (request *Request) ReqNodeFind(r *HTTPRequest) error { 50 | req := &protoManage.ReqNodeList{} 51 | err := request.unmarshalWithHttp(r, req) 52 | if err != nil { 53 | return err 54 | } 55 | ans, err := request.Data.NodeFind(req) 56 | if err != nil { 57 | return err 58 | } 59 | err = request.marshalWithHttp(r, ans) 60 | if err != nil { 61 | return err 62 | } 63 | return nil 64 | } 65 | 66 | func (request *Request) ReqNodeFindByID(r *HTTPRequest) error { 67 | req := &protoManage.Node{} 68 | err := request.unmarshalWithHttp(r, req) 69 | if err != nil { 70 | return err 71 | } 72 | err = request.Data.NodeFindByID(req) 73 | if err != nil { 74 | return err 75 | } 76 | err = request.marshalWithHttp(r, req) 77 | if err != nil { 78 | return err 79 | } 80 | return nil 81 | } 82 | 83 | func (request *Request) ReqNodeDel(r *HTTPRequest) error { 84 | req := &protoManage.Node{} 85 | err := request.unmarshalWithHttp(r, req) 86 | if err != nil { 87 | return err 88 | } 89 | err = request.Data.NodeDel(req) 90 | if err != nil { 91 | return err 92 | } 93 | err = request.marshalWithHttp(r, req) 94 | if err != nil { 95 | return err 96 | } 97 | return nil 98 | } 99 | 100 | func (request *Request) ReqNodeTest(r *HTTPRequest) error { 101 | req := &protoManage.ReqNodeTest{} 102 | err := request.unmarshalWithHttp(r, req) 103 | if err != nil { 104 | return err 105 | } 106 | err = request.Data.NodeTest(r.UserID, req) 107 | if err != nil { 108 | return err 109 | } 110 | err = request.marshalWithHttp(r, req) 111 | if err != nil { 112 | return err 113 | } 114 | return nil 115 | } -------------------------------------------------------------------------------- /server/request/nodeFunc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package request 17 | 18 | import ( 19 | "context" 20 | "github.com/liyiligang/mxui/protoFiles/protoManage" 21 | ) 22 | 23 | func (request *Request) RegisterNodeFunc(ctx context.Context, nodeFunc *protoManage.NodeFunc) (*protoManage.NodeFunc, error) { 24 | err := request.Data.NodeFuncUpdateOrAdd(nodeFunc) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return nodeFunc, nil 29 | } 30 | 31 | func (request *Request) ReqNodeFuncFind(r *HTTPRequest) error { 32 | req := &protoManage.ReqNodeFuncList{} 33 | err := request.unmarshalWithHttp(r, req) 34 | if err != nil { 35 | return err 36 | } 37 | req.LevelMax = r.UserLevel 38 | ans, err := request.Data.NodeFuncFind(req) 39 | if err != nil { 40 | return err 41 | } 42 | err = request.marshalWithHttp(r, ans) 43 | if err != nil { 44 | return err 45 | } 46 | return nil 47 | } 48 | 49 | func (request *Request) ReqNodeFuncDel(r *HTTPRequest) error { 50 | req := &protoManage.NodeFunc{} 51 | err := request.unmarshalWithHttp(r, req) 52 | if err != nil { 53 | return err 54 | } 55 | err = request.Data.NodeFuncDel(req) 56 | if err != nil { 57 | return err 58 | } 59 | err = request.marshalWithHttp(r, req) 60 | if err != nil { 61 | return err 62 | } 63 | return nil 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /server/request/nodeNotify.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package request 18 | 19 | import ( 20 | "github.com/liyiligang/base/component/Jlog" 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | ) 23 | 24 | func (request *Request) ReqNodeNotifyAdd(nodeID int64, message []byte) error { 25 | nodeNotify := protoManage.NodeNotify{} 26 | err := nodeNotify.Unmarshal(message) 27 | if err != nil { 28 | return err 29 | } 30 | return request.Data.NodeNotifyAdd(&nodeNotify, nodeNotify.ShowPop) 31 | } 32 | 33 | func (request *Request) SaveNodeNotify(senderID int64, senderType protoManage.NotifySenderType, 34 | message string, state protoManage.State, isSend bool) { 35 | nodeNotify := protoManage.NodeNotify{ 36 | SenderID: senderID, 37 | SenderType: senderType, 38 | Message: message, 39 | State: state, 40 | } 41 | err := request.Data.NodeNotifyAdd(&nodeNotify, isSend) 42 | if err != nil { 43 | Jlog.Warn("save node notify fail", "error", err) 44 | } 45 | } 46 | 47 | func (request *Request) SaveNodeNotifyWithUserError(senderID int64, message string) { 48 | request.SaveNodeNotify(senderID, protoManage.NotifySenderType_NotifySenderTypeUser, 49 | message, protoManage.State_StateError, false) 50 | } 51 | 52 | func (request *Request) SaveNodeNotifyWithUserInfo(senderID int64, message string) { 53 | request.SaveNodeNotify(senderID, protoManage.NotifySenderType_NotifySenderTypeUser, 54 | message, protoManage.State_StateNormal, false) 55 | } 56 | 57 | func (request *Request) SaveNodeNotifyWithNodeError(senderID int64, message string) { 58 | request.SaveNodeNotify(senderID, protoManage.NotifySenderType_NotifySenderTypeNode, 59 | message, protoManage.State_StateError, true) 60 | } 61 | 62 | func (request *Request) SaveNodeNotifyWithNodeInfo(senderID int64, message string) { 63 | request.SaveNodeNotify(senderID, protoManage.NotifySenderType_NotifySenderTypeNode, 64 | message, protoManage.State_StateNormal, true) 65 | } 66 | 67 | func (request *Request) SendNodeNotifyWithNodeError(senderID int64, message string) { 68 | nodeNotify := protoManage.NodeNotify{ 69 | SenderID: senderID, 70 | SenderType: protoManage.NotifySenderType_NotifySenderTypeNode, 71 | Message: message, 72 | State: protoManage.State_StateError, 73 | } 74 | err := request.Data.Gateway.RpcSendOrBroadCastPB(senderID, protoManage.Order_NodeNotifyError, &nodeNotify) 75 | if err != nil { 76 | Jlog.Warn("send node notify fail", "error", err) 77 | } 78 | } 79 | 80 | func (request *Request) ReqNodeNotifyFind(r *HTTPRequest) error { 81 | req := &protoManage.ReqNodeNotifyList{} 82 | err := request.unmarshalWithHttp(r, req) 83 | if err != nil { 84 | return err 85 | } 86 | ans, err := request.Data.NodeNotifyFind(req) 87 | if err != nil { 88 | return err 89 | } 90 | err = request.marshalWithHttp(r, ans) 91 | if err != nil { 92 | return err 93 | } 94 | return nil 95 | } -------------------------------------------------------------------------------- /server/request/nodeReport.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | package request 19 | 20 | import ( 21 | "context" 22 | "github.com/liyiligang/mxui/protoFiles/protoManage" 23 | ) 24 | 25 | 26 | func (request *Request) RegisterNodeReport(ctx context.Context, nodeReport *protoManage.NodeReport) (*protoManage.NodeReport, error) { 27 | err := request.Data.NodeReportUpdateOrAdd(nodeReport) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return nodeReport, nil 32 | } 33 | 34 | func (request *Request) ReqNodeReportFind(r *HTTPRequest) error { 35 | req := &protoManage.ReqNodeReportList{} 36 | err := request.unmarshalWithHttp(r, req) 37 | if err != nil { 38 | return err 39 | } 40 | req.LevelMax = r.UserLevel 41 | ans, err := request.Data.NodeReportFind(req) 42 | if err != nil { 43 | return err 44 | } 45 | err = request.marshalWithHttp(r, ans) 46 | if err != nil { 47 | return err 48 | } 49 | return nil 50 | } 51 | 52 | func (request *Request) ReqNodeReportDel(r *HTTPRequest) error { 53 | req := &protoManage.NodeReport{} 54 | err := request.unmarshalWithHttp(r, req) 55 | if err != nil { 56 | return err 57 | } 58 | err = request.Data.NodeReportLevelCheck(r.UserLevel, req.Base.ID) 59 | if err != nil { 60 | return err 61 | } 62 | err = request.Data.NodeReportDel(req) 63 | if err != nil { 64 | return err 65 | } 66 | err = request.marshalWithHttp(r, req) 67 | if err != nil { 68 | return err 69 | } 70 | return nil 71 | } 72 | 73 | -------------------------------------------------------------------------------- /server/request/nodeReportVal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | package request 19 | 20 | import "github.com/liyiligang/mxui/protoFiles/protoManage" 21 | 22 | func (request *Request) ReqNodeReportValFind(r *HTTPRequest) error { 23 | req := &protoManage.ReqNodeReportValList{} 24 | err := request.unmarshalWithHttp(r, req) 25 | if err != nil { 26 | return err 27 | } 28 | err = request.Data.NodeReportLevelCheck(r.UserLevel, req.ReportID) 29 | if err != nil { 30 | return err 31 | } 32 | ans, err := request.Data.NodeReportValFind(req) 33 | if err != nil { 34 | return err 35 | } 36 | err = request.marshalWithHttp(r, ans) 37 | if err != nil { 38 | return err 39 | } 40 | return nil 41 | } 42 | 43 | func (request *Request) ReqNodeReportValAdd(nodeID int64, message []byte) error { 44 | nodeReportVal := protoManage.NodeReportVal{} 45 | err := nodeReportVal.Unmarshal(message) 46 | if err != nil { 47 | return err 48 | } 49 | err = request.Data.NodeReportValAdd(&nodeReportVal) 50 | if err != nil { 51 | return err 52 | } 53 | return nil 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /server/request/rpcStream.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package request 18 | 19 | import ( 20 | "errors" 21 | "github.com/liyiligang/base/component/Jlog" 22 | "github.com/liyiligang/base/component/Jrpc" 23 | "github.com/liyiligang/base/component/Jtool" 24 | "github.com/liyiligang/mxui/protoFiles/protoManage" 25 | "time" 26 | ) 27 | 28 | func (request *Request) RpcChannel(engine protoManage.RpcEngine_RpcChannelServer) error { 29 | conn, err := Jrpc.GrpcStreamServerInit(engine, new(protoManage.Message), Jrpc.RpcStreamCall{ 30 | RpcStreamConnect:request.RpcStreamConnect, 31 | RpcStreamConnected:request.RpcStreamConnected, 32 | RpcStreamClosed:request.RpcStreamClosed, 33 | RpcStreamReceiver:request.RpcStreamReceiver, 34 | RpcStreamError:request.RpcStreamError, 35 | }) 36 | if err != nil { 37 | return err 38 | } 39 | return conn.GrpcStreamServerRun(engine) 40 | } 41 | 42 | func (request *Request) RpcStreamConnect(conn *Jrpc.RpcStream) (interface{}, error) { 43 | node := protoManage.Node{} 44 | err := node.Unmarshal(conn.GetRpcContext().RpcStreamClientHeader) 45 | if err != nil { 46 | return 0, err 47 | } 48 | node.State = protoManage.State_StateNormal 49 | err = request.Data.NodeStateUpdate(&node) 50 | if err != nil { 51 | return 0, err 52 | } 53 | return node.Base.ID, nil 54 | } 55 | 56 | func (request *Request) RpcStreamConnected(conn *Jrpc.RpcStream) error { 57 | nodeID, err := request.Data.Gateway.RpcGetID(conn.GetBindVal()) 58 | if err != nil { 59 | return err 60 | } 61 | if request.Data.Gateway.RpcManage.IsExistDelayCheck(nodeID, 500*time.Millisecond, 6) { 62 | return errors.New("node id "+Jtool.Int64ToString(nodeID)+" is existed") 63 | } 64 | request.Data.Gateway.RpcManage.Store(nodeID, conn) 65 | Jlog.Info("node is online", "nodeID", nodeID) 66 | return nil 67 | } 68 | 69 | func (request *Request) RpcStreamClosed(conn *Jrpc.RpcStream) error { 70 | request.Data.Gateway.RpcManage.Delete(conn.GetBindVal()) 71 | nodeID, err := request.Data.Gateway.RpcGetID(conn.GetBindVal()) 72 | if err != nil { 73 | return err 74 | } 75 | err = request.ReqNodeOffline(nodeID) 76 | if err != nil { 77 | return err 78 | } 79 | Jlog.Info("node is offline", "nodeID", nodeID) 80 | return nil 81 | } 82 | 83 | func (request *Request) RpcStreamReceiver(conn *Jrpc.RpcStream, recv interface{}) error { 84 | nodeID, err := request.Data.Gateway.RpcGetID(conn.GetBindVal()) 85 | if err != nil { 86 | return err 87 | } 88 | res, ok := recv.(*protoManage.Message) 89 | if !ok { 90 | return errors.New("recv assert fail with *protoManage.Message") 91 | } 92 | switch res.Order { 93 | case protoManage.Order_NodeFuncCallAns: 94 | err = request.AnsNodeFuncCall(nodeID, res.Message) 95 | break 96 | case protoManage.Order_NodeReportUpdateVal: 97 | err = request.ReqNodeReportValAdd(nodeID, res.Message) 98 | break 99 | case protoManage.Order_NodeNotifyAdd: 100 | err = request.ReqNodeNotifyAdd(nodeID, res.Message) 101 | break 102 | default: 103 | err = errors.New("rpc order is invalid with number " + Jtool.Int64ToString(int64(res.Order))) 104 | } 105 | return err 106 | } 107 | 108 | func (request *Request) RpcStreamError(text string, err error) { 109 | Jlog.Warn(text, "error", err) 110 | } -------------------------------------------------------------------------------- /server/request/topMenu.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | package request 19 | 20 | import ( 21 | "github.com/liyiligang/mxui/protoFiles/protoManage" 22 | ) 23 | 24 | func (request *Request) ReqTopLinkFind(r *HTTPRequest) error { 25 | req := &protoManage.ReqTopLinkList{} 26 | err := request.unmarshalWithHttp(r, req) 27 | if err != nil { 28 | return err 29 | } 30 | ans, err := request.Data.TopLinkFind(req) 31 | if err != nil { 32 | return err 33 | } 34 | err = request.marshalWithHttp(r, ans) 35 | if err != nil { 36 | return err 37 | } 38 | return nil 39 | } 40 | 41 | func (request *Request) ReqTopLinkFindByID(r *HTTPRequest) error { 42 | req := &protoManage.TopLink{} 43 | err := request.unmarshalWithHttp(r, req) 44 | if err != nil { 45 | return err 46 | } 47 | err = request.Data.TopLinkFindByID(req) 48 | if err != nil { 49 | return err 50 | } 51 | err = request.marshalWithHttp(r, req) 52 | if err != nil { 53 | return err 54 | } 55 | return nil 56 | } 57 | 58 | func (request *Request) ReqTopLinkAdd(r *HTTPRequest) error { 59 | req := &protoManage.TopLink{} 60 | err := request.unmarshalWithHttp(r, req) 61 | if err != nil { 62 | return err 63 | } 64 | err = request.Data.TopLinkAdd(req) 65 | if err != nil { 66 | return err 67 | } 68 | err = request.marshalWithHttp(r, req) 69 | if err != nil { 70 | return err 71 | } 72 | return nil 73 | } 74 | 75 | func (request *Request) ReqTopLinkDel(r *HTTPRequest) error { 76 | req := &protoManage.TopLink{} 77 | err := request.unmarshalWithHttp(r, req) 78 | if err != nil { 79 | return err 80 | } 81 | err = request.Data.TopLinkDel(req) 82 | if err != nil { 83 | return err 84 | } 85 | err = request.marshalWithHttp(r, req) 86 | if err != nil { 87 | return err 88 | } 89 | return nil 90 | } 91 | 92 | func (request *Request) ReqTopLinkUpdate(r *HTTPRequest) error { 93 | req := &protoManage.TopLink{} 94 | err := request.unmarshalWithHttp(r, req) 95 | if err != nil { 96 | return err 97 | } 98 | err = request.Data.TopLinkUpdate(req) 99 | if err != nil { 100 | return err 101 | } 102 | err = request.marshalWithHttp(r, req) 103 | if err != nil { 104 | return err 105 | } 106 | return nil 107 | } -------------------------------------------------------------------------------- /server/request/websocket.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package request 18 | 19 | import ( 20 | "errors" 21 | "github.com/liyiligang/base/component/Jlog" 22 | "github.com/liyiligang/base/component/Jtool" 23 | "github.com/liyiligang/base/component/Jweb" 24 | "github.com/liyiligang/mxui/protoFiles/protoManage" 25 | ) 26 | 27 | func (request *Request) WebsocketConnect(conn *Jweb.WebsocketConn) (interface{}, error) { 28 | return request.ReqWsTokenCheck([]byte(conn.GetParm().WsClientMsg), conn.GetParm().WsClientAddr) 29 | } 30 | 31 | func (request *Request) WebsocketConnected(conn *Jweb.WebsocketConn) error { 32 | userID, err := request.Data.Gateway.WsGetID(conn.GetBindVal()) 33 | if err != nil { 34 | return err 35 | } 36 | if request.Data.Gateway.WebsocketManage.IsExist(userID) { 37 | return errors.New("user id "+Jtool.Int64ToString(userID)+" is existed") 38 | } 39 | err = request.Data.ManagerStateUpdate(&protoManage.Manager{Base: protoManage.Base{ID: userID}, 40 | State: protoManage.State_StateNormal}) 41 | if err != nil { 42 | return err 43 | } 44 | request.Data.Gateway.WebsocketManage.Store(userID, conn) 45 | Jlog.Info("user is online", "userID", userID) 46 | return nil 47 | } 48 | 49 | func (request *Request) WebsocketClosed(conn *Jweb.WebsocketConn, code int, text string) error { 50 | request.Data.Gateway.WebsocketManage.Delete(conn.GetBindVal()) 51 | userID, err := request.Data.Gateway.WsGetID(conn.GetBindVal()) 52 | if err != nil { 53 | return err 54 | } 55 | err = request.Data.ManagerStateUpdate(&protoManage.Manager{Base: protoManage.Base{ID: userID}, 56 | State: protoManage.State_StateUnknow}) 57 | if err != nil { 58 | return err 59 | } 60 | Jlog.Info("user is offline", "userID", userID) 61 | return nil 62 | } 63 | 64 | func (request *Request) WebsocketError(text string, err error){ 65 | Jlog.Warn(text, "error", err) 66 | } -------------------------------------------------------------------------------- /server/test/makeDBData/make_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package makeDBData 18 | 19 | import ( 20 | "github.com/liyiligang/base/component/Jlog" 21 | "github.com/liyiligang/base/component/Jtool" 22 | "github.com/liyiligang/mxui" 23 | "github.com/liyiligang/mxui/protoFiles/protoManage" 24 | "github.com/liyiligang/mxui/typedef/orm" 25 | "strconv" 26 | "testing" 27 | ) 28 | 29 | var appServer *main.App 30 | 31 | func init() { 32 | InitApp() 33 | } 34 | 35 | func TestMake(t *testing.T) { 36 | MakeNodeNotifyData(200, 200) 37 | } 38 | 39 | func InitApp(){ 40 | var err error 41 | appServer, err = main.InitServer() 42 | if err != nil { 43 | Jlog.Fatal("server init fail", "error", err) 44 | } 45 | Jlog.Info("server init success") 46 | } 47 | 48 | func MakeNodeData(num int, nodeGroupLen int, nodeTypeLen int){ 49 | for i:=0; i<=num; i++ { 50 | state, _ := Jtool.GetRandInt(0, 5) 51 | _ = appServer.DBServer.AddNode(&orm.Node{ 52 | Name: "node" + strconv.Itoa(i+1), 53 | State: int32(state), 54 | }) 55 | } 56 | } 57 | 58 | func MakeNodeNotifyData(num int, nodeLen int){ 59 | for j := 0; j 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | MXUI 24 | 25 | 26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mxui", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "build": "vite build", 6 | "dev": "vite" 7 | }, 8 | "dependencies": { 9 | "@element-plus/icons": "0.0.11", 10 | "@lljj/vjsf-utils": "^1.9.5", 11 | "@lljj/vue3-form-element": "^1.10.0", 12 | "@types/file-saver": "^2.0.5", 13 | "@types/spark-md5": "^3.0.2", 14 | "@vitejs/plugin-vue": "^2.1.0", 15 | "@vue/composition-api": "^1.4.6", 16 | "ajv-i18n": "^4.2.0", 17 | "axios": "^0.25.0", 18 | "clipboard": "^2.0.10", 19 | "dplayer": "^1.26.0", 20 | "echarts": "^5.3.0", 21 | "el-table-infinite-scroll": "^1.0.10", 22 | "element-plus": "^2.0.1", 23 | "es6-promise": "^4.2.8", 24 | "file-saver": "^2.0.5", 25 | "flv.js": "^1.6.2", 26 | "hls.js": "^1.1.3", 27 | "jsoneditor": "^9.7.0", 28 | "lodash": "^4.17.21", 29 | "protobufjs": "^6.11.2", 30 | "spark-md5": "^3.0.2", 31 | "vue": "^3.2.30", 32 | "vue-echarts": "^6.0.2", 33 | "vue-i18n": "^9.2.0-beta.26", 34 | "vue-json-editor": "^1.4.3", 35 | "vue-native-websocket-vue3": "^3.1.4", 36 | "vue-router": "^4.0.12", 37 | "vue3-json-viewer": "^1.0.4", 38 | "vuex": "^4.0.2", 39 | "webpack-merge": "^5.8.0" 40 | }, 41 | "devDependencies": { 42 | "@types/dplayer": "^1.25.2", 43 | "@types/jsoneditor": "^9.5.1", 44 | "@types/lodash": "^4.14.178", 45 | "@vue/cli-plugin-router": "^5.0.0-beta.4", 46 | "@vue/cli-plugin-typescript": "^5.0.0-beta.4", 47 | "@vue/compiler-sfc": "^3.2.30", 48 | "typescript": "^4.5.5", 49 | "vite": "^2.7.13", 50 | "vue-loader": "^17.0.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /web/public/mxui.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/App.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 23 | 76 | -------------------------------------------------------------------------------- /web/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/base/defaultVal.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {protoManage} from "../proto/manage"; 18 | import i18n from '../base/i18n' 19 | 20 | export module defaultVal { 21 | export function getDefaultProtoNode():protoManage.Node { 22 | return protoManage.Node.create({ 23 | Base: protoManage.Base.create(), 24 | Name: i18n.global.t('defaultVal.unknown') 25 | }) 26 | } 27 | 28 | export function getDefaultProtoNodeFunc():protoManage.NodeFunc { 29 | return protoManage.NodeFunc.create({ 30 | Base: protoManage.Base.create(), 31 | Name: i18n.global.t('defaultVal.unknown') 32 | }) 33 | } 34 | 35 | export function getDefaultProtoNodeFuncCall():protoManage.NodeFuncCall { 36 | return protoManage.NodeFuncCall.create({ 37 | Base: protoManage.Base.create(), 38 | }) 39 | } 40 | 41 | export function getDefaultProtoNodeReport():protoManage.NodeReport{ 42 | return protoManage.NodeReport.create({ 43 | Base: protoManage.Base.create(), 44 | Name: i18n.global.t('defaultVal.unknown') 45 | }) 46 | } 47 | 48 | export function getDefaultProtoNodeReportVal():protoManage.NodeReportVal{ 49 | return protoManage.NodeReportVal.create({ 50 | Base: protoManage.Base.create() 51 | }) 52 | } 53 | 54 | export function getDefaultLanguage():string{ 55 | // @ts-ignore 56 | let lan = navigator.systemLanguage || navigator.language; 57 | if(lan.toLowerCase().indexOf('zh')!==-1){ 58 | return 'chs' 59 | }else if(lan.toLowerCase().indexOf('en')!==-1){ 60 | return 'eng' 61 | } 62 | return 'eng' 63 | } 64 | } -------------------------------------------------------------------------------- /web/src/components/Empty.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 31 | 32 | -------------------------------------------------------------------------------- /web/src/components/Load.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | 29 | 38 | 39 | -------------------------------------------------------------------------------- /web/src/components/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 27 | 28 | 83 | 84 | -------------------------------------------------------------------------------- /web/src/components/card/CardViewFrame.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 29 | 30 | 80 | 81 | -------------------------------------------------------------------------------- /web/src/components/card/NodeCard.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 33 | 34 | 92 | 93 | -------------------------------------------------------------------------------- /web/src/components/card/NodeFuncCard.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 34 | 35 | 92 | 93 | -------------------------------------------------------------------------------- /web/src/components/card/NodeReportCard.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 35 | 36 | 92 | 93 | -------------------------------------------------------------------------------- /web/src/components/cardItem/CardBase.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 23 | 24 | 39 | 40 | -------------------------------------------------------------------------------- /web/src/components/cardItem/CardFuncCall.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 33 | 34 | 77 | 78 | -------------------------------------------------------------------------------- /web/src/components/cardItem/CardInfo.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 29 | 30 | 70 | 71 | -------------------------------------------------------------------------------- /web/src/components/cardItem/CardName.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | 29 | 65 | 66 | 75 | 76 | -------------------------------------------------------------------------------- /web/src/components/cardItem/CardReportVal.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | 29 | 77 | 78 | 95 | -------------------------------------------------------------------------------- /web/src/components/cardItem/CardState.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 30 | 31 | 66 | 67 | -------------------------------------------------------------------------------- /web/src/components/echarts/NodeFuncReturnCharts.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 50 | 51 | -------------------------------------------------------------------------------- /web/src/components/file/FileSave.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 23 | 24 | 56 | 57 | -------------------------------------------------------------------------------- /web/src/components/headButton/AutoRefreshButton.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 73 | 74 | -------------------------------------------------------------------------------- /web/src/components/headButton/FilterButton.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /web/src/components/headButton/SettingButton.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 32 | 33 | 89 | 90 | -------------------------------------------------------------------------------- /web/src/components/link/LinkJump.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 23 | 24 | 67 | 68 | -------------------------------------------------------------------------------- /web/src/components/media/Player.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 85 | 86 | -------------------------------------------------------------------------------- /web/src/components/setting/AutoRefresh.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 23 | 43 | 44 | -------------------------------------------------------------------------------- /web/src/components/setting/LevelSelect.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /web/src/components/table/NodeReportValTable.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 34 | 35 | 36 | 104 | 105 | 108 | 109 | -------------------------------------------------------------------------------- /web/src/components/tableInfiniteScroll/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // directive 18 | import elTableInfiniteScroll from './tableInfiniteScroll'; 19 | 20 | // Vue.use() 21 | elTableInfiniteScroll.install = (Vue) => { 22 | Vue.directive('elTableInfiniteScroll', elTableInfiniteScroll); 23 | }; 24 | 25 | // Vue.component() 26 | export default elTableInfiniteScroll; -------------------------------------------------------------------------------- /web/src/components/tableInfiniteScroll/tableInfiniteScroll.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * 对 element-ui 的无限滚动在 el-dialog 上使用的封装 19 | */ 20 | import { ElInfiniteScroll } from "element-plus"; 21 | 22 | const elScope = 'ElInfiniteScroll'; // scope name 23 | const msgTitle = `[elTableInfiniteScroll]: `; // message title 24 | const elTableScrollWrapperClass = '.el-table__body-wrapper'; 25 | 26 | export default { 27 | install: (app, options) => {}, 28 | mounted(el, binding, vnode, oldVnode) { 29 | // 获取 dialog 中的滚动层 30 | const scrollElem = el.querySelector(elTableScrollWrapperClass); 31 | 32 | // 如果没找到元素,返回错误 33 | if (!scrollElem) { 34 | throw `${msgTitle}找不到 ${elTableScrollWrapperClass} 容器`; 35 | } 36 | 37 | // 设置自动滚动 38 | scrollElem.style.overflowY = 'auto'; 39 | 40 | // dom 渲染后 41 | setTimeout(() => { 42 | if (!el.style.height) { 43 | scrollElem.style.height = '400px'; 44 | console.warn( 45 | `${msgTitle}请尽量设置 el-table 的高度,可以设置为 auto/100%(自适应高度),未设置会取 400px 的默认值(不然会导致一直加载)` 46 | ); 47 | } 48 | 49 | asyncElOptions(vnode, el, scrollElem); 50 | 51 | // 绑定 infinite-scroll 52 | if (ElInfiniteScroll.mounted == undefined){ 53 | throw `${msgTitle} mounted is undefined`; 54 | } 55 | ElInfiniteScroll.mounted(scrollElem, binding, vnode, oldVnode); 56 | 57 | // 将子集的引用放入 el 上,用于 unmounted 中销毁事件 58 | el[elScope] = scrollElem[elScope]; 59 | }, 0); 60 | }, 61 | updated(el, binding, vnode) { 62 | asyncElOptions(vnode, el, el.querySelector(elTableScrollWrapperClass)); 63 | }, 64 | unmounted(el, binding, vnode, oldVnode){ 65 | // if (ElInfiniteScroll.unmounted == undefined){ 66 | // throw `${msgTitle} unmounted is undefined`; 67 | // } 68 | // ElInfiniteScroll.unmounted(el, binding, vnode, oldVnode) 69 | } 70 | }; 71 | 72 | /** 73 | * 同步 el-infinite-scroll 的配置项 74 | * @param sourceVNode 75 | * @param sourceElem 76 | * @param targetElem 77 | */ 78 | function asyncElOptions(sourceVNode, sourceElem, targetElem) { 79 | let value; 80 | ['disabled', 'delay', 'immediate'].forEach((name) => { 81 | name = 'infinite-scroll-' + name; 82 | value = sourceElem.getAttribute(name); 83 | if (value !== null) { 84 | targetElem.setAttribute(name, value); 85 | } 86 | }); 87 | 88 | // fix: windows/chrome 的 scrollTop + clientHeight 与 scrollHeight 不一致的 BUG 89 | const name = 'infinite-scroll-distance'; 90 | value = sourceElem.getAttribute(name); 91 | targetElem.setAttribute(name, value < 1 ? 1 : value); 92 | } 93 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/FilterViewTag.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 35 | 36 | 70 | 71 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/NodeFilter.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 25 | 26 | 66 | 67 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/NodeFuncFilter.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 78 | 79 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/NodeNotifyFilter.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 26 | 27 | 73 | 74 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/NodeReportFilter.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 78 | 79 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/NodeResourceFilter.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 26 | 27 | 70 | 71 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/components/FilterDateTimePicker.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 27 | 28 | 87 | 88 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/components/FilterInput.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 29 | 30 | 88 | 89 | -------------------------------------------------------------------------------- /web/src/components/toolbar/filter/components/FilterSelect.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 27 | 28 | 102 | 103 | -------------------------------------------------------------------------------- /web/src/css/card.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .card{ 18 | margin-left: 16px; 19 | margin-top: 8px; 20 | margin-bottom: 8px; 21 | width: 305px; 22 | } 23 | 24 | .card-link{ 25 | text-decoration: none; 26 | } 27 | 28 | .card-text-omit{ 29 | white-space:nowrap; 30 | overflow:hidden; 31 | text-overflow:ellipsis; 32 | } 33 | 34 | .card-dialog-title{ 35 | font-size: 18px; 36 | } -------------------------------------------------------------------------------- /web/src/css/color.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .color-state-main{ 18 | color: #409EFF; 19 | } 20 | 21 | .color-state-success{ 22 | color: #67C23A; 23 | } 24 | 25 | .color-state-warning{ 26 | color: #E6A23C; 27 | } 28 | 29 | .color-state-danger{ 30 | color: #F56C6C; 31 | } 32 | 33 | .color-state-lose{ 34 | color: #909399; 35 | } 36 | 37 | .color-state-other{ 38 | color: #000000; 39 | } 40 | 41 | .color-text-main{ 42 | color: #303133; 43 | } 44 | 45 | .color-text-normal{ 46 | color: #606266; 47 | } 48 | 49 | .color-text-assist{ 50 | color: #909399; 51 | } 52 | 53 | .color-text-unnecessary{ 54 | color: #C0C4CC; 55 | } 56 | 57 | .el-table .table-color-state-info { 58 | --el-table-tr-background-color: var(--el-color-info-light); 59 | } 60 | .el-table .table-color-state-success { 61 | --el-table-tr-background-color: var(--el-color-success-lighter); 62 | } 63 | .el-table .table-color-state-warning { 64 | --el-table-tr-background-color: var(--el-color-warning-lighter); 65 | } 66 | .el-table .table-color-state-danger { 67 | --el-table-tr-background-color: var(--el-color-error-lighter); 68 | } 69 | -------------------------------------------------------------------------------- /web/src/css/flex.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .flex-row-center-start{ 18 | display: flex; 19 | flex-direction:row; 20 | flex-wrap:wrap; 21 | justify-content: center; 22 | align-content: flex-start; 23 | } 24 | 25 | .flex-row-start-start{ 26 | display: flex; 27 | flex-direction:row; 28 | flex-wrap:wrap; 29 | justify-content: flex-start; 30 | align-content: flex-start; 31 | } 32 | 33 | .flex-row-start-start-nowrap{ 34 | display: flex; 35 | flex-direction:row; 36 | flex-wrap:nowrap; 37 | justify-content: flex-start; 38 | align-content: flex-start; 39 | } 40 | 41 | .flex-row-center-between{ 42 | display: flex; 43 | flex-direction:row; 44 | flex-wrap:wrap; 45 | justify-content: center; 46 | align-content: space-between; 47 | } 48 | 49 | .flex-row-center-around{ 50 | display: flex; 51 | flex-direction:row; 52 | flex-wrap:wrap; 53 | justify-content: center; 54 | align-content: space-around; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /web/src/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #app { 18 | font-family: "Helvetica Neue","PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 19 | font-weight: 400; 20 | -webkit-font-smoothing: antialiased; 21 | -moz-osx-font-smoothing: grayscale; 22 | -webkit-tap-highlight-color: transparent; 23 | height: 100vh; 24 | width: 100vw; 25 | margin: 0px; 26 | padding: 0px; 27 | } 28 | 29 | body { 30 | margin: 0px; 31 | padding: 0px; 32 | } 33 | 34 | ::-webkit-scrollbar { 35 | width: 7px; 36 | height: 5px; 37 | border-radius:15px; 38 | -webkit-border-radius: 15px; 39 | } 40 | ::-webkit-scrollbar-track-piece { 41 | background-color: #ffff; 42 | border-radius:15px; 43 | -webkit-border-radius: 15px; 44 | } 45 | ::-webkit-scrollbar-thumb:vertical { 46 | height: 5px; 47 | -webkit-border-radius: 15px; 48 | cursor: pointer; 49 | background-color: rgba(144,147,153,.3); 50 | transition: background-color .3s; 51 | -webkit-transition: background-color .3s; 52 | } 53 | ::-webkit-scrollbar-thumb:hover:vertical { 54 | background-color: rgba(144,147,153,.5); 55 | } 56 | 57 | ::-webkit-scrollbar-thumb:horizontal { 58 | width: 7px; 59 | -webkit-border-radius: 15px; 60 | cursor: pointer; 61 | background-color: rgba(144, 147, 153, .3); 62 | transition: background-color .3s; 63 | -webkit-transition: background-color .3s; 64 | } 65 | 66 | ::-webkit-scrollbar-thumb:hover:horizontal { 67 | background-color: rgba(144,147,153,.5); 68 | } 69 | -------------------------------------------------------------------------------- /web/src/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 liyiligang. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createApp } from 'vue' 18 | import App from './App.vue' 19 | import './index.css' 20 | import router from './router' 21 | import ElementPlus from 'element-plus' 22 | import 'element-plus/dist/index.css' 23 | import VueForm from '@lljj/vue3-form-element'; 24 | import elTableInfiniteScroll from "./components/tableInfiniteScroll"; 25 | import UploadFile from "./components/vueForm/widgets/UploadFile.vue"; 26 | import JsonViewer from "vue3-json-viewer" 27 | import i18n from './base/i18n' 28 | import "echarts"; 29 | import ECharts from 'vue-echarts' 30 | 31 | const app = createApp(App) 32 | app.config.unwrapInjectedRef = true 33 | app.use(router) 34 | .use(elTableInfiniteScroll) 35 | .use(ElementPlus) 36 | .use(JsonViewer) 37 | .use(i18n) 38 | .component('v-chart', ECharts) 39 | .component('VueForm', VueForm) 40 | .component('UploadFile', UploadFile) 41 | .mount('#app') 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /web/src/views/NotFound.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 29 | 30 | 52 | 53 | 84 | 85 | -------------------------------------------------------------------------------- /web/src/views/node/NodeTest.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 39 | 40 | -------------------------------------------------------------------------------- /web/src/views/node/NodeViewFrame.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 31 | 32 | 59 | 60 | 105 | -------------------------------------------------------------------------------- /web/tsconfig.json: -------------------------------------------------------------------------------- 1 | // tsconfig.json 2 | { 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "module": "esnext", 6 | "strict": true, 7 | "jsx": "preserve", 8 | "moduleResolution": "node", 9 | "noImplicitAny":false, 10 | "lib": ["es2018", "dom"] 11 | } 12 | } -------------------------------------------------------------------------------- /web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | 3 | module.exports = { 4 | plugins:[vue()], 5 | build:{ 6 | outDir:"../bin/web" 7 | }, 8 | optimizeDeps: { 9 | include: ["protobufjs/minimal", "element-plus/lib/locale/lang/zh-cn", "dayjs/locale/zh-cn", "echarts/core", 10 | "echarts/charts", "echarts/renderers", "echarts/components"] 11 | }, 12 | server: { 13 | host:"localhost", 14 | proxy: { 15 | '/api': { 16 | target: 'http://localhost:806', 17 | changeOrigin: true, 18 | ws:true, 19 | rewrite: (path) => path.replace(/^\/api/, '') 20 | }, 21 | } 22 | } 23 | } --------------------------------------------------------------------------------