自动点赞

This commit is contained in:
wong
2025-05-09 09:22:31 +08:00
parent 3ff8b5a95c
commit 998b795df4
9 changed files with 648 additions and 55 deletions

View File

@@ -2,15 +2,19 @@
import { useState, useEffect, use } from "react"
import { useRouter } from "next/navigation"
import { ChevronLeft, Search } from "lucide-react"
import { ChevronLeft, Search, Users } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { StepIndicator } from "../../components/step-indicator"
import { BasicSettings } from "../../components/basic-settings"
import { DeviceSelectionDialog } from "../../components/device-selection-dialog"
import { TagSelector } from "../../components/tag-selector"
import { WechatGroupMemberSelector } from "@/components/WechatGroupMemberSelector"
import { WechatFriendSelector } from "@/components/WechatFriendSelector"
import { api, ApiResponse } from "@/lib/api"
import { showToast } from "@/lib/toast"
import { WechatGroupMember } from "@/types/wechat"
import { WechatFriend } from "@/components/WechatFriendSelector"
interface TaskConfig {
id: number
@@ -43,6 +47,11 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
const router = useRouter()
const [currentStep, setCurrentStep] = useState(1)
const [deviceDialogOpen, setDeviceDialogOpen] = useState(false)
const [isGroupMemberSelectorOpen, setIsGroupMemberSelectorOpen] = useState(false)
const [currentGroupId, setCurrentGroupId] = useState<string>("")
const [selectedGroupMembers, setSelectedGroupMembers] = useState<WechatGroupMember[]>([])
const [isFriendSelectorOpen, setIsFriendSelectorOpen] = useState(false)
const [selectedFriends, setSelectedFriends] = useState<WechatFriend[]>([])
const [loading, setLoading] = useState(true)
const [formData, setFormData] = useState({
taskName: "",
@@ -52,8 +61,7 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
contentTypes: ["text", "image", "video"],
enabled: true,
selectedDevices: [] as number[],
selectedTags: [] as string[],
tagOperator: "and" as "and" | "or",
friends: [] as string[],
})
useEffect(() => {
@@ -78,8 +86,7 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
contentTypes: task.config.contentTypes,
enabled: task.status === 1,
selectedDevices: task.config.devices,
selectedTags: task.config.targetGroups,
tagOperator: task.config.tagOperator === 1 ? "and" : "or"
friends: Array.isArray(task.config.friends) ? task.config.friends : [],
})
} else {
showToast(response.msg || "获取任务信息失败", "error")
@@ -121,8 +128,7 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
contentTypes: formData.contentTypes,
enabled: formData.enabled,
devices: formData.selectedDevices,
targetGroups: formData.selectedTags,
tagOperator: formData.tagOperator === 'and' ? 1 : 2
friends: formData.friends,
});
if (response.code === 200) {
@@ -140,6 +146,17 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
}
};
const handleSelectFriends = () => {
setIsFriendSelectorOpen(true)
}
const handleSaveSelectedFriends = (friends: WechatFriend[]) => {
const ids = friends.map(f => f.id)
setSelectedFriends(friends)
handleUpdateFormData({ friends: ids })
setIsFriendSelectorOpen(false)
}
if (loading) {
return null;
}
@@ -207,15 +224,19 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
{currentStep === 3 && (
<div className="px-6">
<TagSelector
selectedTags={formData.selectedTags}
tagOperator={formData.tagOperator}
onTagsChange={(tags) => handleUpdateFormData({ selectedTags: tags })}
onOperatorChange={(operator) => handleUpdateFormData({ tagOperator: operator })}
onBack={handlePrev}
onComplete={handleComplete}
/>
<div className="relative">
<Users className="absolute left-3 top-4 h-5 w-5 text-gray-400" />
<Input
placeholder="选择微信好友"
className="h-12 pl-11 rounded-xl border-gray-200 text-base"
onClick={handleSelectFriends}
readOnly
value={formData.friends.length > 0 ? `已选择 ${formData.friends.length} 个好友` : ""}
/>
</div>
{formData.friends.length > 0 && (
<div className="text-base text-gray-500">{formData.friends.length} </div>
)}
<div className="flex space-x-4 pt-4">
<Button variant="outline" onClick={handlePrev} className="flex-1 h-12 rounded-xl text-base">
@@ -227,6 +248,12 @@ export default function EditAutoLikePage({ params }: { params: Promise<{ id: str
</Button>
</div>
<WechatFriendSelector
open={isFriendSelectorOpen}
onOpenChange={setIsFriendSelectorOpen}
selectedFriends={selectedFriends}
onSelect={handleSaveSelectedFriends}
/>
</div>
)}
</div>

View File

@@ -10,7 +10,7 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { api } from "@/lib/api"
import { showToast } from "@/lib/toast"
interface WechatFriend {
export interface WechatFriend {
id: string
nickname: string
wechatId: string

View File

@@ -220,8 +220,8 @@ class WebSocketController extends BaseController
$maxPages = 20; // 最大页数限制为20
$currentPage = 1; // 当前页码
$allMoments = []; // 存储所有朋友圈数据
//过滤消息
//过滤消息
if (empty($wechatAccountId)) {
return json_encode(['code'=>400,'msg'=>'指定账号不能为空']);
}
@@ -243,12 +243,39 @@ class WebSocketController extends BaseController
$message = $this->sendMessage($params);
Log::info('获取朋友圈信成功:' . json_encode($message, 256));
// 检查是否遇到频率限制
if (isset($message['extra']) && strpos($message['extra'], '朋友圈太频繁了') !== false) {
Log::info('遇到频率限制,休息10秒后继续');
sleep(10);
continue;
}
// 检查返回结果
if (!isset($message['result']) || empty($message['result']) || !is_array($message['result'])) {
break;
}
// 检查是否遇到旧数据
$hasOldData = false;
foreach ($message['result'] as $moment) {
$momentId = WechatMoments::where('snsId', $moment['snsId'])
->where('wechatAccountId', $wechatAccountId)
->value('id');
if (!empty($momentId)) {
$hasOldData = true;
break;
}
}
// 如果遇到旧数据,结束本次任务
if ($hasOldData) {
// Log::info('遇到旧数据,结束本次任务');
// break;
}
// 合并朋友圈数据
$allMoments = array_merge($allMoments, $message['result']);
@@ -299,40 +326,36 @@ class WebSocketController extends BaseController
* 朋友圈点赞
* @return \think\response\Json
*/
public function momentInteract()
public function momentInteract($data = [])
{
if ($this->request->isPost()) {
$data = $this->request->param();
$snsId = !empty($data['snsId']) ? $data['snsId'] : '';
$wechatAccountId = !empty($data['wechatAccountId']) ? $data['wechatAccountId'] : '';
$wechatFriendId = !empty($data['wechatFriendId']) ? $data['wechatFriendId'] : 0;
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
//过滤消息
if (empty($data['snsId'])) {
return json_encode(['code'=>400,'msg'=>'snsId不能为空']);
}
if (empty($data['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
//过滤消息
if (empty($snsId)) {
return json_encode(['code'=>400,'msg'=>'snsId不能为空']);
}
if (empty($wechatAccountId)) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
try {
try {
$result = [
"cmdType" => "CmdMomentInteract",
"momentInteractType" => 1,
"seq" => time(),
"snsId" => $data['snsId'],
"wechatAccountId" => $data['wechatAccountId'],
"wechatFriendId" => 0,
];
"snsId" => $snsId,
"wechatAccountId" => $wechatAccountId,
"wechatFriendId" => $wechatFriendId,
];
$message = $this->sendMessage($result);
return json_encode(['code'=>200,'msg'=>'点赞成功','data'=>$message]);
} catch (\Exception $e) {
return json_encode(['code'=>500,'msg'=>$e->getMessage()]);
}
} else {
return json_encode(['code'=>400,'msg'=>'非法请求']);
$message = $this->sendMessage($result);
return json_encode(['code'=>200,'msg'=>'点赞成功','data'=>$message]);
} catch (\Exception $e) {
return json_encode(['code'=>500,'msg'=>$e->getMessage()]);
}
}

View File

@@ -27,4 +27,5 @@ return [
'allotrule:autocreate' => 'app\command\AutoCreateAllotRulesCommand', // 自动创建分配规则 √
'content:collect' => 'app\command\ContentCollectCommand', // 内容采集任务 √
'moments:collect' => 'app\command\WechatMomentsCommand', // 朋友圈采集任务
'workbench:run' => 'app\command\WorkbenchCommand', // 工作台任务
];

View File

@@ -0,0 +1,77 @@
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Option;
use think\facade\Log;
use think\Queue;
use app\job\WorkbenchJob;
use think\facade\Cache;
class WorkbenchCommand extends Command
{
// 队列名称
protected $queueName = 'workbench';
protected function configure()
{
$this->setName('workbench:run')
->setDescription('工作台任务队列')
->addOption('jobId', null, Option::VALUE_OPTIONAL, '任务ID用于区分不同实例', date('YmdHis') . rand(1000, 9999));
}
protected function execute(Input $input, Output $output)
{
$output->writeln('开始处理工作台任务...');
try {
// 获取任务ID
$jobId = $input->getOption('jobId');
$output->writeln('任务ID: ' . $jobId);
// 检查队列是否已经在运行
$queueLockKey = "queue_lock:{$this->queueName}";
Cache::rm($queueLockKey);
if (Cache::get($queueLockKey)) {
$output->writeln("队列 {$this->queueName} 已经在运行中,跳过执行");
Log::warning("队列 {$this->queueName} 已经在运行中,跳过执行");
return false;
}
// 设置队列运行锁有效期1小时
Cache::set($queueLockKey, $jobId, 3600);
$output->writeln("已设置队列运行锁,键名:{$queueLockKey},值:{$jobId},有效期:1小时");
// 将任务添加到队列
$this->addToQueue($jobId, $queueLockKey);
$output->writeln('工作台任务已添加到队列');
} catch (\Exception $e) {
Log::error('工作台任务添加失败:' . $e->getMessage());
$output->writeln('工作台任务添加失败:' . $e->getMessage());
return false;
}
return true;
}
/**
* 添加任务到队列
* @param string $jobId 任务ID
* @param string $queueLockKey 队列锁键名
*/
public function addToQueue($jobId = '', $queueLockKey = '')
{
$data = [
'jobId' => $jobId,
'queueLockKey' => $queueLockKey
];
// 添加到队列,设置任务名为 workbench
Queue::push(WorkbenchJob::class, $data, $this->queueName);
}
}

View File

@@ -10,7 +10,7 @@ use think\facade\Log;
class AuthService
{
const TOKEN_EXPIRE = 7200;
const TOKEN_EXPIRE = 86400;
protected $smsService;

View File

@@ -71,8 +71,9 @@ class WorkbenchController extends Controller
$config->endTime = $param['endTime'];
$config->contentTypes = json_encode($param['contentTypes']);
$config->devices = json_encode($param['devices']);
$config->targetGroups = json_encode($param['targetGroups']);
$config->tagOperator = $param['tagOperator'];
$config->friends = json_encode($param['friends']);
// $config->targetGroups = json_encode($param['targetGroups']);
// $config->tagOperator = $param['tagOperator'];
$config->createTime = time();
$config->updateTime = time();
$config->save();
@@ -156,7 +157,7 @@ class WorkbenchController extends Controller
// 定义关联关系
$with = [
'autoLike' => function($query) {
$query->field('workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,targetGroups');
$query->field('workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,friends');
},
'momentsSync' => function($query) {
$query->field('workbenchId,syncInterval,syncCount,syncType,startTime,endTime,accountType,devices,contentLibraries');
@@ -179,8 +180,9 @@ class WorkbenchController extends Controller
if (!empty($item->autoLike)) {
$item->config = $item->autoLike;
$item->config->devices = json_decode($item->config->devices, true);
$item->config->targetGroups = json_decode($item->config->targetGroups, true);
//$item->config->targetGroups = json_decode($item->config->targetGroups, true);
$item->config->contentTypes = json_decode($item->config->contentTypes, true);
$item->config->friends = json_decode($item->config->friends, true);
}
unset($item->autoLike,$item->auto_like);
break;
@@ -256,7 +258,7 @@ class WorkbenchController extends Controller
// 定义关联关系
$with = [
'autoLike' => function($query) {
$query->field('workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,targetGroups');
$query->field('workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,friends');
},
'momentsSync' => function($query) {
$query->field('workbenchId,syncInterval,syncCount,syncType,startTime,endTime,accountType,devices,contentLibraries');
@@ -288,7 +290,8 @@ class WorkbenchController extends Controller
if (!empty($workbench->autoLike)) {
$workbench->config = $workbench->autoLike;
$workbench->config->devices = json_decode($workbench->config->devices, true);
$workbench->config->targetGroups = json_decode($workbench->config->targetGroups, true);
$workbench->config->friends = json_decode($workbench->config->friends, true);
//$workbench->config->targetGroups = json_decode($workbench->config->targetGroups, true);
$workbench->config->contentTypes = json_decode($workbench->config->contentTypes, true);
unset($workbench->autoLike,$workbench->auto_like);
}
@@ -372,8 +375,9 @@ class WorkbenchController extends Controller
$config->endTime = $param['endTime'];
$config->contentTypes = json_encode($param['contentTypes']);
$config->devices = json_encode($param['devices']);
$config->targetGroups = json_encode($param['targetGroups']);
$config->tagOperator = $param['tagOperator'];
$config->friends = json_encode($param['friends']);
// $config->targetGroups = json_encode($param['targetGroups']);
// $config->tagOperator = $param['tagOperator'];
$config->updateTime = time();
$config->save();
}
@@ -540,7 +544,8 @@ class WorkbenchController extends Controller
$newConfig->endTime = $config->endTime;
$newConfig->contentTypes = $config->contentTypes;
$newConfig->devices = $config->devices;
$newConfig->targetGroups = $config->targetGroups;
$newConfig->friends = $config->friends;
//$newConfig->targetGroups = $config->targetGroups;
$newConfig->save();
}
break;

View File

@@ -25,7 +25,7 @@ class Workbench extends Validate
'startTime' => 'requireIf:type,1|dateFormat:H:i',
'endTime' => 'requireIf:type,1|dateFormat:H:i',
'contentTypes' => 'requireIf:type,1|array|contentTypeEnum:text,image,video',
'targetGroups' => 'requireIf:type,1|array',
//'targetGroups' => 'requireIf:type,1|array',
// 朋友圈同步特有参数
'syncInterval' => 'requireIf:type,2|number|min:1',
'syncCount' => 'requireIf:type,2|number|min:1',

View File

@@ -0,0 +1,460 @@
<?php
namespace app\job;
use think\queue\Job;
use think\facade\Log;
use think\Queue;
use think\facade\Config;
use think\facade\Cache;
use app\cunkebao\model\Workbench;
use app\cunkebao\model\WorkbenchAutoLike;
use app\cunkebao\model\WorkbenchMomentsSync;
use app\cunkebao\model\WorkbenchGroupPush;
use app\cunkebao\model\WorkbenchGroupCreate;
use think\Db;
use app\api\controller\WebSocketController;
class WorkbenchJob
{
/**
* 工作台类型定义
*/
const TYPE_AUTO_LIKE = 1; // 自动点赞
const TYPE_MOMENTS_SYNC = 2; // 朋友圈同步
const TYPE_GROUP_PUSH = 3; // 群消息推送
const TYPE_GROUP_CREATE = 4; // 自动建群
/**
* 最大重试次数
*/
const MAX_RETRY_ATTEMPTS = 3;
/**
* 队列任务处理
* @param Job $job 队列任务
* @param array $data 任务数据
* @return bool
*/
public function fire(Job $job, $data)
{
$jobId = $data['jobId'] ?? '';
$queueLockKey = $data['queueLockKey'] ?? '';
try {
$this->logJobStart($jobId, $queueLockKey);
$workbenches = $this->getActiveWorkbenches();
if ($workbenches->isEmpty()) {
$this->handleEmptyWorkbenches($job, $queueLockKey);
return true;
}
$this->processWorkbenches($workbenches);
$this->handleJobSuccess($job, $queueLockKey);
return true;
} catch (\Exception $e) {
return $this->handleJobError($e, $job, $queueLockKey);
}
}
/**
* 获取活跃的工作台
* @return \think\Collection
*/
protected function getActiveWorkbenches()
{
return Workbench::where([
['status', '=', 1],
['isDel', '=', 0]
])->order('id DESC')->select();
}
/**
* 处理空工作台情况
* @param Job $job
* @param string $queueLockKey
*/
protected function handleEmptyWorkbenches(Job $job, $queueLockKey)
{
Log::info('没有需要处理的工作台任务');
$job->delete();
Cache::rm($queueLockKey);
}
/**
* 处理工作台列表
* @param \think\Collection $workbenches
*/
protected function processWorkbenches($workbenches)
{
foreach ($workbenches as $workbench) {
try {
$this->processSingleWorkbench($workbench);
} catch (\Exception $e) {
Log::error("处理工作台 {$workbench->id} 失败: " . $e->getMessage());
}
}
}
/**
* 处理单个工作台
* @param Workbench $workbench
*/
protected function processSingleWorkbench($workbench)
{
$config = $this->getWorkbenchConfig($workbench);
if (!$config) {
Log::error("工作台 {$workbench->id} 配置获取失败");
return;
}
$handler = $this->getWorkbenchHandler($workbench->type);
if ($handler) {
$handler($workbench, $config);
}
}
/**
* 获取工作台处理器
* @param int $type
* @return callable|null
*/
protected function getWorkbenchHandler($type)
{
$handlers = [
self::TYPE_AUTO_LIKE => [$this, 'handleAutoLike'],
self::TYPE_MOMENTS_SYNC => [$this, 'handleMomentsSync'],
self::TYPE_GROUP_PUSH => [$this, 'handleGroupPush'],
self::TYPE_GROUP_CREATE => [$this, 'handleGroupCreate']
];
return $handlers[$type] ?? null;
}
/**
* 处理自动点赞任务
* @param Workbench $workbench
* @param WorkbenchAutoLike $config
*/
protected function handleAutoLike($workbench, $config)
{
if (!$this->validateAutoLikeConfig($workbench, $config)) {
return;
}
$likeCount = $this->getTodayLikeCount($workbench, $config);
if ($likeCount >= $config['maxLikes']) {
Log::info("工作台 {$workbench->id} 点赞次数已达上限");
return;
}
if (!$this->isWithinLikeTimeRange($config)) {
return;
}
$friendList = $this->getFriendList($config['friends']);
foreach ($friendList as $friend) {
$this->processFriendMoments($workbench, $config, $friend, $likeCount);
}
}
/**
* 验证自动点赞配置
* @param Workbench $workbench
* @param WorkbenchAutoLike $config
* @return bool
*/
protected function validateAutoLikeConfig($workbench, $config)
{
$requiredFields = ['friends', 'contentTypes', 'interval', 'maxLikes', 'startTime', 'endTime'];
foreach ($requiredFields as $field) {
if (empty($config[$field])) {
Log::error("工作台 {$workbench->id} 配置字段 {$field} 为空");
return false;
}
}
$friends = json_decode($config['friends'], true);
if (!is_array($friends) || empty($friends)) {
Log::error("工作台 {$workbench->id} 点赞的好友为空");
return false;
}
return true;
}
/**
* 获取今日点赞次数
* @param Workbench $workbench
* @param WorkbenchAutoLike $config
* @return int
*/
protected function getTodayLikeCount($workbench, $config)
{
return Db::name('workbench_auto_like_item')
->where('workbenchId', $workbench->id)
->whereTime('createTime', 'between', [
strtotime(date('Y-m-d') . ' ' . $config['startTime'] . ':00'),
strtotime(date('Y-m-d') . ' ' . $config['endTime'] . ':00')
])
->count();
}
/**
* 检查是否在点赞时间范围内
* @param WorkbenchAutoLike $config
* @return bool
*/
protected function isWithinLikeTimeRange($config)
{
$currentTime = date('H:i');
if ($currentTime < $config['startTime'] || $currentTime > $config['endTime']) {
Log::info("当前时间 {$currentTime} 不在点赞时间范围内 ({$config['startTime']} - {$config['endTime']})");
return false;
}
return true;
}
/**
* 获取好友列表
* @param string $friendsJson
* @return array
*/
protected function getFriendList($friendsJson)
{
$friends = json_decode($friendsJson, true);
return Db::table('s2_company_account')
->alias('ca')
->join(['s2_wechat_account' => 'wa'], 'ca.id = wa.deviceAccountId')
->join(['s2_wechat_friend' => 'wf'], 'ca.id = wf.accountId')
->where('ca.passwordLocal', '<>', '')
->where([
'ca.status' => 0,
'wf.isDeleted' => 0,
'wa.deviceAlive' => 1,
'wa.wechatAlive' => 1
])
->whereIn('wf.id', $friends)
->field([
'ca.id as accountId',
'ca.userName',
'ca.passwordLocal',
'wf.id as friendId',
'wf.wechatId',
'wf.wechatAccountId'
])
->group('wf.wechatAccountId DESC')
->order('ca.id DESC')
->select()
->toArray();
}
/**
* 处理好友朋友圈
* @param Workbench $workbench
* @param WorkbenchAutoLike $config
* @param array $friend
* @param int &$likeCount
*/
protected function processFriendMoments($workbench, $config, $friend, &$likeCount)
{
$moments = $this->getUnlikedMoments($friend['friendId']);
if ($moments->isEmpty()) {
Log::info("好友 {$friend['friendId']} 没有需要点赞的朋友圈");
return;
}
foreach ($moments as $moment) {
if ($likeCount >= $config['maxLikes']) {
break;
}
$this->likeMoment($workbench, $config, $friend, $moment, $likeCount);
}
}
/**
* 获取未点赞的朋友圈
* @param int $friendId
* @return \think\Collection
*/
protected function getUnlikedMoments($friendId)
{
return Db::table('s2_wechat_moments')
->alias('wm')
->join('workbench_auto_like_item wali', 'wali.momentsId = wm.id', 'left')
->where([
['wm.wechatFriendId', '=', $friendId],
['wali.id', 'null', null]
])
->field('wm.id, wm.snsId')
->order('wm.id DESC')
->select();
}
/**
* 点赞朋友圈
* @param Workbench $workbench
* @param WorkbenchAutoLike $config
* @param array $friend
* @param array $moment
* @param int &$likeCount
*/
protected function likeMoment($workbench, $config, $friend, $moment, &$likeCount)
{
try {
$wsController = new WebSocketController([
'userName' => $friend['userName'],
'password' => localDecrypt($friend['passwordLocal']),
'accountId' => $friend['accountId']
]);
$result = $wsController->momentInteract([
'snsId' => $moment['snsId'],
'wechatAccountId' => $friend['wechatAccountId'],
]);
$result = json_decode($result, true);
if ($result['code'] == 200) {
$this->recordLike($workbench, $moment, $friend);
$likeCount++;
sleep($config['interval']);
} else {
Log::error("工作台 {$workbench->id} 点赞失败: " . ($result['msg'] ?? '未知错误'));
}
} catch (\Exception $e) {
Log::error("工作台 {$workbench->id} 点赞异常: " . $e->getMessage());
}
}
/**
* 记录点赞
* @param Workbench $workbench
* @param array $moment
* @param array $friend
*/
protected function recordLike($workbench, $moment, $friend)
{
Db::name('workbench_auto_like_item')->insert([
'workbenchId' => $workbench->id,
'momentsId' => $moment['id'],
'snsId' => $moment['snsId'],
'wechatAccountId' => $friend['wechatAccountId'],
'wechatFriendId' => $friend['friendId'],
'createTime' => time()
]);
Log::info("工作台 {$workbench->id} 点赞成功: {$moment['snsId']}");
}
/**
* 记录任务开始
* @param string $jobId
* @param string $queueLockKey
*/
protected function logJobStart($jobId, $queueLockKey)
{
Log::info('开始处理工作台任务: ' . json_encode([
'jobId' => $jobId,
'queueLockKey' => $queueLockKey
]));
}
/**
* 处理任务成功
* @param Job $job
* @param string $queueLockKey
*/
protected function handleJobSuccess($job, $queueLockKey)
{
$job->delete();
Cache::rm($queueLockKey);
Log::info('工作台任务执行成功');
}
/**
* 处理任务错误
* @param \Exception $e
* @param Job $job
* @param string $queueLockKey
* @return bool
*/
protected function handleJobError(\Exception $e, $job, $queueLockKey)
{
Log::error('工作台任务异常:' . $e->getMessage());
if (!empty($queueLockKey)) {
Cache::rm($queueLockKey);
Log::info("由于异常释放队列锁: {$queueLockKey}");
}
if ($job->attempts() > self::MAX_RETRY_ATTEMPTS) {
$job->delete();
} else {
$job->release(Config::get('queue.failed_delay', 10));
}
return false;
}
/**
* 获取工作台配置
* @param Workbench $workbench 工作台实例
* @return mixed
*/
protected function getWorkbenchConfig($workbench)
{
switch ($workbench->type) {
case self::TYPE_AUTO_LIKE:
return WorkbenchAutoLike::where('workbenchId', $workbench->id)->find();
case self::TYPE_MOMENTS_SYNC:
return WorkbenchMomentsSync::where('workbenchId', $workbench->id)->find();
case self::TYPE_GROUP_PUSH:
return WorkbenchGroupPush::where('workbenchId', $workbench->id)->find();
case self::TYPE_GROUP_CREATE:
return WorkbenchGroupCreate::where('workbenchId', $workbench->id)->find();
default:
return null;
}
}
/**
* 处理朋友圈同步任务
* @param Workbench $workbench 工作台实例
* @param WorkbenchMomentsSync $config 配置实例
*/
protected function handleMomentsSync($workbench, $config)
{
// TODO: 实现朋友圈同步逻辑
Log::info("处理朋友圈同步任务: {$workbench->id}");
}
/**
* 处理群消息推送任务
* @param Workbench $workbench 工作台实例
* @param WorkbenchGroupPush $config 配置实例
*/
protected function handleGroupPush($workbench, $config)
{
// TODO: 实现群消息推送逻辑
Log::info("处理群消息推送任务: {$workbench->id}");
}
/**
* 处理自动建群任务
* @param Workbench $workbench 工作台实例
* @param WorkbenchGroupCreate $config 配置实例
*/
protected function handleGroupCreate($workbench, $config)
{
// TODO: 实现自动建群逻辑
Log::info("处理自动建群任务: {$workbench->id}");
}
}