Merge remote-tracking branch 'origin/master'

This commit is contained in:
wangjinlei
2025-10-22 13:33:49 +08:00
8 changed files with 1367 additions and 565 deletions

View File

@@ -1724,6 +1724,16 @@ class Article extends Base
}
//文章状态修改为退修状态 给同意审稿但一直未审稿人发送邮件且扣减其分数值 chengxiaoling 20250617 end
//文章状态修改为预接收 对作者提交的稿件内容进行校对 chengxiaoling 20251013 start
if ($data['state'] == 6) {
$iArticleId = empty($article_info['article_id']) ? 0 : $article_info['article_id'];
if (!empty($iArticleId)) {
$iSeconds = 120;//两分钟后执行
Queue::later($iSeconds,'app\api\job\ArticleProofRead@fire',['article_id' => $iArticleId], 'ArticleProofRead');
}
}
//文章状态修改为预接收 对作者提交的稿件内容进行校对 chengxiaoling 20251013 end
//重新计算审稿人的审稿质量 chengxiaoling start 0416
$this->reviewQuality($article_info['article_id']);
//重新计算审稿人的审稿质量 chengxiaoling end 0416
@@ -4610,7 +4620,7 @@ class Article extends Base
*/
private function messageTips($article_id, $user_id)
{
$article = $this->article_obj->field('t_article.user_id,t_article.editor_id,t_article.accept_sn,t_journal.journal_id,t_journal.title,t_journal.email,t_journal.epassword')
$article = $this->article_obj->field('t_article.user_id,t_article.editor_id,t_article.accept_sn,t_journal.journal_id,t_journal.title,t_journal.email,t_journal.epassword,t_journal.issn as journal_issn,t_journal.website as journal_website')
->join('t_journal', 't_journal.journal_id = t_article.journal_id', 'LEFT')
->where('t_article.article_id', $article_id)
->find();
@@ -4629,12 +4639,64 @@ class Article extends Base
if ($res['type'] == 2) { //编辑 - 修改editor_act,并发送给作者发邮件
$this->article_obj->where('article_id', $article_id)->update(['editor_act' => 1]);
$author = $this->user_obj->where('user_id', $article['user_id'])->find();
// 发邮件
$content = 'Dear ' . $author['realname'] . ',<br>';
$content .= 'Thank you for contacting our editor. <br>ID: ' . $article['accept_sn'] . '.<br><br>';
$content .= ' Your manuscript: ' . $article['accept_sn'] . ' has received a new reply; please login https://submission.tmrjournals.com/login to check. <br>';
$content .= 'Sincerely,<br>' . $article['title'];
sendEmail($author['email'], $article['title'], $article['title'], $content, $article['email'], $article['epassword']);
// // 发邮件
// $content = 'Dear ' . $author['realname'] . ',<br>';
// $content .= 'Thank you for contacting our editor. <br>ID: ' . $article['accept_sn'] . '.<br><br>';
// $content .= ' Your manuscript: ' . $article['accept_sn'] . ' has received a new reply; please login https://submission.tmrjournals.com/login to check. <br>';
// $content .= 'Sincerely,<br>' . $article['title'];
// sendEmail($author['email'], $article['title'], $article['title'], $content, $article['email'], $article['epassword']);
//邮件内容修改 chengxiaoling 20251015 start
//邮箱
$email = empty($author['email']) ? '' : $author['email'];
if(!empty($email)){
//邮件模版
$aEmailConfig = [
'email_subject' => 'Please Check the Editorial Comments in the Submission System',
'email_content' => 'Dear {author_name},<br><br>
We would like to inform you that our editors have left a message regarding your submission in the online submission system at https://submission.tmrjournals.com/login.<br>
Please log in to your account to view the message and respond at your earliest convenience.<br><br>
If you have any questions or encounter any issues accessing the submission system, please feel free to contact us.<br><br>
Sincerely,<br>
Editorial Office<br>
{journal_title}<br>
<a href="https://www.tmrjournals.com/draw_up.html?issn={journal_issn}">Subscribe to this journal</a><br>
Email: {journal_email}<br>
Website: {website}'
];
//作者姓名
$realname = empty($author['realname']) ? '' : $author['realname'];
$realname = empty($author['account']) ? $realname : $author['account'];
//期刊标题
$from_name = empty($article['title']) ? '' : $article['title'];
//发送邮件
$memail = empty($article['email']) ? '' : $article['email'];
$mpassword = empty($article['epassword']) ? '' : $article['epassword'];
//处理数据
$aSearch = [
'{journal_title}' => $from_name,//期刊名
'{journal_issn}' => empty($article['journal_issn']) ? '' : $article['journal_issn'],
'{journal_email}' => empty($article['email']) ? '' : $article['email'],
'{website}' => empty($article['journal_website']) ? '' : $article['journal_website'],
'{author_name}' => $realname
];
//邮件标题
$title = empty($aEmailConfig['email_subject']) ? '' : $aEmailConfig['email_subject'];
//邮件内容变量替换
$content = str_replace(array_keys($aSearch), array_values($aSearch), $aEmailConfig['email_content']);
$pre = \think\Env::get('emailtemplete.pre');
$net = \think\Env::get('emailtemplete.net');
$net1 = str_replace("{{email}}",trim($email),$net);
$content=$pre.$content.$net1;
//发送邮件
$result = sendEmail($email,$title,$from_name,$content,$memail,$mpassword);
}
//邮件内容修改 chengxiaoling 20251015 end
}
}

