daShangDao_planA/initialization/cron/task.go

842 lines
24 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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程序启动***********/////////////////////////