style: 去除Impl接口声明层聚焦服务函数
This commit is contained in:
@@ -26,7 +26,7 @@ func ClearLocaleData() {
|
|||||||
// LoadLocaleData 加载国际化数据
|
// LoadLocaleData 加载国际化数据
|
||||||
func LoadLocaleData(language string) []localeItem {
|
func LoadLocaleData(language string) []localeItem {
|
||||||
dictType := fmt.Sprintf("i18n_%s", language)
|
dictType := fmt.Sprintf("i18n_%s", language)
|
||||||
dictTypeList := systemService.NewSysDictTypeImpl.DictDataCache(dictType)
|
dictTypeList := systemService.NewSysDictType.DictDataCache(dictType)
|
||||||
localeData := []localeItem{}
|
localeData := []localeItem{}
|
||||||
for _, v := range dictTypeList {
|
for _, v := range dictTypeList {
|
||||||
localeData = append(localeData, localeItem{
|
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)
|
item := sysDictDataService.SelectDictDataByCode(code)
|
||||||
if item.DictCode == code && item.DictLabel == key {
|
if item.DictCode == code && item.DictLabel == key {
|
||||||
item.DictValue = value
|
item.DictValue = value
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var NewProcessor = &MonitorSysResourceProcessor{
|
var NewProcessor = &MonitorSysResourceProcessor{
|
||||||
monitorService: monitorService.NewMonitorImpl,
|
monitorService: monitorService.NewMonitor,
|
||||||
count: 0,
|
count: 0,
|
||||||
openDataCancel: false,
|
openDataCancel: false,
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ var NewProcessor = &MonitorSysResourceProcessor{
|
|||||||
// MonitorSysResourceProcessor 系统资源CPU/IO/Netword收集
|
// MonitorSysResourceProcessor 系统资源CPU/IO/Netword收集
|
||||||
type MonitorSysResourceProcessor struct {
|
type MonitorSysResourceProcessor struct {
|
||||||
// 服务器系统相关信息服务
|
// 服务器系统相关信息服务
|
||||||
monitorService monitorService.IMonitor
|
monitorService *monitorService.Monitor
|
||||||
// 执行次数
|
// 执行次数
|
||||||
count int
|
count int
|
||||||
// 是否已经开启数据通道
|
// 是否已经开启数据通道
|
||||||
|
|||||||
@@ -11,15 +11,14 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 MonitorInfoController 结构体
|
// 实例化控制层 MonitorInfoController 结构体
|
||||||
var NewMonitor = &MonitorController{
|
var NewMonitor = &MonitorController{
|
||||||
monitorService: service.NewMonitorImpl,
|
monitorService: service.NewMonitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务器资源监控信息
|
// 服务器资源监控信息
|
||||||
//
|
//
|
||||||
// PATH /monitor
|
// PATH /monitor
|
||||||
type MonitorController struct {
|
type MonitorController struct {
|
||||||
// 服务器系统相关信息服务
|
monitorService *service.Monitor // 服务器系统相关信息服务
|
||||||
monitorService service.IMonitor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 资源监控信息加载
|
// 资源监控信息加载
|
||||||
|
|||||||
@@ -22,18 +22,16 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 SysJobLogController 结构体
|
// 实例化控制层 SysJobLogController 结构体
|
||||||
var NewSysJob = &SysJobController{
|
var NewSysJob = &SysJobController{
|
||||||
sysJobService: service.NewSysJobImpl,
|
sysJobService: service.NewSysJob,
|
||||||
sysDictDataService: systemService.NewSysDictDataImpl,
|
sysDictDataService: systemService.NewSysDictData,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调度任务信息
|
// 调度任务信息
|
||||||
//
|
//
|
||||||
// PATH /monitor/job
|
// PATH /monitor/job
|
||||||
type SysJobController struct {
|
type SysJobController struct {
|
||||||
// 调度任务服务
|
sysJobService *service.SysJob // 调度任务服务
|
||||||
sysJobService service.ISysJob
|
sysDictDataService *systemService.SysDictData // 字典数据服务
|
||||||
// 字典数据服务
|
|
||||||
sysDictDataService systemService.ISysDictData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调度任务列表
|
// 调度任务列表
|
||||||
|
|||||||
@@ -21,18 +21,16 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 SysJobLogController 结构体
|
// 实例化控制层 SysJobLogController 结构体
|
||||||
var NewSysJobLog = &SysJobLogController{
|
var NewSysJobLog = &SysJobLogController{
|
||||||
sysJobLogService: service.NewSysJobLogImpl,
|
sysJobLogService: service.NewSysJobLog,
|
||||||
sysDictDataService: systemService.NewSysDictDataImpl,
|
sysDictDataService: systemService.NewSysDictData,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调度任务日志信息
|
// 调度任务日志信息
|
||||||
//
|
//
|
||||||
// PATH /monitor/jobLog
|
// PATH /monitor/jobLog
|
||||||
type SysJobLogController struct {
|
type SysJobLogController struct {
|
||||||
// 调度任务日志服务
|
sysJobLogService *service.SysJobLog // 调度任务日志服务
|
||||||
sysJobLogService service.ISysJobLog
|
sysDictDataService *systemService.SysDictData // 字典数据服务
|
||||||
// 字典数据服务
|
|
||||||
sysDictDataService systemService.ISysDictData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调度任务日志列表
|
// 调度任务日志列表
|
||||||
@@ -44,7 +42,7 @@ func (s *SysJobLogController) List(c *gin.Context) {
|
|||||||
querys := ctx.QueryMap(c)
|
querys := ctx.QueryMap(c)
|
||||||
// 任务ID优先级更高
|
// 任务ID优先级更高
|
||||||
if v, ok := querys["jobId"]; ok && v != nil {
|
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["jobName"] = jobInfo.JobName
|
||||||
querys["jobGroup"] = jobInfo.JobGroup
|
querys["jobGroup"] = jobInfo.JobGroup
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,15 +19,14 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 SysUserOnlineController 结构体
|
// 实例化控制层 SysUserOnlineController 结构体
|
||||||
var NewSysUserOnline = &SysUserOnlineController{
|
var NewSysUserOnline = &SysUserOnlineController{
|
||||||
sysUserOnlineService: service.NewSysUserOnlineImpl,
|
sysUserOnlineService: service.NewSysUserOnline,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在线用户监控
|
// 在线用户监控
|
||||||
//
|
//
|
||||||
// PATH /monitor/online
|
// PATH /monitor/online
|
||||||
type SysUserOnlineController struct {
|
type SysUserOnlineController struct {
|
||||||
// 在线用户服务
|
sysUserOnlineService *service.SysUserOnline // 在线用户服务
|
||||||
sysUserOnlineService service.ISysUserOnline
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在线用户列表
|
// 在线用户列表
|
||||||
|
|||||||
@@ -9,15 +9,14 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 SystemInfoController 结构体
|
// 实例化控制层 SystemInfoController 结构体
|
||||||
var NewSystemInfo = &SystemInfoController{
|
var NewSystemInfo = &SystemInfoController{
|
||||||
systemInfogService: service.NewSystemInfoImpl,
|
systemInfogService: service.NewSystemInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务器监控信息
|
// 服务器监控信息
|
||||||
//
|
//
|
||||||
// PATH /monitor/system-info
|
// PATH /monitor/system-info
|
||||||
type SystemInfoController struct {
|
type SystemInfoController struct {
|
||||||
// 服务器系统相关信息服务
|
systemInfogService *service.SystemInfo // 服务器系统相关信息服务
|
||||||
systemInfogService service.ISystemInfo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务器信息
|
// 服务器信息
|
||||||
|
|||||||
@@ -165,5 +165,5 @@ func InitLoad() {
|
|||||||
// 初始化定时任务处理
|
// 初始化定时任务处理
|
||||||
processor.InitCronQueue()
|
processor.InitCronQueue()
|
||||||
// 启动时,初始化调度任务
|
// 启动时,初始化调度任务
|
||||||
service.NewSysJobImpl.ResetQueueJob()
|
service.NewSysJob.ResetQueueJob()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,274 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
// IMonitor 服务器系统相关信息 服务层接口
|
import (
|
||||||
type IMonitor interface {
|
"context"
|
||||||
// RunMonitor 执行资源监控
|
"strconv"
|
||||||
RunMonitor()
|
"time"
|
||||||
|
|
||||||
// RunMonitorDataCancel 启动资源监控数据存储io/network通道 移除之前的chan上下文后在设置新的均值
|
"be.ems/src/framework/logger"
|
||||||
// interval 采集的平均值(分钟)
|
"be.ems/src/modules/monitor/model"
|
||||||
RunMonitorDataCancel(removeBefore bool, interval float64)
|
"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 查询监控资源信息
|
// 实例化服务层 Monitor 结构体
|
||||||
SelectMonitorInfo(query map[string]any) map[string]any
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -12,10 +12,6 @@ import (
|
|||||||
"github.com/shirou/gopsutil/v4/net"
|
"github.com/shirou/gopsutil/v4/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfo(t *testing.T) {
|
func TestInfo(t *testing.T) {
|
||||||
s := MonitorInfo{}
|
s := MonitorInfo{}
|
||||||
s.load(0.5) // 0.5 半分钟
|
s.load(0.5) // 0.5 半分钟
|
||||||
@@ -36,17 +32,21 @@ func (m *MonitorInfo) load(interval float64) {
|
|||||||
var itemBase MonitorBase
|
var itemBase MonitorBase
|
||||||
itemBase.CreateTime = time.Now().UnixMilli()
|
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()
|
loadInfo, _ := load.Avg()
|
||||||
itemBase.CPULoad1 = loadInfo.Load1
|
itemBase.CPULoad1 = loadInfo.Load1
|
||||||
itemBase.CPULoad5 = loadInfo.Load5
|
itemBase.CPULoad5 = loadInfo.Load5
|
||||||
itemBase.CPULoad15 = loadInfo.Load15
|
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()
|
memoryInfo, _ := mem.VirtualMemory()
|
||||||
itemBase.Memory = memoryInfo.UsedPercent
|
itemBase.Memory = memoryInfo.UsedPercent
|
||||||
|
|||||||
@@ -1,35 +1,169 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"be.ems/src/framework/constants/common"
|
||||||
|
"be.ems/src/framework/cron"
|
||||||
"be.ems/src/modules/monitor/model"
|
"be.ems/src/modules/monitor/model"
|
||||||
|
"be.ems/src/modules/monitor/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ISysJob 调度任务信息 服务层接口
|
// 实例化服务层 SysJob 结构体
|
||||||
type ISysJob interface {
|
var NewSysJob = &SysJob{
|
||||||
// SelectJobPage 分页查询调度任务集合
|
sysJobRepository: repository.NewSysJobImpl,
|
||||||
SelectJobPage(query map[string]any) map[string]any
|
}
|
||||||
|
|
||||||
// SelectJobList 查询调度任务集合
|
// SysJob 调度任务 服务层处理
|
||||||
SelectJobList(sysJob model.SysJob) []model.SysJob
|
type SysJob struct {
|
||||||
|
// 调度任务数据信息
|
||||||
// SelectJobById 通过调度ID查询调度任务信息
|
sysJobRepository repository.ISysJob
|
||||||
SelectJobById(jobId string) model.SysJob
|
}
|
||||||
|
|
||||||
// CheckUniqueJobName 校验调度任务名称和组是否唯一
|
// SelectJobPage 分页查询调度任务集合
|
||||||
CheckUniqueJobName(jobName, jobGroup, jobId string) bool
|
func (r *SysJob) SelectJobPage(query map[string]any) map[string]any {
|
||||||
|
return r.sysJobRepository.SelectJobPage(query)
|
||||||
// InsertJob 新增调度任务信息
|
}
|
||||||
InsertJob(sysJob model.SysJob) string
|
|
||||||
|
// SelectJobList 查询调度任务集合
|
||||||
// UpdateJob 修改调度任务信息
|
func (r *SysJob) SelectJobList(sysJob model.SysJob) []model.SysJob {
|
||||||
UpdateJob(sysJob model.SysJob) int64
|
return r.sysJobRepository.SelectJobList(sysJob)
|
||||||
|
}
|
||||||
// DeleteJobByIds 批量删除调度任务信息
|
|
||||||
DeleteJobByIds(jobIds []string) (int64, error)
|
// SelectJobById 通过调度ID查询调度任务信息
|
||||||
|
func (r *SysJob) SelectJobById(jobId string) model.SysJob {
|
||||||
// RunQueueJob 立即运行一次调度任务
|
if jobId == "" {
|
||||||
RunQueueJob(sysJob model.SysJob) bool
|
return model.SysJob{}
|
||||||
|
}
|
||||||
// ResetQueueJob 重置初始调度任务
|
jobs := r.sysJobRepository.SelectJobByIds([]string{jobId})
|
||||||
ResetQueueJob()
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -2,22 +2,41 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"be.ems/src/modules/monitor/model"
|
"be.ems/src/modules/monitor/model"
|
||||||
|
"be.ems/src/modules/monitor/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ISysJobLog 调度任务日志 服务层接口
|
// 实例化服务层 SysJobLog 结构体
|
||||||
type ISysJobLog interface {
|
var NewSysJobLog = &SysJobLog{
|
||||||
// SelectJobLogPage 分页查询调度任务日志集合
|
sysJobLogRepository: repository.NewSysJobLogImpl,
|
||||||
SelectJobLogPage(query map[string]any) map[string]any
|
}
|
||||||
|
|
||||||
// SelectJobLogList 查询调度任务日志集合
|
// SysJobLog 调度任务日志 服务层处理
|
||||||
SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog
|
type SysJobLog struct {
|
||||||
|
// 调度任务日志数据信息
|
||||||
// SelectJobLogById 通过调度ID查询调度任务日志信息
|
sysJobLogRepository repository.ISysJobLog
|
||||||
SelectJobLogById(jobLogId string) model.SysJobLog
|
}
|
||||||
|
|
||||||
// DeleteJobLogByIds 批量删除调度任务日志信息
|
// SelectJobLogPage 分页查询调度任务日志集合
|
||||||
DeleteJobLogByIds(jobLogIds []string) int64
|
func (s *SysJobLog) SelectJobLogPage(query map[string]any) map[string]any {
|
||||||
|
return s.sysJobLogRepository.SelectJobLogPage(query)
|
||||||
// CleanJobLog 清空调度任务日志
|
}
|
||||||
CleanJobLog() error
|
|
||||||
|
// 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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,29 @@ import (
|
|||||||
"be.ems/src/modules/monitor/model"
|
"be.ems/src/modules/monitor/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ISysUserOnline 在线用户 服务层接口
|
// 实例化服务层 SysUserOnline 结构体
|
||||||
type ISysUserOnline interface {
|
var NewSysUserOnline = &SysUserOnline{}
|
||||||
// LoginUserToUserOnline 设置在线用户信息
|
|
||||||
LoginUserToUserOnline(loginUser vo.LoginUser) model.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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,177 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
// ISystemInfo 服务器系统相关信息 服务层接口
|
import (
|
||||||
type ISystemInfo interface {
|
"context"
|
||||||
// SystemInfo 系统信息
|
"fmt"
|
||||||
SystemInfo() map[string]any
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
// TimeInfo 系统时间信息
|
"be.ems/src/framework/config"
|
||||||
TimeInfo() map[string]string
|
"be.ems/src/framework/utils/parse"
|
||||||
|
|
||||||
// MemoryInfo 内存信息
|
"github.com/shirou/gopsutil/v4/cpu"
|
||||||
MemoryInfo() map[string]any
|
"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信息
|
// 实例化服务层 SystemInfo 结构体
|
||||||
CPUInfo() map[string]any
|
var NewSystemInfo = &SystemInfo{}
|
||||||
|
|
||||||
// NetworkInfo 网络信息
|
// SystemInfo 服务器系统相关信息 服务层处理
|
||||||
NetworkInfo() map[string]string
|
type SystemInfo struct{}
|
||||||
|
|
||||||
// DiskInfo 磁盘信息
|
// SystemInfo 系统信息
|
||||||
DiskInfo() []map[string]string
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -119,11 +119,11 @@ func (s *AMFController) UEExport(c *gin.Context) {
|
|||||||
"E1": "Time",
|
"E1": "Time",
|
||||||
}
|
}
|
||||||
// 读取字典数据 UE 事件类型
|
// 读取字典数据 UE 事件类型
|
||||||
dictUEEventType := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_type")
|
dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type")
|
||||||
// 读取字典数据 UE 事件认证代码类型
|
// 读取字典数据 UE 事件认证代码类型
|
||||||
dictUEAauthCode := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_auth_code")
|
dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code")
|
||||||
// 读取字典数据 UE 事件CM状态
|
// 读取字典数据 UE 事件CM状态
|
||||||
dictUEEventCmState := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_cm_state")
|
dictUEEventCmState := sysService.NewSysDictData.SelectDictDataByType("ue_event_cm_state")
|
||||||
// 从第二行开始的数据
|
// 从第二行开始的数据
|
||||||
dataCells := make([]map[string]any, 0)
|
dataCells := make([]map[string]any, 0)
|
||||||
for i, row := range rows {
|
for i, row := range rows {
|
||||||
|
|||||||
@@ -130,9 +130,9 @@ func (s *IMSController) CDRExport(c *gin.Context) {
|
|||||||
"H1": "Time",
|
"H1": "Time",
|
||||||
}
|
}
|
||||||
// 读取字典数据 CDR SIP响应代码类别类型
|
// 读取字典数据 CDR SIP响应代码类别类型
|
||||||
dictCDRSipCode := sysService.NewSysDictDataImpl.SelectDictDataByType("cdr_sip_code")
|
dictCDRSipCode := sysService.NewSysDictData.SelectDictDataByType("cdr_sip_code")
|
||||||
// 读取字典数据 CDR 呼叫类型
|
// 读取字典数据 CDR 呼叫类型
|
||||||
dictCDRCallType := sysService.NewSysDictDataImpl.SelectDictDataByType("cdr_call_type")
|
dictCDRCallType := sysService.NewSysDictData.SelectDictDataByType("cdr_call_type")
|
||||||
// 从第二行开始的数据
|
// 从第二行开始的数据
|
||||||
dataCells := make([]map[string]any, 0)
|
dataCells := make([]map[string]any, 0)
|
||||||
for i, row := range rows {
|
for i, row := range rows {
|
||||||
|
|||||||
@@ -120,11 +120,11 @@ func (s *MMEController) UEExport(c *gin.Context) {
|
|||||||
"E1": "Time",
|
"E1": "Time",
|
||||||
}
|
}
|
||||||
// 读取字典数据 UE 事件类型
|
// 读取字典数据 UE 事件类型
|
||||||
dictUEEventType := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_type")
|
dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type")
|
||||||
// 读取字典数据 UE 事件认证代码类型
|
// 读取字典数据 UE 事件认证代码类型
|
||||||
dictUEAauthCode := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_auth_code")
|
dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code")
|
||||||
// 读取字典数据 UE 事件CM状态
|
// 读取字典数据 UE 事件CM状态
|
||||||
dictUEEventCmState := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_cm_state")
|
dictUEEventCmState := sysService.NewSysDictData.SelectDictDataByType("ue_event_cm_state")
|
||||||
// 从第二行开始的数据
|
// 从第二行开始的数据
|
||||||
dataCells := make([]map[string]any, 0)
|
dataCells := make([]map[string]any, 0)
|
||||||
for i, row := range rows {
|
for i, row := range rows {
|
||||||
|
|||||||
@@ -20,18 +20,16 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 SysDictDataController 结构体
|
// 实例化控制层 SysDictDataController 结构体
|
||||||
var NewSysDictData = &SysDictDataController{
|
var NewSysDictData = &SysDictDataController{
|
||||||
sysDictDataService: service.NewSysDictDataImpl,
|
sysDictDataService: service.NewSysDictData,
|
||||||
sysDictTypeService: service.NewSysDictTypeImpl,
|
sysDictTypeService: service.NewSysDictType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 字典类型对应的字典数据信息
|
// 字典类型对应的字典数据信息
|
||||||
//
|
//
|
||||||
// PATH /system/dict/data
|
// PATH /system/dict/data
|
||||||
type SysDictDataController struct {
|
type SysDictDataController struct {
|
||||||
// 字典数据服务
|
sysDictDataService *service.SysDictData // 字典数据服务
|
||||||
sysDictDataService service.ISysDictData
|
sysDictTypeService *service.SysDictType // 字典类型服务
|
||||||
// 字典类型服务
|
|
||||||
sysDictTypeService service.ISysDictType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 字典数据列表
|
// 字典数据列表
|
||||||
|
|||||||
@@ -21,15 +21,14 @@ import (
|
|||||||
|
|
||||||
// 实例化控制层 SysDictTypeController 结构体
|
// 实例化控制层 SysDictTypeController 结构体
|
||||||
var NewSysDictType = &SysDictTypeController{
|
var NewSysDictType = &SysDictTypeController{
|
||||||
sysDictTypeService: service.NewSysDictTypeImpl,
|
sysDictTypeService: service.NewSysDictType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 字典类型信息
|
// 字典类型信息
|
||||||
//
|
//
|
||||||
// PATH /system/dict/type
|
// PATH /system/dict/type
|
||||||
type SysDictTypeController struct {
|
type SysDictTypeController struct {
|
||||||
// 字典类型服务
|
sysDictTypeService *service.SysDictType // 字典类型服务
|
||||||
sysDictTypeService service.ISysDictType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 字典类型列表
|
// 字典类型列表
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
var NewSysRole = &SysRoleController{
|
var NewSysRole = &SysRoleController{
|
||||||
sysRoleService: service.NewSysRoleImpl,
|
sysRoleService: service.NewSysRoleImpl,
|
||||||
sysUserService: service.NewSysUserImpl,
|
sysUserService: service.NewSysUserImpl,
|
||||||
sysDictDataService: service.NewSysDictDataImpl,
|
sysDictDataService: service.NewSysDictData,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 角色信息
|
// 角色信息
|
||||||
@@ -34,9 +34,8 @@ type SysRoleController struct {
|
|||||||
// 角色服务
|
// 角色服务
|
||||||
sysRoleService service.ISysRole
|
sysRoleService service.ISysRole
|
||||||
// 用户服务
|
// 用户服务
|
||||||
sysUserService service.ISysUser
|
sysUserService service.ISysUser
|
||||||
// 字典数据服务
|
sysDictDataService *service.SysDictData // 字典数据服务
|
||||||
sysDictDataService service.ISysDictData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 角色列表
|
// 角色列表
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ var NewSysUser = &SysUserController{
|
|||||||
sysUserService: service.NewSysUserImpl,
|
sysUserService: service.NewSysUserImpl,
|
||||||
sysRoleService: service.NewSysRoleImpl,
|
sysRoleService: service.NewSysRoleImpl,
|
||||||
sysPostService: service.NewSysPostImpl,
|
sysPostService: service.NewSysPostImpl,
|
||||||
sysDictDataService: service.NewSysDictDataImpl,
|
sysDictDataService: service.NewSysDictData,
|
||||||
sysConfigService: service.NewSysConfigImpl,
|
sysConfigService: service.NewSysConfigImpl,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +41,8 @@ type SysUserController struct {
|
|||||||
// 角色服务
|
// 角色服务
|
||||||
sysRoleService service.ISysRole
|
sysRoleService service.ISysRole
|
||||||
// 岗位服务
|
// 岗位服务
|
||||||
sysPostService service.ISysPost
|
sysPostService service.ISysPost
|
||||||
// 字典数据服务
|
sysDictDataService *service.SysDictData // 字典数据服务
|
||||||
sysDictDataService service.ISysDictData
|
|
||||||
// 参数配置服务
|
// 参数配置服务
|
||||||
sysConfigService service.ISysConfig
|
sysConfigService service.ISysConfig
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 实例化数据层 SysDictDataImpl 结构体
|
// 实例化数据层 SysDictDataImpl 结构体
|
||||||
var NewSysDictDataImpl = &SysDictDataImpl{
|
var NewSysDictData = &SysDictDataImpl{
|
||||||
selectSql: `select
|
selectSql: `select
|
||||||
dict_code, dict_sort, dict_label, dict_value, dict_type, tag_class, tag_type, status, create_by, create_time, remark
|
dict_code, dict_sort, dict_label, dict_value, dict_type, tag_class, tag_type, status, create_by, create_time, remark
|
||||||
from sys_dict_data`,
|
from sys_dict_data`,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 实例化数据层 SysDictTypeImpl 结构体
|
// 实例化数据层 SysDictTypeImpl 结构体
|
||||||
var NewSysDictTypeImpl = &SysDictTypeImpl{
|
var NewSysDictType = &SysDictTypeImpl{
|
||||||
selectSql: `select
|
selectSql: `select
|
||||||
dict_id, dict_name, dict_type, status, create_by, create_time, remark
|
dict_id, dict_name, dict_type, status, create_by, create_time, remark
|
||||||
from sys_dict_type`,
|
from sys_dict_type`,
|
||||||
|
|||||||
@@ -1,33 +1,114 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import "be.ems/src/modules/system/model"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
// ISysDictData 字典类型数据 服务层接口
|
"be.ems/src/modules/system/model"
|
||||||
type ISysDictData interface {
|
"be.ems/src/modules/system/repository"
|
||||||
// SelectDictDataPage 根据条件分页查询字典数据
|
)
|
||||||
SelectDictDataPage(query map[string]any) map[string]any
|
|
||||||
|
|
||||||
// SelectDictDataList 根据条件查询字典数据
|
// 实例化服务层 SysDictData 结构体
|
||||||
SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData
|
var NewSysDictData = &SysDictData{
|
||||||
|
sysDictDataRepository: repository.NewSysDictData,
|
||||||
// SelectDictDataByCode 根据字典数据编码查询信息
|
sysDictTypeService: NewSysDictType,
|
||||||
SelectDictDataByCode(dictCode string) model.SysDictData
|
}
|
||||||
|
|
||||||
// SelectDictDataByType 根据字典类型查询信息
|
// SysDictData 字典类型数据 服务层处理
|
||||||
SelectDictDataByType(dictType string) []model.SysDictData
|
type SysDictData struct {
|
||||||
|
sysDictDataRepository repository.ISysDictData // 字典数据服务
|
||||||
// CheckUniqueDictLabel 校验字典标签是否唯一
|
sysDictTypeService *SysDictType // 字典类型服务
|
||||||
CheckUniqueDictLabel(dictType, dictLabel, dictCode string) bool
|
}
|
||||||
|
|
||||||
// CheckUniqueDictValue 校验字典键值是否唯一
|
// SelectDictDataPage 根据条件分页查询字典数据
|
||||||
CheckUniqueDictValue(dictType, dictValue, dictCode string) bool
|
func (r *SysDictData) SelectDictDataPage(query map[string]any) map[string]any {
|
||||||
|
return r.sysDictDataRepository.SelectDictDataPage(query)
|
||||||
// DeleteDictDataByCodes 批量删除字典数据信息
|
}
|
||||||
DeleteDictDataByCodes(dictCodes []string) (int64, error)
|
|
||||||
|
// SelectDictDataList 根据条件查询字典数据
|
||||||
// InsertDictData 新增字典数据信息
|
func (r *SysDictData) SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData {
|
||||||
InsertDictData(sysDictData model.SysDictData) string
|
return r.sysDictDataRepository.SelectDictDataList(sysDictData)
|
||||||
|
}
|
||||||
// UpdateDictData 修改字典数据信息
|
|
||||||
UpdateDictData(sysDictData model.SysDictData) int64
|
// 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -1,45 +1,212 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import "be.ems/src/modules/system/model"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
// ISysDictType 字典类型 服务层接口
|
"be.ems/src/framework/constants/cachekey"
|
||||||
type ISysDictType interface {
|
"be.ems/src/framework/constants/common"
|
||||||
// SelectDictTypePage 根据条件分页查询字典类型
|
"be.ems/src/framework/redis"
|
||||||
SelectDictTypePage(query map[string]any) map[string]any
|
"be.ems/src/modules/system/model"
|
||||||
|
"be.ems/src/modules/system/repository"
|
||||||
|
)
|
||||||
|
|
||||||
// SelectDictTypeList 根据条件查询字典类型
|
// 实例化服务层 SysDictType 结构体
|
||||||
SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType
|
var NewSysDictType = &SysDictType{
|
||||||
|
sysDictTypeRepository: repository.NewSysDictType,
|
||||||
// SelectDictTypeByID 根据字典类型ID查询信息
|
sysDictDataRepository: repository.NewSysDictData,
|
||||||
SelectDictTypeByID(dictID string) model.SysDictType
|
}
|
||||||
|
|
||||||
// SelectDictTypeByType 根据字典类型查询信息
|
// SysDictType 字典类型 服务层处理
|
||||||
SelectDictTypeByType(dictType string) model.SysDictType
|
type SysDictType struct {
|
||||||
|
// 字典类型服务
|
||||||
// CheckUniqueDictName 校验字典名称是否唯一
|
sysDictTypeRepository repository.ISysDictType
|
||||||
CheckUniqueDictName(dictName, dictID string) bool
|
// 字典数据服务
|
||||||
|
sysDictDataRepository repository.ISysDictData
|
||||||
// CheckUniqueDictType 校验字典类型是否唯一
|
}
|
||||||
CheckUniqueDictType(dictType, dictID string) bool
|
|
||||||
|
// SelectDictTypePage 根据条件分页查询字典类型
|
||||||
// InsertDictType 新增字典类型信息
|
func (r *SysDictType) SelectDictTypePage(query map[string]any) map[string]any {
|
||||||
InsertDictType(sysDictType model.SysDictType) string
|
return r.sysDictTypeRepository.SelectDictTypePage(query)
|
||||||
|
}
|
||||||
// UpdateDictType 修改字典类型信息
|
|
||||||
UpdateDictType(sysDictType model.SysDictType) int64
|
// SelectDictTypeList 根据条件查询字典类型
|
||||||
|
func (r *SysDictType) SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType {
|
||||||
// DeleteDictTypeByIDs 批量删除字典类型信息
|
return r.sysDictTypeRepository.SelectDictTypeList(sysDictType)
|
||||||
DeleteDictTypeByIDs(dictIDs []string) (int64, error)
|
}
|
||||||
|
|
||||||
// ResetDictCache 重置字典缓存数据
|
// SelectDictTypeByID 根据字典类型ID查询信息
|
||||||
ResetDictCache()
|
func (r *SysDictType) SelectDictTypeByID(dictID string) model.SysDictType {
|
||||||
|
if dictID == "" {
|
||||||
// 加载字典缓存数据
|
return model.SysDictType{}
|
||||||
LoadingDictCache(dictType string)
|
}
|
||||||
|
dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{dictID})
|
||||||
// 清空字典缓存数据
|
if len(dictTypes) > 0 {
|
||||||
ClearDictCache(dictType string) bool
|
return dictTypes[0]
|
||||||
|
}
|
||||||
// DictDataCache 获取字典数据缓存数据
|
return model.SysDictType{}
|
||||||
DictDataCache(dictType string) []model.SysDictData
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -439,5 +439,5 @@ func InitLoad() {
|
|||||||
// 启动时,刷新缓存-参数配置
|
// 启动时,刷新缓存-参数配置
|
||||||
service.NewSysConfigImpl.ResetConfigCache()
|
service.NewSysConfigImpl.ResetConfigCache()
|
||||||
// 启动时,刷新缓存-字典类型数据
|
// 启动时,刷新缓存-字典类型数据
|
||||||
service.NewSysDictTypeImpl.ResetDictCache()
|
service.NewSysDictType.ResetDictCache()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user