diff --git a/application/api/controller/Article.php b/application/api/controller/Article.php
index 27037a8..7b4207a 100644
--- a/application/api/controller/Article.php
+++ b/application/api/controller/Article.php
@@ -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'] . ',
';
- $content .= 'Thank you for contacting our editor.
ID: ' . $article['accept_sn'] . '.
';
- $content .= ' Your manuscript: ' . $article['accept_sn'] . ' has received a new reply; please login https://submission.tmrjournals.com/login to check.
';
- $content .= 'Sincerely,
' . $article['title'];
- sendEmail($author['email'], $article['title'], $article['title'], $content, $article['email'], $article['epassword']);
+ // // 发邮件
+ // $content = 'Dear ' . $author['realname'] . ',
';
+ // $content .= 'Thank you for contacting our editor.
ID: ' . $article['accept_sn'] . '.
';
+ // $content .= ' Your manuscript: ' . $article['accept_sn'] . ' has received a new reply; please login https://submission.tmrjournals.com/login to check.
';
+ // $content .= 'Sincerely,
' . $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},
+
+ 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.
+ Please log in to your account to view the message and respond at your earliest convenience.
+
+ If you have any questions or encounter any issues accessing the submission system, please feel free to contact us.
+
+ Sincerely,
+ Editorial Office
+ {journal_title}
+ Subscribe to this journal
+ Email: {journal_email}
+ 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
}
}
diff --git a/application/api/controller/Board.php b/application/api/controller/Board.php
index 8736423..623ea30 100644
--- a/application/api/controller/Board.php
+++ b/application/api/controller/Board.php
@@ -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()]);
+ }
+ }
+ }
}
diff --git a/application/api/controller/Chief.php b/application/api/controller/Chief.php
index 983ad6c..368a54c 100644
--- a/application/api/controller/Chief.php
+++ b/application/api/controller/Chief.php
@@ -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);
}
diff --git a/application/api/controller/Preaccept.php b/application/api/controller/Preaccept.php
index ba66f5b..9f08e11 100644
--- a/application/api/controller/Preaccept.php
+++ b/application/api/controller/Preaccept.php
@@ -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());
+ }
-}
\ No newline at end of file
+ //定义空数组
+ $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'] = "".$main['content']."";
+ }
+ if($main['is_h2']==1||$main['is_h3']==1){
+ $main['content'] = "".$main['content']."";
+ }
+ $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);
+ }
+
+}
diff --git a/application/api/controller/Proofread.php b/application/api/controller/Proofread.php
index 7d55dcd..46e4aa3 100644
--- a/application/api/controller/Proofread.php
+++ b/application/api/controller/Proofread.php
@@ -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'));
+ }
}
diff --git a/application/api/job/ArticleProofReadLine.php b/application/api/job/ArticleProofReadLine.php
new file mode 100644
index 0000000..c2002a9
--- /dev/null
+++ b/application/api/job/ArticleProofReadLine.php
@@ -0,0 +1,85 @@
+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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/application/common/JournalArticle.php b/application/common/JournalArticle.php
index cd4e75f..febd9e6 100644
--- a/application/common/JournalArticle.php
+++ b/application/common/JournalArticle.php
@@ -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];
//邮件发送记录
diff --git a/application/common/ProofReadService.php b/application/common/ProofReadService.php
index 2a21ac3..2dcecf3 100644
--- a/application/common/ProofReadService.php
+++ b/application/common/ProofReadService.php
@@ -18,12 +18,12 @@ class ProofReadService
$correctedContent = $this->checkTextFormat($correctedContent);
//数字格式校对
$correctedContent = $this->checkNumberFormat($correctedContent);
+ //No. 123456的写法统一
+ $correctedContent = $this->checkNoFormatUniformity($correctedContent);
//毫升单位校对
$correctedContent = $this->checkMlUnit($correctedContent);
//显著性P斜体校对
$correctedContent = $this->checkPSignificance($correctedContent);
- //No. 123456的写法统一
- $correctedContent = $this->checkNoFormatUniformity($correctedContent);
//图表标题一律使用全称Figure 1, Table 1.不能写成Fig. 1, Tab 1.
$correctedContent = $this->checkFigureTableTitle($correctedContent);
//检测参考文献是否能打开
@@ -60,41 +60,19 @@ class ProofReadService
$excludeMarkers = []; // 存储 URL/DOI + /