diff --git a/application/api/controller/Production.php b/application/api/controller/Production.php index 679955e..85e3b0f 100644 --- a/application/api/controller/Production.php +++ b/application/api/controller/Production.php @@ -18,6 +18,13 @@ use think\log; class Production extends Base { + private $supportedTags = ['sup', 'sub', 'blue', 'b', 'i', 't', 'r']; + // 颜色映射(自定义标签颜色对应LaTeX的HTML十六进制颜色) + private $colorMap = [ + 'blue' => '0082AA', + 't' => 'D25A5A', + 'r' => 'D25A5A', + ]; public function __construct(\think\Request $request = null) { parent::__construct($request); @@ -53,7 +60,7 @@ class Production extends Base return jsonError('No Manuscript'); } - $url = $this->ts_base_url."api/typeset/webReaddoc"; + $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']; @@ -89,7 +96,7 @@ class Production extends Base } - if(!isset($frag['main'])){ + if (!isset($frag['main'])) { return jsonError("manuscript file error!"); } @@ -101,7 +108,7 @@ class Production extends Base //将主体内容写入数据库 - foreach($frag['main'] as $v){ + foreach ($frag['main'] as $v) { $ca['p_article_id'] = $p_article_id; $ca['content'] = $v; $ca['content_g'] = ''; @@ -111,131 +118,138 @@ class Production extends Base return jsonSuccess([]); } - public function getWebMains(){ + public function getWebMains() + { $data = $this->request->post(); $rule = new Validate([ - "article_id"=>"require" + "article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/getArticleMainsForSubmission"; $pro['article_id'] = $data['article_id']; - $res = object_to_array(json_decode(myPost($url,$pro))); + $res = object_to_array(json_decode(myPost($url, $pro))); $re['mains'] = $res['data']['mains']; $re['article'] = $res['data']['article']; return jsonSuccess($re); } - public function addWebMain(){ + public function addWebMain() + { $data = $this->request->post(); $rule = new Validate([ - "article_id"=>'require', - "pre_id"=>"require", - "type"=>"require", - "content"=>"require" + "article_id" => 'require', + "pre_id" => "require", + "type" => "require", + "content" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/addArticleMainAddForSubmission"; - $res = object_to_array(json_decode(myPost($url,$data))); + $res = object_to_array(json_decode(myPost($url, $data))); return jsonSuccess([]); } - public function addWebMains(){ + public function addWebMains() + { $data = $this->request->post(); $rule = new Validate([ - "article_id"=>'require', - "pre_id"=>"require", - "contents"=>"require|array" + "article_id" => 'require', + "pre_id" => "require", + "contents" => "require|array" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/addArticleMainsAddForSubmission"; $program['article_id'] = $data['article_id']; $program['pre_id'] = $data['pre_id']; $program['contents'] = json_encode($data['contents']); - $res = object_to_array(json_decode(myPost($url,$program))); + $res = object_to_array(json_decode(myPost($url, $program))); return jsonSuccess($res); } /**添加主题内容的空白行 * @return void */ - public function addWebMainEmpty(){ + public function addWebMainEmpty() + { $data = $this->request->post(); $rule = new Validate([ - "article_id"=>"require", - "pre_id"=>"require", + "article_id" => "require", + "pre_id" => "require", ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/addArticleMainAddEmptyForSubmission"; - $res = object_to_array(json_decode(myPost($url,$data))); + $res = object_to_array(json_decode(myPost($url, $data))); return jsonSuccess([]); } /**清空web的主体内容 * @return void */ - public function clearWebMains(){ + public function clearWebMains() + { $data = $this->request->post(); $rule = new Validate([ - "article_id"=>"require" + "article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/clearArticleMainForSubmission"; - $res = object_to_array(json_decode(myPost($url,$data))); + $res = object_to_array(json_decode(myPost($url, $data))); return jsonSuccess([]); } - - public function delWebMain(){ + public function delWebMain() + { $data = $this->request->post(); $rule = new Validate([ - "article_main_id"=>"require" + "article_main_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/delArticleMainForSubmission"; - $res = object_to_array(json_decode(myPost($url,$data))); + $res = object_to_array(json_decode(myPost($url, $data))); return jsonSuccess([]); } - public function delWebMains(){ + public function delWebMains() + { $data = $this->request->post(); $rule = new Validate([ - "ids"=>"require" + "ids" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $program['ids'] = json_encode($data['ids']); $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/delArticleMainsForSubmission"; - $res = object_to_array(json_decode(myPost($url,$program))); + $res = object_to_array(json_decode(myPost($url, $program))); return jsonSuccess([]); } - public function editWebMain(){ + public function editWebMain() + { $data = $this->request->post(); $rule = new Validate([ - "article_main_id"=>"require", - "type"=>"require", - "content"=>"require" - ]); - if(!$rule->check($data)){ + "article_main_id" => "require", + "type" => "require", + "content" => "require" + ]); + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/editArticleMainForSubmission"; - $res = object_to_array(json_decode(myPost($url,$data))); + $res = object_to_array(json_decode(myPost($url, $data))); return jsonSuccess([]); } @@ -244,17 +258,18 @@ class Production extends Base * @return \think\response\Json|void * @author wangjinlei */ - public function getProductionMains(){ + public function getProductionMains() + { $data = $this->request->post(); $rule = new Validate([ "p_article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where('p_article_id',$data['p_article_id'])->find(); + $p_info = $this->production_article_obj->where('p_article_id', $data['p_article_id'])->find(); $frag = $this->getProductionMainImgs($data['p_article_id']); - if(count($frag)==0){ + if (count($frag) == 0) { return jsonError("create error"); } $re['mains'] = $frag; @@ -265,26 +280,27 @@ class Production extends Base /** * @return void */ - public function getProductionMainsByDoi(){ + public function getProductionMainsByDoi() + { $data = $this->request->post(); $rule = new Validate([ - 'doi'=>'require' + 'doi' => 'require' ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $a = explode('/',$data['doi']); - $pro_info = $this->production_article_obj->where('doi',$a[1])->where('state',2)->find(); - if(!$pro_info){ + $a = explode('/', $data['doi']); + $pro_info = $this->production_article_obj->where('doi', $a[1])->where('state', 2)->find(); + if (!$pro_info) { return jsonError("production error"); } - if(isset($data['file'])&&$data['file']!=""){ - $frag = $this->getProductionMainImgsByNew($pro_info['p_article_id'],$data['file']); - }else{ + if (isset($data['file']) && $data['file'] != "") { + $frag = $this->getProductionMainImgsByNew($pro_info['p_article_id'], $data['file']); + } else { $frag = $this->getProductionMainImgs($pro_info['p_article_id']); } - if(count($frag)==0){ + if (count($frag) == 0) { return jsonError("create error"); } $re['mains'] = $frag; @@ -298,38 +314,40 @@ class Production extends Base * @return void * */ - public function delProductionMain(){ + public function delProductionMain() + { $data = $this->request->post(); $rule = new Validate([ 'p_main_id' => 'require' ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $this->production_article_main_obj->where('p_main_id',$data['p_main_id'])->update(['state'=>1]); + $this->production_article_main_obj->where('p_main_id', $data['p_main_id'])->update(['state' => 1]); return jsonSuccess([]); } /**添加主体文章图片 * @return void */ - public function addProductionMainImg(){ + public function addProductionMainImg() + { $data = $this->request->post(); $rule = new Validate([ - 'p_article_id'=>'require', - "pre_type"=>"require", - "body"=>"require", - "content"=>"require", - "width"=>"require", - "note"=>"require" + 'p_article_id' => 'require', + "pre_type" => "require", + "body" => "require", + "content" => "require", + "width" => "require", + "note" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $insert['p_article_id'] = $data['p_article_id']; - if($data['pre_type']=="main"){ + if ($data['pre_type'] == "main") { $insert['p_main_id'] = $data['body']; - }else{ + } else { $insert['pre_id'] = $data['body']; } $insert['content'] = $data['content']; @@ -343,46 +361,48 @@ class Production extends Base /**删除mainimg * @return void */ - public function delProductionMainImg(){ + public function delProductionMainImg() + { $data = $this->request->post(); $rule = new Validate([ - 'p_main_img_id'=>'require' + 'p_main_img_id' => 'require' ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_img_info = $this->production_article_main_img_obj->where('p_main_img_id',$data['p_main_img_id'])->find(); - $next_info = $this->production_article_main_img_obj->where('pre_id',$p_img_info['p_main_img_id'])->find(); - if($next_info){ - if($p_img_info['p_main_id']==0){ - $this->production_article_main_img_obj->where('p_main_img_id',$next_info['p_main_img_id'])->update(['pre_id'=>$p_img_info['pre_id']]); - }else{ - $this->production_article_main_img_obj->where('p_main_img_id',$next_info['p_main_img_id'])->update(['p_main_id'=>$p_img_info['p_main_id']]); + $p_img_info = $this->production_article_main_img_obj->where('p_main_img_id', $data['p_main_img_id'])->find(); + $next_info = $this->production_article_main_img_obj->where('pre_id', $p_img_info['p_main_img_id'])->find(); + if ($next_info) { + if ($p_img_info['p_main_id'] == 0) { + $this->production_article_main_img_obj->where('p_main_img_id', $next_info['p_main_img_id'])->update(['pre_id' => $p_img_info['pre_id']]); + } else { + $this->production_article_main_img_obj->where('p_main_img_id', $next_info['p_main_img_id'])->update(['p_main_id' => $p_img_info['p_main_id']]); } } - $this->production_article_main_img_obj->where('p_main_img_id',$data['p_main_img_id'])->update(['state'=>1]); + $this->production_article_main_img_obj->where('p_main_img_id', $data['p_main_img_id'])->update(['state' => 1]); return jsonSuccess([]); } /**编辑mainimg * @return void */ - public function editProductionMainImg(){ + public function editProductionMainImg() + { $data = $this->request->post(); $rule = new Validate([ - 'p_main_img_id'=>'require', - "width"=>"require", - "content"=>"require", - "note"=>"require" + 'p_main_img_id' => 'require', + "width" => "require", + "content" => "require", + "note" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $update['width']=$data['width']; - $update['content']=$data['content']; + $update['width'] = $data['width']; + $update['content'] = $data['content']; $update['title'] = $data['title']; $update['note'] = $data['note']; - $this->production_article_main_img_obj->where('p_main_img_id',$data['p_main_img_id'])->update($update); + $this->production_article_main_img_obj->where('p_main_img_id', $data['p_main_img_id'])->update($update); return jsonSuccess([]); } @@ -391,34 +411,36 @@ class Production extends Base * @return \think\response\Json|void * */ - public function editProductionMain(){ + public function editProductionMain() + { $data = $this->request->post(); $rule = new Validate([ 'p_main_id' => 'require', - 'content'=>'require' + 'content' => 'require' ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $update['content'] = trim($data['content']); - $this->production_article_main_obj->where('p_main_id',$data['p_main_id'])->update($update); + $this->production_article_main_obj->where('p_main_id', $data['p_main_id'])->update($update); return jsonSuccess([]); } - public function pushMainToWeb(){ + public function pushMainToWeb() + { $data = $this->request->post(); $rule = new Validate([ - 'article_id'=>"require", - "p_article_id"=>"require" + 'article_id' => "require", + "p_article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } $url = "http://journalapi.tmrjournals.com/public/index.php/master/Article/addArticleMainForSubmission"; $pro['article_id'] = $data['article_id']; $pro['p_article_id'] = $data['p_article_id']; - $res = object_to_array(json_decode(myPost($url,$pro))); + $res = object_to_array(json_decode(myPost($url, $pro))); // if($res['code']==1){ // return jsonError("Repeated submission"); // } @@ -429,25 +451,27 @@ class Production extends Base * @return void * */ - public function mainGptcheck(){ + public function mainGptcheck() + { $data = $this->request->post(); $rule = new Validate([ - 'p_main_id'=>'require' + 'p_main_id' => 'require' ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $main_info = $this->production_article_main_obj->where('p_main_id',$data['p_main_id'])->find(); - if(mb_strlen($main_info['content'])<20){ + $main_info = $this->production_article_main_obj->where('p_main_id', $data['p_main_id'])->find(); + if (mb_strlen($main_info['content']) < 20) { return trim($main_info['content']); } - $res = object_to_array(json_decode(pushGpt('请将以下内容按照医学期刊的标准校对,不要改变原意,主要是对格式和拼写的校对,将这四个标签保留,将校对好的内容返回 :'.trim($main_info['content'])))); + $res = object_to_array(json_decode(pushGpt('请将以下内容按照医学期刊的标准校对,不要改变原意,主要是对格式和拼写的校对,将这四个标签保留,将校对好的内容返回 :' . trim($main_info['content'])))); $r = $res['choices'][0]['message']['content']; $re['content'] = $r; return jsonSuccess($re); } - public function getPublicMains(){ + public function getPublicMains() + { } @@ -590,14 +614,14 @@ class Production extends Base return jsonError($rule->getError()); } $this->refuseReferIndex($data['p_article_id']); - $dois = $this->production_article_refer_obj->where("p_article_id", $data['p_article_id'])->where("refer_doi","<>","")->where("state",0)->group("refer_doi")->having("count(*)>1")->column("refer_doi"); + $dois = $this->production_article_refer_obj->where("p_article_id", $data['p_article_id'])->where("refer_doi", "<>", "")->where("state", 0)->group("refer_doi")->having("count(*)>1")->column("refer_doi"); $list = $this->production_article_refer_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order("index")->select(); $aRepeat = []; - foreach ($list as $k => $v){ - if(in_array($v['refer_doi'],$dois)){ + foreach ($list as $k => $v) { + if (in_array($v['refer_doi'], $dois)) { $list[$k]['is_repeat'] = 1; $aRepeat[$v['refer_doi']][] = $v['index']; - }else{ + } else { $list[$k]['is_repeat'] = 0; } } @@ -643,7 +667,7 @@ class Production extends Base $journalids = []; if ($data['journal_id'] == 0) { $journalids = $this->journal_obj->where('editor_id', $data['editor_id'])->column('journal_id'); - }else{ + } else { $journalids[] = $data['journal_id']; } $limit_start = ($data['pageIndex'] - 1) * $data['pageSize']; @@ -675,7 +699,7 @@ class Production extends Base if (!$rule->check($data)) { return jsonError($rule->getError()); } - if(isset($data['abstract'])){ + if (isset($data['abstract'])) { $updata['abstract'] = trim($data['abstract']); } $updata['doi'] = $data['doi']; @@ -698,12 +722,11 @@ class Production extends Base } $p_info = $this->production_article_obj->where('p_article_id', $data['p_article_id'])->find(); - if($p_info['topics']==""||$p_info['related']==""){ + if ($p_info['topics'] == "" || $p_info['related'] == "") { return jsonError("Topic and related articles cannot be empty"); } - if ($p_info['state'] != 0) { return jsonError("Non repeatable submission"); } @@ -726,8 +749,8 @@ class Production extends Base ->where('t_production_article_author_to_organ.state', 0) ->select(); $authors[$k]['organs'] = $cache; - if($v['is_report']==1){ - $c_user = $this->user_obj->where('email',$v['email'])->find(); + if ($v['is_report'] == 1) { + $c_user = $this->user_obj->where('email', $v['email'])->find(); $cac['user_id'] = $c_user['user_id']; $report_authors[] = $cac; } @@ -755,7 +778,7 @@ class Production extends Base $pra['pub_date'] = $p_info['pub_date']; $pra['abbr'] = $p_info['abbr']; $pra['icon'] = $p_info['icon']; - $pra['lx_online'] = $journal_info['cycle']==0?0:1; + $pra['lx_online'] = $journal_info['cycle'] == 0 ? 0 : 1; $pra['related'] = $p_info['related']; $pra['topics'] = $p_info['topics']; @@ -774,7 +797,7 @@ class Production extends Base if ($p_info['bibtex'] != '') { $pra['bibtex'] = $p_info['bibtex']; } - if ($p_info['file_original'] != ''){ + if ($p_info['file_original'] != '') { $pra['file_original'] = $p_info['file_original']; } $pra['file_pdf'] = $p_info['file_pdf']; @@ -785,29 +808,29 @@ class Production extends Base $res = object_to_array(json_decode(myPost($url, $pra))); if ($res['code'] == 0) { $r_update['state'] = 2; - $r_update['w_article_id'] = isset($res['data']['article_id'])?$res['data']['article_id']:0; + $r_update['w_article_id'] = isset($res['data']['article_id']) ? $res['data']['article_id'] : 0; $this->production_article_obj->where('p_article_id', $data['p_article_id'])->update($r_update); - foreach($report_authors as $v){ + foreach ($report_authors as $v) { $iua['user_id'] = $v['user_id']; $iua['w_article_id'] = $res['data']['article_id']; - $iua['w_article_doi'] = '10.53388/'.$p_info['doi']; + $iua['w_article_doi'] = '10.53388/' . $p_info['doi']; $iua['journal_title'] = $journal_info['title']; $this->user_author_obj->insert($iua); } //推送到生成AI内容队列 chengxiaoling start 20250530 - if(!empty($p_info['type']) && in_array($p_info['type'], ['Article','Review','Mini Review'])){ + if (!empty($p_info['type']) && in_array($p_info['type'], ['Article', 'Review', 'Mini Review'])) { $iArticleId = empty($r_update['w_article_id']) ? 0 : $r_update['w_article_id']; - if(!empty($iArticleId)){ + if (!empty($iArticleId)) { Queue::push('app\api\job\ArticleAiCreateContent@fire', ['article_id' => $iArticleId], 'ArticleAiCreateContent'); } } //推送到生成AI内容队列 chengxiaoling end 20250530 //推送到关联文章发送邮件提醒队列【立即发送提醒邮件给关联文章的作者及文章作者】 chengxiaoling start 20250609 - if(!empty($p_info['related'])){ + if (!empty($p_info['related'])) { $iArticleId = empty($r_update['w_article_id']) ? 0 : $r_update['w_article_id']; - if(!empty($iArticleId)){ + if (!empty($iArticleId)) { Queue::push('app\api\job\RelatedArticle@fire', ['article_id' => $iArticleId], 'RelatedArticle'); } } @@ -819,7 +842,8 @@ class Production extends Base } - public function getPdfByHtml(){ + public function getPdfByHtml() + { $data = $this->request->post(); $html = $data['html']; $path = ROOT_PATH . 'public' . DS . 'testpdf' . DS; @@ -850,18 +874,18 @@ class Production extends Base __DIR__ . '/custom/font/directory', ]), 'fontdata' => $fontData + [ - '宋体' => [ - 'R' => 'Sun-ExtA.ttf', - 'I' => 'Sun-ExtB.ttf', - ] - ], + '宋体' => [ + 'R' => 'Sun-ExtA.ttf', + 'I' => 'Sun-ExtB.ttf', + ] + ], 'default_font' => '宋体' //CSS中写的汉字宋体就这么写要是别的自定义的就写自己的 自定义字体关键 ]); $strContent = $html; $mpdf->WriteHTML($strContent); $strFileName_New = time() . rand(100, 999) . '.pdf'; - $mpdf->Output($path .$strFileName_New, 'f'); - return jsonSuccess(['url'=>$strFileName_New]); + $mpdf->Output($path . $strFileName_New, 'f'); + return jsonSuccess(['url' => $strFileName_New]); } public function creatpdf() @@ -907,11 +931,11 @@ class Production extends Base __DIR__ . '/custom/font/directory', ]), 'fontdata' => $fontData + [ - '宋体' => [ - 'R' => 'Sun-ExtA.ttf', - 'I' => 'Sun-ExtB.ttf', - ] - ], + '宋体' => [ + 'R' => 'Sun-ExtA.ttf', + 'I' => 'Sun-ExtB.ttf', + ] + ], 'default_font' => '宋体' //CSS中写的汉字宋体就这么写要是别的自定义的就写自己的 自定义字体关键 ]); //自定义标签样式设置也可以直接修改DefaultCss.php中的默认设置 @@ -934,9 +958,9 @@ class Production extends Base // 'PADDINT-TOP' => '0px', // 'PADDINT-BOTTOM' => '0px' // ]; - $strContent =file_get_contents($path . 'meaut33.html'); + $strContent = file_get_contents($path . 'meaut33.html'); $mpdf->WriteHTML($strContent); - $strFileName_New = $path .time() . rand(100, 999) . '.pdf'; + $strFileName_New = $path . time() . rand(100, 999) . '.pdf'; $mpdf->Output($strFileName_New, true); //第二个参数true是直接下载 不设置默认仅保存 } @@ -952,7 +976,7 @@ class Production extends Base public function prgeAuthor($author) { - $a = explode(',', $author); + $a = explode(',', $author); if (count($a) < 7) { return $author . '.'; } else { @@ -1125,7 +1149,7 @@ class Production extends Base // $typesetInfo['refers'] = json_encode($refers); $typesetInfo['refers'] = json_encode($rs); - $url = $this->ts_base_url."api/typeset/webGetDocx"; + $url = $this->ts_base_url . "api/typeset/webGetDocx"; // $url = "http://localhost:8081/typeset/webGetDocx"; $res = object_to_array(json_decode(myPost1($url, $typesetInfo))); @@ -1142,40 +1166,42 @@ class Production extends Base } - public function getTopicsByIssn(){ + public function getTopicsByIssn() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require" + "p_article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("p_article_id",$data['p_article_id'])->find(); - $journal_info = $this->journal_obj->where("journal_id",$p_info['journal_id'])->find(); + $p_info = $this->production_article_obj->where("p_article_id", $data['p_article_id'])->find(); + $journal_info = $this->journal_obj->where("journal_id", $p_info['journal_id'])->find(); $url = 'http://journalapi.tmrjournals.com/public/index.php/master/Article/getTopicByIssn'; $pra = []; $pra['issn'] = $journal_info['issn']; $res = object_to_array(json_decode(myPost($url, $pra))); - $re['now'] = $p_info['topics']==""?[]:json_decode($p_info['topics']); + $re['now'] = $p_info['topics'] == "" ? [] : json_decode($p_info['topics']); $re['list'] = $res['data']['list']; return jsonSuccess($re); } - public function getProductRelatedList(){ + public function getProductRelatedList() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require" + "p_article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("p_article_id",$data['p_article_id'])->find(); - if($p_info['related']==""){ - return jsonSuccess(['list'=>null]); + $p_info = $this->production_article_obj->where("p_article_id", $data['p_article_id'])->find(); + if ($p_info['related'] == "") { + return jsonSuccess(['list' => null]); } $url = 'http://journalapi.tmrjournals.com/public/index.php/master/Article/getArticlesForSubmission'; $pra = []; @@ -1185,20 +1211,21 @@ class Production extends Base return jsonSuccess($re); } - public function addProductRelated(){ + public function addProductRelated() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require", - "article_id"=>"require" + "p_article_id" => "require", + "article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("p_article_id",$data['p_article_id'])->find(); - if ($p_info['related']==""){ + $p_info = $this->production_article_obj->where("p_article_id", $data['p_article_id'])->find(); + if ($p_info['related'] == "") { $list[] = $data['article_id']; - }else{ - if(array_search($data['article_id'], json_decode($p_info['related']))!==false){ + } else { + if (array_search($data['article_id'], json_decode($p_info['related'])) !== false) { return jsonSuccess([]); } $list = json_decode($p_info['related']); @@ -1206,36 +1233,38 @@ class Production extends Base sort($list); } $l = self::repalecArray($list); - $this->production_article_obj->where("p_article_id",$data['p_article_id'])->update(['related'=>count($l)>0?json_encode($l):'']); + $this->production_article_obj->where("p_article_id", $data['p_article_id'])->update(['related' => count($l) > 0 ? json_encode($l) : '']); return jsonSuccess($list); } - private function repalecArray($list){ + private function repalecArray($list) + { $frag = []; - foreach ($list as $v){ + foreach ($list as $v) { $frag[] = $v; } return $frag; } - public function delProductRelated(){ + public function delProductRelated() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require", - "article_id"=>"require" + "p_article_id" => "require", + "article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("p_article_id",$data['p_article_id'])->find(); + $p_info = $this->production_article_obj->where("p_article_id", $data['p_article_id'])->find(); $list = json_decode($p_info['related']); - $key = array_search($data['article_id'],$list); - if($key!==false){ + $key = array_search($data['article_id'], $list); + if ($key !== false) { unset($list[$key]); } - $this->production_article_obj->where("p_article_id",$data['p_article_id'])->update(['related'=>json_encode(self::repalecArray($list))]); - return jsonSuccess(['list'=>$list]); + $this->production_article_obj->where("p_article_id", $data['p_article_id'])->update(['related' => json_encode(self::repalecArray($list))]); + return jsonSuccess(['list' => $list]); } @@ -1253,84 +1282,89 @@ class Production extends Base // return jsonSuccess([]); // } - public function addProductTopic(){ + public function addProductTopic() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require", - "journal_topic_id"=>"require" + "p_article_id" => "require", + "journal_topic_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("p_article_id",$data['p_article_id'])->find(); - if($p_info['topics']==""){ + $p_info = $this->production_article_obj->where("p_article_id", $data['p_article_id'])->find(); + if ($p_info['topics'] == "") { $list[] = $data['journal_topic_id']; - }else{ - if(array_search($data['journal_topic_id'],json_decode($p_info['topics']))!==false){ + } else { + if (array_search($data['journal_topic_id'], json_decode($p_info['topics'])) !== false) { return jsonSuccess([]); } $list = json_decode($p_info['topics']); $list[] = $data['journal_topic_id']; sort($list); } - $this->production_article_obj->where("p_article_id",$data['p_article_id'])->update(['topics'=>json_encode(self::repalecArray($list))]); - return jsonSuccess(['list'=>$list]); + $this->production_article_obj->where("p_article_id", $data['p_article_id'])->update(['topics' => json_encode(self::repalecArray($list))]); + return jsonSuccess(['list' => $list]); } - public function delProductTopic(){ + public function delProductTopic() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require", - "journal_topic_id"=>"require" + "p_article_id" => "require", + "journal_topic_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("p_article_id",$data['p_article_id'])->find(); + $p_info = $this->production_article_obj->where("p_article_id", $data['p_article_id'])->find(); $list = json_decode($p_info['topics']); - $key = array_search($data['journal_topic_id'],$list); - if($key!==false){ + $key = array_search($data['journal_topic_id'], $list); + if ($key !== false) { unset($list[$key]); } $l = self::repalecArray($list); - $this->production_article_obj->where("p_article_id",$data['p_article_id'])->update(['topics'=>count($l)>0?json_encode($l):'']); - return jsonSuccess(['list'=>$list]); + $this->production_article_obj->where("p_article_id", $data['p_article_id'])->update(['topics' => count($l) > 0 ? json_encode($l) : '']); + return jsonSuccess(['list' => $list]); } - public function editProductRelated(){ + public function editProductRelated() + { $data = $this->request->post(); $rule = new Validate([ - "p_article_id"=>"require", - "list"=>"require" + "p_article_id" => "require", + "list" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $this->production_article_obj->where("p_article_id",$data['p_article_id'])->update(['related'=>json_encode($data['list'])]); + $this->production_article_obj->where("p_article_id", $data['p_article_id'])->update(['related' => json_encode($data['list'])]); return jsonSuccess([]); } - private function abstractChange($str){ + private function abstractChange($str) + { $html = preg_replace('/(.*?)<\/strong>/', '{b}$2{/b}', $str); $html = strip_tags($html); - $html = str_replace("{b}","",$html); - $html = str_replace("{/b}","",$html); + $html = str_replace("{b}", "", $html); + $html = str_replace("{/b}", "", $html); return $html; } - public function doTypeSettingNew(){ + public function doTypeSettingNew() + { $data = $this->request->post(); $rule = new Validate([ - "article_id"=>"require" + "article_id" => "require" ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $p_info = $this->production_article_obj->where("article_id",$data['article_id'])->whereIn("state",[0,2])->find(); - if(!$p_info){ + $p_info = $this->production_article_obj->where("article_id", $data['article_id'])->whereIn("state", [0, 2])->find(); + if (!$p_info) { return jsonError("error"); } $article_info = $this->article_obj->where('article_id', $p_info['article_id'])->find(); @@ -1377,11 +1411,11 @@ class Production extends Base $typesetInfo['acknowledgment'] = $p_info['acknowledgment']; // $received_info = $this->article_msg_obj->where("article_id",$p_info['article_id'])->where("state_from",4)->where("state_to",1)->find(); - $received_data = $article_info['received_time']>0?$article_info['received_time']:$article_info['ctime']; + $received_data = $article_info['received_time'] > 0 ? $article_info['received_time'] : $article_info['ctime']; $typesetInfo['received_date'] = date("d F Y", $received_data); - $super_num = $this->article_author_obj->where("article_id",$p_info['article_id'])->where("state",0)->where("is_super",1)->count(); - $typesetInfo['has_more'] = $super_num>1; + $super_num = $this->article_author_obj->where("article_id", $p_info['article_id'])->where("state", 0)->where("is_super", 1)->count(); + $typesetInfo['has_more'] = $super_num > 1; $typesetInfo['accepted_date'] = date("d F Y", $article_info['rtime']); $typesetInfo['online_date'] = $p_info['pub_date']; //这里可能会有问题 $typesetInfo['abbreviation'] = $p_info['abbreviation']; @@ -1402,11 +1436,11 @@ class Production extends Base $rs = $this->production_article_refer_obj->where('p_article_id', $p_info['p_article_id'])->where('state', 0)->order("index")->select(); $typesetInfo['refers'] = json_encode($rs); - $main_list = $this->article_main_obj->where("article_id",$data['article_id'])->whereIn("state",[0,2])->order("sort")->select(); + $main_list = $this->article_main_obj->where("article_id", $data['article_id'])->whereIn("state", [0, 2])->order("sort")->select(); $start = 0; - foreach ($main_list as $k => $v){ + foreach ($main_list as $k => $v) { $cas = strip_tags($v['content']); - if(strtolower(substr($cas, 0, 8)) === "keywords"){ + if (strtolower(substr($cas, 0, 8)) === "keywords") { $start = $k; break; } @@ -1415,37 +1449,37 @@ class Production extends Base $images = []; $tables = []; $nbsp = false; - foreach ($main_list as $k =>$item){ - if($start>=$k){ + foreach ($main_list as $k => $item) { + if ($start >= $k) { continue; } $main_string = ""; - if($item['type']==1){ + if ($item['type'] == 1) { continue; - $info = $this->article_main_image_obj->where("ami_id",$item['ami_id'])->find(); + $info = $this->article_main_image_obj->where("ami_id", $item['ami_id'])->find(); $arr['image'] = $info['url']; - $arr['title'] = "".$info['title'].""; + $arr['title'] = "" . $info['title'] . ""; $arr['note'] = $info['note']; $images[$info['ami_id']] = $arr; - $main_string = ""; - }else if($item['type']==2){ + $main_string = ""; + } else if ($item['type'] == 2) { continue; - $info = $this->article_main_table_obj->where("amt_id",$item['amt_id'])->find(); - $arr_table['title'] = "".strip_tags($info['title']).""; + $info = $this->article_main_table_obj->where("amt_id", $item['amt_id'])->find(); + $arr_table['title'] = "" . strip_tags($info['title']) . ""; $arr_table['table_data'] = $info['table_data']; $arr_table['note'] = $info['note']; $tables[$info['amt_id']] = $arr_table; - $main_string = ""; - }else{ - if($item['is_h1']==1){ + $main_string = "
"; + } else { + if ($item['is_h1'] == 1) { // $main_string = "".$item['content'].""; - $main_string = "".strip_tags($item['content']).""; + $main_string = "" . strip_tags($item['content']) . ""; $nbsp = true; - }else if($item['is_h2']==1||$item['is_h3']==1){ - $main_string = "".$item['content'].""; + } else if ($item['is_h2'] == 1 || $item['is_h3'] == 1) { + $main_string = "" . $item['content'] . ""; $nbsp = false; - }else{ - $main_string = $nbsp?"".$item['content']:$item['content']; + } else { + $main_string = $nbsp ? "" . $item['content'] : $item['content']; $nbsp = false; } } @@ -1456,32 +1490,32 @@ class Production extends Base // $typesetInfo['tables'] = $tables==[]?null:$tables; $as = $this->user_obj->field("t_user.*,t_article_reviewer_question.is_anonymous") - ->join("t_article_reviewer","t_article_reviewer.reviewer_id=t_user.user_id","left") - ->join("t_article_reviewer_question","t_article_reviewer_question.art_rev_id=t_article_reviewer.art_rev_id","left") - ->where("t_article_reviewer.article_id",$article_info['article_id']) - ->whereIn("t_article_reviewer.state",[1,2,3]) + ->join("t_article_reviewer", "t_article_reviewer.reviewer_id=t_user.user_id", "left") + ->join("t_article_reviewer_question", "t_article_reviewer_question.art_rev_id=t_article_reviewer.art_rev_id", "left") + ->where("t_article_reviewer.article_id", $article_info['article_id']) + ->whereIn("t_article_reviewer.state", [1, 2, 3]) ->select(); $as_str = ""; $has_yc = false; - foreach ($as as $v){ - if($v['is_anonymous']==1){ + foreach ($as as $v) { + if ($v['is_anonymous'] == 1) { $has_yc = true; - }else{ - $as_str .= $v["realname"].", "; + } else { + $as_str .= $v["realname"] . ", "; } } - $aca= trim(trim($as_str),","); + $aca = trim(trim($as_str), ","); // return jsonSuccess(["ddd"=>$has_yc?$aca." and other anonymous reviewers":$aca]); - if($as_str==""){ + if ($as_str == "") { $author_str = "all anonymous reviewers"; - }else{ - $author_str = $has_yc?$aca." and other anonymous reviewers":$aca; + } else { + $author_str = $has_yc ? $aca . " and other anonymous reviewers" : $aca; } $typesetInfo['author_str'] = $author_str; $typesetInfo['images'] = null; $typesetInfo['tables'] = null; - $url = $this->ts_base_url."api/typeset/createDocx"; + $url = $this->ts_base_url . "api/typeset/createDocx"; // $url = "http://192.168.110.110:8081/typeset/createDocx"; // $url = "http://192.168.110.110:8081/typeset/testqt"; $res = object_to_array(json_decode(myPost1($url, $typesetInfo))); @@ -1501,7 +1535,8 @@ class Production extends Base } - public function readTest(){ + public function readTest() + { $url = "http://192.168.110.110:8081/typeset/readdoc"; $typesetInfo['filename'] = "11.docx"; $res = object_to_array(json_decode(myPost($url, $typesetInfo))); @@ -1642,21 +1677,21 @@ class Production extends Base $old_article_author_info = $this->production_article_author_obj->where('p_article_author_id', $data['p_article_author_id'])->find(); //判断邮箱是否重复 chengxiaoling 20250926 start - if(empty($old_article_author_info)){ + if (empty($old_article_author_info)) { return jsonError('Author information does not exist'); } $iPArticleId = empty($old_article_author_info['p_article_id']) ? 0 : $old_article_author_info['p_article_id']; $sEmail = empty($data['email']) ? '' : $data['email']; $iAuthorId = empty($old_article_author_info['p_article_author_id']) ? 0 : $old_article_author_info['p_article_author_id']; - if(!empty($sEmail) && !empty($iPArticleId)){ - $aWhere = ['p_article_id' => $iPArticleId,'email' => $sEmail,'state' => 0,'p_article_author_id' => ['<>',$iAuthorId]]; + if (!empty($sEmail) && !empty($iPArticleId)) { + $aWhere = ['p_article_id' => $iPArticleId, 'email' => $sEmail, 'state' => 0, 'p_article_author_id' => ['<>', $iAuthorId]]; $aAuthor = $this->production_article_author_obj->field('p_article_author_id')->where($aWhere)->find(); - if(!empty($aAuthor)){ + if (!empty($aAuthor)) { return jsonError("Email has been bound by another author"); } } //判断邮箱是否重复 chengxiaoling 20250926 end - + $article_info = $this->article_obj->where('article_id', $old_article_author_info['article_id'])->find(); $updata['author_name'] = $article_info['journal_id'] == 21 ? trim($data['last_name']) . trim($data['first_name']) : trim($data['first_name']) . ' ' . trim($data['last_name']); $updata['first_name'] = trim($data['first_name']); @@ -1725,7 +1760,7 @@ class Production extends Base return jsonSuccess($re); } - + /** * 添加作者 */ @@ -1750,10 +1785,10 @@ class Production extends Base //判断邮箱是否重复 chengxiaoling 20250926 start $iPArticleId = empty($data['p_article_id']) ? 0 : $data['p_article_id']; $sEmail = empty($data['email']) ? '' : $data['email']; - if(!empty($sEmail) && !empty($iPArticleId)){ - $aWhere = ['p_article_id' => $iPArticleId,'email' => $sEmail,'state' => 0]; + if (!empty($sEmail) && !empty($iPArticleId)) { + $aWhere = ['p_article_id' => $iPArticleId, 'email' => $sEmail, 'state' => 0]; $aAuthor = $this->production_article_author_obj->field('p_article_author_id')->where($aWhere)->find(); - if(!empty($aAuthor)){ + if (!empty($aAuthor)) { return jsonError("Email has been bound by another author"); } } @@ -1793,19 +1828,20 @@ class Production extends Base /** * gpt校对main内容 */ - public function freshMain(){ + public function freshMain() + { $data = $this->request->post(); $rule = new Validate([ - 'p_article_id'=>'require' + 'p_article_id' => 'require' ]); - if(!$rule->check($data)){ + if (!$rule->check($data)) { return jsonError($rule->getError()); } - $list = $this->production_article_main_obj->where('p_article_id',$data['p_article_id'])->where('state',0)->select(); - foreach($list as $v){ - if($v['content']==''||strlen($v['content'])<60){ - $this->production_article_main_obj->where('p_main_id',$v['p_main_id'])->update(['content_g'=>$v['content']]); - }else{ + $list = $this->production_article_main_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select(); + foreach ($list as $v) { + if ($v['content'] == '' || strlen($v['content']) < 60) { + $this->production_article_main_obj->where('p_main_id', $v['p_main_id'])->update(['content_g' => $v['content']]); + } else { Queue::push('app\api\job\gpt@fresh', $v, 'gpt'); } } @@ -1815,17 +1851,6 @@ class Production extends Base - public function testref(){ - // $mes['role'] = "user"; - // $mes['content'] = "你好啊"; - // $ckey = md5(rand(1000,9999).time().rand(10000,99999)); - // GptChar([$mes],$ckey); - // echo $ckey; - dump(pushGpt("The role of inflammation in MPNs has been increasingly reported in the literature, overproduction of inflammatory cytokines is a clinical feature of patients with MPNs [17-23]. The core proteins screened for inflammation-related RELA, TNF and IL6. IL6 is an important cytosolic inflammatory factor in vivo and the most commonly overexpressed inflammatory factor in myeloid malignancies[24], which promotes STAT3 phosphorylation[25]. Activated IL6/STAT3 signaling can further mediate the production of TNFα, IL1β and other inflammatory factors, continuously enhancing the inflammatory response. TNF mediates the clonal advantage of mutant cells in MPNs[20], and inhibition of TNFR showed a therapeutic effect in mice with MPNs [26]. The above data suggest a central role of inflammation-related factors in MPNs. It suggests that DHI may play a role in treating myeloproliferative neoplasms through multiple targets.")); - // $production_obj = $this->production_article_main_obj->where('p_main_id',4)->find(); - // freshContent($production_obj); - } - /** * 更新引用条目 */ @@ -1858,7 +1883,6 @@ class Production extends Base } - /** * 合并到上个文献中 */ @@ -1918,18 +1942,6 @@ class Production extends Base return jsonSuccess([]); } - public function testtest(){ - $data = $this->request->post(); - $rule = new Validate([ - "id"=>"require" - ]); - if(!$rule->check($data)){ - return jsonError($rule->getError()); - } - $d = $this->production_article_refer_obj->where("p_refer_id",$data['id'])->find(); - $res = my_doiToFrag2($d); - return jsonSuccess($res); - } public function doiTofrag($p_article_id) { @@ -1939,7 +1951,7 @@ class Production extends Base if ($v['refer_doi'] == '') { $this->production_article_refer_obj->where('p_refer_id', $v['p_refer_id'])->update(['refer_frag' => $v['refer_content']]); } else { - + //修改队列兼容对接OPENAI接口 chengxiaoling 20251128 start // Queue::push('app\api\job\ts@fire1', $v, 'ts'); Queue::push('app\api\job\ArticleReferDetailQueue@fire', $v, 'ArticleReferDetailQueue'); @@ -1949,40 +1961,7 @@ class Production extends Base return jsonSuccess([]); } - public function mytestDoi(){ - $data = $this->request->post(); - $rule = new Validate([ - "p_refer_id"=>"require" - ]); - if(!$rule->check($data)){ - return jsonError($rule->getError()); - } - - $info= $this->production_article_refer_obj->where("p_refer_id",$data['p_refer_id'])->find(); - my_doiToFrag2($info); - } - - - public function mytest11() - { - $r = $this->production_article_refer_obj->where('p_refer_id', 8)->find(); - my_doiToFrag2($r); - } - - - public function myreaddoc(){ - Log::log("ceshi"); - $file = "D://11/327ef248323aa75a3ba8347752b03764.docx"; - $fileRoute['fileRoute'] = $file; - $url = "http://192.168.110.110:8081/typeset/readDocxNormal"; - $res = object_to_array(json_decode(myPost1($url, $fileRoute))); - - - -// $r = readDocx($file); - return jsonSuccess($res); - } /** * 验证参考文献是否全部通过 @@ -2016,76 +1995,16 @@ class Production extends Base - public function mytestbib(){ - $data = $this->request->post(); - $rule = new Validate([ - "article_id"=>"require" - ]); - if(!$rule->check($data)){ - return jsonError($rule->getError()); - } - $file = $this->generateBibFile($data['article_id']); - return jsonSuccess(['file'=>$file]); - } - - - /** - * 生成指定文章的 BibTeX 文件 - * @param int $p_article_id 生产文章ID - * @param string $outputPath 输出文件路径(可选) - * @return string 生成的文件路径 - */ - public function generateBibFile($article_id, $outputPath = null) - { - $production_article_obj = $this->production_article_obj->where("article_id",$article_id)->find(); - if($production_article_obj==null){ - $this->addProductionEx($article_id); - $production_article_obj = $this->production_article_obj->where("article_id",$article_id)->find(); - } - if (!$outputPath) { - $outputPath = ROOT_PATH . 'public' . DS . 'latex' . DS . 'tex_'.$article_id . DS .'references_' . $article_id . '.bib'; - } - $dir = dirname($outputPath); - if (!is_dir($dir)) { - mkdir($dir, 0755, true); - } - $bibContent = $this->generateBibContent($production_article_obj['p_article_id']); - file_put_contents($outputPath, $bibContent); - - return $outputPath; - } - - /** - * 获取参考文献数据 - * @param int $p_article_id 生产文章ID - * @return array 参考文献数组 - */ - private function getReferences($p_article_id) - { - return $this->production_article_refer_obj->where("p_article_id",$p_article_id)->where("state",0)->select(); -// $sql = "SELECT * FROM t_production_article_refer -// WHERE p_article_id = :p_article_id -// AND state = 0 -// ORDER BY `index`"; -// -// $stmt = $this->db->prepare($sql); -// $stmt->bindParam(':p_article_id', $p_article_id, PDO::PARAM_INT); -// $stmt->execute(); -// -// return $stmt->fetchAll(PDO::FETCH_ASSOC); - } - /** * 生成 BibTeX 内容 * @param array $references 参考文献数据 * @param int $p_article_id 文章ID * @return string BibTeX 内容 */ - private function generateBibContent( $p_article_id) + private function generateBibContent($p_article_id, $references) { $content = "% BibTeX file generated for article ID: {$p_article_id}\n"; $content .= "% Generated on " . date('Y-m-d H:i:s') . "\n\n"; - $references = $this->production_article_refer_obj->where("p_article_id",$p_article_id)->where("state",0)->select(); foreach ($references as $ref) { $entry = $this->generateBibEntry($ref); if ($entry) { @@ -2096,6 +2015,427 @@ class Production extends Base return $content; } + public function creatLatex(){ + $data = $this->request->post(); + $rule = new Validate([ + "article_id"=>"require" + ]); + if(!$rule->check($data)){ + return jsonError($rule->getError()); + } + //查询基础信息 + $article_production_info = $this->production_article_obj->where("article_id",$data['article_id'])->find(); + $references = $this->production_article_refer_obj + ->where('p_article_id', $article_production_info['p_article_id']) + ->where('state', 0) + ->order('index ASC') + ->select(); + if($article_production_info==null){ + return jsonError("No production information found"); + } + //创建基础目录,加载必要文件 + $outputPath = ROOT_PATH . 'public' . DS . 'latex' . DS . 'tex_' . $data['article_id']; + if (!$outputPath) { + mkdir($outputPath, 0755, true); + } + //生成tex文件 + $article_main_list = $this->article_main_obj->where("article_id",$data['article_id'])->where("state",0)->order("sort asc")->select(); + $fragContentList = []; + $refArray = []; + foreach ($references as $ref) { + $refArray[$ref['index'] + 1] = $ref; + } + foreach ($article_main_list as $article_main_info){ + if($article_main_info['type']!=0){ + $fragContentList[] = $article_main_info; + continue; + } + //整理引用信息的内容 +// $updatedContent = $this->convertReferencesToLatex($article_main_info['content'], $refArray); + //替换其他标签 + $updatedContent = $this->convertToLatex($updatedContent,$refArray); + //做内容替换 + $article_main_info['content'] = $updatedContent; + $fragContentList[] = $article_main_info; + } + + + + + //生成bib文件 + $file = ROOT_PATH . 'public' . DS . 'latex' . DS . 'tex_' . $data['article_id'] . DS . 'references_' . $data['article_id'] . '.bib'; + $bibContent = $this->generateBibContent($article_production_info['p_article_id'],$references); + file_put_contents($file, $bibContent); + + //生成pdf文件 + $pdfFile = ROOT_PATH . 'public' . DS . 'latex' . DS . 'tex_' . $data['article_id'] . DS . 'article_' . $data['article_id'] . '.pdf'; + $command = "cd {$outputPath} && pdflatex -interaction=nonstopmode article_" . $data['article_id'] . ".tex"; + exec($command, $output, $returnCode); + if ($returnCode !== 0) { + return jsonError("Failed to generate PDF"); + } + //存储pdf文件 + + return jsonSuccess(['file'=>$pdfFile]); + } + + + public function mytestconvertToLatex(){ + $data = $this->request->post(); + $rule = new Validate([ + "article_id"=>"require", + "content"=>"require" + ]); + if(!$rule->check($data)){ + return jsonError($rule->getError()); + } + $article_production_info = $this->production_article_obj->where("article_id",$data['article_id'])->find(); + $references = $this->production_article_refer_obj + ->where('p_article_id', $article_production_info['p_article_id']) + ->where('state', 0) + ->order('index ASC') + ->select(); + $refArray = []; + foreach ($references as $ref) { + $refArray[$ref['index'] + 1] = $ref; + } + $res = $this->convertToLatex($data['content'],$refArray); + echo $res; +// return jsonSuccess(["content"=>$res]); + } + + + + + public function convertToLatex($content,$refArray) { + // 空内容直接返回 + if (empty(trim($content))) { + return ''; + } + $content = $this->convertReferencesToLatex($content, $refArray); + // 步骤1:忽略并移除、和标签 + $content = $this->removeIgnoredTags($content); + + // 步骤2:解析剩余标签并生成LaTeX内容 + $latexContent = $this->textRenderCreate($content); + + return $latexContent; + } + + /** + * 移除需要忽略的标签:、、 + * @param string $content 原始内容 + * @return string 处理后的内容 + */ + private function removeIgnoredTags($content) { + // 移除和(不区分大小写,处理可能的空格) + $content = preg_replace('/<\/?tr\s*>/i', '', $content); + // 移除 + $content = str_replace('', '', $content); + return $content; + } + + /** + * 对应Java的textRenderCreate方法,解析文本和标签 + * @param string $content 待解析的内容 + * @return string 解析后的LaTeX内容 + */ + private function textRenderCreate($content) { + $latex = ''; + while (!empty($content)) { + $nextTag = $this->determineNextTag($content); + if ($nextTag === 'no') { + // 无标签,转义特殊字符后直接拼接 + $latex .= $this->escapeLatexSpecialChars($content); + $content = ''; + } else { + $tagOpen = "<{$nextTag}>"; + $tagClose = ""; + $beginTag = strpos($content, $tagOpen); + + // 标签前的文本 + if ($beginTag > 0) { + $latex .= $this->escapeLatexSpecialChars(substr($content, 0, $beginTag)); + } + + // 找到标签的最后闭合位置(处理嵌套) + $endTag = $this->getLastTabIndex($content, $nextTag); + if ($endTag === false) { + // 无闭合标签,保留原内容(异常情况处理) + $latex .= $this->escapeLatexSpecialChars(substr($content, $beginTag)); + $content = ''; + continue; + } + + // 截取标签包裹的内容(包含标签) + $tagWrappedContent = substr( + $content, + $beginTag, + $endTag - $beginTag + strlen($tagClose) + ); + + // 解析标签内容并应用样式 + $style = []; + $tagContentList = []; + $this->getTextRenderData($tagWrappedContent, $nextTag, $style, $tagContentList); + // 拼接解析后的标签内容 + $latex .= implode('', $tagContentList); + + // 剩余内容 + $content = substr($content, $endTag + strlen($tagClose)); + } + } + + return $latex; + } + + /** + * 对应Java的getLastTabIndex方法,找到标签的最后闭合位置(处理嵌套) + * @param string $content 内容 + * @param string $tag 标签名 + * @return int|false 闭合标签的起始位置 + */ + private function getLastTabIndex($content, $tag) { + $tagOpen = "<{$tag}>"; + $tagClose = ""; + + $beginTag = strpos($content, $tagOpen); + if ($beginTag === false) { + return false; + } + + // 先找第一个闭合标签 + $endTagCa = strpos($content, $tagClose, $beginTag); + if ($endTagCa === false) { + return false; + } + + // 统计当前标签内的开放标签数量 + $caNowStr = substr($content, $beginTag, $endTagCa - $beginTag + strlen($tagClose)); + $caCount = preg_match_all("/<{$tag}>/", $caNowStr, $matches); + + if ($caCount === 1) { + return $endTagCa; + } else { + // 递归查找匹配的闭合标签数量 + $reallyNum = 0; + while ($reallyNum !== $caCount) { + $numIndex = $this->getNumIndex($content, $tag, $caCount); + if ($numIndex === false) { + break; + } + $substring = substr($content, $beginTag, $numIndex - $beginTag + strlen($tagClose)); + $ccaCount = preg_match_all("/<{$tag}>/", $substring, $matches); + if ($ccaCount !== $caCount) { + $caCount = $ccaCount; + } else { + $reallyNum = $ccaCount; + } + } + return $this->getNumIndex($content, $tag, $reallyNum); + } + } + + /** + * 对应Java的getNumIndex方法,找到第num个闭合标签的位置 + * @param string $content 内容 + * @param string $tag 标签名 + * @param int $num 第几个闭合标签 + * @return int|false 标签位置 + */ + private function getNumIndex($content, $tag, $num) { + $tagClose = ""; + $count = 0; + $index = -1; + + while (($index = strpos($content, $tagClose, $index + 1)) !== false) { + $count++; + if ($count === $num) { + return $index; + } + } + + return false; + } + + /** + * 对应Java的getTextRenderData方法,递归解析标签内容并应用样式 + * @param string $now 标签包裹的内容(如xxx) + * @param string $tag 标签名 + * @param array $style 样式数组(引用传递,深拷贝处理嵌套) + * @param array $textRenderData 输出的LaTeX内容列表 + */ + private function getTextRenderData($now, $tag, &$style, &$textRenderData) { + // 应用当前标签的样式 + $this->addStyle($style, $tag); + // 提取标签内的内容(去掉前后标签) + $tagOpen = "<{$tag}>"; + $tagClose = ""; + $content = substr($now, strlen($tagOpen), strlen($now) - strlen($tagOpen) - strlen($tagClose)); + + while (!empty($content)) { + $nextTag = $this->determineNextTag($content); + if ($nextTag === 'no') { + // 无子标签,应用样式并添加内容 + $styledContent = $this->applyStyleToContent($this->escapeLatexSpecialChars($content), $style); + $textRenderData[] = $styledContent; + $content = ''; + } else { + $subTagOpen = "<{$nextTag}>"; + $subBeginTag = strpos($content, $subTagOpen); + + // 子标签前的内容 + if ($subBeginTag > 0) { + $prefixContent = $this->escapeLatexSpecialChars(substr($content, 0, $subBeginTag)); + $styledPrefix = $this->applyStyleToContent($prefixContent, $style); + $textRenderData[] = $styledPrefix; + } + + // 找到子标签的最后闭合位置 + $subEndTag = $this->getLastTabIndex($content, $nextTag); + if ($subEndTag === false) { + // 无闭合标签,保留原内容 + $textRenderData[] = $this->escapeLatexSpecialChars(substr($content, $subBeginTag)); + $content = ''; + continue; + } + + // 子标签包裹的内容 + $subNow = substr( + $content, + $subBeginTag, + $subEndTag - $subBeginTag + strlen("") + ); + + // 深拷贝样式(避免父级样式被修改) + $newStyle = $this->deepCopy($style); + // 递归解析子标签 + $this->getTextRenderData($subNow, $nextTag, $newStyle, $textRenderData); + + // 剩余内容 + $content = substr($content, $subEndTag + strlen("")); + } + } + } + + /** + * 对应Java的deepCopy方法,深拷贝样式数组 + * @param array $original 原始样式 + * @return array 拷贝后的样式 + */ + private function deepCopy($original) { + // 由于样式是简单数组,直接使用数组拷贝即可 + return $original; + } + + /** + * 对应Java的determineNextTag方法,确定下一个匹配的标签 + * @param string $content 待检查的内容 + * @return string 标签名或'no' + */ + private function determineNextTag($content) { + $tagPattern = '/<(' . implode('|', $this->supportedTags) . ')>/i'; + if (preg_match($tagPattern, $content, $matches)) { + return $matches[1]; + } + return 'no'; + } + + /** + * 对应Java的addStyle方法,根据标签设置样式 + * @param array $style 样式数组(引用传递) + * @param string $tag 标签名 + */ + private function addStyle(&$style, $tag) { + switch ($tag) { + case 'sup': + $style['vertAlign'] = 'superscript'; + break; + case 'sub': + $style['vertAlign'] = 'subscript'; + break; + case 'blue': + $style['color'] = $this->colorMap['blue']; + break; + case 'b': + $style['bold'] = true; + break; + case 'i': + $style['italic'] = true; + break; + case 't': + $style['color'] = $this->colorMap['t']; + break; + case 'r': + $style['color'] = $this->colorMap['r']; + break; + // tr标签已被移除,无需处理 + } + } + + /** + * 将样式应用到内容上,生成对应的LaTeX命令 + * @param string $content LaTeX内容 + * @param array $style 样式数组 + * @return string 应用样式后的LaTeX内容 + */ + private function applyStyleToContent($content, $style) { + if (empty($style)) { + return $content; + } + + // 处理加粗 + if (isset($style['bold']) && $style['bold']) { + $content = "\\textbf{{$content}}"; + } + + // 处理斜体 + if (isset($style['italic']) && $style['italic']) { + $content = "\\textit{{$content}}"; + } + + // 处理颜色(LaTeX需要xcolor包,支持HTML十六进制颜色) + if (isset($style['color'])) { + $color = $style['color']; + $content = "\\textcolor[HTML]{{$color}}{{$content}}"; + } + + // 处理上标 + if (isset($style['vertAlign']) && $style['vertAlign'] === 'superscript') { + // LaTeX上标需要考虑嵌套,用{}包裹内容 + $content = "^{{$content}}"; + } + + // 处理下标 + if (isset($style['vertAlign']) && $style['vertAlign'] === 'subscript') { + $content = "_{{$content}}"; + } + + return $content; + } + + /** + * 转义LaTeX特殊字符,避免编译错误 + * @param string $text 原始文本 + * @return string 转义后的文本 + */ + private function escapeLatexSpecialChars($text) { + $specialChars = [ +// '\\' => '\\textbackslash', +// '{' => '\\{', +// '}' => '\\}', + '$' => '\\$', + '%' => '\\%', + '#' => '\\#', + '&' => '\\&', + '_' => '\\_', + '^' => '\\textasciicircum', + '~' => '\\textasciitilde', + ]; + return strtr($text, $specialChars); + } + + /** * 生成单个 BibTeX 条目 * @param array $ref 参考文献数据 @@ -2104,38 +2444,20 @@ class Production extends Base private function generateBibEntry($ref) { // 使用 DOI 或索引作为 citation key - $citationKey = $this->generateCitationKey($ref); + $citationKey = 'ref_' . $ref['p_refer_id']; // 如果有解析后的作者和标题信息,优先使用 if (!empty($ref['author']) && !empty($ref['title'])) { return $this->generateFromParsedData($ref, $citationKey); - } - // 否则尝试从原始内容解析 + } // 否则尝试从原始内容解析 else { - return ; + return; // return $this->generateFromRawContent($ref, $citationKey); } } - /** - * 生成 citation key - * @param array $ref 参考文献数据 - * @return string citation key - */ - private function generateCitationKey($ref) - { - if (!empty($ref['refer_doi'])) { - // 使用 DOI 的部分作为 key - $parts = explode('/', $ref['refer_doi']); - if (count($parts) > 1) { - return str_replace('.', '_', end($parts)); - } - } - // 默认使用索引 - return 'ref_' . $ref['p_refer_id']; - } - private function parsePublicationInfo($referenceText) + private function parsePublicationInfo($referenceText) { $result = [ 'year' => '', @@ -2202,7 +2524,6 @@ class Production extends Base } - /** * 从解析后的数据生成 BibTeX 条目 * @param array $ref 参考文献数据 @@ -2258,20 +2579,155 @@ class Production extends Base } + + + /** + * 将文章正文中的引用标记转换为LaTeX格式 + * @param string $content 文章正文内容 + * @param array $references 引用数组,键为索引(int-1),值为引用对象 + * @return string 转换后的内容 + */ +// private function convertReferencesToLatex($content, $references) +// { +// // 匹配 [1] 或 [1,2] 或 [1,2,3] 等格式 +// return preg_replace_callback('/\[(\d+(?:,\d+)*)\]/', function ($matches) use ($references) { +// $indices = explode(',', $matches[1]); +// $latexRefs = []; +// +// foreach ($indices as $index) { +// // 数据库索引从1开始,数组索引从0开始,所以需要减1 +// $arrayIndex = $index - 1; +// +// if (isset($references[$arrayIndex]) && !empty($references[$arrayIndex]['p_refer_id'])) { +// $latexRefs[] = 'ref_' . $references[$arrayIndex]['p_refer_id']; +// } else { +// // 如果找不到对应引用,保持原来的数字格式 +// $latexRefs[] = $index; +// } +// } +// +// return '\parencite{' . implode(',', $latexRefs) . '}'; +// }, $content); +// } + + + private function convertReferencesToLatex($content, $references) + { + // 匹配 [1], [1,2], [2-4], [1,3-6] 等格式,并处理相邻的 标签 + return preg_replace_callback( + '/(?:)?\[(\d+(?:[-,]\d+)*)\](?:<\/blue>)?/', + function ($matches) use ($references) { + // 去除匹配中的 + $cleanedMatch = str_replace(['', ''], '', $matches[0]); + + // 提取引用编号部分(去掉方括号) + $referencePart = trim($cleanedMatch, '[]'); + + // 分割逗号分隔的不同引用项 + $parts = explode(',', $referencePart); + $latexRefs = []; + + foreach ($parts as $part) { + // 判断是否是范围形式如 3-5 + if (strpos($part, '-') !== false) { + list($start, $end) = explode('-', $part); + $start = intval($start); + $end = intval($end); + + // 展开范围并逐个查找 ref_id + for ($i = $start; $i <= $end; $i++) { + $arrayIndex = $i; + if (isset($references[$arrayIndex]) && !empty($references[$arrayIndex]['p_refer_id'])) { + $latexRefs[] = 'ref_' . $references[$arrayIndex]['p_refer_id']; + } else { + $latexRefs[] = $i; + } + } + } else { + // 单个引用编号处理 + $index = intval($part); + $arrayIndex = $index; + + if (isset($references[$arrayIndex]) && !empty($references[$arrayIndex]['p_refer_id'])) { + $latexRefs[] = 'ref_' . $references[$arrayIndex]['p_refer_id']; + } else { + $latexRefs[] = $index; + } + } + } + + return '\parencite{' . implode(',', $latexRefs) . '}'; + }, + $content + ); + } + + /** + * 处理文章正文中的引用标记 + * @param int $p_article_id 文章ID + * @return void + */ +// public function processArticleReferences() +// { +// $data = $this->request->post(); +// $rule = new Validate([ +// 'article_id' => 'require|number' +// ]); +// +// if (!$rule->check($data)) { +// return jsonError($rule->getError()); +// } +// +// // 获取文章信息 +// $particle = $this->production_article_obj->where('article_id', $data['article_id'])->find(); +// if (!$particle) { +// return jsonError('文章不存在'); +// } +// +// // 获取该文章的所有引用 +// $references = $this->production_article_refer_obj +// ->where('p_article_id', $particle['p_article_id']) +// ->where('state', 0) +// ->order('index ASC') +// ->select(); +// +// +// $refArray = []; +// foreach ($references as $ref) { +// $refArray[$ref['index'] + 1] = $ref; +// } +// +// +// $mainContents = $this->article_main_obj->where("article_id", $data['article_id'])->where("type", 0)->where("state", 0)->order("sort asc")->select(); +// +// +// $frag = []; +// // 处理每个正文段落 +// foreach ($mainContents as $main) { +// $updatedContent = $this->convertReferencesToLatex($main['content'], $refArray); +// $frag[] = $updatedContent; +// // 更新处理后的内容 +// } +// +// return jsonSuccess($frag); +// } + + /** * 格式化作者信息为BibTeX格式 * @param string $authors 作者字符串,如 "Li Y, Yang C, Zhao H, Qu S, Li X, Li Y" * @return string 格式化后的作者字符串,如 "Li, Y. and Yang, C. and Zhao, H. and Qu, S. and Li, X. and Li, Y." */ - private function formatBibTeXAuthors($authors) { + private function formatBibTeXAuthors($authors) + { $authors = rtrim($authors, ". \t\n\r\0\x0B"); // 如果包含"et al",则原样保留 - if (stripos($authors, 'et al') !== false) { - return $authors; - } +// if (stripos($authors, 'et al') !== false) { +// return $authors; +// } // 按逗号分割各个作者 - $authorArray = array_map('trim', explode(',', $authors)); + $authorArray = array_map('trim', explode(', ', $authors)); $formattedAuthors = []; foreach ($authorArray as $author) { @@ -2286,7 +2742,7 @@ class Production extends Base // 最后一个是姓氏,前面的是名字首字母 $lastName = array_pop($authorParts); $firstName = implode(' ', $authorParts); - $formattedAuthors[] = $firstName.", ".$lastName; + $formattedAuthors[] = $lastName . ", " . $firstName; // $firstNameInitials = implode('. ', $authorParts) . '.'; // $formattedAuthors[] = $lastName . ', ' . $firstNameInitials; } else { @@ -2338,72 +2794,39 @@ class Production extends Base return $text; } - -// 在 Production 控制器中添加以下方法: - -// 在 Production.php 中添加以下方法: - -/** - * 生成 BibTeX 文件 - */ -public function generateBibtex() -{ - $data = $this->request->post(); - $rule = new Validate([ - 'p_article_id' => 'require|number' - ]); - - if (!$rule->check($data)) { - return jsonError($rule->getError()); - } - - try { - // 创建数据库连接 - $db = Db::connect(); - $generator = new ReferenceBibGenerator($db); - - // 生成 BibTeX 文件 - $filePath = $generator->generateBibFile($data['p_article_id']); - - // 返回相对路径供前端使用 - $relativePath = str_replace(ROOT_PATH . 'public' . DS, '', $filePath); - - return jsonSuccess([ - 'file_path' => $relativePath, - 'full_path' => $filePath + /** + * 生成 BibTeX 文件 + */ + public function generateBibtex() + { + $data = $this->request->post(); + $rule = new Validate([ + 'p_article_id' => 'require|number' ]); - } catch (Exception $e) { - return jsonError('生成 BibTeX 文件失败: ' . $e->getMessage()); - } -} + if (!$rule->check($data)) { + return jsonError($rule->getError()); + } -/** - * 下载 BibTeX 文件 - */ -public function downloadBibtex() -{ - $p_article_id = $this->request->param('p_article_id', 0); + try { + // 创建数据库连接 + $db = Db::connect(); + $generator = new ReferenceBibGenerator($db); + // 生成 BibTeX 文件 + $filePath = $generator->generateBibFile($data['p_article_id']); + // 返回相对路径供前端使用 + $relativePath = str_replace(ROOT_PATH . 'public' . DS, '', $filePath); + return jsonSuccess([ + 'file_path' => $relativePath, + 'full_path' => $filePath + ]); - if (!$p_article_id) { - return jsonError('缺少参数'); + } catch (Exception $e) { + return jsonError('生成 BibTeX 文件失败: ' . $e->getMessage()); + } } - $filePath = ROOT_PATH . 'public' . DS . 'bibtex' . DS . 'references_' . $p_article_id . '.bib'; - if (!file_exists($filePath)) { - return jsonError('文件不存在'); - } - - // 设置下载头信息 - header('Content-Type: application/x-bibtex'); - header('Content-Disposition: attachment; filename="references_' . $p_article_id . '.bib"'); - header('Content-Length: ' . filesize($filePath)); - - // 输出文件内容 - readfile($filePath); - exit; -} public function getFragBF() @@ -2420,7 +2843,7 @@ public function downloadBibtex() $z = count($list); $m = 0; foreach ($list as $v) { - if ($v['refer_frag'] != ''||$v['author']!='') { + if ($v['refer_frag'] != '' || $v['author'] != '') { $m++; } } @@ -2503,7 +2926,7 @@ public function downloadBibtex() $updata['bibtex'] = $data['fileURL']; } elseif ($data['filetype'] == 'CDF') { $updata['file_cdf'] = $data['fileURL']; - }elseif ($data['filetype'] == 'Original') { + } elseif ($data['filetype'] == 'Original') { $updata['file_original'] = $data['fileURL']; } $this->production_article_obj->where('p_article_id', $data['p_article_id'])->update($updata); @@ -2592,7 +3015,6 @@ public function downloadBibtex() } - /** * 作者反馈proof */ @@ -2632,19 +3054,19 @@ public function downloadBibtex() } - public function myproofAdd(){ + public function myproofAdd() + { $article_id = $this->request->post("article_id"); self::pdfAddProof($article_id); } - /** * @title 文章文件上传 - * + * * @param name:name type:string require:1 desc:文件域名称(articleSUB/articleSUB2/bibTex/endNote/articleCDF/articleOriginal) * @param name:type type:string require:1 desc:pathinfo(articleSUB/articleSUB2/bibTex/endNote/articleCDF/articleOriginal) - * + * * @return upurl:图片地址 */ public function up_article_file($type) @@ -2681,9 +3103,9 @@ public function downloadBibtex() // } // } // } - $os = $this->production_article_author_to_organ_obj->where('p_article_id',$p_article_id)->where('state',0)->column('p_article_organ_id'); - $ors = $this->production_article_organ_obj->where('p_article_organ_id','in',$os)->select(); - foreach($ors as $v){ + $os = $this->production_article_author_to_organ_obj->where('p_article_id', $p_article_id)->where('state', 0)->column('p_article_organ_id'); + $ors = $this->production_article_organ_obj->where('p_article_organ_id', 'in', $os)->select(); + foreach ($ors as $v) { $address[] = $v['organ_name']; } @@ -2725,10 +3147,10 @@ public function downloadBibtex() $address1 = []; foreach ($address as $k => $v) { $address_str .= ($k + 1) . ' ' . $v . ' '; - $address1[] = [ - "k"=>$k + 1, - "content"=>$v - ]; + $address1[] = [ + "k" => $k + 1, + "content" => $v + ]; } $frag['author'] = $author; $frag['address'] = $address_str; @@ -2775,7 +3197,8 @@ public function downloadBibtex() /**上传最终版文章word文件 * @return \think\response\Json|void */ - public function up_last_artFile(){ + public function up_last_artFile() + { $file = request()->file('completedManuscirpt'); if ($file) { $info = $file->move(ROOT_PATH . 'public' . DS . 'completedManuscirpt');