Compare commits

...

44 Commits

Author SHA1 Message Date
wangjinlei
16f58319ba content转成latex update 2025-12-23 11:20:11 +08:00
wangjinlei
c88731a4b7 content转成latex update 2025-12-23 11:16:43 +08:00
wangjinlei
92fb9433e5 content转成latex update 2025-12-23 11:10:38 +08:00
chengxl
ae5033ccd7 生成文件 2025-12-22 10:08:24 +08:00
wangjinlei
515425b2d7 content转成latex 2025-12-22 09:15:12 +08:00
wangjinlei
7068120d2c content转成latex 2025-12-19 17:17:23 +08:00
wangjinlei
9ba80f434a content转成latex 2025-12-19 16:27:13 +08:00
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
wangjinlei
ef62e8e7d0 Merge remote-tracking branch 'origin/master' 2025-11-27 16:32:07 +08:00
wangjinlei
01293220ef 支付bug 2025-11-27 16:32:03 +08:00
chengxl
774dc72635 接口调整 2025-11-27 10:29:11 +08:00
wangjinlei
2ddc30aa3d Merge remote-tracking branch 'origin/master' 2025-11-27 10:03:40 +08:00
wangjinlei
3c7e25ec65 支付bug 2025-11-27 10:03:35 +08:00
chengxl
325710815d 参考文献列表接口调整 2025-11-27 10:00:49 +08:00
chengxl
42c6c887ad 参考文献列表接口调整 2025-11-27 09:54:09 +08:00
chengxl
7009332c9f 接口修改 2025-11-27 09:51:24 +08:00
wangjinlei
b8dc9ded3a 支付bug 2025-11-26 17:39:35 +08:00
wangjinlei
f7641d4654 Merge remote-tracking branch 'origin/master' 2025-11-25 14:28:15 +08:00
wangjinlei
539694abc5 修復bug 2025-11-25 14:28:08 +08:00
chengxl
96a333922e 接口修改 2025-11-25 10:09:30 +08:00
chengxl
526a760545 接口修改 2025-11-21 17:35:59 +08:00
chengxl
d2ec39ddbe 接口修改 2025-11-21 16:18:56 +08:00
wangjinlei
4298ec83c6 编辑改版面费 2025-11-21 14:08:20 +08:00
chengxl
1b227c101e 新增方法 2025-11-21 10:06:54 +08:00
wangjinlei
f81aa69f05 订单bug 文章生产实例bug 2025-11-21 09:52:26 +08:00
wangjinlei
6b87375a6e 订单bug 文章生产实例bug 2025-11-20 14:16:49 +08:00
wangjinlei
5b11a2b8d6 订单bug 文章生产实例bug 2025-11-20 14:09:53 +08:00
12 changed files with 3601 additions and 1036 deletions

View File

@@ -501,7 +501,7 @@ class Article extends Base
$data = $this->request->post();
//查询文章基础数据
$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();
//查询审稿人审稿建议
@@ -1583,14 +1583,17 @@ class Article extends Base
$this->sendEmailToReviewer($data['articleId'], $data['state']);
}
//为预接收的文章生成production实例
//为预接收的文章生成production实例,处理收费
if ($data['state'] == 6) {
// $this->addProductionEx($data['articleId']);
$this->addProductionEx($data['articleId']);
$this->addArticleMainEx($data['articleId']);
//如果是免费的期刊文章,那么直接变成付款完成
if ($journal_info['fee'] == 0 || $article_info['ctime'] < 1735660800) {
$this->article_obj->where("article_id", $article_info['article_id'])->update(["is_buy" => 1]);
}else{//如果期刊收费,那么文章费用初始化
$this->article_obj->where("article_id", $article_info['article_id'])->update(["fee" => $journal_info['fee']]);
}
}
}
@@ -4656,6 +4659,10 @@ class Article extends Base
}
}
public function phpIn(){
phpinfo();
}
public function up_approval_file()
{
$file = request()->file('articleApproval');

View File

@@ -356,6 +356,7 @@ class Base extends Controller
return 'Instance already exists';
}
$article_info = $this->article_obj->where('article_id', $article_id)->find();
$files = $this->article_file_obj
->where('article_id', $article_info['article_id'])

View File

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

View File

@@ -1081,15 +1081,17 @@ class Finalreview extends Base
$aQuestion = empty($aQuestion) ? [] : array_column($aQuestion, null,'art_rev_id');
//查询复审
$aReviewerRepeatLists = [];
$aWhere = ['art_rev_id' => ['in',$aArtRevId],'recommend' => ['between',[1,3]]];
$aReviewerRepeat = Db::name('article_reviewer_repeat')->field('art_rev_rep_id,art_rev_id,recommend,ctime,stime')->where($aWhere)->select();
$aReviewerRepeatLists = $aReviewerRepeatListsData = [];
$aWhere = ['art_rev_id' => ['in',$aArtRevId],'recommend' => ['between',[0,3]]];
$aReviewerRepeat = Db::name('article_reviewer_repeat')->field('art_rev_rep_id,art_rev_id,recommend,ctime,stime,state')->where($aWhere)->select();
if(!empty($aReviewerRepeat)){
foreach ($aReviewerRepeat as $key => $value) {
$aReviewerRepeatLists[$value['art_rev_id']][] = $value;
if(in_array($value['recommend'], [1,2,3])){
$aReviewerRepeatLists[$value['art_rev_id']][] = $value;
}
$aReviewerRepeatListsData[$value['art_rev_id']][] = $value;
}
}
//查询作者信息
$aUserId = array_unique(array_column($aArticleReviewer, 'reviewer_id'));
$aWhere = ['user_id' => ['in',$aUserId],'state' => 0];
@@ -1100,6 +1102,18 @@ class Finalreview extends Base
$value['ctime'] = empty($aQuestionData['ctime']) ? $value['ctime'] : $aQuestionData['ctime'];
$value['score'] = empty($aQuestionData['score']) ? 0 : $aQuestionData['score'];
$value['repeat'] = empty($aReviewerRepeatLists[$value['art_rev_id']]) ? [] : $aReviewerRepeatLists[$value['art_rev_id']];
//判断是否复审
$value['can_repeat'] = empty($aQuestionData) ? 0 : 1;
if(!empty($aReviewerRepeatListsData[$value['art_rev_id']])){
$aEnd = end($aReviewerRepeatListsData[$value['art_rev_id']]);
$iState = empty($aEnd['state']) ? 0 : $aEnd['state'];
$iRecommend = empty($aEnd['recommend']) ? 0 : $aEnd['recommend'];
if($iState == 1 && $iRecommend == 3){
$value['can_repeat'] = 1;
}else{
$value['can_repeat'] = 0;
}
}
$value['rated'] = empty($aQuestionData['rated']) ? 0 : $aQuestionData['rated'];
$value['realname'] = empty($aUser[$value['reviewer_id']]) ? '' : $aUser[$value['reviewer_id']];
$value['recommend'] = empty($aQuestionData['recommend']) ? 0 : $aQuestionData['recommend'];

View File

