diff --git a/src/framework/i18n/i18n.go b/src/framework/i18n/i18n.go index 7e5c2ded..657964fa 100644 --- a/src/framework/i18n/i18n.go +++ b/src/framework/i18n/i18n.go @@ -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 diff --git a/src/modules/crontask/processor/monitor_sys_resource/monitor_sys_resource.go b/src/modules/crontask/processor/monitor_sys_resource/monitor_sys_resource.go index 9b1187bf..401d0233 100644 --- a/src/modules/crontask/processor/monitor_sys_resource/monitor_sys_resource.go +++ b/src/modules/crontask/processor/monitor_sys_resource/monitor_sys_resource.go @@ -10,7 +10,7 @@ import ( ) 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 // 是否已经开启数据通道 diff --git a/src/modules/monitor/controller/monitor.go b/src/modules/monitor/controller/monitor.go index 67921d1a..17f44dd5 100644 --- a/src/modules/monitor/controller/monitor.go +++ b/src/modules/monitor/controller/monitor.go @@ -11,15 +11,14 @@ import ( // 实例化控制层 MonitorInfoController 结构体 var NewMonitor = &MonitorController{ - monitorService: service.NewMonitorImpl, + monitorService: service.NewMonitor, } // 服务器资源监控信息 // // PATH /monitor type MonitorController struct { - // 服务器系统相关信息服务 - monitorService service.IMonitor + monitorService *service.Monitor // 服务器系统相关信息服务 } // 资源监控信息加载 diff --git a/src/modules/monitor/controller/sys_job.go b/src/modules/monitor/controller/sys_job.go index 2420e553..07868c8b 100644 --- a/src/modules/monitor/controller/sys_job.go +++ b/src/modules/monitor/controller/sys_job.go @@ -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 // 字典数据服务 } // 调度任务列表 diff --git a/src/modules/monitor/controller/sys_job_log.go b/src/modules/monitor/controller/sys_job_log.go index 4705700e..9401a28d 100644 --- a/src/modules/monitor/controller/sys_job_log.go +++ b/src/modules/monitor/controller/sys_job_log.go @@ -21,18 +21,16 @@ import ( // 实例化控制层 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 } diff --git a/src/modules/monitor/controller/sys_user_online.go b/src/modules/monitor/controller/sys_user_online.go index 40a84193..072cad32 100644 --- a/src/modules/monitor/controller/sys_user_online.go +++ b/src/modules/monitor/controller/sys_user_online.go @@ -19,15 +19,14 @@ import ( // 实例化控制层 SysUserOnlineController 结构体 var NewSysUserOnline = &SysUserOnlineController{ - sysUserOnlineService: service.NewSysUserOnlineImpl, + sysUserOnlineService: service.NewSysUserOnline, } // 在线用户监控 // // PATH /monitor/online type SysUserOnlineController struct { - // 在线用户服务 - sysUserOnlineService service.ISysUserOnline + sysUserOnlineService *service.SysUserOnline // 在线用户服务 } // 在线用户列表 diff --git a/src/modules/monitor/controller/system_info.go b/src/modules/monitor/controller/system_info.go index d93e0ffa..14437dda 100644 --- a/src/modules/monitor/controller/system_info.go +++ b/src/modules/monitor/controller/system_info.go @@ -9,15 +9,14 @@ import ( // 实例化控制层 SystemInfoController 结构体 var NewSystemInfo = &SystemInfoController{ - systemInfogService: service.NewSystemInfoImpl, + systemInfogService: service.NewSystemInfo, } // 服务器监控信息 // // PATH /monitor/system-info type SystemInfoController struct { - // 服务器系统相关信息服务 - systemInfogService service.ISystemInfo + systemInfogService *service.SystemInfo // 服务器系统相关信息服务 } // 服务器信息 diff --git a/src/modules/monitor/monitor.go b/src/modules/monitor/monitor.go index 67fa63e2..b71bbfa4 100644 --- a/src/modules/monitor/monitor.go +++ b/src/modules/monitor/monitor.go @@ -165,5 +165,5 @@ func InitLoad() { // 初始化定时任务处理 processor.InitCronQueue() // 启动时,初始化调度任务 - service.NewSysJobImpl.ResetQueueJob() + service.NewSysJob.ResetQueueJob() } diff --git a/src/modules/monitor/service/monitor.go b/src/modules/monitor/service/monitor.go index 5e836cc8..285a265b 100644 --- a/src/modules/monitor/service/monitor.go +++ b/src/modules/monitor/service/monitor.go @@ -1,14 +1,274 @@ package service -// IMonitor 服务器系统相关信息 服务层接口 -type IMonitor interface { - // RunMonitor 执行资源监控 - RunMonitor() +import ( + "context" + "strconv" + "time" - // RunMonitorDataCancel 启动资源监控数据存储io/network通道 移除之前的chan上下文后在设置新的均值 - // interval 采集的平均值(分钟) - RunMonitorDataCancel(removeBefore bool, interval float64) + "be.ems/src/framework/logger" + "be.ems/src/modules/monitor/model" + "be.ems/src/modules/monitor/repository" + systemService "be.ems/src/modules/system/service" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/disk" + "github.com/shirou/gopsutil/v4/load" + "github.com/shirou/gopsutil/v4/mem" + "github.com/shirou/gopsutil/v4/net" +) - // SelectMonitorInfo 查询监控资源信息 - SelectMonitorInfo(query map[string]any) map[string]any +// 实例化服务层 Monitor 结构体 +var NewMonitor = &Monitor{ + sysConfigService: systemService.NewSysConfigImpl, + monitorRepository: repository.NewMonitorImpl, + diskIO: make(chan []disk.IOCountersStat, 2), + netIO: make(chan []net.IOCountersStat, 2), +} + +// Monitor 服务器系统相关信息 服务层处理 +type Monitor struct { + // 参数配置服务 + sysConfigService systemService.ISysConfig + // 监控服务资源数据信息 + monitorRepository repository.IMonitor + // 磁盘网络IO 数据通道 + diskIO chan ([]disk.IOCountersStat) + netIO chan ([]net.IOCountersStat) +} + +// RunMonitor 执行资源监控 +func (s *Monitor) RunMonitor() { + var itemBase model.MonitorBase + itemBase.CreateTime = time.Now().UnixMilli() + itemBase.NeType = "#" + itemBase.NeID = "#" + loadInfo, _ := load.Avg() + itemBase.CPULoad1 = loadInfo.Load1 + itemBase.CPULoad5 = loadInfo.Load5 + itemBase.CPULoad15 = loadInfo.Load15 + totalPercent, _ := cpu.Percent(3*time.Second, false) + if len(totalPercent) > 0 { + itemBase.CPU = totalPercent[0] + } + cpuCount, _ := cpu.Counts(false) + cpuAvg := (float64(cpuCount*2) * 0.75) * 100 + itemBase.LoadUsage = 0 + if cpuAvg > 0 { + itemBase.LoadUsage = loadInfo.Load1 / cpuAvg + } + + memoryInfo, _ := mem.VirtualMemory() + itemBase.Memory = memoryInfo.UsedPercent + + if err := s.monitorRepository.CreateMonitorBase(itemBase); err != nil { + logger.Errorf("CreateMonitorBase err: %v", err) + } + + // 将当前资源发送到chan中处理保存 + s.loadDiskIO() + s.loadNetIO() + + // 监控系统资源-保留天数 + storeDays := s.sysConfigService.SelectConfigValueByKey("monitor.sysResource.storeDays") + if storeDays != "" { + storeDays, _ := strconv.Atoi(storeDays) + ltTime := time.Now().AddDate(0, 0, -storeDays).UnixMilli() + _ = s.monitorRepository.DelMonitorBase(ltTime) + _ = s.monitorRepository.DelMonitorIO(ltTime) + _ = s.monitorRepository.DelMonitorNet(ltTime) + } +} + +func (s *Monitor) loadDiskIO() { + ioStat, _ := disk.IOCounters() + var diskIOList []disk.IOCountersStat + for _, io := range ioStat { + diskIOList = append(diskIOList, io) + } + s.diskIO <- diskIOList +} + +func (s *Monitor) loadNetIO() { + netStat, _ := net.IOCounters(true) + netStatAll, _ := net.IOCounters(false) + var netList []net.IOCountersStat + netList = append(netList, netStat...) + netList = append(netList, netStatAll...) + s.netIO <- netList +} + +// monitorCancel 监控搜集IO/Network上下文 +var monitorCancel context.CancelFunc + +// RunMonitorDataCancel 启动资源监控数据存储io/network通道 移除之前的chan上下文后在设置新的均值 +// interval 采集的平均值(分钟) +func (s *Monitor) RunMonitorDataCancel(removeBefore bool, interval float64) { + // 是否取消之前的 + if removeBefore { + monitorCancel() + } + + // 上下文控制 + ctx, cancel := context.WithCancel(context.Background()) + monitorCancel = cancel + + // chanl 通道进行存储数据 + go s.saveIODataToDB(ctx, interval) + go s.saveNetDataToDB(ctx, interval) +} + +func (s *Monitor) saveIODataToDB(ctx context.Context, interval float64) { + defer close(s.diskIO) + for { + select { + case <-ctx.Done(): + return + case ioStat := <-s.diskIO: + select { + case <-ctx.Done(): + return + case ioStat2 := <-s.diskIO: + var ioList []model.MonitorIO + timeMilli := time.Now().UnixMilli() + for _, io2 := range ioStat2 { + for _, io1 := range ioStat { + if io2.Name == io1.Name { + var itemIO model.MonitorIO + itemIO.CreateTime = timeMilli + itemIO.NeType = "#" + itemIO.NeID = "#" + itemIO.Name = io1.Name + + if io2.ReadBytes != 0 && io1.ReadBytes != 0 && io2.ReadBytes > io1.ReadBytes { + itemIO.Read = int64(float64(io2.ReadBytes-io1.ReadBytes) / interval / 60) + } + if io2.WriteBytes != 0 && io1.WriteBytes != 0 && io2.WriteBytes > io1.WriteBytes { + itemIO.Write = int64(float64(io2.WriteBytes-io1.WriteBytes) / interval / 60) + } + + if io2.ReadCount != 0 && io1.ReadCount != 0 && io2.ReadCount > io1.ReadCount { + itemIO.Count = int64(float64(io2.ReadCount-io1.ReadCount) / interval / 60) + } + writeCount := int64(0) + if io2.WriteCount != 0 && io1.WriteCount != 0 && io2.WriteCount > io1.WriteCount { + writeCount = int64(float64(io2.WriteCount-io1.WriteCount) / interval * 60) + } + if writeCount > itemIO.Count { + itemIO.Count = writeCount + } + + if io2.ReadTime != 0 && io1.ReadTime != 0 && io2.ReadTime > io1.ReadTime { + itemIO.Time = int64(float64(io2.ReadTime-io1.ReadTime) / interval / 60) + } + writeTime := int64(0) + if io2.WriteTime != 0 && io1.WriteTime != 0 && io2.WriteTime > io1.WriteTime { + writeTime = int64(float64(io2.WriteTime-io1.WriteTime) / interval / 60) + } + if writeTime > itemIO.Time { + itemIO.Time = writeTime + } + ioList = append(ioList, itemIO) + break + } + } + } + if err := s.monitorRepository.BatchCreateMonitorIO(ioList); err != nil { + logger.Errorf("BatchCreateMonitorIO err: %v", err) + } + s.diskIO <- ioStat2 + } + } + } +} + +func (s *Monitor) saveNetDataToDB(ctx context.Context, interval float64) { + defer close(s.netIO) + for { + select { + case <-ctx.Done(): + return + case netStat := <-s.netIO: + select { + case <-ctx.Done(): + return + case netStat2 := <-s.netIO: + var netList []model.MonitorNetwork + timeMilli := time.Now().UnixMilli() + for _, net2 := range netStat2 { + for _, net1 := range netStat { + if net2.Name == net1.Name { + var itemNet model.MonitorNetwork + itemNet.CreateTime = timeMilli + itemNet.NeType = "#" + itemNet.NeID = "#" + itemNet.Name = net1.Name + + if net2.BytesSent != 0 && net1.BytesSent != 0 && net2.BytesSent > net1.BytesSent { + itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / interval / 60 + } + if net2.BytesRecv != 0 && net1.BytesRecv != 0 && net2.BytesRecv > net1.BytesRecv { + itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / interval / 60 + } + netList = append(netList, itemNet) + break + } + } + } + + if err := s.monitorRepository.BatchCreateMonitorNet(netList); err != nil { + logger.Errorf("BatchCreateMonitorNet err: %v", err) + } + s.netIO <- netStat2 + } + } + } +} + +// SelectMonitorInfo 查询监控资源信息 +func (s *Monitor) SelectMonitorInfo(query map[string]any) map[string]any { + infoType := query["type"] + startTimeMilli := query["startTime"] + endTimeMilli := query["endTime"] + neType := query["neType"] + neId := query["neId"] + name := query["name"] + + // 返回数据 + backDatas := map[string]any{} + + // 基本信息 + if infoType == "all" || infoType == "load" || infoType == "cpu" || infoType == "memory" { + rows := s.monitorRepository.SelectMonitorBase(map[string]any{ + "startTime": startTimeMilli, + "endTime": endTimeMilli, + "neType": neType, + "neId": neId, + }) + backDatas["base"] = rows + } + + // 磁盘IO + if infoType == "all" || infoType == "io" { + rows := s.monitorRepository.SelectMonitorIO(map[string]any{ + "startTime": startTimeMilli, + "endTime": endTimeMilli, + "neType": neType, + "neId": neId, + "name": name, + }) + backDatas["io"] = rows + } + + // 网络 + if infoType == "all" || infoType == "network" { + rows := s.monitorRepository.SelectMonitorNetwork(map[string]any{ + "startTime": startTimeMilli, + "endTime": endTimeMilli, + "neType": neType, + "neId": neId, + "name": name, + }) + backDatas["network"] = rows + } + + return backDatas } diff --git a/src/modules/monitor/service/monitor.impl.go b/src/modules/monitor/service/monitor.impl.go deleted file mode 100644 index 4152193f..00000000 --- a/src/modules/monitor/service/monitor.impl.go +++ /dev/null @@ -1,274 +0,0 @@ -package service - -import ( - "context" - "strconv" - "time" - - "be.ems/src/framework/logger" - "be.ems/src/modules/monitor/model" - "be.ems/src/modules/monitor/repository" - systemService "be.ems/src/modules/system/service" - "github.com/shirou/gopsutil/v4/cpu" - "github.com/shirou/gopsutil/v4/disk" - "github.com/shirou/gopsutil/v4/load" - "github.com/shirou/gopsutil/v4/mem" - "github.com/shirou/gopsutil/v4/net" -) - -// 实例化服务层 MonitorImpl 结构体 -var NewMonitorImpl = &MonitorImpl{ - sysConfigService: systemService.NewSysConfigImpl, - monitorRepository: repository.NewMonitorImpl, - diskIO: make(chan []disk.IOCountersStat, 2), - netIO: make(chan []net.IOCountersStat, 2), -} - -// MonitorImpl 服务器系统相关信息 服务层处理 -type MonitorImpl struct { - // 参数配置服务 - sysConfigService systemService.ISysConfig - // 监控服务资源数据信息 - monitorRepository repository.IMonitor - // 磁盘网络IO 数据通道 - diskIO chan ([]disk.IOCountersStat) - netIO chan ([]net.IOCountersStat) -} - -// RunMonitor 执行资源监控 -func (s *MonitorImpl) RunMonitor() { - var itemBase model.MonitorBase - itemBase.CreateTime = time.Now().UnixMilli() - itemBase.NeType = "#" - itemBase.NeID = "#" - loadInfo, _ := load.Avg() - itemBase.CPULoad1 = loadInfo.Load1 - itemBase.CPULoad5 = loadInfo.Load5 - itemBase.CPULoad15 = loadInfo.Load15 - totalPercent, _ := cpu.Percent(3*time.Second, false) - if len(totalPercent) == 1 { - itemBase.CPU = totalPercent[0] - } - cpuCount, _ := cpu.Counts(false) - cpuAvg := (float64(cpuCount*2) * 0.75) * 100 - itemBase.LoadUsage = 0 - if cpuAvg > 0 { - itemBase.LoadUsage = loadInfo.Load1 / cpuAvg - } - - memoryInfo, _ := mem.VirtualMemory() - itemBase.Memory = memoryInfo.UsedPercent - - if err := s.monitorRepository.CreateMonitorBase(itemBase); err != nil { - logger.Errorf("CreateMonitorBase err: %v", err) - } - - // 将当前资源发送到chan中处理保存 - s.loadDiskIO() - s.loadNetIO() - - // 监控系统资源-保留天数 - storeDays := s.sysConfigService.SelectConfigValueByKey("monitor.sysResource.storeDays") - if storeDays != "" { - storeDays, _ := strconv.Atoi(storeDays) - ltTime := time.Now().AddDate(0, 0, -storeDays).UnixMilli() - _ = s.monitorRepository.DelMonitorBase(ltTime) - _ = s.monitorRepository.DelMonitorIO(ltTime) - _ = s.monitorRepository.DelMonitorNet(ltTime) - } -} - -func (s *MonitorImpl) loadDiskIO() { - ioStat, _ := disk.IOCounters() - var diskIOList []disk.IOCountersStat - for _, io := range ioStat { - diskIOList = append(diskIOList, io) - } - s.diskIO <- diskIOList -} - -func (s *MonitorImpl) loadNetIO() { - netStat, _ := net.IOCounters(true) - netStatAll, _ := net.IOCounters(false) - var netList []net.IOCountersStat - netList = append(netList, netStat...) - netList = append(netList, netStatAll...) - s.netIO <- netList -} - -// monitorCancel 监控搜集IO/Network上下文 -var monitorCancel context.CancelFunc - -// RunMonitorDataCancel 启动资源监控数据存储io/network通道 移除之前的chan上下文后在设置新的均值 -// interval 采集的平均值(分钟) -func (s *MonitorImpl) RunMonitorDataCancel(removeBefore bool, interval float64) { - // 是否取消之前的 - if removeBefore { - monitorCancel() - } - - // 上下文控制 - ctx, cancel := context.WithCancel(context.Background()) - monitorCancel = cancel - - // chanl 通道进行存储数据 - go s.saveIODataToDB(ctx, interval) - go s.saveNetDataToDB(ctx, interval) -} - -func (s *MonitorImpl) saveIODataToDB(ctx context.Context, interval float64) { - defer close(s.diskIO) - for { - select { - case <-ctx.Done(): - return - case ioStat := <-s.diskIO: - select { - case <-ctx.Done(): - return - case ioStat2 := <-s.diskIO: - var ioList []model.MonitorIO - timeMilli := time.Now().UnixMilli() - for _, io2 := range ioStat2 { - for _, io1 := range ioStat { - if io2.Name == io1.Name { - var itemIO model.MonitorIO - itemIO.CreateTime = timeMilli - itemIO.NeType = "#" - itemIO.NeID = "#" - itemIO.Name = io1.Name - - if io2.ReadBytes != 0 && io1.ReadBytes != 0 && io2.ReadBytes > io1.ReadBytes { - itemIO.Read = int64(float64(io2.ReadBytes-io1.ReadBytes) / interval / 60) - } - if io2.WriteBytes != 0 && io1.WriteBytes != 0 && io2.WriteBytes > io1.WriteBytes { - itemIO.Write = int64(float64(io2.WriteBytes-io1.WriteBytes) / interval / 60) - } - - if io2.ReadCount != 0 && io1.ReadCount != 0 && io2.ReadCount > io1.ReadCount { - itemIO.Count = int64(float64(io2.ReadCount-io1.ReadCount) / interval / 60) - } - writeCount := int64(0) - if io2.WriteCount != 0 && io1.WriteCount != 0 && io2.WriteCount > io1.WriteCount { - writeCount = int64(float64(io2.WriteCount-io1.WriteCount) / interval * 60) - } - if writeCount > itemIO.Count { - itemIO.Count = writeCount - } - - if io2.ReadTime != 0 && io1.ReadTime != 0 && io2.ReadTime > io1.ReadTime { - itemIO.Time = int64(float64(io2.ReadTime-io1.ReadTime) / interval / 60) - } - writeTime := int64(0) - if io2.WriteTime != 0 && io1.WriteTime != 0 && io2.WriteTime > io1.WriteTime { - writeTime = int64(float64(io2.WriteTime-io1.WriteTime) / interval / 60) - } - if writeTime > itemIO.Time { - itemIO.Time = writeTime - } - ioList = append(ioList, itemIO) - break - } - } - } - if err := s.monitorRepository.BatchCreateMonitorIO(ioList); err != nil { - logger.Errorf("BatchCreateMonitorIO err: %v", err) - } - s.diskIO <- ioStat2 - } - } - } -} - -func (s *MonitorImpl) saveNetDataToDB(ctx context.Context, interval float64) { - defer close(s.netIO) - for { - select { - case <-ctx.Done(): - return - case netStat := <-s.netIO: - select { - case <-ctx.Done(): - return - case netStat2 := <-s.netIO: - var netList []model.MonitorNetwork - timeMilli := time.Now().UnixMilli() - for _, net2 := range netStat2 { - for _, net1 := range netStat { - if net2.Name == net1.Name { - var itemNet model.MonitorNetwork - itemNet.CreateTime = timeMilli - itemNet.NeType = "#" - itemNet.NeID = "#" - itemNet.Name = net1.Name - - if net2.BytesSent != 0 && net1.BytesSent != 0 && net2.BytesSent > net1.BytesSent { - itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / interval / 60 - } - if net2.BytesRecv != 0 && net1.BytesRecv != 0 && net2.BytesRecv > net1.BytesRecv { - itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / interval / 60 - } - netList = append(netList, itemNet) - break - } - } - } - - if err := s.monitorRepository.BatchCreateMonitorNet(netList); err != nil { - logger.Errorf("BatchCreateMonitorNet err: %v", err) - } - s.netIO <- netStat2 - } - } - } -} - -// SelectMonitorInfo 查询监控资源信息 -func (s *MonitorImpl) SelectMonitorInfo(query map[string]any) map[string]any { - infoType := query["type"] - startTimeMilli := query["startTime"] - endTimeMilli := query["endTime"] - neType := query["neType"] - neId := query["neId"] - name := query["name"] - - // 返回数据 - backDatas := map[string]any{} - - // 基本信息 - if infoType == "all" || infoType == "load" || infoType == "cpu" || infoType == "memory" { - rows := s.monitorRepository.SelectMonitorBase(map[string]any{ - "startTime": startTimeMilli, - "endTime": endTimeMilli, - "neType": neType, - "neId": neId, - }) - backDatas["base"] = rows - } - - // 磁盘IO - if infoType == "all" || infoType == "io" { - rows := s.monitorRepository.SelectMonitorIO(map[string]any{ - "startTime": startTimeMilli, - "endTime": endTimeMilli, - "neType": neType, - "neId": neId, - "name": name, - }) - backDatas["io"] = rows - } - - // 网络 - if infoType == "all" || infoType == "network" { - rows := s.monitorRepository.SelectMonitorNetwork(map[string]any{ - "startTime": startTimeMilli, - "endTime": endTimeMilli, - "neType": neType, - "neId": neId, - "name": name, - }) - backDatas["network"] = rows - } - - return backDatas -} diff --git a/src/modules/monitor/service/monitor_test.go b/src/modules/monitor/service/monitor_test.go index 00ae73e8..44dd2a72 100644 --- a/src/modules/monitor/service/monitor_test.go +++ b/src/modules/monitor/service/monitor_test.go @@ -12,10 +12,6 @@ import ( "github.com/shirou/gopsutil/v4/net" ) -func init() { - -} - func TestInfo(t *testing.T) { s := MonitorInfo{} s.load(0.5) // 0.5 半分钟 @@ -36,17 +32,21 @@ func (m *MonitorInfo) load(interval float64) { var itemBase MonitorBase itemBase.CreateTime = time.Now().UnixMilli() - totalPercent, _ := cpu.Percent(3*time.Second, false) - if len(totalPercent) == 1 { - itemBase.CPU = totalPercent[0] - } - cpuCount, _ := cpu.Counts(false) - loadInfo, _ := load.Avg() itemBase.CPULoad1 = loadInfo.Load1 itemBase.CPULoad5 = loadInfo.Load5 itemBase.CPULoad15 = loadInfo.Load15 - itemBase.LoadUsage = loadInfo.Load1 / (float64(cpuCount*2) * 0.75) * 100 + + totalPercent, _ := cpu.Percent(3*time.Second, false) + if len(totalPercent) > 0 { + itemBase.CPU = totalPercent[0] + } + cpuCount, _ := cpu.Counts(false) + cpuAvg := (float64(cpuCount*2) * 0.75) * 100 + itemBase.LoadUsage = 0 + if cpuAvg > 0 { + itemBase.LoadUsage = loadInfo.Load1 / cpuAvg + } memoryInfo, _ := mem.VirtualMemory() itemBase.Memory = memoryInfo.UsedPercent diff --git a/src/modules/monitor/service/sys_job.go b/src/modules/monitor/service/sys_job.go index f4beb36c..af1ca91e 100644 --- a/src/modules/monitor/service/sys_job.go +++ b/src/modules/monitor/service/sys_job.go @@ -1,35 +1,169 @@ package service import ( + "fmt" + + "be.ems/src/framework/constants/common" + "be.ems/src/framework/cron" "be.ems/src/modules/monitor/model" + "be.ems/src/modules/monitor/repository" ) -// ISysJob 调度任务信息 服务层接口 -type ISysJob interface { - // SelectJobPage 分页查询调度任务集合 - SelectJobPage(query map[string]any) map[string]any - - // SelectJobList 查询调度任务集合 - SelectJobList(sysJob model.SysJob) []model.SysJob - - // SelectJobById 通过调度ID查询调度任务信息 - SelectJobById(jobId string) model.SysJob - - // CheckUniqueJobName 校验调度任务名称和组是否唯一 - CheckUniqueJobName(jobName, jobGroup, jobId string) bool - - // InsertJob 新增调度任务信息 - InsertJob(sysJob model.SysJob) string - - // UpdateJob 修改调度任务信息 - UpdateJob(sysJob model.SysJob) int64 - - // DeleteJobByIds 批量删除调度任务信息 - DeleteJobByIds(jobIds []string) (int64, error) - - // RunQueueJob 立即运行一次调度任务 - RunQueueJob(sysJob model.SysJob) bool - - // ResetQueueJob 重置初始调度任务 - ResetQueueJob() +// 实例化服务层 SysJob 结构体 +var NewSysJob = &SysJob{ + sysJobRepository: repository.NewSysJobImpl, +} + +// SysJob 调度任务 服务层处理 +type SysJob struct { + // 调度任务数据信息 + sysJobRepository repository.ISysJob +} + +// SelectJobPage 分页查询调度任务集合 +func (r *SysJob) SelectJobPage(query map[string]any) map[string]any { + return r.sysJobRepository.SelectJobPage(query) +} + +// SelectJobList 查询调度任务集合 +func (r *SysJob) SelectJobList(sysJob model.SysJob) []model.SysJob { + return r.sysJobRepository.SelectJobList(sysJob) +} + +// SelectJobById 通过调度ID查询调度任务信息 +func (r *SysJob) SelectJobById(jobId string) model.SysJob { + if jobId == "" { + return model.SysJob{} + } + jobs := r.sysJobRepository.SelectJobByIds([]string{jobId}) + if len(jobs) > 0 { + return jobs[0] + } + return model.SysJob{} +} + +// CheckUniqueJobName 校验调度任务名称和组是否唯一 +func (r *SysJob) CheckUniqueJobName(jobName, jobGroup, jobId string) bool { + uniqueId := r.sysJobRepository.CheckUniqueJob(model.SysJob{ + JobName: jobName, + JobGroup: jobGroup, + }) + if uniqueId == jobId { + return true + } + return uniqueId == "" +} + +// InsertJob 新增调度任务信息 +func (r *SysJob) InsertJob(sysJob model.SysJob) string { + insertId := r.sysJobRepository.InsertJob(sysJob) + if insertId == "" && sysJob.Status == common.STATUS_YES { + sysJob.JobID = insertId + r.insertQueueJob(sysJob, true) + } + return insertId +} + +// UpdateJob 修改调度任务信息 +func (r *SysJob) UpdateJob(sysJob model.SysJob) int64 { + rows := r.sysJobRepository.UpdateJob(sysJob) + if rows > 0 { + //状态正常添加队列任务 + if sysJob.Status == common.STATUS_YES { + r.insertQueueJob(sysJob, true) + } + // 状态禁用删除队列任务 + if sysJob.Status == common.STATUS_NO { + r.deleteQueueJob(sysJob) + } + } + return rows +} + +// DeleteJobByIds 批量删除调度任务信息 +func (r *SysJob) DeleteJobByIds(jobIds []string) (int64, error) { + // 检查是否存在 + jobs := r.sysJobRepository.SelectJobByIds(jobIds) + if len(jobs) <= 0 { + // 没有可访问调度任务数据! + return 0, fmt.Errorf("there is no accessible scheduling task data") + } + if len(jobs) == len(jobIds) { + // 清除任务 + for _, job := range jobs { + r.deleteQueueJob(job) + } + rows := r.sysJobRepository.DeleteJobByIds(jobIds) + return rows, nil + } + // 删除调度任务信息失败! + return 0, fmt.Errorf("failed to delete scheduling task information") +} + +// ResetQueueJob 重置初始调度任务 +func (r *SysJob) ResetQueueJob() { + // 获取注册的队列名称 + queueNames := cron.QueueNames() + if len(queueNames) == 0 { + return + } + // 查询系统中定义状态为正常启用的任务 + sysJobs := r.sysJobRepository.SelectJobList(model.SysJob{ + Status: common.STATUS_YES, + }) + for _, sysJob := range sysJobs { + for _, name := range queueNames { + if name == sysJob.InvokeTarget { + r.insertQueueJob(sysJob, true) + } + } + } +} + +// RunQueueJob 立即运行一次调度任务 +func (r *SysJob) RunQueueJob(sysJob model.SysJob) bool { + return r.insertQueueJob(sysJob, false) +} + +// insertQueueJob 添加调度任务 +func (r *SysJob) insertQueueJob(sysJob model.SysJob, repeat bool) bool { + // 获取队列 Processor + queue := cron.GetQueue(sysJob.InvokeTarget) + if queue.Name != sysJob.InvokeTarget { + return false + } + + // 给执行任务数据参数 + options := cron.JobData{ + Repeat: repeat, + SysJob: sysJob, + } + + // 不是重复任务的情况,立即执行一次 + if !repeat { + // 执行单次任务 + status := queue.RunJob(options, cron.JobOptions{ + JobId: sysJob.JobID, + }) + // 执行中或等待中的都返回正常 + return status == cron.Active || status == cron.Waiting + } + + // 执行重复任务 + queue.RunJob(options, cron.JobOptions{ + JobId: sysJob.JobID, + Cron: sysJob.CronExpression, + }) + + return true +} + +// deleteQueueJob 删除调度任务 +func (r *SysJob) deleteQueueJob(sysJob model.SysJob) bool { + // 获取队列 Processor + queue := cron.GetQueue(sysJob.InvokeTarget) + if queue.Name != sysJob.InvokeTarget { + return false + } + return queue.RemoveJob(sysJob.JobID) } diff --git a/src/modules/monitor/service/sys_job.impl.go b/src/modules/monitor/service/sys_job.impl.go deleted file mode 100644 index 81fd7e7e..00000000 --- a/src/modules/monitor/service/sys_job.impl.go +++ /dev/null @@ -1,169 +0,0 @@ -package service - -import ( - "fmt" - - "be.ems/src/framework/constants/common" - "be.ems/src/framework/cron" - "be.ems/src/modules/monitor/model" - "be.ems/src/modules/monitor/repository" -) - -// 实例化服务层 SysJobImpl 结构体 -var NewSysJobImpl = &SysJobImpl{ - sysJobRepository: repository.NewSysJobImpl, -} - -// SysJobImpl 调度任务 服务层处理 -type SysJobImpl struct { - // 调度任务数据信息 - sysJobRepository repository.ISysJob -} - -// SelectJobPage 分页查询调度任务集合 -func (r *SysJobImpl) SelectJobPage(query map[string]any) map[string]any { - return r.sysJobRepository.SelectJobPage(query) -} - -// SelectJobList 查询调度任务集合 -func (r *SysJobImpl) SelectJobList(sysJob model.SysJob) []model.SysJob { - return r.sysJobRepository.SelectJobList(sysJob) -} - -// SelectJobById 通过调度ID查询调度任务信息 -func (r *SysJobImpl) SelectJobById(jobId string) model.SysJob { - if jobId == "" { - return model.SysJob{} - } - jobs := r.sysJobRepository.SelectJobByIds([]string{jobId}) - if len(jobs) > 0 { - return jobs[0] - } - return model.SysJob{} -} - -// CheckUniqueJobName 校验调度任务名称和组是否唯一 -func (r *SysJobImpl) CheckUniqueJobName(jobName, jobGroup, jobId string) bool { - uniqueId := r.sysJobRepository.CheckUniqueJob(model.SysJob{ - JobName: jobName, - JobGroup: jobGroup, - }) - if uniqueId == jobId { - return true - } - return uniqueId == "" -} - -// InsertJob 新增调度任务信息 -func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string { - insertId := r.sysJobRepository.InsertJob(sysJob) - if insertId == "" && sysJob.Status == common.STATUS_YES { - sysJob.JobID = insertId - r.insertQueueJob(sysJob, true) - } - return insertId -} - -// UpdateJob 修改调度任务信息 -func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 { - rows := r.sysJobRepository.UpdateJob(sysJob) - if rows > 0 { - //状态正常添加队列任务 - if sysJob.Status == common.STATUS_YES { - r.insertQueueJob(sysJob, true) - } - // 状态禁用删除队列任务 - if sysJob.Status == common.STATUS_NO { - r.deleteQueueJob(sysJob) - } - } - return rows -} - -// DeleteJobByIds 批量删除调度任务信息 -func (r *SysJobImpl) DeleteJobByIds(jobIds []string) (int64, error) { - // 检查是否存在 - jobs := r.sysJobRepository.SelectJobByIds(jobIds) - if len(jobs) <= 0 { - // 没有可访问调度任务数据! - return 0, fmt.Errorf("there is no accessible scheduling task data") - } - if len(jobs) == len(jobIds) { - // 清除任务 - for _, job := range jobs { - r.deleteQueueJob(job) - } - rows := r.sysJobRepository.DeleteJobByIds(jobIds) - return rows, nil - } - // 删除调度任务信息失败! - return 0, fmt.Errorf("failed to delete scheduling task information") -} - -// ResetQueueJob 重置初始调度任务 -func (r *SysJobImpl) ResetQueueJob() { - // 获取注册的队列名称 - queueNames := cron.QueueNames() - if len(queueNames) == 0 { - return - } - // 查询系统中定义状态为正常启用的任务 - sysJobs := r.sysJobRepository.SelectJobList(model.SysJob{ - Status: common.STATUS_YES, - }) - for _, sysJob := range sysJobs { - for _, name := range queueNames { - if name == sysJob.InvokeTarget { - r.insertQueueJob(sysJob, true) - } - } - } -} - -// RunQueueJob 立即运行一次调度任务 -func (r *SysJobImpl) RunQueueJob(sysJob model.SysJob) bool { - return r.insertQueueJob(sysJob, false) -} - -// insertQueueJob 添加调度任务 -func (r *SysJobImpl) insertQueueJob(sysJob model.SysJob, repeat bool) bool { - // 获取队列 Processor - queue := cron.GetQueue(sysJob.InvokeTarget) - if queue.Name != sysJob.InvokeTarget { - return false - } - - // 给执行任务数据参数 - options := cron.JobData{ - Repeat: repeat, - SysJob: sysJob, - } - - // 不是重复任务的情况,立即执行一次 - if !repeat { - // 执行单次任务 - status := queue.RunJob(options, cron.JobOptions{ - JobId: sysJob.JobID, - }) - // 执行中或等待中的都返回正常 - return status == cron.Active || status == cron.Waiting - } - - // 执行重复任务 - queue.RunJob(options, cron.JobOptions{ - JobId: sysJob.JobID, - Cron: sysJob.CronExpression, - }) - - return true -} - -// deleteQueueJob 删除调度任务 -func (r *SysJobImpl) deleteQueueJob(sysJob model.SysJob) bool { - // 获取队列 Processor - queue := cron.GetQueue(sysJob.InvokeTarget) - if queue.Name != sysJob.InvokeTarget { - return false - } - return queue.RemoveJob(sysJob.JobID) -} diff --git a/src/modules/monitor/service/sys_job_log.go b/src/modules/monitor/service/sys_job_log.go index b1e227e2..185c17a0 100644 --- a/src/modules/monitor/service/sys_job_log.go +++ b/src/modules/monitor/service/sys_job_log.go @@ -2,22 +2,41 @@ package service import ( "be.ems/src/modules/monitor/model" + "be.ems/src/modules/monitor/repository" ) -// ISysJobLog 调度任务日志 服务层接口 -type ISysJobLog interface { - // SelectJobLogPage 分页查询调度任务日志集合 - SelectJobLogPage(query map[string]any) map[string]any - - // SelectJobLogList 查询调度任务日志集合 - SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog - - // SelectJobLogById 通过调度ID查询调度任务日志信息 - SelectJobLogById(jobLogId string) model.SysJobLog - - // DeleteJobLogByIds 批量删除调度任务日志信息 - DeleteJobLogByIds(jobLogIds []string) int64 - - // CleanJobLog 清空调度任务日志 - CleanJobLog() error +// 实例化服务层 SysJobLog 结构体 +var NewSysJobLog = &SysJobLog{ + sysJobLogRepository: repository.NewSysJobLogImpl, +} + +// SysJobLog 调度任务日志 服务层处理 +type SysJobLog struct { + // 调度任务日志数据信息 + sysJobLogRepository repository.ISysJobLog +} + +// SelectJobLogPage 分页查询调度任务日志集合 +func (s *SysJobLog) SelectJobLogPage(query map[string]any) map[string]any { + return s.sysJobLogRepository.SelectJobLogPage(query) +} + +// SelectJobLogList 查询调度任务日志集合 +func (s *SysJobLog) SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog { + return s.sysJobLogRepository.SelectJobLogList(sysJobLog) +} + +// SelectJobLogById 通过调度ID查询调度任务日志信息 +func (s *SysJobLog) SelectJobLogById(jobLogId string) model.SysJobLog { + return s.sysJobLogRepository.SelectJobLogById(jobLogId) +} + +// DeleteJobLogByIds 批量删除调度任务日志信息 +func (s *SysJobLog) DeleteJobLogByIds(jobLogIds []string) int64 { + return s.sysJobLogRepository.DeleteJobLogByIds(jobLogIds) +} + +// CleanJobLog 清空调度任务日志 +func (s *SysJobLog) CleanJobLog() error { + return s.sysJobLogRepository.CleanJobLog() } diff --git a/src/modules/monitor/service/sys_job_log.impl.go b/src/modules/monitor/service/sys_job_log.impl.go deleted file mode 100644 index 692d40a3..00000000 --- a/src/modules/monitor/service/sys_job_log.impl.go +++ /dev/null @@ -1,42 +0,0 @@ -package service - -import ( - "be.ems/src/modules/monitor/model" - "be.ems/src/modules/monitor/repository" -) - -// 实例化服务层 SysJobLogImpl 结构体 -var NewSysJobLogImpl = &SysJobLogImpl{ - sysJobLogRepository: repository.NewSysJobLogImpl, -} - -// SysJobLogImpl 调度任务日志 服务层处理 -type SysJobLogImpl struct { - // 调度任务日志数据信息 - sysJobLogRepository repository.ISysJobLog -} - -// SelectJobLogPage 分页查询调度任务日志集合 -func (s *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any { - return s.sysJobLogRepository.SelectJobLogPage(query) -} - -// SelectJobLogList 查询调度任务日志集合 -func (s *SysJobLogImpl) SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog { - return s.sysJobLogRepository.SelectJobLogList(sysJobLog) -} - -// SelectJobLogById 通过调度ID查询调度任务日志信息 -func (s *SysJobLogImpl) SelectJobLogById(jobLogId string) model.SysJobLog { - return s.sysJobLogRepository.SelectJobLogById(jobLogId) -} - -// DeleteJobLogByIds 批量删除调度任务日志信息 -func (s *SysJobLogImpl) DeleteJobLogByIds(jobLogIds []string) int64 { - return s.sysJobLogRepository.DeleteJobLogByIds(jobLogIds) -} - -// CleanJobLog 清空调度任务日志 -func (s *SysJobLogImpl) CleanJobLog() error { - return s.sysJobLogRepository.CleanJobLog() -} diff --git a/src/modules/monitor/service/sys_user_online.go b/src/modules/monitor/service/sys_user_online.go index c6aef2cd..1d7115d8 100644 --- a/src/modules/monitor/service/sys_user_online.go +++ b/src/modules/monitor/service/sys_user_online.go @@ -5,8 +5,29 @@ import ( "be.ems/src/modules/monitor/model" ) -// ISysUserOnline 在线用户 服务层接口 -type ISysUserOnline interface { - // LoginUserToUserOnline 设置在线用户信息 - LoginUserToUserOnline(loginUser vo.LoginUser) model.SysUserOnline +// 实例化服务层 SysUserOnline 结构体 +var NewSysUserOnline = &SysUserOnline{} + +// SysUserOnline 在线用户 服务层处理 +type SysUserOnline struct{} + +// LoginUserToUserOnline 设置在线用户信息 +func (r *SysUserOnline) LoginUserToUserOnline(loginUser vo.LoginUser) model.SysUserOnline { + if loginUser.UserID == "" { + return model.SysUserOnline{} + } + + sysUserOnline := model.SysUserOnline{ + TokenID: loginUser.UUID, + UserName: loginUser.User.UserName, + IPAddr: loginUser.IPAddr, + LoginLocation: loginUser.LoginLocation, + Browser: loginUser.Browser, + OS: loginUser.OS, + LoginTime: loginUser.LoginTime, + } + if loginUser.User.DeptID != "" { + sysUserOnline.DeptName = loginUser.User.Dept.DeptName + } + return sysUserOnline } diff --git a/src/modules/monitor/service/sys_user_online.impl.go b/src/modules/monitor/service/sys_user_online.impl.go deleted file mode 100644 index 99c0ec4f..00000000 --- a/src/modules/monitor/service/sys_user_online.impl.go +++ /dev/null @@ -1,33 +0,0 @@ -package service - -import ( - "be.ems/src/framework/vo" - "be.ems/src/modules/monitor/model" -) - -// 实例化服务层 SysUserOnlineImpl 结构体 -var NewSysUserOnlineImpl = &SysUserOnlineImpl{} - -// SysUserOnlineImpl 在线用户 服务层处理 -type SysUserOnlineImpl struct{} - -// LoginUserToUserOnline 设置在线用户信息 -func (r *SysUserOnlineImpl) LoginUserToUserOnline(loginUser vo.LoginUser) model.SysUserOnline { - if loginUser.UserID == "" { - return model.SysUserOnline{} - } - - sysUserOnline := model.SysUserOnline{ - TokenID: loginUser.UUID, - UserName: loginUser.User.UserName, - IPAddr: loginUser.IPAddr, - LoginLocation: loginUser.LoginLocation, - Browser: loginUser.Browser, - OS: loginUser.OS, - LoginTime: loginUser.LoginTime, - } - if loginUser.User.DeptID != "" { - sysUserOnline.DeptName = loginUser.User.Dept.DeptName - } - return sysUserOnline -} diff --git a/src/modules/monitor/service/system_info.go b/src/modules/monitor/service/system_info.go index a6e9a51d..3fda7b7b 100644 --- a/src/modules/monitor/service/system_info.go +++ b/src/modules/monitor/service/system_info.go @@ -1,22 +1,177 @@ package service -// ISystemInfo 服务器系统相关信息 服务层接口 -type ISystemInfo interface { - // SystemInfo 系统信息 - SystemInfo() map[string]any +import ( + "context" + "fmt" + "os" + "runtime" + "strings" + "time" - // TimeInfo 系统时间信息 - TimeInfo() map[string]string + "be.ems/src/framework/config" + "be.ems/src/framework/utils/parse" - // MemoryInfo 内存信息 - MemoryInfo() map[string]any + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/disk" + "github.com/shirou/gopsutil/v4/host" + "github.com/shirou/gopsutil/v4/mem" + "github.com/shirou/gopsutil/v4/net" +) - // CPUInfo CPU信息 - CPUInfo() map[string]any +// 实例化服务层 SystemInfo 结构体 +var NewSystemInfo = &SystemInfo{} - // NetworkInfo 网络信息 - NetworkInfo() map[string]string +// SystemInfo 服务器系统相关信息 服务层处理 +type SystemInfo struct{} - // DiskInfo 磁盘信息 - DiskInfo() []map[string]string +// SystemInfo 系统信息 +func (s *SystemInfo) SystemInfo() map[string]any { + info, err := host.Info() + if err != nil { + info.Platform = err.Error() + } + // 获取主机运行时间 + bootTime := time.Since(time.Unix(int64(info.BootTime), 0)).Seconds() + // 获取程序运行时间 + runTime := time.Since(config.RunTime()).Abs().Seconds() + return map[string]any{ + "platform": info.Platform, + "platformVersion": info.PlatformVersion, + "arch": info.KernelArch, + "archVersion": info.KernelVersion, + "os": info.OS, + "hostname": info.Hostname, + "bootTime": int64(bootTime), + "processId": os.Getpid(), + "runArch": runtime.GOARCH, + "runVersion": runtime.Version(), + "runTime": int64(runTime), + } +} + +// TimeInfo 系统时间信息 +func (s *SystemInfo) TimeInfo() map[string]string { + now := time.Now() + // 获取当前时间 + current := now.Format("2006-01-02 15:04:05") + // 获取时区 + timezone := now.Format("-0700 MST") + // 获取时区名称 + timezoneName := now.Format("MST") + + return map[string]string{ + "current": current, + "timezone": timezone, + "timezoneName": timezoneName, + } +} + +// MemoryInfo 内存信息 +func (s *SystemInfo) MemoryInfo() map[string]any { + memInfo, err := mem.VirtualMemory() + if err != nil { + memInfo.UsedPercent = 0 + memInfo.Available = 0 + memInfo.Total = 0 + } + + var memStats runtime.MemStats + runtime.ReadMemStats(&memStats) + + return map[string]any{ + "usage": fmt.Sprintf("%.2f", memInfo.UsedPercent), // 内存利用率 + "freemem": parse.Bit(float64(memInfo.Available)), // 可用内存大小(GB) + "totalmem": parse.Bit(float64(memInfo.Total)), // 总内存大小(GB) + "rss": parse.Bit(float64(memStats.Sys)), // 常驻内存大小(RSS) + "heapTotal": parse.Bit(float64(memStats.HeapSys)), // 堆总大小 + "heapUsed": parse.Bit(float64(memStats.HeapAlloc)), // 堆已使用大小 + "external": parse.Bit(float64(memStats.Sys - memStats.HeapSys)), // 外部内存大小(非堆) + } +} + +// CPUInfo CPU信息 +func (s *SystemInfo) CPUInfo() map[string]any { + var core int = 0 + var speed string = "未知" + var model string = "未知" + cpuInfo, err := cpu.Info() + if err == nil { + core = runtime.NumCPU() + speed = fmt.Sprintf("%.0fMHz", cpuInfo[0].Mhz) + model = strings.TrimSpace(cpuInfo[0].ModelName) + } + + useds := []string{} + cpuPercent, err := cpu.Percent(0, true) + if err == nil { + for _, v := range cpuPercent { + useds = append(useds, fmt.Sprintf("%.2f", v)) + } + } + + return map[string]any{ + "model": model, + "speed": speed, + "core": core, + "coreUsed": useds, + } +} + +// NetworkInfo 网络信息 +func (s *SystemInfo) NetworkInfo() map[string]string { + ipAddrs := make(map[string]string) + interfaces, err := net.Interfaces() + if err == nil { + for _, iface := range interfaces { + name := iface.Name + if name[len(name)-1] == '0' { + name = name[0 : len(name)-1] + name = strings.Trim(name, "") + } + // ignore localhost + if name == "lo" { + continue + } + var addrs []string + for _, v := range iface.Addrs { + prefix := strings.Split(v.Addr, "/")[0] + if strings.Contains(prefix, "::") { + addrs = append(addrs, fmt.Sprintf("IPv6 %s", prefix)) + } + if strings.Contains(prefix, ".") { + addrs = append(addrs, fmt.Sprintf("IPv4 %s", prefix)) + } + } + ipAddrs[name] = strings.Join(addrs, " / ") + } + } + return ipAddrs +} + +// DiskInfo 磁盘信息 +func (s *SystemInfo) DiskInfo() []map[string]string { + disks := make([]map[string]string, 0) + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + + partitions, err := disk.PartitionsWithContext(ctx, false) + if err != nil && err != context.DeadlineExceeded { + return disks + } + + for _, partition := range partitions { + usage, err := disk.Usage(partition.Mountpoint) + if err != nil { + continue + } + disks = append(disks, map[string]string{ + "size": parse.Bit(float64(usage.Total)), + "used": parse.Bit(float64(usage.Used)), + "avail": parse.Bit(float64(usage.Free)), + "pcent": fmt.Sprintf("%.1f%%", usage.UsedPercent), + "target": partition.Device, + }) + } + return disks } diff --git a/src/modules/monitor/service/system_info.impl.go b/src/modules/monitor/service/system_info.impl.go deleted file mode 100644 index 43feba5c..00000000 --- a/src/modules/monitor/service/system_info.impl.go +++ /dev/null @@ -1,177 +0,0 @@ -package service - -import ( - "context" - "fmt" - "os" - "runtime" - "strings" - "time" - - "be.ems/src/framework/config" - "be.ems/src/framework/utils/parse" - - "github.com/shirou/gopsutil/v4/cpu" - "github.com/shirou/gopsutil/v4/disk" - "github.com/shirou/gopsutil/v4/host" - "github.com/shirou/gopsutil/v4/mem" - "github.com/shirou/gopsutil/v4/net" -) - -// 实例化服务层 SystemInfoImpl 结构体 -var NewSystemInfoImpl = &SystemInfoImpl{} - -// SystemInfoImpl 服务器系统相关信息 服务层处理 -type SystemInfoImpl struct{} - -// SystemInfo 系统信息 -func (s *SystemInfoImpl) SystemInfo() map[string]any { - info, err := host.Info() - if err != nil { - info.Platform = err.Error() - } - // 获取主机运行时间 - bootTime := time.Since(time.Unix(int64(info.BootTime), 0)).Seconds() - // 获取程序运行时间 - runTime := time.Since(config.RunTime()).Abs().Seconds() - return map[string]any{ - "platform": info.Platform, - "platformVersion": info.PlatformVersion, - "arch": info.KernelArch, - "archVersion": info.KernelVersion, - "os": info.OS, - "hostname": info.Hostname, - "bootTime": int64(bootTime), - "processId": os.Getpid(), - "runArch": runtime.GOARCH, - "runVersion": runtime.Version(), - "runTime": int64(runTime), - } -} - -// TimeInfo 系统时间信息 -func (s *SystemInfoImpl) TimeInfo() map[string]string { - now := time.Now() - // 获取当前时间 - current := now.Format("2006-01-02 15:04:05") - // 获取时区 - timezone := now.Format("-0700 MST") - // 获取时区名称 - timezoneName := now.Format("MST") - - return map[string]string{ - "current": current, - "timezone": timezone, - "timezoneName": timezoneName, - } -} - -// MemoryInfo 内存信息 -func (s *SystemInfoImpl) MemoryInfo() map[string]any { - memInfo, err := mem.VirtualMemory() - if err != nil { - memInfo.UsedPercent = 0 - memInfo.Available = 0 - memInfo.Total = 0 - } - - var memStats runtime.MemStats - runtime.ReadMemStats(&memStats) - - return map[string]any{ - "usage": fmt.Sprintf("%.2f", memInfo.UsedPercent), // 内存利用率 - "freemem": parse.Bit(float64(memInfo.Available)), // 可用内存大小(GB) - "totalmem": parse.Bit(float64(memInfo.Total)), // 总内存大小(GB) - "rss": parse.Bit(float64(memStats.Sys)), // 常驻内存大小(RSS) - "heapTotal": parse.Bit(float64(memStats.HeapSys)), // 堆总大小 - "heapUsed": parse.Bit(float64(memStats.HeapAlloc)), // 堆已使用大小 - "external": parse.Bit(float64(memStats.Sys - memStats.HeapSys)), // 外部内存大小(非堆) - } -} - -// CPUInfo CPU信息 -func (s *SystemInfoImpl) CPUInfo() map[string]any { - var core int = 0 - var speed string = "未知" - var model string = "未知" - cpuInfo, err := cpu.Info() - if err == nil { - core = runtime.NumCPU() - speed = fmt.Sprintf("%.0fMHz", cpuInfo[0].Mhz) - model = strings.TrimSpace(cpuInfo[0].ModelName) - } - - useds := []string{} - cpuPercent, err := cpu.Percent(0, true) - if err == nil { - for _, v := range cpuPercent { - useds = append(useds, fmt.Sprintf("%.2f", v)) - } - } - - return map[string]any{ - "model": model, - "speed": speed, - "core": core, - "coreUsed": useds, - } -} - -// NetworkInfo 网络信息 -func (s *SystemInfoImpl) NetworkInfo() map[string]string { - ipAddrs := make(map[string]string) - interfaces, err := net.Interfaces() - if err == nil { - for _, iface := range interfaces { - name := iface.Name - if name[len(name)-1] == '0' { - name = name[0 : len(name)-1] - name = strings.Trim(name, "") - } - // ignore localhost - if name == "lo" { - continue - } - var addrs []string - for _, v := range iface.Addrs { - prefix := strings.Split(v.Addr, "/")[0] - if strings.Contains(prefix, "::") { - addrs = append(addrs, fmt.Sprintf("IPv6 %s", prefix)) - } - if strings.Contains(prefix, ".") { - addrs = append(addrs, fmt.Sprintf("IPv4 %s", prefix)) - } - } - ipAddrs[name] = strings.Join(addrs, " / ") - } - } - return ipAddrs -} - -// DiskInfo 磁盘信息 -func (s *SystemInfoImpl) DiskInfo() []map[string]string { - disks := make([]map[string]string, 0) - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, 2*time.Second) - defer cancel() - - partitions, err := disk.PartitionsWithContext(ctx, false) - if err != nil && err != context.DeadlineExceeded { - return disks - } - - for _, partition := range partitions { - usage, err := disk.Usage(partition.Mountpoint) - if err != nil { - continue - } - disks = append(disks, map[string]string{ - "size": parse.Bit(float64(usage.Total)), - "used": parse.Bit(float64(usage.Used)), - "avail": parse.Bit(float64(usage.Free)), - "pcent": fmt.Sprintf("%.1f%%", usage.UsedPercent), - "target": partition.Device, - }) - } - return disks -} diff --git a/src/modules/network_data/controller/amf.go b/src/modules/network_data/controller/amf.go index a41e95c9..746cbc3b 100644 --- a/src/modules/network_data/controller/amf.go +++ b/src/modules/network_data/controller/amf.go @@ -119,11 +119,11 @@ func (s *AMFController) UEExport(c *gin.Context) { "E1": "Time", } // 读取字典数据 UE 事件类型 - dictUEEventType := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_type") + dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type") // 读取字典数据 UE 事件认证代码类型 - dictUEAauthCode := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_auth_code") + dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code") // 读取字典数据 UE 事件CM状态 - dictUEEventCmState := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_cm_state") + dictUEEventCmState := sysService.NewSysDictData.SelectDictDataByType("ue_event_cm_state") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { diff --git a/src/modules/network_data/controller/ims.go b/src/modules/network_data/controller/ims.go index 051ceb1b..60aff2bb 100644 --- a/src/modules/network_data/controller/ims.go +++ b/src/modules/network_data/controller/ims.go @@ -130,9 +130,9 @@ func (s *IMSController) CDRExport(c *gin.Context) { "H1": "Time", } // 读取字典数据 CDR SIP响应代码类别类型 - dictCDRSipCode := sysService.NewSysDictDataImpl.SelectDictDataByType("cdr_sip_code") + dictCDRSipCode := sysService.NewSysDictData.SelectDictDataByType("cdr_sip_code") // 读取字典数据 CDR 呼叫类型 - dictCDRCallType := sysService.NewSysDictDataImpl.SelectDictDataByType("cdr_call_type") + dictCDRCallType := sysService.NewSysDictData.SelectDictDataByType("cdr_call_type") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { diff --git a/src/modules/network_data/controller/mme.go b/src/modules/network_data/controller/mme.go index 1c61daa0..ac26d60b 100644 --- a/src/modules/network_data/controller/mme.go +++ b/src/modules/network_data/controller/mme.go @@ -120,11 +120,11 @@ func (s *MMEController) UEExport(c *gin.Context) { "E1": "Time", } // 读取字典数据 UE 事件类型 - dictUEEventType := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_type") + dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type") // 读取字典数据 UE 事件认证代码类型 - dictUEAauthCode := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_auth_code") + dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code") // 读取字典数据 UE 事件CM状态 - dictUEEventCmState := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_cm_state") + dictUEEventCmState := sysService.NewSysDictData.SelectDictDataByType("ue_event_cm_state") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { diff --git a/src/modules/system/controller/sys_dict_data.go b/src/modules/system/controller/sys_dict_data.go index 8e3d56bc..c3eec5f3 100644 --- a/src/modules/system/controller/sys_dict_data.go +++ b/src/modules/system/controller/sys_dict_data.go @@ -20,18 +20,16 @@ import ( // 实例化控制层 SysDictDataController 结构体 var NewSysDictData = &SysDictDataController{ - sysDictDataService: service.NewSysDictDataImpl, - sysDictTypeService: service.NewSysDictTypeImpl, + sysDictDataService: service.NewSysDictData, + sysDictTypeService: service.NewSysDictType, } // 字典类型对应的字典数据信息 // // PATH /system/dict/data type SysDictDataController struct { - // 字典数据服务 - sysDictDataService service.ISysDictData - // 字典类型服务 - sysDictTypeService service.ISysDictType + sysDictDataService *service.SysDictData // 字典数据服务 + sysDictTypeService *service.SysDictType // 字典类型服务 } // 字典数据列表 diff --git a/src/modules/system/controller/sys_dict_type.go b/src/modules/system/controller/sys_dict_type.go index 1af741e5..939cd3e3 100644 --- a/src/modules/system/controller/sys_dict_type.go +++ b/src/modules/system/controller/sys_dict_type.go @@ -21,15 +21,14 @@ import ( // 实例化控制层 SysDictTypeController 结构体 var NewSysDictType = &SysDictTypeController{ - sysDictTypeService: service.NewSysDictTypeImpl, + sysDictTypeService: service.NewSysDictType, } // 字典类型信息 // // PATH /system/dict/type type SysDictTypeController struct { - // 字典类型服务 - sysDictTypeService service.ISysDictType + sysDictTypeService *service.SysDictType // 字典类型服务 } // 字典类型列表 diff --git a/src/modules/system/controller/sys_role.go b/src/modules/system/controller/sys_role.go index 2300679c..c291c3fe 100644 --- a/src/modules/system/controller/sys_role.go +++ b/src/modules/system/controller/sys_role.go @@ -24,7 +24,7 @@ import ( var NewSysRole = &SysRoleController{ sysRoleService: service.NewSysRoleImpl, sysUserService: service.NewSysUserImpl, - sysDictDataService: service.NewSysDictDataImpl, + sysDictDataService: service.NewSysDictData, } // 角色信息 @@ -34,9 +34,8 @@ type SysRoleController struct { // 角色服务 sysRoleService service.ISysRole // 用户服务 - sysUserService service.ISysUser - // 字典数据服务 - sysDictDataService service.ISysDictData + sysUserService service.ISysUser + sysDictDataService *service.SysDictData // 字典数据服务 } // 角色列表 diff --git a/src/modules/system/controller/sys_user.go b/src/modules/system/controller/sys_user.go index 4eb2c10e..c6c521b4 100644 --- a/src/modules/system/controller/sys_user.go +++ b/src/modules/system/controller/sys_user.go @@ -28,7 +28,7 @@ var NewSysUser = &SysUserController{ sysUserService: service.NewSysUserImpl, sysRoleService: service.NewSysRoleImpl, sysPostService: service.NewSysPostImpl, - sysDictDataService: service.NewSysDictDataImpl, + sysDictDataService: service.NewSysDictData, sysConfigService: service.NewSysConfigImpl, } @@ -41,9 +41,8 @@ type SysUserController struct { // 角色服务 sysRoleService service.ISysRole // 岗位服务 - sysPostService service.ISysPost - // 字典数据服务 - sysDictDataService service.ISysDictData + sysPostService service.ISysPost + sysDictDataService *service.SysDictData // 字典数据服务 // 参数配置服务 sysConfigService service.ISysConfig } diff --git a/src/modules/system/repository/sys_dict_data.impl.go b/src/modules/system/repository/sys_dict_data.impl.go index 3782a14c..5231a2a6 100644 --- a/src/modules/system/repository/sys_dict_data.impl.go +++ b/src/modules/system/repository/sys_dict_data.impl.go @@ -13,7 +13,7 @@ import ( ) // 实例化数据层 SysDictDataImpl 结构体 -var NewSysDictDataImpl = &SysDictDataImpl{ +var NewSysDictData = &SysDictDataImpl{ selectSql: `select dict_code, dict_sort, dict_label, dict_value, dict_type, tag_class, tag_type, status, create_by, create_time, remark from sys_dict_data`, diff --git a/src/modules/system/repository/sys_dict_type.impl.go b/src/modules/system/repository/sys_dict_type.impl.go index 1da01121..db321360 100644 --- a/src/modules/system/repository/sys_dict_type.impl.go +++ b/src/modules/system/repository/sys_dict_type.impl.go @@ -13,7 +13,7 @@ import ( ) // 实例化数据层 SysDictTypeImpl 结构体 -var NewSysDictTypeImpl = &SysDictTypeImpl{ +var NewSysDictType = &SysDictTypeImpl{ selectSql: `select dict_id, dict_name, dict_type, status, create_by, create_time, remark from sys_dict_type`, diff --git a/src/modules/system/service/sys_dict_data.go b/src/modules/system/service/sys_dict_data.go index 716eb2ac..d5581078 100644 --- a/src/modules/system/service/sys_dict_data.go +++ b/src/modules/system/service/sys_dict_data.go @@ -1,33 +1,114 @@ package service -import "be.ems/src/modules/system/model" +import ( + "fmt" -// ISysDictData 字典类型数据 服务层接口 -type ISysDictData interface { - // SelectDictDataPage 根据条件分页查询字典数据 - SelectDictDataPage(query map[string]any) map[string]any + "be.ems/src/modules/system/model" + "be.ems/src/modules/system/repository" +) - // SelectDictDataList 根据条件查询字典数据 - SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData - - // SelectDictDataByCode 根据字典数据编码查询信息 - SelectDictDataByCode(dictCode string) model.SysDictData - - // SelectDictDataByType 根据字典类型查询信息 - SelectDictDataByType(dictType string) []model.SysDictData - - // CheckUniqueDictLabel 校验字典标签是否唯一 - CheckUniqueDictLabel(dictType, dictLabel, dictCode string) bool - - // CheckUniqueDictValue 校验字典键值是否唯一 - CheckUniqueDictValue(dictType, dictValue, dictCode string) bool - - // DeleteDictDataByCodes 批量删除字典数据信息 - DeleteDictDataByCodes(dictCodes []string) (int64, error) - - // InsertDictData 新增字典数据信息 - InsertDictData(sysDictData model.SysDictData) string - - // UpdateDictData 修改字典数据信息 - UpdateDictData(sysDictData model.SysDictData) int64 +// 实例化服务层 SysDictData 结构体 +var NewSysDictData = &SysDictData{ + sysDictDataRepository: repository.NewSysDictData, + sysDictTypeService: NewSysDictType, +} + +// SysDictData 字典类型数据 服务层处理 +type SysDictData struct { + sysDictDataRepository repository.ISysDictData // 字典数据服务 + sysDictTypeService *SysDictType // 字典类型服务 +} + +// SelectDictDataPage 根据条件分页查询字典数据 +func (r *SysDictData) SelectDictDataPage(query map[string]any) map[string]any { + return r.sysDictDataRepository.SelectDictDataPage(query) +} + +// SelectDictDataList 根据条件查询字典数据 +func (r *SysDictData) SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData { + return r.sysDictDataRepository.SelectDictDataList(sysDictData) +} + +// SelectDictDataByCode 根据字典数据编码查询信息 +func (r *SysDictData) SelectDictDataByCode(dictCode string) model.SysDictData { + if dictCode == "" { + return model.SysDictData{} + } + dictCodes := r.sysDictDataRepository.SelectDictDataByCodes([]string{dictCode}) + if len(dictCodes) > 0 { + return dictCodes[0] + } + return model.SysDictData{} +} + +// SelectDictDataByType 根据字典类型查询信息 +func (r *SysDictData) SelectDictDataByType(dictType string) []model.SysDictData { + return r.sysDictTypeService.DictDataCache(dictType) +} + +// CheckUniqueDictLabel 校验字典标签是否唯一 +func (r *SysDictData) CheckUniqueDictLabel(dictType, dictLabel, dictCode string) bool { + uniqueId := r.sysDictDataRepository.CheckUniqueDictData(model.SysDictData{ + DictType: dictType, + DictLabel: dictLabel, + }) + if uniqueId == dictCode { + return true + } + return uniqueId == "" +} + +// CheckUniqueDictValue 校验字典键值是否唯一 +func (r *SysDictData) CheckUniqueDictValue(dictType, dictValue, dictCode string) bool { + uniqueId := r.sysDictDataRepository.CheckUniqueDictData(model.SysDictData{ + DictType: dictType, + DictValue: dictValue, + }) + if uniqueId == dictCode { + return true + } + return uniqueId == "" +} + +// DeleteDictDataByCodes 批量删除字典数据信息 +func (r *SysDictData) DeleteDictDataByCodes(dictCodes []string) (int64, error) { + // 检查是否存在 + dictDatas := r.sysDictDataRepository.SelectDictDataByCodes(dictCodes) + if len(dictDatas) <= 0 { + // 没有可访问字典编码数据! + return 0, fmt.Errorf("there is no accessible dictionary-encoded data") + } + if len(dictDatas) == len(dictCodes) { + for _, v := range dictDatas { + // 刷新缓存 + r.sysDictTypeService.ClearDictCache(v.DictType) + r.sysDictTypeService.LoadingDictCache(v.DictType) + } + rows := r.sysDictDataRepository.DeleteDictDataByCodes(dictCodes) + return rows, nil + } + // 删除字典数据信息失败! + return 0, fmt.Errorf("failed to delete dictionary data information") +} + +// InsertDictData 新增字典数据信息 +func (r *SysDictData) InsertDictData(sysDictData model.SysDictData) string { + insertId := r.sysDictDataRepository.InsertDictData(sysDictData) + if insertId != "" { + // 刷新缓存 + r.sysDictTypeService.ClearDictCache(sysDictData.DictType) + r.sysDictTypeService.LoadingDictCache(sysDictData.DictType) + } + return insertId +} + +// UpdateDictData 修改字典数据信息 +func (r *SysDictData) UpdateDictData(sysDictData model.SysDictData) int64 { + rows := r.sysDictDataRepository.UpdateDictData(sysDictData) + if rows > 0 { + // 刷新缓存 + r.sysDictTypeService.ClearDictCache(sysDictData.DictType) + r.sysDictTypeService.LoadingDictCache(sysDictData.DictType) + } + return rows } diff --git a/src/modules/system/service/sys_dict_data.impl.go b/src/modules/system/service/sys_dict_data.impl.go deleted file mode 100644 index 13dcf89a..00000000 --- a/src/modules/system/service/sys_dict_data.impl.go +++ /dev/null @@ -1,116 +0,0 @@ -package service - -import ( - "fmt" - - "be.ems/src/modules/system/model" - "be.ems/src/modules/system/repository" -) - -// 实例化服务层 SysDictDataImpl 结构体 -var NewSysDictDataImpl = &SysDictDataImpl{ - sysDictDataRepository: repository.NewSysDictDataImpl, - sysDictTypeService: NewSysDictTypeImpl, -} - -// SysDictDataImpl 字典类型数据 服务层处理 -type SysDictDataImpl struct { - // 字典数据服务 - sysDictDataRepository repository.ISysDictData - // 字典类型服务 - sysDictTypeService ISysDictType -} - -// SelectDictDataPage 根据条件分页查询字典数据 -func (r *SysDictDataImpl) SelectDictDataPage(query map[string]any) map[string]any { - return r.sysDictDataRepository.SelectDictDataPage(query) -} - -// SelectDictDataList 根据条件查询字典数据 -func (r *SysDictDataImpl) SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData { - return r.sysDictDataRepository.SelectDictDataList(sysDictData) -} - -// SelectDictDataByCode 根据字典数据编码查询信息 -func (r *SysDictDataImpl) SelectDictDataByCode(dictCode string) model.SysDictData { - if dictCode == "" { - return model.SysDictData{} - } - dictCodes := r.sysDictDataRepository.SelectDictDataByCodes([]string{dictCode}) - if len(dictCodes) > 0 { - return dictCodes[0] - } - return model.SysDictData{} -} - -// SelectDictDataByType 根据字典类型查询信息 -func (r *SysDictDataImpl) SelectDictDataByType(dictType string) []model.SysDictData { - return r.sysDictTypeService.DictDataCache(dictType) -} - -// CheckUniqueDictLabel 校验字典标签是否唯一 -func (r *SysDictDataImpl) CheckUniqueDictLabel(dictType, dictLabel, dictCode string) bool { - uniqueId := r.sysDictDataRepository.CheckUniqueDictData(model.SysDictData{ - DictType: dictType, - DictLabel: dictLabel, - }) - if uniqueId == dictCode { - return true - } - return uniqueId == "" -} - -// CheckUniqueDictValue 校验字典键值是否唯一 -func (r *SysDictDataImpl) CheckUniqueDictValue(dictType, dictValue, dictCode string) bool { - uniqueId := r.sysDictDataRepository.CheckUniqueDictData(model.SysDictData{ - DictType: dictType, - DictValue: dictValue, - }) - if uniqueId == dictCode { - return true - } - return uniqueId == "" -} - -// DeleteDictDataByCodes 批量删除字典数据信息 -func (r *SysDictDataImpl) DeleteDictDataByCodes(dictCodes []string) (int64, error) { - // 检查是否存在 - dictDatas := r.sysDictDataRepository.SelectDictDataByCodes(dictCodes) - if len(dictDatas) <= 0 { - // 没有可访问字典编码数据! - return 0, fmt.Errorf("there is no accessible dictionary-encoded data") - } - if len(dictDatas) == len(dictCodes) { - for _, v := range dictDatas { - // 刷新缓存 - r.sysDictTypeService.ClearDictCache(v.DictType) - r.sysDictTypeService.LoadingDictCache(v.DictType) - } - rows := r.sysDictDataRepository.DeleteDictDataByCodes(dictCodes) - return rows, nil - } - // 删除字典数据信息失败! - return 0, fmt.Errorf("failed to delete dictionary data information") -} - -// InsertDictData 新增字典数据信息 -func (r *SysDictDataImpl) InsertDictData(sysDictData model.SysDictData) string { - insertId := r.sysDictDataRepository.InsertDictData(sysDictData) - if insertId != "" { - // 刷新缓存 - r.sysDictTypeService.ClearDictCache(sysDictData.DictType) - r.sysDictTypeService.LoadingDictCache(sysDictData.DictType) - } - return insertId -} - -// UpdateDictData 修改字典数据信息 -func (r *SysDictDataImpl) UpdateDictData(sysDictData model.SysDictData) int64 { - rows := r.sysDictDataRepository.UpdateDictData(sysDictData) - if rows > 0 { - // 刷新缓存 - r.sysDictTypeService.ClearDictCache(sysDictData.DictType) - r.sysDictTypeService.LoadingDictCache(sysDictData.DictType) - } - return rows -} diff --git a/src/modules/system/service/sys_dict_type.go b/src/modules/system/service/sys_dict_type.go index 5171d22b..4008b327 100644 --- a/src/modules/system/service/sys_dict_type.go +++ b/src/modules/system/service/sys_dict_type.go @@ -1,45 +1,212 @@ package service -import "be.ems/src/modules/system/model" +import ( + "encoding/json" + "fmt" -// ISysDictType 字典类型 服务层接口 -type ISysDictType interface { - // SelectDictTypePage 根据条件分页查询字典类型 - SelectDictTypePage(query map[string]any) map[string]any + "be.ems/src/framework/constants/cachekey" + "be.ems/src/framework/constants/common" + "be.ems/src/framework/redis" + "be.ems/src/modules/system/model" + "be.ems/src/modules/system/repository" +) - // SelectDictTypeList 根据条件查询字典类型 - SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType - - // SelectDictTypeByID 根据字典类型ID查询信息 - SelectDictTypeByID(dictID string) model.SysDictType - - // SelectDictTypeByType 根据字典类型查询信息 - SelectDictTypeByType(dictType string) model.SysDictType - - // CheckUniqueDictName 校验字典名称是否唯一 - CheckUniqueDictName(dictName, dictID string) bool - - // CheckUniqueDictType 校验字典类型是否唯一 - CheckUniqueDictType(dictType, dictID string) bool - - // InsertDictType 新增字典类型信息 - InsertDictType(sysDictType model.SysDictType) string - - // UpdateDictType 修改字典类型信息 - UpdateDictType(sysDictType model.SysDictType) int64 - - // DeleteDictTypeByIDs 批量删除字典类型信息 - DeleteDictTypeByIDs(dictIDs []string) (int64, error) - - // ResetDictCache 重置字典缓存数据 - ResetDictCache() - - // 加载字典缓存数据 - LoadingDictCache(dictType string) - - // 清空字典缓存数据 - ClearDictCache(dictType string) bool - - // DictDataCache 获取字典数据缓存数据 - DictDataCache(dictType string) []model.SysDictData +// 实例化服务层 SysDictType 结构体 +var NewSysDictType = &SysDictType{ + sysDictTypeRepository: repository.NewSysDictType, + sysDictDataRepository: repository.NewSysDictData, +} + +// SysDictType 字典类型 服务层处理 +type SysDictType struct { + // 字典类型服务 + sysDictTypeRepository repository.ISysDictType + // 字典数据服务 + sysDictDataRepository repository.ISysDictData +} + +// SelectDictTypePage 根据条件分页查询字典类型 +func (r *SysDictType) SelectDictTypePage(query map[string]any) map[string]any { + return r.sysDictTypeRepository.SelectDictTypePage(query) +} + +// SelectDictTypeList 根据条件查询字典类型 +func (r *SysDictType) SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType { + return r.sysDictTypeRepository.SelectDictTypeList(sysDictType) +} + +// SelectDictTypeByID 根据字典类型ID查询信息 +func (r *SysDictType) SelectDictTypeByID(dictID string) model.SysDictType { + if dictID == "" { + return model.SysDictType{} + } + dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{dictID}) + if len(dictTypes) > 0 { + return dictTypes[0] + } + return model.SysDictType{} +} + +// SelectDictTypeByType 根据字典类型查询信息 +func (r *SysDictType) SelectDictTypeByType(dictType string) model.SysDictType { + return r.sysDictTypeRepository.SelectDictTypeByType(dictType) +} + +// CheckUniqueDictName 校验字典名称是否唯一 +func (r *SysDictType) CheckUniqueDictName(dictName, dictID string) bool { + uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(model.SysDictType{ + DictName: dictName, + }) + if uniqueId == dictID { + return true + } + return uniqueId == "" +} + +// CheckUniqueDictType 校验字典类型是否唯一 +func (r *SysDictType) CheckUniqueDictType(dictType, dictID string) bool { + uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(model.SysDictType{ + DictType: dictType, + }) + if uniqueId == dictID { + return true + } + return uniqueId == "" +} + +// InsertDictType 新增字典类型信息 +func (r *SysDictType) InsertDictType(sysDictType model.SysDictType) string { + insertId := r.sysDictTypeRepository.InsertDictType(sysDictType) + if insertId != "" { + r.LoadingDictCache(sysDictType.DictType) + } + return insertId +} + +// UpdateDictType 修改字典类型信息 +func (r *SysDictType) UpdateDictType(sysDictType model.SysDictType) int64 { + data := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{sysDictType.DictID}) + if len(data) == 0 { + return 0 + } + // 修改字典类型key时同步更新其字典数据的类型key + oldDictType := data[0].DictType + rows := r.sysDictTypeRepository.UpdateDictType(sysDictType) + if rows > 0 && oldDictType != "" && oldDictType != sysDictType.DictType { + r.sysDictDataRepository.UpdateDictDataType(oldDictType, sysDictType.DictType) + } + // 刷新缓存 + r.ClearDictCache(oldDictType) + r.LoadingDictCache(sysDictType.DictType) + return rows +} + +// DeleteDictTypeByIDs 批量删除字典类型信息 +func (r *SysDictType) DeleteDictTypeByIDs(dictIDs []string) (int64, error) { + // 检查是否存在 + dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs(dictIDs) + if len(dictTypes) <= 0 { + // 没有可访问字典类型数据! + return 0, fmt.Errorf("there is no accessible dictionary type data") + } + for _, v := range dictTypes { + // 字典类型下级含有数据 + useCount := r.sysDictDataRepository.CountDictDataByType(v.DictType) + if useCount > 0 { + // 【%s】存在字典数据,不能删除 + return 0, fmt.Errorf("[%s] dictionary data exists and cannot be deleted", v.DictName) + } + // 清除缓存 + r.ClearDictCache(v.DictType) + } + if len(dictTypes) == len(dictIDs) { + rows := r.sysDictTypeRepository.DeleteDictTypeByIDs(dictIDs) + return rows, nil + } + // 删除字典数据信息失败! + return 0, fmt.Errorf("failed to delete dictionary data information") +} + +// ResetDictCache 重置字典缓存数据 +func (r *SysDictType) ResetDictCache() { + r.ClearDictCache("*") + r.LoadingDictCache("") +} + +// getCacheKey 组装缓存key +func (r *SysDictType) getDictCache(dictType string) string { + return cachekey.SYS_DICT_KEY + dictType +} + +// LoadingDictCache 加载字典缓存数据 +func (r *SysDictType) LoadingDictCache(dictType string) { + sysDictData := model.SysDictData{ + Status: common.STATUS_YES, + } + + // 指定字典类型 + if dictType != "" { + sysDictData.DictType = dictType + // 删除缓存 + key := r.getDictCache(dictType) + redis.Del("", key) + } + + sysDictDataList := r.sysDictDataRepository.SelectDictDataList(sysDictData) + if len(sysDictDataList) == 0 { + return + } + + // 将字典数据按类型分组 + m := make(map[string][]model.SysDictData, 0) + for _, v := range sysDictDataList { + key := v.DictType + if item, ok := m[key]; ok { + m[key] = append(item, v) + } else { + m[key] = []model.SysDictData{v} + } + } + + // 放入缓存 + for k, v := range m { + key := r.getDictCache(k) + values, _ := json.Marshal(v) + redis.Set("", key, string(values)) + } +} + +// ClearDictCache 清空字典缓存数据 +func (r *SysDictType) ClearDictCache(dictType string) bool { + key := r.getDictCache(dictType) + keys, err := redis.GetKeys("", key) + if err != nil { + return false + } + delOk, _ := redis.DelKeys("", keys) + return delOk +} + +// DictDataCache 获取字典数据缓存数据 +func (r *SysDictType) DictDataCache(dictType string) []model.SysDictData { + data := []model.SysDictData{} + key := r.getDictCache(dictType) + jsonStr, _ := redis.Get("", key) + if len(jsonStr) > 7 { + err := json.Unmarshal([]byte(jsonStr), &data) + if err != nil { + data = []model.SysDictData{} + } + } else { + data = r.sysDictDataRepository.SelectDictDataList(model.SysDictData{ + Status: common.STATUS_YES, + DictType: dictType, + }) + if len(data) > 0 { + redis.Del("", key) + values, _ := json.Marshal(data) + redis.Set("", key, string(values)) + } + } + return data } diff --git a/src/modules/system/service/sys_dict_type.impl.go b/src/modules/system/service/sys_dict_type.impl.go deleted file mode 100644 index 4f8c6d5c..00000000 --- a/src/modules/system/service/sys_dict_type.impl.go +++ /dev/null @@ -1,212 +0,0 @@ -package service - -import ( - "encoding/json" - "fmt" - - "be.ems/src/framework/constants/cachekey" - "be.ems/src/framework/constants/common" - "be.ems/src/framework/redis" - "be.ems/src/modules/system/model" - "be.ems/src/modules/system/repository" -) - -// 实例化服务层 SysDictTypeImpl 结构体 -var NewSysDictTypeImpl = &SysDictTypeImpl{ - sysDictTypeRepository: repository.NewSysDictTypeImpl, - sysDictDataRepository: repository.NewSysDictDataImpl, -} - -// SysDictTypeImpl 字典类型 服务层处理 -type SysDictTypeImpl struct { - // 字典类型服务 - sysDictTypeRepository repository.ISysDictType - // 字典数据服务 - sysDictDataRepository repository.ISysDictData -} - -// SelectDictTypePage 根据条件分页查询字典类型 -func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]any { - return r.sysDictTypeRepository.SelectDictTypePage(query) -} - -// SelectDictTypeList 根据条件查询字典类型 -func (r *SysDictTypeImpl) SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType { - return r.sysDictTypeRepository.SelectDictTypeList(sysDictType) -} - -// SelectDictTypeByID 根据字典类型ID查询信息 -func (r *SysDictTypeImpl) SelectDictTypeByID(dictID string) model.SysDictType { - if dictID == "" { - return model.SysDictType{} - } - dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{dictID}) - if len(dictTypes) > 0 { - return dictTypes[0] - } - return model.SysDictType{} -} - -// SelectDictTypeByType 根据字典类型查询信息 -func (r *SysDictTypeImpl) SelectDictTypeByType(dictType string) model.SysDictType { - return r.sysDictTypeRepository.SelectDictTypeByType(dictType) -} - -// CheckUniqueDictName 校验字典名称是否唯一 -func (r *SysDictTypeImpl) CheckUniqueDictName(dictName, dictID string) bool { - uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(model.SysDictType{ - DictName: dictName, - }) - if uniqueId == dictID { - return true - } - return uniqueId == "" -} - -// CheckUniqueDictType 校验字典类型是否唯一 -func (r *SysDictTypeImpl) CheckUniqueDictType(dictType, dictID string) bool { - uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(model.SysDictType{ - DictType: dictType, - }) - if uniqueId == dictID { - return true - } - return uniqueId == "" -} - -// InsertDictType 新增字典类型信息 -func (r *SysDictTypeImpl) InsertDictType(sysDictType model.SysDictType) string { - insertId := r.sysDictTypeRepository.InsertDictType(sysDictType) - if insertId != "" { - r.LoadingDictCache(sysDictType.DictType) - } - return insertId -} - -// UpdateDictType 修改字典类型信息 -func (r *SysDictTypeImpl) UpdateDictType(sysDictType model.SysDictType) int64 { - data := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{sysDictType.DictID}) - if len(data) == 0 { - return 0 - } - // 修改字典类型key时同步更新其字典数据的类型key - oldDictType := data[0].DictType - rows := r.sysDictTypeRepository.UpdateDictType(sysDictType) - if rows > 0 && oldDictType != "" && oldDictType != sysDictType.DictType { - r.sysDictDataRepository.UpdateDictDataType(oldDictType, sysDictType.DictType) - } - // 刷新缓存 - r.ClearDictCache(oldDictType) - r.LoadingDictCache(sysDictType.DictType) - return rows -} - -// DeleteDictTypeByIDs 批量删除字典类型信息 -func (r *SysDictTypeImpl) DeleteDictTypeByIDs(dictIDs []string) (int64, error) { - // 检查是否存在 - dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs(dictIDs) - if len(dictTypes) <= 0 { - // 没有可访问字典类型数据! - return 0, fmt.Errorf("there is no accessible dictionary type data") - } - for _, v := range dictTypes { - // 字典类型下级含有数据 - useCount := r.sysDictDataRepository.CountDictDataByType(v.DictType) - if useCount > 0 { - // 【%s】存在字典数据,不能删除 - return 0, fmt.Errorf("[%s] dictionary data exists and cannot be deleted", v.DictName) - } - // 清除缓存 - r.ClearDictCache(v.DictType) - } - if len(dictTypes) == len(dictIDs) { - rows := r.sysDictTypeRepository.DeleteDictTypeByIDs(dictIDs) - return rows, nil - } - // 删除字典数据信息失败! - return 0, fmt.Errorf("failed to delete dictionary data information") -} - -// ResetDictCache 重置字典缓存数据 -func (r *SysDictTypeImpl) ResetDictCache() { - r.ClearDictCache("*") - r.LoadingDictCache("") -} - -// getCacheKey 组装缓存key -func (r *SysDictTypeImpl) getDictCache(dictType string) string { - return cachekey.SYS_DICT_KEY + dictType -} - -// LoadingDictCache 加载字典缓存数据 -func (r *SysDictTypeImpl) LoadingDictCache(dictType string) { - sysDictData := model.SysDictData{ - Status: common.STATUS_YES, - } - - // 指定字典类型 - if dictType != "" { - sysDictData.DictType = dictType - // 删除缓存 - key := r.getDictCache(dictType) - redis.Del("", key) - } - - sysDictDataList := r.sysDictDataRepository.SelectDictDataList(sysDictData) - if len(sysDictDataList) == 0 { - return - } - - // 将字典数据按类型分组 - m := make(map[string][]model.SysDictData, 0) - for _, v := range sysDictDataList { - key := v.DictType - if item, ok := m[key]; ok { - m[key] = append(item, v) - } else { - m[key] = []model.SysDictData{v} - } - } - - // 放入缓存 - for k, v := range m { - key := r.getDictCache(k) - values, _ := json.Marshal(v) - redis.Set("", key, string(values)) - } -} - -// ClearDictCache 清空字典缓存数据 -func (r *SysDictTypeImpl) ClearDictCache(dictType string) bool { - key := r.getDictCache(dictType) - keys, err := redis.GetKeys("", key) - if err != nil { - return false - } - delOk, _ := redis.DelKeys("", keys) - return delOk -} - -// DictDataCache 获取字典数据缓存数据 -func (r *SysDictTypeImpl) DictDataCache(dictType string) []model.SysDictData { - data := []model.SysDictData{} - key := r.getDictCache(dictType) - jsonStr, _ := redis.Get("", key) - if len(jsonStr) > 7 { - err := json.Unmarshal([]byte(jsonStr), &data) - if err != nil { - data = []model.SysDictData{} - } - } else { - data = r.sysDictDataRepository.SelectDictDataList(model.SysDictData{ - Status: common.STATUS_YES, - DictType: dictType, - }) - if len(data) > 0 { - redis.Del("", key) - values, _ := json.Marshal(data) - redis.Set("", key, string(values)) - } - } - return data -} diff --git a/src/modules/system/system.go b/src/modules/system/system.go index 850f72eb..1331f83b 100644 --- a/src/modules/system/system.go +++ b/src/modules/system/system.go @@ -439,5 +439,5 @@ func InitLoad() { // 启动时,刷新缓存-参数配置 service.NewSysConfigImpl.ResetConfigCache() // 启动时,刷新缓存-字典类型数据 - service.NewSysDictTypeImpl.ResetDictCache() + service.NewSysDictType.ResetDictCache() }