Compare commits

..

18 Commits

Author SHA1 Message Date
wangjinlei
987197ea3c bib文件生成 2025-12-17 15:54:45 +08:00
wangjinlei
73bbc843a9 费用初始化bug 2025-12-10 14:27:33 +08:00
wangjinlei
691dbb98c1 Merge remote-tracking branch 'origin/master' 2025-12-10 10:07:52 +08:00
wangjinlei
0e935f828b phpinfo 2025-12-10 10:07:47 +08:00
chengxl
48d523eb8a 接口新增 2025-12-05 16:17:50 +08:00
chengxl
0361857cd7 接口新增 2025-12-05 15:08:56 +08:00
chengxl
fdae595baf 接口新增 2025-12-05 13:14:33 +08:00
chengxl
03b012c8c8 接口新增 2025-12-05 11:17:40 +08:00
chengxl
b944931568 接口修改 2025-12-04 17:42:36 +08:00
chengxl
1e2a08c410 定时任务时间修改 2025-12-04 16:43:47 +08:00
chengxl
f6391adcb0 定时任务时间修改 2025-12-04 15:20:18 +08:00
chengxl
c8d7923f49 新增接口 2025-12-04 10:47:02 +08:00
chengxl
90884273e0 测试问题修改 2025-12-02 15:20:51 +08:00
chengxl
5daf18608b 测试问题修改 2025-12-01 09:16:50 +08:00
chengxl
ab0ee4d6b4 接口调整 2025-11-28 13:15:47 +08:00
chengxl
2a5e011593 新增期卷号处理 2025-11-28 09:25:11 +08:00
chengxl
dbc697e57f 新增期卷号处理 2025-11-28 09:20:07 +08:00
chengxl
6604c82301 接口新增需求 2025-11-27 16:33:27 +08:00
6 changed files with 1731 additions and 551 deletions

View File

