新增查看推文模块
This commit is contained in:
@@ -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
39
models/ar_twitter_post.go
Normal 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
|
||||||
|
}
|
||||||
103
plugin/task-view-post-plugin.go
Normal file
103
plugin/task-view-post-plugin.go
Normal 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)
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|||||||
25
services/twitter_post_service.go
Normal file
25
services/twitter_post_service.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user