diff --git a/boot/boot.go b/boot/boot.go index 587ec10..58d4405 100644 --- a/boot/boot.go +++ b/boot/boot.go @@ -41,16 +41,26 @@ func initDb() { func initConfiguration() { defer func() { if err := recover(); err != nil { - panic("config init fail") + log.Panic("config init fail", err) } }() + configKvMap := map[string]string{} + + data, err := repository.ConfigRepository.GetAllConfig() + if err != nil { + panic(err) + } + for _, v := range data { + configKvMap[v.Key] = *v.Value + } + typeElem := reflect.TypeOf(config.CF).Elem() valueElem := reflect.ValueOf(config.CF).Elem() for i := 0; i < typeElem.NumField(); i++ { typeField := typeElem.Field(i) valueField := valueElem.Field(i) - value, err := repository.ConfigRepository.GetConfigValue(typeField.Name) - if err != nil { + value, ok := configKvMap[typeField.Name] + if !ok { value = typeField.Tag.Get("default") } if value == "-" { diff --git a/internal/app/api/event.go b/internal/app/api/event.go new file mode 100644 index 0000000..9b0269e --- /dev/null +++ b/internal/app/api/event.go @@ -0,0 +1,22 @@ +package api + +import ( + "github.com/gin-gonic/gin" + "github.com/lzh-1625/go_process_manager/internal/app/logic" + "github.com/lzh-1625/go_process_manager/internal/app/model" +) + +type eventApi struct{} + +var EventApi = new(eventApi) + +func (e *eventApi) GetEventList(ctx *gin.Context, req model.EventListReq) any { + data, total, err := logic.EventLogic.Get(req) + if err != nil { + return err + } + return model.EventListResp{ + Total: total, + Data: data, + } +} diff --git a/internal/app/logic/event.go b/internal/app/logic/event.go index 0542312..d2b05a7 100644 --- a/internal/app/logic/event.go +++ b/internal/app/logic/event.go @@ -33,3 +33,7 @@ func (e *eventLogic) Create(name string, eventType eum.EventType, additionalKv . log.Logger.Errorw("事件创建失败", "err", err) } } + +func (e *eventLogic) Get(req model.EventListReq) ([]*model.Event, int64, error) { + return repository.EventRepository.GetList(req) +} diff --git a/internal/app/logic/task.go b/internal/app/logic/task.go index c8d1e29..10680fa 100644 --- a/internal/app/logic/task.go +++ b/internal/app/logic/task.go @@ -2,6 +2,8 @@ package logic import ( "context" + "errors" + "strconv" "time" "github.com/google/uuid" @@ -35,12 +37,14 @@ func NewTaskJob(data model.Task) (*TaskJob, error) { return tj, nil } -func (t *TaskJob) Run(ctx context.Context) { +func (t *TaskJob) Run(ctx context.Context) (err error) { if ctx.Value(eum.CtxTaskTraceId{}) == nil { ctx = context.WithValue(ctx, eum.CtxTaskTraceId{}, uuid.NewString()) } EventLogic.Create(t.TaskConfig.Name, eum.EventTaskStart, "traceId", ctx.Value(eum.CtxTaskTraceId{}).(string)) - defer EventLogic.Create(t.TaskConfig.Name, eum.EventTaskStop, "traceId", ctx.Value(eum.CtxTaskTraceId{}).(string)) + defer func() { + EventLogic.Create(t.TaskConfig.Name, eum.EventTaskStop, "traceId", ctx.Value(eum.CtxTaskTraceId{}).(string), "success", strconv.FormatBool(err == nil)) + }() t.Running = true middle.TaskWaitCond.Trigger() defer func() { @@ -48,11 +52,12 @@ func (t *TaskJob) Run(ctx context.Context) { middle.TaskWaitCond.Trigger() }() var ok bool + var proc *ProcessBase // 判断条件是否满足 - if t.TaskConfig.Condition == eum.TaskCondPass { + if t.TaskConfig.Condition == eum.TaskCondPass || t.TaskConfig.ProcessId == 0 { ok = true } else { - proc, err := ProcessCtlLogic.GetProcess(t.TaskConfig.OperationTarget) + proc, err = ProcessCtlLogic.GetProcess(t.TaskConfig.OperationTarget) if err != nil { return } @@ -63,7 +68,7 @@ func (t *TaskJob) Run(ctx context.Context) { return } - proc, err := ProcessCtlLogic.GetProcess(t.TaskConfig.OperationTarget) + proc, err = ProcessCtlLogic.GetProcess(t.TaskConfig.OperationTarget) if err != nil { log.Logger.Debugw("不存在该进程,结束任务") return @@ -73,12 +78,14 @@ func (t *TaskJob) Run(ctx context.Context) { log.Logger.Infow("任务开始执行") if !OperationHandle[t.TaskConfig.Operation](t.TaskConfig, proc) { log.Logger.Warnw("任务执行失败") + err = errors.New("task execute failed") return } log.Logger.Infow("任务执行成功", "target", t.TaskConfig.OperationTarget) if t.TaskConfig.NextId != nil { - nextTask, err := TaskLogic.getTaskJob(*t.TaskConfig.NextId) + var nextTask *TaskJob + nextTask, err = TaskLogic.getTaskJob(*t.TaskConfig.NextId) if err != nil { log.Logger.Errorw("无法获取到下一个节点,结束任务", "nextId", t.TaskConfig.NextId) return @@ -92,11 +99,12 @@ func (t *TaskJob) Run(ctx context.Context) { log.Logger.Errorw("下一个节点已在运行,结束任务", "nextId", t.TaskConfig.NextId) return } - nextTask.Run(ctx) + err = nextTask.Run(ctx) } } else { log.Logger.Infow("任务流结束") } + return } func (t *TaskJob) InitCronHandle() error { diff --git a/internal/app/model/event.go b/internal/app/model/event.go index a8fef44..781d231 100644 --- a/internal/app/model/event.go +++ b/internal/app/model/event.go @@ -17,3 +17,17 @@ type Event struct { func (*Event) TableName() string { return "event" } + +type EventListReq struct { + Page int `form:"page"` + Size int `form:"size"` + StartTime int64 `form:"startTime"` + EndTime int64 `form:"endTime"` + Type eum.EventType `form:"type"` + Name string `form:"name"` +} + +type EventListResp struct { + Total int64 `json:"total"` + Data []*Event `json:"data"` +} diff --git a/internal/app/repository/config.go b/internal/app/repository/config.go index 33d682c..bad2b69 100644 --- a/internal/app/repository/config.go +++ b/internal/app/repository/config.go @@ -19,6 +19,11 @@ func (c *configRepository) GetConfigValue(key string) (string, error) { return *data.Value, err } +func (c *configRepository) GetAllConfig() ([]*model.Config, error) { + data, err := query.Config.Select(query.Config.Value).Find() + return data, err +} + func (c *configRepository) SetConfigValue(key, value string) error { config := model.Config{Key: key} updateData := model.Config{Value: &value} diff --git a/internal/app/repository/event.go b/internal/app/repository/event.go index 78defd4..5f3e80b 100644 --- a/internal/app/repository/event.go +++ b/internal/app/repository/event.go @@ -1,6 +1,9 @@ package repository import ( + "context" + "time" + "github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/lzh-1625/go_process_manager/internal/app/repository/query" ) @@ -12,3 +15,21 @@ var EventRepository = new(eventRepository) func (e *eventRepository) Create(event model.Event) error { return query.Event.Create(&event) } + +func (e *eventRepository) GetList(req model.EventListReq) ([]*model.Event, int64, error) { + tx := query.Event.WithContext(context.TODO()) + + if req.StartTime != 0 { + tx = tx.Where(query.Event.CreatedTime.Gte(time.Unix(req.StartTime, 0))) + } + if req.EndTime != 0 { + tx = tx.Where(query.Event.CreatedTime.Lte(time.Unix(req.EndTime, 0))) + } + if req.Type != "" { + tx = tx.Where(query.Event.Type.Eq(string(req.Type))) + } + if req.Name != "" { + tx = tx.Where(query.Event.Name.Like("%" + req.Name + "%")) + } + return tx.Order(query.Event.CreatedTime.Desc()).FindByPage((req.Page-1)*req.Size, req.Size) +} diff --git a/internal/app/route/route.go b/internal/app/route/route.go index 12b61bf..da34a32 100644 --- a/internal/app/route/route.go +++ b/internal/app/route/route.go @@ -122,6 +122,11 @@ func routePathInit(r *gin.Engine) { fileGroup.GET("", bind(api.FileApi.FileReadHandler, Query)) } + eventGroup := apiGroup.Group("/event").Use(middle.RolePermission(eum.RoleAdmin)) + { + eventGroup.GET("", bind(api.EventApi.GetEventList, Query)) + } + permissionGroup := apiGroup.Group("/permission").Use(middle.RolePermission(eum.RoleRoot)) { permissionGroup.GET("/list", bind(api.PermissionApi.GetPermissionList, Query)) @@ -138,7 +143,7 @@ func routePathInit(r *gin.Engine) { { configGroup.GET("", bind(api.ConfigApi.GetSystemConfiguration, None)) configGroup.PUT("", bind(api.ConfigApi.SetSystemConfiguration, None)) - configGroup.GET("/reload", bind(api.ConfigApi.LogConfigReload, None)) + configGroup.PUT("/reload", bind(api.ConfigApi.LogConfigReload, None)) } } } diff --git a/resources/src/api/event.ts b/resources/src/api/event.ts new file mode 100644 index 0000000..a3ac49c --- /dev/null +++ b/resources/src/api/event.ts @@ -0,0 +1,7 @@ +import api from "./api"; +import type { EventListReq, EventListResp } from "../types/event/event"; + +export function getEventList(params: EventListReq) { + return api.get("/event", params).then((res) => res); +} + diff --git a/resources/src/components/navigation/MainMenu.vue b/resources/src/components/navigation/MainMenu.vue index 081535e..e87849c 100644 --- a/resources/src/components/navigation/MainMenu.vue +++ b/resources/src/components/navigation/MainMenu.vue @@ -12,7 +12,7 @@ const props = defineProps({ diff --git a/resources/src/configs/menus/log.menus.ts b/resources/src/configs/menus/log.menus.ts index e4240bd..e365a80 100644 --- a/resources/src/configs/menus/log.menus.ts +++ b/resources/src/configs/menus/log.menus.ts @@ -5,7 +5,14 @@ export default [ key: "menu.log", link: "/log", }, + { + icon: "mdi-bell-ring", + name: "event-page", + key: "menu.event", + link: "/event", + }, ]; + diff --git a/resources/src/configs/menus/settings.menus.ts b/resources/src/configs/menus/settings.menus.ts index c08b89f..981223c 100644 --- a/resources/src/configs/menus/settings.menus.ts +++ b/resources/src/configs/menus/settings.menus.ts @@ -5,5 +5,11 @@ export default [ text: "系统设置", link: "/settings", }, + { + icon: "mdi-bell-ring", + key: "menu.push", + text: "推送管理", + link: "/settings/push", + }, ]; diff --git a/resources/src/configs/navigation.ts b/resources/src/configs/navigation.ts index edb1c2b..6be341c 100644 --- a/resources/src/configs/navigation.ts +++ b/resources/src/configs/navigation.ts @@ -27,34 +27,42 @@ export default { }, { text: "process", + key: "menu.group.process", items: menuProcess, }, { text: "task", + key: "menu.group.task", items: menuTask, }, { text: "log", + key: "menu.group.log", items: menuLog, }, { text: "user", + key: "menu.group.user", items: menuUser, }, { text: "settings", + key: "menu.group.settings", items: menuSettings, }, { text: "Apps", + key: "menu.group.apps", items: menuApps, }, { text: "Data", + key: "menu.group.data", items: menuData, }, { text: "Landing", + key: "menu.group.landing", items: [ ...menuLanding, // { @@ -68,21 +76,22 @@ export default { { text: "UI - Theme Preview", + key: "menu.group.ui", items: menuUI, }, { text: "Pages", - key: "menu.pages", + key: "menu.group.pages", items: menuPages, }, { text: "Charts", - key: "menu.charts", + key: "menu.group.charts", items: menuCharts, }, { text: "UML", - // key: "menu.uml", + key: "menu.group.uml", items: menuUML, }, ], diff --git a/resources/src/locales/en.ts b/resources/src/locales/en.ts index ab29b16..250a714 100644 --- a/resources/src/locales/en.ts +++ b/resources/src/locales/en.ts @@ -28,7 +28,29 @@ export default { signin: "Sign In", }, menu: { - process: "ProcessManager", + // Core feature menus + process: "Process Manager", + task: "Scheduled Tasks", + log: "Log Viewer", + event: "System Events", + user: "User Management", + settings: "Settings", + push: "Push Management", + // Group titles + group: { + process: "Process", + task: "Task", + log: "Log", + user: "User", + settings: "Settings", + apps: "Apps", + data: "Data", + landing: "Landing", + ui: "UI - Theme Preview", + pages: "Pages", + charts: "Charts", + uml: "UML", + }, search: 'Search (press "ctrl + /" to focus)', dashboard: "Dashboard", logout: "Logout", diff --git a/resources/src/locales/ja.ts b/resources/src/locales/ja.ts index e4ec27d..c8fc10d 100644 --- a/resources/src/locales/ja.ts +++ b/resources/src/locales/ja.ts @@ -34,6 +34,29 @@ export default { signin: "サインイン", }, menu: { + // コア機能メニュー + process: "プロセス管理", + task: "スケジュールタスク", + log: "ログビューア", + event: "システムイベント", + user: "ユーザー管理", + settings: "システム設定", + push: "プッシュ管理", + // グループタイトル + group: { + process: "プロセス", + task: "タスク", + log: "ログ", + user: "ユーザー", + settings: "設定", + apps: "アプリ", + data: "データ", + landing: "ランディング", + ui: "UI - テーマプレビュー", + pages: "ページ", + charts: "チャート", + uml: "UML", + }, search: "検索(フォーカスするには「ctrl + /」を押します)", dashboard: "ダッシュボード", logout: "ログアウト", diff --git a/resources/src/locales/zhHans.ts b/resources/src/locales/zhHans.ts index 2a4eaf9..bdcfecf 100644 --- a/resources/src/locales/zhHans.ts +++ b/resources/src/locales/zhHans.ts @@ -28,8 +28,29 @@ export default { signin: "登录", }, menu: { + // 核心功能菜单 process: "进程管理", - search: "搜索(按“ Ctrl + /”进行聚焦)", + task: "定时任务", + log: "日志查看", + event: "系统事件", + user: "用户管理", + settings: "系统设置", + push: "推送管理", + // 分组标题 + group: { + process: "进程", + task: "任务", + log: "日志", + user: "用户", + settings: "设置", + apps: "应用", + data: "数据", + landing: "着陆页", + ui: "UI - 主题预览", + pages: "页面", + charts: "图表", + uml: "UML", + }, dashboard: "仪表板", logout: "登出", profile: "个人资料", diff --git a/resources/src/router/log.routes.ts b/resources/src/router/log.routes.ts index aae1fce..e2dfba5 100644 --- a/resources/src/router/log.routes.ts +++ b/resources/src/router/log.routes.ts @@ -9,5 +9,14 @@ export default [ category: "Data", }, }, + { + path: "/event", + component: () => import("@/views/log/Event.vue"), + meta: { + requiresAuth: true, + layout: "landing", + category: "Data", + }, + }, ]; diff --git a/resources/src/router/settings.routes.ts b/resources/src/router/settings.routes.ts index b0957d5..27cee3a 100644 --- a/resources/src/router/settings.routes.ts +++ b/resources/src/router/settings.routes.ts @@ -9,5 +9,14 @@ export default [ category: "Settings", }, }, + { + path: "/settings/push", + component: () => import("@/views/settings/Push.vue"), + meta: { + requiresAuth: true, + layout: "landing", + category: "Settings", + }, + }, ]; diff --git a/resources/src/types/event/event.ts b/resources/src/types/event/event.ts new file mode 100644 index 0000000..424e4d2 --- /dev/null +++ b/resources/src/types/event/event.ts @@ -0,0 +1,33 @@ +// 事件类型枚举 +export type EventType = + | "ProcessStart" + | "ProcessStop" + | "ProcessWarning" + | "TaskStart" + | "TaskStop"; + +// 事件模型 +export interface Event { + id: number; + name: string; + type: EventType; + additional: string; + createdTime: string; +} + +// 事件列表请求参数 +export interface EventListReq { + page?: number; + size?: number; + startTime?: number; + endTime?: number; + type?: EventType; + name?: string; +} + +// 事件列表响应 +export interface EventListResp { + total: number; + data: Event[]; +} + diff --git a/resources/src/views/log/Event.vue b/resources/src/views/log/Event.vue new file mode 100644 index 0000000..b4a9693 --- /dev/null +++ b/resources/src/views/log/Event.vue @@ -0,0 +1,375 @@ + + + + + + diff --git a/resources/src/views/settings/Push.vue b/resources/src/views/settings/Push.vue new file mode 100644 index 0000000..851cacf --- /dev/null +++ b/resources/src/views/settings/Push.vue @@ -0,0 +1,430 @@ + + + + + +