@@ -95,6 +95,7 @@ class Article extends Base
if ($data['name'] != '') { if ($data['name'] != '') {
$where['t_article.title'] = array('like', "%" . $data['name'] . "%"); $where['t_article.title'] = array('like', "%" . $data['name'] . "%");
} }
//分页查询数据 //分页查询数据
$limit_start = ($data['pageIndex'] - 1) * $data['pageSize']; $limit_start = ($data['pageIndex'] - 1) * $data['pageSize'];
$res = $this->article_obj->field('t_article.*,t_journal.title journalname') $res = $this->article_obj->field('t_article.*,t_journal.title journalname')
@@ -103,6 +104,7 @@ class Article extends Base
->order('article_id desc') ->order('article_id desc')
->limit($limit_start, $data['pageSize'])->select(); ->limit($limit_start, $data['pageSize'])->select();
$count = $this->article_obj->where($where)->count(); $count = $this->article_obj->where($where)->count();
foreach ($res as $key => $val) { foreach ($res as $key => $val) {
//查询建议转投详情 //查询建议转投详情
$transfer_info = $this->article_transfer_obj $transfer_info = $this->article_transfer_obj
@@ -499,7 +501,7 @@ class Article extends Base
$data = $this->request->post(); $data = $this->request->post();
//查询文章基础数据 //查询文章基础数据
$where['t_article.article_id'] = $data['articleId']; $where['t_article.article_id'] = $data['articleId'];
$article_res = $this->article_obj->field('t_article.*,t_journal.title journalname,t_user.account')->join(array(['t_journal', 't_journal.journal_id = t_article.journal_id', 'LEFT'], ['t_user', 't_user.user_id = t_article.user_id', 'LEFT']))->where($where)->find(); $article_res = $this->article_obj->field('t_article.*,t_journal.title journalname,t_user.account,t_user.email as user_email')->join(array(['t_journal', 't_journal.journal_id = t_article.journal_id', 'LEFT'], ['t_user', 't_user.user_id = t_article.user_id', 'LEFT']))->where($where)->find();
//查询文章状态跟踪信息 //查询文章状态跟踪信息
$article_msg = $this->article_msg_obj->where(['article_id' => $data['articleId']])->where('state', 0)->select(); $article_msg = $this->article_msg_obj->where(['article_id' => $data['articleId']])->where('state', 0)->select();
//查询审稿人审稿建议 //查询审稿人审稿建议
@@ -1581,20 +1583,18 @@ class Article extends Base
$this->sendEmailToReviewer($data['articleId'], $data['state']); $this->sendEmailToReviewer($data['articleId'], $data['state']);
} }
//为预接收的文章生成production实例 //为预接收的文章生成production实例,处理收费
if ($data['state'] == 6) { if ($data['state'] == 6) {
$this->addProductionEx($data['articleId']); $this->addProductionEx($data['articleId']);
$this->addArticleMainEx($data['articleId']); $this->addArticleMainEx($data['articleId']);
//处理缴费相关信息 //如果是免费的期刊文章,那么直接变成付款完成
if($journal_info['fee']==0){ if ($journal_info['fee'] == 0 || $article_info['ctime'] < 1735660800) {
$this->article_obj->where("article_id", $article_info['article_id'])->update(["is_buy" => 1]); $this->article_obj->where("article_id", $article_info['article_id'])->update(["is_buy" => 1]);
}else{ }else{//如果期刊收费,那么文章费用初始化
$this->article_obj->where("article_id", $article_info['article_id'])->update(["fee" => $journal_info['fee']]); $this->article_obj->where("article_id", $article_info['article_id'])->update(["fee" => $journal_info['fee']]);
} }
// if ($journal_info['fee'] == 0 || $article_info['ctime'] < 1735660800) {
// $this->article_obj->where("article_id", $article_info['article_id'])->update(["is_buy" => 1]);
// }
} }
} }
@@ -4659,6 +4659,10 @@ class Article extends Base
} }
} }
public function phpIn(){
phpinfo();
}
public function up_approval_file() public function up_approval_file()
{ {
$file = request()->file('articleApproval'); $file = request()->file('articleApproval');

View File

@@ -2,9 +2,11 @@
namespace app\api\controller; namespace app\api\controller;
use think\Controller; use think\Controller;
use think\Db; use think\Db;
use app\common\Reviewer;
class Crontask extends Controller class Crontask extends Controller
{ {
protected $iChunkSize = 500;
/** /**
* 批量处理审稿人审稿质量 * 批量处理审稿人审稿质量
* @return void * @return void
@@ -144,7 +146,8 @@ class Crontask extends Controller
//获取该文章审核人的信息 //获取该文章审核人的信息
$aWhere = [ $aWhere = [
'ctime'=>['>',$sDate], 'ctime'=>['>',$sDate],
'state'=>['in',[1,2,3]] // 'state'=>['in',[1,2,3]]
'state' => ['BETWEEN',[1,3]]
]; ];
$aReviewer = Db::name('article_reviewer')->field('reviewer_id,count(article_id) as review_num ')->where($aWhere)->order('reviewer_id asc')->group('reviewer_id')->select(); $aReviewer = Db::name('article_reviewer')->field('reviewer_id,count(article_id) as review_num ')->where($aWhere)->order('reviewer_id asc')->group('reviewer_id')->select();
@@ -159,8 +162,10 @@ class Crontask extends Controller
exit; exit;
} }
$aUser = empty($aUser) ? [] : array_column($aUser, null,'user_id'); $aUser = empty($aUser) ? [] : array_column($aUser, null,'user_id');
//分片处理数量
$iChunkSize = 200;
if(!empty($aReviewer)){ if(!empty($aReviewer)){
$aChunk = array_chunk($aReviewer, 100); $aChunk = array_chunk($aReviewer, $iChunkSize);
Db::startTrans(); Db::startTrans();
foreach ($aChunk as $key => $item) { //数据分片操作 foreach ($aChunk as $key => $item) { //数据分片操作
//需要更新的用户ID //需要更新的用户ID
@@ -174,8 +179,7 @@ class Crontask extends Controller
//拼接更新语句 //拼接更新语句
if(empty($aUser[$iUserId])){ if(empty($aUser[$iUserId])){
//更新数量 //更新数量
$aCase['review_num'] .= "WHEN {$iUserId} THEN "; $aCase['review_num'] .= "WHEN {$iUserId} THEN '{$value['review_num']}' ";
$aCase['review_num'] .= "'{$value['review_num']}' ";
$aUpdateId[] = $iUserId; $aUpdateId[] = $iUserId;
continue; continue;
} }
@@ -185,8 +189,7 @@ class Crontask extends Controller
continue; continue;
} }
//审核数量有,变化更新数量 //审核数量有,变化更新数量
$aCase['review_num'] .= "WHEN {$iUserId} THEN "; $aCase['review_num'] .= "WHEN {$iUserId} THEN '{$value['review_num']}' ";
$aCase['review_num'] .= "'{$value['review_num']}' ";
$aUpdateId[] = $iUserId; $aUpdateId[] = $iUserId;
unset($aUser[$iUserId]); unset($aUser[$iUserId]);
} }
@@ -198,6 +201,7 @@ class Crontask extends Controller
} }
$result = Db::name('user') $result = Db::name('user')
->where(['user_id' => ['in',$aUpdateId]]) ->where(['user_id' => ['in',$aUpdateId]])
->limit(count($aUpdateId))
->update([ ->update([
'review_num' => Db::raw($aCase['review_num']), 'review_num' => Db::raw($aCase['review_num']),
]); ]);
@@ -210,14 +214,14 @@ class Crontask extends Controller
Db::commit(); Db::commit();
} }
if(!empty($aUser)){ if(!empty($aUser)){
$aChunk = array_chunk($aUser, 100); $aChunk = array_chunk($aUser, $iChunkSize);
Db::startTrans(); Db::startTrans();
foreach ($aChunk as $key => $item) { //数据分片操作 foreach ($aChunk as $key => $item) { //数据分片操作
$aUserId = array_column($item, 'user_id'); $aUserId = array_column($item, 'user_id');
if(empty($aUserId)){ if(empty($aUserId)){
continue; continue;
} }
$result = Db::name('user')->where(['is_reviewer' => 1,'user_id' => ['in',$aUserId]]) $result = Db::name('user')->where(['user_id' => ['in',$aUserId]])
->limit(count($aUserId)) ->limit(count($aUserId))
->update([ ->update([
'review_num' => 0, 'review_num' => 0,
@@ -235,11 +239,11 @@ class Crontask extends Controller
} }
/** /**
* @title 审稿人拒绝审稿[超过日默认自动拒绝审稿] * @title 审稿人拒绝审稿[超过5日默认自动拒绝审稿]
* *
*/ */
public function refuseReviewArticle(){ public function refuseReviewArticle(){
$sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-7 day'))); $sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-5 day')));
//获取该文章审核人的信息 //获取该文章审核人的信息
$aWhere = [ $aWhere = [
'ctime'=>['<',$sDate], 'ctime'=>['<',$sDate],
@@ -252,11 +256,14 @@ class Crontask extends Controller
$this->showMessage('未查询到需要超过七日的稿件',2); $this->showMessage('未查询到需要超过七日的稿件',2);
exit; exit;
} }
//分片处理数量
$iChunkSize = $this->iChunkSize;
//扣减分值
$iScore = 3;
//更新审稿人未审稿的数量
$aChunkReviewerNum = array_chunk($aReviewerNum, $iChunkSize);
//更新超过七日未审核的数据 //更新超过七日未审核的数据
Db::startTrans(); Db::startTrans();
//更新审稿人未审稿的数量
$aChunkReviewerNum = array_chunk($aReviewerNum, 500);
foreach ($aChunkReviewerNum as $key => $value) { foreach ($aChunkReviewerNum as $key => $value) {
$aId = array_column($value, 'reviewer_id'); $aId = array_column($value, 'reviewer_id');
if(empty($aId)){ if(empty($aId)){
@@ -270,26 +277,38 @@ class Crontask extends Controller
}else{ }else{
$this->showMessage('更新审稿人审稿状态成功['.$key.']执行SQL条数:'.$iResult."\n",1); $this->showMessage('更新审稿人审稿状态成功['.$key.']执行SQL条数:'.$iResult."\n",1);
} }
$aCase = $aUpdateId = []; $aUpdateId = [];
$sRdNum = ''; $aCase = ['rd_num' => '','review_score' => ''];
foreach ($value as $key => $item) { foreach ($value as $key => $item) {
if($item['reviewer_id'] <=0){ if($item['reviewer_id'] <=0){
continue; continue;
} }
//审核数量有,变化更新数量 //审核数量有,变化更新数量
$sRdNum .= "WHEN {$item['reviewer_id']} THEN "; $aCase['rd_num'] .= "WHEN {$item['reviewer_id']} THEN ";
$sRdNum .= Db::raw("rd_num + {$item['num']}")." "; $aCase['rd_num'] .= Db::raw("rd_num + {$item['num']}")." ";
//扣减分数
$aCase['review_score'] .= "WHEN {$item['reviewer_id']} THEN ";
$aCase['review_score'] .= Db::raw("review_score - {$iScore}")." ";
$aUpdateId[] = $item['reviewer_id']; $aUpdateId[] = $item['reviewer_id'];
} }
//SQL拼接最后结尾 //更新数据库
$aCase['rd_num'] ='CASE user_id '.$sRdNum.'END'; foreach ($aCase as $kk => $value) {
if(empty($value)){
continue;
}
$aUpdateCase[$kk] = Db::raw('CASE user_id '.$value.'END');
}
if(empty($aUpdateCase) || empty($aId)){
$this->showMessage('未查询到满足要求的审稿人数据['.$key.']'."\n",2);
continue;
}
//执行更新 //执行更新
$result = Db::name('user') $result = Db::name('user')
->where(['user_id' => ['in',$aUpdateId]]) ->where(['user_id' => ['in',$aUpdateId]])
->limit(count($aUpdateId)) ->limit(count($aUpdateId))
->update([ ->update($aUpdateCase);
'rd_num' => Db::raw($aCase['rd_num']),
]);
if ($result === false) { if ($result === false) {
$this->showMessage('更新用户拒绝审稿数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); $this->showMessage('更新用户拒绝审稿数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2);
}else{ }else{
@@ -333,8 +352,7 @@ class Crontask extends Controller
continue; continue;
} }
//审核数量有,变化更新数量 //审核数量有,变化更新数量
$sRdNum .= "WHEN {$item['reviewer_id']} THEN "; $sRdNum .= "WHEN {$item['reviewer_id']} THEN {$item['num']} ";
$sRdNum .= "{$item['num']} ";
$aUpdateId[] = $item['reviewer_id']; $aUpdateId[] = $item['reviewer_id'];
} }
//SQL拼接最后结尾 //SQL拼接最后结尾
@@ -360,7 +378,7 @@ class Crontask extends Controller
/** /**
* 批量处理审稿人活跃度[近两年] * 批量处理审稿人活跃度/同意审稿数量[近两年]
* *
* @return void * @return void
*/ */
@@ -368,64 +386,98 @@ class Crontask extends Controller
$sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-2 year'))); $sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-2 year')));
//获取该文章审核人的信息 //获取该文章审核人的信息
$aWhere = [ $aWhere = [
'ctime'=>['>',$sDate], 'ctime' => ['>',$sDate],
'state'=>['in',[1,2,3]] 'state' => ['BETWEEN',[0,5]]
]; ];
$aReviewer = Db::name('article_reviewer')->field('reviewer_id,count(article_id) as review_num_two_year')->where($aWhere)->order('reviewer_id asc')->group('reviewer_id')->select(); $aReviewer = Db::name('article_reviewer')->field('reviewer_id,SUM(state IN (0,1,2,3)) AS review_agree_num,SUM(state IN (1,2,3)) AS review_activity_num,SUM(state = 4) AS review_refuse_num,SUM(state IN (0,1,2,3,4,5)) AS review_invite_num')->where($aWhere)->order('reviewer_id asc')->group('reviewer_id')->select();
//查询审稿人数量不为0的审稿信息 //查询审稿人数量不为0的审稿信息
$aUserWhere = [ $aUser = Db::name('user')->field('user_id,review_activity_num,review_agree_num,review_refuse_num,review_invite_num')->where('review_invite_num','>',0)->select();
// 'is_reviewer' => 1,
'review_num_two_year' => ['>',0]
];
$aUser = Db::name('user')->field('user_id,review_num_two_year')->where($aUserWhere)->select();
if(empty($aReviewer) && empty($aUser)){ if(empty($aReviewer) && empty($aUser)){
$this->showMessage('未查询到待处理的审稿人数据【近两年】',2); $this->showMessage('未查询到待处理的审稿人数据【近两年】',2);
exit; exit;
} }
//处理数量
$iChunkSize = $this->iChunkSize;
$aUser = empty($aUser) ? [] : array_column($aUser, null,'user_id'); $aUser = empty($aUser) ? [] : array_column($aUser, null,'user_id');
//分片处理数据
if(!empty($aReviewer)){ if(!empty($aReviewer)){
$aChunk = array_chunk($aReviewer, 100); $aChunk = array_chunk($aReviewer, $iChunkSize);
Db::startTrans(); Db::startTrans();
foreach ($aChunk as $key => $item) { //数据分片操作 foreach ($aChunk as $key => $item) { //数据分片操作
//需要更新的用户ID //需要更新的用户ID
$aUpdateId = []; $aUpdateId = [];
//SQL拼接 //SQL拼接
$aCase['review_num_two_year'] = 'CASE user_id '; $aCase = ['review_activity_num' => [], 'review_agree_num' => [],'review_refuse_num' => [],'review_invite_num' => [],'review_agree_rate' => []];
foreach ($item as $key => $value) { foreach ($item as $key => $value) {
//用户ID //用户ID
$iUserId = $value['reviewer_id']; $iUserId = $value['reviewer_id'];
//活跃度
$review_activity_num = empty($value['review_activity_num']) ? 0 : $value['review_activity_num'];
//同意审稿数量
$review_agree_num = empty($value['review_agree_num']) ? 0 : $value['review_agree_num'];
//拒绝审稿数量
$review_refuse_num = empty($value['review_refuse_num']) ? 0 : $value['review_refuse_num'];
//邀请审稿数量
$review_invite_num = empty($value['review_invite_num']) ? 0 : $value['review_invite_num'];
//同意审稿占比
$review_agree_rate = empty($review_invite_num) ? 0 : round($review_agree_num/$review_invite_num,2);
//用户信息
$aUserInfo = empty($aUser[$iUserId]) ? [] : $aUser[$iUserId];
//拼接更新语句 //拼接更新语句
if(empty($aUser[$iUserId])){ if(empty($aUserInfo)){
//更新数量 //更新活跃度-审稿数量
$aCase['review_num_two_year'] .= "WHEN {$iUserId} THEN "; $aCase['review_activity_num'][]= "WHEN {$iUserId} THEN '{$review_activity_num}' ";
$aCase['review_num_two_year'] .= "'{$value['review_num_two_year']}' "; //更新同意审稿数量
$aCase['review_agree_num'][] = "WHEN {$iUserId} THEN '{$review_agree_num}' ";
//更新拒绝审稿数量
$aCase['review_refuse_num'][] = "WHEN {$iUserId} THEN '{$review_refuse_num}' ";
//更新邀请审稿数量
$aCase['review_invite_num'][] = "WHEN {$iUserId} THEN '{$review_invite_num}' ";
//同意审稿占比
$aCase['review_agree_rate'][] = "WHEN {$iUserId} THEN '{$review_agree_rate}' ";
$aUpdateId[] = $iUserId; $aUpdateId[] = $iUserId;
continue; continue;
} }
//审核数量无变化,跳过更新 //数量无变化,跳过更新
if($aUser[$iUserId]['review_num_two_year'] == $value['review_num_two_year']){ if($aUserInfo['review_activity_num'] == $value['review_activity_num'] && $aUserInfo['review_agree_num'] == $value['review_agree_num'] && $aUserInfo['review_refuse_num'] == $value['review_refuse_num'] && $aUserInfo['review_invite_num'] == $value['review_invite_num']){
unset($aUser[$iUserId]); unset($aUser[$iUserId]);
continue; continue;
} }
//审核数量有,变化更新数量
$aCase['review_num_two_year'] .= "WHEN {$iUserId} THEN "; //更新活跃度-审稿数量
$aCase['review_num_two_year'] .= "'{$value['review_num_two_year']}' "; $aCase['review_activity_num'][] = "WHEN {$iUserId} THEN '{$review_activity_num}' ";
//更新同意审稿数量
$aCase['review_agree_num'][] = "WHEN {$iUserId} THEN '{$review_agree_num}' ";
//更新拒绝审稿数量
$aCase['review_refuse_num'][] = "WHEN {$iUserId} THEN '{$review_refuse_num}' ";
//更新邀请审稿数量
$aCase['review_invite_num'][] = "WHEN {$iUserId} THEN '{$review_invite_num}' ";
//同意审稿占比
$aCase['review_agree_rate'][] = "WHEN {$iUserId} THEN '{$review_agree_rate}' ";
$aUpdateId[] = $iUserId; $aUpdateId[] = $iUserId;
unset($aUser[$iUserId]); unset($aUser[$iUserId]);
} }
//SQL拼接最后结尾 //更新数据库
$aCase['review_num_two_year'] .= 'END'; foreach ($aCase as $kk => $value) {
//执行更新 if(empty($value)){
if(empty($aUpdateId)){ continue;
}
$sWhere = implode(" ", $value);
$aUpdateCase[$kk] = Db::raw('CASE user_id '.$sWhere.'END');
}
if(empty($aUpdateCase) || empty($aUpdateId)){
$this->showMessage('未查询到满足要求的审稿人数据['.$key.']'."\n",2);
continue; continue;
} }
$result = Db::name('user') //更新数据
->where(['user_id' => ['in',$aUpdateId]]) $result = Db::name('user')
->update([ ->where(['user_id' => ['in',$aUpdateId]])
'review_num_two_year' => Db::raw($aCase['review_num_two_year']), ->update($aUpdateCase);
]);
if ($result === false) { if ($result === false) {
$this->showMessage('更新近两年审稿人审核数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); $this->showMessage('更新近两年审稿人审核数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2);
}else{ }else{
@@ -435,7 +487,7 @@ class Crontask extends Controller
Db::commit(); Db::commit();
} }
if(!empty($aUser)){ if(!empty($aUser)){
$aChunk = array_chunk($aUser, 100); $aChunk = array_chunk($aUser, $iChunkSize);
Db::startTrans(); Db::startTrans();
foreach ($aChunk as $key => $item) { //数据分片操作 foreach ($aChunk as $key => $item) { //数据分片操作
$aUserId = array_column($item, 'user_id'); $aUserId = array_column($item, 'user_id');
@@ -445,7 +497,11 @@ class Crontask extends Controller
$result = Db::name('user')->where(['user_id' => ['in',$aUserId]]) $result = Db::name('user')->where(['user_id' => ['in',$aUserId]])
->limit(count($aUserId)) ->limit(count($aUserId))
->update([ ->update([
'review_num' => 0, 'review_activity_num' => 0,
'review_agree_num' => 0,
'review_refuse_num' => 0,
'review_refuse_num' => 0,
'review_agree_rate' => 0,
]); ]);
if ($result === false) { if ($result === false) {
$this->showMessage('清空近两年审稿人审核数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); $this->showMessage('清空近两年审稿人审核数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2);
@@ -458,13 +514,44 @@ class Crontask extends Controller
} }
$this->showMessage('批量更新近两年审稿人审核数量成功'."\n",1); $this->showMessage('批量更新近两年审稿人审核数量成功'."\n",1);
} }
/**
* 批量处理待审核的文章自动推荐审稿人
*
* @return void
*/
public function recommendedReviewer(){
$this->showMessage('批量处理待审核的文章自动推荐审稿人成功'."\n",1);
exit;
//查询条件
$aWhere = ['state' => 2];
$aWhere['user_id'] = 54;
$aArticle = Db::name('article')->field('article_id,accept_sn')->where($aWhere)->limit(1)->select();
if(empty($aArticle)){
$this->showMessage('未查询到需要处理的待审核的文章',2);
exit;
}
//数据处理
foreach ($aArticle as $key => $value) {
$iArticleId = empty($value['article_id']) ? 0 : $value['article_id'];
if(empty($iArticleId)){
continue;
}
$sQueueId = \think\Queue::push('app\api\job\RecommendReviewer@fire',['article_id' =>$iArticleId], 'RecommendReviewer');
if($sQueueId === false){
$this->showMessage('文章入队失败,文章ID:'.$value['article_id'].'['.$value['accept_sn']."]\n",2);
continue;
}
}
$this->showMessage('批量处理待审核的文章自动推荐审稿人成功'."\n",1);
}
/** /**
* *
* 格式化信息输出 * 格式化信息输出
* *
* @access public * @access public
* @return void * @return void
* @author huangpu
* @date 2018.09.28 * @date 2018.09.28
* @param $[message] [<显示信息>] * @param $[message] [<显示信息>]
* @param $[status] [<输出信息1成功2失败>] * @param $[status] [<输出信息1成功2失败>]
@@ -477,4 +564,6 @@ class Crontask extends Controller
} }
echo date("Y-m-d H:i:s") . " " . $message . "\n"; echo date("Y-m-d H:i:s") . " " . $message . "\n";
} }
} }

View File

@@ -1939,7 +1939,11 @@ class Production extends Base
if ($v['refer_doi'] == '') { if ($v['refer_doi'] == '') {
$this->production_article_refer_obj->where('p_refer_id', $v['p_refer_id'])->update(['refer_frag' => $v['refer_content']]); $this->production_article_refer_obj->where('p_refer_id', $v['p_refer_id'])->update(['refer_frag' => $v['refer_content']]);
} else { } else {
Queue::push('app\api\job\ts@fire1', $v, 'ts');
//修改队列兼容对接OPENAI接口 chengxiaoling 20251128 start
// Queue::push('app\api\job\ts@fire1', $v, 'ts');
Queue::push('app\api\job\ArticleReferDetailQueue@fire', $v, 'ArticleReferDetailQueue');
//修改队列兼容对接OPENAI接口 chengxiaoling 20251128 end
} }
} }
return jsonSuccess([]); return jsonSuccess([]);
@@ -2011,6 +2015,397 @@ class Production extends Base
} }
public function mytestbib(){
$data = $this->request->post();
$rule = new Validate([
"article_id"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
$file = $this->generateBibFile($data['article_id']);
return jsonSuccess(['file'=>$file]);
}
/**
* 生成指定文章的 BibTeX 文件
* @param int $p_article_id 生产文章ID
* @param string $outputPath 输出文件路径(可选)
* @return string 生成的文件路径
*/
public function generateBibFile($article_id, $outputPath = null)
{
$production_article_obj = $this->production_article_obj->where("article_id",$article_id)->find();
if($production_article_obj==null){
$this->addProductionEx($article_id);
$production_article_obj = $this->production_article_obj->where("article_id",$article_id)->find();
}
if (!$outputPath) {
$outputPath = ROOT_PATH . 'public' . DS . 'latex' . DS . 'tex_'.$article_id . DS .'references_' . $article_id . '.bib';
}
$dir = dirname($outputPath);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$bibContent = $this->generateBibContent($production_article_obj['p_article_id']);
file_put_contents($outputPath, $bibContent);
return $outputPath;
}
/**
* 获取参考文献数据
* @param int $p_article_id 生产文章ID
* @return array 参考文献数组
*/
private function getReferences($p_article_id)
{
return $this->production_article_refer_obj->where("p_article_id",$p_article_id)->where("state",0)->select();
// $sql = "SELECT * FROM t_production_article_refer
// WHERE p_article_id = :p_article_id
// AND state = 0
// ORDER BY `index`";
//
// $stmt = $this->db->prepare($sql);
// $stmt->bindParam(':p_article_id', $p_article_id, PDO::PARAM_INT);
// $stmt->execute();
//
// return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 生成 BibTeX 内容
* @param array $references 参考文献数据
* @param int $p_article_id 文章ID
* @return string BibTeX 内容
*/
private function generateBibContent( $p_article_id)
{
$content = "% BibTeX file generated for article ID: {$p_article_id}\n";
$content .= "% Generated on " . date('Y-m-d H:i:s') . "\n\n";
$references = $this->production_article_refer_obj->where("p_article_id",$p_article_id)->where("state",0)->select();
foreach ($references as $ref) {
$entry = $this->generateBibEntry($ref);
if ($entry) {
$content .= $entry . "\n\n";
}
}
return $content;
}
/**
* 生成单个 BibTeX 条目
* @param array $ref 参考文献数据
* @return string|null BibTeX 条目或 null
*/
private function generateBibEntry($ref)
{
// 使用 DOI 或索引作为 citation key
$citationKey = $this->generateCitationKey($ref);
// 如果有解析后的作者和标题信息,优先使用
if (!empty($ref['author']) && !empty($ref['title'])) {
return $this->generateFromParsedData($ref, $citationKey);
}
// 否则尝试从原始内容解析
else {
return ;
// return $this->generateFromRawContent($ref, $citationKey);
}
}
/**
* 生成 citation key
* @param array $ref 参考文献数据
* @return string citation key
*/
private function generateCitationKey($ref)
{
if (!empty($ref['refer_doi'])) {
// 使用 DOI 的部分作为 key
$parts = explode('/', $ref['refer_doi']);
if (count($parts) > 1) {
return str_replace('.', '_', end($parts));
}
}
// 默认使用索引
return 'ref_' . $ref['p_refer_id'];
}
private function parsePublicationInfo($referenceText)
{
$result = [
'year' => '',
'volume' => '',
'number' => '',
'pages' => ''
];
// 匹配模式year;volume(number):pages
$pattern = '/(\d{4})\s*;\s*(\d+)(?:\(([^)]+)\))?(?:\s*:\s*([a-zA-Z0-9\u2013\u2014\-]+(?:\s*[\u2013\u2014\-]\s*[a-zA-Z0-9]+)?))?/';
if (preg_match($pattern, $referenceText, $matches)) {
$result['year'] = isset($matches[1]) ? $matches[1] : '';
$result['volume'] = isset($matches[2]) ? $matches[2] : '';
// 期号可能是可选的
if (isset($matches[3]) && $matches[3] !== '') {
$result['number'] = $matches[3];
}
// 页码也是可选的
if (isset($matches[4]) && $matches[4] !== '') {
$result['pages'] = $matches[4];
}
} else {
// 如果标准模式不匹配,尝试更宽松的匹配方式
$result = self::parseLooseFormat($referenceText);
}
return $result;
}
private function parseLooseFormat($referenceText)
{
$result = [
'year' => '',
'volume' => '',
'number' => '',
'pages' => ''
];
// 提取年份4位数字
if (preg_match('/\b(\d{4})\b/', $referenceText, $yearMatches)) {
$result['year'] = $yearMatches[1];
}
// 提取卷号和期号(格式如 54(4) 或 54 (4)
if (preg_match('/(\d+)\s*\(?(\d*)\)?\s*:?\s*([a-zA-Z0-9\-]*)/', $referenceText, $volMatches)) {
if (isset($volMatches[1])) {
$result['volume'] = $volMatches[1];
}
if (isset($volMatches[2]) && $volMatches[2] !== '') {
$result['number'] = $volMatches[2];
}
if (isset($volMatches[3]) && $volMatches[3] !== '') {
$result['pages'] = $volMatches[3];
}
}
return $result;
}
/**
* 从解析后的数据生成 BibTeX 条目
* @param array $ref 参考文献数据
* @param string $citationKey citation key
* @return string BibTeX 条目
*/
private function generateFromParsedData($ref, $citationKey)
{
$entry = "@article{{$citationKey},\n";
// 添加已解析的字段
if (!empty($ref['author'])) {
$entry .= " author={" . $this->escapeBibTeX($this->formatBibTeXAuthors($ref['author'])) . "},\n";
}
if (!empty($ref['title'])) {
$entry .= " title={" . $this->escapeBibTeX($ref['title']) . "},\n";
}
if (!empty($ref['joura'])) {
$entry .= " journal={" . $this->escapeBibTeX($ref['joura']) . "},\n";
}
// 解析并添加出版信息
if (!empty($ref['dateno'])) {
$pubInfo = $this->parsePublicationInfo($ref['dateno']);
if (!empty($pubInfo['year'])) {
$entry .= " year={" . $this->escapeBibTeX($pubInfo['year']) . "},\n";
}
if (!empty($pubInfo['volume'])) {
$entry .= " volume={" . $this->escapeBibTeX($pubInfo['volume']) . "},\n";
}
if (!empty($pubInfo['number'])) {
$entry .= " number={" . $this->escapeBibTeX($pubInfo['number']) . "},\n";
}
if (!empty($pubInfo['pages'])) {
$entry .= " pages={" . $this->escapeBibTeX($pubInfo['pages']) . "},\n";
}
}
if (!empty($ref['refer_doi'])) {
$entry .= " doi={" . $this->escapeBibTeX($ref['refer_doi']) . "},\n";
}
// 移除最后一个逗号并关闭条目
$entry = rtrim($entry, ",\n") . "\n}";
return $entry;
}
/**
* 格式化作者信息为BibTeX格式
* @param string $authors 作者字符串,如 "Li Y, Yang C, Zhao H, Qu S, Li X, Li Y"
* @return string 格式化后的作者字符串,如 "Li, Y. and Yang, C. and Zhao, H. and Qu, S. and Li, X. and Li, Y."
*/
private function formatBibTeXAuthors($authors) {
$authors = rtrim($authors, ". \t\n\r\0\x0B");
// 如果包含"et al",则原样保留
if (stripos($authors, 'et al') !== false) {
return $authors;
}
// 按逗号分割各个作者
$authorArray = array_map('trim', explode(',', $authors));
$formattedAuthors = [];
foreach ($authorArray as $author) {
$author = trim($author);
if (empty($author)) {
continue;
}
// 按空格分割作者的各部分
$authorParts = explode(' ', $author);
if (count($authorParts) >= 2) {
// 最后一个是姓氏,前面的是名字首字母
$lastName = array_pop($authorParts);
$firstName = implode(' ', $authorParts);
$formattedAuthors[] = $firstName.", ".$lastName;
// $firstNameInitials = implode('. ', $authorParts) . '.';
// $formattedAuthors[] = $lastName . ', ' . $firstNameInitials;
} else {
// 如果只有一个部分,当作姓氏处理
$formattedAuthors[] = $author;
}
}
// 用 " and " 连接所有作者
return implode(' and ', $formattedAuthors);
}
/**
* 从原始内容生成 BibTeX 条目(简单处理)
* @param array $ref 参考文献数据
* @param string $citationKey citation key
* @return string BibTeX 条目
*/
private function generateFromRawContent($ref, $citationKey)
{
$entry = "@misc{{$citationKey},\n";
// 将整个参考文献内容作为 note 字段
if (!empty($ref['refer_content'])) {
$entry .= " note={" . $this->escapeBibTeX($ref['refer_content']) . "},\n";
}
if (!empty($ref['refer_doi'])) {
$entry .= " doi={" . $this->escapeBibTeX($ref['refer_doi']) . "},\n";
}
// 移除最后一个逗号并关闭条目
$entry = rtrim($entry, ",\n") . "\n}";
return $entry;
}
/**
* 转义 BibTeX 特殊字符
* @param string $text 文本内容
* @return string 转义后的内容
*/
private function escapeBibTeX($text)
{
// 转义大括号
$text = str_replace(['{', '}'], ['\\{', '\\}'], $text);
// 转义反斜杠
$text = str_replace('\\', '\\\\', $text);
return $text;
}
// 在 Production 控制器中添加以下方法:
// 在 Production.php 中添加以下方法:
/**
* 生成 BibTeX 文件
*/
public function generateBibtex()
{
$data = $this->request->post();
$rule = new Validate([
'p_article_id' => 'require|number'
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
try {
// 创建数据库连接
$db = Db::connect();
$generator = new ReferenceBibGenerator($db);
// 生成 BibTeX 文件
$filePath = $generator->generateBibFile($data['p_article_id']);
// 返回相对路径供前端使用
$relativePath = str_replace(ROOT_PATH . 'public' . DS, '', $filePath);
return jsonSuccess([
'file_path' => $relativePath,
'full_path' => $filePath
]);
} catch (Exception $e) {
return jsonError('生成 BibTeX 文件失败: ' . $e->getMessage());
}
}
/**
* 下载 BibTeX 文件
*/
public function downloadBibtex()
{
$p_article_id = $this->request->param('p_article_id', 0);
if (!$p_article_id) {
return jsonError('缺少参数');
}
$filePath = ROOT_PATH . 'public' . DS . 'bibtex' . DS . 'references_' . $p_article_id . '.bib';
if (!file_exists($filePath)) {
return jsonError('文件不存在');
}
// 设置下载头信息
header('Content-Type: application/x-bibtex');
header('Content-Disposition: attachment; filename="references_' . $p_article_id . '.bib"');
header('Content-Length: ' . filesize($filePath));
// 输出文件内容
readfile($filePath);
exit;
}
public function getFragBF() public function getFragBF()
{ {
$data = $this->request->post(); $data = $this->request->post();

View File

@@ -463,4 +463,425 @@ class Workbench extends Base
} }
return json_encode(['status' => 1,'msg' => 'success','data' => $aData]); return json_encode(['status' => 1,'msg' => 'success','data' => $aData]);
} }
/**
* 获取审稿权限
* @param art_rev_id 审稿记录ID
* @param
*/
public function getReviewerAuth(){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
$aData = ['is_review_auth' => 2];//审稿权限1是2否
//获取审稿记录ID
$iArtRevId = empty($aParam['art_rev_id']) ? 0 : $aParam['art_rev_id'];
if(empty($iArtRevId)){
return json_encode(['status' => 2,'msg' => 'Please select a record','data' => $aData]);
}
//获取账号
$sAccount = empty($aParam['account']) ? '' : $aParam['account'];
if(empty($sAccount)){
return json_encode(['status' => 2,'msg' => 'Please enter your account','data' => $aData]);
}
//查询用户是否存在
$aWhere = ['account' => $sAccount,'state' => 0];
$aUser = Db::name('user')->field('user_id,account,email')->where($aWhere)->find();
if(empty($aUser)){
return json_encode(['status' => 3,'msg' => 'Account does not exist','data' => $aData]);
}
$iUserId = $aUser['user_id'];
//查询审稿记录
$aWhere = ['art_rev_id' => $iArtRevId];
$aArticleReviewer = Db::name('article_reviewer')->where($aWhere)->find();
if(empty($aArticleReviewer)){
return json_encode(['status' => 4,'msg' => 'Review record does not exist','data' => $aData]);
}
$aData['review'] = $aArticleReviewer;
//获取文章信息
$aWhere = ['article_id' => $aArticleReviewer['article_id']];
$aArticle = Db::name('article')->field('article_id,abstrart,title article_title,type,accept_sn,journal_id,state')->where($aWhere)->find();
if(empty($aArticle)){
return json_encode(['status' => 5,'msg' => 'The article does not exist','data' => $aData]);
}
$aArticle['type_name'] = translateType($aArticle['type']);//文章类型
//查询期刊信息
$aWhere = ['journal_id' => $aArticle['article_id'],'state' => 0];
$aJournal = Db::name('journal')->field('title as journal_name,website,email as journal_email')->find();
if(!empty($aJournal)){
$aArticle += $aJournal;
}
//判断是否有权限审稿
$aData['article'] = $aArticle;
if($aArticleReviewer['reviewer_id'] != $iUserId){
return json_encode(['status' => 6,'msg' => 'No review permission','data' => $aData]);
}
//判断审稿权限
if($aArticle['state'] != 2){
return json_encode(['status' => 7,'msg' => 'The article has not entered the review status','data' => $aData]);
}
//审稿拒绝
if($aArticleReviewer['state'] == 2){
//获取审稿答卷
$aWhere = ['art_rev_id' => $iArtRevId,'state' => 0];
$aQuestion = Db::name('article_reviewer_question')->field('art_rev_id,recommend')->where($aWhere)->find();
if(empty($aQuestion)){
return json_encode(['status' => 8,'msg' => 'You have declined the review','data' => $aData]);
}
}
//审稿已过期
if($aArticleReviewer['state'] == 4){
return json_encode(['status' => 13,'msg' => 'The review has expired','data' => $aData]);
}
//同意/1小改后接收/接收
//判断是否为邮件
$iIsCode = 2;//是否邮件进入
$sAct = empty($aParam['act']) ? '' : $aParam['act'];
$aWhere = ['code' => $sAct,'state' => 0];
if(!empty($sAct)){
//查询绑定的用户ID
$aCode = Db::name('login_auto')->field('user_id')->where($aWhere)->find();
if(empty($aCode)){
return json_encode(['status' => 10,'msg' => 'Code is illegal','data' => $aData]);
}
if($aCode['user_id'] != $iUserId){
return json_encode(['status' => 11,'msg' => 'Illegal code operation','data' => $aData]);
}
$iIsCode = 1;
}
//当前时间
$iNowTime = time();
// 14天 = 14*24*3600 秒 = 1209600 秒
$iFourteenDays = 14 * 24 * 3600;
//五天
$iFiveDays = 5 * 24 * 3600;
//审稿邀请
if($aArticleReviewer['state'] == 5){
if($iIsCode == 1){//邮件进入未同意审稿直接同意
//添加时间
$iTime = empty($aArticleReviewer['ctime']) ? 0 : $aArticleReviewer['ctime'];
if (!is_numeric($iTime) || (int)$iTime <= 0) {
return json_encode([
'status' => 12,
'msg' => 'Invalid record time, the review period has expired',
'data' => $aData
]);
}
//判断是否超过5天
$timeDiff = $iTime+$iFiveDays;
if($timeDiff < $iNowTime){
//执行审稿过期
$aWhere = ['art_rev_id' => $iArtRevId,'state' => 5];
$result = Db::name('article_reviewer')->where($aWhere)->limit(1)->update(['state' => 4]);
return json_encode(['status' => 13,'msg' => 'The number of days for agreeing to review has exceeded 5','data' => $aData]);
}
// var_dump(date('Y-m-d H:i:s',$timeDiff),date('Y-m-d H:i:s',$iTime),date('Y-m-d H:i:s',$iNowTime));
//执行同意审稿
$aWhere = ['art_rev_id' => $iArtRevId,'state' => 5];
$result = Db::name('article_reviewer')->where($aWhere)->limit(1)->update(['state' => 0,'agree_review_time' => time()]);
}
if($iIsCode != 1){
return json_encode(['status' => 14,'msg' => 'Reviewer did not agree to review','data' => $aData]);
}
}
//同意审稿
if($aArticleReviewer['state'] == 0){
//同意审稿的时间
$iTime = empty($aArticleReviewer['agree_review_time']) ? 0 : $aArticleReviewer['agree_review_time'];
//添加时间
$iCtime = empty($aArticleReviewer['ctime']) ? 0 : $aArticleReviewer['ctime'];
$iTime = empty($iTime) ? intval($iCtime) : intval($iTime);
if (!is_numeric($iTime) || (int)$iTime <= 0) {
return json_encode([
'status' => 15,
'msg' => 'Invalid record time, the review period has expired',
'data' => $aData
]);
}
//判断是否超过14天
$timeDiff = $iTime+$iFourteenDays;
if($timeDiff < $iNowTime){
return json_encode(['status' => 16,'msg' => 'The number of days for agreeing to review has exceeded 14','data' => $aData]);
}
$aData['is_review_auth'] = 1;
return json_encode(['status' => 1,'msg' => 'success','data' => $aData]);
}
$aData['is_review_auth'] = 1;
return json_encode(['status' => 1,'msg' => 'success','data' => $aData]);
}
/**
* 审稿人邮件链接失效-重新申请邮件
*/
public function applySendEmail(){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//获取审稿记录ID
$iArtRevId = empty($aParam['art_rev_id']) ? 0 : $aParam['art_rev_id'];
if(empty($iArtRevId)){
return json_encode(['status' => 2,'msg' => 'Please select a record']);
}
//获取账号
$sAccount = empty($aParam['account']) ? '' : $aParam['account'];
if(empty($sAccount)){
return json_encode(['status' => 2,'msg' => 'Please enter your account']);
}
//查询用户是否存在
$aWhere = ['account' => $sAccount,'state' => 0];
$aUser = Db::name('user')->field('user_id')->where($aWhere)->find();
if(empty($aUser)){
return json_encode(['status' => 3,'msg' => 'Account does not exist']);
}
$iUserId = $aUser['user_id'];
//查询审稿记录
$aWhere = ['art_rev_id' => $iArtRevId];
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,article_id,state')->where($aWhere)->find();
if(empty($aArticleReviewer)){
return json_encode(['status' => 4,'msg' => 'Review record does not exist']);
}
if($aArticleReviewer['state'] != 4){
return json_encode(['status' => 5,'msg' => 'The review link has not expired and no application is required']);
}
//获取文章信息
$aWhere = ['article_id' => $aArticleReviewer['article_id']];
$aArticle = Db::name('article')->field('article_id,abstrart,title article_title,type,accept_sn,journal_id,state')->where($aWhere)->find();
if(empty($aArticle)){
return json_encode(['status' => 6,'msg' => 'The article does not exist']);
}
if($aArticle['state'] != 2){
return json_encode(['status' => 7,'msg' => 'The article is not in the review status']);
}
//查询期刊信息
$aWhere = ['journal_id' => $aArticle['article_id'],'state' => 0];
$aJournal = Db::name('journal')->field('title as journal_name,website')->find();
//查询期刊信息
if(empty($aArticle['journal_id'])){
return json_encode(array('status' => 8,'msg' => 'The article is not associated with a journal' ));
}
$aWhere = ['state' => 0,'journal_id' => $aArticle['journal_id']];
$aJournal = Db::name('journal')->where($aWhere)->find();
if(empty($aJournal)){
return json_encode(array('status' => 9,'msg' => 'No journal information found' ));
}
//查询编辑邮箱
$iUserId = empty($aJournal['editor_id']) ? 0 : $aJournal['editor_id'];
if(empty($iUserId)){
return json_encode(array('status' => 10,'msg' => 'The journal to which the article belongs has not designated a responsible editor' ));
}
//查询审稿人跟编辑的信息
$aUserId = [$aArticleReviewer['reviewer_id'],$iUserId];
$aWhere = ['user_id' => ['in',$aUserId],'state' => 0,'email' => ['<>','']];
$aUser = Db::name('user')->field('user_id,email,realname,account')->where($aWhere)->select();
if(empty($aUser)){
return json_encode(['status' => 11,'msg' => "Reviewer and editor information not found"]);
}
$aUser = array_column($aUser, null,'user_id');
//更新审稿人重新申请状态为
$aWhere = ['art_rev_id' => $iArtRevId,'state' => 4];
$result = Db::name('article_reviewer')->where($aWhere)->limit(1)->update(['is_reapply' => 1,'reapply_time' => time(),'reviewer_act' => 1]);
if($result === false){
return json_encode(array('status' => 11,'msg' => 'Application to reopen link failed' ));
}
//处理发邮件
//邮件模版
$aEmailConfig = [
'email_subject' => 'Request to Reopen Expired Review Link---{accept_sn}',
'email_content' => '
Dear Editor,<br><br>
The reviewer would like to reopen the expired review link for the manuscript. Below are the details:<br>
Reviewer Information:<br>
Real Name:{realname}<br>
Email:{email}<br><br>
Sincerely,<br>Editorial Office<br>
<a href="https://www.tmrjournals.com/draw_up.html?issn={journal_issn}">Subscribe to this journal</a><br>{journal_title}<br>
Email: {journal_email}<br>
Website: {website}'
];
//邮件内容
$aSearch = [
'{accept_sn}' => empty($aArticle['accept_sn']) ? '' : $aArticle['accept_sn'],//accept_sn
'{journal_title}' => empty($aJournal['title']) ? '' : $aJournal['title'],//期刊名
'{journal_issn}' => empty($aJournal['issn']) ? '' : $aJournal['issn'],
'{journal_email}' => empty($aJournal['email']) ? '' : $aJournal['email'],
'{website}' => empty($aJournal['website']) ? '' : $aJournal['website'],
'{realname}' => empty($aUser[$aArticleReviewer['reviewer_id']]['realname']) ? '' : $aUser[$aArticleReviewer['reviewer_id']]['realname'],
'{email}' => empty($aUser[$aArticleReviewer['reviewer_id']]['email']) ? '' : $aUser[$aArticleReviewer['reviewer_id']]['email'],
];
//发邮件
//邮箱
$email = empty($aUser[$iUserId]['email']) ? '' : $aUser[$iUserId]['email'];
if(empty($email)){
return json_encode(['status' => 8,'msg' => 'Edit email as empty']);
}
$title = str_replace(array_keys($aSearch), array_values($aSearch),$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;
//发送邮件
$memail = empty($aJournal['email']) ? '' : $aJournal['email'];
$mpassword = empty($aJournal['epassword']) ? '' : $aJournal['epassword'];
//期刊标题
$from_name = empty($aJournal['title']) ? '' : $aJournal['title'];
//邮件队列组装参数
$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){
return json_encode(['status' => 1,'msg' => 'success']);
}
return json_encode(['status' => 8,'msg' => 'fail']);
}
/**
* 编辑审稿人邮件链接失效-重开
*/
public function updateReviewerState(){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//获取审稿记录ID
$iArtRevId = empty($aParam['art_rev_id']) ? 0 : $aParam['art_rev_id'];
if(empty($iArtRevId)){
return json_encode(['status' => 2,'msg' => 'Please select a record']);
}
//获取账号
$sAccount = empty($aParam['account']) ? '' : $aParam['account'];
if(empty($sAccount)){
return json_encode(['status' => 2,'msg' => 'Please enter your account']);
}
//查询用户是否存在
$aWhere = ['account' => $sAccount,'state' => 0];
$aUser = Db::name('user')->field('user_id,account,email')->where($aWhere)->find();
if(empty($aUser)){
return json_encode(['status' => 3,'msg' => 'Account does not exist']);
}
$iUserId = $aUser['user_id'];
//查询审稿记录
$aWhere = ['art_rev_id' => $iArtRevId];
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,article_id,state')->where($aWhere)->find();
if(empty($aArticleReviewer)){
return json_encode(['status' => 4,'msg' => 'Review record does not exist']);
}
if($aArticleReviewer['state'] != 4){
return json_encode(['status' => 5,'msg' => 'The review link has not expired and no application is required']);
}
//获取文章信息
$aWhere = ['article_id' => $aArticleReviewer['article_id']];
$aArticle = Db::name('article')->field('article_id,abstrart,title,type,accept_sn,journal_id,state')->where($aWhere)->find();
if(empty($aArticle)){
return json_encode(['status' => 6,'msg' => 'The article does not exist']);
}
if($aArticle['state'] != 2){
return json_encode(['status' => 7,'msg' => 'The article is not in the review status']);
}
//查询期刊信息
$aWhere = ['journal_id' => $aArticle['article_id'],'state' => 0];
$aJournal = Db::name('journal')->field('title as journal_name,website')->find();
//查询期刊信息
if(empty($aArticle['journal_id'])){
return json_encode(array('status' => 8,'msg' => 'The article is not associated with a journal' ));
}
$aWhere = ['state' => 0,'journal_id' => $aArticle['journal_id']];
$aJournal = Db::name('journal')->where($aWhere)->find();
if(empty($aJournal)){
return json_encode(array('status' => 9,'msg' => 'No journal information found' ));
}
//判断编辑的操作权限
$iEditorId = empty($aJournal['editor_id']) ? 0 : $aJournal['editor_id'];
if($iEditorId != $iUserId){
return json_encode(array('status' => 10,'msg' => 'This article is not authorized for operation under the journal you are responsible for' ));
}
//更新文章状态为邀请
$aWhere = ['art_rev_id' => $iArtRevId,'state' => 4];
$result = Db::name('article_reviewer')->where($aWhere)->limit(1)->update(['state' => 5,'ctime' => time(),'editor_act' => 1,'is_reapply' => 2,'update_time' => time(),'reviewer_act' => 0]);
if($result === false){
return json_encode(array('status' => 11,'msg' => 'Status update failed' ));
}
//查询审稿人的邮箱
$aWhere = ['user_id' => $aArticleReviewer['reviewer_id'],'state' => 0,'email' => ['<>','']];
$aUser = Db::name('user')->field('user_id,email,realname,account')->where($aWhere)->find();
if(empty($aUser)){
return json_encode(['status' => 12,'msg' => "Reviewer and editor information not found"]);
}
//处理发邮件
//邮箱
$email = empty($aUser['email']) ? '' : $aUser['email'];
if(empty($email)){
return json_encode(['status' => 13,'msg' => 'Reviewer email as empty']);
}
//邮件模版
$aEmailConfig = [
'email_subject' => 'Invitation to review a manuscript for {journal_title}-[{accept_sn}]',
'email_content' => '
Dear Dr. {realname},<br><br>
The manuscript entitled "{article_title}" has been submitted to the journal {journal_title}.The Editor-in-Chief would be most grateful if you could offer an opinion regarding its suitability for publication in the journal {journal_title}. <br><br>
<b style="font-size: 14px;">Abstract of the Manuscript:</b><br>
<b style="font-size: 12px;">{abstrart}</b><br><br>
Please let us know if there are any potential conflicts of interest and click the following link to review the manuscript.<br>
<a href="{creatLoginUrlForreviewer}">Click here to accept the invitation to review</a><br>
Your username: {account}<br>
Your original password:123456qwe, if you have reset the password, please login with the new one or click the "<a href="https://submission.tmrjournals.com/retrieve">forgot password</a>".<br>
Thank you for your continued support of our journal.<br><br>
Sincerely,<br>Editorial Office<br>
<a href="https://www.tmrjournals.com/draw_up.html?issn={journal_issn}">Subscribe to this journal</a><br>{journal_title}<br>
Email: {journal_email}<br>
Website: {website}'
];
$aSearch = [
'{accept_sn}' => empty($aArticle['accept_sn']) ? '' : $aArticle['accept_sn'],//accept_sn
'{article_title}' => empty($aArticle['title']) ? '' : $aArticle['title'],//文章标题
'{abstrart}' => empty($aArticle['abstrart']) ? '' : $aArticle['abstrart'],//文章摘要
'{journal_title}' => empty($aJournal['title']) ? '' : $aJournal['title'],//期刊名
'{journal_issn}' => empty($aJournal['issn']) ? '' : $aJournal['issn'],
'{journal_email}' => empty($aJournal['email']) ? '' : $aJournal['email'],
'{website}' => empty($aJournal['website']) ? '' : $aJournal['website'],
];
//用户名
$realname = empty($aUser['account']) ? '' : $aUser['account'];
$realname = empty($aUser['realname']) ? $realname : $aUser['realname'];
$aSearch['{realname}'] = $realname;
//用户账号
$aSearch['{account}'] = empty($aUser['account']) ? '' : $aUser['account'];
//审稿链接
$oArticle = new \app\api\controller\Article;
$aSearch['{creatLoginUrlForreviewer}'] = $oArticle->creatLoginUrlForreviewer(['user_id' => $aArticleReviewer['reviewer_id']],$iArtRevId);
$title = str_replace(array_keys($aSearch), array_values($aSearch),$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;
//发送邮件
$memail = empty($aJournal['email']) ? '' : $aJournal['email'];
$mpassword = empty($aJournal['epassword']) ? '' : $aJournal['epassword'];
//期刊标题
$from_name = empty($aJournal['title']) ? '' : $aJournal['title'];
//邮件队列组装参数
$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){
return json_encode(['status' => 1,'msg' => 'success']);
}
return json_encode(['status' => 14,'msg' => 'fail']);
}
} }

View File

@@ -850,6 +850,29 @@ function my_doiToFrag2($data)
$update['refer_type'] = "journal"; $update['refer_type'] = "journal";
$update['is_ja'] = $joura == trim($bj[0]) ? 0 : 1; $update['is_ja'] = $joura == trim($bj[0]) ? 0 : 1;
$update['dateno'] = str_replace(' ', '', str_replace('-', '', trim($bj[1]))); $update['dateno'] = str_replace(' ', '', str_replace('-', '', trim($bj[1])));
//新增处理 期卷页码 20251127 start
if(!empty($update['dateno'])){
$sStr = $update['dateno'];
$aStr = explode(':', $sStr);
if(!empty($aStr[1])){
$parts = explode('', $aStr[1]);
if(count($parts) == 2){
$prefix = empty($parts[0]) ? 0 : intval($parts[0]);
$suffix = empty($parts[1]) ? 0 : intval($parts[1]);
if($prefix > $suffix){
$prefixLen = strlen($prefix);
$suffixLen = strlen($suffix);
$missingLen = $prefixLen - $suffixLen;
if ($missingLen > 0) {
$fillPart = substr($prefix, 0, $missingLen);
$newSuffix = $fillPart . $suffix;
$update['dateno'] = $aStr[0].':'.$prefix.'-'.$newSuffix;
}
}
}
}
}
//新增处理 期卷页码 20251127 end
$update['doilink'] = strpos($data['refer_doi'],"http")===false?"https://doi.org/" . $data['refer_doi']:$data['refer_doi']; $update['doilink'] = strpos($data['refer_doi'],"http")===false?"https://doi.org/" . $data['refer_doi']:$data['refer_doi'];
$update['cs'] = 1; $update['cs'] = 1;
} }

File diff suppressed because it is too large Load Diff