Compare commits
81 Commits
603869a651
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85ae4aeffd | ||
|
|
f17c1e2308 | ||
|
|
da658e6880 | ||
|
|
1e210b2ba1 | ||
|
|
9bace438b9 | ||
|
|
d411d53a82 | ||
|
|
da54478a64 | ||
|
|
62e89e32ec | ||
|
|
b215fc1ab8 | ||
|
|
71c94933f9 | ||
|
|
46ebbc3f0e | ||
|
|
dad360489e | ||
|
|
efc766cf1c | ||
|
|
9c0f14d8d7 | ||
|
|
736d32bf91 | ||
|
|
e9bcaa5c24 | ||
|
|
c55e764a48 | ||
|
|
44b88a83ca | ||
|
|
6f417f6e9f | ||
|
|
8319777d3e | ||
|
|
71ec3c2ccd | ||
|
|
56dd707f9b | ||
|
|
d2fe34a7a3 | ||
|
|
2f921a4ea2 | ||
|
|
e109a84eff | ||
|
|
31da31b252 | ||
|
|
7c54b4f518 | ||
|
|
8fe397ff50 | ||
|
|
f9e29ad876 | ||
|
|
875d486ab5 | ||
|
|
a80897644e | ||
|
|
d518097f18 | ||
|
|
63a89b4af7 | ||
|
|
fd6d9de32f | ||
|
|
0029b96308 | ||
|
|
14e425c057 | ||
|
|
1d0581e46e | ||
|
|
56e8bb2a17 | ||
|
|
fda672ddc3 | ||
|
|
b37060be8f | ||
|
|
5dedee7988 | ||
|
|
f68ceb7523 | ||
|
|
f26f51ea37 | ||
|
|
3ebaf881e2 | ||
|
|
4d0cec198f | ||
|
|
06308bc319 | ||
|
|
f954c4b772 | ||
|
|
40f25544fa | ||
|
|
ad7085ee6c | ||
|
|
cd5bde87dc | ||
|
|
94f5208195 | ||
|
|
f77f722994 | ||
|
|
c2ee3b170f | ||
|
|
f31b75c85c | ||
|
|
67dc74575d | ||
|
|
b217ab03fd | ||
|
|
4704b61448 | ||
|
|
bf0208b32a | ||
|
|
42978e1756 | ||
|
|
2e5c0bb223 | ||
|
|
c180ea5b0e | ||
|
|
88593aa40c | ||
|
|
d4b03e7ec3 | ||
|
|
b6f2881bfb | ||
|
|
9e5fd03f31 | ||
|
|
6d2868c8f9 | ||
|
|
7e76540a66 | ||
|
|
6fc412c100 | ||
|
|
deb79eb249 | ||
|
|
d2f044a153 | ||
|
|
5dd87bd9fb | ||
|
|
a8a06c256e | ||
|
|
9268766f4d | ||
|
|
fc3b64ba5f | ||
|
|
5e073d832b | ||
|
|
b4bf4a6369 | ||
|
|
9849282f4b | ||
|
|
ef8c7de183 | ||
|
|
87f6a01c94 | ||
|
|
041141a68e | ||
|
|
ff0a873749 |
@@ -129,6 +129,12 @@ class Article extends Base
|
||||
}
|
||||
}
|
||||
$res[$key]['proof'] = $proof_state;
|
||||
//新增是否是草稿删除 20260204 start
|
||||
$res[$key]['is_draft'] = 2;
|
||||
if(!empty($val['accept_sn']) && substr($val['accept_sn'], 0, 5) === 'Draft'){
|
||||
$res[$key]['is_draft'] = 1;
|
||||
}
|
||||
//新增是否是草稿删除 20260204 end
|
||||
}
|
||||
|
||||
//返回数据
|
||||
@@ -585,6 +591,14 @@ class Article extends Base
|
||||
}
|
||||
}
|
||||
//查询终审意见 chengxiaoling 20250828 end
|
||||
//新增是否是草稿删除 20260204 start
|
||||
if(!empty($article_res)){
|
||||
$article_res['is_draft'] = 2;
|
||||
if(!empty($article_res['accept_sn']) && substr($article_res['accept_sn'], 0, 5) === 'Draft'){
|
||||
$article_res['is_draft'] = 1;
|
||||
}
|
||||
}
|
||||
//新增是否是草稿删除 20260204 end
|
||||
return json(['article' => $article_res, 'msg' => $article_msg, 'authors' => $author_res, 'suggest' => $suggest, 'transfer' => $transfer_res, 'transinfo' => $transfer_info, "major" => $major,'suggest_final' => $aFinal]);
|
||||
}
|
||||
|
||||
|
||||
358
application/api/controller/Articlemain.php
Normal file
358
application/api/controller/Articlemain.php
Normal file
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
use app\api\controller\Base;
|
||||
use think\Db;
|
||||
/**
|
||||
* @title 文章正文内容处理
|
||||
*/
|
||||
class Articlemain extends Base
|
||||
{
|
||||
|
||||
|
||||
|
||||
public function __construct(\think\Request $request = null) {
|
||||
parent::__construct($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传表格图片
|
||||
*/
|
||||
public function uploadTableImage(){
|
||||
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//上传文件域
|
||||
$file = $this->request->file('file_name');
|
||||
if (empty($file)) {
|
||||
return json_encode(array('status' => 2,'msg' => 'No uploaded file was obtained'));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//验证文件(类型/大小)
|
||||
$validate = [
|
||||
'size' => 1024000, // 限制1M以内
|
||||
// 'ext' => 'jpg,jpeg,png,gif' // 允许的后缀
|
||||
];
|
||||
$fileValid = $file->validate($validate);
|
||||
if (!$fileValid) {
|
||||
$errorMsg = $file->getError();
|
||||
return json_encode(['status' => 3, 'msg' => 'Format/size validation failed:' . $errorMsg]);
|
||||
}
|
||||
|
||||
//图片名后缀
|
||||
$ext = $file->getExtension();
|
||||
if (empty($ext)) {
|
||||
// 获取文件真实MIME类型(复制粘贴的图片也能识别)
|
||||
$mime = $file->getMime();
|
||||
// MIME类型与后缀的映射表(覆盖常见图片类型)
|
||||
$mimeExtMap = [
|
||||
// 基础图片格式
|
||||
'image/jpeg' => 'jpg',
|
||||
'image/jpg' => 'jpg', // 兼容简写
|
||||
'image/png' => 'png',
|
||||
'image/gif' => 'gif',
|
||||
'image/bmp' => 'bmp',
|
||||
'image/x-bmp' => 'bmp', // 兼容Windows bmp
|
||||
// 扩展图片格式
|
||||
'image/webp' => 'webp', // 网页常用
|
||||
'image/tiff' => 'tiff',
|
||||
'image/x-tiff' => 'tiff',
|
||||
'image/svg+xml' => 'svg', // 矢量图
|
||||
'image/heic' => 'heic', // 苹果图片格式
|
||||
'image/heif' => 'heif',
|
||||
'image/avif' => 'avif', // 高效压缩图
|
||||
// 特殊图片格式
|
||||
'image/x-icon' => 'ico', // 图标
|
||||
'image/vnd.microsoft.icon' => 'ico',
|
||||
];
|
||||
$ext = $mimeExtMap[$mime] ?? '';
|
||||
}
|
||||
$ext = empty($ext) ? 'png' : $ext;
|
||||
//组装新的图片名
|
||||
$sFileName = md5(uniqid(mt_rand(), true)) . '.' . $ext;
|
||||
|
||||
//保存文件
|
||||
$sImagePath = rtrim(ROOT_PATH,'/') . '/public' . DS . 'articleTableImage' . DS . $iArticleId;
|
||||
if (!is_dir($sImagePath)) {
|
||||
mkdir($sImagePath, 0777, true);
|
||||
}
|
||||
$sImageName = $fileValid->move($sImagePath,$sFileName);
|
||||
if (!$sImageName) {
|
||||
return json_encode(['status' => 4, 'msg' => $fileValid->getError()]);
|
||||
}
|
||||
|
||||
//返回图片路径
|
||||
return json_encode(['status' => 1, 'msg' => 'Upload successful','data' => $iArticleId .DS.$sFileName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取正文内容里删除图片
|
||||
*/
|
||||
public function removeMainImage(){
|
||||
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//图片ID
|
||||
$iAmiId = empty($aParam['ami_id']) ? 0 : $aParam['ami_id'];
|
||||
if(empty($iAmiId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select the image ID to query'));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//查询图片信息
|
||||
$aWhere = ['ami_id' => $iAmiId,'state' => 0,'article_id' => $iArticleId];
|
||||
$aMainImage = Db::name('article_main_image')->field('ami_id')->where($aWhere)->find();
|
||||
if(empty($aMainImage)){
|
||||
return json_encode(array('status' => 4,'msg' => 'Article image information does not exist' ));
|
||||
}
|
||||
//获取正文内容
|
||||
$aWhere = ['article_id' => $iArticleId,'type' => ['in',[0,1]],'state' => 0,'is_h1' => ['<>',1],'is_h2' => ['<>',1],'is_h3' => ['<>',1]];
|
||||
$aArticleMain = Db::name('article_main')->field('am_id,content,type,ami_id')->where($aWhere)->order('sort asc')->select();
|
||||
|
||||
$iBindImage = 2;
|
||||
if(!empty($aArticleMain)){//验证正文内容是否绑定该图片
|
||||
//数据处理
|
||||
foreach ($aArticleMain as $key => $value) {
|
||||
$sContent = empty($value['content']) ? '' : trim($value['content']);
|
||||
if(empty($sContent)){
|
||||
continue;
|
||||
}
|
||||
if(!empty($iAmiId)){
|
||||
if($value['type'] == 1 && $value['ami_id'] == $iAmiId){
|
||||
$iBindImage = 1;
|
||||
break;
|
||||
}
|
||||
if($value['type'] == 0){
|
||||
$result = $this->hasProcessedTagWithId($value['content'],$iAmiId);
|
||||
if($result == 1){
|
||||
$iBindImage = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($iBindImage == 1){
|
||||
return json_encode(array('status' => 5,'msg' => 'The main content has been bound to this image and cannot be deleted' ));
|
||||
}
|
||||
//删除图片
|
||||
$aWhere = ['ami_id' => $iAmiId];
|
||||
$aUpdate = ['state' => 1];
|
||||
$result = Db::name('article_main_image')->where($aWhere)->limit(1)->update($aUpdate);
|
||||
if($result === false){
|
||||
return json_encode(array('status' => 6,'msg' => 'Image deletion failed' ));
|
||||
}
|
||||
//返回数据
|
||||
return json_encode(array('status' => 1,'msg' => 'Image deleted successfully'));
|
||||
}
|
||||
/**
|
||||
* 获取正文内容里删除表格
|
||||
*/
|
||||
public function removeMainTable(){
|
||||
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//表格ID
|
||||
$iAmtId = empty($aParam['amt_id']) ? 0 : $aParam['amt_id'];
|
||||
if(empty($iAmtId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select the table ID to query'));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//查询表格信息
|
||||
$aWhere = ['amt_id' => $iAmtId,'state' => 0,'article_id' => $iArticleId];
|
||||
$aMainTable = Db::name('article_main_table')->field('amt_id')->where($aWhere)->find();
|
||||
if(empty($aMainTable)){
|
||||
return json_encode(array('status' => 4,'msg' => 'Article table information does not exist' ));
|
||||
}
|
||||
|
||||
//获取正文内容
|
||||
$aWhere = ['article_id' => $iArticleId,'type' => ['in',[0,2]],'state' => 0,'is_h1' => ['<>',1],'is_h2' => ['<>',1],'is_h3' => ['<>',1]];
|
||||
$aArticleMain = Db::name('article_main')->field('am_id,content,type,amt_id')->where($aWhere)->order('sort asc')->select();
|
||||
//数据处理-验证正文是否绑定表格
|
||||
$iBindTable = 2;
|
||||
if(!empty($aArticleMain)){
|
||||
foreach ($aArticleMain as $key => $value) {
|
||||
$sContent = empty($value['content']) ? '' : trim($value['content']);
|
||||
if(empty($sContent)){
|
||||
continue;
|
||||
}
|
||||
if($value['type'] == 2 && $value['amt_id'] == $iAmtId){
|
||||
$iBindTable = 1;
|
||||
break;
|
||||
}
|
||||
if($value['type'] == 0){
|
||||
$result = $this->hasProcessedTagWithId($value['content'],$iAmtId,'mytable');
|
||||
if($result == 1){
|
||||
$iBindTable = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($iBindTable == 1){
|
||||
return json_encode(array('status' => 5,'msg' => 'The main content is already bound to this table and cannot be deleted' ));
|
||||
}
|
||||
//删除表格
|
||||
$aWhere = ['amt_id' => $iAmtId];
|
||||
$aUpdate = ['state' => 1];
|
||||
$result = Db::name('article_main_table')->where($aWhere)->limit(1)->update($aUpdate);
|
||||
if($result === false){
|
||||
return json_encode(array('status' => 6,'msg' => 'Table deletion failed' ));
|
||||
}
|
||||
//返回数据
|
||||
return json_encode(array('status' => 1,'msg' => 'Table deleted successfully'));
|
||||
}
|
||||
/**
|
||||
* 验证是否存在
|
||||
*/
|
||||
public function hasProcessedTagWithId($content = '', $primaryId = 0, $sLable = 'myfigure') {
|
||||
if(empty($content) || empty($primaryId)){
|
||||
return 2;
|
||||
}
|
||||
$escapedTagName = preg_quote($sLable, '/');
|
||||
$escapedId = preg_quote($primaryId, '/');
|
||||
|
||||
// 优化后的正则表达式
|
||||
$pattern = "/<{$escapedTagName}\s+data-id\s*=\s*['\"]{$escapedId}['\"]\s*>(.*?)<\/{$escapedTagName}>/i";
|
||||
|
||||
// 执行匹配
|
||||
if (!preg_match($pattern, $content, $matches)) {
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* 获取文章关联的图片
|
||||
*/
|
||||
public function getArticleMainImage(){
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//查询图片信息
|
||||
$aWhere = ['state' => 0,'article_id' => $iArticleId];
|
||||
$aMainImage = Db::name('article_main_image')->field('ami_id,title')->where($aWhere)->select();
|
||||
return json_encode(array('status' => 1,'msg' => 'success','data' => $aMainImage));
|
||||
}
|
||||
/**
|
||||
* 获取文章关联的表格
|
||||
*/
|
||||
public function getArticleMainTable(){
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//查询表格信息
|
||||
$aWhere = ['state' => 0,'article_id' => $iArticleId];
|
||||
$aMainTable = Db::name('article_main_table')->field('amt_id,title')->where($aWhere)->order('amt_id asc')->select();
|
||||
return json_encode(array('status' => 1,'msg' => 'success','data' => $aMainTable));
|
||||
}
|
||||
/**
|
||||
* 获取文章关联图片的详细信息
|
||||
*/
|
||||
public function getMainImageInfo(){
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//图片ID
|
||||
$iAmiId = empty($aParam['ami_id']) ? 0 : $aParam['ami_id'];
|
||||
if(empty($iAmiId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select the image ID to query'));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//查询图片信息
|
||||
$aWhere = ['state' => 0,'article_id' => $iArticleId,'ami_id' => $iAmiId];
|
||||
$aMainImage = Db::name('article_main_image')->field('ami_id,title,url,note')->where($aWhere)->find();
|
||||
return json_encode(array('status' => 1,'msg' => 'success','data' => $aMainImage));
|
||||
}
|
||||
/**
|
||||
* 获取文章关联表格的详细信息
|
||||
*/
|
||||
public function getMainTableInfo(){
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//文章ID
|
||||
$iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
|
||||
}
|
||||
//表格ID
|
||||
$iAmtId = empty($aParam['amt_id']) ? 0 : $aParam['amt_id'];
|
||||
if(empty($iAmtId)){
|
||||
return json_encode(array('status' => 2,'msg' => 'Please select the table ID to query'));
|
||||
}
|
||||
//查询文章信息
|
||||
$aWhere = ['article_id' => $iArticleId];
|
||||
$aArticle = Db::name('article')->field('article_id')->where($aWhere)->find();
|
||||
if(empty($aArticle)){
|
||||
return json_encode(array('status' => 3,'msg' => 'The article does not exist' ));
|
||||
}
|
||||
//查询表格信息
|
||||
$aWhere = ['state' => 0,'article_id' => $iArticleId,'amt_id' => $iAmtId];
|
||||
$aMainTable = Db::name('article_main_table')->field('amt_id,type,table_data,url,title,note')->where($aWhere)->find();
|
||||
return json_encode(array('status' => 1,'msg' => 'success','data' => $aMainTable));
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class Base extends Controller
|
||||
protected $production_article_author_to_organ_obj = '';
|
||||
protected $production_article_frag_obj = '';
|
||||
protected $production_article_main_obj = '';
|
||||
protected $production_article_main_img_obj = '';
|
||||
// protected $production_article_main_img_obj = '';
|
||||
protected $apply_reviewer_obj = '';
|
||||
protected $promotion_obj = '';
|
||||
protected $promotion_email_obj = '';
|
||||
@@ -150,7 +150,7 @@ class Base extends Controller
|
||||
$this->production_article_author_to_organ_obj = Db::name('production_article_author_to_organ');
|
||||
$this->production_article_frag_obj = Db::name('production_article_frag');
|
||||
$this->production_article_main_obj = Db::name('production_article_main');
|
||||
$this->production_article_main_img_obj = Db::name("production_article_main_img");
|
||||
// $this->production_article_main_img_obj = Db::name("production_article_main_img");
|
||||
$this->apply_reviewer_obj = Db::name("apply_reviewer");
|
||||
$this->promotion_obj = Db::name("promotion");
|
||||
$this->promotion_email_obj = Db::name("promotion_email");
|
||||
@@ -437,7 +437,7 @@ class Base extends Controller
|
||||
$article_info = $this->article_obj->where('article_id', $article_id)->find();
|
||||
|
||||
$check = $this->article_main_obj->where("article_id",$article_id)->whereIn("state",[0,2])->find();
|
||||
if($check){
|
||||
if($check){//防止重复添加
|
||||
return ;
|
||||
}
|
||||
|
||||
@@ -523,7 +523,10 @@ class Base extends Controller
|
||||
$this->article_main_table_obj->insert($ins);
|
||||
}
|
||||
|
||||
|
||||
//写入处理内容里table和figure队列-排版 20260121 start
|
||||
\think\Queue::later(60,'app\api\job\DealMainFigureOrTable@fire', ['article_id' => $article_id], 'DealMainFigureOrTable');
|
||||
//写入处理内容里table和figure队列-排版 20260121 end
|
||||
|
||||
$pics = $this->article_file_obj->where("article_id",$article_id)->where("type_name","picturesAndTables")->where("state",0)->order("file_id desc")->limit(1)->select();
|
||||
if(!isset($pics[0])){
|
||||
return ;
|
||||
@@ -843,95 +846,95 @@ class Base extends Controller
|
||||
}
|
||||
|
||||
|
||||
public function getProductionMainImgs($p_article_id)
|
||||
{
|
||||
$mains = $this->production_article_main_obj->where('p_article_id', $p_article_id)->where('state', 0)->select();
|
||||
if (count($mains) == 0) {
|
||||
$this->creatMainData($p_article_id);
|
||||
$mains = $this->production_article_main_obj->where('p_article_id', $p_article_id)->where('state', 0)->select();
|
||||
}
|
||||
$frag = [];
|
||||
foreach ($mains as $v) {
|
||||
$frag[] = $v;
|
||||
$ca = $this->production_article_main_img_obj->where('p_main_id', $v['p_main_id'])->where("state", 0)->find();
|
||||
if ($ca) {
|
||||
$frag[] = $ca;
|
||||
$pre_id = $ca['p_main_img_id'];
|
||||
while ($pre_id != 0) {
|
||||
$cac = $this->production_article_main_img_obj->where('pre_id', $pre_id)->where('state', 0)->find();
|
||||
if ($cac) {
|
||||
$frag[] = $cac;
|
||||
$pre_id = $cac['p_main_img_id'];
|
||||
} else {
|
||||
$pre_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $frag;
|
||||
}
|
||||
// public function getProductionMainImgs($p_article_id)
|
||||
// {
|
||||
// $mains = $this->production_article_main_obj->where('p_article_id', $p_article_id)->where('state', 0)->select();
|
||||
// if (count($mains) == 0) {
|
||||
// $this->creatMainData($p_article_id);
|
||||
// $mains = $this->production_article_main_obj->where('p_article_id', $p_article_id)->where('state', 0)->select();
|
||||
// }
|
||||
// $frag = [];
|
||||
// foreach ($mains as $v) {
|
||||
// $frag[] = $v;
|
||||
// $ca = $this->production_article_main_img_obj->where('p_main_id', $v['p_main_id'])->where("state", 0)->find();
|
||||
// if ($ca) {
|
||||
// $frag[] = $ca;
|
||||
// $pre_id = $ca['p_main_img_id'];
|
||||
// while ($pre_id != 0) {
|
||||
// $cac = $this->production_article_main_img_obj->where('pre_id', $pre_id)->where('state', 0)->find();
|
||||
// if ($cac) {
|
||||
// $frag[] = $cac;
|
||||
// $pre_id = $cac['p_main_img_id'];
|
||||
// } else {
|
||||
// $pre_id = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return $frag;
|
||||
// }
|
||||
|
||||
private function creatMainData($p_article_id)
|
||||
{
|
||||
$p_info = $this->production_article_obj->where('p_article_id', $p_article_id)->find();
|
||||
$article_info = $this->article_obj->where('article_id', $p_info['article_id'])->find();
|
||||
$files = $this->article_file_obj
|
||||
->where('article_id', $article_info['article_id'])
|
||||
->where('type_name', 'manuscirpt')
|
||||
->order('ctime desc')
|
||||
->limit(1)
|
||||
->select();
|
||||
if (count($files) == 0) {
|
||||
return jsonError('No Manuscript');
|
||||
}
|
||||
$url = $this->ts_base_url."api/typeset/webReaddoc";
|
||||
$program['fileRoute'] = "https://submission.tmrjournals.com/public/" . $files[0]['file_url'];
|
||||
$res = object_to_array(json_decode(myPost($url, $program)));
|
||||
|
||||
$file_runs = $res['data'];
|
||||
|
||||
//整理信息
|
||||
$frag = [];
|
||||
$aa = [];
|
||||
$frag['title'] = $article_info['title'];
|
||||
$start_refer = false;
|
||||
foreach ($file_runs as $k => $v) {
|
||||
if ($start_refer && $v != '') {
|
||||
if (strlen($v) > 500) {
|
||||
$start_refer = false;
|
||||
$frag['main'][] = $v;
|
||||
continue;
|
||||
}
|
||||
$frag['references'][] = $v;
|
||||
continue;
|
||||
}
|
||||
$g_val = trim(preg_replace('/\<.*?\>/', '', $v));
|
||||
$aa[] = $g_val;
|
||||
|
||||
if ((strpos(strtolower(trim($g_val)), "keyword") == 0 || strpos(strtolower(trim($g_val)), "keyword") == 1) && !isset($frag['keywords'])) {
|
||||
$frag['keywords'] = $v;
|
||||
continue;
|
||||
}
|
||||
if (strtolower($g_val) == 'reference:' || strtolower($g_val) == 'references:' || strtolower($g_val) == 'references' || strtolower($g_val) == 'reference') {
|
||||
$start_refer = true;
|
||||
continue;
|
||||
}
|
||||
$frag['main'][] = $v;
|
||||
}
|
||||
if (!isset($frag['main'])) {
|
||||
return jsonError("manuscript file error!");
|
||||
}
|
||||
|
||||
|
||||
//将主体内容写入数据库
|
||||
foreach ($frag['main'] as $v) {
|
||||
$ca['p_article_id'] = $p_article_id;
|
||||
$ca['content'] = $v;
|
||||
$ca['content_g'] = '';
|
||||
$ca['ctime'] = time();
|
||||
$this->production_article_main_obj->insert($ca);
|
||||
}
|
||||
}
|
||||
// private function creatMainData($p_article_id)
|
||||
// {
|
||||
// $p_info = $this->production_article_obj->where('p_article_id', $p_article_id)->find();
|
||||
// $article_info = $this->article_obj->where('article_id', $p_info['article_id'])->find();
|
||||
// $files = $this->article_file_obj
|
||||
// ->where('article_id', $article_info['article_id'])
|
||||
// ->where('type_name', 'manuscirpt')
|
||||
// ->order('ctime desc')
|
||||
// ->limit(1)
|
||||
// ->select();
|
||||
// if (count($files) == 0) {
|
||||
// return jsonError('No Manuscript');
|
||||
// }
|
||||
// $url = $this->ts_base_url."api/typeset/webReaddoc";
|
||||
// $program['fileRoute'] = "https://submission.tmrjournals.com/public/" . $files[0]['file_url'];
|
||||
// $res = object_to_array(json_decode(myPost($url, $program)));
|
||||
//
|
||||
// $file_runs = $res['data'];
|
||||
//
|
||||
// //整理信息
|
||||
// $frag = [];
|
||||
// $aa = [];
|
||||
// $frag['title'] = $article_info['title'];
|
||||
// $start_refer = false;
|
||||
// foreach ($file_runs as $k => $v) {
|
||||
// if ($start_refer && $v != '') {
|
||||
// if (strlen($v) > 500) {
|
||||
// $start_refer = false;
|
||||
// $frag['main'][] = $v;
|
||||
// continue;
|
||||
// }
|
||||
// $frag['references'][] = $v;
|
||||
// continue;
|
||||
// }
|
||||
// $g_val = trim(preg_replace('/\<.*?\>/', '', $v));
|
||||
// $aa[] = $g_val;
|
||||
//
|
||||
// if ((strpos(strtolower(trim($g_val)), "keyword") == 0 || strpos(strtolower(trim($g_val)), "keyword") == 1) && !isset($frag['keywords'])) {
|
||||
// $frag['keywords'] = $v;
|
||||
// continue;
|
||||
// }
|
||||
// if (strtolower($g_val) == 'reference:' || strtolower($g_val) == 'references:' || strtolower($g_val) == 'references' || strtolower($g_val) == 'reference') {
|
||||
// $start_refer = true;
|
||||
// continue;
|
||||
// }
|
||||
// $frag['main'][] = $v;
|
||||
// }
|
||||
// if (!isset($frag['main'])) {
|
||||
// return jsonError("manuscript file error!");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// //将主体内容写入数据库
|
||||
// foreach ($frag['main'] as $v) {
|
||||
// $ca['p_article_id'] = $p_article_id;
|
||||
// $ca['content'] = $v;
|
||||
// $ca['content_g'] = '';
|
||||
// $ca['ctime'] = time();
|
||||
// $this->production_article_main_obj->insert($ca);
|
||||
// }
|
||||
// }
|
||||
|
||||
public function refuseReferIndex($p_article_id)
|
||||
{
|
||||
@@ -946,83 +949,83 @@ class Base extends Controller
|
||||
}
|
||||
|
||||
|
||||
public function getProductionMainImgsByNew($p_article_id, $file)
|
||||
{
|
||||
$p_info = $this->production_article_obj->where('p_article_id', $p_article_id)->find();
|
||||
$article_info = $this->article_obj->where('article_id', $p_info['article_id'])->find();
|
||||
$url = $this->ts_base_url."api/typeset/webReaddoc";
|
||||
$program['fileRoute'] = "https://submission.tmrjournals.com/public/completedManuscirpt/" . $file;
|
||||
// $program['fileRoute'] = "https://submission.tmrjournals.com/public/completedManuscirpt/20230706/87628e769c4ee8a8414219b05c72a028.docx" ;
|
||||
$res = object_to_array(json_decode(myPost($url, $program)));
|
||||
$file_runs = $res['data'];
|
||||
if (count($file_runs) == 0) {
|
||||
return jsonError("File crawl failed");
|
||||
}
|
||||
//清空之前的
|
||||
$this->production_article_main_obj->where('p_article_id', $p_article_id)->update(['state' => 1]);
|
||||
|
||||
//整理信息
|
||||
$frag = [];
|
||||
$aa = [];
|
||||
$frag['title'] = $article_info['title'];
|
||||
$start_refer = false;
|
||||
foreach ($file_runs as $k => $v) {
|
||||
if ($start_refer && $v != '') {
|
||||
if (strlen($v) > 500) {
|
||||
$start_refer = false;
|
||||
$frag['main'][] = $v;
|
||||
continue;
|
||||
}
|
||||
$frag['references'][] = $v;
|
||||
continue;
|
||||
}
|
||||
$g_val = trim(preg_replace('/\<.*?\>/', '', $v));
|
||||
$aa[] = $g_val;
|
||||
|
||||
if ((strpos(strtolower(trim($g_val)), "keyword") == 0 || strpos(strtolower(trim($g_val)), "keyword") == 1) && !isset($frag['keywords'])) {
|
||||
$frag['keywords'] = $v;
|
||||
continue;
|
||||
}
|
||||
if (strtolower($g_val) == 'reference:' || strtolower($g_val) == 'references:' || strtolower($g_val) == 'references' || strtolower($g_val) == 'reference') {
|
||||
$start_refer = true;
|
||||
continue;
|
||||
}
|
||||
$frag['main'][] = $v;
|
||||
}
|
||||
if (!isset($frag['main'])) {
|
||||
return jsonError("manuscript file error!");
|
||||
}
|
||||
|
||||
//将主体内容写入数据库
|
||||
foreach ($frag['main'] as $v) {
|
||||
$ca['p_article_id'] = $p_article_id;
|
||||
$ca['content'] = $v;
|
||||
$ca['content_g'] = '';
|
||||
$ca['ctime'] = time();
|
||||
$this->production_article_main_obj->insert($ca);
|
||||
}
|
||||
|
||||
$mains = $this->production_article_main_obj->where('p_article_id', $p_article_id)->where('state', 0)->select();
|
||||
$f = [];
|
||||
foreach ($mains as $v) {
|
||||
$f[] = $v;
|
||||
$ca = $this->production_article_main_img_obj->where('p_main_id', $v['p_main_id'])->where("state", 0)->find();
|
||||
if ($ca) {
|
||||
$f[] = $ca;
|
||||
$pre_id = $ca['p_main_img_id'];
|
||||
while ($pre_id != 0) {
|
||||
$cac = $this->production_article_main_img_obj->where('pre_id', $pre_id)->where('state', 0)->find();
|
||||
if ($cac) {
|
||||
$f[] = $cac;
|
||||
$pre_id = $cac['p_main_img_id'];
|
||||
} else {
|
||||
$pre_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
// public function getProductionMainImgsByNew($p_article_id, $file)
|
||||
// {
|
||||
// $p_info = $this->production_article_obj->where('p_article_id', $p_article_id)->find();
|
||||
// $article_info = $this->article_obj->where('article_id', $p_info['article_id'])->find();
|
||||
// $url = $this->ts_base_url."api/typeset/webReaddoc";
|
||||
// $program['fileRoute'] = "https://submission.tmrjournals.com/public/completedManuscirpt/" . $file;
|
||||
//// $program['fileRoute'] = "https://submission.tmrjournals.com/public/completedManuscirpt/20230706/87628e769c4ee8a8414219b05c72a028.docx" ;
|
||||
// $res = object_to_array(json_decode(myPost($url, $program)));
|
||||
// $file_runs = $res['data'];
|
||||
// if (count($file_runs) == 0) {
|
||||
// return jsonError("File crawl failed");
|
||||
// }
|
||||
// //清空之前的
|
||||
// $this->production_article_main_obj->where('p_article_id', $p_article_id)->update(['state' => 1]);
|
||||
//
|
||||
// //整理信息
|
||||
// $frag = [];
|
||||
// $aa = [];
|
||||
// $frag['title'] = $article_info['title'];
|
||||
// $start_refer = false;
|
||||
// foreach ($file_runs as $k => $v) {
|
||||
// if ($start_refer && $v != '') {
|
||||
// if (strlen($v) > 500) {
|
||||
// $start_refer = false;
|
||||
// $frag['main'][] = $v;
|
||||
// continue;
|
||||
// }
|
||||
// $frag['references'][] = $v;
|
||||
// continue;
|
||||
// }
|
||||
// $g_val = trim(preg_replace('/\<.*?\>/', '', $v));
|
||||
// $aa[] = $g_val;
|
||||
//
|
||||
// if ((strpos(strtolower(trim($g_val)), "keyword") == 0 || strpos(strtolower(trim($g_val)), "keyword") == 1) && !isset($frag['keywords'])) {
|
||||
// $frag['keywords'] = $v;
|
||||
// continue;
|
||||
// }
|
||||
// if (strtolower($g_val) == 'reference:' || strtolower($g_val) == 'references:' || strtolower($g_val) == 'references' || strtolower($g_val) == 'reference') {
|
||||
// $start_refer = true;
|
||||
// continue;
|
||||
// }
|
||||
// $frag['main'][] = $v;
|
||||
// }
|
||||
// if (!isset($frag['main'])) {
|
||||
// return jsonError("manuscript file error!");
|
||||
// }
|
||||
//
|
||||
// //将主体内容写入数据库
|
||||
// foreach ($frag['main'] as $v) {
|
||||
// $ca['p_article_id'] = $p_article_id;
|
||||
// $ca['content'] = $v;
|
||||
// $ca['content_g'] = '';
|
||||
// $ca['ctime'] = time();
|
||||
// $this->production_article_main_obj->insert($ca);
|
||||
// }
|
||||
//
|
||||
// $mains = $this->production_article_main_obj->where('p_article_id', $p_article_id)->where('state', 0)->select();
|
||||
// $f = [];
|
||||
// foreach ($mains as $v) {
|
||||
// $f[] = $v;
|
||||
// $ca = $this->production_article_main_img_obj->where('p_main_id', $v['p_main_id'])->where("state", 0)->find();
|
||||
// if ($ca) {
|
||||
// $f[] = $ca;
|
||||
// $pre_id = $ca['p_main_img_id'];
|
||||
// while ($pre_id != 0) {
|
||||
// $cac = $this->production_article_main_img_obj->where('pre_id', $pre_id)->where('state', 0)->find();
|
||||
// if ($cac) {
|
||||
// $f[] = $cac;
|
||||
// $pre_id = $cac['p_main_img_id'];
|
||||
// } else {
|
||||
// $pre_id = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return $f;
|
||||
// }
|
||||
|
||||
|
||||
/**创建空production实例,应对main和refers
|
||||
|
||||
@@ -21,7 +21,7 @@ class Contribute extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动投稿
|
||||
* 自动投稿,提交存储文章相关信息
|
||||
* @param file_url 文件地址
|
||||
*/
|
||||
public function contribute($aParam = []){
|
||||
|
||||
@@ -229,7 +229,7 @@ class Email extends Base
|
||||
|
||||
|
||||
public function myPush(){
|
||||
$journal_info = $this->journal_obj->where("journal_id",23)->find();
|
||||
$journal_info = $this->journal_obj->where("journal_id",1)->find();
|
||||
$edata['email'] = "751475802@qq.com";
|
||||
$edata['title'] = "Notice: Merger of Natural Therapy Advances and Food and Health into Integrative Medicine Discovery";
|
||||
$edata['content'] = "test content";
|
||||
|
||||
@@ -1167,9 +1167,17 @@ class Finalreview extends Base
|
||||
if(empty($aReviewerFinal)){
|
||||
return json_encode(['status' => 3,'msg' => 'Review record does not exist or review has been completed']);
|
||||
}
|
||||
//查询审稿人基本信息
|
||||
$aWhere = ['user_id' => $iReviewerId];
|
||||
$aUser = Db::name('user')->field('realname')->where($aWhere)->find();
|
||||
$aUser = Db::name('user')->field('realname,email')->where($aWhere)->find();
|
||||
$aReviewerFinal['realname'] = empty($aUser['realname']) ? '' : $aUser['realname'];
|
||||
$aReviewerFinal['email'] = empty($aUser['email']) ? '' : $aUser['email'];
|
||||
//查询审稿人机构
|
||||
if(!empty($aUser)){
|
||||
$aWhere = ['reviewer_id' => $iReviewerId,'state' => 0];
|
||||
$aReviewerInfo = Db::name('user_reviewer_info')->field('company')->where($aWhere)->find();
|
||||
$aReviewerFinal['company'] = empty($aReviewerInfo['company']) ? '' : $aReviewerInfo['company'];
|
||||
}
|
||||
return json_encode(['status' => 1,'msg' => 'success','data' => $aReviewerFinal]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
class Latex extends Base
|
||||
{
|
||||
public function __construct(\think\Request $request = null)
|
||||
{
|
||||
parent::__construct($request);
|
||||
}
|
||||
|
||||
public function generateLatexPdf()
|
||||
{
|
||||
$data = $this->request->post();
|
||||
$rule = new Validate([
|
||||
'p_article_id' => 'require|number'
|
||||
]);
|
||||
|
||||
if (!$rule->check($data)) {
|
||||
return jsonError($rule->getError());
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取文章信息
|
||||
$p_info = $this->production_article_obj->where('p_article_id', $data['p_article_id'])->find();
|
||||
if (!$p_info) {
|
||||
return jsonError('文章实例不存在');
|
||||
}
|
||||
|
||||
// 获取作者信息
|
||||
$authors = $this->production_article_author_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
|
||||
|
||||
// 获取机构信息
|
||||
$organs = $this->production_article_organ_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
|
||||
|
||||
// 获取正文内容
|
||||
$main_contents = $this->production_article_main_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('p_main_id')->select();
|
||||
|
||||
// 获取参考文献
|
||||
$references = $this->production_article_refer_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('index')->select();
|
||||
|
||||
// 构建LaTeX内容
|
||||
$latex_content = $this->buildLatexContent($p_info, $authors, $organs, $main_contents, $references);
|
||||
|
||||
// 创建临时目录
|
||||
$temp_dir = ROOT_PATH . 'public' . DS . 'temp_latex' . DS;
|
||||
if (!is_dir($temp_dir)) {
|
||||
mkdir($temp_dir, 0755, true);
|
||||
}
|
||||
|
||||
// 生成唯一的文件名
|
||||
$filename = 'article_' . $p_info['p_article_id'] . '_' . time();
|
||||
$tex_file = $temp_dir . $filename . '.tex';
|
||||
$pdf_file = $temp_dir . $filename . '.pdf';
|
||||
|
||||
// 写入LaTeX文件
|
||||
file_put_contents($tex_file, $latex_content);
|
||||
|
||||
// 执行LaTeX编译命令生成PDF
|
||||
$command = sprintf(
|
||||
'cd %s && pdflatex -interaction=nonstopmode -output-directory=%s %s',
|
||||
escapeshellarg($temp_dir),
|
||||
escapeshellarg($temp_dir),
|
||||
escapeshellarg($tex_file)
|
||||
);
|
||||
|
||||
// 执行命令
|
||||
$output = [];
|
||||
$return_var = 0;
|
||||
exec($command, $output, $return_var);
|
||||
|
||||
// 检查PDF是否生成成功
|
||||
if (!file_exists($pdf_file) || filesize($pdf_file) == 0) {
|
||||
return jsonError('PDF生成失败,请检查LaTeX内容或系统环境');
|
||||
}
|
||||
|
||||
// 移动PDF到正式目录
|
||||
$pdf_dir = ROOT_PATH . 'public' . DS . 'latex_pdfs' . DS;
|
||||
if (!is_dir($pdf_dir)) {
|
||||
mkdir($pdf_dir, 0755, true);
|
||||
}
|
||||
|
||||
$final_pdf_path = $pdf_dir . $filename . '.pdf';
|
||||
rename($pdf_file, $final_pdf_path);
|
||||
|
||||
// 清理临时文件
|
||||
if (file_exists($tex_file)) {
|
||||
unlink($tex_file);
|
||||
}
|
||||
|
||||
// 清理辅助文件(.aux, .log等)
|
||||
$aux_file = $temp_dir . $filename . '.aux';
|
||||
$log_file = $temp_dir . $filename . '.log';
|
||||
if (file_exists($aux_file)) unlink($aux_file);
|
||||
if (file_exists($log_file)) unlink($log_file);
|
||||
|
||||
// 返回PDF路径
|
||||
$relative_path = 'latex_pdfs/' . $filename . '.pdf';
|
||||
return jsonSuccess([
|
||||
'pdf_url' => $relative_path,
|
||||
'message' => 'PDF生成成功'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return jsonError('生成过程中发生错误: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建LaTeX文档内容
|
||||
* @param $p_info
|
||||
* @param $authors
|
||||
* @param $organs
|
||||
* @param $main_contents
|
||||
* @param $references
|
||||
* @return string
|
||||
*/
|
||||
private function buildLatexContent($p_info, $authors, $organs, $main_contents, $references)
|
||||
{
|
||||
// 构建机构映射
|
||||
$organ_map = [];
|
||||
foreach ($organs as $index => $organ) {
|
||||
$organ_map[$organ['p_article_organ_id']] = $index + 1;
|
||||
}
|
||||
|
||||
// LaTeX文档开始
|
||||
$latex = '\documentclass[twocolumn]{article}' . "\n";
|
||||
$latex .= '\usepackage[utf8]{inputenc}' . "\n";
|
||||
$latex .= '\usepackage[T1]{fontenc}' . "\n";
|
||||
$latex .= '\usepackage{geometry}' . "\n";
|
||||
$latex .= '\usepackage{graphicx}' . "\n";
|
||||
$latex .= '\usepackage{amsmath}' . "\n";
|
||||
$latex .= '\usepackage{amsfonts}' . "\n";
|
||||
$latex .= '\usepackage{amssymb}' . "\n";
|
||||
$latex .= '\usepackage{setspace}' . "\n";
|
||||
$latex .= '\usepackage{titlesec}' . "\n";
|
||||
$latex .= '\usepackage{hyperref}' . "\n";
|
||||
$latex .= '\usepackage{caption}' . "\n";
|
||||
$latex .= '\usepackage{multicol}' . "\n";
|
||||
$latex .= '\usepackage{abstract}' . "\n";
|
||||
|
||||
$latex .= '\geometry{left=1.5cm,right=1.5cm,top=2.5cm,bottom=2.5cm}' . "\n";
|
||||
$latex .= '\setstretch{1.5}' . "\n";
|
||||
|
||||
$latex .= '\title{' . $this->escapeLatexText($p_info['title']) . '}' . "\n";
|
||||
|
||||
// 处理作者和机构
|
||||
if (!empty($authors)) {
|
||||
$author_text = '';
|
||||
$affiliations = [];
|
||||
|
||||
foreach ($authors as $author) {
|
||||
if ($author_text !== '') {
|
||||
$author_text .= ', ';
|
||||
}
|
||||
$author_text .= $this->escapeLatexText($author['first_name'] . ' ' . $author['last_name']);
|
||||
|
||||
// 获取作者的机构
|
||||
$author_organs = $this->production_article_author_to_organ_obj
|
||||
->where('p_article_author_id', $author['p_article_author_id'])
|
||||
->where('state', 0)
|
||||
->select();
|
||||
|
||||
foreach ($author_organs as $ao) {
|
||||
if (isset($organ_map[$ao['p_article_organ_id']])) {
|
||||
$author_text .= '$^{' . $organ_map[$ao['p_article_organ_id']] . '}$';
|
||||
}
|
||||
}
|
||||
|
||||
if ($author['is_report'] == 1) {
|
||||
$author_text .= '$^{*}$';
|
||||
}
|
||||
}
|
||||
|
||||
$latex .= '\author{' . $author_text . "\n";
|
||||
|
||||
// 添加机构信息
|
||||
foreach ($organs as $index => $organ) {
|
||||
$latex .= '\\\\$' . ($index + 1) . '$ ' . $this->escapeLatexText($organ['organ_name']) . "\n";
|
||||
}
|
||||
if (!empty($authors)) {
|
||||
// 查找通讯作者
|
||||
$corresponding_authors = array_filter($authors, function($author) {
|
||||
return $author['is_report'] == 1;
|
||||
});
|
||||
|
||||
if (!empty($corresponding_authors)) {
|
||||
$corr_author = reset($corresponding_authors);
|
||||
$latex .= '\\\\$*$ Corresponding author: ' .
|
||||
$this->escapeLatexText($corr_author['email']) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$latex .= '}' . "\n";
|
||||
}
|
||||
|
||||
$latex .= '\date{}' . "\n";
|
||||
$latex .= '\begin{document}' . "\n";
|
||||
$latex .= '\maketitle' . "\n";
|
||||
|
||||
// 摘要
|
||||
if (!empty($p_info['abstract'])) {
|
||||
$latex .= '\begin{abstract}' . "\n";
|
||||
$latex .= $this->escapeLatexText($p_info['abstract']) . "\n";
|
||||
$latex .= '\end{abstract}' . "\n";
|
||||
}
|
||||
|
||||
// 关键词
|
||||
if (!empty($p_info['keywords'])) {
|
||||
$latex .= '\textbf{Keywords:} ' . $this->escapeLatexText($p_info['keywords']) . "\n";
|
||||
$latex .= '\sectionbreak' . "\n";
|
||||
}
|
||||
|
||||
// 正文内容
|
||||
$in_section = false;
|
||||
$section_count = 0;
|
||||
|
||||
foreach ($main_contents as $content) {
|
||||
$text = trim($content['content']);
|
||||
|
||||
// 跳过空内容
|
||||
if (empty($text)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否是标题
|
||||
$clean_text = strip_tags($text);
|
||||
$lower_text = strtolower($clean_text);
|
||||
|
||||
// 判断是否为章节标题
|
||||
if (stripos($lower_text, 'introduction') === 0 ||
|
||||
stripos($lower_text, 'methods') === 0 ||
|
||||
stripos($lower_text, 'results') === 0 ||
|
||||
stripos($lower_text, 'discussion') === 0 ||
|
||||
stripos($lower_text, 'conclusion') === 0 ||
|
||||
stripos($lower_text, 'references') === 0) {
|
||||
|
||||
// 结束前一节
|
||||
if ($in_section) {
|
||||
$latex .= "\n" . '\sectionbreak' . "\n";
|
||||
}
|
||||
|
||||
// 开始新节
|
||||
$section_count++;
|
||||
$section_title = $this->escapeLatexText($clean_text);
|
||||
$latex .= '\section{' . $section_title . '}' . "\n";
|
||||
$in_section = true;
|
||||
}
|
||||
// 检查是否是图片或表格占位符
|
||||
else if (preg_match('/<img[^>]*imageId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $img_matches)) {
|
||||
$image_id = $img_matches[1];
|
||||
// 这里可以添加图片处理逻辑
|
||||
$latex .= '% 图片插入位置 (ID: ' . $image_id . ')' . "\n";
|
||||
$latex .= '\begin{figure}[htbp]' . "\n";
|
||||
$latex .= '\centering' . "\n";
|
||||
$latex .= '\includegraphics[width=0.8\textwidth]{image_' . $image_id . '}' . "\n";
|
||||
$latex .= '\caption{图片说明}' . "\n";
|
||||
$latex .= '\end{figure}' . "\n";
|
||||
}
|
||||
else if (preg_match('/<table[^>]*tableId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $table_matches)) {
|
||||
$table_id = $table_matches[1];
|
||||
// 这里可以添加表格处理逻辑
|
||||
$latex .= '% 表格插入位置 (ID: ' . $table_id . ')' . "\n";
|
||||
$latex .= '\begin{table}[htbp]' . "\n";
|
||||
$latex .= '\centering' . "\n";
|
||||
$latex .= '\caption{表格说明}' . "\n";
|
||||
$latex .= '\begin{tabular}{|c|c|c|}' . "\n";
|
||||
$latex .= '\hline' . "\n";
|
||||
$latex .= '列1 & 列2 & 列3 \\\\' . "\n";
|
||||
$latex .= '\hline' . "\n";
|
||||
$latex .= '% 表格数据' . "\n";
|
||||
$latex .= '\hline' . "\n";
|
||||
$latex .= '\end{tabular}' . "\n";
|
||||
$latex .= '\end{table}' . "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 普通段落文本
|
||||
else {
|
||||
// 移除HTML标签并转义特殊字符
|
||||
$plain_text = $this->escapeLatexText(strip_tags($text));
|
||||
$latex .= $plain_text . "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
// 参考文献
|
||||
if (!empty($references)) {
|
||||
$latex .= '\section*{References}' . "\n";
|
||||
$latex .= '\begin{thebibliography}{99}' . "\n";
|
||||
|
||||
foreach ($references as $index => $ref) {
|
||||
$ref_text = isset($ref['refer_frag']) ? $ref['refer_frag'] : $ref['refer_content'];
|
||||
$latex .= '\bibitem{} ' . $this->escapeLatexText($ref_text) . "\n";
|
||||
}
|
||||
|
||||
$latex .= '\end{thebibliography}' . "\n";
|
||||
}
|
||||
|
||||
$latex .= '\end{document}' . "\n";
|
||||
|
||||
return $latex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转义LaTeX特殊字符
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
private function escapeLatexText($text)
|
||||
{
|
||||
// 移除HTML标签
|
||||
$text = strip_tags($text);
|
||||
|
||||
// 转义LaTeX特殊字符
|
||||
$escape_chars = [
|
||||
'\\' => '\\textbackslash{}',
|
||||
'&' => '\\&',
|
||||
'%' => '\\%',
|
||||
'$' => '\\$',
|
||||
'#' => '\\#',
|
||||
'_' => '\\_',
|
||||
'{' => '\\{',
|
||||
'}' => '\\}',
|
||||
'~' => '\\textasciitilde{}',
|
||||
'^' => '\\textasciicircum{}',
|
||||
'"' => '\\"{}',
|
||||
'\'' => '\\\'{}',
|
||||
'<' => '\\textless{}',
|
||||
'>' => '\\textgreater{}',
|
||||
];
|
||||
|
||||
foreach ($escape_chars as $char => $replacement) {
|
||||
$text = str_replace($char, $replacement, $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -45,6 +45,12 @@ class Preaccept extends Base
|
||||
}else{
|
||||
$list[$k]['is_repeat'] = 0;
|
||||
}
|
||||
if(strpos($v['refer_content'],'retraction')!==false||strpos($v['refer_content'],'retracted')!==false){
|
||||
$list[$k]['retract'] = 1;
|
||||
}else{
|
||||
$list[$k]['retract'] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
$re["refers"] = $list;
|
||||
$re['repeat'] = empty($aRepeat) ? [] : $aRepeat;
|
||||
@@ -321,8 +327,15 @@ class Preaccept extends Base
|
||||
$insert['ami_id'] = $data['ami_id'];
|
||||
$insert['sort'] = $am_info['sort']+1;
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_obj->insert($insert);
|
||||
return jsonSuccess([]);
|
||||
//$this->article_main_obj->insert($insert);
|
||||
// return jsonSuccess([]);
|
||||
//返回更新数据 20260120 start
|
||||
$iId = $this->article_main_obj->insertGetId($insert);
|
||||
$insert = empty($insert) ? [] : array_merge($insert,['am_id' => empty($iId) ? 0 : $iId]);
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? $insert : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回更新数据 20260120 end
|
||||
}
|
||||
|
||||
public function removeImage(){
|
||||
@@ -384,8 +397,15 @@ class Preaccept extends Base
|
||||
$insert["content"] = "<table tableId='".$amt_info['amt_id']."' />";
|
||||
$insert['sort'] = $am_info['sort']+1;
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_obj->insert($insert);
|
||||
return jsonSuccess([]);
|
||||
// $this->article_main_obj->insert($insert);
|
||||
// return jsonSuccess([]);
|
||||
//返回更新数据 20260120 start
|
||||
$iId = $this->article_main_obj->insertGetId($insert);
|
||||
$insert = empty($insert) ? [] : array_merge($insert,['am_id' => empty($iId) ? 0 : $iId]);
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? $insert : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回更新数据 20260120 end
|
||||
}
|
||||
|
||||
|
||||
@@ -832,7 +852,14 @@ class Preaccept extends Base
|
||||
$this->addBRow($am_info['article_id'],$data['am_id']);
|
||||
}
|
||||
$this->article_main_obj->where("am_id",$data['am_id'])->update(["is_h1"=>1,"is_h2"=>0,"is_h3"=>0]);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回数据 20260119 start
|
||||
$am_info = empty($am_info) ? [] : array_merge($am_info,["is_h1"=>1,"is_h2"=>0,"is_h3"=>0]);
|
||||
$iId = empty($data['am_id']) ? 0 : $data['am_id'];
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? $am_info : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回数据 20260119 end
|
||||
}
|
||||
|
||||
public function changeH2(){
|
||||
@@ -850,7 +877,14 @@ class Preaccept extends Base
|
||||
$this->addBRow($am_info['article_id'],$p_list[0]['am_id']);
|
||||
}
|
||||
$this->article_main_obj->where("am_id",$data['am_id'])->update(["is_h1"=>0,"is_h2"=>1,"is_h3"=>0]);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回数据 20260119 start
|
||||
$am_info = empty($am_info) ? [] : array_merge($am_info,["is_h1"=>0,"is_h2"=>1,"is_h3"=>0]);
|
||||
$iId = empty($data['am_id']) ? 0 : $data['am_id'];
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? $am_info : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回数据 20260119 end
|
||||
}
|
||||
|
||||
public function changeH3(){
|
||||
@@ -863,7 +897,14 @@ class Preaccept extends Base
|
||||
}
|
||||
$am_info = $this->article_main_obj->where("am_id",$data['am_id'])->find();
|
||||
$this->article_main_obj->where("am_id",$data['am_id'])->update(["is_h1"=>0,"is_h2"=>0,"is_h3"=>1]);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回数据 20260119 start
|
||||
$am_info = empty($am_info) ? [] : array_merge($am_info,["is_h1"=>0,"is_h2"=>0,"is_h3"=>1]);
|
||||
$iId = empty($data['am_id']) ? 0 : $data['am_id'];
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? $am_info : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回数据 20260119 end
|
||||
}
|
||||
|
||||
public function changeNormal(){
|
||||
@@ -875,7 +916,13 @@ class Preaccept extends Base
|
||||
return jsonError($rule->getError());
|
||||
}
|
||||
$this->article_main_obj->where("am_id",$data['am_id'])->update(["is_h1"=>0,"is_h2"=>0,"is_h3"=>0]);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回数据 20260119 start
|
||||
$iId = empty($data['am_id']) ? 0 : $data['am_id'];
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? [] : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回数据 20260119 end
|
||||
}
|
||||
|
||||
public function addBlankRow(){
|
||||
@@ -892,14 +939,26 @@ class Preaccept extends Base
|
||||
}else{
|
||||
$row = 1;
|
||||
}
|
||||
// while ($row>0){
|
||||
// $this->addBRow($data['article_id'],$data['am_id']);
|
||||
// $row--;
|
||||
// }
|
||||
// return jsonSuccess([]);
|
||||
//返回添加数据 20260119 start
|
||||
$aId = [];
|
||||
while ($row>0){
|
||||
$this->addBRow($data['article_id'],$data['am_id']);
|
||||
$iId = $this->addBRow($data['article_id'],$data['am_id']);
|
||||
$row--;
|
||||
if(!empty($iId)){
|
||||
$aId[] = $iId;
|
||||
}
|
||||
}
|
||||
return jsonSuccess([]);
|
||||
$aResult = $this->_getRowInfo($aId);
|
||||
$aResult = empty($aResult) ? $aId : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回添加数据 20260119 end
|
||||
}
|
||||
|
||||
|
||||
/**添加批量主体内容
|
||||
* @return \think\response\Json
|
||||
* @throws \think\Exception
|
||||
@@ -926,15 +985,32 @@ class Preaccept extends Base
|
||||
$this->article_main_obj->where("article_id",$data['article_id'])->where("sort",">",$r['sort'])->inc("sort",count($data['rows']))->update();
|
||||
$sort = $r['sort']+1;
|
||||
}
|
||||
// foreach ($data['rows'] as $v){
|
||||
// $insert['article_id'] = $data['article_id'];
|
||||
// $insert['content'] = $v;
|
||||
// $insert['sort'] = $sort;
|
||||
// $insert['ctime'] = time();
|
||||
// $this->article_main_obj->insert($insert);
|
||||
// $sort++;
|
||||
// }
|
||||
// return jsonSuccess([]);
|
||||
|
||||
//返回数组数据 20260119 start
|
||||
$aInsert = [];
|
||||
foreach ($data['rows'] as $v){
|
||||
$insert['article_id'] = $data['article_id'];
|
||||
$insert['content'] = $v;
|
||||
$insert['sort'] = $sort;
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_obj->insert($insert);
|
||||
$iId = $this->article_main_obj->insertGetId($insert);
|
||||
$sort++;
|
||||
$aInsert[] = empty($iId) ? $insert : array_merge($insert,['am_id' => $iId]);
|
||||
}
|
||||
return jsonSuccess([]);
|
||||
$aId = empty($aInsert) ? [] : array_column($aInsert, 'am_id');
|
||||
$aResult = $this->_getRowInfo($aId);
|
||||
$aResult = empty($aResult) ? $aInsert : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回数组数据 20260119 end
|
||||
}
|
||||
|
||||
|
||||
@@ -945,7 +1021,10 @@ class Preaccept extends Base
|
||||
$insert['content'] = "";
|
||||
$insert['sort'] = 1;
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_obj->insert($insert);
|
||||
// $this->article_main_obj->insert($insert);
|
||||
//返回主键ID 0119 start
|
||||
return $this->article_main_obj->insertGetId($insert);
|
||||
//返回主键ID 0119 end
|
||||
}else{
|
||||
$am_info = $this->article_main_obj->where("am_id",$am_id)->find();
|
||||
$this->article_main_obj->where("article_id",$article_id)->where("sort",">",$am_info['sort'])->inc("sort",1)->update();
|
||||
@@ -953,7 +1032,10 @@ class Preaccept extends Base
|
||||
$insert['content'] = "";
|
||||
$insert['sort'] = $am_info['sort']+1;
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_obj->insert($insert);
|
||||
// $this->article_main_obj->insert($insert);
|
||||
//返回主键ID 0119 start
|
||||
return $this->article_main_obj->insertGetId($insert);
|
||||
//返回主键ID 0119 end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,7 +1145,14 @@ class Preaccept extends Base
|
||||
$update['content'] = $this->formatMain($data['content']);
|
||||
$update['state'] = 0;
|
||||
$this->article_main_obj->where("am_id",$data['am_id'])->update($update);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回更新数据 20260119 start
|
||||
$update = empty($update) ? [] : array_merge($update,['am_id' => empty($data['am_id']) ? 0 : $data['am_id']]);
|
||||
$iId = empty($data['am_id']) ? 0 : $data['am_id'];
|
||||
$aResult = $this->_getMainRow($iId);
|
||||
$aResult = empty($aResult) ? $update : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回更新数据 20260119 end
|
||||
}
|
||||
|
||||
public function getArticleMainsRecycle(){
|
||||
@@ -1099,11 +1188,18 @@ class Preaccept extends Base
|
||||
$insert['title'] = $data['title'];
|
||||
}
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_image_obj->insert($insert);
|
||||
$re['url'] = $data['url'];
|
||||
// $this->article_main_image_obj->insert($insert);
|
||||
// $re['url'] = $data['url'];
|
||||
|
||||
|
||||
return jsonSuccess($re);
|
||||
// return jsonSuccess($re);
|
||||
//返回新增数据 20260119 start
|
||||
$iId = $this->article_main_image_obj->insertGetId($insert);
|
||||
$insert = empty($iId) ? $insert : array_merge(['ami_id' => $iId],$insert);
|
||||
$aResult = $this->_getImageInfo($iId);
|
||||
$aResult = empty($aResult) ? $insert : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回新增数据 20260119 end
|
||||
}
|
||||
|
||||
public function editMainImage(){
|
||||
@@ -1119,7 +1215,18 @@ class Preaccept extends Base
|
||||
$update['note'] = isset($data['note'])?$data['note']:"";
|
||||
$update['title'] = isset($data['title'])?$data['title']:"";
|
||||
$this->article_main_image_obj->where("ami_id",$data['ami_id'])->update($update);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回修改数据 20260119 start
|
||||
$update = empty($update) ? [] : array_merge(['ami_id' => empty($data['ami_id']) ? 0 : $data['ami_id']],$update);
|
||||
$iId = empty($data['ami_id']) ? 0 : $data['ami_id'];
|
||||
$aResult = $this->_getImageInfo($iId);
|
||||
$aResult = empty($aResult) ? $update : $aResult;
|
||||
if(!empty($aResult['main'])){
|
||||
$aResultInfo = $this->_getMainRow(0,$aResult['main']);
|
||||
$aResult = empty($aResultInfo) ? $aResult : $aResultInfo;
|
||||
}
|
||||
return jsonSuccess($aResult);
|
||||
//返回新增数据 20260119 end
|
||||
}
|
||||
|
||||
public function addMainTable(){
|
||||
@@ -1144,9 +1251,15 @@ class Preaccept extends Base
|
||||
$insert['note'] = $data['note'];
|
||||
}
|
||||
$insert['ctime'] = time();
|
||||
$this->article_main_table_obj->insert($insert);
|
||||
return jsonSuccess([]);
|
||||
|
||||
// $this->article_main_table_obj->insert($insert);
|
||||
// return jsonSuccess([]);
|
||||
//返回新增数据 20260119 start
|
||||
$iId = $this->article_main_table_obj->insertGetId($insert);
|
||||
$insert = empty($iId) ? $insert : array_merge(['amt_id' => $iId],$insert);
|
||||
$aResult = $this->_getTableInfo($iId);
|
||||
$aResult = empty($aResult) ? $insert : $aResult;
|
||||
return jsonSuccess($aResult);
|
||||
//返回新增数据 20260119 end
|
||||
}
|
||||
|
||||
|
||||
@@ -1168,7 +1281,18 @@ class Preaccept extends Base
|
||||
$update['note'] = $data['note'];
|
||||
}
|
||||
$this->article_main_table_obj->where("amt_id",$data['amt_id'])->update($update);
|
||||
return jsonSuccess([]);
|
||||
// return jsonSuccess([]);
|
||||
//返回修改数据 20260119 start
|
||||
$update = empty($update) ? [] : array_merge(['amt_id' => empty($data['amt_id']) ? 0 : $data['amt_id']],$update);
|
||||
$iId = empty($data['amt_id']) ? 0 : $data['amt_id'];
|
||||
$aResult = $this->_getTableInfo($iId);
|
||||
$aResult = empty($aResult) ? $update : $aResult;
|
||||
if(!empty($aResult['main'])){
|
||||
$aResultInfo = $this->_getMainRow(0,$aResult['main']);
|
||||
$aResult = empty($aResultInfo) ? $aResult : $aResultInfo;
|
||||
}
|
||||
return jsonSuccess($aResult);
|
||||
//返回新增数据 20260119 end
|
||||
}
|
||||
|
||||
|
||||
@@ -1549,12 +1673,14 @@ return null;
|
||||
}
|
||||
|
||||
foreach ($item as $k => $main) {
|
||||
if($main['is_h1']==1){
|
||||
$main['content'] = "<b><i>".$main['content']."</i></b>";
|
||||
}
|
||||
if($main['is_h2']==1||$main['is_h3']==1){
|
||||
$main['content'] = "<b>".$main['content']."</b>";
|
||||
}
|
||||
//取消一级/二级/三级 标题样式 20260119 start
|
||||
// if($main['is_h1']==1){
|
||||
// $main['content'] = "<b><i>".$main['content']."</i></b>";
|
||||
// }
|
||||
// if($main['is_h2']==1||$main['is_h3']==1){
|
||||
// $main['content'] = "<b>".$main['content']."</b>";
|
||||
// }
|
||||
//取消一级/二级/三级 标题样式 20260119 end
|
||||
$main['checks'] = empty($aMainCheckData[$main['am_id']]) ? [] : $aMainCheckData[$main['am_id']];
|
||||
if($main['type'] == 1){
|
||||
$main['image'] = empty($aArticleMainImage[$main['ami_id']]) ? [] : $aArticleMainImage[$main['ami_id']];
|
||||
@@ -1743,4 +1869,175 @@ return null;
|
||||
return jsonSuccess([]);
|
||||
}
|
||||
|
||||
//获取多条信息
|
||||
private function _getRowInfo($aId = []){
|
||||
if(empty($aId)){
|
||||
return [];
|
||||
}
|
||||
//获取信息
|
||||
$aWhere = ['am_id' => ['in',$aId],'state' => 0];
|
||||
$aArticleMain = Db::name("article_main")->where($aWhere)->order("sort asc")->select();
|
||||
if(empty($aArticleMain)){
|
||||
return [];
|
||||
}
|
||||
//获取主键ID
|
||||
$aMId = array_column($aArticleMain, 'am_id');
|
||||
//查询article_main_check
|
||||
$aWhere = ['am_id' => ['in',$aMId],'state' => 0];
|
||||
$aMainCheck = Db::name("article_main_check")->where($aWhere)->select();
|
||||
$aMainCheckData = [];
|
||||
if(!empty($aMainCheck)){
|
||||
foreach ($aMainCheck as $value) {
|
||||
if(empty($value['am_id'])){
|
||||
continue;
|
||||
}
|
||||
$aMainCheckData[$value['am_id']][] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
//获取图片信息
|
||||
$aMiId = array_unique(array_column($aArticleMain, 'ami_id'));
|
||||
$aWhere = ['ami_id' => ['in',$aMiId],'state' => 0];
|
||||
$aArticleMainImage = Db::name("article_main_image")->where($aWhere)->select();
|
||||
$aArticleMainImage = empty($aArticleMainImage) ? [] : array_column($aArticleMainImage, null,'ami_id');
|
||||
//获取表格信息
|
||||
$aMiId = array_unique(array_column($aArticleMain, 'amt_id'));
|
||||
$aWhere = ['amt_id' => ['in',$aMiId],'state' => 0];
|
||||
$aArticleMainTable = Db::name("article_main_table")->where($aWhere)->select();
|
||||
$aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
|
||||
|
||||
//查询校对数量 t_article_proofread
|
||||
$aWhere = ['am_id' => ['in',$aMId],'state' => ['between',[1,2]],'is_delete' => 2];
|
||||
$aArticleProofread = Db::name("article_proofread")->field('am_id,count(id) as num,state')->where($aWhere)->group('am_id,state')->select();
|
||||
$aArticleProofreadData = [];
|
||||
if(!empty($aArticleProofread)){
|
||||
foreach ($aArticleProofread as $key => $value) {
|
||||
$aArticleProofreadData[$value['am_id']][$value['state']] = $value['num'];
|
||||
}
|
||||
}
|
||||
|
||||
//数据处理
|
||||
foreach ($aArticleMain as $k => $main) {
|
||||
$aArticleMain[$k]['checks'] = empty($aMainCheckData[$main['am_id']]) ? [] : $aMainCheckData[$main['am_id']];
|
||||
if($main['type'] == 1){
|
||||
$aArticleMain[$k]['image'] = empty($aArticleMainImage[$main['ami_id']]) ? [] : $aArticleMainImage[$main['ami_id']];
|
||||
}
|
||||
if($main['type'] == 2){
|
||||
$aArticleMain[$k]['table'] = empty($aArticleMainTable[$main['amt_id']]) ? [] : $aArticleMainTable[$main['amt_id']];
|
||||
}
|
||||
if($main['type'] == 0){
|
||||
$aDataInfo = empty($aArticleProofreadData[$main['am_id']]) ? [] : $aArticleProofreadData[$main['am_id']];
|
||||
$main['proof_read_num'] = -1;
|
||||
if(!empty($aDataInfo)){
|
||||
$main['proof_read_num'] = empty($aDataInfo[2]) ? 0 : $aDataInfo[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aArticleMain;
|
||||
}
|
||||
//获取图片信息
|
||||
private function _getImageInfo($iAmiId = 0){
|
||||
if(empty($iAmiId)){
|
||||
return [];
|
||||
}
|
||||
|
||||
//获取图片信息
|
||||
$aWhere = ['ami_id' => $iAmiId,'state' => 0];
|
||||
$aArticleMainImage = Db::name("article_main_image")->where($aWhere)->find();
|
||||
if(empty($aArticleMainImage)){
|
||||
return [];
|
||||
}
|
||||
$iArticleId = empty($aArticleMainImage['article_id']) ? 0 : $aArticleMainImage['article_id'];
|
||||
//获取表信息
|
||||
$aWhere = ['ami_id' => $iAmiId,'state' => 0,'type' => 1,'article_id' => $iArticleId];
|
||||
$aArticleMain = Db::name("article_main")->where($aWhere)->find();
|
||||
//数据处理
|
||||
$aArticleMainImage['has_selected'] = empty($aArticleMain) ? 0 : 1;
|
||||
if(!empty($aArticleMain)){
|
||||
$aArticleMainImage['main'] = $aArticleMain;
|
||||
}
|
||||
return $aArticleMainImage;
|
||||
}
|
||||
//获取表格信息
|
||||
private function _getTableInfo($iAmtId = 0){
|
||||
if(empty($iAmtId)){
|
||||
return [];
|
||||
}
|
||||
|
||||
//获取图片信息
|
||||
$aWhere = ['amt_id' => $iAmtId,'state' => 0];
|
||||
$aArticleMainTable = Db::name("article_main_table")->where($aWhere)->find();
|
||||
if(empty($aArticleMainTable)){
|
||||
return [];
|
||||
}
|
||||
$iArticleId = empty($aArticleMainTable['article_id']) ? 0 : $aArticleMainTable['article_id'];
|
||||
//获取表信息
|
||||
$aWhere = ['amt_id' => $iAmtId,'state' => 0,'type' => 2,'article_id' => $iArticleId];
|
||||
$aArticleMain = Db::name("article_main")->where($aWhere)->find();
|
||||
//数据处理
|
||||
$aArticleMainTable['has_selected'] = empty($aArticleMain) ? 0 : 1;
|
||||
if(!empty($aArticleMain)){
|
||||
$aArticleMainTable['main'] = $aArticleMain;
|
||||
}
|
||||
return $aArticleMainTable;
|
||||
}
|
||||
//获取单独的一条信息
|
||||
private function _getMainRow($iId = 0,$aArticleMain = []){
|
||||
if(empty($iId) && empty($aArticleMain)){
|
||||
return [];
|
||||
}
|
||||
//获取基本信息
|
||||
if(empty($aArticleMain)){
|
||||
$aWhere = ['am_id' => $iId,'state' => 0];
|
||||
$aArticleMain = Db::name("article_main")->where($aWhere)->find();
|
||||
}
|
||||
if(empty($aArticleMain)){
|
||||
return [];
|
||||
}
|
||||
//获取主键ID
|
||||
$iId = empty($aArticleMain['am_id']) ? 0 : $aArticleMain['am_id'];
|
||||
//查询article_main_check
|
||||
$aWhere = ['am_id' => $iId,'state' => 0];
|
||||
$aMainCheck = Db::name("article_main_check")->where($aWhere)->select();
|
||||
|
||||
//获取主体信息
|
||||
$iType = isset($aArticleMain['type']) ? $aArticleMain['type'] : -1;
|
||||
if($iType == 1){//获取图片
|
||||
$iAmiId = empty($aArticleMain['ami_id']) ? 0 : $aArticleMain['ami_id'];
|
||||
$aWhere = ['ami_id' => $iAmiId,'state' => 0];
|
||||
$aArticleMainImage = Db::name("article_main_image")->where($aWhere)->find();
|
||||
}
|
||||
//获取表格信息
|
||||
if($iType == 2){
|
||||
$iAmtId = empty($aArticleMain['amt_id']) ? 0 : $aArticleMain['amt_id'];
|
||||
$aWhere = ['amt_id' => $iAmtId,'state' => 0];
|
||||
$aArticleMainTable = Db::name("article_main_table")->where($aWhere)->find();
|
||||
}
|
||||
//查询校对数量 t_article_proofread
|
||||
$aWhere = ['am_id' => $iId,'state' => ['between',[1,2]],'is_delete' => 2];
|
||||
$aArticleProofread = Db::name("article_proofread")->field('am_id,count(id) as num,state')->where($aWhere)->group('state')->select();
|
||||
$aArticleProofreadData = [];
|
||||
if(!empty($aArticleProofread)){
|
||||
foreach ($aArticleProofread as $key => $value) {
|
||||
$aArticleProofreadData[$value['state']] = $value['num'];
|
||||
}
|
||||
}
|
||||
|
||||
//数据处理
|
||||
$aArticleMain['checks'] = empty($aMainCheckData) ? [] : $aMainCheckData;
|
||||
if($iType == 1){
|
||||
$aArticleMain['image'] = empty($aArticleMainImage) ? [] : $aArticleMainImage;
|
||||
}
|
||||
if($iType == 2){
|
||||
$aArticleMain['table'] = empty($aArticleMainTable) ? [] : $aArticleMainTable;
|
||||
}
|
||||
if($iType == 0){
|
||||
$aDataInfo = empty($aArticleProofreadData) ? [] : $aArticleProofreadData;
|
||||
$aArticleMain['proof_read_num'] = -1;
|
||||
if(!empty($aDataInfo)){
|
||||
$aArticleMain['proof_read_num'] = empty($aDataInfo[2]) ? 0 : $aDataInfo[2];
|
||||
}
|
||||
}
|
||||
return $aArticleMain;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2242,7 +2242,7 @@ class Reviewer extends Base
|
||||
$aReviewerCompany = [];
|
||||
if(!empty($aUserId)){
|
||||
//作者同机构的审稿人
|
||||
$aReviewerCompany = Db::name('user_reviewer_info')->where(['reviewer_id' => ['in',$aUserId],'state' => 0])->column('reviewer_id,company');
|
||||
$aReviewerCompany = Db::name('user_reviewer_info')->where(['reviewer_id' => ['in',$aUserId],'state' => 0,'company' => ['<>','']])->column('reviewer_id,company');
|
||||
}
|
||||
|
||||
//文章作者机构信息
|
||||
@@ -2277,7 +2277,12 @@ class Reviewer extends Base
|
||||
|
||||
//过滤审稿人机构
|
||||
if(!empty($aAuthorCompany)){
|
||||
$where['t_user_reviewer_info.company'] = ['not in', $aAuthorCompany];
|
||||
$aAuthorCompany = array_filter($aAuthorCompany, function($v) {
|
||||
return trim((string)$v) !== '';
|
||||
});
|
||||
if(!empty($aAuthorCompany)){
|
||||
$where['t_user_reviewer_info.company'] = ['not in', $aAuthorCompany];
|
||||
}
|
||||
}
|
||||
// 计算10天之后的时间戳(10天 = 10 * 24 * 60 * 60秒)
|
||||
$iTeenDaysLater = strtotime('-10 days');
|
||||
@@ -2292,6 +2297,7 @@ class Reviewer extends Base
|
||||
->whereOr('t_user_reviewer_info.last_invite_time', '=', 0);
|
||||
})
|
||||
->count();
|
||||
|
||||
if(empty($count)){
|
||||
return jsonSuccess(['reviewers' => [],'count' => 0]);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class Supplementary extends Base
|
||||
public function getJournalBoard(){
|
||||
|
||||
|
||||
//获取参数
|
||||
//获取参数
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//参数验证
|
||||
@@ -38,17 +38,17 @@ class Supplementary extends Base
|
||||
$aWhere = ['state' => 0,'issn' => ['in',$sIssn]];
|
||||
$aJournal = Db::name('journal')->where($aWhere)->column('journal_id,issn');
|
||||
if(empty($aJournal)){
|
||||
return json_encode(['status' => 3,'msg' => 'No journal information found']);
|
||||
return json_encode(['status' => 3,'msg' => 'No journal information found']);
|
||||
}
|
||||
|
||||
//查询期刊编辑信息
|
||||
$aWhere = ['state' => 0,'journal_id' => ['in',array_keys($aJournal)]];
|
||||
if(isset($aParam['type'])){//编辑类型
|
||||
$aWhere['type'] = $aParam['type'];
|
||||
$aWhere['type'] = $aParam['type'];
|
||||
}
|
||||
$aJournalBoard = Db::name('board_to_journal')->field('journal_id,user_id')->where($aWhere)->select();
|
||||
if(empty($aJournalBoard)){
|
||||
return json_encode(['status' => 4,'msg' => 'No editorial information was found for the journal']);
|
||||
return json_encode(['status' => 4,'msg' => 'No editorial information was found for the journal']);
|
||||
}
|
||||
|
||||
//查询编辑详情
|
||||
@@ -62,10 +62,73 @@ class Supplementary extends Base
|
||||
continue;
|
||||
}
|
||||
$sRealName = empty($aUser[$value['user_id']]) ? '' : $aUser[$value['user_id']];
|
||||
if(!empty($sRealName) && strlen($sRealName) >= 3 && substr($sRealName, 0, 3) === "\xEF\xBB\xBF") {
|
||||
$sRealName = substr($sRealName, 3);
|
||||
}
|
||||
$aUserData[$sIssn][] = $sRealName;
|
||||
}
|
||||
return json_encode(['status' => 1,'msg' => 'success','data' => $aUserData]);
|
||||
}
|
||||
return json_encode(['status' => 1,'msg' => 'success','data' => $aUserData]);
|
||||
}
|
||||
/**
|
||||
* @title 获取文章底部信息
|
||||
* @description 获取期刊编辑接口
|
||||
*/
|
||||
public function getProductiArticleFooter(){
|
||||
|
||||
$aParam = $this->request->post();
|
||||
|
||||
//官网文章ID
|
||||
$iWarticleId = empty($aParam['w_article_id']) ? 0 : $aParam['w_article_id'];
|
||||
if(empty($iWarticleId)){
|
||||
return json_encode(['status' => 2,'msg' => 'Please select an article']);
|
||||
}
|
||||
|
||||
//获取子刊信息
|
||||
$aJournalStage = empty($aParam['journal_stage']) ? [] : $aParam['journal_stage'];
|
||||
|
||||
//查询文章生产信息
|
||||
$aWhere = ['w_article_id' => $iWarticleId,'state' => ['in',[0,2]]];
|
||||
$aProductionArticle = Db::name('production_article')->field('p_article_id,article_id,journal_stage_id,journal_id,title,type,acknowledgment,abbreviation,author_contribution,abbr,npp,doi,executive_editor')->where($aWhere)->find();
|
||||
if(empty($aProductionArticle)){
|
||||
return json_encode(['status' => 3,'msg' => 'No production article information found']);
|
||||
}
|
||||
|
||||
//查询期刊信息
|
||||
$iJournalId = empty($aProductionArticle['journal_id']) ? 0 : $aProductionArticle['journal_id'];
|
||||
$aJournal = [];
|
||||
if(!empty($iJournalId)){
|
||||
$aWhere = ['journal_id' => $iJournalId,'state' => 0];
|
||||
$aJournal = Db::name('journal')->field('jabbr,title')->where($aWhere)->find();
|
||||
}
|
||||
//获取文章时间/编委信息
|
||||
$iArticleId = empty($aProductionArticle['article_id']) ? 0 : $aProductionArticle['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
return json_encode(['status' => 3,'msg' => 'No article information found']);
|
||||
}
|
||||
$oLatexContent = new \app\common\LatexContent;
|
||||
$aTime = $oLatexContent->getArticleTime(['article_id' => $iArticleId]);
|
||||
$aProductionArticle = empty($aTime['data']) ? $aProductionArticle : array_merge($aTime['data'],$aProductionArticle);
|
||||
|
||||
//获取期刊引用信息
|
||||
$sCite = $this->_cite($aProductionArticle,$aJournal,$aJournalStage);
|
||||
$aProductionArticle['article_cite'] = empty($sCite) ? '' : $sCite;
|
||||
$aProductionArticle['journal_title'] = empty($aJournal['title']) ? '' : $aJournal['title'];
|
||||
return json_encode(['status' => 1,'data' => $aProductionArticle]);
|
||||
}
|
||||
//处理期刊引用信息
|
||||
private function _cite($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'];
|
||||
|
||||
$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'];
|
||||
} else {
|
||||
$sCite = $aArticle['abbr'] . '. ' . $aArticle['title'] . '. <i>' . choiseJabbr($aArticle['article_id'], $jabbr) . '</i>. ' . $stage_year . ';' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
|
||||
}
|
||||
return $sCite;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -199,48 +199,48 @@ class Typeset extends Base
|
||||
/**
|
||||
* 推送文章到官网系统
|
||||
*/
|
||||
public function pushArticleToSystem(){
|
||||
die('Service suspension!');
|
||||
$data = $this->request->post();
|
||||
$rule = new Validate([
|
||||
'on_id'=>'require'
|
||||
]);
|
||||
if(!$rule->check($data)){
|
||||
return jsonError($rule->getError());
|
||||
}
|
||||
$on_info = $this->online_obj->where('on_id',$data['on_id'])->find();
|
||||
$ts_info = $this->ts_obj->where('article_id',$on_info['article_id'])->where('ts_state',0)->find();
|
||||
$article_info = $this->article_obj->where('article_id',$on_info['article_id'])->find();
|
||||
$journal_info = $this->journal_obj->where('journal_id',$article_info['journal_id'])->find();
|
||||
$authors = $this->article_author_obj->where('article_id',$article_info['article_id'])->where('state',0)->select();
|
||||
//check信息是否完整
|
||||
if($on_info['journal_stage_id']==''||$on_info['on_doi']==''||$on_info['abstract']==''||$on_info['npp']==''){
|
||||
return jsonError('信息不全!');
|
||||
}
|
||||
//发送推送请求
|
||||
// $url = "http://www.journal.com/master/Article/addArticleForSubmission";
|
||||
$url = 'http://journalapi.tmrjournals.com/public/index.php/master/Article/addArticleForSubmission';
|
||||
$pra = [];
|
||||
$pra['title'] = $ts_info['ts_title'];
|
||||
$pra['journal_stage_id'] = $on_info['journal_stage_id'];
|
||||
$pra['issn'] = $journal_info['issn'];
|
||||
$pra['type'] = translateType($article_info['type']);
|
||||
$pra['doi'] = $on_info['on_doi'];
|
||||
$pra['abstract'] = $on_info['abstract'];
|
||||
$pra['pub_date'] = $ts_info['online_date'];
|
||||
$pra['file_pdf'] = $article_info['pdf_url'];
|
||||
$pra['keywords'] = $ts_info['keywords'];
|
||||
$pra['npp'] = $on_info['npp'];
|
||||
$pra['authors'] = json_encode($authors);
|
||||
|
||||
$res = object_to_array(json_decode(myPost($url, $pra)));
|
||||
if($res['code']==0){
|
||||
$this->online_obj->where('on_id',$data['on_id'])->update(['has_push'=>1]);
|
||||
return jsonSuccess([]);
|
||||
}else{
|
||||
return jsonError('system error:'.$res['msg']);
|
||||
}
|
||||
}
|
||||
// public function pushArticleToSystem(){
|
||||
// die('Service suspension!');
|
||||
// $data = $this->request->post();
|
||||
// $rule = new Validate([
|
||||
// 'on_id'=>'require'
|
||||
// ]);
|
||||
// if(!$rule->check($data)){
|
||||
// return jsonError($rule->getError());
|
||||
// }
|
||||
// $on_info = $this->online_obj->where('on_id',$data['on_id'])->find();
|
||||
// $ts_info = $this->ts_obj->where('article_id',$on_info['article_id'])->where('ts_state',0)->find();
|
||||
// $article_info = $this->article_obj->where('article_id',$on_info['article_id'])->find();
|
||||
// $journal_info = $this->journal_obj->where('journal_id',$article_info['journal_id'])->find();
|
||||
// $authors = $this->article_author_obj->where('article_id',$article_info['article_id'])->where('state',0)->select();
|
||||
// //check信息是否完整
|
||||
// if($on_info['journal_stage_id']==''||$on_info['on_doi']==''||$on_info['abstract']==''||$on_info['npp']==''){
|
||||
// return jsonError('信息不全!');
|
||||
// }
|
||||
// //发送推送请求
|
||||
// // $url = "http://www.journal.com/master/Article/addArticleForSubmission";
|
||||
// $url = 'http://journalapi.tmrjournals.com/public/index.php/master/Article/addArticleForSubmission';
|
||||
// $pra = [];
|
||||
// $pra['title'] = $ts_info['ts_title'];
|
||||
// $pra['journal_stage_id'] = $on_info['journal_stage_id'];
|
||||
// $pra['issn'] = $journal_info['issn'];
|
||||
// $pra['type'] = translateType($article_info['type']);
|
||||
// $pra['doi'] = $on_info['on_doi'];
|
||||
// $pra['abstract'] = $on_info['abstract'];
|
||||
// $pra['pub_date'] = $ts_info['online_date'];
|
||||
// $pra['file_pdf'] = $article_info['pdf_url'];
|
||||
// $pra['keywords'] = $ts_info['keywords'];
|
||||
// $pra['npp'] = $on_info['npp'];
|
||||
// $pra['authors'] = json_encode($authors);
|
||||
//
|
||||
// $res = object_to_array(json_decode(myPost($url, $pra)));
|
||||
// if($res['code']==0){
|
||||
// $this->online_obj->where('on_id',$data['on_id'])->update(['has_push'=>1]);
|
||||
// return jsonSuccess([]);
|
||||
// }else{
|
||||
// return jsonError('system error:'.$res['msg']);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 编辑online信息
|
||||
|
||||
@@ -36,7 +36,7 @@ class Workbench extends Base
|
||||
//获取状态
|
||||
$iState = isset($aParam['state']) ? $aParam['state'] : -2;
|
||||
//空的查询条件
|
||||
$aWhere = [];
|
||||
$aWhere = ['accept_sn' => ['not like','Draft%']];
|
||||
//SN
|
||||
$sAcceptSn = empty($aParam['accept_sn']) ? '': $aParam['accept_sn'];
|
||||
if(!empty($sAcceptSn)){
|
||||
@@ -181,6 +181,10 @@ class Workbench extends Base
|
||||
$aArticle[$key]['report'] = $aAuthorInfo;
|
||||
$aArticle[$key]['country'] = empty($aAuthorInfo) ? [] : array_unique(array_column($aAuthorInfo, 'country'));
|
||||
$aArticle[$key]['type_name'] = translateType($value['type']);
|
||||
$aArticle[$key]['is_draft'] = 2;
|
||||
if(!empty($value['accept_sn']) && substr($value['accept_sn'], 0, 5) === 'Draft'){
|
||||
$aArticle[$key]['is_draft'] = 1;
|
||||
}
|
||||
|
||||
// //付款信息
|
||||
// $iPsId = empty($aOrder[$value['article_id']]) ? 0 : $aOrder[$value['article_id']];
|
||||
@@ -452,6 +456,12 @@ class Workbench extends Base
|
||||
$aArticleReviewer['realname'] = empty($aUser['realname']) ? '' : $aUser['realname'];
|
||||
$aArticleReviewer['email'] = empty($aUser['email']) ? '' : $aUser['email'];
|
||||
}
|
||||
//查询审稿人机构
|
||||
if(!empty($aUser)){
|
||||
$aWhere = ['reviewer_id' => $iUserId,'state' => 0];
|
||||
$aReviewerInfo = Db::name('user_reviewer_info')->field('company')->where($aWhere)->find();
|
||||
$aArticleReviewer['company'] = empty($aReviewerInfo['company']) ? '' : $aReviewerInfo['company'];
|
||||
}
|
||||
|
||||
//组装信息
|
||||
$aData = ['article' => $aArticle,'article_reviewer' => $aArticleReviewer];
|
||||
@@ -641,13 +651,31 @@ class Workbench extends Base
|
||||
|
||||
//查询审稿记录
|
||||
$aWhere = ['art_rev_id' => $iArtRevId];
|
||||
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,article_id,state')->where($aWhere)->find();
|
||||
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,article_id,state,agree_review_time,ctime')->where($aWhere)->find();
|
||||
if(empty($aArticleReviewer)){
|
||||
return json_encode(['status' => 4,'msg' => 'Review record does not exist']);
|
||||
}
|
||||
if($aArticleReviewer['state'] != 4){
|
||||
if($aArticleReviewer['state'] != 4 && $aArticleReviewer['state'] != 0){
|
||||
return json_encode(['status' => 5,'msg' => 'The review link has not expired and no application is required']);
|
||||
}
|
||||
if($aArticleReviewer['state'] == 0){
|
||||
$iCtime = empty($aArticleReviewer['ctime']) ? 0 : $aArticleReviewer['ctime'];
|
||||
$iTime = empty($aArticleReviewer['agree_review_time']) ? 0 : $aArticleReviewer['agree_review_time'];
|
||||
$iTime = empty($iTime) ? intval($iCtime) : intval($iTime);
|
||||
if (!is_numeric($iTime) || (int)$iTime <= 0) {
|
||||
return json_encode(['status' => 12,'msg' => 'Invalid record time, the review period has expired']);
|
||||
}
|
||||
//判断是否超过14天
|
||||
// 14天 = 14*24*3600 秒 = 1209600 秒
|
||||
$iNowTime = strtotime(date('Y-m-d', time()));
|
||||
$iFourteenDays = 14 * 24 * 3600;
|
||||
$iTime = date('Y-m-d', $iTime);
|
||||
$iTime = strtotime($iTime);//同意审稿时间戳
|
||||
$timeDiff = $iTime+$iFourteenDays;
|
||||
if($timeDiff >= $iNowTime){
|
||||
return json_encode(['status' => 13,'msg' => 'The review link has not expired and no application is required']);
|
||||
}
|
||||
}
|
||||
|
||||
//获取文章信息
|
||||
$aWhere = ['article_id' => $aArticleReviewer['article_id']];
|
||||
@@ -659,9 +687,6 @@ class Workbench extends Base
|
||||
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' ));
|
||||
@@ -688,7 +713,7 @@ class Workbench extends Base
|
||||
$aUser = array_column($aUser, null,'user_id');
|
||||
|
||||
//更新审稿人重新申请状态为
|
||||
$aWhere = ['art_rev_id' => $iArtRevId,'state' => 4];
|
||||
$aWhere = ['art_rev_id' => $iArtRevId];
|
||||
$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' ));
|
||||
@@ -721,7 +746,8 @@ class Workbench extends Base
|
||||
|
||||
//发邮件
|
||||
//邮箱
|
||||
$email = empty($aUser[$iUserId]['email']) ? '' : $aUser[$iUserId]['email'];
|
||||
// $email = empty($aUser[$iUserId]['email']) ? '' : $aUser[$iUserId]['email'];
|
||||
$email = empty($aJournal['email']) ? '' : $aJournal['email'];
|
||||
if(empty($email)){
|
||||
return json_encode(['status' => 8,'msg' => 'Edit email as empty']);
|
||||
}
|
||||
@@ -775,14 +801,34 @@ class Workbench extends Base
|
||||
|
||||
//查询审稿记录
|
||||
$aWhere = ['art_rev_id' => $iArtRevId];
|
||||
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,article_id,state')->where($aWhere)->find();
|
||||
$aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,reviewer_id,article_id,state,ctime,agree_review_time')->where($aWhere)->find();
|
||||
if(empty($aArticleReviewer)){
|
||||
return json_encode(['status' => 4,'msg' => 'Review record does not exist']);
|
||||
}
|
||||
if($aArticleReviewer['state'] != 4){
|
||||
// if($aArticleReviewer['state'] != 4){
|
||||
// return json_encode(['status' => 5,'msg' => 'The review link has not expired and no application is required']);
|
||||
// }
|
||||
if($aArticleReviewer['state'] != 4 && $aArticleReviewer['state'] != 0){
|
||||
return json_encode(['status' => 5,'msg' => 'The review link has not expired and no application is required']);
|
||||
}
|
||||
|
||||
if($aArticleReviewer['state'] == 0){
|
||||
$iCtime = empty($aArticleReviewer['ctime']) ? 0 : $aArticleReviewer['ctime'];
|
||||
$iTime = empty($aArticleReviewer['agree_review_time']) ? 0 : $aArticleReviewer['agree_review_time'];
|
||||
$iTime = empty($iTime) ? intval($iCtime) : intval($iTime);
|
||||
if (!is_numeric($iTime) || (int)$iTime <= 0) {
|
||||
return json_encode(['status' => 12,'msg' => 'Invalid record time, the review period has expired']);
|
||||
}
|
||||
//判断是否超过14天
|
||||
$iNowTime = strtotime(date('Y-m-d', time()));
|
||||
// 14天 = 14*24*3600 秒 = 1209600 秒
|
||||
$iFourteenDays = 14 * 24 * 3600;
|
||||
$iTime = date('Y-m-d', $iTime);
|
||||
$iTime = strtotime($iTime);//同意审稿时间戳
|
||||
$timeDiff = $iTime+$iFourteenDays;
|
||||
if($timeDiff >= $iNowTime){
|
||||
return json_encode(['status' => 13,'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();
|
||||
@@ -793,9 +839,6 @@ class Workbench extends Base
|
||||
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' ));
|
||||
@@ -807,18 +850,30 @@ class Workbench extends Base
|
||||
}
|
||||
|
||||
//判断编辑的操作权限
|
||||
$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' ));
|
||||
}
|
||||
// $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]);
|
||||
$aWhere = ['art_rev_id' => $iArtRevId];
|
||||
$aUpdate = [];
|
||||
if($aArticleReviewer['state'] == 4){
|
||||
$aUpdate['state'] = 5;
|
||||
$aUpdate['ctime'] = time();
|
||||
}
|
||||
if($aArticleReviewer['state'] == 0){
|
||||
$aUpdate['agree_review_time'] = time();
|
||||
}
|
||||
if(empty($aUpdate)){
|
||||
return json_encode(array('status' => 15,'msg' => 'Update data to empty' ));
|
||||
}
|
||||
$aUpdate += ['editor_act' => 1,'is_reapply' => 2,'update_time' => time(),'reviewer_act' => 0];
|
||||
$result = Db::name('article_reviewer')->where($aWhere)->limit(1)->update($aUpdate);
|
||||
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();
|
||||
|
||||
84
application/api/job/ArticleCreateLongTable.php
Normal file
84
application/api/job/ArticleCreateLongTable.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace app\api\job;
|
||||
|
||||
use think\queue\Job;
|
||||
use app\common\QueueJob;
|
||||
use app\common\QueueRedis;
|
||||
class ArticleCreateLongTable
|
||||
{
|
||||
private $oQueueJob;
|
||||
private $QueueRedis;
|
||||
private $completedExprie = 180;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->oQueueJob = new QueueJob;
|
||||
$this->QueueRedis = QueueRedis::getInstance();
|
||||
}
|
||||
|
||||
public function fire(Job $job, $data)
|
||||
{
|
||||
//任务开始判断
|
||||
$this->oQueueJob->init($job);
|
||||
|
||||
// 获取 Redis 任务的原始数据
|
||||
$rawBody = empty($job->getRawBody()) ? '' : $job->getRawBody();
|
||||
$jobData = empty($rawBody) ? [] : json_decode($rawBody, true);
|
||||
$jobId = empty($jobData['id']) ? 'unknown' : $jobData['id'];
|
||||
|
||||
$this->oQueueJob->log("-----------队列任务开始-----------");
|
||||
$this->oQueueJob->log("当前任务ID: {$jobId}, 尝试次数: {$job->attempts()}");
|
||||
|
||||
// 获取文章ID
|
||||
$iPArticleId = empty($data['p_article_id']) ? 0 : $data['p_article_id'];
|
||||
if (empty($iPArticleId)) {
|
||||
$this->oQueueJob->log("无效的p_article_id,删除任务");
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
// 获取表格ID
|
||||
$aLongTableId = empty($data['long_table_id']) ? [] : $data['long_table_id'];
|
||||
if (empty($aLongTableId)) {
|
||||
$this->oQueueJob->log("无效的long_table_id,删除任务");
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
$sLongTableId = is_array($aLongTableId) ? implode(',', $aLongTableId) : 0;
|
||||
try {
|
||||
|
||||
// 生成Redis键并尝试获取锁
|
||||
$sClassName = get_class($this);
|
||||
$sRedisKey = "queue_job:{$sClassName}:{$iPArticleId}:{$sLongTableId}";
|
||||
$sRedisValue = uniqid() . '_' . getmypid();
|
||||
if (!$this->oQueueJob->acquireLock($sRedisKey, $sRedisValue, $job)) {
|
||||
return; // 未获取到锁,已处理
|
||||
}
|
||||
//生成内容
|
||||
$oProduction = new \app\api\controller\Production;
|
||||
$response = $oProduction->longTablePdfCreate($aLongTableId);
|
||||
// 验证API响应
|
||||
if (empty($response)) {
|
||||
throw new \RuntimeException("返回空结果");
|
||||
}
|
||||
// 检查JSON解析错误
|
||||
$aResult = json_decode($response, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \RuntimeException("解析响应失败: " . json_last_error_msg() . " | 原始响应: {$response}");
|
||||
}
|
||||
$sMsg = empty($aResult['msg']) ? 'success' : $aResult['msg'];
|
||||
//更新完成标识
|
||||
$this->QueueRedis->finishJob($sRedisKey, 'completed', $this->completedExprie,$sRedisValue);
|
||||
$job->delete();
|
||||
$this->oQueueJob->log("任务执行成功 | 日志ID: {$sRedisKey} | 执行日志:{$sMsg}");
|
||||
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\LogicException $e) {
|
||||
$this->oQueueJob->handleNonRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\Exception $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} finally {
|
||||
$this->oQueueJob->finnal();
|
||||
}
|
||||
}
|
||||
}
|
||||
77
application/api/job/ArticleCreatePdf.php
Normal file
77
application/api/job/ArticleCreatePdf.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace app\api\job;
|
||||
|
||||
use think\queue\Job;
|
||||
use app\common\QueueJob;
|
||||
use app\common\QueueRedis;
|
||||
class ArticleCreatePdf
|
||||
{
|
||||
private $oQueueJob;
|
||||
private $QueueRedis;
|
||||
private $completedExprie = 180;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->oQueueJob = new QueueJob;
|
||||
$this->QueueRedis = QueueRedis::getInstance();
|
||||
}
|
||||
|
||||
public function fire(Job $job, $data)
|
||||
{
|
||||
//任务开始判断
|
||||
$this->oQueueJob->init($job);
|
||||
|
||||
// 获取 Redis 任务的原始数据
|
||||
$rawBody = empty($job->getRawBody()) ? '' : $job->getRawBody();
|
||||
$jobData = empty($rawBody) ? [] : json_decode($rawBody, true);
|
||||
$jobId = empty($jobData['id']) ? 'unknown' : $jobData['id'];
|
||||
|
||||
$this->oQueueJob->log("-----------队列任务开始-----------");
|
||||
$this->oQueueJob->log("当前任务ID: {$jobId}, 尝试次数: {$job->attempts()}");
|
||||
|
||||
// 获取文章ID
|
||||
$iPArticleId = empty($data['p_article_id']) ? 0 : $data['p_article_id'];
|
||||
if (empty($iPArticleId)) {
|
||||
$this->oQueueJob->log("无效的p_article_id,删除任务");
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
// 生成Redis键并尝试获取锁
|
||||
$sClassName = get_class($this);
|
||||
$sRedisKey = "queue_job:{$sClassName}:{$iPArticleId}";
|
||||
$sRedisValue = uniqid() . '_' . getmypid();
|
||||
if (!$this->oQueueJob->acquireLock($sRedisKey, $sRedisValue, $job)) {
|
||||
return; // 未获取到锁,已处理
|
||||
}
|
||||
|
||||
//生成内容
|
||||
$oProduction = new \app\api\controller\Production;
|
||||
$response = $oProduction->execCreatePdf($data);
|
||||
// 验证API响应
|
||||
if (empty($response)) {
|
||||
throw new \RuntimeException("返回空结果");
|
||||
}
|
||||
// 检查JSON解析错误
|
||||
$aResult = json_decode($response, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \RuntimeException("解析响应失败: " . json_last_error_msg() . " | 原始响应: {$response}");
|
||||
}
|
||||
$sMsg = empty($aResult['msg']) ? 'success' : $aResult['msg'];
|
||||
//更新完成标识
|
||||
$this->QueueRedis->finishJob($sRedisKey, 'completed', $this->completedExprie,$sRedisValue);
|
||||
$job->delete();
|
||||
$this->oQueueJob->log("任务执行成功 | 日志ID: {$sRedisKey} | 执行日志:{$sMsg}");
|
||||
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\LogicException $e) {
|
||||
$this->oQueueJob->handleNonRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\Exception $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} finally {
|
||||
$this->oQueueJob->finnal();
|
||||
}
|
||||
}
|
||||
}
|
||||
77
application/api/job/ArticleCreateTex.php
Normal file
77
application/api/job/ArticleCreateTex.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace app\api\job;
|
||||
|
||||
use think\queue\Job;
|
||||
use app\common\QueueJob;
|
||||
use app\common\QueueRedis;
|
||||
class ArticleCreateTex
|
||||
{
|
||||
private $oQueueJob;
|
||||
private $QueueRedis;
|
||||
private $completedExprie = 180;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->oQueueJob = new QueueJob;
|
||||
$this->QueueRedis = QueueRedis::getInstance();
|
||||
}
|
||||
|
||||
public function fire(Job $job, $data)
|
||||
{
|
||||
//任务开始判断
|
||||
$this->oQueueJob->init($job);
|
||||
|
||||
// 获取 Redis 任务的原始数据
|
||||
$rawBody = empty($job->getRawBody()) ? '' : $job->getRawBody();
|
||||
$jobData = empty($rawBody) ? [] : json_decode($rawBody, true);
|
||||
$jobId = empty($jobData['id']) ? 'unknown' : $jobData['id'];
|
||||
|
||||
$this->oQueueJob->log("-----------队列任务开始-----------");
|
||||
$this->oQueueJob->log("当前任务ID: {$jobId}, 尝试次数: {$job->attempts()}");
|
||||
|
||||
// 获取文章ID
|
||||
$iPArticleId = empty($data['p_article_id']) ? 0 : $data['p_article_id'];
|
||||
if (empty($iPArticleId)) {
|
||||
$this->oQueueJob->log("无效的p_article_id,删除任务");
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
// 生成Redis键并尝试获取锁
|
||||
$sClassName = get_class($this);
|
||||
$sRedisKey = "queue_job:{$sClassName}:{$iPArticleId}";
|
||||
$sRedisValue = uniqid() . '_' . getmypid();
|
||||
if (!$this->oQueueJob->acquireLock($sRedisKey, $sRedisValue, $job)) {
|
||||
return; // 未获取到锁,已处理
|
||||
}
|
||||
|
||||
//生成内容
|
||||
$oProduction = new \app\api\controller\Production;
|
||||
$response = $oProduction->execCreateTex($data);
|
||||
// 验证API响应
|
||||
if (empty($response)) {
|
||||
throw new \RuntimeException("返回空结果");
|
||||
}
|
||||
// 检查JSON解析错误
|
||||
$aResult = json_decode($response, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \RuntimeException("解析响应失败: " . json_last_error_msg() . " | 原始响应: {$response}");
|
||||
}
|
||||
$sMsg = empty($aResult['msg']) ? 'success' : $aResult['msg'];
|
||||
//更新完成标识
|
||||
$this->QueueRedis->finishJob($sRedisKey, 'completed', $this->completedExprie,$sRedisValue);
|
||||
$job->delete();
|
||||
$this->oQueueJob->log("任务执行成功 | 日志ID: {$sRedisKey} | 执行日志:{$sMsg}");
|
||||
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\LogicException $e) {
|
||||
$this->oQueueJob->handleNonRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\Exception $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} finally {
|
||||
$this->oQueueJob->finnal();
|
||||
}
|
||||
}
|
||||
}
|
||||
77
application/api/job/DealMainFigureOrTable.php
Normal file
77
application/api/job/DealMainFigureOrTable.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace app\api\job;
|
||||
|
||||
use think\queue\Job;
|
||||
use app\common\QueueJob;
|
||||
use app\common\QueueRedis;
|
||||
class DealMainFigureOrTable
|
||||
{
|
||||
private $oQueueJob;
|
||||
private $QueueRedis;
|
||||
private $completedExprie = 3600;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->oQueueJob = new QueueJob;
|
||||
$this->QueueRedis = QueueRedis::getInstance();
|
||||
}
|
||||
|
||||
public function fire(Job $job, $data)
|
||||
{
|
||||
//任务开始判断
|
||||
$this->oQueueJob->init($job);
|
||||
|
||||
// 获取 Redis 任务的原始数据
|
||||
$rawBody = empty($job->getRawBody()) ? '' : $job->getRawBody();
|
||||
$jobData = empty($rawBody) ? [] : json_decode($rawBody, true);
|
||||
$jobId = empty($jobData['id']) ? 'unknown' : $jobData['id'];
|
||||
|
||||
$this->oQueueJob->log("-----------队列任务开始-----------");
|
||||
$this->oQueueJob->log("当前任务ID: {$jobId}, 尝试次数: {$job->attempts()}");
|
||||
|
||||
// 获取文章ID
|
||||
$iArticleId = empty($data['article_id']) ? 0 : $data['article_id'];
|
||||
if (empty($iArticleId)) {
|
||||
$this->oQueueJob->log("无效的article_id,删除任务");
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
// 生成Redis键并尝试获取锁
|
||||
$sClassName = get_class($this);
|
||||
$sRedisKey = "queue_job:{$sClassName}:{$iArticleId}";
|
||||
$sRedisValue = uniqid() . '_' . getmypid();
|
||||
if (!$this->oQueueJob->acquireLock($sRedisKey, $sRedisValue, $job)) {
|
||||
return; // 未获取到锁,已处理
|
||||
}
|
||||
|
||||
//生成内容
|
||||
$oProduction = new \app\api\controller\Production;
|
||||
$response = $oProduction->dealMainFigureOrTable($data);
|
||||
// 验证API响应
|
||||
if (empty($response)) {
|
||||
throw new \RuntimeException("返回空结果");
|
||||
}
|
||||
// 检查JSON解析错误
|
||||
$aResult = json_decode($response, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \RuntimeException("解析响应失败: " . json_last_error_msg() . " | 原始响应: {$response}");
|
||||
}
|
||||
$sMsg = empty($aResult['msg']) ? 'success' : $aResult['msg'];
|
||||
//更新完成标识
|
||||
$this->QueueRedis->finishJob($sRedisKey, 'completed', $this->completedExprie,$sRedisValue);
|
||||
$job->delete();
|
||||
$this->oQueueJob->log("任务执行成功 | 日志ID: {$sRedisKey} | 执行日志:{$sMsg}");
|
||||
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\LogicException $e) {
|
||||
$this->oQueueJob->handleNonRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} catch (\Exception $e) {
|
||||
$this->oQueueJob->handleRetryableException($e,$sRedisKey,$sRedisValue, $job);
|
||||
} finally {
|
||||
$this->oQueueJob->finnal();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
application/common/ArticleMain.php
Normal file
13
application/common/ArticleMain.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace app\common;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class ArticleMain extends Model
|
||||
{
|
||||
// 绑定数据表(如果表名与模型名不一致需要指定)
|
||||
protected $table = 't_article_main';
|
||||
|
||||
// 允许批量赋值的字段(必须设置,否则批量更新会失败)
|
||||
protected $fillable = ['am_id','article_id','type','content','ami_id','amt_id','is_h1','is_h2','is_h3','sort','remark','ctime','state','is_proofread','proofread_time'];
|
||||
}
|
||||
385
application/common/FigureTagProcessor.php
Normal file
385
application/common/FigureTagProcessor.php
Normal file
@@ -0,0 +1,385 @@
|
||||
<?php
|
||||
namespace app\common;
|
||||
|
||||
/**
|
||||
* 功能:精准匹配并替换Figure相关格式为myfigure标签
|
||||
* 支持格式:figure 数字、(figure 数字)、figure 数字:/figure 数字.(含嵌套/拆分标签)
|
||||
* 跳过已被myfigure包裹的Figure(含后缀)
|
||||
* 跳过Figure 数字+字母/数字后缀(含拆分标签场景,无论是否有空白)
|
||||
* 正常处理Figure 数字+空白/样式标签场景
|
||||
*/
|
||||
class FigureTagProcessor{
|
||||
//支持的样式标签列表
|
||||
private const STYLE_TAGS = ['i', 'b', 'font', 'strong', 'em','blue'];
|
||||
//HTML文本最大处理长度(防止内存溢出)
|
||||
private const MAX_HTML_LENGTH = 100000;
|
||||
//替换后的目标标签名
|
||||
private const PROCESSED_TAG = 'myfigure';
|
||||
//Figure数字与对应ID的映射数组
|
||||
private $aImageMain = [];
|
||||
|
||||
/**
|
||||
* 处理Figure标签替换的主方法
|
||||
* @param string $html 待处理的HTML文本
|
||||
* @param array $aImageMain Figure数字=>ID的映射数组
|
||||
* @return array ['status' => 状态码, 'data' => 处理后文本]
|
||||
* status说明:2-空文本, 4-无匹配/已处理, 1-处理成功, 5-处理异常
|
||||
*/
|
||||
public function dealFigureStr($html = '', $aImageMain = []){
|
||||
//空文本校验
|
||||
$html = trim($html);
|
||||
if ($html === '' || !is_string($html)) {
|
||||
return ['status' => 2, 'data' => ''];
|
||||
}
|
||||
|
||||
//超长文本保护
|
||||
if (strlen($html) > self::MAX_HTML_LENGTH) {
|
||||
return ['status' => 4, 'data' => $html];
|
||||
}
|
||||
|
||||
//编码处理
|
||||
if (!mb_check_encoding($html, 'UTF-8')) {
|
||||
$html = mb_convert_encoding($html, 'UTF-8', 'GBK,GB2312,ASCII,ISO-8859-1');
|
||||
}
|
||||
|
||||
//初始化映射数组(过滤非数字键值)
|
||||
$this->initImageMap($aImageMain);
|
||||
//原始内容
|
||||
$originalHtml = $html;
|
||||
$hasReplace = false;
|
||||
|
||||
try {
|
||||
//只要包含数字+字母/数字后缀,直接返回原内容(核心修复)
|
||||
if ($this->hasFigureSuffix($html)) {
|
||||
return ['status' => 4, 'data' => $html];
|
||||
}
|
||||
|
||||
//合并拆分标签的Figure+数字
|
||||
$html = $this->preprocessSplitTags($html);
|
||||
|
||||
//替换(核心修复:适配样式标签+后缀标点场景)
|
||||
$html = $this->replaceFigureInHtml($html, $hasReplace);
|
||||
|
||||
//清理冗余样式/标签
|
||||
if ($hasReplace) {
|
||||
$html = $this->cleanRedundantStyles($html);
|
||||
$html = $this->cleanRedundantPunctuation($html);
|
||||
$html = $this->cleanUnclosedTags($html);
|
||||
$html = $this->optimizeFormat($html);
|
||||
$html = $this->cleanDuplicateNestedTags($html);
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return ['status' => 5, 'data' => $originalHtml];
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => $hasReplace ? 1 : 4,
|
||||
'data' => $html
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局检测是否包含Figure数字+字母/数字后缀
|
||||
* 覆盖所有拆分/嵌套/无标签场景,无论是否有空白
|
||||
* @param string $html 待检测HTML
|
||||
* @return bool
|
||||
*/
|
||||
private function hasFigureSuffix($html){
|
||||
$styleTagsPattern = implode('|', self::STYLE_TAGS);
|
||||
|
||||
// 正则1:无标签场景(Figure 4B/4123)
|
||||
$pattern1 = "/figure\s*\d+[a-zA-Z0-9]/iu";
|
||||
|
||||
// 正则2:拆分标签场景(<b>4</b><b>B</b> / <b>4</b> <b>B</b> / <b>4</b> <b>B</b>)
|
||||
$pattern2 = "/figure\s*(?:<\/(?:{$styleTagsPattern})>)\s*[\s| ]*\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\d+)\s*(?:<\/(?:{$styleTagsPattern})>)\s*[\s| ]*\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*([a-zA-Z0-9])/iu";
|
||||
|
||||
// 正则3:嵌套标签场景(<b>4B</b> / <i>4123</i>)
|
||||
$pattern3 = "/figure\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*\d+[a-zA-Z0-9]\s*(?:<\/(?:{$styleTagsPattern})>)/iu";
|
||||
|
||||
// 加@抑制正则警告
|
||||
return @preg_match($pattern1, $html) || @preg_match($pattern2, $html) || @preg_match($pattern3, $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Figure数字映射数组
|
||||
* @param array $aImageMain 原始映射数组
|
||||
* @return void
|
||||
*/
|
||||
private function initImageMap($aImageMain){
|
||||
if (!is_array($aImageMain)) {
|
||||
$aImageMain = [];
|
||||
}
|
||||
$imageMap = [];
|
||||
foreach ($aImageMain as $key => $value) {
|
||||
// 严格校验键值均为数字
|
||||
if (ctype_digit((string)$key) && ctype_digit((string)$value)) {
|
||||
$imageMap[(int)$key] = (int)$value;
|
||||
}
|
||||
}
|
||||
$this->aImageMain = $imageMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并所有拆分标签的Figure+数字(含空白样式标签)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function preprocessSplitTags($html){
|
||||
$styleTagsPattern = implode('|', self::STYLE_TAGS);
|
||||
|
||||
// 正则1:匹配基础拆分标签的Figure+数字
|
||||
$pattern = "/(figure)\s*(?:<\/(?:{$styleTagsPattern})>)\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\d+)/iu";
|
||||
$html = @preg_replace_callback($pattern, function($matches) {
|
||||
return $matches[1] . ' ' . $matches[2];
|
||||
}, $html);
|
||||
|
||||
// 正则2:匹配多轮拆分标签的Figure+数字(含空白)
|
||||
$pattern2 = "/(figure)(?:<\/(?:{$styleTagsPattern})>)\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\s*)\s*(?:<\/(?:{$styleTagsPattern})>)\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\d+)/iu";
|
||||
$html = @preg_replace_callback($pattern2, function($matches) {
|
||||
return $matches[1] . $matches[2] . $matches[3];
|
||||
}, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心替换逻辑:将纯数字Figure替换为myfigure标签
|
||||
* 修复:适配样式标签包裹 + 后缀标点场景(如 <b>Figure 2</b>.)
|
||||
* @param string $html 待处理HTML
|
||||
* @param bool $hasReplace 是否发生替换(引用传递)
|
||||
* @return string
|
||||
*/
|
||||
private function replaceFigureInHtml($html, &$hasReplace){
|
||||
$styleTagsPattern = implode('|', self::STYLE_TAGS);
|
||||
$styleTagsRegex = "(?:<(?:{$styleTagsPattern})[^>]*>)*\s*";
|
||||
$styleTagsCloseRegex = "\s*(?:<\/(?:{$styleTagsPattern})>)*";
|
||||
|
||||
// 正则1:匹配括号内的纯数字Figure(如 (Figure 2)、(<b>Figure 3</b>)、(<b>Figure 3</b>).)
|
||||
$pattern1 = "/\(\s*{$styleTagsRegex}figure\s*(\d+){$styleTagsCloseRegex}\s*([\.,:]{0,1})\s*\)\s*([\.,:]{0,1})/iuD";
|
||||
$html = @preg_replace_callback($pattern1, function($matches) use (&$hasReplace) {
|
||||
$num = $matches[1];
|
||||
$numInt = (int)$num;
|
||||
$suffix1 = $matches[2] ?? '';
|
||||
$suffix2 = $matches[3] ?? '';
|
||||
$suffix = $suffix1 . $suffix2;
|
||||
|
||||
// 过滤条件:非数字、无映射、已处理过的标签
|
||||
if (!ctype_digit($num) || !isset($this->aImageMain[$numInt]) ||
|
||||
$this->isMatchPositionHasMyFigureTag($matches[0], "Figure {$num}")) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
// 执行替换
|
||||
$primaryId = $this->aImageMain[$numInt];
|
||||
$baseTag = "<" . self::PROCESSED_TAG . " data-id=\"{$primaryId}\">Figure {$num}</" . self::PROCESSED_TAG . ">";
|
||||
$target = "({$baseTag}{$suffix})";
|
||||
|
||||
$hasReplace = true;
|
||||
return $target;
|
||||
}, $html);
|
||||
|
||||
// 正则2:匹配无括号的纯数字Figure(核心修复:适配 <b>Figure 2</b>. 场景)
|
||||
$pattern2 = "/{$styleTagsRegex}figure\s*(\d+){$styleTagsCloseRegex}\s*([\.,:]{0,1})(?![a-zA-Z0-9])/iuD";
|
||||
$html = @preg_replace_callback($pattern2, function($matches) use (&$hasReplace) {
|
||||
$num = $matches[1];
|
||||
$numInt = (int)$num;
|
||||
$suffix = $matches[2] ?? '';
|
||||
|
||||
// 过滤条件:非数字、无映射、已处理过的标签
|
||||
if (!ctype_digit($num) || !isset($this->aImageMain[$numInt]) ||
|
||||
$this->isMatchPositionHasMyFigureTag($matches[0], "Figure {$num}")) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
// 执行替换
|
||||
$primaryId = $this->aImageMain[$numInt];
|
||||
$baseTag = "<" . self::PROCESSED_TAG . " data-id=\"{$primaryId}\">Figure {$num}</" . self::PROCESSED_TAG . ">";
|
||||
$target = "{$baseTag}{$suffix}";
|
||||
|
||||
$hasReplace = true;
|
||||
return $target;
|
||||
}, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测当前匹配内容是否已包含myfigure标签(避免重复替换)
|
||||
* @param string $content 匹配的文本片段
|
||||
* @param string $figureText 待检测的Figure文本(如 Figure 2)
|
||||
* @return bool
|
||||
*/
|
||||
private function isMatchPositionHasMyFigureTag($content, $figureText){
|
||||
$escapedText = preg_quote($figureText, '/');
|
||||
$pattern = '/<' . self::PROCESSED_TAG . '[^>]*>\s*' . $escapedText . '\s*<\/' . self::PROCESSED_TAG . '>/is';
|
||||
return (bool)@preg_match($pattern, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理myfigure标签周围的冗余样式标签
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanRedundantStyles($html){
|
||||
foreach (self::STYLE_TAGS as $tag) {
|
||||
$pattern = '/<' . $tag . '>\s*<'.self::PROCESSED_TAG.'([^>]*?)>(.*?)<\/'.self::PROCESSED_TAG.'>([\.,:]{0,1})\s*<\/' . $tag . '>/is';
|
||||
$html = @preg_replace($pattern, '<'.self::PROCESSED_TAG.'$1>$2</'.self::PROCESSED_TAG.'>$3', $html);
|
||||
}
|
||||
|
||||
// 清理无匹配的闭合样式标签
|
||||
$html = @preg_replace('/<\/('.implode('|', self::STYLE_TAGS).')>(?![^<]*<\1>)/is', '', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理myfigure标签周围的冗余标点
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanRedundantPunctuation($html){
|
||||
// 修复括号+标点的冗余格式
|
||||
$html = @preg_replace('/<'.self::PROCESSED_TAG.' data-id="(\d+)">\(Figure \d+\)<\/'.self::PROCESSED_TAG.'>\)\./i',
|
||||
'<'.self::PROCESSED_TAG.' data-id="$1">(Figure $1)</'.self::PROCESSED_TAG.'>.', $html);
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>\)\.([\.,:]{0,1})/', '</'.self::PROCESSED_TAG.'>)$1', $html);
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>\.\)([\.,:]{0,1})/', '</'.self::PROCESSED_TAG.'>)$1', $html);
|
||||
|
||||
// 清理重复标点
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>([\.,:]){2,}/', '</'.self::PROCESSED_TAG.'>$1', $html);
|
||||
|
||||
// 修复括号内的标签冗余
|
||||
$html = @preg_replace('/<'.self::PROCESSED_TAG.' data-id="(\d+)">\((Figure \d+)\s*<\/'.self::PROCESSED_TAG.'>([\.,:]{0,1})/i',
|
||||
'<'.self::PROCESSED_TAG.' data-id="$1">($2)</'.self::PROCESSED_TAG.'>$3', $html);
|
||||
|
||||
$html = $this->cleanExtraParentheses($html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理文本中多余的成对括号(仅处理myfigure标签相关的括号)
|
||||
* @param string $html 待处理文本
|
||||
* @return string
|
||||
*/
|
||||
private function cleanExtraParentheses($html){
|
||||
// 匹配myfigure标签周围的括号区域
|
||||
$pattern = '/(\()*(<'.self::PROCESSED_TAG.'[^>]*>.*?<\/'.self::PROCESSED_TAG.'>)(\))*/is';
|
||||
|
||||
$html = @preg_replace_callback($pattern, function($matches) {
|
||||
$tagContent = $matches[2];
|
||||
$leftParen = $matches[1] ?? '';
|
||||
$rightParen = $matches[3] ?? '';
|
||||
|
||||
// 只保留1个左括号和1个右括号(无论原始有多少)
|
||||
$newLeft = $leftParen ? '(' : '';
|
||||
$newRight = $rightParen ? ')' : '';
|
||||
|
||||
return $newLeft . $tagContent . $newRight;
|
||||
}, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
/**
|
||||
* 清理未闭合的样式标签
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanUnclosedTags($html){
|
||||
foreach (self::STYLE_TAGS as $tag) {
|
||||
// 清理myfigure标签后的冗余闭合标签
|
||||
$html = @preg_replace('/(<\/'.self::PROCESSED_TAG.'>)\s*<\/' . $tag . '>/i', '$1', $html);
|
||||
|
||||
// 定位所有该标签的开闭标签位置
|
||||
@preg_match_all("/<{$tag}\b[^>]*>/i", $html, $openMatches, PREG_OFFSET_CAPTURE);
|
||||
@preg_match_all("/<\/{$tag}>/i", $html, $closeMatches, PREG_OFFSET_CAPTURE);
|
||||
|
||||
$allTags = [];
|
||||
// 收集开标签
|
||||
foreach ($openMatches[0] as $m) {
|
||||
$allTags[] = [
|
||||
'offset' => $m[1],
|
||||
'type' => 'open',
|
||||
'content' => $m[0],
|
||||
'length' => strlen($m[0])
|
||||
];
|
||||
}
|
||||
// 收集闭标签
|
||||
foreach ($closeMatches[0] as $m) {
|
||||
$allTags[] = [
|
||||
'offset' => $m[1],
|
||||
'type' => 'close',
|
||||
'content' => $m[0],
|
||||
'length' => strlen($m[0])
|
||||
];
|
||||
}
|
||||
|
||||
// 按位置排序
|
||||
usort($allTags, function($a, $b) {
|
||||
return $a['offset'] - $b['offset'];
|
||||
});
|
||||
|
||||
// 栈结构匹配开闭标签
|
||||
$tagStack = [];
|
||||
$removeOffsets = [];
|
||||
foreach ($allTags as $t) {
|
||||
if ($t['type'] === 'open') {
|
||||
array_push($tagStack, $t);
|
||||
} else {
|
||||
if (!empty($tagStack)) {
|
||||
array_pop($tagStack);
|
||||
} else {
|
||||
// 无匹配开标签的闭标签,标记删除
|
||||
$removeOffsets[] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 无匹配闭标签的开标签,标记删除
|
||||
foreach ($tagStack as $t) {
|
||||
$removeOffsets[] = $t;
|
||||
}
|
||||
|
||||
// 按偏移量倒序删除(避免影响后续偏移)
|
||||
usort($removeOffsets, function($a, $b) {
|
||||
return $b['offset'] - $a['offset'];
|
||||
});
|
||||
|
||||
foreach ($removeOffsets as $item) {
|
||||
if ($item['offset'] >= 0 && $item['offset'] < strlen($html)) {
|
||||
$html = substr_replace($html, '', $item['offset'], $item['length']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化文本格式(清理多余空格)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function optimizeFormat($html){
|
||||
// 清理连续空格
|
||||
$html = @preg_replace('/\s{2,}/', ' ', trim($html));
|
||||
// 标签后紧跟字母/数字时加空格
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>([A-Za-z0-9])/is', '</'.self::PROCESSED_TAG.'> $1', $html);
|
||||
// 字母/数字紧跟标签前时加空格
|
||||
$html = @preg_replace('/([a-zA-Z0-9])<'.self::PROCESSED_TAG.'/is', '$1 <'.self::PROCESSED_TAG.'', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理嵌套的myfigure标签(避免重复嵌套)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanDuplicateNestedTags($html){
|
||||
$pattern = '/<'.self::PROCESSED_TAG.'[^>]*>\s*<'.self::PROCESSED_TAG.'([^>]*)>(.*?)<\/'.self::PROCESSED_TAG.'>\s*<\/'.self::PROCESSED_TAG.'>/is';
|
||||
$html = @preg_replace($pattern, '<'.self::PROCESSED_TAG.'$1>$2</'.self::PROCESSED_TAG.'>', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,14 @@ use app\common\LatexTable;
|
||||
*/
|
||||
class LatexContent{
|
||||
//期刊相关的信息
|
||||
private $iYear = 2025;//年
|
||||
private $iYear = 2026;//年
|
||||
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 $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php/';//'http://zmzm.journal.dev.com/';//
|
||||
//文章图片
|
||||
private $sArticleIcon = '/public/articleicon/';
|
||||
//文章图片
|
||||
@@ -35,6 +35,7 @@ journalname={{{{journal_title}}}},
|
||||
layout=largetwo,
|
||||
year={{stage_year}},%年
|
||||
volume={{stage_vol}},%卷
|
||||
articletype={{{{article_type}}}},
|
||||
no={{stage_no}},%期
|
||||
page={{stage_page}},%号
|
||||
]{../tmr-tex}
|
||||
@@ -42,38 +43,38 @@ page={{stage_page}},%号
|
||||
\doi{{{doi}}}
|
||||
\journalweb{{{website}}}
|
||||
|
||||
% \def\ORCIdICONNAME{{{CLSFILEURL}}/orcid_icon.png} %定义ORCID图片
|
||||
% \def\TMRLOGONAME{{{CLSFILEURL}}/tmr-logo.pdf} % 定义期刊LOGO图片
|
||||
|
||||
\usepackage{amsmath}
|
||||
\usepackage{balance}
|
||||
\usepackage[nopatch]{microtype}
|
||||
\usepackage{booktabs}
|
||||
\usepackage[backend=biber]{biblatex}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{tabularray}
|
||||
\addbibresource{references_{{p_article_id}}.bib}
|
||||
\addbibresource{references_{{article_id}}.bib}
|
||||
\definecolor{evenRowColor}{RGB}{250,231,232}
|
||||
|
||||
\SetLeftRatio{{{left_ratio}}}
|
||||
\setlength{\parindent}{1em}
|
||||
\title{{{article_title}}}
|
||||
|
||||
{{author_info}}
|
||||
|
||||
{{correspondence_info}}
|
||||
\Correspondence{{{correspondence_info}}}
|
||||
|
||||
|
||||
\keywords{keyword entry 1, keyword entry 2, keyword entry 3} %% First letter not capped
|
||||
|
||||
{{author_contribution}}
|
||||
\authorcontributions{{{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}}
|
||||
\Acknowledgments{{{article_acknowledgment}}}
|
||||
\Peerreviewinformation{\textit{{{journal_title}}} thanks all anonymous reviewers for their contribution to the peer review of this paper}
|
||||
\Abbreviations{{{article_abbreviation}}}
|
||||
\Citation{{{article_cite}}}
|
||||
\received{{{received_date}}}
|
||||
\revised{{{revision_date}}}
|
||||
\accepted{{{accepted_date}}}
|
||||
\Availableonline{{{pub_date}}}
|
||||
{{executive_editor}}
|
||||
\EditorialAdvisoryBoard{{{editorial_advisory_board}}}
|
||||
\Executiveeditor{{{executive_editor}}}
|
||||
{{abstract}}
|
||||
{{keywords}}
|
||||
|
||||
@@ -86,6 +87,7 @@ page={{stage_page}},%号
|
||||
{{article_main}}
|
||||
\nocite{*}
|
||||
\printbibliography[title={References}]
|
||||
\balance
|
||||
\end{document}';
|
||||
/**
|
||||
* 生成初稿-基本内容
|
||||
@@ -108,6 +110,7 @@ page={{stage_page}},%号
|
||||
}
|
||||
}
|
||||
//子刊信息
|
||||
$aJournalStage = [];
|
||||
$iJournalStageId = empty($aProductionArticle['journal_stage_id']) ? 0 : $aProductionArticle['journal_stage_id'];
|
||||
if(!empty($iJournalStageId)){
|
||||
$aJournalStage = $this->getJournalStage(['journal_stage_id' => $iJournalStageId]);
|
||||
@@ -115,30 +118,33 @@ page={{stage_page}},%号
|
||||
}
|
||||
|
||||
//期刊简写
|
||||
$sAbbr = empty($aJournal['abbr']) ? $this->sAbbr : $aJournal['abbr'];
|
||||
$sAbbr = $this->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'];
|
||||
$iVolume = empty($aJournalStage['stage_vol']) ? '' : $aJournalStage['stage_vol'];
|
||||
//期
|
||||
$iPeriod = empty($aJournalStage['stage_no']) ? 0 : $aJournalStage['stage_no'];
|
||||
$iPeriod = empty($aJournalStage['stage_no']) ? '' : $aJournalStage['stage_no'];
|
||||
//页
|
||||
$sPage = empty($aJournalStage['stage_page']) ? '' : $aJournalStage['stage_page'];
|
||||
$sPage = empty($aProductionArticle['npp']) ? '' : $aProductionArticle['npp'];
|
||||
|
||||
//期刊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
|
||||
if(!empty($aProductionArticle['doi'])){
|
||||
$aProductionArticle['doi'] = '10.53388/'.trim($aProductionArticle['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'].'}';
|
||||
$aSearch['{{correspondence_info}}'] = empty($aAuthoInfo['correspondence']) ? '' : $aAuthoInfo['correspondence'];
|
||||
|
||||
//文章基本信息处理
|
||||
//标题
|
||||
@@ -156,31 +162,41 @@ page={{stage_page}},%号
|
||||
}
|
||||
$aSearch['{{article_title}}'] = $sTitle;
|
||||
//author_contribution
|
||||
$aSearch['{{author_contribution}}'] = empty($aProductionArticle['author_contribution']) ? '' : '\authorcontributions{'.$this->dealContent($aProductionArticle['author_contribution']).'}';
|
||||
$aSearch['{{author_contribution}}'] = empty($aProductionArticle['author_contribution']) ? '' : $this->dealContent($aProductionArticle['author_contribution']);
|
||||
//acknowledgment
|
||||
$aSearch['{{article_acknowledgment}}'] = empty($aProductionArticle['acknowledgment']) ? '' : '\Acknowledgments{'.$this->dealContent($aProductionArticle['acknowledgment']).'}';
|
||||
$aSearch['{{article_acknowledgment}}'] = empty($aProductionArticle['acknowledgment']) ? '' : $this->dealContent($aProductionArticle['acknowledgment']);
|
||||
//abbreviation
|
||||
$aSearch['{{article_abbreviation}}'] = empty($aProductionArticle['abbreviation']) ? '' : '\Abbreviations{'.$this->dealContent($aProductionArticle['abbreviation']).'}';
|
||||
$aSearch['{{article_abbreviation}}'] = empty($aProductionArticle['abbreviation']) ? '' : $this->dealContent($aProductionArticle['abbreviation']);
|
||||
|
||||
//文章引用信息
|
||||
$sCite = $this->getArticleCite($aProductionArticle,$aJournal,$aJournalStage);
|
||||
$aSearch['{{article_cite}}'] = empty($sCite) ? '' : '\Citation{'.$sCite.'}';
|
||||
$aSearch['{{article_cite}}'] = empty($sCite) ? '' : $sCite;
|
||||
|
||||
//文章类型
|
||||
$aSearch['{{article_type}}'] = empty($aProductionArticle['type']) ? 'ARTICLE' : strtoupper($aProductionArticle['type']);
|
||||
//获取文章时间
|
||||
$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['{{revision_date}}'] = '';
|
||||
if(in_array( $aSearch['{{article_type}}'], ['ARTICLE','REVIEW','MINI REVIEW'])){
|
||||
$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['{{editorial_advisory_board}}'] = empty($aTime['editorial_advisory_board']) ? '' : $aTime['editorial_advisory_board'];
|
||||
//获取编辑信息
|
||||
$aSearch['{{executive_editor}}'] = empty($aUser['realname']) ? '' : '\Executiveeditor{'.$this->dealContent($aUser['realname']).'}';
|
||||
$executive_editor = empty($aProductionArticle['executive_editor']) ? '' : $this->dealContent($aProductionArticle['executive_editor']);
|
||||
$executive_editor_realname = empty($aUser['realname']) ? '' : $this->dealContent($aUser['realname']);
|
||||
$executive_editor = empty($executive_editor) ? $executive_editor_realname : $executive_editor;
|
||||
$aSearch['{{executive_editor}}'] = $executive_editor;
|
||||
|
||||
//摘要替换
|
||||
$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:}}'];
|
||||
$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.'}';
|
||||
}
|
||||
@@ -191,26 +207,34 @@ page={{stage_page}},%号
|
||||
|
||||
//文章图片地址
|
||||
$sIcon = empty($aProductionArticle['icon']) ? '' : $aProductionArticle['icon'];
|
||||
$is_graphical_abstract = empty($aProductionArticle['is_graphical_abstract']) ? 3 : $aProductionArticle['is_graphical_abstract'];//是否显示图文摘要1是2否3未选择
|
||||
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'].'}';
|
||||
$sIconUrl = ROOT_PATH.trim($this->sArticleIcon,'/').'/'.$sIcon;
|
||||
if(file_exists($sIconUrl) && $is_graphical_abstract == 1){
|
||||
$sIconUrl = str_replace(ROOT_PATH.'public/', '', $sIconUrl);
|
||||
$sIconUrl = '../../'.$sIconUrl;
|
||||
$sIcon = $sIconUrl;
|
||||
}else{
|
||||
$sIcon = '';
|
||||
}
|
||||
// //下载图片
|
||||
// $sImagePath = trim($this->sSubmissionUrl,'/').$this->sArticleIcon.'/'.$sIcon;
|
||||
// $aImageInfo = $this->getImage($sImagePath,$aProductionArticle['article_id']);
|
||||
// if(!empty($aImageInfo['data'])){
|
||||
// $aImageInfo['data'] = './image/'.basename($aImageInfo['data']);
|
||||
// $sIcon = '\KeywordImage{'.$aImageInfo['data'].'}';
|
||||
// }else{
|
||||
// $sIcon = '';
|
||||
// }
|
||||
}
|
||||
$aSearch['{{article_icon}}'] = $sIcon;
|
||||
$aSearch['{{article_icon}}'] = '\KeywordImage{'.$sIcon.'}';
|
||||
$aSearch['{{keywords}}'] = $sKeywords;
|
||||
$aSearch['{{CLSFILEURL}}'] = ROOT_PATH.'public/latex/cls';
|
||||
$aSearch['{{p_article_id}}'] = $aProductionArticle['p_article_id'];
|
||||
// $aSearch['{{CLSFILEURL}}'] = ROOT_PATH.'public/latex/cls';
|
||||
$aSearch['{{article_id}}'] = $aProductionArticle['article_id'];
|
||||
$aSearch['is_have_icon'] = empty($sIcon) ? 2 : 1;
|
||||
//计算左侧内容长度
|
||||
$aRatio = $this->generateLatexDynamicColumns($aSearch);
|
||||
$aSearch['{{left_ratio}}'] = empty($aRatio['left_ratio']) ? '' : $aRatio['left_ratio'];
|
||||
//模版内容替换
|
||||
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
|
||||
//返回内容
|
||||
@@ -249,22 +273,28 @@ page={{stage_page}},%号
|
||||
$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 = Db::name('article_main_image')->field('ami_id,url,title,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;
|
||||
//长表格ID
|
||||
$aLongTableId = [];
|
||||
//数据处理
|
||||
$iStart = 0;
|
||||
$sMain = '';
|
||||
$oLatexTable = new LaTeXTable;
|
||||
//字符串处理
|
||||
$oProduction = new \app\api\controller\Production;
|
||||
foreach ($aArticleMain as $key => $value) {
|
||||
@@ -296,7 +326,13 @@ page={{stage_page}},%号
|
||||
}
|
||||
if($value['is_h1'] == 0 && $value['is_h2'] == 0 && $value['is_h3'] == 0){
|
||||
if($value['type'] == 0 ){
|
||||
$sMain .= $this->dealContent($value['content'],$aReferences)."\\par\n";
|
||||
//处理内容
|
||||
$sMainContent = $this->dealContent($value['content'],$aReferences);
|
||||
// //替换myh3标签
|
||||
// $contentpattern = '/<myh3>(.*?)<\/myh3>/is';
|
||||
// $contentreplacement = '\\subsubsection{$1}';
|
||||
// $sMainContent = preg_replace($contentpattern, $contentreplacement, $sMainContent);
|
||||
$sMain .= $sMainContent."\\par\n";
|
||||
}
|
||||
if($value['type'] == 1 ){//图片
|
||||
$aImageInfo = empty($aArticleMainImage[$value['ami_id']]) ? [] : $aArticleMainImage[$value['ami_id']];
|
||||
@@ -304,38 +340,50 @@ page={{stage_page}},%号
|
||||
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'])){
|
||||
$sMainImageUrl = ROOT_PATH.trim($this->sArticleMainImage,'/').'/'.$aImageInfo['url'];
|
||||
if(!file_exists($sMainImageUrl)){
|
||||
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";
|
||||
// //下载图片
|
||||
// $sImagePath = trim($this->sSubmissionUrl,'/').$this->sArticleMainImage.'/'.$aImageInfo['url'];
|
||||
// $aResult = $this->getImage($sImagePath,$aProductionArticle['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);
|
||||
// $aImageInfo['image_url'] = $aResult['data'];
|
||||
$aImageInfo['image_url'] = $sMainImageUrl;
|
||||
$aDealImage = $this->dealImage($aImageInfo);
|
||||
if(empty($aDealImage['data'])){
|
||||
continue;
|
||||
}
|
||||
$sMain .= $aDealImage['data']."\\par\n";
|
||||
}
|
||||
if($value['type'] == 2 ){//表格
|
||||
$sTableInfo = $oProduction->tableCovertLatex($value['amt_id'],$aReferences);
|
||||
var_dump($sTableInfo);
|
||||
$aTableInfo = empty($aArticleMainTable[$value['amt_id']]) ? [] : $aArticleMainTable[$value['amt_id']];
|
||||
if(empty($aTableInfo['table_data'])){
|
||||
continue;
|
||||
}
|
||||
$sTableInfo = $oProduction->tableCovertLatex($value['amt_id'],$aReferences,$aTableInfo);
|
||||
if($sTableInfo == 'JSON error'){
|
||||
continue;
|
||||
}
|
||||
if($sTableInfo == 'long table'){
|
||||
$aLongTableId[] = $value['amt_id'];
|
||||
continue;
|
||||
}
|
||||
$sMain .= $sTableInfo."\\par\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aSearch['{{article_main}}'] = empty($sMain) ? '' : $sMain."\n";
|
||||
//模版内容替换
|
||||
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
|
||||
//返回内容
|
||||
return ['status' => 1,'msg' => 'success','data' => $sTemplateInfo];
|
||||
return ['status' => 1,'msg' => 'success','data' => $sTemplateInfo,'long_table_id' => $aLongTableId];
|
||||
}
|
||||
/**
|
||||
* 生成初稿-作者信息
|
||||
@@ -359,7 +407,7 @@ page={{stage_page}},%号
|
||||
}
|
||||
//查询作者机构
|
||||
$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();
|
||||
$aAuthorOrgan = Db::name('production_article_author_to_organ')->field('p_article_author_id,p_article_organ_id')->where($aWhere)->order('p_article_author_id asc,p_article_organ_id asc')->select();
|
||||
//查询机构信息
|
||||
$aAuthorOrganList = [];
|
||||
if(!empty($aAuthorOrgan)){
|
||||
@@ -378,9 +426,10 @@ page={{stage_page}},%号
|
||||
}
|
||||
//处理作者
|
||||
$sAuthor = $sCorrespondence = '';
|
||||
$iFirstNum = 0;
|
||||
foreach ($aAuthor as $key => $value) {
|
||||
//作者姓名
|
||||
$sName = empty($value['fifirst_name']) ? '' : $value['fifirst_name'];
|
||||
$sName = empty($value['first_name']) ? '' : $value['first_name'];
|
||||
$sName = empty($sName) ? '' : $sName . ' ' .$value['last_name'];
|
||||
if(empty($sName)){
|
||||
$sName = empty($value['author_name']) ? '' : $value['author_name'];
|
||||
@@ -411,21 +460,32 @@ page={{stage_page}},%号
|
||||
}
|
||||
if($value['is_first'] == 1){
|
||||
$sAuthor .= '\firstauthor'."\n";
|
||||
$iFirstNum++;
|
||||
}
|
||||
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]),'.');
|
||||
$sCorrespondenceInfo = $sName;
|
||||
// if(!empty($aOrganList[0])){
|
||||
// $sCorrespondence .= ','.trim($this->dealContent($aOrganList[0]),'.');
|
||||
// }
|
||||
if(!empty($value['mailing_address'])){//通讯地址
|
||||
$value['mailing_address'] = trim($value['mailing_address']);
|
||||
$sCorrespondenceInfo .= ','.trim($this->dealContent($value['mailing_address']),'.');
|
||||
}
|
||||
if(!empty($value['email'])){
|
||||
$sCorrespondence .= '.E-mail: '.trim($this->dealContent($value['email']),'.').'.';
|
||||
$sCorrespondenceInfo .= '. E-mail:'.trim($this->dealContent($value['email']),'.').'.';
|
||||
}else{
|
||||
$sCorrespondenceInfo .= trim($sCorrespondenceInfo,'.').'.';
|
||||
}
|
||||
$sCorrespondence .= $sCorrespondenceInfo .' ';
|
||||
}
|
||||
}
|
||||
return ['author' => $sAuthor,'correspondence' => $sCorrespondence];
|
||||
if($iFirstNum == 1 && !empty($sAuthor)){
|
||||
$sAuthor = str_replace('\firstauthor'."\n", '', $sAuthor);
|
||||
}
|
||||
return ['author' => $sAuthor,'correspondence' => trim($sCorrespondence)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,28 +513,29 @@ page={{stage_page}},%号
|
||||
$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';
|
||||
}
|
||||
}
|
||||
}
|
||||
$sAbbr = empty($aArticle['abbr']) ? '' : trim(trim($aArticle['abbr'],'.'));
|
||||
// $aAbbr = empty( $sAbbr ) ? [] : explode(',', trim( $sAbbr ));
|
||||
// if(!empty($aAbbr)){
|
||||
// $sEnd = end($aAbbr);
|
||||
// if($sEnd != 'et al'){
|
||||
// $aThree = array_slice($aAbbr, 0,3);
|
||||
// $sAbbr = implode(',', $aThree);
|
||||
// if(!empty( $sAbbr ) && count($aThree) > 3){
|
||||
// $sAbbr .= ', 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 = $sAbbr . '. ' . $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'];
|
||||
$sCite = $this->dealContent($sAbbr) . '. ' . $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 = []){
|
||||
public function getArticleTime($aParam = []){
|
||||
//必填值验证
|
||||
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
|
||||
if(empty($iArticleId)){
|
||||
@@ -486,6 +547,15 @@ page={{stage_page}},%号
|
||||
if(empty($aArticle)){
|
||||
return array('status' => 2,'msg' => 'The article does not exist' );
|
||||
}
|
||||
//查询终审-审稿记录
|
||||
$aWhere = ['article_id' => $iArticleId,'state' => ['in',[1,2,3]]];
|
||||
$aFinalReviewerId = Db::name('article_reviewer_final')->order('review_time desc')->where($aWhere)->column('reviewer_id');
|
||||
//查询审稿人姓名
|
||||
$aUserName = [];
|
||||
if(!empty($aFinalReviewerId)){
|
||||
$aWhere = ['user_id' => ['in',array_unique($aFinalReviewerId)],'state' => 0,'realname' => ['<>','']];
|
||||
$aUserName = Db::name('user')->where($aWhere)->column('realname');
|
||||
}
|
||||
//获取文章记录
|
||||
$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();
|
||||
@@ -509,6 +579,7 @@ page={{stage_page}},%号
|
||||
$aTime['received_date'] = empty($iReceivedTime) ? '' : $this->timestampToEnglishDate($iReceivedTime);
|
||||
$aTime['revision_date'] = empty($iRevisionTime) ? '' : $this->timestampToEnglishDate($iRevisionTime);
|
||||
$aTime['accepted_date'] = empty($iAcceptedTime) ? '' : $this->timestampToEnglishDate($iAcceptedTime);
|
||||
$aTime['editorial_advisory_board'] = empty($aUserName) ? '' : implode(',', $aUserName);
|
||||
return ['status' => 1,'msg' => 'success','data' => $aTime];
|
||||
}
|
||||
/**
|
||||
@@ -549,60 +620,8 @@ page={{stage_page}},%号
|
||||
//字符串处理
|
||||
$oProduction = new \app\api\controller\Production;
|
||||
$sContent = $oProduction->convertToLatex($content,$aReferences);
|
||||
$content = $this->htmlToLaTeX($content);
|
||||
return $sContent;
|
||||
}
|
||||
private function htmlToLaTeX($text = ''){
|
||||
if(empty($text)){
|
||||
return '';
|
||||
}
|
||||
$replaceMap = [
|
||||
// 基础标签转换
|
||||
'<i>' => '\textit{',
|
||||
'</i>' => '}',
|
||||
'<em>' => '\textit{',
|
||||
'</em>' => '}',
|
||||
'<b>' => '\textbf{',
|
||||
'</b>' => '}',
|
||||
'<blue>' => '\textcolor{blue}{',
|
||||
'</blue>' => '}',
|
||||
'<p>' => '',
|
||||
'</p>' => '',
|
||||
'<sub>' => '$_{',
|
||||
'</sub>' => '}$',
|
||||
'<sup>' => '$^{',
|
||||
'</sup>' => '}$',
|
||||
'~' => '--', // 波浪号→范围符
|
||||
'(' => '(', // 全角左括号→半角
|
||||
')' => ')', // 全角右括号→半角
|
||||
'((' => '(', // 重复括号去重
|
||||
'))' => ')',
|
||||
|
||||
// ========== 新增:<span> 标签处理 ==========
|
||||
// 场景1:纯空 <span> 标签(无属性)→ 直接删除,保留内容
|
||||
'<span>' => '',
|
||||
'</span>' => '',
|
||||
// 场景2:带蓝色样式的 <span style="color:blue"> → 转为 LaTeX 蓝色命令
|
||||
'<span style="color:blue">' => '\textcolor{blue}{',
|
||||
'<span style="color: Blue;">' => '\textcolor{blue}{', // 兼容大小写/空格
|
||||
'<span style="color:red">' => '\textcolor{red}{', // 扩展:红色
|
||||
'</span>' => '}', // 所有 span 闭标签统一转为 }(匹配开标签的 LaTeX 命令)
|
||||
|
||||
// 扩展:其他常用 span 样式(按需添加)
|
||||
'<span style="font-weight:bold">' => '\textbf{',
|
||||
'<span style="font-style:italic">' => '\textit{',
|
||||
];
|
||||
|
||||
// 第一步:替换所有标签(优先处理带属性的 span,再处理空 span)
|
||||
$text = strtr($text, $replaceMap);
|
||||
|
||||
// 第二步:清理残留的特殊 span 标签(如未匹配的属性,直接删除标签保留内容)
|
||||
// 匹配 <span ...> 形式的标签(任意属性),仅删除标签,保留内容
|
||||
$text = preg_replace('/<span(\s+[^>]*?)?>/i', '', $text);
|
||||
$text = preg_replace('/<\/span>/i', '', $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
/**
|
||||
* @title curl 请求获取图片保存到本地
|
||||
* @param sPath 图片链接地址
|
||||
@@ -620,7 +639,7 @@ page={{stage_page}},%号
|
||||
$sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension'];
|
||||
|
||||
//图片地址
|
||||
$sDir = ROOT_PATH.trim($this->sLatexUrl,'/').'/article_pdf/'.$iId.'/';
|
||||
$sDir = ROOT_PATH.trim($this->sLatexUrl,'/').'/tex_'.$iId.'/image/';
|
||||
$sImagePath = $sDir.basename($sPath);
|
||||
if (file_exists($sImagePath)) {
|
||||
return ['status' => 1,'msg' => 'success','data' => $sImagePath];
|
||||
@@ -645,6 +664,150 @@ page={{stage_page}},%号
|
||||
return ['status' => 1,'msg' => 'success','data' => $sImagePath];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @title curl 图片Latex代码封装
|
||||
*/
|
||||
private function dealImage($aImageInfo = []){
|
||||
|
||||
//获取图片路径
|
||||
$sImageUrl = empty($aImageInfo['image_url']) ? '' : $aImageInfo['image_url'];
|
||||
if(empty($sImageUrl)){
|
||||
return ['status' => 2,'msg' => 'The image link is empty'];
|
||||
}
|
||||
//判断图片是否存在
|
||||
if(!file_exists($sImageUrl)){
|
||||
return ['status' => 3,'msg' => 'The image does not exist:'.$sImageUrl];
|
||||
}
|
||||
|
||||
// 检测图片尺寸
|
||||
$imageInfo = getimagesize($sImageUrl);
|
||||
$imageWidth = $imageInfo[0]; // 图片宽度
|
||||
$imageHeight = $imageInfo[1]; // 图片高度
|
||||
|
||||
// 定义宽度阈值(例如:宽度大于600像素则使用两栏)
|
||||
$wideImageThreshold = 600;
|
||||
$isWideImage = $imageWidth > $wideImageThreshold;
|
||||
|
||||
// 生成LaTeX图片代码
|
||||
$sImageUrl = str_replace(ROOT_PATH.'public/', '', $sImageUrl);
|
||||
$sImageUrl = '../../'.$sImageUrl;
|
||||
if ($isWideImage) {
|
||||
$latexLines[] = "\\begin{figure*}[htbp]"; // 使用figure*环境实现两栏
|
||||
$latexLines[] = " \\centering";
|
||||
$latexLines[] = " \\includegraphics[width=0.9\\textwidth]{" . $sImageUrl . "}"; // 使用全宽度
|
||||
} else {
|
||||
$latexLines[] = "\\begin{figure}[H]";
|
||||
$latexLines[] = " \\centering";
|
||||
$latexLines[] = " \\includegraphics[width=0.9\\textwidth]{" . $sImageUrl . "}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!empty($aImageInfo['title']) && !empty($aImageInfo['note'])){
|
||||
$escapedTitle = '{\fontspec{Calibri}\footnotesize\bfseries\color{figerTitleColor} '.$this->dealContent(preg_replace('/^Figure\s+\d+\s*/i', '', $aImageInfo['title']),[]).'}\\\\';
|
||||
$escapedTitle .= '{\vspace{0.5em}\raggedright\small {'.$this->dealContent($aImageInfo['note'],[]).'}}';
|
||||
$latexLines[] = " \\caption{" . $escapedTitle . "}";
|
||||
}
|
||||
|
||||
if (!empty($ami_info['title'])) {
|
||||
$escapedTitle = $this->dealContent(preg_replace('/^Figure\s+\d+\s*/i', '', $ami_info['title']),[]);
|
||||
$latexLines[] = " \\caption{" . $escapedTitle . "}";
|
||||
}
|
||||
$latexLines[] = "\\end{figure" . ($isWideImage ? "*" : "") . "}";
|
||||
|
||||
return ['status' => 1,'msg' => 'success','data' => implode("\n", $latexLines)];
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态LaTeX 比例分栏[两栏]
|
||||
*/
|
||||
private function generateLatexDynamicColumns($aSearch = []) {
|
||||
|
||||
//数据处理
|
||||
//右侧列
|
||||
$sRightLen = '';
|
||||
if(!empty($aSearch['{{abstract}}'])){
|
||||
$sRightLen .= $aSearch['{{abstract}}'];
|
||||
}
|
||||
if(!empty($aSearch['{{keywords}}'])){
|
||||
$sRightLen .= $aSearch['{{keywords}}'];
|
||||
}
|
||||
$iRightLen = mb_strlen($sRightLen, 'UTF-8');
|
||||
|
||||
if(!empty($aSearch['is_have_icon']) && $aSearch['is_have_icon'] == 1){
|
||||
$iRightImgRatio = 0.6; // 图片宽度=0.6\textwidth
|
||||
$iRightImgChar = $this->imgRatioToCharCount($iRightImgRatio);
|
||||
$iRightLen = $iRightLen + $iRightImgChar;
|
||||
}
|
||||
//左侧列
|
||||
$sLefttLen = '';
|
||||
if(!empty($aSearch['{{author_contribution}}'])){
|
||||
$sLefttLen .= 'Author contributions'."\n".$aSearch['{{author_contribution}}'];
|
||||
}
|
||||
$sLefttLen .= 'Competing interests'."\n".'The authors declare no conflicts of interest.';
|
||||
if(!empty($aSearch['{{article_acknowledgment}}'])){
|
||||
$sLefttLen .= 'Acknowledgments'."\n".$aSearch['{{article_acknowledgment}}'];
|
||||
}
|
||||
if(!empty($aSearch['{{article_abbreviation}}'])){
|
||||
$sLefttLen .= 'Abbreviations'."\n".$aSearch['{{article_abbreviation}}'];
|
||||
}
|
||||
if(!empty($aSearch['{{article_cite}}'])){
|
||||
$sLefttLen .= 'Citation'."\n".$aSearch['{{article_cite}}'];
|
||||
}
|
||||
if(!empty($aSearch['{{journal_title}}'])){
|
||||
$sLefttLen .= 'Peer review information'."\n".$aSearch['{{journal_title}}'].' thanks all anonymous reviewers for their contribution to the peer review of this paper';
|
||||
}
|
||||
if(!empty($aSearch['{{editorial_advisory_board}}'])){
|
||||
$sLefttLen .= 'Editorial Advisory Board: '.$aSearch['{{editorial_advisory_board}}'];
|
||||
}
|
||||
if(!empty($aSearch['{{executive_editor}}'])){
|
||||
$sLefttLen .= 'Executive editor: '.$aSearch['{{executive_editor}}'];
|
||||
}
|
||||
if(!empty($aSearch['{{received_date}}'])){
|
||||
$sLefttLen .= 'Received: '.$aSearch['{{received_date}}'].'; ';
|
||||
}
|
||||
if(!empty($aSearch['{{revision_date}}'])){
|
||||
$sLefttLen .= 'Revised: '.$aSearch['{{revision_date}}'].'; ';
|
||||
}
|
||||
if(!empty($aSearch['{{accepted_date}}'])){
|
||||
$sLefttLen .= 'Accepted:'.$aSearch['{{accepted_date}}'].'; ';
|
||||
}
|
||||
if(!empty($aSearch['{{pub_date}}'])){
|
||||
$sLefttLen .= 'Available online: '.$aSearch['{{pub_date}}'];
|
||||
}
|
||||
$sLefttLen .= date('Y').' By Author(s). Published by TMR Publishing Group Limited. This is an open access article under the CC-BY license. (https://creativecommons.org/licenses/by/4.0/)';
|
||||
$iLeftLen = mb_strlen($sLefttLen, 'UTF-8');
|
||||
|
||||
//统计总字数
|
||||
$iTotalLen = $iLeftLen + $iRightLen;
|
||||
|
||||
$iLeftRatio = $iRightRatio = 0.5;
|
||||
if($iTotalLen > 0) {
|
||||
$iLeftRatio = round($iLeftLen / $iTotalLen,2);
|
||||
}
|
||||
if(intval($iLeftRatio*100) > 50){
|
||||
$iLeftRatio = 0.5;
|
||||
}
|
||||
if(intval($iLeftRatio*100) < 36){
|
||||
$iLeftRatio = 0.36;
|
||||
}
|
||||
return ['left_ratio' => $iLeftRatio];
|
||||
}
|
||||
/**
|
||||
* 图片宽度比例 → 等效英文字符数
|
||||
* @param float $fImgRatio 图片宽度占\textwidth的比例(如0.5=0.5\textwidth)
|
||||
* @param float $fTextWidthEm 页面\textwidth的em宽度(英文期刊默认36em)
|
||||
* @return int 英文字符数
|
||||
*/
|
||||
function imgRatioToCharCount($fImgRatio = 0.6, $fTextWidthEm = 36) {
|
||||
if ($fImgRatio <= 0 || !is_numeric($fImgRatio)) {
|
||||
return 0;
|
||||
}
|
||||
//计算图片宽度(em)
|
||||
$fImgWidthEm = $fImgRatio * $fTextWidthEm;
|
||||
//折算为英文字符数(1em=2个英文字符)
|
||||
$iImgCharCount = round($fImgWidthEm * 2);
|
||||
return max($iImgCharCount, 0);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -210,11 +210,19 @@ class Reviewer
|
||||
$sMajorQuery = Db::name('major_to_user')->field('user_id')->where($aWhere)->buildSql();
|
||||
|
||||
// 查询符合公司条件的审稿人ID,确保去重
|
||||
$aWhere = ['state' => 0, 'company' => ['<>', $sCompany]];
|
||||
$aWhere = ['state' => 0];
|
||||
if(!empty($sCompany)){
|
||||
$aWhere['company'] = ['<>',$sCompany];
|
||||
}
|
||||
if(!empty($aAuthorCompany)){
|
||||
array_push($aAuthorCompany, $sCompany);
|
||||
$aAuthorCompany = array_unique($aAuthorCompany);
|
||||
$aWhere['company'] = ['not in', $aAuthorCompany];
|
||||
$aAuthorCompany = array_filter($aAuthorCompany, function($v) {
|
||||
return trim((string)$v) !== '';
|
||||
});
|
||||
if(!empty($aAuthorCompany)){
|
||||
$aWhere['company'] = ['not in', $aAuthorCompany];
|
||||
}
|
||||
}
|
||||
if(!empty($aBlack) && !empty($aParam['not_choose_id'])){
|
||||
$aBlack = array_unique(array_merge($aBlack, $aParam['not_choose_id']));
|
||||
|
||||
399
application/common/TableTagProcessor.php
Normal file
399
application/common/TableTagProcessor.php
Normal file
@@ -0,0 +1,399 @@
|
||||
<?php
|
||||
namespace app\common;
|
||||
|
||||
/**
|
||||
* 功能:精准匹配并替换Table相关格式为mytable标签
|
||||
* 支持格式:table 数字、(table 数字)、table 数字:/table 数字.(含嵌套/拆分标签)
|
||||
* 跳过已被mytable包裹的table(含后缀)
|
||||
* 跳过table 数字+字母/数字后缀(含拆分标签场景,无论是否有空白)
|
||||
* 正常处理table 数字+空白/样式标签场景
|
||||
*/
|
||||
class TableTagProcessor{
|
||||
// 支持的样式标签列表
|
||||
private const STYLE_TAGS = ['i', 'b', 'font', 'strong', 'em','blue'];
|
||||
// HTML文本最大处理长度(防止内存溢出)
|
||||
private const MAX_HTML_LENGTH = 100000;
|
||||
// 替换后的目标标签名
|
||||
private const PROCESSED_TAG = 'mytable';
|
||||
// Table数字与对应ID的映射数组
|
||||
private $aTableMain = [];
|
||||
|
||||
/**
|
||||
* 处理Table标签替换的主方法
|
||||
* @param string $html 待处理的HTML文本
|
||||
* @param array $aTableMain Table数字=>ID的映射数组(可选,默认1=>1~10=>10)
|
||||
* @return array ['status' => 状态码, 'data' => 处理后文本]
|
||||
* status说明:2-空文本, 4-无匹配/已处理, 1-处理成功, 5-处理异常
|
||||
*/
|
||||
public function dealTableStr($html = '', $aTableMain = []){
|
||||
// 初始化默认映射数组(仅当入参为空时使用)
|
||||
$defaultTableMap = [1=>1,2=>2,3=>3,4=>4,5=>5,6=>6,7=>7,8=>8,9=>9,10=>10];
|
||||
// 优先使用入参,入参为空则用默认值
|
||||
$tableMap = !empty($aTableMain) ? $aTableMain : $defaultTableMap;
|
||||
|
||||
// 空文本校验
|
||||
$html = trim($html);
|
||||
if ($html === '' || !is_string($html)) {
|
||||
return ['status' => 2, 'data' => ''];
|
||||
}
|
||||
|
||||
// 超长文本保护
|
||||
if (strlen($html) > self::MAX_HTML_LENGTH) {
|
||||
return ['status' => 4, 'data' => $html];
|
||||
}
|
||||
|
||||
// 编码处理(统一转为UTF-8,避免中文乱码)
|
||||
if (!mb_check_encoding($html, 'UTF-8')) {
|
||||
$html = mb_convert_encoding($html, 'UTF-8', 'GBK,GB2312,ASCII,ISO-8859-1');
|
||||
}
|
||||
|
||||
// 初始化映射数组(过滤非数字键值)
|
||||
$this->initTableMap($tableMap);
|
||||
|
||||
// 原始内容(异常时返回)
|
||||
$originalHtml = $html;
|
||||
$hasReplace = false;
|
||||
|
||||
try {
|
||||
// 只要包含数字+字母/数字后缀,直接返回原内容
|
||||
if ($this->hasTableSuffix($html)) {
|
||||
return ['status' => 4, 'data' => $html];
|
||||
}
|
||||
|
||||
// 合并拆分标签的Table+数字
|
||||
$html = $this->preprocessSplitTags($html);
|
||||
|
||||
// 核心替换逻辑(修复后)
|
||||
$html = $this->replaceTableInHtml($html, $hasReplace);
|
||||
|
||||
// 清理冗余样式/标签(仅当发生替换时执行)
|
||||
if ($hasReplace) {
|
||||
$html = $this->cleanRedundantStyles($html);
|
||||
$html = $this->cleanRedundantPunctuation($html);
|
||||
$html = $this->cleanUnclosedTags($html);
|
||||
$html = $this->optimizeFormat($html);
|
||||
$html = $this->cleanDuplicateNestedTags($html);
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return ['status' => 5, 'data' => $originalHtml];
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => $hasReplace ? 1 : 4,
|
||||
'data' => $html
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局检测是否包含Table数字+字母/数字后缀
|
||||
* 覆盖所有拆分/嵌套/无标签场景,无论是否有空白
|
||||
* @param string $html 待检测HTML
|
||||
* @return bool
|
||||
*/
|
||||
private function hasTableSuffix($html){
|
||||
$styleTagsPattern = implode('|', self::STYLE_TAGS);
|
||||
|
||||
// 正则1:无标签场景(Table 4B/4123)
|
||||
$pattern1 = "/table\s*\d+[a-zA-Z0-9]/iu";
|
||||
|
||||
// 正则2:拆分标签场景(<b>4</b><b>B</b> / <b>4</b> <b>B</b> / <b>4</b> <b>B</b>)
|
||||
$pattern2 = "/table\s*(?:<\/(?:{$styleTagsPattern})>)\s*[\s| ]*\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\d+)\s*(?:<\/(?:{$styleTagsPattern})>)\s*[\s| ]*\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*([a-zA-Z0-9])/iu";
|
||||
|
||||
// 正则3:嵌套标签场景(<b>4B</b> / <i>4123</i>)
|
||||
$pattern3 = "/table\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*\d+[a-zA-Z0-9]\s*(?:<\/(?:{$styleTagsPattern})>)/iu";
|
||||
|
||||
// 加@抑制正则警告,避免极端文本导致报错
|
||||
return @preg_match($pattern1, $html) || @preg_match($pattern2, $html) || @preg_match($pattern3, $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Table数字映射数组(过滤非数字键值)
|
||||
* @param array $aTableMain 原始映射数组
|
||||
* @return void
|
||||
*/
|
||||
private function initTableMap($aTableMain = []){
|
||||
if (!is_array($aTableMain)) {
|
||||
$aTableMain = [];
|
||||
}
|
||||
|
||||
$tableMap = [];
|
||||
foreach ($aTableMain as $key => $value) {
|
||||
// 严格校验键值均为数字
|
||||
if (ctype_digit((string)$key) && ctype_digit((string)$value)) {
|
||||
$tableMap[(int)$key] = (int)$value;
|
||||
}
|
||||
}
|
||||
|
||||
$this->aTableMain = $tableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并所有拆分标签的Table+数字(含空白样式标签)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function preprocessSplitTags($html){
|
||||
$styleTagsPattern = implode('|', self::STYLE_TAGS);
|
||||
|
||||
// 正则1:匹配基础拆分标签的Table+数字
|
||||
$pattern = "/(table)\s*(?:<\/(?:{$styleTagsPattern})>)\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\d+)/iu";
|
||||
$html = @preg_replace_callback($pattern, function($matches) {
|
||||
return $matches[1] . ' ' . $matches[2];
|
||||
}, $html);
|
||||
|
||||
// 正则2:匹配多轮拆分标签的Table+数字(含空白)
|
||||
$pattern2 = "/(table)(?:<\/(?:{$styleTagsPattern})>)\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\s*)\s*(?:<\/(?:{$styleTagsPattern})>)\s*(?:<(?:{$styleTagsPattern})[^>]*>)\s*(\d+)/iu";
|
||||
$html = @preg_replace_callback($pattern2, function($matches) {
|
||||
return $matches[1] . $matches[2] . $matches[3];
|
||||
}, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心替换逻辑:将纯数字Table替换为mytable标签
|
||||
* 修复:调整标点匹配位置,适配 <b>Table 2</b>. 场景
|
||||
* @param string $html 待处理HTML
|
||||
* @param bool $hasReplace 是否发生替换(引用传递)
|
||||
* @return string
|
||||
*/
|
||||
private function replaceTableInHtml($html, &$hasReplace){
|
||||
$styleTagsPattern = implode('|', self::STYLE_TAGS);
|
||||
$styleTagsRegex = "(?:<(?:{$styleTagsPattern})[^>]*>)*\s*";
|
||||
$styleTagsCloseRegex = "\s*(?:<\/(?:{$styleTagsPattern})>)*";
|
||||
|
||||
// 正则1:匹配括号内的纯数字Table(如 (Table 2)、(<b>Table 3</b>)、(<b>Table 3</b>).)
|
||||
// 修复:将标点匹配移到样式标签闭合后
|
||||
$pattern1 = "/\(\s*{$styleTagsRegex}table\s*(\d+){$styleTagsCloseRegex}\s*([\.,:]{0,1})\s*\)\s*([\.,:]{0,1})/iuD";
|
||||
$html = @preg_replace_callback($pattern1, function($matches) use (&$hasReplace) {
|
||||
$num = $matches[1];
|
||||
$numInt = (int)$num;
|
||||
$suffix1 = $matches[2] ?? '';
|
||||
$suffix2 = $matches[3] ?? '';
|
||||
$suffix = $suffix1 . $suffix2;
|
||||
|
||||
// 过滤条件:非数字、无映射、已处理过的标签
|
||||
if (!ctype_digit($num) || !isset($this->aTableMain[$numInt]) ||
|
||||
$this->isMatchPositionHasMyTableTag($matches[0], "Table {$num}")) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
// 执行替换(清理冗余括号,避免生成((...)))
|
||||
$primaryId = $this->aTableMain[$numInt];
|
||||
$baseTagClean = "<" . self::PROCESSED_TAG . " data-id=\"{$primaryId}\">Table {$num}</" . self::PROCESSED_TAG . ">";
|
||||
$target = "({$baseTagClean}{$suffix})";
|
||||
|
||||
$hasReplace = true;
|
||||
return $target;
|
||||
}, $html);
|
||||
|
||||
// 正则2:匹配无括号的纯数字Table(核心修复:适配 <b>Table 2</b>. 场景)
|
||||
// 修复:将标点匹配移到样式标签闭合后
|
||||
$pattern2 = "/{$styleTagsRegex}table\s*(\d+){$styleTagsCloseRegex}\s*([\.,:]{0,1})(?![a-zA-Z0-9])/iuD";
|
||||
$html = @preg_replace_callback($pattern2, function($matches) use (&$hasReplace) {
|
||||
$num = $matches[1];
|
||||
$numInt = (int)$num;
|
||||
$suffix = $matches[2] ?? '';
|
||||
|
||||
// 过滤条件:非数字、无映射、已处理过的标签
|
||||
if (!ctype_digit($num) || !isset($this->aTableMain[$numInt]) ||
|
||||
$this->isMatchPositionHasMyTableTag($matches[0], "Table {$num}")) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
// 执行替换
|
||||
$primaryId = $this->aTableMain[$numInt];
|
||||
$baseTag = "<" . self::PROCESSED_TAG . " data-id=\"{$primaryId}\">Table {$num}</" . self::PROCESSED_TAG . ">";
|
||||
$target = "{$baseTag}{$suffix}";
|
||||
|
||||
$hasReplace = true;
|
||||
return $target;
|
||||
}, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测当前匹配内容是否已包含mytable标签(避免重复替换)
|
||||
* @param string $content 匹配的文本片段
|
||||
* @param string $tableText 待检测的Table文本(如 Table 2)
|
||||
* @return bool
|
||||
*/
|
||||
private function isMatchPositionHasMyTableTag($content, $tableText){
|
||||
$escapedText = preg_quote($tableText, '/');
|
||||
$pattern = '/<' . self::PROCESSED_TAG . '[^>]*>\s*' . $escapedText . '\s*<\/' . self::PROCESSED_TAG . '>/is';
|
||||
return (bool)@preg_match($pattern, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理mytable标签周围的冗余样式标签
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanRedundantStyles($html){
|
||||
foreach (self::STYLE_TAGS as $tag) {
|
||||
$pattern = '/<' . $tag . '>\s*<'.self::PROCESSED_TAG.'([^>]*?)>(.*?)<\/'.self::PROCESSED_TAG.'>([\.,:]{0,1})\s*<\/' . $tag . '>/is';
|
||||
$html = @preg_replace($pattern, '<'.self::PROCESSED_TAG.'$1>$2</'.self::PROCESSED_TAG.'>$3', $html);
|
||||
}
|
||||
|
||||
// 清理无匹配的闭合样式标签
|
||||
$html = @preg_replace('/<\/('.implode('|', self::STYLE_TAGS).')>(?![^<]*<\1>)/is', '', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理mytable标签周围的冗余标点(新增冗余括号清理)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanRedundantPunctuation($html){
|
||||
// 修复括号+标点的冗余格式
|
||||
$html = @preg_replace('/<'.self::PROCESSED_TAG.' data-id="(\d+)">\(Table \d+\)<\/'.self::PROCESSED_TAG.'>\)\./i',
|
||||
'<'.self::PROCESSED_TAG.' data-id="$1">(Table $1)</'.self::PROCESSED_TAG.'>.', $html);
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>\)\.([\.,:]{0,1})/', '</'.self::PROCESSED_TAG.'>)$1', $html);
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>\.\)([\.,:]{0,1})/', '</'.self::PROCESSED_TAG.'>)$1', $html);
|
||||
|
||||
// 新增:清理mytable标签后的冗余括号(避免))问题)
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>\)\)+/', '</'.self::PROCESSED_TAG.'>)', $html);
|
||||
$html = @preg_replace('/\(\(<'.self::PROCESSED_TAG.'/', '(<'.self::PROCESSED_TAG.'', $html);
|
||||
|
||||
// 清理重复标点
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>([\.,:]){2,}/', '</'.self::PROCESSED_TAG.'>$1', $html);
|
||||
|
||||
// 修复括号内的标签冗余
|
||||
$html = @preg_replace('/<'.self::PROCESSED_TAG.' data-id="(\d+)">\((Table \d+)\s*<\/'.self::PROCESSED_TAG.'>([\.,:]{0,1})/i',
|
||||
'<'.self::PROCESSED_TAG.' data-id="$1">($2)</'.self::PROCESSED_TAG.'>$3', $html);
|
||||
|
||||
$html = $this->cleanExtraParentheses($html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理文本中多余的成对括号(仅处理mytable标签相关的括号)
|
||||
* @param string $html 待处理文本
|
||||
* @return string
|
||||
*/
|
||||
private function cleanExtraParentheses($html){
|
||||
// 匹配myfigure标签周围的括号区域
|
||||
$pattern = '/(\()*(<'.self::PROCESSED_TAG.'[^>]*>.*?<\/'.self::PROCESSED_TAG.'>)(\))*/is';
|
||||
|
||||
$html = @preg_replace_callback($pattern, function($matches) {
|
||||
$tagContent = $matches[2];
|
||||
$leftParen = $matches[1] ?? '';
|
||||
$rightParen = $matches[3] ?? '';
|
||||
|
||||
// 只保留1个左括号和1个右括号(无论原始有多少)
|
||||
$newLeft = $leftParen ? '(' : '';
|
||||
$newRight = $rightParen ? ')' : '';
|
||||
|
||||
return $newLeft . $tagContent . $newRight;
|
||||
}, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
/**
|
||||
* 清理未闭合的样式标签
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanUnclosedTags($html){
|
||||
foreach (self::STYLE_TAGS as $tag) {
|
||||
// 清理mytable标签后的冗余闭合标签
|
||||
$html = @preg_replace('/(<\/'.self::PROCESSED_TAG.'>)\s*<\/' . $tag . '>/i', '$1', $html);
|
||||
|
||||
// 定位所有该标签的开闭标签位置
|
||||
@preg_match_all("/<{$tag}\b[^>]*>/i", $html, $openMatches, PREG_OFFSET_CAPTURE);
|
||||
@preg_match_all("/<\/{$tag}>/i", $html, $closeMatches, PREG_OFFSET_CAPTURE);
|
||||
|
||||
$allTags = [];
|
||||
// 收集开标签
|
||||
foreach ($openMatches[0] as $m) {
|
||||
$allTags[] = [
|
||||
'offset' => $m[1],
|
||||
'type' => 'open',
|
||||
'content' => $m[0],
|
||||
'length' => strlen($m[0])
|
||||
];
|
||||
}
|
||||
// 收集闭标签
|
||||
foreach ($closeMatches[0] as $m) {
|
||||
$allTags[] = [
|
||||
'offset' => $m[1],
|
||||
'type' => 'close',
|
||||
'content' => $m[0],
|
||||
'length' => strlen($m[0])
|
||||
];
|
||||
}
|
||||
|
||||
// 按位置排序
|
||||
usort($allTags, function($a, $b) {
|
||||
return $a['offset'] - $b['offset'];
|
||||
});
|
||||
|
||||
// 栈结构匹配开闭标签
|
||||
$tagStack = [];
|
||||
$removeOffsets = [];
|
||||
foreach ($allTags as $t) {
|
||||
if ($t['type'] === 'open') {
|
||||
array_push($tagStack, $t);
|
||||
} else {
|
||||
if (!empty($tagStack)) {
|
||||
array_pop($tagStack);
|
||||
} else {
|
||||
// 无匹配开标签的闭标签,标记删除
|
||||
$removeOffsets[] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 无匹配闭标签的开标签,标记删除
|
||||
foreach ($tagStack as $t) {
|
||||
$removeOffsets[] = $t;
|
||||
}
|
||||
|
||||
// 按偏移量倒序删除(避免影响后续偏移)
|
||||
usort($removeOffsets, function($a, $b) {
|
||||
return $b['offset'] - $a['offset'];
|
||||
});
|
||||
|
||||
foreach ($removeOffsets as $item) {
|
||||
if ($item['offset'] >= 0 && $item['offset'] < strlen($html)) {
|
||||
$html = substr_replace($html, '', $item['offset'], $item['length']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化文本格式(清理多余空格)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function optimizeFormat($html){
|
||||
// 清理连续空格
|
||||
$html = @preg_replace('/\s{2,}/', ' ', trim($html));
|
||||
// 标签后紧跟字母/数字时加空格
|
||||
$html = @preg_replace('/<\/'.self::PROCESSED_TAG.'>([A-Za-z0-9])/is', '</'.self::PROCESSED_TAG.'> $1', $html);
|
||||
// 字母/数字紧跟标签前时加空格
|
||||
$html = @preg_replace('/([a-zA-Z0-9])<'.self::PROCESSED_TAG.'/is', '$1 <'.self::PROCESSED_TAG.'', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理嵌套的mytable标签(避免重复嵌套)
|
||||
* @param string $html 待处理HTML
|
||||
* @return string
|
||||
*/
|
||||
private function cleanDuplicateNestedTags($html){
|
||||
$pattern = '/<'.self::PROCESSED_TAG.'[^>]*>\s*<'.self::PROCESSED_TAG.'([^>]*)>(.*?)<\/'.self::PROCESSED_TAG.'>\s*<\/'.self::PROCESSED_TAG.'>/is';
|
||||
$html = @preg_replace($pattern, '<'.self::PROCESSED_TAG.'$1>$2</'.self::PROCESSED_TAG.'>', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user