Files
tougao/application/common/LatexContent.php
2026-02-04 10:47:40 +08:00

682 lines
31 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\common;
use think\Db;
use app\common\LatexTable;
/**
* LaTeX内容生成类
*/
class LatexContent{
//期刊相关的信息
private $iYear = 2026;//年
private $iPeriod = 1;//期
private $sAbbr = 'tmr';//期刊缩写
private $sWebsite = 'https://www.tmrjournals.com/tmr';//期刊官网
//模版地址
private $sLatexUrl = '/public/latex/';
//期刊官网接口地址
private $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php/';//'http://zmzm.journal.dev.com/';//
//文章图片
private $sArticleIcon = '/public/articleicon/';
//文章图片
private $sArticleMainImage = '/public/articleImage/';
//编辑系统URL
private $sSubmissionUrl = 'https://submission.tmrjournals.com/';
//图片模版
private $sImageTempalte = '\begin{figure}[hbt!]
\centering
\includegraphics[width=0.75\linewidth]{{{img_url}}}
\caption{{{img_title}}}
\label{{{img_fig_sim}}}
\end{figure}' ;
//首页内容
private $sFirst = '\documentclass[
journal={{journal_abbr}},
journalname={{{{journal_title}}}},
layout=largetwo,
year={{stage_year}},%年
volume={{stage_vol}},%卷
no={{stage_no}},%期
page={{stage_page}},%号
]{../tmr-tex}
\doi{{{doi}}}
\journalweb{{{website}}}
\usepackage{amsmath}
\usepackage[nopatch]{microtype}
\usepackage{booktabs}
\usepackage[backend=biber]{biblatex}
\usepackage{xcolor}
\usepackage{tabularray}
\addbibresource{references_{{article_id}}.bib}
\definecolor{evenRowColor}{RGB}{250,231,232}
\title{{{article_title}}}
{{author_info}}
{{correspondence_info}}
\keywords{keyword entry 1, keyword entry 2, keyword entry 3} %% First letter not capped
{{author_contribution}}
\competinginterests{The authors declare no conflicts of interest.}
{{article_acknowledgment}}
\Peerreviewinformation{{{journal_title}} thanks all anonymous reviewers for their contribution to the peer review of this paper}
{{article_abbreviation}}
{{article_cite}}
\received{{{received_date}}}
\revised{{{revision_date}}}
\accepted{{{accepted_date}}}
\Availableonline{{{pub_date}}}
{{executive_editor}}
{{abstract}}
{{keywords}}
{{article_icon}}';
//正文内容
private $sMain = '\begin{document}
\twocolumn
{{tmr_highlight}}
{{article_main}}
\nocite{*}
\printbibliography[title={References}]
\end{document}';
/**
* 生成初稿-基本内容
* @param article_id 文章ID
*/
public function buildFirst($aProductionArticle = []){
//获取模版
$sTemplateInfo = $this->sFirst;
//查询期刊信息
$iJournalId = empty($aProductionArticle['journal_id']) ? 0 : $aProductionArticle['journal_id'];
if(!empty($iJournalId)){
$aWhere = ['journal_id' => $iJournalId,'state' => 0];
$aJournal = Db::name('journal')->where($aWhere)->find();
if(!empty($aJournal)){
//获取编辑信息
$aWhere = ['user_id' => $aJournal['editor_id'],'state' => 0];
$aUser = Db::name('user')->field('realname')->where($aWhere)->find();
}
}
//子刊信息
$aJournalStage = [];
$iJournalStageId = empty($aProductionArticle['journal_stage_id']) ? 0 : $aProductionArticle['journal_stage_id'];
if(!empty($iJournalStageId)){
$aJournalStage = $this->getJournalStage(['journal_stage_id' => $iJournalStageId]);
$aJournalStage = empty($aJournalStage['data']) ? [] : $aJournalStage['data'];
}
//期刊简写
$sAbbr = $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'];
//期
$iPeriod = empty($aJournalStage['stage_no']) ? 0 : $aJournalStage['stage_no'];
//页
$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'].'}';
//文章基本信息处理
//标题
$sTitle = empty($aProductionArticle['title']) ? '' : $this->dealContent($aProductionArticle['title']);
if(!empty($sTitle)){
if(!empty($aProductionArticle['ltai'])){
$aLtai = explode(',', $aProductionArticle['ltai']);
foreach ($aLtai as $key => $value) {
if(empty($value)){
continue;
}
$sTitle = str_replace($value, '\textit{'.$value.'}', $sTitle);
}
}
}
$aSearch['{{article_title}}'] = $sTitle;
//author_contribution
$aSearch['{{author_contribution}}'] = empty($aProductionArticle['author_contribution']) ? '' : '\authorcontributions{'.$this->dealContent($aProductionArticle['author_contribution']).'}';
//acknowledgment
$aSearch['{{article_acknowledgment}}'] = empty($aProductionArticle['acknowledgment']) ? '' : '\Acknowledgments{'.$this->dealContent($aProductionArticle['acknowledgment']).'}';
//abbreviation
$aSearch['{{article_abbreviation}}'] = empty($aProductionArticle['abbreviation']) ? '' : '\Abbreviations{'.$this->dealContent($aProductionArticle['abbreviation']).'}';
//文章引用信息
$sCite = $this->getArticleCite($aProductionArticle,$aJournal,$aJournalStage);
$aSearch['{{article_cite}}'] = empty($sCite) ? '' : '\Citation{'.$sCite.'}';
//获取文章时间
$aTime = $this->getArticleTime(['article_id' => $aProductionArticle['article_id']]);
$aTime = empty($aTime['data']) ? [] : $aTime['data'];
$aSearch['{{received_date}}'] = empty($aTime['received_date']) ? '' : $aTime['received_date'];
$aSearch['{{revision_date}}'] = empty($aTime['revision_date']) ? '' : $aTime['revision_date'];
$aSearch['{{accepted_date}}'] = empty($aTime['accepted_date']) ? '' : $aTime['accepted_date'];
$aSearch['{{pub_date}}'] = empty($aProductionArticle['pub_date']) ? '' : $aProductionArticle['pub_date'];
//获取编辑信息
$executive_editor = empty($aProductionArticle['executive_editor']) ? '' : '\Executiveeditor{'.$this->dealContent($aProductionArticle['executive_editor']).'}';
$executive_editor_realname = empty($aUser['realname']) ? '' : '\Executiveeditor{'.$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:}}'];
$sAbstract = str_replace(array_keys($aRelace), array_values($aRelace), $sAbstract);
$sAbstract = '\tmrabstract{'.$sAbstract.'}';
}
$aSearch['{{abstract}}'] = $sAbstract;
//关键词
$sKeywords = empty($aProductionArticle['keywords']) ? '' : '\keywords{'.$this->dealContent($aProductionArticle['keywords']).'}';
$aSearch['{{keywords}}'] = $sKeywords;
//文章图片地址
$sIcon = empty($aProductionArticle['icon']) ? '' : $aProductionArticle['icon'];
if(!empty($sIcon)){
$sIconUrl = ROOT_PATH.trim($this->sArticleIcon,'/').'/'.$sIcon;
if(file_exists($sIconUrl)){
$sIconUrl = str_replace(ROOT_PATH.'public/', '', $sIconUrl);
$sIconUrl = '../../'.$sIconUrl;
$sIcon = '\KeywordImage{'.$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['{{keywords}}'] = $sKeywords;
// $aSearch['{{CLSFILEURL}}'] = ROOT_PATH.'public/latex/cls';
$aSearch['{{article_id}}'] = $aProductionArticle['article_id'];
//模版内容替换
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
//返回内容
return ['status' => 1,'msg' => 'success','data' => $sTemplateInfo];
}
/**
* 生成初稿-主内容
* @param article_id 文章ID
*/
public function buildMain($aParam = []){
//生产环境文章信息
$aProductionArticle = empty($aParam['production_article']) ? [] : $aParam['production_article'];
//参考文献信息
$aReferences = empty($aParam['references']) ? [] : $aParam['references'];
//获取模版
$sTemplateInfo = $this->sMain;
//数据替换
$aSearch = ['{{tmr_highlight}}' => '','{{article_main}}' => ''];
$sHighlight = '';
if($aProductionArticle['journal_id'] == 1){//tmr独有
$tradition_tag = empty($aProductionArticle['tradition_tag']) ? '' : strtolower( $aProductionArticle['tradition_tag']);
$tradition = empty($aProductionArticle['tradition']) ? '' : $this->dealContent($aProductionArticle['tradition']);
$pattern = '/<em[^>]*>(.*?)<\/em>/is';
$replacement = '\\emph{$1}';
// $tradition = preg_replace($pattern, $replacement, $tradition);
if(in_array($tradition_tag, ['highlight','highlights']) && !empty($tradition)){
$sHighlight .= '\highlightitem{Highlights}{'.$tradition.'}'."\n";
}
$mhoo = empty($aProductionArticle['mhoo']) ? '' : $this->dealContent( $aProductionArticle['mhoo']);
$mhoo = preg_replace($pattern, $replacement, $mhoo);
if(!empty($mhoo)){
$sHighlight .= '\highlightitem{Medical history of objective}{'.$mhoo.'}'."\n";
}
}
$aSearch['{{tmr_highlight}}'] = empty($sHighlight) ? '' : '\begin{highlight}'."\n".$sHighlight."\n".'\end{highlight}'."\n";
//查询正文信息
$aWhere = ['article_id' => $aProductionArticle['article_id'],'state' => 0];
$aArticleMain = Db::name('article_main')->field('am_id,article_id,type,content,ami_id,amt_id,is_h1,is_h2,is_h3,sort')->where($aWhere)->order('sort')->select();
if(!empty($aArticleMain)){
//查询图片
$aAmiId = array_unique(array_column($aArticleMain, 'ami_id'));
$aWhere = ['ami_id' => ['in',$aAmiId],'state' => 0];
$aArticleMainImage = Db::name('article_main_image')->field('ami_id,url,note')->where($aWhere)->select();
$aArticleMainImage = empty($aArticleMainImage) ? [] : array_column($aArticleMainImage, null,'ami_id');
//查询表格
$aAmtId = array_unique(array_column($aArticleMain, 'amt_id'));
$aWhere = ['amt_id' => ['in',$aAmtId],'state' => 0];
$aArticleMainTable = Db::name('article_main_table')->field('amt_id,type,table_data,url,title,note')->where($aWhere)->select();
$aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
//获取图片模版
$sImageTempalte = $this->sImageTempalte;
//长表格ID
$aLongTableId = [];
//数据处理
$iStart = 0;
$sMain = '';
//字符串处理
$oProduction = new \app\api\controller\Production;
foreach ($aArticleMain as $key => $value) {
if(empty($iStart)){
if($value['is_h1'] == 0){
continue;
}else{
$iStart = $value['am_id'];
}
}
if($value['am_id'] >= $iStart){
if($value['is_h1'] == 1){
if(empty($value['content'])){
continue;
}
$sMain .= '\section{'.$this->dealContent($value['content']).'}'."\n";
}
if($value['is_h2'] == 1){
if(empty($value['content'])){
continue;
}
$sMain .= '\subsection{'.$this->dealContent($value['content']).'}'."\n";
}
if($value['is_h3'] == 1){
if(empty($value['content'])){
continue;
}
$sMain .= '\subsubsection{'.$this->dealContent($value['content']).'}'."\n";
}
if($value['is_h1'] == 0 && $value['is_h2'] == 0 && $value['is_h3'] == 0){
if($value['type'] == 0 ){
//处理内容
$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']];
if(empty($aImageInfo['url'])){
continue;
}
$sMainImageUrl = ROOT_PATH.trim($this->sArticleMainImage,'/').'/'.$aImageInfo['url'];
if(!file_exists($sMainImageUrl)){
continue;
}
// //下载图片
// $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 ){//表格
$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,'long_table_id' => $aLongTableId];
}
/**
* 生成初稿-作者信息
*/
private function dealAuthor($aParam = []){
// 获取作者信息
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//必填值验证
$iPArticleId = empty($aParam['p_article_id']) ? '' : $aParam['p_article_id'];
if(empty($iPArticleId)){
return json_encode(array('status' => 2,'msg' => 'Please select an article' ));
}
//
//查询作者信息
$aWhere = ['p_article_id' => $iPArticleId,'state' => 0];
$aAuthor = Db::name('production_article_author')->where($aWhere)->select();
if(empty($aAuthor)){
return ['status' => 3,'msg' => 'Author information is empty'];
}
//查询作者机构
$aWhere['p_article_author_id'] = ['in',array_column($aAuthor, 'p_article_author_id')];
$aAuthorOrgan = Db::name('production_article_author_to_organ')->field('p_article_author_id,p_article_organ_id')->where($aWhere)->select();
//查询机构信息
$aAuthorOrganList = [];
if(!empty($aAuthorOrgan)){
unset($aWhere['p_article_author_id']);
$aOrganId = array_unique(array_column($aAuthorOrgan, 'p_article_organ_id'));
$aWhere['p_article_organ_id'] = ['in',$aOrganId];
$aOrgan = Db::name('production_article_organ')->where($aWhere)->column('p_article_organ_id,organ_name');
if(!empty($aOrgan)) {
foreach ($aAuthorOrgan as $key => $value) {
if(empty($aOrgan[$value['p_article_organ_id']])){
continue;
}
$aAuthorOrganList[$value['p_article_author_id']][] = $aOrgan[$value['p_article_organ_id']];
}
}
}
//处理作者
$sAuthor = $sCorrespondence = '';
foreach ($aAuthor as $key => $value) {
//作者姓名
$sName = empty($value['fifirst_name']) ? '' : $value['fifirst_name'];
$sName = empty($sName) ? '' : $sName . ' ' .$value['last_name'];
if(empty($sName)){
$sName = empty($value['author_name']) ? '' : $value['author_name'];
}
if(empty($sName)){
continue;
}
$sAuthor .= '\author{'.$this->dealContent($sName).'}'."\n";
if(!empty($value['email']) && $value['is_report'] == 1){
$sAuthor .= '\email{'.$this->dealContent($value['email']).'}'."\n";
}
//作者机构
$aOrganList = empty($aAuthorOrganList[$value['p_article_author_id']]) ? [] : $aAuthorOrganList[$value['p_article_author_id']];
if(!empty($aOrganList)){
$i = 0;
foreach($aOrganList as $organ){
if(empty($organ)){
continue;
}
if($i == 0){
$sAuthor .= '\affiliation{'.$this->dealContent($organ).'}'."\n";
}else{
$sAuthor .= '\alsoaffiliation{'.$this->dealContent($organ).'}'."\n";
}
$i++;
}
}
if($value['is_first'] == 1){
$sAuthor .= '\firstauthor'."\n";
}
if(!empty($value['orcid'])){
$sAuthor .= '\orcid{'.$this->dealContent($value['orcid']).'}'."\n";
}
if($value['is_report'] == 1){
$sCorrespondence .= $sName;
if(!empty($aOrganList[0])){
$sCorrespondence .= ','.trim($this->dealContent($aOrganList[0]),'.');
}
if(!empty($value['email'])){
$sCorrespondence .= '.E-mail: '.trim($this->dealContent($value['email']),'.').'.';
}
}
}
return ['author' => $sAuthor,'correspondence' => $sCorrespondence];
}
/**
* 生成初稿-获取期刊分期信息
*/
private function getJournalStage($aParam = []){
// 获取分期ID
$aParam = empty($aParam) ? $this->request->post() : $aParam;
//必填值验证
$iJournalStageId = empty($aParam['journal_stage_id']) ? '' : $aParam['journal_stage_id'];
if(empty($iJournalStageId)){
return json_encode(array('status' => 2,'msg' => 'Please choose journal installment' ));
}
$sUrl = $this->sJournalUrl."api/Supplementary/getJournalStage";
$aResult = object_to_array(json_decode(myPost1($sUrl,$aParam)));
return $aResult;
}
/**
* 处理文章引用
* @param string $html
* @return string
*/
private function getArticleCite($aArticle = [],$aJournal = [],$aJournalStage = []){
$no = empty($aJournalStage['stage_no']) ? ':' : '(' . $aJournalStage['stage_no'] . '):';
$jabbr = empty($aJournal['jabbr']) ? '' : $aJournal['jabbr'];
$stage_year = empty($aJournalStage['stage_year']) ? '' : $aJournalStage['stage_year'];
$stage_vol = empty($aJournalStage['stage_vol']) ? '' : $aJournalStage['stage_vol'];
$aAbbr = empty($aArticle['abbr']) ? '' : explode(',', trim($aArticle['abbr']));
if(!empty($aAbbr)){
$sEnd = end($aAbbr);
if($sEnd != 'et al'){
$aArticle['abbr'] = implode(',', array_slice($aAbbr, 0,3));
if(!empty($aArticle['abbr'])){
$aArticle['abbr'] .= ', et al';
}
}
}
$sCite = '';
if ($aArticle['journal_id'] == 22) {
$sCite = $aArticle['abbr'] . '. ' . $aArticle['title'] . '[J]. ' . choiseJabbr($aArticle['article_id'],$jabbr) . ',' . $stage_year . ',' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
$sCite = $this->dealContent($sCite);
} else {
$sCite = $this->dealContent($aArticle['abbr']) . '. ' . $this->dealContent($aArticle['title']) . '. \textit{' . $this->dealContent(choiseJabbr($aArticle['article_id'], $jabbr)) . '}. ' . $stage_year . ';' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
}
return $sCite;
}
private function getArticleTime($aParam = []){
//必填值验证
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
if(empty($iArticleId)){
return array('status' => 2,'msg' => 'Please select an article' );
}
//查询文章
$aWhere = ['article_id' => $iArticleId];
$aArticle= Db::name('article')->field('ctime,received_time')->where($aWhere)->find();
if(empty($aArticle)){
return array('status' => 2,'msg' => 'The article does not exist' );
}
//获取文章记录
$aWhere = ['article_id' => $iArticleId,'state' => 0,'state_to' => ['in',[0,1,5]]];
$aArticleMsg = Db::name('article_msg')->field('state_from,state_to,ctime')->where($aWhere)->order('ctime deac')->select();
$iReceivedTime = $iRevisionTime = $iAcceptedTime = 0;
if(!empty($aArticleMsg)){
foreach ($aArticleMsg as $key => $value) {
if(empty($iReceivedTime) && $value['state_to'] == 0){
$iReceivedTime = $value['ctime'];
}
if(empty($iRevisionTime) && $value['state_to'] == 1){
$iRevisionTime = $value['ctime'];
}
if(empty($iAcceptedTime) && $value['state_to'] == 5){
$iAcceptedTime = $value['ctime'];
}
}
}
$iReceivedTime = empty($iReceivedTime) ? $aArticle['received_time'] : $iReceivedTime;
$iReceivedTime = empty($iReceivedTime) ? $aArticle['ctime'] : $iReceivedTime;
$aTime = [];
$aTime['received_date'] = empty($iReceivedTime) ? '' : $this->timestampToEnglishDate($iReceivedTime);
$aTime['revision_date'] = empty($iRevisionTime) ? '' : $this->timestampToEnglishDate($iRevisionTime);
$aTime['accepted_date'] = empty($iAcceptedTime) ? '' : $this->timestampToEnglishDate($iAcceptedTime);
return ['status' => 1,'msg' => 'success','data' => $aTime];
}
/**
* 时间戳转换为「d F Y」格式如 12 June 2025
* @param int $timestamp 时间戳如1749600000
* @return string 格式化后的英文日期
*/
private function timestampToEnglishDate($timestamp) {
//验证时间戳有效性
if (!is_numeric($timestamp) || $timestamp < 0) {
return '';
}
//设置本地化确保月份为英文全称兼容Linux/Windows
$locale = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'
? 'English_United States.1252'
: 'en_US.UTF-8';
setlocale(LC_TIME, $locale);
//格式化d=日无前导零、F=英文月份全称、Y=四位年 strftime的%e在Linux下是无前导零的日Windows用%#d
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$dateStr = strftime('%#d %B %Y', $timestamp); // Windows
} else {
$dateStr = strftime('%e %B %Y', $timestamp); // Linux/Mac
}
return trim($dateStr);
}
private function dealContent($content = '',$aReferences = []) {
// 空值直接返回
if(empty($content)){
return '';
}
//统一编码为UTF-8
$content = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content));
//过滤不可见/非法字符
$content = preg_replace('/[\x00-\x1F\x7F]/u', '', $content);
//字符串处理
$oProduction = new \app\api\controller\Production;
$sContent = $oProduction->convertToLatex($content,$aReferences);
return $sContent;
}
/**
* @title curl 请求获取图片保存到本地
* @param sPath 图片链接地址
*/
private function getImage($sPath = '',$iId = 0){
//判断参数
if(empty($sPath) || empty($iId)){
return ['status' => 2,'msg' => 'url is empty','data' => ''];
}
//获取图片名称
$aImageInfo = pathinfo($sPath);
//图片后缀名
$sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension'];
//图片地址
$sDir = ROOT_PATH.trim($this->sLatexUrl,'/').'/tex_'.$iId.'/image/';
$sImagePath = $sDir.basename($sPath);
if (file_exists($sImagePath)) {
return ['status' => 1,'msg' => 'success','data' => $sImagePath];
}
//下载图片
if (!is_dir($sDir)) {
mkdir($sDir, 0755, true);
}
//curl 请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$sPath); // 设置请求URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 设置返回数据而不是直接输出
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用SSL验证
$response = curl_exec($ch);
if (curl_errno($ch)) {
return ['status' => 3,'msg' => 'Error:' . curl_error($ch),'data' => $sImagePath];
}
//保存图片
file_put_contents($sImagePath, $response);
curl_close($ch);
return ['status' => 1,'msg' => 'success','data' => $sImagePath];
}
/**
* @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)];
}
}
?>