View File

@@ -838,6 +838,127 @@ class Board extends Base {
}
}
/**
* 新增编辑编委信息-新
*/
public function addBoardNew(){
$data = $this->request->post();
$rule = new Validate([
"user_id"=>"require",
"journal_id"=>"require",
"type"=>"require",
"board_group_id"=>"require",
"research_areas"=>"require",
"realname"=>"require",
"email"=>"require",
"website"=>"require",
"affiliation"=>"require",
"technical"=>"require",
'icon' => "require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
$check = $this->board_to_journal_obj->where('user_id',$data['user_id'])->where('state',0)->find();
if($check){
return jsonError("According to TMR Publishing Group Policy, scientists are not allowed to serve on the editorial board of more than one journal at the same time.");
}
//新增必填字段 chengxiaoling 20251020 start
//必填验证
$sField = '';
$aFields = ['research_areas','realname','email','website','affiliation','technical','icon'];
foreach ($aFields as $value) {
$sInfo = empty($data[$value]) ? '' : trim($data[$value]);
if(empty($sInfo)){
$sField = $value;
break;
}
}
if(!empty($sField)){
return jsonError($sField.' cannot be empty');
}
//新增必填字段 chengxiaoling 20251020 end
//添加对应关系
$insert['user_id'] = $data['user_id'];
$insert['journal_id'] = $data['journal_id'];
$insert['type'] = $data['type'];
$insert['board_group_id'] = $data['board_group_id'];
$insert['research_areas'] = trim($data['research_areas']);
//新增必填字段 chengxiaoling 20251020 start
$insert['realname'] = trim($data['realname']);
$insert['email'] = trim($data['email']);
$insert['website'] = trim($data['website']);
$insert['affiliation'] = trim($data['affiliation']);
$insert['technical'] = trim($data['technical']);
$insert['icon'] = trim($data['icon']);
//新增必填字段 chengxiaoling 20251020 end
$this->board_to_journal_obj->insert($insert);
return jsonSuccess([]);
}
/**
* 修改编辑编委信息-新
*/
public function editBoardNew(){
$data = $this->request->post();
$rule = new Validate([
"btj_id"=>"require",
"type"=>'require',
"board_group_id"=>"require",
"research_areas"=>"require",
"realname"=>"require",
"email"=>"require",
"website"=>"require",
"affiliation"=>"require",
"technical"=>"require",
'icon' => "require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
//新增必填字段 chengxiaoling 20251020 start
//必填验证
$sField = '';
$aFields = ['research_areas','realname','email','website','affiliation','technical','icon'];
foreach ($aFields as $value) {
$sInfo = empty($data[$value]) ? '' : trim($data[$value]);
if(empty($sInfo)){
$sField = $value;
break;
}
}
if(!empty($sField)){
return jsonError($sField.' cannot be empty');
}
//新增必填字段 chengxiaoling 20251020 end
$update['type'] = $data['type'];
$update['board_group_id'] = $data['type']==2?$data['board_group_id']:0;
$update['research_areas'] = trim($data['research_areas']);
//新增必填字段 chengxiaoling 20251020 start
$update['realname'] = trim($data['realname']);
$update['email'] = trim($data['email']);
$update['website'] = trim($data['website']);
$update['affiliation'] = trim($data['affiliation']);
$update['technical'] = trim($data['technical']);
$update['icon'] = trim($data['icon']);
//新增必填字段 chengxiaoling 20251020 end
$this->board_to_journal_obj->where('btj_id',$data['btj_id'])->update($update);
return jsonSuccess([]);
}
/**
* 编委上传头像
*/
public function uploadIcon()
{
$file = request()->file('icon');
if ($file) {
$info = $file->move(ROOT_PATH . 'public' . DS . 'boardusericon');
if ($info) {
return json(['code' => 0, 'upurl' => str_replace("\\", "/", $info->getSaveName())]);
} else {
return json(['code' => 1, 'msg' => $file->getError()]);
}
}
}
}

View File

@@ -531,6 +531,14 @@ class Chief extends Controller {
public function checkEmailForUser(){
$data = $this->request->post();
$user_info = $this->user_obj->where('account|email',$data['email'])->find();
//新增查询数据 chengxiaoling 20251020 start
if(!empty($user_info)){
$aWhere = ['reviewer_id' => $user_info['user_id']];
$user_reviewer_info = Db::name('user_reviewer_info')->field('technical,company as affiliation,website,field as research_areas')->where($aWhere)->find();
$user_info = empty($user_reviewer_info) ? $user_info : array_merge($user_info,$user_reviewer_info);
}
//新增查询数据 chengxiaoling 20251020 end
$re['user_info'] = $user_info;
return jsonSuccess($re);
}

View File

@@ -47,33 +47,6 @@ class Preaccept extends Base
return jsonSuccess($re);
}
public function spiltContent(){
$data = $this->request->post();
$rule = new Validate([
"content"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
$text = $data['content'];
$text = preg_replace('/(\d+)([a-zA-Z%℃°]+)/', '$1 $2', $text);
$text = preg_replace('/\s*%\s*/', '%', $text);
$pattern_en_dash = '/(\d+)(\d+)/';
$text = preg_replace($pattern_en_dash, '$1-$2', $text);
$pattern_em_dash = '/(\d+)—(\d+)/';
$text = preg_replace($pattern_em_dash, '$1-$2', $text);
}
/**清空引用文献
* @return \think\response\Json
* @throws \think\Exception
@@ -1503,5 +1476,97 @@ return null;
}
}
public function getArticleMainsNew(){
$data = $this->request->post();
$rule = new Validate([
"article_id"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
}
//定义空数组
$re = ['list' => []];
//获取数量
$aWhere = ['article_id' => $data['article_id'],'state' => ['in',[0,2]]];
$iCount = $this->article_main_obj->where($aWhere)->count();
if(empty($iCount)){
$this->addArticleMainEx($data['article_id']);
}
//获取数据
$aArticleMain = Db::name("article_main")->where($aWhere)->order("sort asc")->select();
if(empty($aArticleMain)){
return null;
}
//处理数据
$iSize = 300;
$aChunk = array_chunk($aArticleMain, $iSize);
$mains = [];
foreach ($aChunk as $item) {
$aMId = array_column($item, 'am_id');
//查询article_main_check
$aWhere = ['am_id' => ['in',$aMId],'state' => 0];
$aMainCheck = Db::name("article_main_check")->where($aWhere)->select();
$aMainCheckData = [];
if(!empty($aMainCheck)){
foreach ($aMainCheck as $value) {
if(empty($value['am_id'])){
continue;
}
$aMainCheckData[$value['am_id']][] = $value;
}
}
//获取图片信息
$aMiId = array_unique(array_column($item, 'ami_id'));
$aWhere = ['ami_id' => ['in',$aMiId],'state' => 0];
$aArticleMainImage = Db::name("article_main_image")->where($aWhere)->select();
$aArticleMainImage = empty($aArticleMainImage) ? [] : array_column($aArticleMainImage, null,'ami_id');
//获取表格信息
$aMiId = array_unique(array_column($item, 'amt_id'));
$aWhere = ['amt_id' => ['in',$aMiId],'state' => 0];
$aArticleMainTable = Db::name("article_main_table")->where($aWhere)->select();
$aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
//查询校对数量 t_article_proofread
$aWhere = ['am_id' => ['in',$aMId],'state' => ['between',[1,2]],'is_delete' => 2];
$aArticleProofread = Db::name("article_proofread")->field('am_id,count(id) as num,state')->where($aWhere)->group('am_id,state')->select();
$aArticleProofreadData = [];
if(!empty($aArticleProofread)){
foreach ($aArticleProofread as $key => $value) {
$aArticleProofreadData[$value['am_id']][$value['state']] = $value['num'];
}
}
foreach ($item as $k => $main) {
if($main['is_h1']==1){
$main['content'] = "<b><i>".$main['content']."</i></b>";
}
if($main['is_h2']==1||$main['is_h3']==1){
$main['content'] = "<b>".$main['content']."</b>";
}
$main['checks'] = empty($aMainCheckData[$main['am_id']]) ? [] : $aMainCheckData[$main['am_id']];
if($main['type'] == 1){
$main['image'] = empty($aArticleMainImage[$main['ami_id']]) ? [] : $aArticleMainImage[$main['ami_id']];
}
if($main['type'] == 2){
$main['table'] = empty($aArticleMainTable[$main['amt_id']]) ? [] : $aArticleMainTable[$main['amt_id']];
}
if($main['type'] == 0){
$aDataInfo = empty($aArticleProofreadData[$main['am_id']]) ? [] : $aArticleProofreadData[$main['am_id']];
$main['proof_read_num'] = -1;
if(!empty($aDataInfo)){
$main['proof_read_num'] = empty($aDataInfo[2]) ? 0 : $aDataInfo[2];
}
}
$mains[] = $main;
}
}
$re['list'] = $mains;
return jsonSuccess($re);
}
}

View File

@@ -24,8 +24,6 @@ class Proofread extends Base
if(empty($iArticleId)){
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
}
//行号
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
//查询文章
$aWhere = ['article_id' => $iArticleId];
$oArticle = new Article;
@@ -34,12 +32,13 @@ class Proofread extends Base
if(empty($aArticle)){
return json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' ));
}
if($aArticle['state'] != 6){
if($aArticle['state'] != 6 && $aArticle['state'] != 5){
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
}
//查询是否进行过校对
$aProofReadWhere = ['article_id' => $iArticleId,'state' => 2];
$aProofReadWhere = ['article_id' => $iArticleId,'state' => 2,'is_delete' => 2];
if(!empty($iAmId)){
$aProofReadWhere['am_id'] = $iAmId;
}
@@ -47,15 +46,11 @@ class Proofread extends Base
if(!empty($iCount)){
return json_encode(array('status' => 5,'msg' => 'The article or paragraph has been proofread'));
}
//查询文章内容
$aWhere['type'] = 0;
$aWhere['content'] = ['<>',''];
$aWhere['state'] = 0;
if(!empty($iAmId)){
$aWhere['am_id'] = $iAmId;
}
$aArticleMain = Db::table('t_article_main')->field('am_id,content,type,is_h1,is_h2,is_h3,ami_id,amt_id')->where($aWhere)->select();
$aArticleMain = Db::table('t_article_main')->field('am_id,content,type,is_h1,is_h2,is_h3,is_proofread')->where($aWhere)->order('sort asc')->select();
if(empty($aArticleMain)){
return json_encode(array('status' => 5,'msg' => 'The content of the article is empty'));
}
@@ -64,11 +59,14 @@ class Proofread extends Base
$oHelperFunction = new \app\common\HelperFunction;
$oProofReadService = new \app\common\ProofReadService;
//数据处理
$aH = $aTable = [];
$aId = [];
foreach ($aArticleMain as $key => $value) {
if(empty($oHelperFunction->filterAllTags($value['content']))){
continue;
}
if($value['is_proofread'] == 2){
$aId[] = $value['am_id'];
}
$aResult = $oProofReadService->proofread($value['content']);
if(empty($aResult)){
continue;
@@ -77,6 +75,15 @@ class Proofread extends Base
$aError[] = $aResult;
}
if(empty($aError)){
//更新文章内容的校对时间及状态
$iCount = count($aId);
if($iCount > 0){
$aUpdateWhere = ['am_id' => ['in',$aId]];
$update_result = Db::name('article_main')->where($aUpdateWhere)->limit($iCount)->update(['is_proofread' => 1,'proofread_time' => time()]);
if($update_result === false){
return json_encode(array('status' => 6,'msg' => 'Failed to update paragraph proofreading status-'.$update_result));
}
}
return json_encode(array('status' => 1,'msg' => 'No errors found'));
}
//数据处理
@@ -89,21 +96,29 @@ class Proofread extends Base
$val['article_id'] = $iArticleId;
$val['proof_before'] = empty($value['proof_before']) ? '' : $value['proof_before'];
$val['proof_after'] = empty($value['proof_after']) ? '' : $value['proof_after'];
$val['create_time'] = time();
$aData[] = $val;
}
}
if(empty($aData)){
return json_encode(array('status' => 1,'msg' => 'Data processing failed'));
}
Db::startTrans();
//更新文章内容的校对时间及状态
$iCount = count($aId);
$update_result = true;
if($iCount > 0){
$aUpdateWhere = ['am_id' => ['in',$aId]];
$update_result = Db::name('article_main')->where($aUpdateWhere)->limit($iCount)->update(['is_proofread' => 1,'proofread_time' => time()]);
}
//插入
$result = Db::name('article_proofread')->insertAll($aData);
if(!$result){
return json_encode(array('status' => 6,'msg' => 'No errors found'));
if(!$result || $update_result === false){
return json_encode(array('status' => 6,'msg' => 'Data operation failed:insert-'.$result.';update-'.$update_result));
}
//查询参考文献
$aWhere = ['state' => ['in',[0,2]],'article_id' => $iArticleId];
return json_encode(['status' => 1,'msg' => 'success']);
Db::commit();
return json_encode(['status' => 1,'msg' => 'Proofreading successful']);
}
/**
* @title 获取每行校对记录
@@ -129,7 +144,7 @@ class Proofread extends Base
if(empty($aArticle)){
return json_encode(['status' => 3,'msg' => 'The query article does not exist']);
}
if($aArticle['state'] < 5 || $aArticle['state'] == 8){
if($aArticle['state'] != 6 && $aArticle['state'] != 5){
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
}
@@ -147,8 +162,8 @@ class Proofread extends Base
//查询校对内容
$aAmId = array_column($aArticleMain, 'am_id');
$aWhere = ['am_id' => ['in',$aAmId]];
$iState = empty($aParam['state']) ? 0 : $aParam['state'];
$aWhere = ['am_id' => ['in',$aAmId],'is_delete' => 2];
$iState = empty($aParam['state']) ? 0 : explode(',', $aParam['state']);
if(!empty($iState)){
$aWhere['state'] = ['in',$iState];
}
@@ -260,7 +275,7 @@ class Proofread extends Base
}
//判断校对记录
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'id' => $iId];
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'id' => $iId,'is_delete' => 2];
$aProofRead = Db::name('article_proofread')->where($aWhere)->find();
if(empty($aProofRead)){
@@ -316,6 +331,7 @@ class Proofread extends Base
}
Db::startTrans();
//更新原始内容
$result_main = true;
if(!empty($sUpdateContent)){
$aWhere = ['am_id' => $iAmId,'state' => 0,'type' => 0];
$aUpdate = ['content' => $sUpdateContent];
@@ -326,12 +342,20 @@ class Proofread extends Base
//数据库更新
$aWhere = ['id' => $iId];
$result_proofread= Db::name('article_proofread')->where($aWhere)->limit(1)->update($aUpdate);
if(!$result_proofread || !$result_main){
if($result_proofread === false || $result_main === false){
return json_encode(['status' => 7,'msg' => "Update failed"]);
}
Db::commit();
//查询未执行的数量
$aCount = json_decode($this->getCountByState(['article_id' => $iArticleId,'am_id' => $iAmId]),true);
$aCount = empty($aCount['data']) ? [] : $aCount['data'];
//返回结果
return json_encode(['status' => 1,'msg' => "Update successful",'data' => $sData]);
$aData = [];
$aData['sum_count'] = empty($aCount['sum_count']) ? 0 : $aCount['sum_count'];
$aData['am_id_count'] = empty($aCount['am_id_count']) ? 0 : $aCount['am_id_count'];
$aData['content'] = $sData;
return json_encode(['status' => 1,'msg' => "Update successful",'data' => $aData]);
}
/**
@@ -469,7 +493,7 @@ class Proofread extends Base
$iIsUpdateAll = empty($aParam['is_update_all']) ? 2 : $aParam['is_update_all'];
//查询内容是否存在
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'id' => $iId];
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'id' => $iId,'is_delete' => 2];
$aProofRead = Db::name('article_proofread')->field('verbatim_texts,revised_content,explanation,state')->where($aWhere)->find();
if(empty($aProofRead)){
return json_encode(['status' => 3,'msg' => 'Proofreading record is empty']);
@@ -500,4 +524,244 @@ class Proofread extends Base
//返回结果
return json_encode(['status' => 1,'msg' => "Update successful"]);
}
/**
* @title 根据状态统计数量
* @param article_id 文章ID
* @param am_id 行号
* @param state 状态1已执行2未执行3删除
*/
public function getCountByState($aParam = []){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//参数验证-文章ID
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
if(empty($iArticleId)){
return json_encode(['status' => 2,'msg' => 'Please select a article']);
}
//行号
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
//查询文章
$aWhere = ['article_id' => $iArticleId];
$aArticle = Db::name('article')->field('journal_id,state')->where($aWhere)->find();
if(empty($aArticle)){
return json_encode(['status' => 3,'msg' => 'The query article does not exist']);
}
if($aArticle['state'] != 6 && $aArticle['state'] != 5){
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
}
//查询校对内容
$aState = empty($aParam['state']) ? [1,2] : explode(',', $aParam['state']);
$aWhere['state'] = ['in',$aState];
$aWhere['is_delete'] = 2;
$aCount = Db::name('article_proofread')->field('am_id,count(id) as num,state')->where($aWhere)->group('am_id,state')->order('am_id')->select();
$aCountData = [];
$iCount = -1;
if(!empty($aCount)){
$iCount = 0;
foreach ($aCount as $key => $value) {
$aCountData[$value['am_id']][$value['state']] = $value['num'];
if($value['state'] == 2){
$iCount += $value['num'];
}
}
}
//总数量
$am_id_count = -1;
if(!empty($aCountData[$iAmId])){
$am_id_count = empty($aCountData[$iAmId][2]) ? 0 : $aCountData[$iAmId][2];
}
$is_proofread = -1;
//查询是否校对
$aWhere = ['state' => 0,'is_proofread' => 1];
if(!empty($iAmId)){
$aWhere['am_id'] = $iAmId;
}
$iProofCount = Db::name('article_main')->where($aWhere)->count();
$is_proofread = $iProofCount > 0 ? 1 : 2;
//总数量统计
if($iCount == -1 && $iProofCount > 0){
$iCount = 0;
}
if($am_id_count == -1 && $iProofCount > 0){
$am_id_count = 0;
}
return json_encode(['status' => 1,'msg' => 'success','data' => ['sum_count' => $iCount,'am_id_count' => $am_id_count,'is_proofread' => $is_proofread]]);
}
/**
* @title AI文章校对-行
* @param article_id 文章ID
*/
public function proofReadByLine(){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
if(empty($iArticleId)){
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
}
//行号
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
if(empty($iAmId)){
return json_encode(array('status' => 2,'msg' => 'Please select the rows that need to be proofread' ));
}
//查询文章
$aWhere = ['article_id' => $iArticleId];
$oArticle = new Article;
$aArticle = json_decode($oArticle->get($aWhere),true);
$aArticle = empty($aArticle['data']) ? [] : $aArticle['data'];
if(empty($aArticle)){
return json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' ));
}
if($aArticle['state'] != 6 && $aArticle['state'] != 5){
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
}
//查询文章内容
$aWhere['type'] = 0;
$aWhere['content'] = ['<>',''];
$aWhere['state'] = 0;
$aWhere['am_id'] = $iAmId;
$aArticleMain = Db::table('t_article_main')->field('am_id,content,type,is_h1,is_h2,is_h3,is_proofread')->where($aWhere)->find();
if(empty($aArticleMain['content'])){
return json_encode(array('status' => 5,'msg' => 'The content of the article is empty'));
}
//写入校对行队列
$sQueue = \think\Queue::push('app\api\job\ArticleProofReadLine@fire',$aParam,'ArticleProofReadLine');
return json_encode(array('status' => 1,'msg' => 'Proofreading in progress, check the results in one minute'));
}
/**
* @title AI文章校对-行队列
* @param article_id 文章ID
*/
public function proofReadLineQueue($aParam = []){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
if(empty($iArticleId)){
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
}
//行号
$iAmId = empty($aParam['am_id']) ? 0 : $aParam['am_id'];
if(empty($iAmId)){
return json_encode(array('status' => 2,'msg' => 'Please select the rows that need to be proofread' ));
}
//查询文章
$aWhere = ['article_id' => $iArticleId];
$oArticle = new Article;
$aArticle = json_decode($oArticle->get($aWhere),true);
$aArticle = empty($aArticle['data']) ? [] : $aArticle['data'];
if(empty($aArticle)){
return json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' ));
}
if($aArticle['state'] != 6 && $aArticle['state'] != 5){
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
}
//查询文章内容
$aWhere['type'] = 0;
$aWhere['content'] = ['<>',''];
$aWhere['state'] = 0;
$aWhere['am_id'] = $iAmId;
$aArticleMain = Db::table('t_article_main')->field('am_id,content,type,is_h1,is_h2,is_h3,is_proofread')->where($aWhere)->find();
if(empty($aArticleMain)){
return json_encode(array('status' => 5,'msg' => 'The content of the article is empty'));
}
//实例化公共方法
$oHelperFunction = new \app\common\HelperFunction;
$oProofReadService = new \app\common\ProofReadService;
//数据处理
if(empty($oHelperFunction->filterAllTags($aArticleMain['content']))){
return json_encode(array('status' => 6,'msg' => 'The proofreading content is empty'));
}
$aResult = $oProofReadService->proofread($aArticleMain['content']);
//数据处理
$aError = empty($aResult['errors']) ? [] : $aResult['errors'];
if(empty($aError)){
$aUpdateWhere = ['am_id' => $iAmId];
$update_result = Db::name('article_main')->where($aUpdateWhere)->limit(1)->update(['is_proofread' => 1,'proofread_time' => time()]);
if($update_result === false){
return json_encode(array('status' => 6,'msg' => 'Failed to update paragraph proofreading status-'.$update_result));
}
return json_encode(array('status' => 1,'msg' => 'No errors found'));
}
$aData = [];
foreach ($aError as $key => $value) {
$value['am_id'] = $iAmId;
$value['article_id'] = $iArticleId;
$value['proof_before'] = empty($aResult['proof_before']) ? '' : $aResult['proof_before'];
$value['proof_after'] = empty($aResult['proof_after']) ? '' : $aResult['proof_after'];
$value['create_time'] = time();
$aData[] = $value;
}
if(empty($aData)){
return json_encode(array('status' => 1,'msg' => 'Data processing failed'));
}
Db::startTrans();
$aUpdateWhere = ['am_id' => $iAmId];
$update_result = Db::name('article_main')->where($aUpdateWhere)->limit(1)->update(['is_proofread' => 1,'proofread_time' => time()]);
//更新之前未执行的数据
$aWhere = ['am_id' => $iAmId,'article_id' => $iArticleId,'is_delete' => 2,'state' => 2];
$result_update = Db::name('article_proofread')->where($aWhere)->update(['is_delete' => 1,'update_time' => time()]);
//插入
$result = Db::name('article_proofread')->insertAll($aData);
if(!$result || $result_update === false || $update_result === false){
return json_encode(array('status' => 6,'msg' => 'Data operation failed:insert-'.$result.';result_update-'.$result_update.';update_result-'.$update_result));
}
Db::commit();
return json_encode(['status' => 1,'msg' => 'Proofreading successful']);
}
/**
* @title AI文章校对-全文章
* @param article_id 文章ID
*/
public function proofReadByArticle(){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
if(empty($iArticleId)){
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
}
//查询文章
$aWhere = ['article_id' => $iArticleId];
$oArticle = new Article;
$aArticle = json_decode($oArticle->get($aWhere),true);
$aArticle = empty($aArticle['data']) ? [] : $aArticle['data'];
if(empty($aArticle)){
return json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' ));
}
if($aArticle['state'] != 6 && $aArticle['state'] != 5){
return json_encode(array('status' => 4,'msg' => 'The article has not entered the proofreading stage'));
}
//查询文章内容
$aWhere['type'] = 0;
$aWhere['content'] = ['<>',''];
$aWhere['state'] = 0;
$iCount = Db::table('t_article_main')->where($aWhere)->count();
if(empty($iCount)){
return json_encode(array('status' => 5,'msg' => 'The content of the article is empty'));
}
//查询是否进行过校对
$aProofReadWhere = ['article_id' => $iArticleId,'state' => 2,'is_delete' => 2];
$iCount = Db::name('article_proofread')->where($aProofReadWhere)->count();
if(!empty($iCount)){
return json_encode(array('status' => 6,'msg' => 'The article or paragraph has been proofread'));
}
//写入校对行队列
$sQueue = \think\Queue::push('app\api\job\ArticleProofReadedi@fire',$aParam,'ArticleProofReadedi');
return json_encode(array('status' => 1,'msg' => 'Proofreading in progress, check the results in one minute'));
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace app\api\job;
use think\queue\Job;
use app\common\QueueJob;
use app\common\QueueRedis;
use app\api\controller\Proofread;
class ArticleProofReadLine
{
private $oQueueJob;
private $QueueRedis;
private $completedExprie = 180;
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()}");
// 获取文章ID
$iArticleId = empty($data['article_id']) ? 0 : $data['article_id'];
if (empty($iArticleId)) {
$this->oQueueJob->log("无效的article_id删除任务");
$job->delete();
return;
}
// 获取文章行ID
$iAmId = empty($data['am_id']) ? 0 : $data['am_id'];
if (empty($iAmId)) {
$this->oQueueJob->log("无效的am_id删除任务");
$job->delete();
return;
}
try {
// 生成Redis键并尝试获取锁
$sClassName = get_class($this);
$sRedisKey = "queue_job:{$sClassName}:{$iArticleId}_{$iAmId}";
$sRedisValue = uniqid() . '_' . getmypid();
if (!$this->oQueueJob->acquireLock($sRedisKey, $sRedisValue, $job)) {
return; // 未获取到锁,已处理
}
//生成内容
$oProofRead = new Proofread;
$response = $oProofRead->proofReadLineQueue($data);
// 验证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}");
}
$sMsg = empty($aResult['msg']) ? 'success' : $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();
}
}
}

View File

@@ -187,14 +187,14 @@ class JournalArticle
//发送邮件
$memail = empty($aJournalInfo['email']) ? '' : $aJournalInfo['email'];
$mpassword = empty($aJournalInfo['epassword']) ? '' : $aJournalInfo['epassword'];
$aResult = sendEmail($email,$title,$from_name,$content,$memail,$mpassword);
$iStatus = empty($aResult['status']) ? 1 : $aResult['status'];
$iIsSuccess = 2;
$sMsg = empty($aResult['data']) ? '失败' : $aResult['data'];
if($iStatus == 1){
$iIsSuccess = 1;
$sMsg = '成功';
}
// $aResult = sendEmail($email,$title,$from_name,$content,$memail,$mpassword);
// $iStatus = empty($aResult['status']) ? 1 : $aResult['status'];
// $iIsSuccess = 2;
// $sMsg = empty($aResult['data']) ? '失败' : $aResult['data'];
// if($iStatus == 1){
// $iIsSuccess = 1;
// $sMsg = '成功';
// }
$aEmailParam = ['article_id' => $iArticleId,'article_author_id' =>$value['article_author_id'],'related_article_id' => $value['article_id'],'email' => $email,'content' => $content,'create_time' => time(),'journal_id' => $aJournalInfo['journal_id'],'journal_issn' => $aJournalInfo['issn'],'title' => $title,'from_name' => $from_name,'memail' => $memail,'mpassword' => $mpassword];
//邮件发送记录

File diff suppressed because it is too large Load Diff