mager: 合并11.3版本,包名和主线一样方便复制

This commit is contained in:
TsMask
2024-11-23 18:54:02 +08:00
parent c0368c07ef
commit d5954d40c8
514 changed files with 24451 additions and 17932 deletions

View File

@@ -4,21 +4,22 @@ import (
"embed"
"fmt"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/errorcatch"
"nms_cxy/src/framework/middleware"
"nms_cxy/src/framework/middleware/security"
"nms_cxy/src/framework/utils/machine"
"nms_cxy/src/modules/chart"
"nms_cxy/src/modules/common"
"nms_cxy/src/modules/crontask"
"nms_cxy/src/modules/monitor"
networkdata "nms_cxy/src/modules/network_data"
networkelement "nms_cxy/src/modules/network_element"
nmscxy "nms_cxy/src/modules/nms_cxy"
"nms_cxy/src/modules/system"
"nms_cxy/src/modules/trace"
"nms_cxy/src/modules/ws"
"be.ems/src/framework/config"
"be.ems/src/framework/errorcatch"
"be.ems/src/framework/middleware"
"be.ems/src/framework/middleware/security"
"be.ems/src/framework/utils/machine"
"be.ems/src/modules/chart"
"be.ems/src/modules/common"
"be.ems/src/modules/crontask"
"be.ems/src/modules/monitor"
networkdata "be.ems/src/modules/network_data"
networkelement "be.ems/src/modules/network_element"
nmscxy "be.ems/src/modules/nms_cxy"
"be.ems/src/modules/system"
"be.ems/src/modules/tool"
"be.ems/src/modules/trace"
"be.ems/src/modules/ws"
"github.com/chenjiandongx/ginprom"
"github.com/gin-gonic/gin"
@@ -144,6 +145,8 @@ func initModulesRoute(app *gin.Engine) {
trace.Setup(app)
// 图表模块
chart.Setup(app)
// 工具模块
tool.Setup(app)
// ws 模块
ws.Setup(app)
// 北向模块 - 中国星网

View File

@@ -1,11 +1,11 @@
package src
import (
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/cron"
"nms_cxy/src/framework/datasource"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/redis"
"be.ems/src/framework/config"
"be.ems/src/framework/cron"
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
)
// 配置中心初始加载

View File

@@ -8,8 +8,7 @@ import (
"os"
"time"
libConfig "nms_cxy/src/lib_features/config"
libConfig "be.ems/src/lib_features/config"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
@@ -27,9 +26,9 @@ func InitConfig() {
func initFlag() {
// --env prod
pflag.String("env", "prod", "Specify Run Environment Configuration local or prod")
// --c /etc/omc.yaml
// -c /etc/omc.yaml
pConfig := pflag.StringP("config", "c", "./etc/omc.yaml", "Specify Configuration File")
// --c /etc/restconf.yaml
// -c /etc/restconf.yaml
pConfig := pflag.StringP("config", "c", "./etc/restconf.yaml", "Specify Configuration File")
// --version
// -V
pVersion := pflag.BoolP("version", "V", false, "Output program version")

View File

@@ -1,7 +1,7 @@
# 项目信息
framework:
name: "OMC"
version: "2.2408.5"
version: "2.2411.2"
# 应用服务配置
server:

View File

@@ -4,7 +4,7 @@ import (
"testing"
"time"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
// 参考文章:

View File

@@ -4,9 +4,9 @@ import (
"encoding/json"
"time"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/modules/monitor/model"
"nms_cxy/src/modules/monitor/repository"
"be.ems/src/framework/constants/common"
"be.ems/src/modules/monitor/model"
"be.ems/src/modules/monitor/repository"
)
// 实例任务执行日志收集

View File

@@ -7,8 +7,8 @@ import (
"regexp"
"time"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/config"
"be.ems/src/framework/logger"
"gorm.io/driver/mysql"
"gorm.io/gorm"
@@ -117,6 +117,9 @@ func DefaultDB() *gorm.DB {
// 获取数据源
func DB(source string) *gorm.DB {
if source == "" {
source = config.Get("gorm.defaultDataSourceName").(string)
}
return dbMap[source]
}

View File

@@ -3,9 +3,9 @@ package errorcatch
import (
"fmt"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/vo/result"
"be.ems/src/framework/config"
"be.ems/src/framework/logger"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
)

View File

@@ -5,7 +5,7 @@ import (
"regexp"
"strings"
systemService "nms_cxy/src/modules/system/service"
systemService "be.ems/src/modules/system/service"
)
// localeItem 国际化数据项
@@ -26,7 +26,7 @@ func ClearLocaleData() {
// LoadLocaleData 加载国际化数据
func LoadLocaleData(language string) []localeItem {
dictType := fmt.Sprintf("i18n_%s", language)
dictTypeList := systemService.NewSysDictTypeImpl.DictDataCache(dictType)
dictTypeList := systemService.NewSysDictType.DictDataCache(dictType)
localeData := []localeItem{}
for _, v := range dictTypeList {
localeData = append(localeData, localeItem{
@@ -58,7 +58,7 @@ func UpdateKeyValue(language, key, value string) bool {
}
// 更新字典数据
sysDictDataService := systemService.NewSysDictDataImpl
sysDictDataService := systemService.NewSysDictData
item := sysDictDataService.SelectDictDataByCode(code)
if item.DictCode == code && item.DictLabel == key {
item.DictValue = value

View File

@@ -7,14 +7,14 @@ import (
"strings"
"time"
"nms_cxy/src/framework/constants/common"
tokenConstants "nms_cxy/src/framework/constants/token"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/vo/result"
"nms_cxy/src/modules/system/model"
"nms_cxy/src/modules/system/service"
"be.ems/src/framework/constants/common"
tokenConstants "be.ems/src/framework/constants/token"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/system/model"
"be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
)

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"nms_cxy/src/framework/config"
"be.ems/src/framework/config"
"github.com/gin-gonic/gin"
)

View File

@@ -7,12 +7,11 @@ import (
"io"
"strings"
"nms_cxy/src/framework/config"
constResult "nms_cxy/src/framework/constants/result"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/crypto"
"nms_cxy/src/framework/utils/parse"
"be.ems/src/framework/config"
constResult "be.ems/src/framework/constants/result"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/parse"
"github.com/gin-gonic/gin"
)

View File

@@ -3,12 +3,12 @@ package middleware
import (
"strings"
AdminConstants "nms_cxy/src/framework/constants/admin"
commonConstants "nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/i18n"
ctxUtils "nms_cxy/src/framework/utils/ctx"
tokenUtils "nms_cxy/src/framework/utils/token"
"nms_cxy/src/framework/vo/result"
AdminConstants "be.ems/src/framework/constants/admin"
commonConstants "be.ems/src/framework/constants/common"
"be.ems/src/framework/i18n"
ctxUtils "be.ems/src/framework/utils/ctx"
tokenUtils "be.ems/src/framework/utils/token"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
)

View File

@@ -5,12 +5,12 @@ import (
"strings"
"time"
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/ip2region"
"nms_cxy/src/framework/vo/result"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/i18n"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/ip2region"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
)

View File

@@ -5,12 +5,12 @@ import (
"strconv"
"time"
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/ip2region"
"nms_cxy/src/framework/vo/result"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/ip2region"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
)

View File

@@ -4,7 +4,7 @@ import (
"runtime"
"time"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
"github.com/gin-gonic/gin"
)

View File

@@ -1,8 +1,8 @@
package security
import (
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/utils/generate"
"be.ems/src/framework/config"
"be.ems/src/framework/utils/generate"
"github.com/gin-gonic/gin"
)

View File

@@ -3,7 +3,7 @@ package security
import (
"fmt"
"nms_cxy/src/framework/config"
"be.ems/src/framework/config"
"github.com/gin-gonic/gin"
)

View File

@@ -1,7 +1,7 @@
package security
import (
"nms_cxy/src/framework/config"
"be.ems/src/framework/config"
"github.com/gin-gonic/gin"
)

View File

@@ -1,7 +1,7 @@
package security
import (
"nms_cxy/src/framework/config"
"be.ems/src/framework/config"
"github.com/gin-gonic/gin"
)

View File

@@ -3,8 +3,8 @@ package security
import (
"net/url"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/vo/result"
"be.ems/src/framework/config"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
)

View File

@@ -1,7 +1,7 @@
package security
import (
"nms_cxy/src/framework/config"
"be.ems/src/framework/config"
"github.com/gin-gonic/gin"
)

View File

@@ -1,7 +1,7 @@
package security
import (
"nms_cxy/src/framework/config"
"be.ems/src/framework/config"
"github.com/gin-gonic/gin"
)

View File

@@ -0,0 +1,79 @@
package redis
import (
"context"
"fmt"
"strings"
"time"
"github.com/redis/go-redis/v9"
)
// ConnRedis 连接redis对象
type ConnRedis struct {
Addr string `json:"addr"` // 地址
Port int64 `json:"port"` // 端口
User string `json:"user"` // 用户名
Password string `json:"password"` // 认证密码
Database int `json:"database"` // 数据库名称
DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开
Client *redis.Client `json:"client"`
}
// NewClient 创建Redis客户端
func (c *ConnRedis) NewClient() (*ConnRedis, error) {
// IPV6地址协议
if strings.Contains(c.Addr, ":") {
c.Addr = fmt.Sprintf("[%s]", c.Addr)
}
addr := fmt.Sprintf("%s:%d", c.Addr, c.Port)
// 默认等待5s
if c.DialTimeOut == 0 {
c.DialTimeOut = 5 * time.Second
}
// 连接
rdb := redis.NewClient(&redis.Options{
Addr: addr,
// Username: c.User,
Password: c.Password,
DB: c.Database,
DialTimeout: c.DialTimeOut,
})
// 测试数据库连接
if _, err := rdb.Ping(context.Background()).Result(); err != nil {
return nil, err
}
c.Client = rdb
return c, nil
}
// Close 关闭当前Redis客户端
func (c *ConnRedis) Close() {
if c.Client != nil {
c.Client.Close()
}
}
// RunCMD 执行单次命令 "GET key"
func (c *ConnRedis) RunCMD(cmd string) (any, error) {
if c.Client == nil {
return "", fmt.Errorf("redis client not connected")
}
// 写入命令
cmdArr := strings.Fields(cmd)
if len(cmdArr) == 0 {
return "", fmt.Errorf("redis command is empty")
}
conn := *c.Client
args := make([]any, 0)
for _, v := range cmdArr {
args = append(args, v)
}
return conn.Do(context.Background(), args...).Result()
}

View File

@@ -4,10 +4,11 @@ import (
"context"
"fmt"
"strings"
"sync"
"time"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/config"
"be.ems/src/framework/logger"
"github.com/redis/go-redis/v9"
)
@@ -30,6 +31,15 @@ if tonumber(current) == 1 then
end
return tonumber(current);`)
// 连接Redis实例
func ConnectPush(source string, rdb *redis.Client) {
if rdb == nil {
delete(rdbMap, source)
return
}
rdbMap[source] = rdb
}
// 连接Redis实例
func Connect() {
ctx := context.Background()
@@ -170,31 +180,22 @@ func GetExpire(source string, key string) (float64, error) {
}
// 获得缓存数据的key列表
func GetKeys(source string, pattern string) ([]string, error) {
func GetKeys(source string, match string) ([]string, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
// 初始化变量
var keys []string
var cursor uint64 = 0
keys := make([]string, 0)
ctx := context.Background()
// 循环遍历获取匹配的键
for {
// 使用 SCAN 命令获取匹配的键
batchKeys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, 100).Result()
if err != nil {
logger.Errorf("Failed to scan keys: %v", err)
return keys, err
}
cursor = nextCursor
keys = append(keys, batchKeys...)
// 当 cursor 为 0表示遍历完成
if cursor == 0 {
break
}
iter := rdb.Scan(ctx, 0, match, 1000).Iterator()
if err := iter.Err(); err != nil {
logger.Errorf("Failed to scan keys: %v", err)
return keys, err
}
for iter.Next(ctx) {
keys = append(keys, iter.Val())
}
return keys, nil
}
@@ -252,6 +253,84 @@ func GetHash(source, key string) (map[string]string, error) {
return value, nil
}
// 批量获得缓存数据 [key]result
func GetHashBatch(source string, keys []string) (map[string]map[string]string, error) {
result := make(map[string]map[string]string, 0)
if len(keys) == 0 {
return result, fmt.Errorf("not keys")
}
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
// 创建一个有限的并发控制信号通道
sem := make(chan struct{}, 10)
var wg sync.WaitGroup
var mt sync.Mutex
batchSize := 1000
total := len(keys)
if total < batchSize {
batchSize = total
}
for i := 0; i < total; i += batchSize {
wg.Add(1)
go func(start int) {
ctx := context.Background()
// 并发控制,限制同时执行的 Goroutine 数量
sem <- struct{}{}
defer func() {
<-sem
ctx.Done()
wg.Done()
}()
pipe := rdb.Pipeline()
for _, key := range keys[start : start+batchSize] {
pipe.HGetAll(ctx, key)
}
cmds, err := pipe.Exec(ctx)
if err != nil {
logger.Errorf("Failed to get hash batch exec err: %v", err)
return
}
// 将结果添加到 result map 并发访问
mt.Lock()
defer mt.Unlock()
// 处理命令结果
for _, cmd := range cmds {
if cmd.Err() != nil {
logger.Errorf("Failed to get hash batch cmds err: %v", cmd.Err())
continue
}
// 将结果转换为 *redis.StringStringMapCmd 类型
rcmd, ok := cmd.(*redis.MapStringStringCmd)
if !ok {
logger.Errorf("Failed to get hash batch type err: %v", cmd.Err())
continue
}
key := "-"
args := rcmd.Args()
if len(args) > 0 {
key = fmt.Sprint(args[1])
}
result[key] = rcmd.Val()
}
}(i)
}
wg.Wait()
return result, nil
}
// 判断是否存在
func Has(source string, keys ...string) (bool, error) {
// 数据源

View File

@@ -0,0 +1,96 @@
package socket
import (
"bytes"
"fmt"
"net"
"strings"
"time"
)
// ConnTCP 连接TCP客户端
type ConnTCP struct {
Addr string `json:"addr"` // 主机地址
Port int64 `json:"port"` // 端口
DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开
Client *net.Conn `json:"client"`
LastResult string `json:"lastResult"` // 记最后一次发送消息的结果
}
// New 创建TCP客户端
func (c *ConnTCP) New() (*ConnTCP, error) {
// IPV6地址协议
proto := "tcp"
if strings.Contains(c.Addr, ":") {
proto = "tcp6"
c.Addr = fmt.Sprintf("[%s]", c.Addr)
}
address := fmt.Sprintf("%s:%d", c.Addr, c.Port)
// 默认等待5s
if c.DialTimeOut == 0 {
c.DialTimeOut = 5 * time.Second
}
// 连接到服务端
client, err := net.DialTimeout(proto, address, c.DialTimeOut)
if err != nil {
return nil, err
}
c.Client = &client
return c, nil
}
// Close 关闭当前TCP客户端
func (c *ConnTCP) Close() {
if c.Client != nil {
(*c.Client).Close()
}
}
// Send 发送消息
func (c *ConnTCP) Send(msg []byte, timer time.Duration) (string, error) {
if c.Client == nil {
return "", fmt.Errorf("tcp client not connected")
}
conn := *c.Client
// 写入信息
if len(msg) > 0 {
if _, err := conn.Write(msg); err != nil {
return "", err
}
}
var buf bytes.Buffer
defer buf.Reset()
tmp := make([]byte, 1024)
for {
select {
case <-time.After(timer):
c.LastResult = buf.String()
return c.LastResult, fmt.Errorf("timeout")
default:
// 读取命令消息
n, err := conn.Read(tmp)
if n == 0 || err != nil {
tmp = nil
break
}
tmpStr := string(tmp[:n])
buf.WriteString(tmpStr)
// 是否有终止符
if strings.HasSuffix(tmpStr, ">") || strings.HasSuffix(tmpStr, "> ") || strings.HasSuffix(tmpStr, "# ") {
tmp = nil
c.LastResult = buf.String()
return c.LastResult, nil
}
}
}
}

View File

@@ -0,0 +1,77 @@
package socket
import (
"fmt"
"net"
"strings"
"be.ems/src/framework/logger"
)
// SocketTCP TCP服务端
type SocketTCP struct {
Addr string `json:"addr"` // 主机地址
Port int64 `json:"port"` // 端口
Listener *net.TCPListener `json:"listener"`
StopChan chan struct{} `json:"stop"` // 停止信号
}
// New 创建TCP服务端
func (s *SocketTCP) New() (*SocketTCP, error) {
// IPV6地址协议
proto := "tcp"
if strings.Contains(s.Addr, ":") {
proto = "tcp6"
s.Addr = fmt.Sprintf("[%s]", s.Addr)
}
address := fmt.Sprintf("%s:%d", s.Addr, s.Port)
// 解析 TCP 地址
tcpAddr, err := net.ResolveTCPAddr(proto, address)
if err != nil {
return nil, err
}
// 监听 TCP 地址
listener, err := net.ListenTCP(proto, tcpAddr)
if err != nil {
return nil, err
}
s.Listener = listener
s.StopChan = make(chan struct{}, 1)
return s, nil
}
// Close 关闭当前TCP服务端
func (s *SocketTCP) Close() {
if s.Listener != nil {
s.StopChan <- struct{}{}
(*s.Listener).Close()
}
}
// Resolve 处理消息
func (s *SocketTCP) Resolve(callback func(conn *net.Conn, err error)) {
if s.Listener == nil {
callback(nil, fmt.Errorf("tcp service not created"))
return
}
listener := *s.Listener
for {
select {
case <-s.StopChan:
callback(nil, fmt.Errorf("udp service stop"))
return
default:
conn, err := listener.Accept()
if err != nil {
logger.Errorf("Error accepting connection: %v ", err)
continue
}
defer conn.Close()
callback(&conn, nil)
}
}
}

View File

@@ -0,0 +1,96 @@
package socket
import (
"bytes"
"fmt"
"net"
"strings"
"time"
)
// ConnUDP 连接UDP客户端
type ConnUDP struct {
Addr string `json:"addr"` // 主机地址
Port int64 `json:"port"` // 端口
DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开
Client *net.Conn `json:"client"`
LastResult string `json:"lastResult"` // 记最后一次发送消息的结果
}
// New 创建UDP客户端
func (c *ConnUDP) New() (*ConnUDP, error) {
// IPV6地址协议
proto := "udp"
if strings.Contains(c.Addr, ":") {
proto = "udp6"
c.Addr = fmt.Sprintf("[%s]", c.Addr)
}
address := fmt.Sprintf("%s:%d", c.Addr, c.Port)
// 默认等待5s
if c.DialTimeOut == 0 {
c.DialTimeOut = 5 * time.Second
}
// 连接到服务端
client, err := net.DialTimeout(proto, address, c.DialTimeOut)
if err != nil {
return nil, err
}
c.Client = &client
return c, nil
}
// Close 关闭当前UDP客户端
func (c *ConnUDP) Close() {
if c.Client != nil {
(*c.Client).Close()
}
}
// Send 发送消息
func (c *ConnUDP) Send(msg []byte, ms int) (string, error) {
if c.Client == nil {
return "", fmt.Errorf("udp client not connected")
}
conn := *c.Client
// 写入信息
if len(msg) > 0 {
if _, err := conn.Write(msg); err != nil {
return "", err
}
}
var buf bytes.Buffer
defer buf.Reset()
tmp := make([]byte, 1024)
for {
select {
case <-time.After(time.Duration(time.Duration(ms).Milliseconds())):
c.LastResult = buf.String()
return c.LastResult, fmt.Errorf("timeout")
default:
// 读取命令消息
n, err := conn.Read(tmp)
if n == 0 || err != nil {
tmp = nil
break
}
tmpStr := string(tmp[:n])
buf.WriteString(tmpStr)
// 是否有终止符
if strings.HasSuffix(tmpStr, ">") || strings.HasSuffix(tmpStr, "> ") || strings.HasSuffix(tmpStr, "# ") {
tmp = nil
c.LastResult = buf.String()
return c.LastResult, nil
}
}
}
}

View File

@@ -0,0 +1,67 @@
package socket
import (
"fmt"
"net"
"strings"
)
// SocketUDP UDP服务端
type SocketUDP struct {
Addr string `json:"addr"` // 主机地址
Port int64 `json:"port"` // 端口
Conn *net.UDPConn `json:"conn"`
StopChan chan struct{} `json:"stop"` // 停止信号
}
// New 创建UDP服务端
func (s *SocketUDP) New() (*SocketUDP, error) {
// IPV6地址协议
proto := "udp"
if strings.Contains(s.Addr, ":") {
proto = "udp6"
s.Addr = fmt.Sprintf("[%s]", s.Addr)
}
address := fmt.Sprintf("%s:%d", s.Addr, s.Port)
// 解析 UDP 地址
udpAddr, err := net.ResolveUDPAddr(proto, address)
if err != nil {
return nil, err
}
// 监听 UDP 地址
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
return nil, err
}
s.Conn = conn
s.StopChan = make(chan struct{}, 1)
return s, nil
}
// CloseService 关闭当前UDP服务端
func (s *SocketUDP) Close() {
if s.Conn != nil {
s.StopChan <- struct{}{}
(*s.Conn).Close()
}
}
// Resolve 处理消息
func (s *SocketUDP) Resolve(callback func(*net.UDPConn, error)) {
if s.Conn == nil {
callback(nil, fmt.Errorf("udp service not created"))
return
}
for {
select {
case <-s.StopChan:
callback(nil, fmt.Errorf("udp service not created"))
default:
callback(s.Conn, nil)
}
}
}

View File

@@ -50,11 +50,6 @@ func (c *ConnTelnet) NewClient() (*ConnTelnet, error) {
// fmt.Fprintln(client, c.User)
// fmt.Fprintln(client, c.Password)
// 调整窗口大小 (120 列 x 128 行)
// 需要确保接收方理解并正确处理发送窗口大小设置命令
client.Write([]byte{255, 251, 31})
client.Write([]byte{255, 250, 31, byte(120 >> 8), byte(120 & 0xFF), byte(128 >> 8), byte(128 & 0xFF), 255, 240})
c.Client = &client
// 排空连接登录的信息
@@ -116,6 +111,6 @@ func (c *ConnTelnet) NewClientSession(cols, rows int) (*TelnetClientSession, err
s := &TelnetClientSession{
Client: *c.Client,
}
s.WindowChange(cols, rows)
// s.WindowChange(cols, rows)
return s, nil
}

View File

@@ -47,11 +47,11 @@ func (s *TelnetClientSession) Read() []byte {
buf := make([]byte, 1024)
// 设置读取超时时间为100毫秒
s.Client.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
_, err := s.Client.Read(buf)
n, err := s.Client.Read(buf)
if err != nil {
return []byte{}
}
return buf
return buf[:n]
}
// CombinedOutput 发送命令带结果返回

View File

@@ -4,18 +4,16 @@ import (
"fmt"
"strings"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/constants/roledatascope"
"nms_cxy/src/framework/constants/token"
"nms_cxy/src/framework/utils/ip2region"
"nms_cxy/src/framework/utils/ua"
"nms_cxy/src/framework/vo"
"be.ems/src/framework/config"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/constants/roledatascope"
"be.ems/src/framework/constants/token"
"be.ems/src/framework/utils/ip2region"
"be.ems/src/framework/utils/ua"
"be.ems/src/framework/vo"
"golang.org/x/text/language"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
// QueryMap 查询参数转换Map
@@ -31,7 +29,7 @@ func QueryMap(c *gin.Context) map[string]any {
// BodyJSONMap JSON参数转换Map
func BodyJSONMap(c *gin.Context) map[string]any {
params := make(map[string]any)
c.ShouldBindBodyWith(&params, binding.JSON)
c.ShouldBindBodyWithJSON(&params)
return params
}
@@ -40,7 +38,7 @@ func RequestParamsMap(c *gin.Context) map[string]any {
params := make(map[string]any)
// json
if strings.HasPrefix(c.ContentType(), "application/json") {
c.ShouldBindBodyWith(&params, binding.JSON)
c.ShouldBindBodyWithJSON(&params)
}
// 表单

View File

@@ -3,7 +3,7 @@ package date
import (
"time"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
const (

View File

@@ -87,7 +87,7 @@ func Post(url string, data url.Values, headers map[string]string) ([]byte, error
// PostJSON 发送 POST 请求,并将请求体序列化为 JSON 格式
func PostJSON(url string, data any, headers map[string]string) ([]byte, error) {
client := &http.Client{
Timeout: 3 * time.Second, // 超时时间
Timeout: 10 * time.Second, // 超时时间
}
jsonData, err := json.Marshal(data)
@@ -180,7 +180,7 @@ func PostUploadFile(url string, params map[string]string, file *os.File) ([]byte
// PutJSON 发送 PUT 请求,并将请求体序列化为 JSON 格式
func PutJSON(url string, data any, headers map[string]string) ([]byte, error) {
client := &http.Client{
Timeout: 3 * time.Second, // 超时时间
Timeout: 10 * time.Second, // 超时时间
}
jsonData, err := json.Marshal(data)

View File

@@ -6,7 +6,7 @@ import (
"path/filepath"
"strings"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
// 写入CSV文件需要转换数据

View File

@@ -7,9 +7,9 @@ import (
"path/filepath"
"time"
"nms_cxy/src/framework/constants/uploadsubpath"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/date"
"be.ems/src/framework/constants/uploadsubpath"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"github.com/xuri/excelize/v2"
)

View File

@@ -11,13 +11,13 @@ import (
"strings"
"time"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/constants/uploadsubpath"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/date"
"nms_cxy/src/framework/utils/generate"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/utils/regular"
"be.ems/src/framework/config"
"be.ems/src/framework/constants/uploadsubpath"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/generate"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/regular"
)
/**最大文件名长度 */

View File

@@ -7,7 +7,7 @@ import (
"os"
"path/filepath"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
// WriterFileJSON 写入JSON文件

View File

@@ -0,0 +1,76 @@
package file
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"path/filepath"
)
// CompressTarGZByDir 将目录下文件添加到 tar.gz 压缩文件
func CompressTarGZByDir(zipFilePath, dirPath string) error {
// 创建本地输出目录
if err := os.MkdirAll(filepath.Dir(zipFilePath), 0775); err != nil {
return err
}
// 创建输出文件
tarFile, err := os.Create(zipFilePath)
if err != nil {
return err
}
defer tarFile.Close()
gw := gzip.NewWriter(tarFile)
defer gw.Close()
tw := tar.NewWriter(gw)
defer tw.Close()
// 遍历目录下的所有文件和子目录
err = filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 忽略目录
if info.IsDir() {
return nil
}
// 创建文件条目
header, err := tar.FileInfoHeader(info, "")
if err != nil {
return err
}
relPath, err := filepath.Rel(dirPath, path)
if err != nil {
return err
}
header.Name = relPath
if err := tw.WriteHeader(header); err != nil {
return err
}
if !info.Mode().IsRegular() {
return nil
}
// 打开文件
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
// 写入文件内容
_, err = io.Copy(tw, file)
if err != nil {
return err
}
return nil
})
return err
}

View File

@@ -7,7 +7,7 @@ import (
"path/filepath"
"strings"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
// WriterFileTXT 写入txt文件 sep 分割符号 需要转换数据

View File

@@ -9,7 +9,7 @@ import (
"sort"
"strconv"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
// transferToNewFile 读取目标文件转移到新路径下

View File

@@ -4,7 +4,7 @@ import (
"math/rand"
"time"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
gonanoid "github.com/matoous/go-nanoid/v2"
)

View File

@@ -5,7 +5,7 @@ import (
"strings"
"time"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
)
// 网络地址(内网)

View File

@@ -8,12 +8,12 @@ import (
"runtime"
"time"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/cmd"
"nms_cxy/src/framework/utils/crypto"
"nms_cxy/src/framework/utils/parse"
"be.ems/src/framework/config"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/cmd"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/parse"
)
// 机器的唯一标识符
@@ -167,7 +167,7 @@ func Reset() error {
return err
}
// 重启服务
if _, err := cmd.Execf("nohup sh -c \"sleep 1s && %s\" > /dev/null 2>&1 &", "sudo systemctl restart omc"); err != nil {
if _, err := cmd.Execf("nohup sh -c \"sleep 1s && %s\" > /dev/null 2>&1 &", "sudo systemctl restart restagent"); err != nil {
return err
}
}

View File

@@ -17,46 +17,53 @@ import (
)
// Number 解析数值型
func Number(str any) int64 {
switch str := str.(type) {
func Number(value any) int64 {
switch v := value.(type) {
case string:
if str == "" {
if v == "" {
return 0
}
num, err := strconv.ParseInt(str, 10, 64)
num, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return 0
}
return num
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return reflect.ValueOf(str).Int()
case int, int8, int16, int32, int64:
return reflect.ValueOf(v).Int()
case uint, uint8, uint16, uint32, uint64:
return int64(reflect.ValueOf(v).Uint())
case float32, float64:
return int64(reflect.ValueOf(str).Float())
return int64(reflect.ValueOf(v).Float())
case bool:
if v {
return 1
}
return 0
default:
return 0
}
}
// Boolean 解析布尔型
func Boolean(str any) bool {
switch str := str.(type) {
func Boolean(value any) bool {
switch v := value.(type) {
case string:
if str == "" || str == "false" || str == "0" {
b, err := strconv.ParseBool(v)
if err != nil {
return false
}
// 尝试将字符串解析为数字
if num, err := strconv.ParseFloat(str, 64); err == nil {
return num != 0
}
return true
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
num := reflect.ValueOf(str).Int()
return b
case int, int8, int16, int32, int64:
num := reflect.ValueOf(v).Int()
return num != 0
case uint, uint8, uint16, uint32, uint64:
num := int64(reflect.ValueOf(v).Uint())
return num != 0
case float32, float64:
num := reflect.ValueOf(str).Float()
num := reflect.ValueOf(v).Float()
return num != 0
case bool:
return str
return v
default:
return false
}

View File

@@ -7,7 +7,7 @@ import (
"strings"
"time"
"nms_cxy/src/framework/utils/parse"
"be.ems/src/framework/utils/parse"
)
// PageNumSize 分页页码记录数

View File

@@ -4,9 +4,9 @@ import (
"fmt"
"strings"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/cmd"
"nms_cxy/src/framework/utils/parse"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/cmd"
"be.ems/src/framework/utils/parse"
)
// FileListRow 文件列表行数据
@@ -24,9 +24,8 @@ type FileListRow struct {
// 文件列表
// search 文件名后模糊*
//
// return 目录大小,行记录,异常
func FileList(sshClient *ConnSSH, path, search string) (string, []FileListRow, error) {
totalSize := ""
// return 行记录,异常
func FileList(sshClient *ConnSSH, path, search string) ([]FileListRow, error) {
var rows []FileListRow
rowStr := ""
@@ -35,40 +34,37 @@ func FileList(sshClient *ConnSSH, path, search string) (string, []FileListRow, e
if search != "" {
searchStr = search + searchStr
}
cmdStr := fmt.Sprintf("cd %s && ls -lthd --time-style=+%%s %s", path, searchStr)
// cd /var/log && find. -maxdepth 1 -name'mme*' -exec ls -lthd --time-style=+%s {} +
cmdStr := fmt.Sprintf("cd %s && find . -maxdepth 1 -name '%s' -exec ls -lthd --time-style=+%%s {} +", path, searchStr)
// cd /var/log && ls -lthd --time-style=+%s mme*
// cmdStr := fmt.Sprintf("cd %s && ls -lthd --time-style=+%%s %s", path, searchStr)
// 是否远程客户端读取
if sshClient == nil {
resultStr, err := cmd.Execf(cmdStr)
if err != nil {
logger.Errorf("Ne FileList Path: %s, Search: %s, Error:%s", path, search, err.Error())
return totalSize, rows, err
return rows, err
}
rowStr = resultStr
} else {
resultStr, err := sshClient.RunCMD(cmdStr)
if err != nil {
logger.Errorf("Ne FileList Path: %s, Search: %s, Error:%s", path, search, err.Error())
return totalSize, rows, err
return rows, err
}
rowStr = resultStr
}
// 遍历组装
rowStrList := strings.Split(rowStr, "\n")
for i, rowStr := range rowStrList {
for _, rowStr := range rowStrList {
if rowStr == "" {
continue
}
// 使用空格对字符串进行切割
fields := strings.Fields(rowStr)
// 无查询过滤会有total总计
if i == 0 && searchStr == "" {
totalSize = fields[1]
continue
}
// 拆分不足7位跳过
if len(fields) != 7 {
continue
@@ -83,6 +79,14 @@ func FileList(sshClient *ConnSSH, path, search string) (string, []FileListRow, e
fileType = "symlink"
}
// 文件名
fileName := fields[6]
if fileName == "." {
continue
} else if strings.HasPrefix(fileName, "./") {
fileName = strings.TrimPrefix(fileName, "./")
}
// 提取各个字段的值
rows = append(rows, FileListRow{
FileMode: fileMode,
@@ -92,8 +96,8 @@ func FileList(sshClient *ConnSSH, path, search string) (string, []FileListRow, e
Group: fields[3],
Size: fields[4],
ModifiedTime: parse.Number(fields[5]),
FileName: fields[6],
FileName: fileName,
})
}
return totalSize, rows, nil
return rows, nil
}

View File

@@ -5,8 +5,7 @@ import (
"os"
"path/filepath"
"nms_cxy/src/framework/logger"
"be.ems/src/framework/logger"
gosftp "github.com/pkg/sftp"
)
@@ -61,7 +60,7 @@ func (s *SSHClientSFTP) CopyDirRemoteToLocal(remoteDir, localDir string) error {
return nil
}
// CopyDirRemoteToLocal 复制目录-本地到远程
// CopyDirLocalToRemote 复制目录-本地到远程
func (s *SSHClientSFTP) CopyDirLocalToRemote(localDir, remoteDir string) error {
// 遍历本地目录中的文件和子目录并复制到远程
err := filepath.Walk(localDir, func(localPath string, info os.FileInfo, err error) error {
@@ -95,7 +94,7 @@ func (s *SSHClientSFTP) CopyDirLocalToRemote(localDir, remoteDir string) error {
return nil
}
// CopyDirRemoteToLocal 复制文件-远程到本地
// CopyFileRemoteToLocal 复制文件-远程到本地
func (s *SSHClientSFTP) CopyFileRemoteToLocal(remotePath, localPath string) error {
if err := os.MkdirAll(filepath.Dir(localPath), 0775); err != nil {
return err
@@ -125,7 +124,7 @@ func (s *SSHClientSFTP) CopyFileRemoteToLocal(remotePath, localPath string) erro
return nil
}
// CopyDirRemoteToLocal 复制文件-本地到远程
// CopyFileLocalToRemote 复制文件-本地到远程
func (s *SSHClientSFTP) CopyFileLocalToRemote(localPath, remotePath string) error {
// 打开本地文件
localFile, err := os.Open(localPath)

View File

@@ -7,9 +7,8 @@ import (
"strings"
"time"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/cmd"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/cmd"
gosftp "github.com/pkg/sftp"
gossh "golang.org/x/crypto/ssh"
)
@@ -213,11 +212,14 @@ func (c *ConnSSH) SendToAuthorizedKeys() error {
if err != nil {
return err
}
// "sudo mkdir -p ~/.ssh && sudo chown omcuser:omcuser ~/.ssh && sudo chmod 700 ~/.ssh"
// "sudo touch ~/.ssh/authorized_keys && sudo chown omcuser:omcuser ~/.ssh/authorized_keys && sudo chmod 600 ~/.ssh/authorized_keys"
// "echo 'ssh-rsa AAAAB3= pc-host\n' | sudo tee -a ~/.ssh/authorized_keys"
authorizedKeysEntry := fmt.Sprintln(strings.TrimSpace(publicKey))
cmdStrArr := []string{
fmt.Sprintf("sudo mkdir -p /home/%s/.ssh && sudo chown %s:%s /home/%s/.ssh && sudo chmod 700 /home/%s/.ssh", c.User, c.User, c.User, c.User, c.User),
fmt.Sprintf("sudo touch /home/%s/.ssh/authorized_keys && sudo chown %s:%s /home/%s/.ssh/authorized_keys && sudo chmod 600 /home/%s/.ssh/authorized_keys", c.User, c.User, c.User, c.User, c.User),
fmt.Sprintf("echo '%s' | sudo tee -a /home/%s/.ssh/authorized_keys", authorizedKeysEntry, c.User),
fmt.Sprintf("sudo mkdir -p ~/.ssh && sudo chown %s:%s ~/.ssh && sudo chmod 700 ~/.ssh", c.User, c.User),
fmt.Sprintf("sudo touch ~/.ssh/authorized_keys && sudo chown %s:%s ~/.ssh/authorized_keys && sudo chmod 600 ~/.ssh/authorized_keys", c.User, c.User),
fmt.Sprintf("echo '%s' | sudo tee -a ~/.ssh/authorized_keys", authorizedKeysEntry),
}
_, err = c.RunCMD(strings.Join(cmdStrArr, " && "))
if err != nil {

View File

@@ -5,14 +5,14 @@ import (
"fmt"
"time"
"nms_cxy/src/framework/config"
cachekeyConstants "nms_cxy/src/framework/constants/cachekey"
tokenConstants "nms_cxy/src/framework/constants/token"
"nms_cxy/src/framework/logger"
redisCahe "nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/generate"
"nms_cxy/src/framework/utils/machine"
"nms_cxy/src/framework/vo"
"be.ems/src/framework/config"
cachekeyConstants "be.ems/src/framework/constants/cachekey"
tokenConstants "be.ems/src/framework/constants/token"
"be.ems/src/framework/logger"
redisCahe "be.ems/src/framework/redis"
"be.ems/src/framework/utils/generate"
"be.ems/src/framework/utils/machine"
"be.ems/src/framework/vo"
jwt "github.com/golang-jwt/jwt/v5"
)

View File

@@ -1,6 +1,6 @@
package vo
import systemModel "nms_cxy/src/modules/system/model"
import systemModel "be.ems/src/modules/system/model"
// LoginUser 登录用户身份权限信息对象
type LoginUser struct {

View File

@@ -1,7 +1,7 @@
package result
import (
constResult "nms_cxy/src/framework/constants/result"
constResult "be.ems/src/framework/constants/result"
)
// CodeMsg 响应结果

View File

@@ -1,6 +1,6 @@
package vo
import systemModel "nms_cxy/src/modules/system/model"
import systemModel "be.ems/src/modules/system/model"
// TreeSelect 树结构实体类
type TreeSelect struct {

View File

@@ -3,16 +3,15 @@ package libfeatures
import (
"fmt"
libConf "nms_cxy/lib/core/conf"
libGlobal "nms_cxy/lib/global"
libConfig "nms_cxy/omc/config"
libConf "be.ems/lib/core/conf"
libGlobal "be.ems/lib/global"
libConfig "be.ems/restagent/config"
"github.com/spf13/viper"
)
// BuildInfo 程序-V查看编译版本号信息
func BuildInfo() string {
return fmt.Sprintf("OMC Version: %s\n%s\n%s\n\n", libGlobal.Version, libGlobal.BuildTime, libGlobal.GoVer)
return fmt.Sprintf("OMC restagent version: %s\n%s\n%s\n\n", libGlobal.Version, libGlobal.BuildTime, libGlobal.GoVer)
}
// ConfigRead 指定配置文件读取

View File

@@ -1,4 +1,4 @@
# 外层 lib 和 features 粘合层
- config.go 配置合并: omc.yaml 文件内容,主要是数据库配置
- config.go 配置合并: restagent.yaml 文件内容,主要是数据库配置

View File

@@ -1,10 +1,10 @@
package chart
import (
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/middleware"
"nms_cxy/src/framework/middleware/collectlogs"
"nms_cxy/src/modules/chart/controller"
"be.ems/src/framework/logger"
"be.ems/src/framework/middleware"
"be.ems/src/framework/middleware/collectlogs"
"be.ems/src/modules/chart/controller"
"github.com/gin-gonic/gin"
)
@@ -13,10 +13,8 @@ import (
func Setup(router *gin.Engine) {
logger.Infof("开始加载 ====> chart 模块路由")
chartGroup := router.Group("/chart")
// 关系图
chartGraphGroup := chartGroup.Group("/graph")
// G6关系图
chartGraphGroup := router.Group("/chart/graph")
{
chartGraphGroup.GET("",
middleware.PreAuthorize(nil),

View File

@@ -1,18 +1,17 @@
package controller
import (
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/vo/result"
chartService "nms_cxy/src/modules/chart/service"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/chart/service"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
// 实例化控制层 ChartGraphController 结构体
var NewChartGraph = &ChartGraphController{
chartGraphService: chartService.NewChartGraphImpl,
chartGraphService: service.NewChartGraph,
}
// G6关系图
@@ -20,7 +19,7 @@ var NewChartGraph = &ChartGraphController{
// PATH /graph
type ChartGraphController struct {
// G6关系图数据表服务
chartGraphService chartService.IChartGraph
chartGraphService *service.ChartGraph
}
// 获取关系图组名

View File

@@ -1,31 +1,32 @@
package model
// ChartGraph G6关系图数据对象 chart_graph
// ChartGraph 图表-G6关系图数据对象 chart_graph
type ChartGraph struct {
RowID int64 `json:"rowId,omitempty" gorm:"column:row_id;primaryKey;autoIncrement"` // 记录ID
RowType string `json:"rowType,omitempty" gorm:"column:row_type"` // 记录类型(node/edge/combo)
RowGroup string `json:"rowGroup,omitempty" gorm:"column:row_group"` // 记录组名
ID string `json:"id,omitempty" gorm:"column:id"` // 元素ID
Type string `json:"type,omitempty" gorm:"column:type"` // node/combo 类型
Depth int `json:"depth,omitempty" gorm:"column:depth"` // node/combo 深度
X float64 `json:"x,omitempty" gorm:"column:x"` // node/combo 横向坐标
Y float64 `json:"y,omitempty" gorm:"column:y"` // node/combo 纵向坐标
Size string `json:"size,omitempty" gorm:"column:size"` // node/combo 大小-JSON数组
Icon string `json:"icon,omitempty" gorm:"column:icon"` // node-部分类型支持图标JSON配置
Img string `json:"img,omitempty" gorm:"column:img"` // node-img 图片
ClipCfg string `json:"clipCfg,omitempty" gorm:"column:clip_cfg"` // node-img 图片裁剪JSON配置
Direction string `json:"direction,omitempty" gorm:"column:direction"` // node-triangle 三角形的方向(up/down/left/right)
Source string `json:"source,omitempty" gorm:"column:source"` // edge-边起始
Target string `json:"target,omitempty" gorm:"column:target"` // edge-边目标
ComboID string `json:"combo_id,omitempty" gorm:"column:combo_id"` // combo-分组
Padding string `json:"padding,omitempty" gorm:"column:padding"` // combo-JSON分组内边距
ParentID string `json:"parentId,omitempty" gorm:"column:parent_id"` // combo-父级分组
Children string `json:"children,omitempty" gorm:"column:children"` // combo-JSON分组内含元素
Style string `json:"style,omitempty" gorm:"column:style"` // 元素样式-JONS配置
Label string `json:"label,omitempty" gorm:"column:label"` // 标签文本
LabelCfg string `json:"labelCfg,omitempty" gorm:"column:label_cfg"` // 标签文本-JSON配置
RowType string `json:"rowType" gorm:"row_type"` // 记录类型
RowGroup string `json:"rowGroup" gorm:"row_group"` // 记录组名
ID string `json:"id" gorm:"id"` // 元素ID
Type string `json:"type" gorm:"type"` // node/combo 类型
Depth int64 `json:"depth" gorm:"depth"` // node/combo 深度
X float64 `json:"x" gorm:"x"` // node/combo 横向坐标
Y float64 `json:"y" gorm:"y"` // node/combo 纵向坐标
Size string `json:"size" gorm:"size"` // node/combo 大小-JSON数组
Icon string `json:"icon" gorm:"icon"` // node-部分类型支持图标JSON配置
Img string `json:"img" gorm:"img"` // node-img 图片
ClipCfg string `json:"clipCfg" gorm:"clip_cfg"` // node-img 图片裁剪JSON配置
Direction string `json:"direction" gorm:"direction"` // node-triangle 三角形的方向
Source string `json:"source" gorm:"source"` // edge-边起始
Target string `json:"target" gorm:"target"` // edge-边目标
ComboId string `json:"comboId" gorm:"combo_id"` // combo-分组
Padding string `json:"padding" gorm:"padding"` // combo-JSON分组内边距
ParentId string `json:"parentId" gorm:"parent_id"` // combo-父级分组
Children string `json:"children" gorm:"children"` // combo-JSON分组内含元素
Style string `json:"style" gorm:"style"` // 元素样式-JONS配置
Label string `json:"label" gorm:"label"` // 标签文本
LabelCfg string `json:"labelCfg" gorm:"label_cfg"` // 标签文本-JSON配置
}
func (ChartGraph) TableName() string {
// TableName 表名称
func (*ChartGraph) TableName() string {
return "chart_graph"
}

View File

@@ -1,21 +1,194 @@
package repository
import "nms_cxy/src/modules/chart/model"
import (
"strings"
// G6关系图数据 数据层接口
type IChartGraph interface {
// SelectPage 根据条件分页查询字典类型
SelectPage(query map[string]any) map[string]any
"be.ems/src/framework/datasource"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/utils/repo"
"be.ems/src/modules/chart/model"
)
// SelectList 根据实体查询
SelectList(graph model.ChartGraph) []model.ChartGraph
// 实例化数据层 ChartGraph 结构体
var NewChartGraph = &ChartGraph{
selectSql: `select
row_id, row_type, row_group,
id, type, depth, x, y, size, icon, img,
clip_cfg, direction,
source, target, combo_id,
padding, parent_id, children,
style, label, label_cfg
from chart_graph`,
// SelectGroup 查询组名
SelectGroup() []string
// Insert 批量添加
Inserts(graphs []model.ChartGraph) int64
// Delete 删除组数据
DeleteGroup(rowGroup string) int64
resultMap: map[string]string{
"row_id": "RowID",
"row_type": "RowType",
"row_group": "RowGroup",
"id": "ID",
"type": "Type",
"depth": "Depth",
"x": "X",
"y": "Y",
"size": "Size",
"icon": "Icon",
"img": "Img",
"clip_cfg": "ClipCfg",
"direction": "Direction",
"source": "Source",
"target": "Target",
"combo_id": "ComboID",
"padding": "Padding",
"parent_id": "ParentID",
"children": "Children",
"style": "Style",
"label": "Label",
"label_cfg": "LabelCfg",
},
}
// ChartGraph G6关系图数据表 数据层处理
type ChartGraph struct {
// 查询视图对象SQL
selectSql string
// 结果字段与实体映射
resultMap map[string]string
}
// convertResultRows 将结果记录转实体结果组
func (r *ChartGraph) convertResultRows(rows []map[string]any) []model.ChartGraph {
arr := make([]model.ChartGraph, 0)
for _, row := range rows {
item := model.ChartGraph{}
for key, value := range row {
if keyMapper, ok := r.resultMap[key]; ok {
repo.SetFieldValue(&item, keyMapper, value)
}
}
arr = append(arr, item)
}
return arr
}
// SelectPage 根据条件分页查询字典类型
func (r *ChartGraph) SelectPage(query map[string]any) map[string]any {
// 查询条件拼接
var conditions []string
var params []any
if v, ok := query["rowType"]; ok && v != "" {
conditions = append(conditions, "row_type = ?")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["rowGroup"]; ok && v != "" {
conditions = append(conditions, "row_group = ?")
params = append(params, strings.Trim(v.(string), " "))
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
result := map[string]any{
"total": 0,
"rows": []model.ChartGraph{},
}
// 查询数量 长度为0直接返回
totalSql := "select count(1) as 'total' from chart_graph"
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
if err != nil {
logger.Errorf("total err => %v", err)
return result
}
total := parse.Number(totalRows[0]["total"])
if total == 0 {
return result
} else {
result["total"] = total
}
// 分页
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
pageSql := " limit ?,? "
params = append(params, pageNum*pageSize)
params = append(params, pageSize)
// 查询数据
querySql := r.selectSql + whereSql + pageSql
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
return result
}
// 转换实体
result["rows"] = r.convertResultRows(results)
return result
}
// SelectList 根据实体查询
func (r *ChartGraph) SelectList(graph model.ChartGraph) []model.ChartGraph {
// 查询条件拼接
var conditions []string
var params []any
if graph.RowType != "" {
conditions = append(conditions, "row_type = ?")
params = append(params, graph.RowType)
}
if graph.RowGroup != "" {
conditions = append(conditions, "row_group = ?")
params = append(params, graph.RowGroup)
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
// 查询数据
querySql := r.selectSql + whereSql + " order by depth asc "
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
}
// 转换实体
return r.convertResultRows(results)
}
// SelectGroup 查询组名
func (r *ChartGraph) SelectGroup() []string {
rows := []string{}
// 查询数量 长度为0直接返回
querySql := "select row_group as 'str' from chart_graph GROUP BY row_group"
strRows, err := datasource.RawDB("", querySql, nil)
if err != nil {
logger.Errorf("Query err => %v", err)
return rows
}
for _, v := range strRows {
rows = append(rows, v["str"].(string))
}
return rows
}
// Insert 批量添加
func (r *ChartGraph) Inserts(graphs []model.ChartGraph) int64 {
tx := datasource.DefaultDB().CreateInBatches(graphs, 2000)
if err := tx.Error; err != nil {
logger.Errorf("CreateInBatches err => %v", err)
}
return tx.RowsAffected
}
// Delete 删除组数据
func (r *ChartGraph) DeleteGroup(rowGroup string) int64 {
tx := datasource.DefaultDB().Where("row_group = ?", rowGroup).Delete(&model.ChartGraph{})
if err := tx.Error; err != nil {
logger.Errorf("Delete err => %v", err)
}
return tx.RowsAffected
}

View File

@@ -1,194 +0,0 @@
package repository
import (
"strings"
"nms_cxy/src/framework/datasource"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/utils/repo"
"nms_cxy/src/modules/chart/model"
)
// 实例化数据层 NewChartGraphImpl 结构体
var NewChartGraphImpl = &ChartGraphImpl{
selectSql: `select
row_id, row_type, row_group,
id, type, depth, x, y, size, icon, img,
clip_cfg, direction,
source, target, combo_id,
padding, parent_id, children,
style, label, label_cfg
from chart_graph`,
resultMap: map[string]string{
"row_id": "RowID",
"row_type": "RowType",
"row_group": "RowGroup",
"id": "ID",
"type": "Type",
"depth": "Depth",
"x": "X",
"y": "Y",
"size": "Size",
"icon": "Icon",
"img": "Img",
"clip_cfg": "ClipCfg",
"direction": "Direction",
"source": "Source",
"target": "Target",
"combo_id": "ComboID",
"padding": "Padding",
"parent_id": "ParentID",
"children": "Children",
"style": "Style",
"label": "Label",
"label_cfg": "LabelCfg",
},
}
// ChartGraphImpl G6关系图数据表 数据层处理
type ChartGraphImpl struct {
// 查询视图对象SQL
selectSql string
// 结果字段与实体映射
resultMap map[string]string
}
// convertResultRows 将结果记录转实体结果组
func (r *ChartGraphImpl) convertResultRows(rows []map[string]any) []model.ChartGraph {
arr := make([]model.ChartGraph, 0)
for _, row := range rows {
item := model.ChartGraph{}
for key, value := range row {
if keyMapper, ok := r.resultMap[key]; ok {
repo.SetFieldValue(&item, keyMapper, value)
}
}
arr = append(arr, item)
}
return arr
}
// SelectPage 根据条件分页查询字典类型
func (r *ChartGraphImpl) SelectPage(query map[string]any) map[string]any {
// 查询条件拼接
var conditions []string
var params []any
if v, ok := query["rowType"]; ok && v != "" {
conditions = append(conditions, "row_type = ?")
params = append(params, strings.Trim(v.(string), " "))
}
if v, ok := query["rowGroup"]; ok && v != "" {
conditions = append(conditions, "row_group = ?")
params = append(params, strings.Trim(v.(string), " "))
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
result := map[string]any{
"total": 0,
"rows": []model.ChartGraph{},
}
// 查询数量 长度为0直接返回
totalSql := "select count(1) as 'total' from chart_graph"
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
if err != nil {
logger.Errorf("total err => %v", err)
return result
}
total := parse.Number(totalRows[0]["total"])
if total == 0 {
return result
} else {
result["total"] = total
}
// 分页
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
pageSql := " limit ?,? "
params = append(params, pageNum*pageSize)
params = append(params, pageSize)
// 查询数据
querySql := r.selectSql + whereSql + pageSql
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
return result
}
// 转换实体
result["rows"] = r.convertResultRows(results)
return result
}
// SelectList 根据实体查询
func (r *ChartGraphImpl) SelectList(graph model.ChartGraph) []model.ChartGraph {
// 查询条件拼接
var conditions []string
var params []any
if graph.RowType != "" {
conditions = append(conditions, "row_type = ?")
params = append(params, graph.RowType)
}
if graph.RowGroup != "" {
conditions = append(conditions, "row_group = ?")
params = append(params, graph.RowGroup)
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
// 查询数据
querySql := r.selectSql + whereSql + " order by depth asc "
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
}
// 转换实体
return r.convertResultRows(results)
}
// SelectGroup 查询组名
func (r *ChartGraphImpl) SelectGroup() []string {
rows := []string{}
// 查询数量 长度为0直接返回
querySql := "select row_group as 'str' from chart_graph GROUP BY row_group"
strRows, err := datasource.RawDB("", querySql, nil)
if err != nil {
logger.Errorf("Query err => %v", err)
return rows
}
for _, v := range strRows {
rows = append(rows, v["str"].(string))
}
return rows
}
// Insert 批量添加
func (r *ChartGraphImpl) Inserts(graphs []model.ChartGraph) int64 {
tx := datasource.DefaultDB().CreateInBatches(graphs, 2000)
if err := tx.Error; err != nil {
logger.Errorf("CreateInBatches err => %v", err)
}
return tx.RowsAffected
}
// Delete 删除组数据
func (r *ChartGraphImpl) DeleteGroup(rowGroup string) int64 {
tx := datasource.DefaultDB().Where("row_group = ?", rowGroup).Delete(&model.ChartGraph{})
if err := tx.Error; err != nil {
logger.Errorf("Delete err => %v", err)
}
return tx.RowsAffected
}

View File

@@ -1,16 +1,359 @@
package service
// G6关系图数据 服务层接口
type IChartGraph interface {
// SelectGroup 查询组名
SelectGroup() []string
import (
"encoding/json"
"strings"
// LoadData 查询所组图数据
LoadData(rowGroup, rowType string) map[string]any
"be.ems/src/framework/utils/parse"
"be.ems/src/modules/chart/model"
"be.ems/src/modules/chart/repository"
)
// SaveData 添加组图数据
SaveData(rowGroup string, data map[string]any) int64
// DeleteGroup 删除所组图数据
DeleteGroup(rowGroup string) int64
// 实例化服务层 ChartGraph 结构体
var NewChartGraph = &ChartGraph{
graphRepository: repository.NewChartGraph,
}
// ChartGraph G6关系图数据表 服务层处理
type ChartGraph struct {
// G6关系图数据服务
graphRepository *repository.ChartGraph
}
// SelectGroup 查询组名
func (s *ChartGraph) SelectGroup() []string {
return s.graphRepository.SelectGroup()
}
// LoadData 查询所组图数据
func (s *ChartGraph) LoadData(rowGroup, rowType string) map[string]any {
// 查询数据
graph := model.ChartGraph{
RowGroup: rowGroup,
}
if rowType != "" {
graph.RowType = rowType
}
data := s.graphRepository.SelectList(graph)
// 数据项
nodes := []map[string]any{}
edges := []map[string]any{}
combos := []map[string]any{}
for _, v := range data {
if v.RowType == "node" {
nodes = append(nodes, s.loadNode(v))
}
if v.RowType == "edge" {
edges = append(edges, s.loadEdge(v))
}
if v.RowType == "combo" {
combos = append(combos, s.loadCombo(v))
}
}
return map[string]any{
"nodes": nodes,
"edges": edges,
"combos": combos,
}
}
// loadNode 图数据Node
func (s *ChartGraph) loadNode(v model.ChartGraph) map[string]any {
node := map[string]any{
"id": v.ID,
"comboId": v.ComboId,
"x": v.X,
"y": v.Y,
"type": v.Type,
"depth": v.Depth,
}
// 元素样式
style := map[string]any{}
if len(v.Style) > 7 {
json.Unmarshal([]byte(v.Style), &style)
}
node["style"] = style
// 元素大小
if strings.Contains(v.Size, "[") {
sizeArr := []int64{}
json.Unmarshal([]byte(v.Size), &sizeArr)
node["size"] = sizeArr
} else {
node["size"] = parse.Number(v.Size)
}
// 标签文本
node["label"] = v.Label
labelCfg := map[string]any{}
if len(v.LabelCfg) > 7 {
json.Unmarshal([]byte(v.LabelCfg), &labelCfg)
}
node["labelCfg"] = labelCfg
// 三角形属性
if v.Type == "triangle" {
node["direction"] = v.Direction
}
// 图片属性
if strings.Index(v.Type, "image") == 0 {
node["img"] = v.Img
clipCfg := map[string]any{}
if len(v.ClipCfg) > 7 {
json.Unmarshal([]byte(v.ClipCfg), &clipCfg)
}
node["clipCfg"] = clipCfg
}
// 图标属性
if v.Icon != "" {
icon := map[string]any{}
if len(v.Icon) > 7 {
json.Unmarshal([]byte(v.Icon), &icon)
}
node["icon"] = icon
}
return node
}
// loadEdge 图数据Edge
func (s *ChartGraph) loadEdge(v model.ChartGraph) map[string]any {
edge := map[string]any{
"id": v.ID,
"source": v.Source,
"target": v.Target,
"type": v.Type,
}
// 元素样式
style := map[string]any{}
if len(v.Style) > 7 {
json.Unmarshal([]byte(v.Style), &style)
}
edge["style"] = style
// 标签文本
edge["label"] = v.Label
labelCfg := map[string]any{}
if len(v.LabelCfg) > 7 {
json.Unmarshal([]byte(v.LabelCfg), &labelCfg)
}
edge["labelCfg"] = labelCfg
return edge
}
// loadCombo 图数据Combo
func (s *ChartGraph) loadCombo(v model.ChartGraph) map[string]any {
combo := map[string]any{
"id": v.ID,
"x": v.X,
"y": v.Y,
"type": v.Type,
"depth": v.Depth,
}
// 元素样式
style := map[string]any{}
if len(v.Style) > 7 {
json.Unmarshal([]byte(v.Style), &style)
}
combo["style"] = style
// 元素大小
if strings.Contains(v.Size, "[") {
sizeArr := []int64{}
json.Unmarshal([]byte(v.Size), &sizeArr)
combo["size"] = sizeArr
} else {
combo["size"] = parse.Number(v.Size)
}
// 元素内边距
if strings.Contains(v.Padding, "[") {
paddingArr := []int64{}
json.Unmarshal([]byte(v.Padding), &paddingArr)
combo["padding"] = paddingArr
} else {
combo["padding"] = parse.Number(v.Padding)
}
// 标签文本
combo["label"] = v.Label
labelCfg := map[string]any{}
if len(v.LabelCfg) > 7 {
json.Unmarshal([]byte(v.LabelCfg), &labelCfg)
}
combo["labelCfg"] = labelCfg
// 分组内元素
if v.Children != "" {
children := []map[string]any{}
if len(v.Children) > 7 {
json.Unmarshal([]byte(v.Children), &children)
}
combo["children"] = children
}
return combo
}
// SaveData 添加组图数据
func (s *ChartGraph) SaveData(rowGroup string, data map[string]any) int64 {
graphs := []model.ChartGraph{}
nodes := data["nodes"].([]map[string]any)
graphNodes := s.saveNode(rowGroup, nodes)
graphs = append(graphs, graphNodes...)
edges := data["edges"].([]map[string]any)
graphEdges := s.saveEdge(rowGroup, edges)
graphs = append(graphs, graphEdges...)
combos := data["combos"].([]map[string]any)
graphCombos := s.saveCombo(rowGroup, combos)
graphs = append(graphs, graphCombos...)
// 删除组数据后插入
if len(graphs) > 0 {
s.graphRepository.DeleteGroup(rowGroup)
}
return s.graphRepository.Inserts(graphs)
}
// saveNode 图数据Node
func (s *ChartGraph) saveNode(rowGroup string, nodes []map[string]any) []model.ChartGraph {
var graphs []model.ChartGraph
for _, v := range nodes {
node := model.ChartGraph{
RowType: "node",
RowGroup: rowGroup,
ID: v["id"].(string),
X: v["x"].(float64),
Y: v["y"].(float64),
Type: v["type"].(string),
}
if comboId, ok := v["comboId"]; ok && comboId != nil {
node.ComboId = comboId.(string)
}
if depth, ok := v["depth"]; ok && depth != nil {
node.Depth = int64(depth.(float64))
}
if styleByte, err := json.Marshal(v["style"]); err == nil {
node.Style = string(styleByte)
}
// 元素大小
if sizeByte, err := json.Marshal(v["size"]); err == nil {
node.Size = string(sizeByte)
}
// 标签文本
if label, ok := v["label"]; ok && label != nil {
node.Label = label.(string)
}
if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil {
node.LabelCfg = string(labelCfgByte)
}
// 三角形属性
if direction, ok := v["direction"]; ok && direction != nil && node.Type == "triangle" {
node.Direction = direction.(string)
}
// 图片属性
if img, ok := v["img"]; ok && img != nil {
node.Img = img.(string)
if clipCfgByte, err := json.Marshal(v["clipCfg"]); err == nil {
node.ClipCfg = string(clipCfgByte)
}
}
// 图标属性
if icon, ok := v["icon"]; ok && icon != nil {
if iconByte, err := json.Marshal(icon); err == nil {
node.Icon = string(iconByte)
}
}
graphs = append(graphs, node)
}
return graphs
}
// saveEdge 图数据Edge
func (s *ChartGraph) saveEdge(rowGroup string, edges []map[string]any) []model.ChartGraph {
var graphs []model.ChartGraph
for _, v := range edges {
edge := model.ChartGraph{
RowType: "edge",
RowGroup: rowGroup,
ID: v["id"].(string),
Source: v["source"].(string),
Target: v["target"].(string),
Type: v["type"].(string),
}
if styleByte, err := json.Marshal(v["style"]); err == nil {
edge.Style = string(styleByte)
}
// 标签文本
if label, ok := v["label"]; ok && label != nil {
edge.Label = label.(string)
}
if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil {
edge.LabelCfg = string(labelCfgByte)
}
graphs = append(graphs, edge)
}
return graphs
}
// saveCombo 图数据Combo
func (s *ChartGraph) saveCombo(rowGroup string, combos []map[string]any) []model.ChartGraph {
var graphs []model.ChartGraph
for _, v := range combos {
combo := model.ChartGraph{
RowType: "combo",
RowGroup: rowGroup,
ID: v["id"].(string),
X: v["x"].(float64),
Y: v["y"].(float64),
Type: v["type"].(string),
}
if depth, ok := v["depth"]; ok && depth != nil {
combo.Depth = int64(depth.(float64))
}
if styleByte, err := json.Marshal(v["style"]); err == nil {
combo.Style = string(styleByte)
}
if paddingByte, err := json.Marshal(v["padding"]); err == nil {
combo.Padding = string(paddingByte)
}
if childrenByte, err := json.Marshal(v["children"]); err == nil {
combo.Children = string(childrenByte)
}
// 元素大小
if sizeByte, err := json.Marshal(v["size"]); err == nil {
combo.Size = string(sizeByte)
}
// 标签文本
if label, ok := v["label"]; ok && label != nil {
combo.Label = label.(string)
}
if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil {
combo.LabelCfg = string(labelCfgByte)
}
graphs = append(graphs, combo)
}
return graphs
}
// Delete 删除所组图数据
func (s *ChartGraph) DeleteGroup(rowGroup string) int64 {
return s.graphRepository.DeleteGroup(rowGroup)
}

View File

@@ -1,360 +0,0 @@
package service
import (
"strings"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/modules/chart/model"
chartRepository "nms_cxy/src/modules/chart/repository"
"github.com/goccy/go-json"
)
// 实例化服务层 ChartGraphImpl 结构体
var NewChartGraphImpl = &ChartGraphImpl{
graphRepository: chartRepository.NewChartGraphImpl,
}
// ChartGraphImpl G6关系图数据表 服务层处理
type ChartGraphImpl struct {
// G6关系图数据服务
graphRepository chartRepository.IChartGraph
}
// SelectGroup 查询组名
func (s *ChartGraphImpl) SelectGroup() []string {
return s.graphRepository.SelectGroup()
}
// LoadData 查询所组图数据
func (s *ChartGraphImpl) LoadData(rowGroup, rowType string) map[string]any {
// 查询数据
graph := model.ChartGraph{
RowGroup: rowGroup,
}
if rowType != "" {
graph.RowType = rowType
}
data := s.graphRepository.SelectList(graph)
// 数据项
nodes := []map[string]any{}
edges := []map[string]any{}
combos := []map[string]any{}
for _, v := range data {
if v.RowType == "node" {
nodes = append(nodes, s.loadNode(v))
}
if v.RowType == "edge" {
edges = append(edges, s.loadEdge(v))
}
if v.RowType == "combo" {
combos = append(combos, s.loadCombo(v))
}
}
return map[string]any{
"nodes": nodes,
"edges": edges,
"combos": combos,
}
}
// loadNode 图数据Node
func (s *ChartGraphImpl) loadNode(v model.ChartGraph) map[string]any {
node := map[string]any{
"id": v.ID,
"comboId": v.ComboID,
"x": v.X,
"y": v.Y,
"type": v.Type,
"depth": v.Depth,
}
// 元素样式
style := map[string]any{}
if len(v.Style) > 7 {
json.Unmarshal([]byte(v.Style), &style)
}
node["style"] = style
// 元素大小
if strings.Contains(v.Size, "[") {
sizeArr := []int64{}
json.Unmarshal([]byte(v.Size), &sizeArr)
node["size"] = sizeArr
} else {
node["size"] = parse.Number(v.Size)
}
// 标签文本
node["label"] = v.Label
labelCfg := map[string]any{}
if len(v.LabelCfg) > 7 {
json.Unmarshal([]byte(v.LabelCfg), &labelCfg)
}
node["labelCfg"] = labelCfg
// 三角形属性
if v.Type == "triangle" {
node["direction"] = v.Direction
}
// 图片属性
if strings.Index(v.Type, "image") == 0 {
node["img"] = v.Img
clipCfg := map[string]any{}
if len(v.ClipCfg) > 7 {
json.Unmarshal([]byte(v.ClipCfg), &clipCfg)
}
node["clipCfg"] = clipCfg
}
// 图标属性
if v.Icon != "" {
icon := map[string]any{}
if len(v.Icon) > 7 {
json.Unmarshal([]byte(v.Icon), &icon)
}
node["icon"] = icon
}
return node
}
// loadEdge 图数据Edge
func (s *ChartGraphImpl) loadEdge(v model.ChartGraph) map[string]any {
edge := map[string]any{
"id": v.ID,
"source": v.Source,
"target": v.Target,
"type": v.Type,
}
// 元素样式
style := map[string]any{}
if len(v.Style) > 7 {
json.Unmarshal([]byte(v.Style), &style)
}
edge["style"] = style
// 标签文本
edge["label"] = v.Label
labelCfg := map[string]any{}
if len(v.LabelCfg) > 7 {
json.Unmarshal([]byte(v.LabelCfg), &labelCfg)
}
edge["labelCfg"] = labelCfg
return edge
}
// loadCombo 图数据Combo
func (s *ChartGraphImpl) loadCombo(v model.ChartGraph) map[string]any {
combo := map[string]any{
"id": v.ID,
"x": v.X,
"y": v.Y,
"type": v.Type,
"depth": v.Depth,
}
// 元素样式
style := map[string]any{}
if len(v.Style) > 7 {
json.Unmarshal([]byte(v.Style), &style)
}
combo["style"] = style
// 元素大小
if strings.Contains(v.Size, "[") {
sizeArr := []int64{}
json.Unmarshal([]byte(v.Size), &sizeArr)
combo["size"] = sizeArr
} else {
combo["size"] = parse.Number(v.Size)
}
// 元素内边距
if strings.Contains(v.Padding, "[") {
paddingArr := []int64{}
json.Unmarshal([]byte(v.Padding), &paddingArr)
combo["padding"] = paddingArr
} else {
combo["padding"] = parse.Number(v.Padding)
}
// 标签文本
combo["label"] = v.Label
labelCfg := map[string]any{}
if len(v.LabelCfg) > 7 {
json.Unmarshal([]byte(v.LabelCfg), &labelCfg)
}
combo["labelCfg"] = labelCfg
// 分组内元素
if v.Children != "" {
children := []map[string]any{}
if len(v.Children) > 7 {
json.Unmarshal([]byte(v.Children), &children)
}
combo["children"] = children
}
return combo
}
// SaveData 添加组图数据
func (s *ChartGraphImpl) SaveData(rowGroup string, data map[string]any) int64 {
graphs := []model.ChartGraph{}
nodes := data["nodes"].([]map[string]any)
graphNodes := s.saveNode(rowGroup, nodes)
graphs = append(graphs, graphNodes...)
edges := data["edges"].([]map[string]any)
graphEdges := s.saveEdge(rowGroup, edges)
graphs = append(graphs, graphEdges...)
combos := data["combos"].([]map[string]any)
graphCombos := s.saveCombo(rowGroup, combos)
graphs = append(graphs, graphCombos...)
// 删除组数据后插入
if len(graphs) > 0 {
s.graphRepository.DeleteGroup(rowGroup)
}
return s.graphRepository.Inserts(graphs)
}
// saveNode 图数据Node
func (s *ChartGraphImpl) saveNode(rowGroup string, nodes []map[string]any) []model.ChartGraph {
var graphs []model.ChartGraph
for _, v := range nodes {
node := model.ChartGraph{
RowType: "node",
RowGroup: rowGroup,
ID: v["id"].(string),
X: v["x"].(float64),
Y: v["y"].(float64),
Type: v["type"].(string),
}
if comboId, ok := v["comboId"]; ok && comboId != nil {
node.ComboID = comboId.(string)
}
if depth, ok := v["depth"]; ok && depth != nil {
node.Depth = int(depth.(float64))
}
if styleByte, err := json.Marshal(v["style"]); err == nil {
node.Style = string(styleByte)
}
// 元素大小
if sizeByte, err := json.Marshal(v["size"]); err == nil {
node.Size = string(sizeByte)
}
// 标签文本
if label, ok := v["label"]; ok && label != nil {
node.Label = label.(string)
}
if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil {
node.LabelCfg = string(labelCfgByte)
}
// 三角形属性
if direction, ok := v["direction"]; ok && direction != nil && node.Type == "triangle" {
node.Direction = direction.(string)
}
// 图片属性
if img, ok := v["img"]; ok && img != nil {
node.Img = img.(string)
if clipCfgByte, err := json.Marshal(v["clipCfg"]); err == nil {
node.ClipCfg = string(clipCfgByte)
}
}
// 图标属性
if icon, ok := v["icon"]; ok && icon != nil {
if iconByte, err := json.Marshal(icon); err == nil {
node.Icon = string(iconByte)
}
}
graphs = append(graphs, node)
}
return graphs
}
// saveEdge 图数据Edge
func (s *ChartGraphImpl) saveEdge(rowGroup string, edges []map[string]any) []model.ChartGraph {
var graphs []model.ChartGraph
for _, v := range edges {
edge := model.ChartGraph{
RowType: "edge",
RowGroup: rowGroup,
ID: v["id"].(string),
Source: v["source"].(string),
Target: v["target"].(string),
Type: v["type"].(string),
}
if styleByte, err := json.Marshal(v["style"]); err == nil {
edge.Style = string(styleByte)
}
// 标签文本
if label, ok := v["label"]; ok && label != nil {
edge.Label = label.(string)
}
if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil {
edge.LabelCfg = string(labelCfgByte)
}
graphs = append(graphs, edge)
}
return graphs
}
// saveCombo 图数据Combo
func (s *ChartGraphImpl) saveCombo(rowGroup string, combos []map[string]any) []model.ChartGraph {
var graphs []model.ChartGraph
for _, v := range combos {
combo := model.ChartGraph{
RowType: "combo",
RowGroup: rowGroup,
ID: v["id"].(string),
X: v["x"].(float64),
Y: v["y"].(float64),
Type: v["type"].(string),
}
if depth, ok := v["depth"]; ok && depth != nil {
combo.Depth = int(depth.(float64))
}
if styleByte, err := json.Marshal(v["style"]); err == nil {
combo.Style = string(styleByte)
}
if paddingByte, err := json.Marshal(v["padding"]); err == nil {
combo.Padding = string(paddingByte)
}
if childrenByte, err := json.Marshal(v["children"]); err == nil {
combo.Children = string(childrenByte)
}
// 元素大小
if sizeByte, err := json.Marshal(v["size"]); err == nil {
combo.Size = string(sizeByte)
}
// 标签文本
if label, ok := v["label"]; ok && label != nil {
combo.Label = label.(string)
}
if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil {
combo.LabelCfg = string(labelCfgByte)
}
graphs = append(graphs, combo)
}
return graphs
}
// Delete 删除所组图数据
func (s *ChartGraphImpl) DeleteGroup(rowGroup string) int64 {
return s.graphRepository.DeleteGroup(rowGroup)
}

View File

@@ -1,9 +1,9 @@
package common
import (
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/middleware"
"nms_cxy/src/modules/common/controller"
"be.ems/src/framework/logger"
"be.ems/src/framework/middleware"
"be.ems/src/modules/common/controller"
"github.com/gin-gonic/gin"
)

View File

@@ -1,24 +1,23 @@
package controller
import (
"nms_cxy/src/framework/config"
commonConstants "nms_cxy/src/framework/constants/common"
tokenConstants "nms_cxy/src/framework/constants/token"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
tokenUtils "nms_cxy/src/framework/utils/token"
"nms_cxy/src/framework/vo"
"nms_cxy/src/framework/vo/result"
commonModel "nms_cxy/src/modules/common/model"
commonService "nms_cxy/src/modules/common/service"
systemService "nms_cxy/src/modules/system/service"
"be.ems/src/framework/config"
commonConstants "be.ems/src/framework/constants/common"
tokenConstants "be.ems/src/framework/constants/token"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
tokenUtils "be.ems/src/framework/utils/token"
"be.ems/src/framework/vo"
"be.ems/src/framework/vo/result"
commonModel "be.ems/src/modules/common/model"
commonService "be.ems/src/modules/common/service"
systemService "be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 AccountController 结构体
var NewAccount = &AccountController{
accountService: commonService.NewAccountImpl,
accountService: commonService.NewAccount,
sysLogLoginService: systemService.NewSysLogLoginImpl,
}
@@ -26,8 +25,7 @@ var NewAccount = &AccountController{
//
// PATH /
type AccountController struct {
// 账号身份操作服务
accountService commonService.IAccount
accountService *commonService.Account // 账号身份操作服务
// 系统登录访问
sysLogLoginService systemService.ISysLogLogin
}

View File

@@ -1,25 +1,24 @@
package controller
import (
adminConstants "nms_cxy/src/framework/constants/admin"
"nms_cxy/src/framework/constants/common"
tokenConstants "nms_cxy/src/framework/constants/token"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/machine"
"nms_cxy/src/framework/utils/regular"
tokenUtils "nms_cxy/src/framework/utils/token"
"nms_cxy/src/framework/vo"
"nms_cxy/src/framework/vo/result"
commonService "nms_cxy/src/modules/common/service"
systemService "nms_cxy/src/modules/system/service"
adminConstants "be.ems/src/framework/constants/admin"
"be.ems/src/framework/constants/common"
tokenConstants "be.ems/src/framework/constants/token"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/machine"
"be.ems/src/framework/utils/regular"
tokenUtils "be.ems/src/framework/utils/token"
"be.ems/src/framework/vo"
"be.ems/src/framework/vo/result"
commonService "be.ems/src/modules/common/service"
systemService "be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 BootloaderController 结构体
var NewBootloader = &BootloaderController{
accountService: commonService.NewAccountImpl,
accountService: commonService.NewAccount,
sysUserService: systemService.NewSysUserImpl,
}
@@ -27,8 +26,7 @@ var NewBootloader = &BootloaderController{
//
// PATH /bootloader
type BootloaderController struct {
// 账号身份操作服务
accountService commonService.IAccount
accountService *commonService.Account // 账号身份操作服务
// 用户信息服务
sysUserService systemService.ISysUser
}

View File

@@ -3,14 +3,14 @@ package controller
import (
"time"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/constants/captcha"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/vo/result"
systemService "nms_cxy/src/modules/system/service"
"be.ems/src/framework/config"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/constants/captcha"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
systemService "be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"

View File

@@ -1,11 +1,10 @@
package controller
import (
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/vo/result"
commonService "nms_cxy/src/modules/common/service"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
commonService "be.ems/src/modules/common/service"
"github.com/gin-gonic/gin"
)

View File

@@ -7,12 +7,12 @@ import (
"path/filepath"
"strings"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/constants/uploadsubpath"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/file"
"nms_cxy/src/framework/vo/result"
"be.ems/src/framework/config"
"be.ems/src/framework/constants/uploadsubpath"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"

View File

@@ -3,8 +3,8 @@ package controller
import (
"fmt"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/vo/result"
"be.ems/src/framework/config"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
)

View File

@@ -1,14 +1,14 @@
package controller
import (
commonConstants "nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/regular"
"nms_cxy/src/framework/vo/result"
commonModel "nms_cxy/src/modules/common/model"
commonService "nms_cxy/src/modules/common/service"
systemService "nms_cxy/src/modules/system/service"
commonConstants "be.ems/src/framework/constants/common"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/regular"
"be.ems/src/framework/vo/result"
commonModel "be.ems/src/modules/common/model"
commonService "be.ems/src/modules/common/service"
systemService "be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
)

View File

@@ -1,24 +1,194 @@
package service
import "nms_cxy/src/framework/vo"
import (
"fmt"
"time"
// 账号身份操作服务 服务层接口
type IAccount interface {
// ValidateCaptcha 校验验证码
ValidateCaptcha(code, uuid string) error
"be.ems/src/framework/config"
adminConstants "be.ems/src/framework/constants/admin"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo"
"be.ems/src/modules/system/model"
systemService "be.ems/src/modules/system/service"
)
// LoginByUsername 登录生成token
LoginByUsername(username, password string) (vo.LoginUser, error)
// UpdateLoginDateAndIP 更新登录时间和IP
UpdateLoginDateAndIP(loginUser *vo.LoginUser) bool
// ClearLoginRecordCache 清除错误记录次数
ClearLoginRecordCache(username string) bool
// RoleAndMenuPerms 角色和菜单数据权限
RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string)
// RouteMenus 前端路由所需要的菜单
RouteMenus(userId string, isAdmin bool) []vo.Router
// 实例化服务层 Account 结构体
var NewAccount = &Account{
sysUserService: systemService.NewSysUserImpl,
sysConfigService: systemService.NewSysConfigImpl,
sysRoleService: systemService.NewSysRoleImpl,
sysMenuService: systemService.NewSysMenuImpl,
}
// 账号身份操作服务 服务层处理
type Account struct {
// 用户信息服务
sysUserService systemService.ISysUser
// 参数配置服务
sysConfigService systemService.ISysConfig
// 角色服务
sysRoleService systemService.ISysRole
// 菜单服务
sysMenuService systemService.ISysMenu
}
// ValidateCaptcha 校验验证码
func (s *Account) ValidateCaptcha(code, uuid string) error {
// 验证码检查,从数据库配置获取验证码开关 true开启false关闭
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
if !parse.Boolean(captchaEnabledStr) {
return nil
}
if code == "" || uuid == "" {
// 验证码信息错误
return fmt.Errorf("captcha.err")
}
verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid
captcha, _ := redis.Get("", verifyKey)
if captcha == "" {
// 验证码已失效
return fmt.Errorf("captcha.errValid")
}
redis.Del("", verifyKey)
if captcha != code {
// 验证码错误
return fmt.Errorf("captcha.err")
}
return nil
}
// LoginByUsername 登录创建用户信息
func (s *Account) LoginByUsername(username, password string) (vo.LoginUser, error) {
loginUser := vo.LoginUser{}
// 检查密码重试次数
retrykey, retryCount, lockTime, err := s.passwordRetryCount(username)
if err != nil {
return loginUser, err
}
// 查询用户登录账号
sysUser := s.sysUserService.SelectUserByUserName(username)
if sysUser.UserName != username {
return loginUser, fmt.Errorf("login.errNameOrPasswd")
}
if sysUser.DelFlag == common.STATUS_YES {
// 对不起,您的账号已被删除
return loginUser, fmt.Errorf("login.errDelFlag")
}
if sysUser.Status == common.STATUS_NO {
return loginUser, fmt.Errorf("login.errStatus")
}
// 检验用户密码
compareBool := crypto.BcryptCompare(password, sysUser.Password)
if !compareBool {
redis.SetByExpire("", retrykey, retryCount+1, lockTime)
// 用户不存在或密码错误
return loginUser, fmt.Errorf("login.errNameOrPasswd")
} else {
// 清除错误记录次数
s.ClearLoginRecordCache(username)
}
// 登录用户信息
loginUser.UserID = sysUser.UserID
loginUser.DeptID = sysUser.DeptID
loginUser.User = sysUser
// 用户权限组标识
isAdmin := config.IsAdmin(sysUser.UserID)
if isAdmin {
loginUser.Permissions = []string{adminConstants.PERMISSION}
} else {
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
loginUser.Permissions = parse.RemoveDuplicates(perms)
}
return loginUser, nil
}
// UpdateLoginDateAndIP 更新登录时间和IP
func (s *Account) UpdateLoginDateAndIP(loginUser *vo.LoginUser) bool {
sysUser := loginUser.User
userInfo := model.SysUser{
UserID: sysUser.UserID,
LoginIP: sysUser.LoginIP,
LoginDate: sysUser.LoginDate,
UpdateBy: sysUser.UserName,
Sex: sysUser.Sex,
PhoneNumber: sysUser.PhoneNumber,
Email: sysUser.Email,
Remark: sysUser.Remark,
}
rows := s.sysUserService.UpdateUser(userInfo)
return rows > 0
}
// ClearLoginRecordCache 清除错误记录次数
func (s *Account) ClearLoginRecordCache(username string) bool {
cacheKey := cachekey.PWD_ERR_CNT_KEY + username
hasKey, _ := redis.Has("", cacheKey)
if hasKey {
delOk, _ := redis.Del("", cacheKey)
return delOk
}
return false
}
// passwordRetryCount 密码重试次数
func (s *Account) passwordRetryCount(username string) (string, int64, time.Duration, error) {
// 从数据库配置获取登录次数和错误锁定时间
maxRetryCountStr := s.sysConfigService.SelectConfigValueByKey("sys.user.maxRetryCount")
lockTimeStr := s.sysConfigService.SelectConfigValueByKey("sys.user.lockTime")
// 验证登录次数和错误锁定时间
maxRetryCount := parse.Number(maxRetryCountStr)
lockTime := parse.Number(lockTimeStr)
// 验证缓存记录次数
retrykey := cachekey.PWD_ERR_CNT_KEY + username
retryCount, err := redis.Get("", retrykey)
if retryCount == "" || err != nil {
retryCount = "0"
}
// 是否超过错误值
retryCountInt64 := parse.Number(retryCount)
if retryCountInt64 >= maxRetryCount {
// 密码输入错误多次,帐户已被锁定
errorMsg := fmt.Errorf("login.errRetryPasswd")
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, errorMsg
}
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil
}
// RoleAndMenuPerms 角色和菜单数据权限
func (s *Account) RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string) {
if isAdmin {
return []string{adminConstants.ROLE_KEY}, []string{adminConstants.PERMISSION}
} else {
// 角色key
roleGroup := []string{}
roles := s.sysRoleService.SelectRoleListByUserId(userId)
for _, role := range roles {
roleGroup = append(roleGroup, role.RoleKey)
}
// 菜单权限key
perms := s.sysMenuService.SelectMenuPermsByUserId(userId)
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
}
}
// RouteMenus 前端路由所需要的菜单
func (s *Account) RouteMenus(userId string, isAdmin bool) []vo.Router {
var buildMenus []vo.Router
if isAdmin {
menus := s.sysMenuService.SelectMenuTreeByUserId("*")
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
} else {
menus := s.sysMenuService.SelectMenuTreeByUserId(userId)
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
}
return buildMenus
}

View File

@@ -1,190 +0,0 @@
package service
import (
"fmt"
"time"
"nms_cxy/src/framework/config"
adminConstants "nms_cxy/src/framework/constants/admin"
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/crypto"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/vo"
"nms_cxy/src/modules/system/model"
systemService "nms_cxy/src/modules/system/service"
)
// 实例化服务层 AccountImpl 结构体
var NewAccountImpl = &AccountImpl{
sysUserService: systemService.NewSysUserImpl,
sysConfigService: systemService.NewSysConfigImpl,
sysRoleService: systemService.NewSysRoleImpl,
sysMenuService: systemService.NewSysMenuImpl,
}
// 账号身份操作服务 服务层处理
type AccountImpl struct {
// 用户信息服务
sysUserService systemService.ISysUser
// 参数配置服务
sysConfigService systemService.ISysConfig
// 角色服务
sysRoleService systemService.ISysRole
// 菜单服务
sysMenuService systemService.ISysMenu
}
// ValidateCaptcha 校验验证码
func (s *AccountImpl) ValidateCaptcha(code, uuid string) error {
// 验证码检查,从数据库配置获取验证码开关 true开启false关闭
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
if !parse.Boolean(captchaEnabledStr) {
return nil
}
if code == "" || uuid == "" {
// 验证码信息错误
return fmt.Errorf("captcha.err")
}
verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid
captcha, _ := redis.Get("", verifyKey)
if captcha == "" {
// 验证码已失效
return fmt.Errorf("captcha.errValid")
}
redis.Del("", verifyKey)
if captcha != code {
// 验证码错误
return fmt.Errorf("captcha.err")
}
return nil
}
// LoginByUsername 登录创建用户信息
func (s *AccountImpl) LoginByUsername(username, password string) (vo.LoginUser, error) {
loginUser := vo.LoginUser{}
// 检查密码重试次数
retrykey, retryCount, lockTime, err := s.passwordRetryCount(username)
if err != nil {
return loginUser, err
}
// 查询用户登录账号
sysUser := s.sysUserService.SelectUserByUserName(username)
if sysUser.UserName != username {
return loginUser, fmt.Errorf("login.errNameOrPasswd")
}
if sysUser.DelFlag == common.STATUS_YES {
// 对不起,您的账号已被删除
return loginUser, fmt.Errorf("login.errDelFlag")
}
if sysUser.Status == common.STATUS_NO {
return loginUser, fmt.Errorf("login.errStatus")
}
// 检验用户密码
compareBool := crypto.BcryptCompare(password, sysUser.Password)
if !compareBool {
redis.SetByExpire("", retrykey, retryCount+1, lockTime)
// 用户不存在或密码错误
return loginUser, fmt.Errorf("login.errNameOrPasswd")
} else {
// 清除错误记录次数
s.ClearLoginRecordCache(username)
}
// 登录用户信息
loginUser.UserID = sysUser.UserID
loginUser.DeptID = sysUser.DeptID
loginUser.User = sysUser
// 用户权限组标识
isAdmin := config.IsAdmin(sysUser.UserID)
if isAdmin {
loginUser.Permissions = []string{adminConstants.PERMISSION}
} else {
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
loginUser.Permissions = parse.RemoveDuplicates(perms)
}
return loginUser, nil
}
// UpdateLoginDateAndIP 更新登录时间和IP
func (s *AccountImpl) UpdateLoginDateAndIP(loginUser *vo.LoginUser) bool {
sysUser := loginUser.User
userInfo := model.SysUser{
UserID: sysUser.UserID,
LoginIP: sysUser.LoginIP,
LoginDate: sysUser.LoginDate,
UpdateBy: sysUser.UserName,
}
rows := s.sysUserService.UpdateUser(userInfo)
return rows > 0
}
// ClearLoginRecordCache 清除错误记录次数
func (s *AccountImpl) ClearLoginRecordCache(username string) bool {
cacheKey := cachekey.PWD_ERR_CNT_KEY + username
hasKey, _ := redis.Has("", cacheKey)
if hasKey {
delOk, _ := redis.Del("", cacheKey)
return delOk
}
return false
}
// passwordRetryCount 密码重试次数
func (s *AccountImpl) passwordRetryCount(username string) (string, int64, time.Duration, error) {
// 从数据库配置获取登录次数和错误锁定时间
maxRetryCountStr := s.sysConfigService.SelectConfigValueByKey("sys.user.maxRetryCount")
lockTimeStr := s.sysConfigService.SelectConfigValueByKey("sys.user.lockTime")
// 验证登录次数和错误锁定时间
maxRetryCount := parse.Number(maxRetryCountStr)
lockTime := parse.Number(lockTimeStr)
// 验证缓存记录次数
retrykey := cachekey.PWD_ERR_CNT_KEY + username
retryCount, err := redis.Get("", retrykey)
if retryCount == "" || err != nil {
retryCount = "0"
}
// 是否超过错误值
retryCountInt64 := parse.Number(retryCount)
if retryCountInt64 >= maxRetryCount {
// 密码输入错误多次,帐户已被锁定
errorMsg := fmt.Errorf("login.errRetryPasswd")
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, errorMsg
}
return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil
}
// RoleAndMenuPerms 角色和菜单数据权限
func (s *AccountImpl) RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string) {
if isAdmin {
return []string{adminConstants.ROLE_KEY}, []string{adminConstants.PERMISSION}
} else {
// 角色key
roleGroup := []string{}
roles := s.sysRoleService.SelectRoleListByUserId(userId)
for _, role := range roles {
roleGroup = append(roleGroup, role.RoleKey)
}
// 菜单权限key
perms := s.sysMenuService.SelectMenuPermsByUserId(userId)
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
}
}
// RouteMenus 前端路由所需要的菜单
func (s *AccountImpl) RouteMenus(userId string, isAdmin bool) []vo.Router {
var buildMenus []vo.Router
if isAdmin {
menus := s.sysMenuService.SelectMenuTreeByUserId("*")
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
} else {
menus := s.sysMenuService.SelectMenuTreeByUserId(userId)
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
}
return buildMenus
}

View File

@@ -3,11 +3,11 @@ package service
import (
"fmt"
"nms_cxy/lib/global"
"nms_cxy/src/framework/config"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/utils/machine"
systemService "nms_cxy/src/modules/system/service"
"be.ems/lib/global"
"be.ems/src/framework/config"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/utils/machine"
systemService "be.ems/src/modules/system/service"
)
// 实例化服务层 CommontImpl 结构体

View File

@@ -3,12 +3,12 @@ package service
import (
"fmt"
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/parse"
systemModel "nms_cxy/src/modules/system/model"
systemService "nms_cxy/src/modules/system/service"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/constants/common"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/parse"
systemModel "be.ems/src/modules/system/model"
systemService "be.ems/src/modules/system/service"
)
// 实例化服务层 RegisterImpl 结构体

View File

@@ -1,8 +1,8 @@
package crontask
import (
"nms_cxy/src/framework/logger"
"nms_cxy/src/modules/crontask/processor"
"be.ems/src/framework/logger"
"be.ems/src/modules/crontask/processor"
"github.com/gin-gonic/gin"
)

View File

@@ -6,11 +6,11 @@ import (
"strings"
"time"
"nms_cxy/lib/dborm"
"nms_cxy/lib/global"
"nms_cxy/lib/log"
"nms_cxy/omc/config"
"nms_cxy/src/framework/cron"
"be.ems/lib/dborm"
"be.ems/lib/global"
"be.ems/lib/log"
"be.ems/restagent/config"
"be.ems/src/framework/cron"
)
var NewProcessor = &BarProcessor{

View File

@@ -4,9 +4,9 @@ import (
"encoding/json"
"fmt"
"nms_cxy/lib/dborm"
"nms_cxy/lib/log"
"nms_cxy/src/framework/cron"
"be.ems/lib/dborm"
"be.ems/lib/log"
"be.ems/src/framework/cron"
)
var NewProcessor = &BarProcessor{

View File

@@ -4,9 +4,9 @@ import (
"encoding/json"
"fmt"
"nms_cxy/lib/dborm"
"nms_cxy/lib/log"
"nms_cxy/src/framework/cron"
"be.ems/lib/dborm"
"be.ems/lib/log"
"be.ems/src/framework/cron"
)
var NewProcessor = &BarProcessor{

View File

@@ -0,0 +1,160 @@
package exportTable
import (
"database/sql"
"encoding/csv"
"encoding/json"
"fmt"
"os"
"time"
"be.ems/lib/dborm"
"be.ems/lib/log"
"be.ems/src/framework/cron"
)
var NewProcessor = &BarProcessor{
progress: 0,
count: 0,
}
// bar 队列任务处理
type BarProcessor struct {
// 任务进度
progress int
// 执行次数
count int
}
type BarParams struct {
Duration int `json:"duration"`
TableName string `json:"tableName"`
Columns string `json:"columns"` // exported column name of time string
TimeCol string `json:"timeCol"` // time stamp of column name
TimeUnit string `json:"timeUnit"` // timestamp unit: second/micro/milli
Extras string `json:"extras"` // extras condition for where
FilePath string `json:"filePath"` // file path
}
func (s *BarProcessor) Execute(data any) (any, error) {
s.count++
options := data.(cron.JobData)
sysJob := options.SysJob
var params BarParams
err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
if err != nil {
return nil, err
}
// mkdir if not exist
if _, err = os.Stat(params.FilePath); os.IsNotExist(err) {
err = os.MkdirAll(params.FilePath, os.ModePerm)
if err != nil {
log.Error("Failed to Mkdir:", err)
return nil, err
}
}
//duration = params.Duration
now := time.Now()
end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
start := end.Add(-time.Duration(params.Duration) * time.Hour)
var startTime, endTime int64
switch params.TimeUnit {
case "second":
// 格式化时间戳为秒级
startTime = start.Unix()
endTime = end.Unix()
case "milli":
// 格式化时间戳为毫秒级
startTime = start.UnixMilli()
endTime = end.UnixMilli()
case "micro":
// 格式化时间戳为微妙级
startTime = start.UnixMicro()
endTime = end.UnixMicro()
default:
return nil, fmt.Errorf("error input parameter")
}
var query string
if params.Extras != "" {
query = fmt.Sprintf("SELECT %s FROM `%s` WHERE `%s` >= %d AND `%s` < %d AND %s",
params.Columns, params.TableName, params.TimeCol, startTime, params.TimeCol, endTime, params.Extras)
} else {
query = fmt.Sprintf("SELECT %s FROM `%s` WHERE `%s` >= %d AND `%s` < %d",
params.Columns, params.TableName, params.TimeCol, startTime, params.TimeCol, endTime)
}
log.Trace("query:", query)
filePath := fmt.Sprintf("%s/%s_export_%s.csv", params.FilePath, params.TableName, time.Now().Format("20060102150405"))
affected, err := s.exportData(query, filePath)
if err != nil {
return nil, err
}
// 返回结果,用于记录执行结果
return map[string]any{
"msg": "sucess",
"filePath": filePath,
"affected": affected,
}, nil
}
func (s *BarProcessor) exportData(query, filePath string) (int64, error) {
rows, err := dborm.XCoreDB().Query(query)
if err != nil {
return 0, err
}
defer rows.Close()
// 创建 CSV 文件
file, err := os.Create(filePath)
if err != nil {
return 0, err
}
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
// 写入表头
columns, _ := rows.ColumnTypes()
header := make([]string, len(columns))
for i, col := range columns {
header[i] = col.Name()
}
if err := writer.Write(header); err != nil {
return 0, err
}
// 写入数据
var affected int64 = 0
for rows.Next() {
values := make([]sql.RawBytes, len(columns))
scanArgs := make([]interface{}, len(columns))
for i := range values {
scanArgs[i] = &values[i]
}
if err := rows.Scan(scanArgs...); err != nil {
return 0, err
}
record := make([]string, len(columns))
for i, val := range values {
if val == nil {
record[i] = ""
} else {
record[i] = string(val)
}
}
affected++
if err := writer.Write(record); err != nil {
return affected, err
}
}
return affected, nil
}

View File

@@ -8,13 +8,12 @@ import (
"strings"
"time"
"nms_cxy/features/fm"
"nms_cxy/lib/dborm"
"nms_cxy/lib/global"
"nms_cxy/lib/log"
"nms_cxy/omc/config"
"nms_cxy/src/framework/cron"
"be.ems/features/fm"
"be.ems/lib/dborm"
"be.ems/lib/global"
"be.ems/lib/log"
"be.ems/restagent/config"
"be.ems/src/framework/cron"
"github.com/go-resty/resty/v2"
)

View File

@@ -7,11 +7,10 @@ import (
"strings"
"time"
"nms_cxy/lib/dborm"
"nms_cxy/lib/log"
"nms_cxy/omc/config"
"nms_cxy/src/framework/cron"
"be.ems/lib/dborm"
"be.ems/lib/log"
"be.ems/restagent/config"
"be.ems/src/framework/cron"
"github.com/go-resty/resty/v2"
)

View File

@@ -4,13 +4,13 @@ import (
"encoding/json"
"fmt"
"nms_cxy/src/framework/cron"
"nms_cxy/src/framework/logger"
monitorService "nms_cxy/src/modules/monitor/service"
"be.ems/src/framework/cron"
"be.ems/src/framework/logger"
monitorService "be.ems/src/modules/monitor/service"
)
var NewProcessor = &MonitorSysResourceProcessor{
monitorService: monitorService.NewMonitorImpl,
monitorService: monitorService.NewMonitor,
count: 0,
openDataCancel: false,
}
@@ -18,7 +18,7 @@ var NewProcessor = &MonitorSysResourceProcessor{
// MonitorSysResourceProcessor 系统资源CPU/IO/Netword收集
type MonitorSysResourceProcessor struct {
// 服务器系统相关信息服务
monitorService monitorService.IMonitor
monitorService *monitorService.Monitor
// 执行次数
count int
// 是否已经开启数据通道

View File

@@ -4,26 +4,23 @@ import (
"fmt"
"path/filepath"
"nms_cxy/src/framework/cron"
"nms_cxy/src/framework/logger"
neModel "nms_cxy/src/modules/network_element/model"
neService "nms_cxy/src/modules/network_element/service"
"be.ems/src/framework/cron"
"be.ems/src/framework/logger"
neModel "be.ems/src/modules/network_element/model"
neService "be.ems/src/modules/network_element/service"
)
var NewProcessor = &NeConfigBackupProcessor{
neConfigBackupService: neService.NewNeConfigBackupImpl,
neInfoService: neService.NewNeInfoImpl,
neConfigBackupService: neService.NewNeConfigBackup,
neInfoService: neService.NewNeInfo,
count: 0,
}
// NeConfigBackupProcessor 网元配置文件定期备份
type NeConfigBackupProcessor struct {
// 网元配置文件备份记录服务
neConfigBackupService neService.INeConfigBackup
// 网元信息服务
neInfoService neService.INeInfo
// 执行次数
count int
neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务
neInfoService *neService.NeInfo // 网元信息服务
count int // 执行次数
}
func (s *NeConfigBackupProcessor) Execute(data any) (any, error) {

View File

@@ -0,0 +1,45 @@
package ne_data_udm
import (
"fmt"
"be.ems/src/framework/cron"
"be.ems/src/framework/logger"
neDataService "be.ems/src/modules/network_data/service"
neModel "be.ems/src/modules/network_element/model"
neService "be.ems/src/modules/network_element/service"
)
var NewProcessor = &NeDataUDM{
udmAuthService: neDataService.NewUDMAuthUser,
udmSubService: neDataService.NewUDMSubUser,
neInfoService: neService.NewNeInfo,
count: 0,
}
// NeDataUDM 网元配置文件定期备份
type NeDataUDM struct {
udmAuthService *neDataService.UDMAuthUser // UDM鉴权信息
udmSubService *neDataService.UDMSubUser // UDM签约信息
neInfoService *neService.NeInfo // 网元信息服务
count int // 执行次数
}
func (s *NeDataUDM) Execute(data any) (any, error) {
s.count++ // 执行次数加一
options := data.(cron.JobData)
sysJob := options.SysJob
logger.Infof("重复 %v 任务ID %s", options.Repeat, sysJob.JobID)
// 返回结果,用于记录执行结果
result := map[string]any{
"count": s.count,
}
neList := s.neInfoService.SelectList(neModel.NeInfo{NeType: "UDM"}, false, false)
for _, neInfo := range neList {
result[fmt.Sprintf("AuthNumber_%s", neInfo.NeId)] = s.udmAuthService.ResetData(neInfo.NeId)
result[fmt.Sprintf("SubNumber_%s", neInfo.NeId)] = s.udmSubService.ResetData(neInfo.NeId)
}
return result, nil
}

View File

@@ -1,14 +1,17 @@
package processor
import (
"nms_cxy/src/framework/cron"
"nms_cxy/src/modules/crontask/processor/backupEtcFromNE"
"nms_cxy/src/modules/crontask/processor/delExpiredNeBackup"
"nms_cxy/src/modules/crontask/processor/deleteExpiredRecord"
"nms_cxy/src/modules/crontask/processor/genNeStateAlarm"
"nms_cxy/src/modules/crontask/processor/getStateFromNE"
processorMonitorSysResource "nms_cxy/src/modules/crontask/processor/monitor_sys_resource"
processorNeConfigBackup "nms_cxy/src/modules/crontask/processor/ne_config_backup"
"be.ems/src/framework/cron"
"be.ems/src/modules/crontask/processor/backupEtcFromNE"
"be.ems/src/modules/crontask/processor/delExpiredNeBackup"
"be.ems/src/modules/crontask/processor/deleteExpiredRecord"
"be.ems/src/modules/crontask/processor/exportTable"
"be.ems/src/modules/crontask/processor/genNeStateAlarm"
"be.ems/src/modules/crontask/processor/getStateFromNE"
processorMonitorSysResource "be.ems/src/modules/crontask/processor/monitor_sys_resource"
processorNeConfigBackup "be.ems/src/modules/crontask/processor/ne_config_backup"
processorNeDataUDM "be.ems/src/modules/crontask/processor/ne_data_udm"
"be.ems/src/modules/crontask/processor/removeFile"
)
// InitCronQueue 初始定时任务队列
@@ -17,10 +20,14 @@ func InitCronQueue() {
cron.CreateQueue("monitor_sys_resource", processorMonitorSysResource.NewProcessor)
// 网元-网元配置文件定期备份
cron.CreateQueue("ne_config_backup", processorNeConfigBackup.NewProcessor)
// 网元数据-UDM数据刷新同步
cron.CreateQueue("ne_data_udm", processorNeDataUDM.NewProcessor)
// delete expired NE backup file
cron.CreateQueue("delExpiredNeBackup", delExpiredNeBackup.NewProcessor)
cron.CreateQueue("deleteExpiredRecord", deleteExpiredRecord.NewProcessor)
cron.CreateQueue("backupEtcFromNE", backupEtcFromNE.NewProcessor)
cron.CreateQueue("getStateFromNE", getStateFromNE.NewProcessor)
cron.CreateQueue("genNeStateAlarm", genNeStateAlarm.NewProcessor)
cron.CreateQueue("exportTable", exportTable.NewProcessor)
cron.CreateQueue("removeFile", removeFile.NewProcessor)
}

View File

@@ -0,0 +1,159 @@
package removeFile
import (
"encoding/json"
"os"
"path/filepath"
"sort"
"time"
"be.ems/lib/log"
"be.ems/src/framework/cron"
)
var NewProcessor = &BarProcessor{
progress: 0,
count: 0,
}
// bar 队列任务处理
type BarProcessor struct {
// 任务进度
progress int
// 执行次数
count int
}
type BarParams struct {
FilePath string `json:"filePath"` // file path
MaxDays int `json:"maxDays"`
MaxFiles *int `json:"maxFiles"` // keep max files
MaxSize *int64 `json:"maxSize"`
Extras string `json:"extras"` // extras condition for where
}
type FileInfo struct {
Path string
Info os.FileInfo
}
func (s *BarProcessor) Execute(data any) (any, error) {
s.count++
options := data.(cron.JobData)
sysJob := options.SysJob
var params []BarParams
err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
if err != nil {
return nil, err
}
result := []map[string]any{}
for _, param := range params {
res, _ := s.ExecuteOne(param)
result = append(result, res)
}
// 返回结果,用于记录执行结果
return map[string]any{
"result": result,
}, nil
}
func (s *BarProcessor) ExecuteOne(params BarParams) (map[string]any, error) {
var maxFiles int = 0
var maxSize int64 = 0
if params.MaxFiles != nil {
maxFiles = *params.MaxFiles
}
if params.MaxSize != nil {
maxSize = int64(*params.MaxSize * 1024 * 1024)
}
files, err := getFiles(params.FilePath)
if err != nil {
return map[string]any{
"msg": "failed",
"err": err.Error(),
}, err
}
// 获取本地时区
loc, err := time.LoadLocation("Local")
if err != nil {
return map[string]any{
"msg": "failed",
"err": err.Error(),
}, err
}
cutoff := time.Now().In(loc).AddDate(0, 0, -params.MaxDays)
var oldFiles []FileInfo
for _, file := range files {
if file.Info.ModTime().Before(cutoff) {
oldFiles = append(oldFiles, file)
}
}
// 按修改时间排序文件(最旧的在前)
sort.Slice(oldFiles, func(i, j int) bool {
return oldFiles[i].Info.ModTime().Before(oldFiles[j].Info.ModTime())
})
deleted, errorDel := 0, 0
// 删除文件直到满足文件总数不超过maxFiles个且总大小不超过maxSize的条件
var totalSize int64
for i, file := range oldFiles {
if (maxFiles > 0 && i >= maxFiles) || (maxSize > 0 && totalSize+file.Info.Size() > maxSize) {
break
}
err := os.Remove(file.Path)
if err != nil {
log.Error("Error deleting file:", file.Path, err)
errorDel++
continue
}
totalSize += file.Info.Size()
deleted++
}
// 如果仍然有超过maxFiles个文件或总大小超过maxSize继续删除最旧的文件
remainingFiles := files
sort.Slice(remainingFiles, func(i, j int) bool {
return remainingFiles[i].Info.ModTime().Before(remainingFiles[j].Info.ModTime())
})
for (maxFiles > 0 && len(remainingFiles) > maxFiles) || (maxSize > 0 && totalSize > maxSize) {
file := remainingFiles[0]
err := os.Remove(file.Path)
if err != nil {
log.Error("Error deleting file:", file.Path, err)
remainingFiles = remainingFiles[1:]
continue
}
totalSize -= file.Info.Size()
remainingFiles = remainingFiles[1:]
}
// 返回结果,用于记录执行结果
return map[string]any{
"msg": "successed",
"filePath": params.FilePath,
"deleted": deleted,
"errorDel": errorDel,
}, nil
}
func getFiles(dir string) ([]FileInfo, error) {
var files []FileInfo
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
files = append(files, FileInfo{Path: path, Info: info})
}
return nil
})
return files, err
}

View File

@@ -1,25 +1,24 @@
package controller
import (
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/vo/result"
"nms_cxy/src/modules/monitor/service"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/monitor/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 MonitorInfoController 结构体
var NewMonitor = &MonitorController{
monitorService: service.NewMonitorImpl,
monitorService: service.NewMonitor,
}
// 服务器资源监控信息
//
// PATH /monitor
type MonitorController struct {
// 服务器系统相关信息服务
monitorService service.IMonitor
monitorService *service.Monitor // 服务器系统相关信息服务
}
// 资源监控信息加载

View File

@@ -1,12 +1,12 @@
package controller
import (
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/vo/result"
"nms_cxy/src/modules/monitor/model"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/i18n"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/monitor/model"
"github.com/gin-gonic/gin"
)

View File

@@ -7,14 +7,14 @@ import (
"strings"
"time"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/file"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/vo/result"
"nms_cxy/src/modules/monitor/model"
"nms_cxy/src/modules/monitor/service"
systemService "nms_cxy/src/modules/system/service"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/monitor/model"
"be.ems/src/modules/monitor/service"
systemService "be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
@@ -22,18 +22,16 @@ import (
// 实例化控制层 SysJobLogController 结构体
var NewSysJob = &SysJobController{
sysJobService: service.NewSysJobImpl,
sysDictDataService: systemService.NewSysDictDataImpl,
sysJobService: service.NewSysJob,
sysDictDataService: systemService.NewSysDictData,
}
// 调度任务信息
//
// PATH /monitor/job
type SysJobController struct {
// 调度任务服务
sysJobService service.ISysJob
// 字典数据服务
sysDictDataService systemService.ISysDictData
sysJobService *service.SysJob // 调度任务服务
sysDictDataService *systemService.SysDictData // 字典数据服务
}
// 调度任务列表

View File

@@ -6,33 +6,31 @@ import (
"strings"
"time"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/utils/date"
"nms_cxy/src/framework/utils/file"
"nms_cxy/src/framework/utils/parse"
"nms_cxy/src/framework/vo/result"
"nms_cxy/src/modules/monitor/model"
"nms_cxy/src/modules/monitor/service"
systemService "nms_cxy/src/modules/system/service"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/monitor/model"
"be.ems/src/modules/monitor/service"
systemService "be.ems/src/modules/system/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 SysJobLogController 结构体
var NewSysJobLog = &SysJobLogController{
sysJobLogService: service.NewSysJobLogImpl,
sysDictDataService: systemService.NewSysDictDataImpl,
sysJobLogService: service.NewSysJobLog,
sysDictDataService: systemService.NewSysDictData,
}
// 调度任务日志信息
//
// PATH /monitor/jobLog
type SysJobLogController struct {
// 调度任务日志服务
sysJobLogService service.ISysJobLog
// 字典数据服务
sysDictDataService systemService.ISysDictData
sysJobLogService *service.SysJobLog // 调度任务日志服务
sysDictDataService *systemService.SysDictData // 字典数据服务
}
// 调度任务日志列表
@@ -44,7 +42,7 @@ func (s *SysJobLogController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
// 任务ID优先级更高
if v, ok := querys["jobId"]; ok && v != nil {
jobInfo := service.NewSysJobImpl.SelectJobById(v.(string))
jobInfo := service.NewSysJob.SelectJobById(v.(string))
querys["jobName"] = jobInfo.JobName
querys["jobGroup"] = jobInfo.JobGroup
}

View File

@@ -5,29 +5,28 @@ import (
"sort"
"strings"
"nms_cxy/src/framework/constants/cachekey"
"nms_cxy/src/framework/i18n"
"nms_cxy/src/framework/redis"
"nms_cxy/src/framework/utils/ctx"
"nms_cxy/src/framework/vo"
"nms_cxy/src/framework/vo/result"
"nms_cxy/src/modules/monitor/model"
"nms_cxy/src/modules/monitor/service"
"be.ems/src/framework/constants/cachekey"
"be.ems/src/framework/i18n"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/monitor/model"
"be.ems/src/modules/monitor/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 SysUserOnlineController 结构体
var NewSysUserOnline = &SysUserOnlineController{
sysUserOnlineService: service.NewSysUserOnlineImpl,
sysUserOnlineService: service.NewSysUserOnline,
}
// 在线用户监控
//
// PATH /monitor/online
type SysUserOnlineController struct {
// 在线用户服务
sysUserOnlineService service.ISysUserOnline
sysUserOnlineService *service.SysUserOnline // 在线用户服务
}
// 在线用户列表

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