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