@@ -55,6 +55,7 @@ class Order extends base{
public function completePaystation(){
Log::log("payStation:act ".date("Y-m-d H:i:s"));
$data = $this->request->post();
if(!isset($data['transaction_id'])|| !$data['result']['success']){
return jsonError("Paystation responds with no results or result fail");
@@ -73,52 +74,31 @@ class Order extends base{
public function testPaystationLookup(){
public function PaystationLookup(){
$data = $this->request->post();
$rule = new Validate([
"ms"=>"require"
"article_id"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
$param = "pi=616562&ms=".$data['ms'];
$url = "https://payments.paystation.co.nz/lookup?".$param;
$res = myGet($url);
return jsonSuccess($res);
}
public function testPaystationLookup1(){
$data = $this->request->post();
$rule = new Validate([
"transaction_id"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
$order_info = $this->order_obj->where("article_id",$article_info['article_id'])->whereIn("state",[0,1])->find();
if($order_info==null){
return jsonError("no order");
}
sleep(2);
$paystation_info = $this->paystation_obj->where("ps_id",$order_info['ps_id'])->find();
$response = paystationLookup($paystation_info["merchant_session"]);
$res = xml_to_array($response);
if(isset($res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage'])&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage']=="Transaction successful"&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorCode']==0){
$this->article_obj->where("article_id",$order_info['article_id'])->update(['is_buy'=>1]);
$this->order_obj->where("order_id",$order_info['order_id'])->update(['state'=>1]);
return jsonSuccess(["result"=>"success","paystation"=>$paystation_info]);
}else{
return jsonSuccess(['result'=>"fail","msg"=> $res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage'] ?? "no message"]);
}
// $accessToken = createPayStationToken();
// $curl = curl_init();
// curl_setopt_array($curl, array(
// CURLOPT_URL => 'https://api.paystation.co.nz/v1/transactions/'.$data['transaction_id'],
// CURLOPT_RETURNTRANSFER => true,
// CURLOPT_ENCODING => '',
// CURLOPT_MAXREDIRS => 10,
// CURLOPT_TIMEOUT => 0,
// CURLOPT_FOLLOWLOCATION => true,
// CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
// CURLOPT_CUSTOMREQUEST => 'GET',
// CURLOPT_HTTPHEADER => array(
// 'Content-Type: application/json',
// 'Authorization: Bearer '.$accessToken
// )
// ));
// $response = curl_exec($curl);
// curl_close($curl);
$response = paystationLookup($data['transaction_id']);
$res = object_to_array(json_decode($response));
return jsonSuccess($res);
}
public function testPays(){
@@ -146,7 +126,7 @@ class Order extends base{
$params["pstn_HMAC"] = $hmac_signature;
$url_with_params = $url . '?' . http_build_query($params);
echo $url_with_params;
// echo $url_with_params;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_with_params);
@@ -154,12 +134,10 @@ class Order extends base{
$response = curl_exec($ch);
if(curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
} else {
echo "Response: " . $response;
}
curl_close($ch);
return jsonSuccess($response);
return jsonSuccess(xml_to_array($response));
}
@@ -180,8 +158,8 @@ class Order extends base{
if($order_info['pay_type']==2){
$paystation = $this->paystation_obj->where("ps_id",$order_info['ps_id'])->find();
if($order_info['state']==0){
$res = object_to_array(json_decode(paystationLookup($paystation['transaction_id'])));
if(isset($res['result']['success'])&&$res['result']['success']){
$res = xml_to_array(paystationLookup($paystation['merchant_session']));
if(isset($res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage'])&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage']=='Transaction successful'){
$this->article_obj->where("article_id",$order_info['article_id'])->update(['is_buy'=>1]);
$this->order_obj->where("order_id",$order_info['order_id'])->update(['state'=>1]);
}
@@ -194,6 +172,64 @@ class Order extends base{
}
}
/**
* 修改文章价格
*
* 该函数用于编辑者修改指定文章的费用信息,包括费用金额和费用备注。
* 同时会同步更新相关的订单信息(如果存在未完成的订单)。
*
* @return \think\response\Json 返回JSON格式的结果成功时返回成功状态失败时返回错误信息
*/
public function changePrice(){
// 获取POST请求数据
$data = $this->request->post();
// 验证必要字段
$rule = new Validate([
"editor_id"=>"require",
"article_id"=>"require",
"fee"=>"require",
"fee_remark"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
// 查询文章、期刊和编辑者信息
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
$editor_info = $this->user_obj->where("user_id",$data['editor_id'])->find();
// 验证编辑者权限
if($journal_info['editor_id']!=$editor_info['user_id']){
return jsonError("You are not the editor of this journal");
}
// 更新文章费用信息
$article_update['fee']=$data['fee'];
$article_update['fee_remark']=$data['fee_remark'];
if(intval($data['fee'])==0) {
$article_update['is_buy']=1;
}
$this->article_obj->where("article_id",$data['article_id'])->update($article_update);
// 如果存在未完成的订单,则同步更新订单费用
$order_info = $this->order_obj->where("article_id",$data['article_id'])->whereIn("state",[0,1])->find();
if($order_info){
if(intval($data['fee'])==0){
$this->order_obj->where("order_id",$order_info['order_id'])->update(['state'=>2]);
}else{
$update1['order_fee']=$data['fee'];
$this->order_obj->where("order_id",$order_info['order_id'])->update($update1);
}
}
return jsonSuccess();
}
/**
* @throws DataNotFoundException
@@ -211,34 +247,14 @@ class Order extends base{
if(!$rule->check($data)){
return jsonError($rule->getError());
}
if(isset($data['type'])&&$data['type']==2){
$payType = 2;
}else{
$payType = 0;
}
$frag = [];
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
if($article_info['is_buy']==1){
return jsonError("paid");
}
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
// $journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
$check = $this->order_obj->where("user_id",$article_info['user_id'])->where("article_id",$data['article_id'])->whereIn("state",[0,1])->find();
if($check){
if($payType==0){
$ii = $this->createPaypalOrder($check['real_fee']);
// if(!isset($ii['jsonResponse']['status'])||$ii['jsonResponse']['status']!="CREATED"){
if(!isset($ii['jsonResponse']['status'])){
return jsonError("system error!");
}else{
$check['paypal_order_id'] = $ii['jsonResponse']['id'];
}
$check['pay_type'] = 0;
$this->order_obj->update($check);
$re['detail'] = $check;
$re['paypal'] = $ii;
$re['paystation'] = null;
return jsonSuccess($re);
}else{
$re['paypal'] = null;
$paystation_res = $this->creatPaystation($article_info['article_id']);
$ps_insert['transaction_id'] = $paystation_res['transaction_id'];
@@ -255,42 +271,23 @@ class Order extends base{
$re['paystation'] = $this->paystation_obj->where("ps_id",$ps_id)->find();
$re['detail'] =$this->order_obj->where("order_id",$check['order_id'])->find();
return jsonSuccess($re);
}
}
if($payType==0){//支付方式为paypal
$insert['order_sn'] = 'TMR'.date('Ymd') . strtoupper(bin2hex(random_bytes(8)));
$insert['user_id'] = $article_info['user_id'];
$insert['pay_type'] = 0;
$insert["article_id"] = $data['article_id'];
$insert['currency'] = "USD";
$insert['order_fee'] = $journal_info['fee'];
$insert['real_fee'] = $journal_info['fee'];
$frag["paypal"] = $this->createPaypalOrder($insert['real_fee']);
if(!isset($paypal['jsonResponse']['status'])){
return jsonError("system error");
}else{
$insert['paypal_order_id'] = $paypal['jsonResponse']['id'];
}
$insert['ctime'] = time();
$id = $this->order_obj->insertGetId($insert);
$frag['paystation'] = null;
}elseif ($payType==2){//支付方式为paystation
}
$ca_sn = 'TMR'.date('Ymd') . strtoupper(bin2hex(random_bytes(8)));
$insert1['order_sn'] = $ca_sn;
$insert1['user_id'] = $article_info['user_id'];
$insert1['pay_type'] = 2;
$insert1["article_id"] = $data['article_id'];
$insert1["currency"] = "USD";
$insert1['order_fee'] = $journal_info['fee'];
$insert1['real_fee'] = $journal_info['fee'];
$insert1['order_fee'] = $article_info['fee'];
$insert1['real_fee'] = $article_info['fee'];
$accessToken = createPayStationToken();
$data_array = [
'paystation_id' => Env::get("paystation.client_id"),
'gateway_id' => "PAYSTATION",//GATEWAY_ID,
"merchant_session" => $ca_sn,
"merchant_reference"=>$ca_sn,
"amount" =>(int)(prin($journal_info['fee'])*100),//(int)((((int)$journal_info['fee'])*726/416)*100),
"amount" =>(int)(prin($article_info['fee'])*100),//(int)((((int)$journal_info['fee'])*726/416)*100),
// "amount" =>100,
// "currency"=>"USD",//目前paystation仅支持nzd
"return_url"=>"https://submission.tmrjournals.com/success?id=".$article_info['article_id'],
@@ -317,16 +314,13 @@ class Order extends base{
$id = $this->order_obj->insertGetId($insert1);
$frag['paystation'] = $paystation_res;
$frag["paypal"] = null;
}else{//暂时不处理,其他情况
return jsonError("pay_type error");
}
$frag['detail'] = $this->order_obj->where("order_id",$id)->find();
return jsonSuccess($frag);
}
private function creatPaystation($article_id){
$article_info = $this->article_obj->where("article_id",$article_id)->find();
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
$ca_sn = 'TMR'.date('Ymd') . strtoupper(bin2hex(random_bytes(8)));
$accessToken = createPayStationToken();
$data_array = [
@@ -334,7 +328,7 @@ class Order extends base{
'gateway_id' => "PAYSTATION",//GATEWAY_ID,
"merchant_session" => $ca_sn,
"merchant_reference"=>$ca_sn,
"amount" =>(int)(prin($journal_info['fee'])*100),//(int)((((int)$journal_info['fee'])*726/416)*100),
"amount" =>(int)(prin($article_info['fee'])*100),
"return_url"=>"https://submission.tmrjournals.com/success?id=".$article_info['article_id'],
"response_url"=>"http://api.tmrjournals.com/public/index.php/api/Order/completePaystation"
];
@@ -386,6 +380,16 @@ class Order extends base{
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
$user_info = $this->user_obj->where("user_id",$article_info['user_id'])->find();
$order_info = $this->order_obj->where("article_id",$article_info['article_id'])->find();
if($order_info&$order_info['state']==0&&$order_info['ps_id']>0){
$paystation = $this->paystation_obj->where("ps_id",$order_info['ps_id'])->find();
$res = xml_to_array(paystationLookup($paystation['merchant_session']));
if(isset($res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage'])&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage']=="Transaction successful"&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorCode']==0){
$this->article_obj->where("article_id",$order_info['article_id'])->update(['is_buy'=>1]);
$this->order_obj->where("order_id",$order_info['order_id'])->update(['state'=>1]);
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
}
}
$re['article_detail'] = $article_info;
$re['journal_detail'] = $journal_info;
$re['user_detail'] = $user_info;

View File

@@ -30,20 +30,24 @@ class Preaccept extends Base
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
$production_info = $this->production_article_obj->where('article_id', $data['article_id'])->find();
$aWhere = ['article_id' => $data['article_id'],'state' => 0];
$production_info = $this->production_article_obj->where($aWhere)->find();
if ($production_info == null) {
return jsonError("Object is null");
}
$dois = $this->production_article_refer_obj->where("p_article_id", $production_info['p_article_id'])->where("refer_doi","<>","")->where("state",0)->group("refer_doi")->having("count(*)>1")->column("refer_doi");
$list = $this->production_article_refer_obj->where("p_article_id", $production_info['p_article_id'])->where('state', 0)->order("index")->select();
$aRepeat = [];
foreach ($list as $k => $v){
if(in_array($v['refer_doi'],$dois)){
$list[$k]['is_repeat'] = 1;
$aRepeat[$v['refer_doi']][] = $v['index'];
}else{
$list[$k]['is_repeat'] = 0;
}
}
$re["refers"] = $list;
$re['repeat'] = empty($aRepeat) ? [] : $aRepeat;
return jsonSuccess($re);
}
@@ -751,44 +755,25 @@ class Preaccept extends Base
}
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
if(intval($journal_info['fee'])==0||$article_info['ctime']<1735660800){//非收费期刊的文章直接返回
$re['state'] = 1;
$re['order'] = null;
$re["fee"] = 0;
return jsonSuccess($re);
}
$order_info = $this->order_obj->where("article_id",$article_info['article_id'])->find();
if($order_info==null){
$re['state'] = 0;
$re['order'] = null;
$re["fee"] = 0;
return jsonSuccess($re);
}
// if($order_info['pay_type']==2){
if($order_info){
$paystation = $this->paystation_obj->where("ps_id",$order_info['ps_id'])->find();
$order_info['paystation'] = $paystation;
if($order_info['state']==0){
$res = object_to_array(json_decode(paystationLookup($paystation['transaction_id'])));
if(isset($res['result']['success'])&&$res['result']['success']){
$res = xml_to_array(paystationLookup($paystation['merchant_session']));
if(isset($res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage'])&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorMessage']=="Transaction successful"&&$res['PaystationQuickLookup']['LookupResponse']['PaystationErrorCode']==0){
$this->article_obj->where("article_id",$order_info['article_id'])->update(['is_buy'=>1]);
$this->order_obj->where("order_id",$order_info['order_id'])->update(['state'=>1]);
$re['state'] = 1;
$re['fee'] = $journal_info['fee'];
$re['order'] = $order_info;
return jsonSuccess($re);
}else{
$re['state'] = 0;
$re['fee'] = $journal_info['fee'];
$re['order'] = $order_info;
return jsonSuccess($re);
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
}
}else{
$re['state'] = 1;
$re['fee'] = $journal_info['fee'];
$re['order'] = $order_info;
return jsonSuccess($re);
}
// }
}
$re['state'] = $article_info['is_buy'];
$re['order'] = $order_info;
$re["fee"] = $article_info['fee'];
$re['article'] = $article_info;
$re['journal'] = $journal_info;
return jsonSuccess($re);
}
@@ -1591,5 +1576,171 @@ return null;
$re['list'] = $mains;
return jsonSuccess($re);
}
//作者上传参考文献 - 新
public function addRefersByExcelNew(){
$data = $this->request->post();
$rule = new Validate([
"article_id" => "require",
"referFile" => "require"
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
//判断数据是否存在 不存在直接入库数据 chengxiaoling 20251119 start
$aWhere = ['article_id' => $data['article_id'],'state' => 0];
$production_info = $this->production_article_obj->where($aWhere)->find();
if (!$production_info) {
$aResult = $this->addProductionEx($data['article_id']);
$aResult = empty($aResult->getData()) ? [] : $aResult->getData();
$iCode = isset($aResult['code']) ? $aResult['code'] : -1;
$sMsg = empty($aResult['msg']) ? 'Data processing failed' : $aResult['msg'];
if($iCode != 0){
return jsonError($sMsg);
}
}
$production_info = $this->production_article_obj->where($aWhere)->find();
if(!$production_info){
return jsonError("Object is null");
}
//判断数据是否存在 不存在直接入库数据 chengxiaoling 20251119 end
$file = ROOT_PATH . 'public' . DS . "referFile" . DS . $data['referFile'];
$list = $this->readRefersExcelNew($file,$production_info['p_article_id'],$data['article_id']);
if(!empty($list)){
$result = $this->production_article_refer_obj->insertAll($list);
}
//写入获取参考文献详情队列
\think\Queue::push('app\api\job\ArticleReferQueue@fire',['article_id' => $data['article_id'],'p_article_id' => $production_info['p_article_id']], 'ArticleReferQueue');
return jsonSuccess([]);
}
public function readRefersExcelNew($afile,$p_article_id = 0,$article_id = 0){
if(empty($p_article_id)){
return [];
}
// //查询参考文献
// $aWhere = ['p_article_id' => $p_article_id,'article_id' => $article_id,'state' => 0,'refer_doi' => ['<>','']];
// $aRefer = Db::name('production_article_refer')->where($aWhere)->column('refer_doi');
$extension = substr($afile, strrpos($afile, '.') + 1);
vendor("PHPExcel.PHPExcel");
if ($extension == 'xlsx') {
$objReader = new \PHPExcel_Reader_Excel2007();
$objPHPExcel = $objReader->load($afile);
} else if ($extension == 'xls') {
$objReader = new \PHPExcel_Reader_Excel5();
$objPHPExcel = $objReader->load($afile);
}
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$frag = [];
$k = 0;
for ($i = 2; $i <= $highestRow; $i++) {
if ($objPHPExcel->getActiveSheet()->getCell("A" . $i)->getValue() == '') {
continue;
}
$aa['refer_content'] = $objPHPExcel->getActiveSheet()->getCell("A" . $i)->getValue();
$aa['refer_doi'] = $objPHPExcel->getActiveSheet()->getCell("B" . $i)->getValue();
if(empty($aa['refer_doi'])){
continue;
}
$aa['refer_doi'] = trim($aa['refer_doi']);
$aa['refer_content'] = trim($aa['refer_content']);
// //判断是否添加过
// $doiLinkPattern = '/^(https?:\/\/)?([a-zA-Z0-9_-]+\.)*[a-zA-Z0-9_-]+\.[a-zA-Z]{2,}(\/.*)?$/i';
// if(preg_match($doiLinkPattern, $aa['refer_doi'], $matches)){
// if(in_array($aa['refer_doi'], $aRefer)){
// continue;
// }
// }
$aa['p_article_id'] = $p_article_id;
$aa['article_id'] = $article_id;
$aa['index'] = $k;
$aa['ctime'] = time();
$aa['index'] = $k;
$aa['refer_frag'] = $aa['refer_content'];
$aa['refer_type'] = 'other';
$aa['is_deal'] = 2;
$k++;
$frag[] = $aa;
}
return $frag;
}
//获取参考文献的状态
public function getReferState(){
//获取参数
$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 the article']);
}
$aWhere = ['article_id' => $iArticleId,'state' => 0];
$aProductionArticle = $this->production_article_obj->field('p_article_id')->where($aWhere)->find();
$iPArticleId = empty($aProductionArticle['p_article_id']) ? 0 : $aProductionArticle['p_article_id'];
if(empty($iPArticleId)) {
return json_encode(array('status' => 2,'msg' => 'No articles found'));
}
//查询参考文献数据
$aWhere = ['p_article_id' => $iPArticleId,'article_id' => $iArticleId,'state' => 0];
$aRefer = Db::name('production_article_refer')->where($aWhere)->select();
if(empty($aRefer)){
return json_encode(array('status' => 3,'msg' => 'Reference is empty','data' => ['total' => 0,'unprocessed_total' => 0,'processed_total' => 0]));
}
//获取总数量
$iCount = empty($aRefer) ? 0 : count($aRefer);
$aWhere["refer_doi"] = ["<>",""];
$aDoi = Db::name('production_article_refer')->field('count(p_article_id) as num,refer_doi')->where($aWhere)->group('refer_doi')->select();
$aDoi = empty($aDoi) ? [] : array_column($aDoi, 'num','refer_doi');
//数据处理
$iUnprocessed = $iProcessed = 0;
foreach ($aRefer as $key => $value) {
if($value['is_deal'] == 1){
$iProcessed++;
}
if($value['is_deal'] == 2){
$iUnprocessed++;
}
$iIsRepat = 0;
if(!empty($value['refer_doi']) && (!empty($aDoi[$value['refer_doi']]) && $aDoi[$value['refer_doi']] > 1)){
$iIsRepat = 1;
}
$aRefer[$key]['is_repeat'] = $iIsRepat;
}
$aRefer = ['total' => $iCount,'unprocessed_total' => $iUnprocessed,'processed_total' => $iProcessed,'refer' => $aRefer];
return json_encode(['status' => 1,'msg' => 'success','data' => $aRefer]);
}
//使文章进入生产状态
public function beginProduce(){
//获取参数
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//获取文章ID
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
if(empty($iArticleId)){
return jsonError('Please select the article');
}
//查询是否缴费
$aWhere = ['article_id' => $iArticleId,'state' => ['in',[5,6]]];
$aArticle = $this->article_obj->field('is_buy')->where($aWhere)->find();
if(empty($aArticle)){
return jsonError('No article information found');
}
// $iIsBuy = empty($aArticle['is_buy']) ? 0 : $aArticle['is_buy'];
// if($iIsBuy != 1){
// return jsonError('Article unpaid');
// }
$aWhere = ['article_id' => $iArticleId,'state' => 0];
$aProductionArticle = $this->production_article_obj->field('p_article_id')->where($aWhere)->find();
if(!empty($aProductionArticle)) {
return jsonError('The article has entered production');
}
$aResult = $this->addProductionEx($iArticleId);
$aResult = empty($aResult->getData()) ? [] : $aResult->getData();
$iCode = isset($aResult['code']) ? $aResult['code'] : -1;
$sMsg = empty($aResult['msg']) ? 'Data processing failed' : $aResult['msg'];
if($iCode != 0){
return jsonError($sMsg);
}
return jsonSuccess([]);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -45,7 +45,7 @@ class Workbench extends Base
//标题
$sTitle = empty($aParam['title']) ? '': $aParam['title'];
if(!empty($sTitle)){
$aWhere = ['title' => trim($sTitle)];
$aWhere = ['title' => ['like','%'.trim($sTitle).'%']];
}
//国家
$sCountry = -1;
@@ -400,4 +400,488 @@ class Workbench extends Base
Db::commit();
return json_encode(['status' => 1,'msg' => 'Update successful']);
}
/**
* 获取审稿记录详情
*/
public function getArticleReviewDetail(){
//获取参数
$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 the article']);
}
//获取审稿记录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']);
}
//获取复审记录ID
$iArtRevRepId = empty($aParam['art_rev_rep_id']) ? 0 : $aParam['art_rev_rep_id'];
if(empty($iArtRevId) && empty($iArtRevRepId)){
return json_encode(['status' => 2,'msg' => 'Please select a record']);
}
//查询文章
$aArticle = json_decode($this->get($aParam),true);
$iStatus = empty($aArticle['status']) ? 0 : $aArticle['status'];
if($iStatus != 1){
return json_encode($aArticle);
}
$aArticle = empty($aArticle['data']) ? [] : $aArticle['data'];
//查询审稿记录
$aWhere = ['art_rev_id' => $iArtRevId,'article_id' => $iArticleId];
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,ctime')->where($aWhere)->find();
if(empty($aArticleReviewer)){
return json_encode(['status' => 3,'msg' => 'Review record does not exist']);
}
if(empty($iArtRevRepId)){
//查询初审问卷
$aWhere = ['art_rev_id' => $iArtRevId];
$aQuestion = Db::name('article_reviewer_question')->field('is_anonymous')->where($aWhere)->find();
$aArticleReviewer['is_anonymous'] = empty($aQuestion['is_anonymous']) ? 0 : $aQuestion['is_anonymous'];
}
//查询审稿人姓名
$iUserId = empty($aArticleReviewer['reviewer_id']) ? 0 : $aArticleReviewer['reviewer_id'];
if(!empty($iUserId)){
$aWhere = ['user_id' => $iUserId,'state' => 0];
$aUser = Db::name('user')->field('realname,email')->where($aWhere)->find();
$aArticleReviewer['realname'] = empty($aUser['realname']) ? '' : $aUser['realname'];
$aArticleReviewer['email'] = empty($aUser['email']) ? '' : $aUser['email'];
}
//组装信息
$aData = ['article' => $aArticle,'article_reviewer' => $aArticleReviewer];
//查询复审信息
if(!empty($iArtRevRepId)){
//查询初审问卷
$aWhere = ['art_rev_id' => $iArtRevId,'art_rev_rep_id' => $iArtRevRepId];
$aData['article_reviewer_repeat'] = Db::name('article_reviewer_repeat')->where($aWhere)->find();
}
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['is_ja'] = $joura == trim($bj[0]) ? 0 : 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['cs'] = 1;
}
@@ -998,27 +1021,54 @@ function aliemail($email,$title,$content,$has_hb=1){
return $res;
}
function paystationLookup($transactionId){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.paystation.co.nz/v1/transactions/'.$transactionId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Bearer '.createPayStationToken()
)
));
$response = curl_exec($curl);
curl_close($curl);
//function paystationLookup($transactionId){
// $curl = curl_init();
// curl_setopt_array($curl, array(
// CURLOPT_URL => 'https://api.paystation.co.nz/v1/transactions/'.$transactionId,
// CURLOPT_RETURNTRANSFER => true,
// CURLOPT_ENCODING => '',
// CURLOPT_MAXREDIRS => 10,
// CURLOPT_TIMEOUT => 0,
// CURLOPT_FOLLOWLOCATION => true,
// CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
// CURLOPT_CUSTOMREQUEST => 'GET',
// CURLOPT_HTTPHEADER => array(
// 'Content-Type: application/json',
// 'Authorization: Bearer '.createPayStationToken()
// )
// ));
// $response = curl_exec($curl);
// curl_close($curl);
// return $response;
//}
function paystationLookup($ms){
$url = "https://payments.paystation.co.nz/lookup/";
$time = time();
$params = [
"pi" => "616562",
"ms" => $ms,
"pstn_HMACTimestamp" => $time
];
$secret_key = Env::get("paystation.hmac");// 使用提供的HMAC认证密钥
$query_string = http_build_query($params);
$hmac_signature = hash_hmac('sha256', $time."paystation".$query_string,$secret_key);
$params["pstn_HMAC"] = $hmac_signature;
$url_with_params = $url . '?' . http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_with_params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
if(curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return $response;
}
function createPayStationToken(){
$bodyParams = [
'client_id' => Env::get("paystation.client_id"),
@@ -1122,7 +1172,7 @@ function add_usermsg($userid, $content, $url)
return $msg_obj->insert($msgdata);
}
function jsonSuccess($data)
function jsonSuccess($data=[])
{
return json(['code' => 0, 'msg' => 'success', 'data' => $data]);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,618 @@
<?php
namespace app\common;
use think\Db;
use app\common\LatexTable;
/**
* LaTeX内容生成类
*/
class LatexContent{
//期刊相关的信息
private $iYear = 2025;//年
private $iPeriod = 1;//期
private $sAbbr = 'tmr';//期刊缩写
private $sWebsite = 'https://www.tmrjournals.com/tmr';//期刊官网
//模版地址
private $sLatexUrl = '/public/latex/';
//期刊官网接口地址
private $sJournalUrl = 'http://zmzm.journal.dev.com/';//'http://journalapi.tmrjournals.com/public/index.php/';//
//文章图片
private $sArticleIcon = '/public/articleicon/';
//文章图片
private $sArticleMainImage = '/public/articleImage/';
//编辑系统URL
private $sSubmissionUrl = 'https://submission.tmrjournals.com/';
//图片模版
private $sImageTempalte = '\begin{figure}[hbt!]
\centering
\includegraphics[width=0.75\linewidth]{{{img_url}}}
\caption{{{img_title}}}
\label{{{img_fig_sim}}}
\end{figure}' ;
//首页内容
private $sFirst = '\documentclass[
journal={{journal_abbr}},
journalname={{{{journal_title}}}},
layout=largetwo,
year={{stage_year}},%年
volume={{stage_vol}},%卷
no={{stage_no}},%期
page={{stage_page}},%号
]{tmr-tex}
\doi{{{doi}}}
\journalweb{{{website}}}
% \def\ORCIdICONNAME{{{CLSFILEURL}}/orcid_icon.png} %定义ORCID图片
% \def\TMRLOGONAME{{{CLSFILEURL}}/tmr-logo.pdf} % 定义期刊LOGO图片
\usepackage{amsmath}
\usepackage[nopatch]{microtype}
\usepackage{booktabs}
\usepackage[backend=biber]{biblatex}
\usepackage{xcolor} % 蓝色字体(参考文献)
\usepackage{multirow} % 单元格合并(必选)
\usepackage{array} % 列格式居中(必选)
\usepackage{geometry} % 页面适配,避免内容溢出
\addbibresource{example.bib}
\title{{{article_title}}}
{{author_info}}
\addbibresource{example.bib}
{{correspondence_info}}
\keywords{keyword entry 1, keyword entry 2, keyword entry 3} %% First letter not capped
{{author_contribution}}
\competinginterests{The authors declare no conflicts of interest.}
{{article_acknowledgment}}
\Peerreviewinformation{{{journal_title}} thanks all anonymous reviewers for their contribution to the peer review of this paper}
{{article_abbreviation}}
{{article_cite}}
\received{{{received_date}}}
\revised{{{revision_date}}}
\accepted{{{accepted_date}}}
\Availableonline{{{pub_date}}}
{{executive_editor}}
{{abstract}}
{{keywords}}
{{article_icon}}';
//正文内容
private $sMain = '\begin{document}
\twocolumn
{{tmr_highlight}}
{{article_main}}
\end{document}';
/**
* 生成初稿-基本内容
* @param article_id 文章ID
*/
public function buildFirst($aProductionArticle = []){
//获取模版
$sTemplateInfo = $this->sFirst;
//查询期刊信息
$iJournalId = empty($aProductionArticle['journal_id']) ? 0 : $aProductionArticle['journal_id'];
if(!empty($iJournalId)){
$aWhere = ['journal_id' => $iJournalId,'state' => 0];
$aJournal = Db::name('journal')->where($aWhere)->find();
if(!empty($aJournal)){
//获取编辑信息
$aWhere = ['user_id' => $aJournal['editor_id'],'state' => 0];
$aUser = Db::name('user')->field('realname')->where($aWhere)->find();
}
}
//子刊信息
$iJournalStageId = empty($aProductionArticle['journal_stage_id']) ? 0 : $aProductionArticle['journal_stage_id'];
if(!empty($iJournalStageId)){
$aJournalStage = $this->getJournalStage(['journal_stage_id' => $iJournalStageId]);
$aJournalStage = empty($aJournalStage['data']) ? [] : $aJournalStage['data'];
}
//期刊简写
$sAbbr = empty($aJournal['abbr']) ? $this->sAbbr : $aJournal['abbr'];
$sAbbr = strtolower($sAbbr);
$sJournalTitle = empty($aJournal['title']) ? '' : $aJournal['title'];
//年
$iYear = empty($aJournalStage['stage_year']) ? date('Y') : $aJournalStage['stage_year'];
//卷
$iVolume = empty($aJournalStage['stage_vol']) ? 0 : $aJournalStage['stage_vol'];
//期
$iPeriod = empty($aJournalStage['stage_no']) ? 0 : $aJournalStage['stage_no'];
//页
$sPage = empty($aJournalStage['stage_page']) ? '' : $aJournalStage['stage_page'];
//期刊web
$sWebsite = empty($aJournal['website']) ? $this->sWebsite : $aJournal['website'];
$aSearch = ['{{journal_abbr}}' => $sAbbr,'{{stage_year}}' => $iYear,'{{stage_vol}}' => $iVolume,'{{stage_no}}' => $iPeriod,'{{stage_page}}' => $sPage,'{{website}}' => $sWebsite,'{{journal_title}}' => $sJournalTitle];
//获取DOI
$aSearch['{{doi}}'] = empty($aProductionArticle['doi']) ? '' : $aProductionArticle['doi'];
//获取作者信息
$aAuthoInfo = $this->dealAuthor(['p_article_id' => $aProductionArticle['p_article_id']]);
$aSearch['{{author_info}}'] = empty($aAuthoInfo['author']) ? '' : $aAuthoInfo['author'];
//通讯作者信息
$aSearch['{{correspondence_info}}'] = empty($aAuthoInfo['correspondence']) ? '' : '\Correspondence{'.$aAuthoInfo['correspondence'].'}';
//文章基本信息处理
//标题
$sTitle = empty($aProductionArticle['title']) ? '' : $this->dealContent($aProductionArticle['title']);
if(!empty($sTitle)){
if(!empty($aProductionArticle['ltai'])){
$aLtai = explode(',', $aProductionArticle['ltai']);
foreach ($aLtai as $key => $value) {
if(empty($value)){
continue;
}
$sTitle = str_replace($value, '\textit{'.$value.'}', $sTitle);
}
}
}
$aSearch['{{article_title}}'] = $sTitle;
//author_contribution
$aSearch['{{author_contribution}}'] = empty($aProductionArticle['author_contribution']) ? '' : '\authorcontributions{'.$this->dealContent($aProductionArticle['author_contribution']).'}';
//acknowledgment
$aSearch['{{article_acknowledgment}}'] = empty($aProductionArticle['acknowledgment']) ? '' : '\Acknowledgments{'.$this->dealContent($aProductionArticle['acknowledgment']).'}';
//abbreviation
$aSearch['{{article_abbreviation}}'] = empty($aProductionArticle['abbreviation']) ? '' : '\Abbreviations{'.$this->dealContent($aProductionArticle['abbreviation']).'}';
//文章引用信息
$sCite = $this->getArticleCite($aProductionArticle,$aJournal,$aJournalStage);
$aSearch['{{article_cite}}'] = empty($sCite) ? '' : '\Citation{'.$sCite.'}';
//获取文章时间
$aTime = $this->getArticleTime(['article_id' => $aProductionArticle['article_id']]);
$aTime = empty($aTime['data']) ? [] : $aTime['data'];
$aSearch['{{received_date}}'] = empty($aTime['received_date']) ? '' : $aTime['received_date'];
$aSearch['{{revision_date}}'] = empty($aTime['revision_date']) ? '' : $aTime['revision_date'];
$aSearch['{{accepted_date}}'] = empty($aTime['accepted_date']) ? '' : $aTime['accepted_date'];
$aSearch['{{pub_date}}'] = empty($aProductionArticle['pub_date']) ? '' : $aProductionArticle['pub_date'];
//获取编辑信息
$aSearch['{{executive_editor}}'] = empty($aUser['realname']) ? '' : '\Executiveeditor{'.$this->dealContent($aUser['realname']).'}';
//摘要替换
$sAbstract = empty($aProductionArticle['abstract']) ? '' : $this->dealContent($aProductionArticle['abstract']);
if(!empty($sAbstract)){
$aRelace = ['Background:' => '\textcolor[HTML]{0070C0}{\textbf{Background:}}','Methods:' => '\textcolor[HTML]{0070C0}{\textbf{Methods:}}','Results:' => '\textcolor[HTML]{0070C0}{\textbf{Results:}}','Conclusion:' => '\textcolor[HTML]{0070C0}{\textbf{Conclusion:}}'];
$sAbstract = str_replace(array_keys($aRelace), array_values($aRelace), $sAbstract);
$sAbstract = '\tmrabstract{'.$sAbstract.'}';
}
$aSearch['{{abstract}}'] = $sAbstract;
//关键词
$sKeywords = empty($aProductionArticle['keywords']) ? '' : '\keywords{'.$this->dealContent($aProductionArticle['keywords']).'}';
$aSearch['{{keywords}}'] = $sKeywords;
//文章图片地址
$sIcon = empty($aProductionArticle['icon']) ? '' : $aProductionArticle['icon'];
if(!empty($sIcon)){
// $sIconUrl = rtrim(ROOT_PATH).$this->sArticleIcon.'/'.$sIcon;
// if(file_exists($sIconUrl)){
// $sIcon = '\KeywordImage{'.$sIconUrl.'}';
// }else{
// $sIcon = '';
// }
//下载图片
$sImagePath = trim($this->sSubmissionUrl,'/').$this->sArticleIcon.'/'.$sIcon;
$aImageInfo = $this->getImage($sImagePath,$aProductionArticle['p_article_id']);
if(!empty($aImageInfo['data'])){
$sIcon = '\KeywordImage{'.$aImageInfo['data'].'}';
}else{
$sIcon = '';
}
}
$aSearch['{{article_icon}}'] = $sIcon;
$aSearch['{{keywords}}'] = $sKeywords;
$aSearch['{{CLSFILEURL}}'] = ROOT_PATH.'public/latex/cls';
//模版内容替换
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
//返回内容
return ['status' => 1,'msg' => 'success','data' => $sTemplateInfo];
}
/**
* 生成初稿-主内容
* @param article_id 文章ID
*/
public function buildMain($aProductionArticle = []){
//获取模版
$sTemplateInfo = $this->sMain;
//数据替换
$aSearch = ['{{tmr_highlight}}' => '','{{article_main}}' => ''];
$sHighlight = '';
if($aProductionArticle['journal_id'] == 1){//tmr独有
$tradition_tag = empty($aProductionArticle['tradition_tag']) ? '' : strtolower( $aProductionArticle['tradition_tag']);
$tradition = empty($aProductionArticle['tradition']) ? '' : $this->dealContent($aProductionArticle['tradition']);
$pattern = '/<em[^>]*>(.*?)<\/em>/is';
$replacement = '\\emph{$1}';
// $tradition = preg_replace($pattern, $replacement, $tradition);
if(in_array($tradition_tag, ['highlight','highlights']) && !empty($tradition)){
$sHighlight .= '\highlightitem{Highlights}{'.$tradition.'}'."\n";
}
$mhoo = empty($aProductionArticle['mhoo']) ? '' : $this->dealContent( $aProductionArticle['mhoo']);
$mhoo = preg_replace($pattern, $replacement, $mhoo);
if(!empty($mhoo)){
$sHighlight .= '\highlightitem{Medical history of objective}{'.$mhoo.'}'."\n";
}
}
$aSearch['{{tmr_highlight}}'] = empty($sHighlight) ? '' : '\begin{highlight}'."\n".$sHighlight."\n".'\end{highlight}'."\n";
//查询正文信息
// $aProductionArticle['article_id'] = 4477;
$aWhere = ['article_id' => $aProductionArticle['article_id'],'state' => 0];
$aArticleMain = Db::name('article_main')->field('am_id,article_id,type,content,ami_id,amt_id,is_h1,is_h2,is_h3,sort')->where($aWhere)->order('sort')->select();
if(!empty($aArticleMain)){
//查询图片
$aAmiId = array_unique(array_column($aArticleMain, 'ami_id'));
$aWhere = ['ami_id' => ['in',$aAmiId],'state' => 0];
$aArticleMainImage = Db::name('article_main_image')->field('ami_id,url,note')->where($aWhere)->select();
$aArticleMainImage = empty($aArticleMainImage) ? [] : array_column($aArticleMainImage, null,'ami_id');
//查询表格
$aAmtId = array_unique(array_column($aArticleMain, 'amt_id'));
$aWhere = ['amt_id' => ['in',$aAmtId],'state' => 0];
$aArticleMainTable = Db::name('article_main_table')->field('amt_id,type,table_data,url,title,note')->where($aWhere)->select();
$aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
//获取图片模版
$sImageTempalte = $this->sImageTempalte;
//数据处理
$iStart = 0;
$sMain = '';
$oLatexTable = new LaTeXTable;
foreach ($aArticleMain as $key => $value) {
if(empty($iStart)){
if($value['is_h1'] == 0){
continue;
}else{
$iStart = $value['am_id'];
}
}
if($value['am_id'] >= $iStart){
if($value['is_h1'] == 1){
if(empty($value['content'])){
continue;
}
$sMain .= '\section{'.$this->dealContent($value['content']).'}'."\n";
}
if($value['is_h2'] == 1){
if(empty($value['content'])){
continue;
}
$sMain .= '\subsection{'.$this->dealContent($value['content']).'}'."\n";
}
if($value['is_h3'] == 1){
if(empty($value['content'])){
continue;
}
$sMain .= '\subsubsection{'.$this->dealContent($value['content']).'}'."\n";
}
if($value['is_h1'] == 0 && $value['is_h2'] == 0 && $value['is_h3'] == 0){
if($value['type'] == 0 ){
$sMain .= $this->dealContent($value['content'])."\\par\n";
}
if($value['type'] == 1 ){//图片
$aImageInfo = empty($aArticleMainImage[$value['ami_id']]) ? [] : $aArticleMainImage[$value['ami_id']];
if(empty($aImageInfo['url'])){
continue;
}
// $sIconUrl = rtrim(ROOT_PATH).$this->sArticleIcon.'/'.$sIcon;
// if(file_exists($sIconUrl)){
// $sIcon = '\KeywordImage{'.$sIconUrl.'}';
// }else{
// $sIcon = '';
// }
//下载图片
$sImagePath = trim($this->sSubmissionUrl,'/').$this->sArticleMainImage.'/'.$aImageInfo['url'];
$aResult = $this->getImage($sImagePath,$aProductionArticle['p_article_id']);
if(empty($aResult['data'])){
continue;
}
$aImageSearch = ['{{img_url}}' => $aResult['data'],'{{img_title}}' => $aImageInfo['note'],'{{img_fig_sim}}' => 'img_fig_sim_'.$value['ami_id']];
$sImageTempalteInfo = str_replace(array_keys($aImageSearch), array_values($aImageSearch), $sImageTempalte);
$sMain .= $sImageTempalteInfo."\\par\n";
}
if($value['type'] == 2 ){//表格
continue;
}
}
}
}
}
$aSearch['{{article_main}}'] = empty($sMain) ? '' : $sMain."\n";
//模版内容替换
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
//返回内容
return ['status' => 1,'msg' => 'success','data' => $sTemplateInfo];
}
/**
* 生成初稿-作者信息
*/
private function dealAuthor($aParam = []){
// 获取作者信息
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//必填值验证
$iPArticleId = empty($aParam['p_article_id']) ? '' : $aParam['p_article_id'];
if(empty($iPArticleId)){
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
}
//
//查询作者信息
$aWhere = ['p_article_id' => $iPArticleId,'state' => 0];
$aAuthor = Db::name('production_article_author')->where($aWhere)->select();
if(empty($aAuthor)){
return ['status' => 3,'msg' => 'Author information is empty'];
}
//查询作者机构
$aWhere['p_article_author_id'] = ['in',array_column($aAuthor, 'p_article_author_id')];
$aAuthorOrgan = Db::name('production_article_author_to_organ')->field('p_article_author_id,p_article_organ_id')->where($aWhere)->select();
//查询机构信息
$aAuthorOrganList = [];
if(!empty($aAuthorOrgan)){
unset($aWhere['p_article_author_id']);
$aOrganId = array_unique(array_column($aAuthorOrgan, 'p_article_organ_id'));
$aWhere['p_article_organ_id'] = ['in',$aOrganId];
$aOrgan = Db::name('production_article_organ')->where($aWhere)->column('p_article_organ_id,organ_name');
if(!empty($aOrgan)) {
foreach ($aAuthorOrgan as $key => $value) {
if(empty($aOrgan[$value['p_article_organ_id']])){
continue;
}
$aAuthorOrganList[$value['p_article_author_id']][] = $aOrgan[$value['p_article_organ_id']];
}
}
}
//处理作者
$sAuthor = $sCorrespondence = '';
foreach ($aAuthor as $key => $value) {
//作者姓名
$sName = empty($value['fifirst_name']) ? '' : $value['fifirst_name'];
$sName = empty($sName) ? '' : $sName . ' ' .$value['last_name'];
if(empty($sName)){
$sName = empty($value['author_name']) ? '' : $value['author_name'];
}
if(empty($sName)){
continue;
}
$sAuthor .= '\author{'.$this->dealContent($sName).'}'."\n";
if(!empty($value['email']) && $value['is_report'] == 1){
$sAuthor .= '\email{'.$this->dealContent($value['email']).'}'."\n";
}
//作者机构
$aOrganList = empty($aAuthorOrganList[$value['p_article_author_id']]) ? [] : $aAuthorOrganList[$value['p_article_author_id']];
if(!empty($aOrganList)){
$i = 0;
foreach($aOrganList as $organ){
if(empty($organ)){
continue;
}
if($i == 0){
$sAuthor .= '\affiliation{'.$this->dealContent($organ).'}'."\n";
}else{
$sAuthor .= '\alsoaffiliation{'.$this->dealContent($organ).'}'."\n";
}
$i++;
}
}
if($value['is_first'] == 1){
$sAuthor .= '\firstauthor'."\n";
}
if(!empty($value['orcid'])){
$sAuthor .= '\orcid{'.$this->dealContent($value['orcid']).'}'."\n";
}
if($value['is_report'] == 1){
$sCorrespondence .= $sName;
if(!empty($aOrganList[0])){
$sCorrespondence .= ','.trim($this->dealContent($aOrganList[0]),'.');
}
if(!empty($value['email'])){
$sCorrespondence .= '.E-mail: '.trim($this->dealContent($value['email']),'.').'.';
}
}
}
return ['author' => $sAuthor,'correspondence' => $sCorrespondence];
}
/**
* 生成初稿-获取期刊分期信息
*/
private function getJournalStage($aParam = []){
// 获取分期ID
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//必填值验证
$iJournalStageId = empty($aParam['journal_stage_id']) ? '' : $aParam['journal_stage_id'];
if(empty($iJournalStageId)){
return json_encode(array('status' => 2,'msg' => 'Please choose journal installment' ));
}
$sUrl = $this->sJournalUrl."api/Supplementary/getJournalStage";
$aResult = object_to_array(json_decode(myPost1($sUrl,$aParam)));
return $aResult;
}
/**
* 处理文章引用
* @param string $html
* @return string
*/
private function getArticleCite($aArticle = [],$aJournal = [],$aJournalStage = []){
$no = empty($aJournalStage['stage_no']) ? ':' : '(' . $aJournalStage['stage_no'] . '):';
$jabbr = empty($aJournal['jabbr']) ? '' : $aJournal['jabbr'];
$stage_year = empty($aJournalStage['stage_year']) ? '' : $aJournalStage['stage_year'];
$stage_vol = empty($aJournalStage['stage_vol']) ? '' : $aJournalStage['stage_vol'];
$aAbbr = empty($aArticle['abbr']) ? '' : explode(',', trim($aArticle['abbr']));
if(!empty($aAbbr)){
$sEnd = end($aAbbr);
if($sEnd != 'et al'){
$aArticle['abbr'] = implode(',', array_slice($aAbbr, 0,3));
if(!empty($aArticle['abbr'])){
$aArticle['abbr'] .= ', et al';
}
}
}
$sCite = '';
if ($aArticle['journal_id'] == 22) {
$sCite = $aArticle['abbr'] . '. ' . $aArticle['title'] . '[J]. ' . choiseJabbr($aArticle['article_id'],$jabbr) . ',' . $stage_year . ',' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
$sCite = $this->dealContent($sCite);
} else {
$sCite = $this->dealContent($aArticle['abbr']) . '. ' . $this->dealContent($aArticle['title']) . '. \textit{' . $this->dealContent(choiseJabbr($aArticle['article_id'], $jabbr)) . '}. ' . $stage_year . ';' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
}
return $sCite;
}
private function getArticleTime($aParam = []){
//必填值验证
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
if(empty($iArticleId)){
return array('status' => 2,'msg' => 'Please select an article' );
}
//查询文章
$aWhere = ['article_id' => $iArticleId];
$aArticle= Db::name('article')->field('ctime,received_time')->where($aWhere)->find();
if(empty($aArticle)){
return array('status' => 2,'msg' => 'The article does not exist' );
}
//获取文章记录
$aWhere = ['article_id' => $iArticleId,'state' => 0,'state_to' => ['in',[0,1,5]]];
$aArticleMsg = Db::name('article_msg')->field('state_from,state_to,ctime')->where($aWhere)->order('ctime deac')->select();
$iReceivedTime = $iRevisionTime = $iAcceptedTime = 0;
if(!empty($aArticleMsg)){
foreach ($aArticleMsg as $key => $value) {
if(empty($iReceivedTime) && $value['state_to'] == 0){
$iReceivedTime = $value['ctime'];
}
if(empty($iRevisionTime) && $value['state_to'] == 1){
$iRevisionTime = $value['ctime'];
}
if(empty($iAcceptedTime) && $value['state_to'] == 5){
$iAcceptedTime = $value['ctime'];
}
}
}
$iReceivedTime = empty($iReceivedTime) ? $aArticle['received_time'] : $iReceivedTime;
$iReceivedTime = empty($iReceivedTime) ? $aArticle['ctime'] : $iReceivedTime;
$aTime = [];
$aTime['received_date'] = empty($iReceivedTime) ? '' : $this->timestampToEnglishDate($iReceivedTime);
$aTime['revision_date'] = empty($iRevisionTime) ? '' : $this->timestampToEnglishDate($iRevisionTime);
$aTime['accepted_date'] = empty($iAcceptedTime) ? '' : $this->timestampToEnglishDate($iAcceptedTime);
return ['status' => 1,'msg' => 'success','data' => $aTime];
}
/**
* 时间戳转换为「d F Y」格式如 12 June 2025
* @param int $timestamp 时间戳如1749600000
* @return string 格式化后的英文日期
*/
private function timestampToEnglishDate($timestamp) {
//验证时间戳有效性
if (!is_numeric($timestamp) || $timestamp < 0) {
return '';
}
//设置本地化确保月份为英文全称兼容Linux/Windows
$locale = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'
? 'English_United States.1252'
: 'en_US.UTF-8';
setlocale(LC_TIME, $locale);
//格式化d=日无前导零、F=英文月份全称、Y=四位年 strftime的%e在Linux下是无前导零的日Windows用%#d
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$dateStr = strftime('%#d %B %Y', $timestamp); // Windows
} else {
$dateStr = strftime('%e %B %Y', $timestamp); // Linux/Mac
}
return trim($dateStr);
}
/**
* 内容处理
*/
private function dealContent($content = '', $target = 'latex',$iIsDeal = 1) {
// 空值直接返回
if (empty($content)) {
return '';
}
//统一编码为UTF-8
$content = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content));
//过滤不可见/非法字符
$content = preg_replace('/[\x00-\x1F\x7F]/u', '', $content);
//整合所有替换规则按优先级排序先处理HTML实体再处理LaTeX特殊字符
$replaceRules = [
// ========== HTML实体替换 ==========
'&nbsp;' => '~', // HTML非断行空格 → LaTeX非断行空格
'&nbsp' => '~', // 兼容无分号的&nbsp
'&amp;' => '\&', // HTML& → LaTeX转义&
'&lt;' => '<', // HTML< → 直接保留
'&gt;' => '>', // HTML> → 直接保留
// ========== LaTeX特殊字符转义 ==========
'{' => '\{', // 左花括号转义
'}' => '\}', // 右花括号转义
'&' => '\&', // 原生&转义(需在&amp;之后,避免覆盖)
'%' => '\%', // 百分号转义LaTeX注释符
'_' => '\_', // 下划线转义LaTeX下标符
'κ' => '$\kappa$', // 希腊字母κ → LaTeX数学环境避免乱码
'-' => '\text{-}', // 短横线强制保留形态
':' => ':', // 冒号无需转义(占位,便于统一维护)
];
//执行批量替换
$content = strtr($content, $replaceRules);
//清理多余空格/换行
$content = preg_replace('/\s+/u', ' ', trim($content));
return $content;
}
/**
* @title curl 请求获取图片保存到本地
* @param sPath 图片链接地址
*/
private function getImage($sPath = '',$iId = 0){
//判断参数
if(empty($sPath) || empty($iId)){
return ['status' => 2,'msg' => 'url is empty','data' => ''];
}
//获取图片名称
$aImageInfo = pathinfo($sPath);
//图片后缀名
$sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension'];
//图片地址
$sDir = ROOT_PATH.trim($this->sLatexUrl,'/').'/article_pdf/'.$iId.'/';
$sImagePath = $sDir.basename($sPath);
if (file_exists($sImagePath)) {
return ['status' => 1,'msg' => 'success','data' => $sImagePath];
}
//下载图片
if (!is_dir($sDir)) {
mkdir($sDir, 0755, true);
}
//curl 请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$sPath); // 设置请求URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 设置返回数据而不是直接输出
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用SSL验证
$response = curl_exec($ch);
if (curl_errno($ch)) {
return ['status' => 3,'msg' => 'Error:' . curl_error($ch),'data' => $sImagePath];
}
//保存图片
file_put_contents($sImagePath, $response);
curl_close($ch);
return ['status' => 1,'msg' => 'success','data' => $sImagePath];
}
}
?>

View File

@@ -445,16 +445,21 @@ class OpenAi
$model = empty($aParam['model']) ? 'gpt-4.1' : $aParam['model'];
//接口地址
$sUrl = $this->sUrl;
$sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url'];
// 降低随机性0-1,0为最确定
$iTemperature = empty($aParam['temperature']) ? '0.1' : $aParam['temperature'];
$iTemperature = empty($aParam['temperature']) ? 0 : $aParam['temperature'];
$iTop = empty($aParam['top_p']) ? 0.9 : $aParam['top_p'];
$sApiKey = empty($aParam['api_key']) ? '' : $aParam['api_key'];
//组装数据
$data = [
'model' => $model,
'messages' => $aMessage,
'temperature' => $iTemperature,
"max_tokens" => 1500, // 足够容纳结构化结论,避免截断
// "top_p" => $iTop, // 控制多样性1.0 表示不限制
// "frequency_penalty" => 0.0, // 避免重复内容
// "presence_penalty" => 0.0
];
$this->curl = curl_init();
@@ -463,7 +468,7 @@ class OpenAi
// 设置头信息
curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->sApiKey
'Authorization: Bearer ' . $sApiKey
]);
curl_setopt($this->curl, CURLOPT_PROXY,$this->proxy);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,true);
@@ -522,6 +527,7 @@ class OpenAi
$sUrl = empty($aParam['url']) ? $this->sUrl : $aParam['url'];
$iTemperature = empty($aParam['temperature']) ? '0.2' : $aParam['temperature'];
$iTop = empty($aParam['top_p']) ? '0.9' : $aParam['top_p'];
$sApiKey = empty($aParam['api_key']) ? '' : $aParam['api_key'];
// 组装数据 - 增加流式传输必要参数
$data = [
'model' => $model,
@@ -539,7 +545,7 @@ class OpenAi
curl_setopt($this->curl, CURLOPT_URL, $sUrl);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->sApiKey,
'Authorization: Bearer ' . $sApiKey,
'Accept: text/event-stream',
'Cache-Control: no-cache',
'Connection: keep-alive', // 保持长连接
@@ -879,6 +885,8 @@ class OpenAi
if(empty($sSysMessagePrompt)){
return [];
}
// 解析JSON
$sSysMessagePrompt = $this->fixEncoding($sSysMessagePrompt);
$aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel];
if(empty($aQuestion)){
return [];
@@ -892,7 +900,10 @@ class OpenAi
}
//系统角色
$sSysMessageInfo = empty($aScopeReturn[$key]) ? '' : json_encode($aScopeReturn[$key],JSON_UNESCAPED_UNICODE);
// 解析JSON
$sSysMessageInfo = $this->fixEncoding($sSysMessageInfo);
$sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $value);
$sUserPrompt = $this->fixEncoding($sUserPrompt);
$aMessage[] = [
['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo],
['role' => 'user', 'content' => $sUserPrompt],
@@ -1025,6 +1036,8 @@ class OpenAi
if(empty($sSysMessagePrompt)){
return [];
}
// 解析JSON
$sSysMessagePrompt = $this->fixEncoding($sSysMessagePrompt);
$aQuestion = empty($aQuestion[$sQuestionLevel]) ? [] : $aQuestion[$sQuestionLevel];
if(empty($aQuestion)){
return [];
@@ -1039,7 +1052,7 @@ class OpenAi
if(empty($sSysMessageInfo)){
return [];
}
$sSysMessageInfo = $this->fixEncoding($sSysMessageInfo);
//处理数据
$aContent = empty($aSearch['content']) ? '' : $aSearch['content'];
if(empty($aContent)){
@@ -1048,6 +1061,7 @@ class OpenAi
foreach ($aContent as $key => $value) {
$aSearch['content'] = $value;
$sUserPrompt = str_replace(array_keys($aSearch), array_values($aSearch), $aQuestion[$sQuestionFields]);
$sUserPrompt = $this->fixEncoding($sUserPrompt);
$aMessage[] = [
['role' => 'system', 'content' => $sSysMessagePrompt.$sSysMessageInfo],
['role' => 'user', 'content' => $sUserPrompt],
@@ -1055,6 +1069,30 @@ class OpenAi
}
return $aMessage;
}
private function fixEncoding($content) {
// 1. 检查是否为UTF-8不是则尝试多种常见编码转换
if (!mb_check_encoding($content, 'UTF-8')) {
// 优先尝试西方编码(因"10.1016/j"是DOI格式常见于英文文献
$encodings = ['Windows-1252', 'ISO-8859-1', 'GBK', 'GB2312'];
foreach ($encodings as $encoding) {
$converted = mb_convert_encoding($content, 'UTF-8', $encoding);
if (mb_check_encoding($converted, 'UTF-8')) {
$content = $converted;
break;
}
}
}
// 2. 过滤残留的乱码字符保留字母、数字、空格及DOI相关符号
// 允许的字符a-z、A-Z、0-9、空格、.、:、/、-、_、(、)、,
$content = preg_replace('/[^\p{L}\p{N}\s\.\:\/\-\_\(\),]/u', '', $content);
// 3. 去除首尾多余空格
$content = trim($content);
return $content;
}
/**
* 微信公众号-生成公微内容(CURL)
*/