diff --git a/application/api/controller/Production.php b/application/api/controller/Production.php index 0e0b528..e05b064 100644 --- a/application/api/controller/Production.php +++ b/application/api/controller/Production.php @@ -3298,9 +3298,14 @@ class Production extends Base echo $res; } - public function tableCovertLatex($amt_id, $references) + public function tableCovertLatex($amt_id, $references,$aTableInfo = []) { - $table_info = $this->article_main_table_obj->where('amt_id', $amt_id)->find(); + if(empty($aTableInfo)){ + $table_info = $this->article_main_table_obj->where('amt_id', $amt_id)->find(); + }else{ + $table_info = $aTableInfo; + } + $tableData = json_decode($table_info['table_data'], true); // 检查JSON解码是否成功 @@ -3615,7 +3620,7 @@ class Production extends Base } //查询文章 - $aWhere = ['p_article_id' => $iPArticleId,'state' => 0]; + $aWhere = ['p_article_id' => $iPArticleId,'state' => ['in',[0,2]]]; $aProductionArticle = Db::name('production_article')->where($aWhere)->find(); if(empty($aProductionArticle)){ return json_encode(array('status' => 3,'msg' => 'No articles found' )); @@ -3638,20 +3643,87 @@ class Production extends Base return json_encode(array('status' => 5,'msg' => 'Article content retrieval failed')); } + //获取参考文献 + $aResult = $this->creatReferences($aProductionArticle); + $iStatus = empty($aResult['status']) ? 0 : $aResult['status']; + $sMsg = empty($aResult['msg']) ? 'Content generation failed-Reference' : $aResult['msg']; + $aResult = empty($aResult['data']) ? [] : $aResult['data']; + $sReferences = empty($aResult['references']) ? '' : $aResult['references'];//参考文献内容 + $aReferencesLists = empty($aResult['references_list']) ? [] : $aResult['references_list'];//参考文献数组 + if($iStatus != 1){ + return json_encode(array('status' => 8,'msg' => $sMsg)); + } + if(empty($sReferences)){ + return json_encode(array('status' => 9,'msg' => 'Article content retrieval failed')); + } + //生成主内容 - $aResult = $oLatexContent->buildMain($aProductionArticle); + $aResult = $oLatexContent->buildMain(['production_article' => $aProductionArticle,'references' => $aReferencesLists]); $iStatus = empty($aResult['status']) ? 0 : $aResult['status']; $sMsg = empty($aResult['msg']) ? 'Content generation failed-Main' : $aResult['msg']; $sMainTemplateInfo = empty($aResult['data']) ? '' : $aResult['data']; if($iStatus != 1){ - return json_encode(array('status' => 4,'msg' => $sMsg)); + return json_encode(array('status' => 6,'msg' => $sMsg)); } if(empty($sMainTemplateInfo)){ - return json_encode(array('status' => 5,'msg' => 'Article content retrieval failed')); + return json_encode(array('status' => 7,'msg' => 'Article content retrieval failed')); } - //生成文件 + //创建基础目录 + $sDir = ROOT_PATH . 'public' . DS . 'latex' . DS . 'tex_' . $iPArticleId; + if (!is_dir($sDir)) { + mkdir($sDir, 0755, true); + } + + //生成Reference文件 + $sFileUrl = $sDir. DS . 'references_' . $iPArticleId . '.bib'; + file_put_contents($sFileUrl, $sReferences); + if(!file_exists($sFileUrl)){ + return json_encode(array('status' => 10,'msg' => 'Reference file generation failed')); + } + + //生成运行文件.tex + $sTexName = 'article_' . $iPArticleId; + $sTexFileUrl = $sDir. DS . $sTexName .'.tex'; $sTemplateInfo = $sFirstTemplateInfo."\n".$sMainTemplateInfo; + file_put_contents($sTexFileUrl, $sTemplateInfo); return json_encode(array('status' => 1,'msg' => 'PDF generated successfully')); } + + /** + * 生成初稿-参考文献 + * @param p_article_id 生产环境文章信息 + */ + private function creatReferences($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]; + $aReferences = Db::name('production_article_refer')->where($aWhere)->order('index asc')->select(); + if(empty($aReferences)){ + return json_encode(array('status' => 3,'msg' => 'No reference information found' )); + } + //参考文献处理 + $sContent = "% BibTeX file generated for article ID: {$iPArticleId}\n"; + $sContent .= "% Generated on " . date('Y-m-d H:i:s') . "\n\n"; + $sReferences = ''; + $aReferencesLists = []; + foreach ($aReferences as $value) { + $aReferencesLists[$value['index'] + 1] = $value; + $sReferencesInfo = $this->generateBibEntry($value); + if(empty($sReferencesInfo)){ + continue; + } + $sReferences .= $sReferencesInfo . "\n\n"; + } + if(empty($sReferences)){ + return json_encode(array('status' => 4,'msg' => 'No reference information found' )); + } + $sContent .= $sReferences; + return ['status' => 1,'msg' => 'success','data' => ['references' => $sContent,'references_list' => $aReferencesLists]]; + } } diff --git a/application/common/LatexContent.php b/application/common/LatexContent.php index d1d00f4..14e10d7 100644 --- a/application/common/LatexContent.php +++ b/application/common/LatexContent.php @@ -14,7 +14,7 @@ class LatexContent{ //模版地址 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/'; //文章图片 @@ -259,6 +259,11 @@ page={{stage_page}},%号 $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')->where($aWhere)->select(); + $aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id'); //获取图片模版 $sImageTempalte = $this->sImageTempalte; //数据处理 @@ -316,16 +321,23 @@ page={{stage_page}},%号 if(empty($aResult['data'])){ continue; } - $aImageSearch = ['{{img_url}}' => $aResult['data'],'{{img_title}}' => $aImageInfo['note'],'{{img_fig_sim}}' => 'img_fig_sim_'.$value['ami_id']]; - $sImageTempalteInfo = str_replace(array_keys($aImageSearch), array_values($aImageSearch), $sImageTempalte); - $sMain .= $sImageTempalteInfo."\\par\n"; + // $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']; + $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); $sMain .= $sTableInfo."\\par\n"; } - } } } @@ -549,60 +561,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 = [ - // 基础标签转换 - '' => '\textit{', - '' => '}', - '' => '\textit{', - '' => '}', - '' => '\textbf{', - '' => '}', - '' => '\textcolor{blue}{', - '' => '}', - '

' => '', - '

' => '', - '' => '$_{', - '' => '}$', - '' => '$^{', - '' => '}$', - '~' => '--', // 波浪号→范围符 - '(' => '(', // 全角左括号→半角 - ')' => ')', // 全角右括号→半角 - '((' => '(', // 重复括号去重 - '))' => ')', - - // ========== 新增: 标签处理 ========== - // 场景1:纯空 标签(无属性)→ 直接删除,保留内容 - '' => '', - '' => '', - // 场景2:带蓝色样式的 → 转为 LaTeX 蓝色命令 - '' => '\textcolor{blue}{', - '' => '\textcolor{blue}{', // 兼容大小写/空格 - '' => '\textcolor{red}{', // 扩展:红色 - '' => '}', // 所有 span 闭标签统一转为 }(匹配开标签的 LaTeX 命令) - - // 扩展:其他常用 span 样式(按需添加) - '' => '\textbf{', - '' => '\textit{', - ]; - - // 第一步:替换所有标签(优先处理带属性的 span,再处理空 span) - $text = strtr($text, $replaceMap); - - // 第二步:清理残留的特殊 span 标签(如未匹配的属性,直接删除标签保留内容) - // 匹配 形式的标签(任意属性),仅删除标签,保留内容 - $text = preg_replace('/]*?)?>/i', '', $text); - $text = preg_replace('/<\/span>/i', '', $text); - - return $text; - } /** * @title curl 请求获取图片保存到本地 * @param sPath 图片链接地址 @@ -620,7 +580,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 +605,57 @@ 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图片代码 + 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)]; + } } ?> \ No newline at end of file