diff --git a/application/api/controller/Article.php b/application/api/controller/Article.php
index f221c49..308fc5f 100644
--- a/application/api/controller/Article.php
+++ b/application/api/controller/Article.php
@@ -1577,7 +1577,6 @@ class Article extends Base
$update_data['rstime'] = time();
}
$this->article_obj->where($where_article)->update($update_data);
-
//拒稿或者录用 - 发送审稿意见
if ($article_info['journal_id'] == 1 && ($data['state'] == 3 || $data['state'] == 5)) {
$this->sendEmailToReviewer($data['articleId'], $data['state']);
@@ -6241,4 +6240,92 @@ class Article extends Base
}
return ['status' => 1,'msg' => 'success'];
}
+
+ /**
+ * 添加图片版权声明文件-编辑
+ */
+ public function addFigureCopyrightForEditor($aParam = []){
+ //获取参数
+ $aParam = empty($aParam) ? $this->request->post() : $aParam;
+
+ //获取文章ID
+ $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id'];
+ if(empty($iArticleId)){
+ return json_encode(['status' => 2,'msg' => 'Please select the article']);
+ }
+ //用户ID
+ $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id'];
+ if(empty($iUserId)){
+ return json_encode(['status' => 2,'msg' => 'Please select author']);
+ }
+ // //是否上传文件
+ // $is_figure_copyright = empty($aParam['is_figure_copyright']) ? 3 : $aParam['is_figure_copyright'];
+ // if($is_figure_copyright == 3){
+ // return json_encode(['status' => 3,'msg' => 'Please check whether to upload the figure copyright statement']);
+ // }
+
+ //获取操作人信息
+ $aWhere = ['user_id' => $iUserId,'state' => 0];
+ $aUser = Db::name('user')->field('account')->where($aWhere)->find();
+ if(empty($aUser)){
+ return json_encode(['status' => 5,'msg' => 'No operator information found']);
+ }
+ //获取文章信息
+ $aWhere = ['article_id' => $iArticleId];
+ $aArticle = Db::name('article')->field('article_id,state,editor_id,journal_id')->where($aWhere)->find();
+ if(empty($aArticle)){
+ return json_encode(['status' => 6,'msg' => 'The article does not exist']);
+ }
+ //判断是否有权限操作
+ if($iUserId != $aArticle['editor_id']){
+ return json_encode(['status' => 7,'msg' => 'Unauthorized operation']);
+ }
+ //查询期刊负责编辑
+ $aWhere = ['journal_id' => $aArticle['journal_id'],'state' => 0];
+ $aJournal = Db::name('journal')->field('editor_id')->where($aWhere)->find();
+ if(empty($aJournal)){
+ return json_encode(['status' => 7,'msg' => 'No article or journal information found']);
+ }
+ if($iUserId != $aJournal['editor_id']){
+ return json_encode(['status' => 7,'msg' => 'No operation permission']);
+ }
+ //图片路径
+ // if($is_figure_copyright == 1){
+ //文件地址
+ $sUrl = empty($aParam['url']) ? '' : $aParam['url'];
+ if(empty($sUrl)){
+ return json_encode(['status' => 4,'msg' => 'Please choose to upload the file']);
+ }
+ // }
+
+ //文件类型
+ $sTypeName = 'figurecopyright';
+ $sUserAccount = empty($aUser['account']) ? '' : $aUser['account'];
+ Db::startTrans();
+ if(!empty($sUrl)){
+ //验证文件是否上传
+ $aWhere = ['file_url' => $sUrl,'state' => 0,'article_id' => $iArticleId,'type_name' => $sTypeName];
+ $result = Db::name('article_file')->where($aWhere)->find();
+ if(empty($result)){
+ $aInsert['article_id'] = $iArticleId;
+ $aInsert['user_id'] = $iUserId;
+ $aInsert['username'] = $sUserAccount;
+ $aInsert['file_url'] = $sUrl;
+ $aInsert['type_name'] = $sTypeName;
+ $aInsert['ctime'] = time();
+ $result = Db::name('article_file')->insertGetId($aInsert);
+ }
+ }
+ // //更新文章内容
+ // $aArticleUpdate = ['is_figure_copyright' => $is_figure_copyright];
+ // if(!empty($aArticleUpdate)){
+ // $aWhere = ['article_id' => $iArticleId];
+ // $update_result = Db::name('article')->where($aWhere)->limit(1)->update($aArticleUpdate);
+ // }
+ //操作日志
+ $aLog = ['article_id' => $iArticleId,'user_id' => $iUserId,'type' => 7,'create_time' => time(),'content' => $sUserAccount . ':Operating the article copyright statement','is_view' => 1];
+ Db::name('user_act_log')->insert($aLog);
+ Db::commit();
+ return json_encode(['status' => 1,'msg' => 'success']);
+ }
}
diff --git a/application/common/LatexContent.php b/application/common/LatexContent.php
index 3df09b1..d1d00f4 100644
--- a/application/common/LatexContent.php
+++ b/application/common/LatexContent.php
@@ -37,7 +37,7 @@ year={{stage_year}},%年
volume={{stage_vol}},%卷
no={{stage_no}},%期
page={{stage_page}},%号
-]{tmr-tex}
+]{../tmr-tex}
\doi{{{doi}}}
\journalweb{{{website}}}
@@ -49,18 +49,15 @@ page={{stage_page}},%号
\usepackage[nopatch]{microtype}
\usepackage{booktabs}
\usepackage[backend=biber]{biblatex}
-\usepackage{xcolor} % 蓝色字体(参考文献)
-\usepackage{multirow} % 单元格合并(必选)
-\usepackage{array} % 列格式居中(必选)
-\usepackage{geometry} % 页面适配,避免内容溢出
-\addbibresource{example.bib}
+\usepackage{xcolor}
+\usepackage{tabularray}
+\addbibresource{references_{{p_article_id}}.bib}
+\definecolor{evenRowColor}{RGB}{250,231,232}
\title{{{article_title}}}
{{author_info}}
-\addbibresource{example.bib}
-
{{correspondence_info}}
@@ -87,6 +84,8 @@ page={{stage_page}},%号
\twocolumn
{{tmr_highlight}}
{{article_main}}
+ \nocite{*}
+ \printbibliography[title={References}]
\end{document}';
/**
* 生成初稿-基本内容
@@ -211,6 +210,7 @@ page={{stage_page}},%号
$aSearch['{{article_icon}}'] = $sIcon;
$aSearch['{{keywords}}'] = $sKeywords;
$aSearch['{{CLSFILEURL}}'] = ROOT_PATH.'public/latex/cls';
+ $aSearch['{{p_article_id}}'] = $aProductionArticle['p_article_id'];
//模版内容替换
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
//返回内容
@@ -220,8 +220,11 @@ page={{stage_page}},%号
* 生成初稿-主内容
* @param article_id 文章ID
*/
- public function buildMain($aProductionArticle = []){
-
+ public function buildMain($aParam = []){
+ //生产环境文章信息
+ $aProductionArticle = empty($aParam['production_article']) ? [] : $aParam['production_article'];
+ //参考文献信息
+ $aReferences = empty($aParam['references']) ? [] : $aParam['references'];
//获取模版
$sTemplateInfo = $this->sMain;
@@ -256,17 +259,14 @@ 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')->field('amt_id,type,table_data,url,title,note')->where($aWhere)->select();
- $aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
//获取图片模版
$sImageTempalte = $this->sImageTempalte;
//数据处理
$iStart = 0;
$sMain = '';
$oLatexTable = new LaTeXTable;
+ //字符串处理
+ $oProduction = new \app\api\controller\Production;
foreach ($aArticleMain as $key => $value) {
if(empty($iStart)){
if($value['is_h1'] == 0){
@@ -296,7 +296,7 @@ page={{stage_page}},%号
}
if($value['is_h1'] == 0 && $value['is_h2'] == 0 && $value['is_h3'] == 0){
if($value['type'] == 0 ){
- $sMain .= $this->dealContent($value['content'])."\\par\n";
+ $sMain .= $this->dealContent($value['content'],$aReferences)."\\par\n";
}
if($value['type'] == 1 ){//图片
$aImageInfo = empty($aArticleMainImage[$value['ami_id']]) ? [] : $aArticleMainImage[$value['ami_id']];
@@ -321,8 +321,11 @@ page={{stage_page}},%号
$sMain .= $sImageTempalteInfo."\\par\n";
}
if($value['type'] == 2 ){//表格
- continue;
+ $sTableInfo = $oProduction->tableCovertLatex($value['amt_id'],$aReferences);
+ var_dump($sTableInfo);
+ $sMain .= $sTableInfo."\\par\n";
}
+
}
}
}
@@ -533,43 +536,72 @@ page={{stage_page}},%号
}
return trim($dateStr);
}
- /**
- * 内容处理
- */
- private function dealContent($content = '', $target = 'latex',$iIsDeal = 1) {
+ private function dealContent($content = '',$aReferences = []) {
// 空值直接返回
- if (empty($content)) {
+ if(empty($content)){
return '';
}
-
//统一编码为UTF-8
$content = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content));
//过滤不可见/非法字符
$content = preg_replace('/[\x00-\x1F\x7F]/u', '', $content);
- //整合所有替换规则(按优先级排序:先处理HTML实体,再处理LaTeX特殊字符)
- $replaceRules = [
- // ========== HTML实体替换 ==========
- ' ' => '~', // HTML非断行空格 → LaTeX非断行空格
- ' ' => '~', // 兼容无分号的 
- '&' => '\&', // HTML& → LaTeX转义&
- '<' => '<', // HTML< → 直接保留
- '>' => '>', // HTML> → 直接保留
- // ========== LaTeX特殊字符转义 ==========
- '{' => '\{', // 左花括号转义
- '}' => '\}', // 右花括号转义
- '&' => '\&', // 原生&转义(需在&之后,避免覆盖)
- '%' => '\%', // 百分号转义(LaTeX注释符)
- '_' => '\_', // 下划线转义(LaTeX下标符)
- 'κ' => '$\kappa$', // 希腊字母κ → LaTeX数学环境(避免乱码)
- '-' => '\text{-}', // 短横线强制保留形态
- ':' => ':', // 冒号无需转义(占位,便于统一维护)
+
+ //字符串处理
+ $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{',
+ '' => '}',
+ '
' => '', + '
' => '', + '' => '$_{', + '' => '}$', + '' => '$^{', + '' => '}$', + '~' => '--', // 波浪号→范围符 + '(' => '(', // 全角左括号→半角 + ')' => ')', // 全角右括号→半角 + '((' => '(', // 重复括号去重 + '))' => ')', + + // ========== 新增: 标签处理 ========== + // 场景1:纯空 标签(无属性)→ 直接删除,保留内容 + '' => '', + '' => '', + // 场景2:带蓝色样式的 → 转为 LaTeX 蓝色命令 + '' => '\textcolor{blue}{', + '' => '\textcolor{blue}{', // 兼容大小写/空格 + '' => '\textcolor{red}{', // 扩展:红色 + '' => '}', // 所有 span 闭标签统一转为 }(匹配开标签的 LaTeX 命令) + + // 扩展:其他常用 span 样式(按需添加) + '' => '\textbf{', + '' => '\textit{', ]; - //执行批量替换 - $content = strtr($content, $replaceRules); - //清理多余空格/换行 - $content = preg_replace('/\s+/u', ' ', trim($content)); - return $content; + // 第一步:替换所有标签(优先处理带属性的 span,再处理空 span) + $text = strtr($text, $replaceMap); + + // 第二步:清理残留的特殊 span 标签(如未匹配的属性,直接删除标签保留内容) + // 匹配 形式的标签(任意属性),仅删除标签,保留内容 + $text = preg_replace('/]*?)?>/i', '', $text); + $text = preg_replace('/<\/span>/i', '', $text); + + return $text; } /** * @title curl 请求获取图片保存到本地