新增查看推文模块

This commit is contained in:
zyj
2025-11-20 11:43:58 +08:00
parent f344de378b
commit e0907c0e80
6 changed files with 202 additions and 16 deletions

View File

@@ -18,7 +18,7 @@ type CreateRequestParams struct {
Name string `form:"name" json:"name" uri:"name" xml:"name"` Name string `form:"name" json:"name" uri:"name" xml:"name"`
RunStatus int `form:"runStatus" json:"runStatus" uri:"runStatus" xml:"runStatus" binding:"required"` RunStatus int `form:"runStatus" json:"runStatus" uri:"runStatus" xml:"runStatus" binding:"required"`
Type int `form:"type" json:"type" uri:"type" xml:"type" binding:"required"` Type int `form:"type" json:"type" uri:"type" xml:"type" binding:"required"`
AccountClassify string `form:"accountClassify" json:"accountClassify" uri:"accountClassify" xml:"accountClassify" binding:"required"` AccountClassify string `form:"accountClassify" json:"accountClassify" uri:"accountClassify" xml:"accountClassify"`
ClassifyId []int `form:"classifyId" json:"classifyId" uri:"classifyId" xml:"classifyId"` ClassifyId []int `form:"classifyId" json:"classifyId" uri:"classifyId" xml:"classifyId"`
Keyword string `form:"keyword" json:"keyword" uri:"keyword" xml:"keyword"` Keyword string `form:"keyword" json:"keyword" uri:"keyword" xml:"keyword"`
TwitterId string `form:"twitterId" json:"twitterId" uri:"twitterId" xml:"twitterId"` TwitterId string `form:"twitterId" json:"twitterId" uri:"twitterId" xml:"twitterId"`

39
models/ar_twitter_post.go Normal file
View File

@@ -0,0 +1,39 @@
package models
import "time"
// TwitterPost 推文记录模型
type TwitterPost struct {
Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
AccountId int64 `gorm:"column:account_id;not null;default:0" json:"account_id"` // 账号ID
Content string `gorm:"column:content;type:varchar(255);default:''" json:"content"` // 推文内容
Images string `gorm:"column:images;type:json" json:"images"` // 图片列表(JSON格式)
Link string `gorm:"column:link;type:varchar(255);default:''" json:"link"` // 推文链接
ContentLink string `gorm:"column:content_link;type:varchar(255);default:''" json:"content_link"` // 内容链接
Status int8 `gorm:"column:status;type:tinyint(3);not null;default:1" json:"status"` // 状态: 1-正常 0-删除
UpdateTime int64 `gorm:"column:update_time;autoUpdateTime" json:"update_time"` // 更新时间
CreateTime int64 `gorm:"column:create_time;autoCreateTime" json:"create_time"` // 创建时间
}
// TableName 指定表名
func (TwitterPost) TableName() string {
return "ar_twitter_post"
}
// BeforeCreate GORM 钩子 - 创建前设置时间
func (tp *TwitterPost) BeforeCreate(tx interface{}) error {
now := time.Now().Unix()
if tp.CreateTime == 0 {
tp.CreateTime = now
}
if tp.UpdateTime == 0 {
tp.UpdateTime = now
}
return nil
}
// BeforeUpdate GORM 钩子 - 更新前设置时间
func (tp *TwitterPost) BeforeUpdate(tx interface{}) error {
tp.UpdateTime = time.Now().Unix()
return nil
}

View File

@@ -0,0 +1,103 @@
package plugin
import (
"go-account-register/config"
"go-account-register/models"
"go-account-register/services"
paramsTypes "go-account-register/types"
"log"
"math"
"runtime/debug"
"sync"
"time"
)
var TwitterService services.TwitterService
type TaskViewPostPlugin struct{}
func (*TaskViewPostPlugin) Run(task *paramsTypes.Task) {
// 查询当前所有账号
userService := services.InitTwitterAccountService()
// 判断是否是补偿任务
var userList []models.TwitterAccount
userList = userService.GetAvailableAccount(&models.TwitterAccount{
Type: "view",
})
if task.Data.Compensate == 1 {
// 补偿任务
userList = userService.GetAccountListByStatus(&models.TwitterAccount{
Status: "查看成功",
Type: "view",
})
} else {
// 清空当前运行的账号状态
userService.ClearAccountStatus(&models.TwitterAccount{
Type: "view",
})
}
log.Println("可用账号数量:", len(userList))
// 获取并发数
appConfig, _ := config.LoadConfig()
num := math.Ceil(float64(len(userList)) / float64(appConfig.Limit.BrowserRunMax))
sem := make(chan struct{}, appConfig.Limit.BrowserRunMax) // 全局并发上限
var globalWait sync.WaitGroup
for i := 0; i < int(num); i++ {
select {
case <-task.Ctx.Done():
log.Println("中断任务")
return
default:
}
log.Println("批次:", i+1)
for j := 0; j < appConfig.Limit.BrowserRunMax; j++ {
log.Println(i*appConfig.Limit.BrowserRunMax + j)
taskIndex := i*appConfig.Limit.BrowserRunMax + j
if taskIndex >= len(userList) {
break
}
time.Sleep(10 * time.Second)
globalWait.Add(1)
sem <- struct{}{} // 阻塞直到有空位
go func() {
defer func() {
<-sem // 释放信号量
globalWait.Done()
}()
changeAccountWork(task, userList[taskIndex].ID)
}()
}
}
globalWait.Wait()
task.Message <- "Success"
}
func changeAccountWork(task *paramsTypes.Task, id int64) {
UserService := services.InitTwitterAccountService()
defer func() {
if r := recover(); r != nil {
log.Printf("Goroutine panic: %v\nStack: %s", r, debug.Stack())
UserService.ChangeAccountLoginStatus(int(id), "账号下线")
TwitterService.Logout(int(id))
}
}()
// 开始登录
res := TwitterService.Login(int(id))
UserService.ChangeAccountLoginStatus(int(id), res.Msg)
if res.Code == 200 {
// 开始拟人
res = TwitterService.LoopViewPost(int(id))
UserService.ChangeAccountStatus(int(id), res.Msg)
time.Sleep(3 * time.Second)
TwitterService.Logout(int(id))
UserService.ChangeAccountLoginStatus(int(id), "账号下线")
}
log.Println(task.ID)
}

View File

@@ -60,19 +60,27 @@ func (u *TwitterAccountService) OfflineAllAccount() bool {
// 获取可用账号 // 获取可用账号
func (u *TwitterAccountService) GetAvailableAccount(params *models.TwitterAccount) []models.TwitterAccount { func (u *TwitterAccountService) GetAvailableAccount(params *models.TwitterAccount) []models.TwitterAccount {
var users []models.TwitterAccount var users []models.TwitterAccount
res := u.db.Model(&models.TwitterAccount{}).Where(`status = ? AND (login_status != "账号异常" OR login_status IS NULL)`, params.Status) res := u.db.Model(&models.TwitterAccount{}).Where(`type = ? AND (login_status != "账号异常" OR login_status IS NULL)`, params.Type)
// if params.Username != "" { // if params.Username != "" {
// res.Where("username LIKE ?", "%"+params.Username+"%") // res.Where("username LIKE ?", "%"+params.Username+"%")
// } // }
res.Order("id DESC").Find(&users)
return users
}
// 获取ID范围内的账号
func (u *TwitterAccountService) GetAccountListByIdRange(minId, maxId int64) []models.TwitterAccount {
var users []models.TwitterAccount
res := u.db.Model(&models.TwitterAccount{}).Where(`id >= ? AND id <= ?`, minId, maxId)
res.Order("id DESC").Find(&users) res.Order("id DESC").Find(&users)
return users return users
} }
// 获取养号未运行或者运行失败的账号 // 获取未运行或者运行失败的账号
func (u *TwitterAccountService) GetAccountListByStatus(params *models.TwitterAccount) []models.TwitterAccount { func (u *TwitterAccountService) GetAccountListByStatus(params *models.TwitterAccount) []models.TwitterAccount {
var users []models.TwitterAccount var users []models.TwitterAccount
res := u.db.Model(&models.TwitterAccount{}).Where(`status = ? AND (login_status != "账号异常" OR login_status IS NULL)`, params.Status) res := u.db.Model(&models.TwitterAccount{}).Where(`type = ? AND (login_status != "账号异常" OR login_status IS NULL) AND (status != ? OR status IS NULL)`, params.Type, params.Status)
// if params.Username != "" { // if params.Username != "" {
// res.Where("username LIKE ?", "%"+params.Username+"%") // res.Where("username LIKE ?", "%"+params.Username+"%")
// } // }
@@ -82,7 +90,13 @@ func (u *TwitterAccountService) GetAccountListByStatus(params *models.TwitterAcc
// 清空状态字段 // 清空状态字段
func (u *TwitterAccountService) ClearAccountStatus(params *models.TwitterAccount) bool { func (u *TwitterAccountService) ClearAccountStatus(params *models.TwitterAccount) bool {
u.db.Model(&models.TwitterAccount{}).Where("status = ?", params.Status).Update("status", nil) u.db.Model(&models.TwitterAccount{}).Where("type = ?", params.Type).Update("status", nil)
return true
}
// 清空状态字段
func (u *TwitterAccountService) ChangeAccountStatusByStatus(params *models.TwitterAccount, status string) bool {
u.db.Model(&models.TwitterAccount{}).Where("status = ?", params.Status).Update("status", status)
return true return true
} }
@@ -90,3 +104,7 @@ func (u *TwitterAccountService) Update(id int64, params *models.TwitterAccount)
params.UpdateTime = time.Now().Unix() params.UpdateTime = time.Now().Unix()
u.db.Model(&models.TwitterAccount{}).Where("id = ?", id).Updates(params) u.db.Model(&models.TwitterAccount{}).Where("id = ?", id).Updates(params)
} }
func (u *TwitterAccountService) Delete(id int64) {
u.db.Delete(&models.TwitterAccount{}, id)
}

View File

@@ -0,0 +1,25 @@
package services
import (
"go-account-register/models"
"go-account-register/utils"
"gorm.io/gorm"
)
type TwitterPostService struct {
db *gorm.DB
}
func InitTwitterPostService() *TwitterPostService {
db := utils.GetDB()
return &TwitterPostService{db: db}
}
func (s *TwitterPostService) GetAll() []models.TwitterPost {
var post []models.TwitterPost
res := s.db.Model(&models.TwitterPost{}).Where(`status = ? `, 1)
res.Order("id DESC").Find(&post)
return post
}

View File

@@ -6,6 +6,7 @@ import (
"sort" "sort"
"sync" "sync"
"go-account-register/plugin"
paramsTypes "go-account-register/types" paramsTypes "go-account-register/types"
"github.com/fatih/structs" "github.com/fatih/structs"
@@ -168,20 +169,20 @@ func (s *Scheduler) processQueue() {
func (s *Scheduler) executeTask(task *paramsTypes.Task) { func (s *Scheduler) executeTask(task *paramsTypes.Task) {
// 根据类型判断任务 // 根据类型判断任务
// switch task.Type { switch task.Type {
// case 6: // case 6:
// var taskNurturingClashPlugin plugin.TaskNurturingClashPlugin // var taskNurturingClashPlugin plugin.TaskNurturingClashPlugin
// go taskNurturingClashPlugin.Run(task) // go taskNurturingClashPlugin.Run(task)
// case 1: case 1:
// var taskChangeAccoutnClashPlugin plugin.TaskChangeAccoutnClashPlugin var taskViewPostPlugin plugin.TaskViewPostPlugin
// go taskChangeAccoutnClashPlugin.Run(task) go taskViewPostPlugin.Run(task)
// case 3: // case 3:
// var taskFollowClashPlugin plugin.TaskFollowClashPlugin // var taskFollowClashPlugin plugin.TaskFollowClashPlugin
// go taskFollowClashPlugin.Run(task) // go taskFollowClashPlugin.Run(task)
// case 7: // case 7:
// var taskSendGifPlugin plugin.TaskSendGifPlugin // var taskSendGifPlugin plugin.TaskSendGifPlugin
// go taskSendGifPlugin.Run(task) // go taskSendGifPlugin.Run(task)
// } }
// 创建一个阻塞获取当前任务 // 创建一个阻塞获取当前任务
select { select {