feat: add notify icon read

This commit is contained in:
engigu
2026-03-09 18:10:23 +08:00
parent e7da316c90
commit 77cf12c9b6
46 changed files with 1347 additions and 252 deletions
+52 -56
View File
@@ -13,6 +13,7 @@ import (
"github.com/engigu/baihu-panel/internal/constant"
"github.com/engigu/baihu-panel/internal/database"
"github.com/engigu/baihu-panel/internal/eventbus"
"github.com/engigu/baihu-panel/internal/executor"
"github.com/engigu/baihu-panel/internal/logger"
"github.com/engigu/baihu-panel/internal/models"
@@ -39,19 +40,12 @@ type EnvService interface {
GetAllEnvVars() []string
}
// Notifier 通知服务接口定义(避免循环依赖)
type Notifier interface {
TriggerEvent(bindingType string, eventType string, dataID string, templateData map[string]interface{})
}
// ExecutorService handles task execution and scheduling
type ExecutorService struct {
taskService *TaskService
taskLogService *TaskLogService
agentWSManager AgentWSManager
settingsService SettingsService
envService EnvService
notifier Notifier
scheduler *executor.Scheduler
cronManager *executor.CronManager
results []executor.ExecutionResult
@@ -64,14 +58,12 @@ func (es *ExecutorService) GetScheduler() *executor.Scheduler {
return es.scheduler
}
// NewExecutorService creates a new executor service
func NewExecutorService(
taskService *TaskService,
taskLogService *TaskLogService,
agentWSManager AgentWSManager,
settingsService SettingsService,
envService EnvService,
notifier Notifier,
) *ExecutorService {
es := &ExecutorService{
taskService: taskService,
@@ -79,7 +71,6 @@ func NewExecutorService(
agentWSManager: agentWSManager,
settingsService: settingsService,
envService: envService,
notifier: notifier,
results: make([]executor.ExecutionResult, 0, 100),
stopCh: make(chan struct{}),
}
@@ -143,7 +134,8 @@ func (h *ServerSchedulerHandler) OnTaskExecuting(req *executor.ExecutionRequest)
if err != nil {
// 并发限制,更新日志状态为失败
taskLog.Status = constant.TaskStatusFailed
taskLog.Output, _ = utils.CompressToBase64("任务并发数限制,拒绝执行")
comp, _ := utils.CompressToBase64("任务并发数限制,拒绝执行")
taskLog.Output = models.BigText(comp)
h.es.taskLogService.SaveTaskLog(taskLog)
return nil, nil, fmt.Errorf("任务并发限制: %v", err)
}
@@ -225,9 +217,9 @@ func (h *ServerSchedulerHandler) OnTaskCompleted(req *executor.ExecutionRequest,
taskLog := &models.TaskLog{
ID: req.LogID,
TaskID: task.ID,
Command: req.Command,
Output: output,
Error: result.Error,
Command: models.BigText(req.Command),
Output: models.BigText(output),
Error: models.BigText(result.Error),
Status: result.Status,
Duration: result.Duration,
ExitCode: result.ExitCode,
@@ -256,27 +248,29 @@ func (h *ServerSchedulerHandler) OnTaskCompleted(req *executor.ExecutionRequest,
h.es.HandleTaskRetry(task, req, result.Success, result.Status, result.ExitCode)
// ======= 通知触发 =======
if h.es.notifier != nil {
go func() {
var eventType string
switch result.Status {
case constant.TaskStatusSuccess:
eventType = constant.EventTaskSuccess
case constant.TaskStatusFailed:
eventType = constant.EventTaskFailed
case constant.TaskStatusTimeout:
eventType = constant.EventTaskTimeout
}
if eventType != "" {
h.es.notifier.TriggerEvent(constant.BindingTypeTask, eventType, task.ID, map[string]interface{}{
// ======= 通知触发 =======
go func() {
var eventType string
switch result.Status {
case constant.TaskStatusSuccess:
eventType = constant.EventTaskSuccess
case constant.TaskStatusFailed:
eventType = constant.EventTaskFailed
case constant.TaskStatusTimeout:
eventType = constant.EventTaskTimeout
}
if eventType != "" {
eventbus.DefaultBus.Publish(eventbus.Event{
Type: eventType,
Payload: map[string]interface{}{
"task_id": task.ID,
"task_name": task.Name,
"status": result.Status,
"duration": result.Duration,
})
}
}()
}
},
})
}
}()
}
func (h *ServerSchedulerHandler) OnTaskFailed(req *executor.ExecutionRequest, err error) {
@@ -305,9 +299,9 @@ func (h *ServerSchedulerHandler) OnTaskFailed(req *executor.ExecutionRequest, er
taskLog := &models.TaskLog{
ID: req.LogID,
TaskID: taskID,
Command: req.Command,
Output: output,
Error: err.Error(),
Command: models.BigText(req.Command),
Output: models.BigText(output),
Error: models.BigText(err.Error()),
Status: constant.TaskStatusFailed,
Duration: 0,
ExitCode: 1,
@@ -338,19 +332,21 @@ func (h *ServerSchedulerHandler) OnTaskFailed(req *executor.ExecutionRequest, er
h.es.HandleTaskRetry(task, req, false, constant.TaskStatusFailed, 1)
// ======= 通知触发 =======
if h.es.notifier != nil {
go func() {
taskName := "未知任务"
if task != nil {
taskName = task.Name
}
h.es.notifier.TriggerEvent(constant.BindingTypeTask, constant.EventTaskFailed, taskID, map[string]interface{}{
// ======= 通知触发 =======
go func() {
taskName := "未知任务"
if task != nil {
taskName = task.Name
}
eventbus.DefaultBus.Publish(eventbus.Event{
Type: constant.EventTaskFailed,
Payload: map[string]interface{}{
"task_id": taskID,
"task_name": taskName,
"error": err.Error(),
})
}()
}
},
})
}()
}
// HandleTaskRetry 处理任务失败重试逻辑
@@ -372,11 +368,11 @@ func (es *ExecutorService) HandleTaskRetry(task *models.Task, req *executor.Exec
return nil
}
newEnvs := es.loadEnvVars(latestTask.ID, latestTask.Envs)
newEnvs := es.loadEnvVars(latestTask.ID, string(latestTask.Envs))
return &executor.ExecutionRequest{
TaskID: req.TaskID,
Name: latestTask.Name,
Command: latestTask.Command,
Command: string(latestTask.Command),
WorkDir: latestTask.WorkDir,
Envs: newEnvs,
Timeout: latestTask.Timeout,
@@ -501,7 +497,7 @@ func (es *ExecutorService) AddCronTask(task *models.Task) error {
return nil
}
// 在加入调度器前,预先加载好环境信息
task.RuntimeEnvs = es.loadEnvVars(task.ID, task.Envs)
task.RuntimeEnvs = es.loadEnvVars(task.ID, string(task.Envs))
return es.cronManager.AddTask(task)
}
@@ -582,7 +578,7 @@ func (es *ExecutorService) ExecuteTask(taskID string, extraEnvs []string) *execu
}
}
envs := es.loadEnvVars(task.ID, task.Envs)
envs := es.loadEnvVars(task.ID, string(task.Envs))
if len(extraEnvs) > 0 {
envs = append(envs, extraEnvs...)
}
@@ -590,7 +586,7 @@ func (es *ExecutorService) ExecuteTask(taskID string, extraEnvs []string) *execu
req := &executor.ExecutionRequest{
TaskID: task.ID,
Name: task.Name,
Command: task.Command,
Command: string(task.Command),
WorkDir: task.WorkDir,
Envs: envs,
Timeout: task.Timeout,
@@ -749,13 +745,13 @@ func (es *ExecutorService) CheckConcurrency(taskID string) error {
return err
}
var goids []int64
if task.RunningGo != "" {
_ = json.Unmarshal([]byte(task.RunningGo), &goids)
if string(task.RunningGo) != "" {
_ = json.Unmarshal([]byte(string(task.RunningGo)), &goids)
}
var config models.TaskConfig
if task.Config != "" {
_ = json.Unmarshal([]byte(task.Config), &config)
var config models.TaskConfig
if string(task.Config) != "" {
_ = json.Unmarshal([]byte(string(task.Config)), &config)
}
if config.Concurrency == 0 && len(goids) > 0 {
@@ -792,7 +788,7 @@ func (es *ExecutorService) AddRunningGo(taskID string) (int64, error) {
goids = append(goids, goid)
data, _ := json.Marshal(goids)
return tx.Model(&task).Update("running_go", string(data)).Error
return tx.Model(&task).Update("running_go", models.BigText(data)).Error
})
if lastErr == nil {
return goid, nil
+7 -7
View File
@@ -40,7 +40,7 @@ func (s *TaskLogService) CreateEmptyLog(taskID string, command string) (*models.
taskLog := &models.TaskLog{
ID: utils.GenerateID(),
TaskID: taskID,
Command: command,
Command: models.BigText(command),
Status: "running",
StartTime: &startTime,
CreatedAt: models.Now(),
@@ -162,9 +162,9 @@ func (s *TaskLogService) CreateTaskLogFromAgentResult(result *models.AgentTaskRe
ID: utils.GenerateID(),
TaskID: result.TaskID,
AgentID: &result.AgentID,
Command: result.Command,
Output: compressed,
Error: result.Error,
Command: models.BigText(result.Command),
Output: models.BigText(compressed),
Error: models.BigText(result.Error),
Status: result.Status,
Duration: result.Duration,
ExitCode: result.ExitCode,
@@ -206,9 +206,9 @@ func (s *TaskLogService) CreateTaskLogFromLocalExecution(taskID string, command,
taskLog := &models.TaskLog{
ID: utils.GenerateID(),
TaskID: taskID,
Command: command,
Output: compressed,
Error: systemErr,
Command: models.BigText(command),
Output: models.BigText(compressed),
Error: models.BigText(systemErr),
Status: status,
Duration: duration,
ExitCode: exitCode,
+6 -6
View File
@@ -23,16 +23,16 @@ func (ts *TaskService) CreateTask(name, command, schedule string, timeout int, w
task := &models.Task{
ID: utils.GenerateID(),
Name: name,
Command: command,
Command: models.BigText(command),
Tags: tags,
Type: taskType,
TriggerType: triggerType,
Config: config,
Config: models.BigText(config),
Schedule: schedule,
Timeout: timeout,
WorkDir: workDir,
CleanConfig: cleanConfig,
Envs: envs,
Envs: models.BigText(envs),
Languages: languages,
AgentID: agentID,
Enabled: true,
@@ -94,17 +94,17 @@ func (ts *TaskService) UpdateTask(id string, name, command, schedule string, tim
return nil
}
task.Name = name
task.Command = command
task.Command = models.BigText(command)
task.Tags = tags
task.Schedule = schedule
task.Timeout = timeout
task.WorkDir = workDir
task.CleanConfig = cleanConfig
task.Envs = envs
task.Envs = models.BigText(envs)
task.Enabled = enabled
task.AgentID = agentID
task.Languages = languages
task.Config = config
task.Config = models.BigText(config)
task.RetryCount = retryCount
task.RetryInterval = retryInterval
task.RandomRange = randomRange