package cron import ( "archive/zip" "encoding/csv" "encoding/json" "fmt" "io" "log" "net/http" "os" "os/exec" "path/filepath" "planA/controlState/serviceAlive" "planA/controller" "planA/initialization/config" "planA/initialization/golabl" "planA/modules/logs" "planA/modules/pdd" "planA/rep" "planA/service" "planA/service/mysql" "planA/tool" toolPdd "planA/tool/pdd" "planA/tool/process" _type "planA/type" "regexp" "strings" "time" ) // DeleteOldExportFile 删除N天前的导出文件 func DeleteOldExportFile() { read := rep.CreateDbFactoryRead() lite, getTaskExportOldListErr := read.GetTaskExportOldList() if getTaskExportOldListErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取SQLite中N天前的记录失败:"+getTaskExportOldListErr.Error()) return } for _, v := range lite { removeErr := os.Remove(v.FileUrl) if removeErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "删除文件失败:"+removeErr.Error()) continue } } } // DeleteOldRecords 删除 task_records 表中N天前的记录 func DeleteOldRecords() { mysqlWrite, sqliteWrite := rep.CreateDbFactoryWrite() mysqlDeleteTaskRecordsOldDataErr := mysqlWrite.DeleteTaskRecordsOldData() if mysqlDeleteTaskRecordsOldDataErr != nil { errMsg := fmt.Sprintf("删除task_records表中N天前的记录失败: %v", mysqlDeleteTaskRecordsOldDataErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) return } sqLiteDeleteTaskRecordsOldDataErr := sqliteWrite.DeleteTaskRecordsOldData() if sqLiteDeleteTaskRecordsOldDataErr != nil { errMsg := fmt.Sprintf("删除task_records表中N天前的记录失败: %v", sqLiteDeleteTaskRecordsOldDataErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) return } } // DeleteOldExport 删除 task_export 表中N天前的记录 func DeleteOldExport() { mysqlWrite, sqliteWrite := rep.CreateDbFactoryWrite() mysqlDeleteTaskExportOldDataErr := mysqlWrite.DeleteTaskExportOldData() if mysqlDeleteTaskExportOldDataErr != nil { errMsg := fmt.Sprintf("删除task_export表中N天前的记录失败: %v", mysqlDeleteTaskExportOldDataErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) return } sqliteDeleteTaskExportOldDataErr := sqliteWrite.DeleteTaskExportOldData() if sqliteDeleteTaskExportOldDataErr != nil { errMsg := fmt.Sprintf("删除task_export表中N天前的记录失败: %v", sqliteDeleteTaskExportOldDataErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) return } } // CheckMysqlAlive mysql心跳 func CheckMysqlAlive() { //计算心跳时间 start := time.Now() mysql.GetTaskRecordsByTaskId("1") elapsed := time.Since(start) elapsedMs := int(elapsed.Milliseconds()) //将time.Duration类型转换为int类型的毫秒 //设置状态 serviceAlive.SetServiceAlive("mysql", elapsedMs) } // CheckRedisAlive redis心跳 func CheckRedisAlive() { //计算心跳时间 start := time.Now() service.GetTaskBookPing() elapsed := time.Since(start) elapsedMs := int(elapsed.Milliseconds()) //将time.Duration类型转换为int类型的毫秒 //设置状态 serviceAlive.SetServiceAlive("redis", elapsedMs) } // CheckPddAlive 拼多多心跳 func CheckPddAlive() { token := "" //获取系统规定拼多多 token //urlConfig, _ := config.GetFileUrlConfig() //_, token, HttpGetRequestErr := tool.HttpGetRequest(urlConfig.PddTokenUrl) //if HttpGetRequestErr != nil { // logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取系统规定拼多多 token失败:"+HttpGetRequestErr.Error()) // return //} pddDll, initPddSOErr := pdd.InitPddDll() if initPddSOErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "初始化拼多多dll文件失败:"+initPddSOErr.Error()) return } client, err := config.GetPddClient() if err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取拼多多配置失败:"+err.Error()) return } //计算心跳时间 start := time.Now() _, pddTimeGetErr := pddDll.PddTimeGet(client.ClientId, client.ClientSecret, token) if pddTimeGetErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取拼多多系统时间失败:"+pddTimeGetErr.Error()) return } elapsed := time.Since(start) elapsedMs := int(elapsed.Milliseconds()) //将time.Duration类型转换为int类型的毫秒 //设置状态 serviceAlive.SetServiceAlive("pdd", elapsedMs) } // CheckCreateTaskNoticeUrlAlive 价软件提交数据通知接口心跳 func CheckCreateTaskNoticeUrlAlive() { //计算心跳时间 start := time.Now() controller.TaskNoticeRequest("ping") elapsed := time.Since(start) elapsedMs := int(elapsed.Milliseconds()) //将time.Duration类型转换为int类型的毫秒 //设置状态 serviceAlive.SetServiceAlive("通知取出bodyOver接口", elapsedMs) } // CheckBannedWordSubstitutionUrlAlive 违禁词接口心跳 func CheckBannedWordSubstitutionUrlAlive() { urlConfig, _ := config.GetFileUrlConfig() bannerWordDataReq := map[string]string{ "isbn": "9787508618388", "bookName": "麦迪逊大道之王:大卫·奥格威转", "author": "[美]肯尼斯·罗曼", "publisher": "中信出版社", "shopId": "2029141110649929729", "replaceMark": "1", } //计算心跳时间 start := time.Now() tool.HttpBannedWordSubstitution(urlConfig.BannedWordSubstitutionUrl, bannerWordDataReq) elapsed := time.Since(start) elapsedMs := int(elapsed.Milliseconds()) //将time.Duration类型转换为int类型的毫秒 //设置状态 serviceAlive.SetServiceAlive("违禁词替换接口", elapsedMs) } // CheckXyBannedWord 闲鱼违禁词 func CheckXyBannedWord() { url := golabl.Config.FileUrl.XYBannedWordSubstitutionUrl //计算心跳时间 start := time.Now() // 发送 GET 请求 resp, err := http.Get(url) if err != nil { fmt.Printf("请求失败: %v\n", err) return } defer resp.Body.Close() // 读取响应体 body, err := io.ReadAll(resp.Body) if err != nil { fmt.Printf("读取响应失败: %v\n", err) return } elapsed := time.Since(start) elapsedMs := int(elapsed.Milliseconds()) //将time.Duration类型转换为int类型的毫秒 //设置状态 serviceAlive.SetServiceAlive("闲鱼违禁词", elapsedMs) // 解析 JSON var healthResp _type.HealthResponse err = json.Unmarshal(body, &healthResp) if err != nil { fmt.Printf("解析 JSON 失败: %v\n", err) return } // 判断 code 是否为 200 if healthResp.Code != 200 { serviceAlive.SetServiceAliveWithMsg("闲鱼违禁词", elapsedMs, healthResp.Message) } } // DeleteOldRedis 删除redisN天前的数据 func DeleteOldRedis() { read := rep.CreateDbFactoryRead() list, getTaskRecordsOldListtErr := read.GetTaskRecordsOldList() if getTaskRecordsOldListtErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取task_export中N天前的记录失败:"+getTaskRecordsOldListtErr.Error()) return } for _, v := range list { err := service.DelTask(v.TaskId) if err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "删除任务失败:"+err.Error()) continue } } } // B 程序守护 func B() { read := rep.CreateDbFactorySqliteRead() //查询task_records中24小时内的所有数据 records, getTaskRecords24HourErr := read.GetTaskRecords24Hour() if getTaskRecords24HourErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取所有任务记录失败:"+getTaskRecords24HourErr.Error()) return } for _, v := range records { //获取 header 信息 header, getTaskHeaderErr := service.GetTaskHeader(v.TaskId) if getTaskHeaderErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取header 信息失败:"+getTaskHeaderErr.Error()) continue } // 不能是淘宝的 if header.Status != 0 && header.ShopType != "6" { // 启动 B程序 _, runTaskWorkerErr := process.RunTaskWorker(v.TaskId) if runTaskWorkerErr != nil { //logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "启动B程序失败:"+runTaskWorkerErr.Error()) continue } fmt.Println("守护进程成功启动任务B程序的窗口 任务ID:" + v.TaskId) } } } // DeleteOldLog 删除日志N天以上的日志文件 func DeleteOldLog(dir string) { // 配置参数 pattern := `^[^-]+-[a-z]+-(\d{4}-\d{2}-\d{2})(?:-\d{2})?\.log$` // 匹配两种格式:ERROR-task-2026-03-23-04.log 和 ERROR-task-2026-03-23.log retentionDays := 3 // 保留天数 // 计算截止时间 cutoffTime := time.Now().AddDate(0, 0, -retentionDays) // 编译正则表达式 regex, err := regexp.Compile(pattern) if err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("无效的正则表达式模式: %v", err)) return } // 遍历目录 entries, err := os.ReadDir(dir) if err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("无法读取目录: %v", err)) return } var cleanedCount int var errors []string for _, entry := range entries { if entry.IsDir() { continue } filename := entry.Name() // 检查文件名是否匹配模式并提取日期 matches := regex.FindStringSubmatch(filename) if len(matches) != 2 { continue } // 解析文件名中的日期 dateStr := matches[1] // 格式: 2026-03-23 fileDate, err := time.Parse("2006-01-02", dateStr) if err != nil { errors = append(errors, fmt.Sprintf("解析日期失败 %s: %v", filename, err)) continue } // 检查文件日期是否早于截止时间 if fileDate.Before(cutoffTime) { filePath := filepath.Join(dir, filename) // 删除文件 if err := os.Remove(filePath); err != nil { errors = append(errors, fmt.Sprintf("删除失败 %s: %v", filename, err)) } else { cleanedCount++ } } } // 输出清理结果 if cleanedCount > 0 || len(errors) > 0 { logs.LoggingMiddleware(logs.LOG_LEVEL_INFO, fmt.Sprintf("清理完成: 删除了 %d 个文件", cleanedCount)) } if len(errors) > 0 { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("清理过程中遇到 %d 个错误", len(errors))) for _, errMsg := range errors { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) } } } // DeleteOldWatermarkImage 删除N天以上的水印图片 func DeleteOldWatermarkImage() { // 目标根目录(你提供的目录) rootDir := `img\watermark` // 计算需要删除的截止时间:当前时间 - N天 days := golabl.Config.Server.DataDay expireTime := time.Now().AddDate(0, 0, -days) // 遍历根目录 err := filepath.Walk(rootDir, func(path string, f os.FileInfo, err error) error { if err != nil { return fmt.Errorf("无法访问目录 %s: %v", path, err) } // 只处理一级子文件夹(不递归) if path == rootDir { return nil } if !f.IsDir() { return nil } // 解析文件夹名称为日期(格式:2006-01-02) dirName := f.Name() dirTime, err := time.Parse("2006-01-02", dirName) if err != nil { // 不是日期格式的文件夹跳过 return nil } // 判断是否超过N天 if dirTime.Before(expireTime) { // 删除文件夹(包括里面所有内容) err := os.RemoveAll(path) if err != nil { return fmt.Errorf("无法删除目录 %s: %v", path, err) } } // 只处理一级子目录,不递归深入 return filepath.SkipDir }) if err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("删除N天以上的水印图片失败: %v", err.Error())) } } // DeleteOldSkuWatermarkImage 删除N天以上的sku水印图片 func DeleteOldSkuWatermarkImage() { // 目标根目录(你提供的目录) rootDir := `img\skuwatermark` // 计算需要删除的截止时间:当前时间 - N天 days := golabl.Config.Server.DataDay expireTime := time.Now().AddDate(0, 0, -days) // 遍历根目录 err := filepath.Walk(rootDir, func(path string, f os.FileInfo, err error) error { if err != nil { return fmt.Errorf("无法访问目录 %s: %v", path, err) } // 只处理一级子文件夹(不递归) if path == rootDir { return nil } if !f.IsDir() { return nil } // 解析文件夹名称为日期(格式:2006-01-02) dirName := f.Name() dirTime, err := time.Parse("2006-01-02", dirName) if err != nil { // 不是日期格式的文件夹跳过 return nil } // 判断是否超过N天 if dirTime.Before(expireTime) { // 删除文件夹(包括里面所有内容) err := os.RemoveAll(path) if err != nil { return fmt.Errorf("无法删除目录 %s: %v", path, err) } } // 只处理一级子目录,不递归深入 return filepath.SkipDir }) if err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("删除N天以上的水印图片失败: %v", err.Error())) } } // BackupBodyBackup 备份 body_backup到硬盘 func BackupBodyBackup() { // 定义导出目录 csvUrl := golabl.Config.FileUrl.BackupUrl fmt.Println("路径:" + csvUrl) // 获取所有任务数据 read := rep.CreateDbFactoryRead() list, getAllTaskErr := read.GetAllTask() if getAllTaskErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, "获取所有任务数据失败:"+getAllTaskErr.Error()) return } for _, v := range list { dateDir := v.CreateAt.Format("2006-01-02") // 按日期分组 // 构建完整的目录路径 taskCsvUrl := filepath.Join(csvUrl, dateDir) // 获取 backup数据长度 backupLen, getBodyBackupLenErr := service.GetBodyBackupLen(v.TaskId) if getBodyBackupLenErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("获取任务 %s 的backup长度失败:%v", v.TaskId, getBodyBackupLenErr)) continue // 跳过当前任务,继续处理下一个 } if backupLen == 0 { // 如果 backup中没有数据则跳过 continue } csvFileName := fmt.Sprintf("%v.csv", v.TaskId) // 检查并创建目录(如果不存在) err := os.MkdirAll(taskCsvUrl, 0755) if err != nil { errMsg := fmt.Sprintf("创建目录失败: %v", err) fmt.Println(errMsg) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) return } // 拼接完整的文件路径 fullPath := filepath.Join(taskCsvUrl, csvFileName) // 判断文件是否存在,决定是创建新文件还是追加写入 var file *os.File if _, err := os.Stat(fullPath); err == nil { // 文件存在,以追加模式打开 file, err = os.OpenFile(fullPath, os.O_APPEND|os.O_WRONLY, 0644) if err != nil { errMsg := fmt.Sprintf("打开文件失败: %v", err) fmt.Println(errMsg) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) continue } } else if os.IsNotExist(err) { // 文件不存在,创建新文件 file, err = os.Create(fullPath) if err != nil { errMsg := fmt.Sprintf("创建文件失败: %v", err) fmt.Println(errMsg) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) continue } } else { // 其他错误(如权限问题) errMsg := fmt.Sprintf("检查文件状态失败: %v", err) fmt.Println(errMsg) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) continue } defer file.Close() // 创建 CSV写入器 writer := csv.NewWriter(file) defer writer.Flush() // 循环获取并写入数据 for i := 0; i < int(backupLen); i++ { // 获取 backup数据 one, getBodyBackupOneErr := service.GetBodyBackupOne(v.TaskId) if getBodyBackupOneErr != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("获取任务 %s 的body_backup数据失败:%v", v.TaskId, getBodyBackupOneErr)) break // 跳出当前循环,继续下一个任务 } // 将数据写入到CSV文件的一行(A列) // 假设 one 是字符串类型,如果是结构体需要根据实际字段调整 record := []string{one} // 如果 one 不是字符串,需要转换,例如 fmt.Sprintf("%v", one) if err := writer.Write(record); err != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("写入CSV数据失败:%v", err)) break } } logs.LoggingMiddleware(logs.LOG_LEVEL_INFO, fmt.Sprintf("任务 %s 的数据已成功写入文件:%s", v.TaskId, fullPath)) } } // ZipBackupFile 压缩backup文件 func ZipBackupFile() { csvUrl := golabl.Config.FileUrl.BackupUrl // 获取昨天的日期 yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02") // 拼接完整的文件路径 taskCsvUrl := filepath.Join(csvUrl, yesterday) // 检查源目录是否存在 srcInfo, err := os.Stat(taskCsvUrl) if os.IsNotExist(err) { log.Printf("目录不存在: %s", taskCsvUrl) return } // 如果不是目录,则直接返回 if !srcInfo.IsDir() { log.Printf("路径不是目录: %s", taskCsvUrl) return } // 创建zip文件 zipFileName := taskCsvUrl + ".zip" zipFile, err := os.Create(zipFileName) if err != nil { log.Printf("创建zip文件失败: %v", err) return } defer zipFile.Close() // 创建zip writer zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close() // 遍历目录并添加文件 err = filepath.Walk(taskCsvUrl, func(path string, info os.FileInfo, err error) error { if err != nil { return err } // 跳过目录本身 if info.IsDir() { return nil } // 获取相对路径作为zip内的文件名 relPath, err := filepath.Rel(taskCsvUrl, path) if err != nil { return err } // 创建zip中的文件头 header, err := zip.FileInfoHeader(info) if err != nil { return err } header.Name = filepath.Join(yesterday, relPath) // 保留目录结构 header.Method = zip.Deflate // 创建zip中的文件 writer, err := zipWriter.CreateHeader(header) if err != nil { return err } // 打开并复制源文件 file, err := os.Open(path) if err != nil { return err } defer file.Close() _, err = io.Copy(writer, file) return err }) if err != nil { log.Printf("压缩失败: %v", err) os.Remove(zipFileName) // 删除不完整的zip文件 return } log.Printf("压缩成功: %s", zipFileName) // 压缩成功后删除原目录 err = os.RemoveAll(taskCsvUrl) if err != nil { log.Printf("删除原目录失败: %v", err) return } log.Printf("成功删除原目录: %s", taskCsvUrl) } // DeleteZipFile 删除zip文件 func DeleteZipFile() { zipDir := golabl.Config.FileUrl.BackupUrl day := golabl.Config.Server.DataDay // 获取当前时间 now := time.Now() // 计算截止时间(当天0点减去指定天数) cutoffTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).AddDate(0, 0, -day) // 读取目录 entries, err := os.ReadDir(zipDir) if err != nil { fmt.Printf("读取目录失败: %v\n", err) return } deletedCount := 0 for _, entry := range entries { if entry.IsDir() { continue } fileName := entry.Name() if !strings.HasSuffix(fileName, ".zip") { continue } // 从文件名解析日期(格式:2026-04-10.zip) dateStr := strings.TrimSuffix(fileName, ".zip") fileDate, err := time.Parse("2006-01-02", dateStr) if err != nil { // 如果文件名不符合日期格式,跳过 continue } // 如果文件日期早于或等于截止时间,则删除 if !fileDate.After(cutoffTime) { filePath := filepath.Join(zipDir, fileName) err := os.Remove(filePath) if err != nil { fmt.Printf("删除文件失败 %s: %v\n", filePath, err) } else { fmt.Printf("已删除文件: %s\n", filePath) deletedCount++ } } } fmt.Printf("共删除 %d 个%d天前的zip文件\n", deletedCount, day) } // ExecuteDelTask 查询del_task 表中待执行 func ExecuteDelTask() { delTask, err := mysql.GetDelTask() if err != nil { fmt.Println("查询del_task 表中待执行失败:", err) } for _, v := range delTask { //如果是暂停中的任务,将任务状态修改为执行中 if *v.Status == 2 { // 要求 v.PauseAt 不能等于 nil 并且 v.PauseAt 必须大于当前时间24小时 if v.PauseAt != nil && !time.Now().After(v.PauseAt.Add(24*time.Hour)) { continue } //修改任务状态 err := mysql.UpdateDelTaskStatus(v.ID) if err != nil { fmt.Println("修改任务状态失败:", err) continue } } //启动任务 _, err := process.RunDprogram(*v.TaskID) if err != nil { fmt.Println("启动任务失败:", err) continue } } } // DeleteDelTaskAndDelTaskDetails 清理删除任务与删除任务详情过期的数据 func DeleteDelTaskAndDelTaskDetails() { defer func() { if r := recover(); r != nil { logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, fmt.Sprintf("DeleteDelTaskAndDelTaskDetails panic: %v", r)) } }() task, getExpiredDelTaskErr := mysql.GetExpiredDelTask() if getExpiredDelTaskErr != nil { errMsg := fmt.Sprintf("查询过期的删除任务失败:%v", getExpiredDelTaskErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) fmt.Println(errMsg) return } for _, v := range task { // 检查必要字段是否为 nil if v.TaskType == nil { logs.LoggingMiddleware(logs.LOG_LEVEL_WARNING, fmt.Sprintf("任务记录中 TaskType 为 nil,跳过处理 ID: %d", v.ID)) continue } if v.TaskID == nil { logs.LoggingMiddleware(logs.LOG_LEVEL_WARNING, fmt.Sprintf("任务记录中 TaskID 为 nil,跳过处理 ID: %d", v.ID)) continue } // 处理任务类型 2 或 3 if *v.TaskType == 2 || *v.TaskType == 3 { // 删除 header 与 footer delTaskErr := service.DelTask(*v.TaskID) if delTaskErr != nil { errMsg := fmt.Sprintf("删除任务失败 TaskID: %s, Error: %v", *v.TaskID, delTaskErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) fmt.Println(errMsg) // 注意:这里用 continue 而不是 return,避免一个任务失败影响其他任务 continue } } // 删除删除任务明细表 deleteDelTaskDetailErr := mysql.DeleteDelTaskDetail(*v.TaskID) if deleteDelTaskDetailErr != nil { errMsg := fmt.Sprintf("删除删除任务明细表失败 TaskID: %s, Error: %v", *v.TaskID, deleteDelTaskDetailErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) fmt.Println(errMsg) continue } // 删除任务 deleteDelTaskByIdErr := mysql.DeleteDelTaskById(v.ID) if deleteDelTaskByIdErr != nil { errMsg := fmt.Sprintf("删除任务失败 ID: %d, Error: %v", v.ID, deleteDelTaskByIdErr) logs.LoggingMiddleware(logs.LOG_LEVEL_ERROR, errMsg) fmt.Println(errMsg) continue } logs.LoggingMiddleware(logs.LOG_LEVEL_INFO, fmt.Sprintf("成功清理任务 ID: %d, TaskID: %s", v.ID, *v.TaskID)) } } // VerifyToken 验证token过期 func VerifyToken() { list, getPddTokenListErr := service.GetPddTokenList() if getPddTokenListErr != nil { fmt.Println("获取token列表失败:", getPddTokenListErr) return } pddDll, initPddSOErr := pdd.InitPddDll() if initPddSOErr != nil { fmt.Println("初始化pdd.so失败:", initPddSOErr) return } for _, v := range list { //使用类目预测接口测试Token 是否有效 buildPddGoodsOuterCatMappingGetErr := toolPdd.BuildPddGoodsOuterCatMappingGet(pddDll, v.Token) if buildPddGoodsOuterCatMappingGetErr != nil { if buildPddGoodsOuterCatMappingGetErr.Error() == "拼多多Token已过期" { //fmt.Printf("token 过期的店铺 %v 店铺id %v\n", v.ShopName, v.ID) reqData := map[string]string{ "shopId": v.ID, } _, submitFormDataErr := tool.SubmitFormData(golabl.Config.FileUrl.UpdateTokenUrl, reqData) if submitFormDataErr != nil { fmt.Println("提交表单数据失败:", submitFormDataErr) return } } } } } // DeleteKfzTempImg 删除本地临时的孔夫子图片 func DeleteKfzTempImg() { err := tool.CleanOldFolders(golabl.Config.FileUrl.KfzImgTempUrl, 3) if err != nil { fmt.Println("删除本地临时的孔夫子图片失败:", err) } } /////////////////*********检查F程序启动***********///////////////////////// func RunF() error { exeName := golabl.Config.FileUrl.FFileName running, err := isProcessRunning(exeName) if err != nil { return fmt.Errorf("检查进程状态出错: %v\n", err) } if !running { runFProgramErr := process.RunFProgram() if runFProgramErr != nil { return runFProgramErr } } return nil } func isProcessRunning(exePath string) (bool, error) { exeName := filepath.Base(exePath) // 方法1:使用 tasklist(适用于Windows) cmd := exec.Command("tasklist", "/FI", fmt.Sprintf("IMAGENAME eq %s", exeName), "/NH", "/FO", "CSV") output, err := cmd.Output() if err != nil { // 检查是否是"未找到进程"的错误 if exitErr, ok := err.(*exec.ExitError); ok { if exitErr.ExitCode() == 1 { return false, nil } } return false, err } outputStr := string(output) // 如果输出包含进程名且不包含"No tasks",则认为进程在运行 return strings.Contains(outputStr, exeName) && !strings.Contains(outputStr, "INFO: No tasks"), nil } /////////////////*********检查F程序启动***********/////////////////////////