Files
tougao/application/api/job/RecommendReviewer.php
chengxl 9637b30873 调整
2025-09-02 09:39:37 +08:00

111 lines
4.9 KiB
PHP
Raw 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.
<?php
namespace app\api\job;
use think\queue\Job;
use app\common\QueueJob;
use app\common\QueueRedis;
use app\common\Reviewer;
class RecommendReviewer
{
private $oQueueJob;
private $QueueRedis;
private $completedExprie = 3600; // 完成状态过期时间
public function __construct()
{
$this->oQueueJob = new QueueJob;
$this->QueueRedis = QueueRedis::getInstance();
}
public function fire(Job $job, $data)
{
//任务开始判断
$this->oQueueJob->init($job);
// 获取 Redis 任务的原始数据
$rawBody = empty($job->getRawBody()) ? '' : $job->getRawBody();
$jobData = empty($rawBody) ? [] : json_decode($rawBody, true);
$jobId = empty($jobData['id']) ? 'unknown' : $jobData['id'];
$this->oQueueJob->log("-----------队列任务开始-----------");
$this->oQueueJob->log("当前任务ID: {$jobId}, 尝试次数: {$job->attempts()}");
try {
// 验证任务数据完整性
$iArticleId = empty($data['article_id']) ? 0 : $data['article_id'];
if (empty($iArticleId)) {
$this->oQueueJob->log("无效的article_id删除任务");
$job->delete();
return;
}
// 生成Redis键并尝试获取锁
$sClassName = get_class($this);
$sRedisKey = "queue_job:{$sClassName}:{$iArticleId}";
$sRedisValue = uniqid() . '_' . getmypid();
if (!$this->oQueueJob->acquireLock($sRedisKey, $sRedisValue, $job)) {
return; // 未获取到锁,已处理
}
// 执行核心任务
//获取推荐审稿人信息
$aParam = ['article_id' => $iArticleId,'page' => 1,'size' => empty($data['size']) ? 5 : $data['size']];
$oReviewer = new Reviewer;
$response = $oReviewer->recommend($aParam);
// 验证API响应
if (empty($response)) {
throw new \RuntimeException("OpenAI API返回空结果");
}
// 检查JSON解析错误
$aResult = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \RuntimeException("解析OpenAI响应失败: " . json_last_error_msg() . " | 原始响应: {$response}");
}
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
$sMsg = empty($aResult['msg']) ? '' : $aResult['msg'];
//处理数据
$iCount = empty($aResult['data']['total']) ? 0 : $aResult['data']['total'];//数量
$iSize = empty($aResult['data']['size']) ? 0 : $aResult['data']['size'];//推荐数量
//判断是否给期刊管理者发邮件【数据库的审稿数量小于推荐数量】
if($iCount < $iSize){
$aSendEmailResult = json_decode($oReviewer->emailForEditor($aParam),true);
$sMsg .= ';';
$sMsg .= empty($aSendEmailResult['msg']) ? '发送邮件入队成功' : $aSendEmailResult['msg'];
}
//推荐审稿人数据
$aResult = empty($aResult['data']['lists']) ? [] : $aResult['data']['lists'];
if(empty($aResult)){
$sMsg .= ';';
$sMsg .= 'No qualified reviewers were selected';
}
if(!empty($aResult)){
$aParam = ['article_id' => $iArticleId,'reviewer_id' => array_column($aResult, 'reviewer_id')];
$aResult = json_decode($oReviewer->add($aParam),true);
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
$sMsg .= ';';
$sMsg .= empty($aResult['msg']) ? 'Reviewer data insertion failed' : $aResult['msg'];
//发送邀请审稿人审稿邮件
if($iStatus == 1){
$aResult = json_decode($oReviewer->email($aParam),true);
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
$sMsg .= ';';
$sMsg .= empty($aResult['msg']) ? 'Reviewer data insertion failed' : $aResult['msg'];
}
}
// 更新完成标识
$this->QueueRedis->finishJob($sRedisKey, 'completed', $this->completedExprie, $sRedisValue);
$job->delete();
$this->oQueueJob->log("任务执行成功 | 日志ID: {$sRedisKey} | 执行日志:{$sMsg}");
} catch (RuntimeException $e) {
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
} catch (LogicException $e) {
$this->oQueueJob->handleNonRetryableException($e,$sRedisKey,$sRedisValue, $job);
} catch (Exception $e) {
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
} finally {
$this->oQueueJob->finnal();
}
}
}