From fe8f66b5c79cf8aa8655aff8c0705b3b07a1afb1 Mon Sep 17 00:00:00 2001 From: chengxl Date: Mon, 12 May 2025 13:30:22 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=96=87=E7=AB=A0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Aiarticle.php | 831 +++++++++++++++++++++-- 1 file changed, 761 insertions(+), 70 deletions(-) diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php index 636b960..ca00917 100644 --- a/application/api/controller/Aiarticle.php +++ b/application/api/controller/Aiarticle.php @@ -4,6 +4,7 @@ use app\api\controller\Base; use think\Controller; use think\Db; use app\common\QrCodeImage; +use think\Cache; /** * @title 数据库接口 @@ -13,14 +14,23 @@ use app\common\QrCodeImage; class Aiarticle extends Base { - protected $sApiKey; + protected $aImage = [ + '640.png' => ['media_id' => 'Cn8zlXvVB5DwjcA9h40z9eW0lwKRJjo_skJ0AmRAwthNP62sxfHGXoC1uIBqzhtc','url' => 'http://mmbiz.qpic.cn/mmbiz_png/QHFVW13lONaQJxK9QbHU9CtrvTS2ModZC7TJuqGRGX6dBIzou8E4d2vfgib3hiaJC5Vv8cI5BTN78FAMqXXL6PmQ/0?wx_fmt=png'], + 'blackground.png' => ['media_id' => 'Cn8zlXvVB5DwjcA9h40z9ZL-R__Pwz7qdbJfxSHmuBjNbphyBFlanm-sBQ_nWUYC','url' => 'http://mmbiz.qpic.cn/mmbiz_png/QHFVW13lONaQJxK9QbHU9CtrvTS2ModZfssPs0wTQYhX6ctSiaY1Uck0WTJ1xXZsZlhU05sOjUqFRmLWamH3XKQ/0?wx_fmt=png'], + 'dongtu.gif' => ['media_id' => 'Cn8zlXvVB5DwjcA9h40z9b7p9bSZhAeYdRRstPiBXjqSRboKJcxeHKz6VsG5H8ZG','url' => 'http://mmbiz.qpic.cn/mmbiz_gif/QHFVW13lONaQJxK9QbHU9CtrvTS2ModZK6wx6OQLlIiaDRcp0sgxXkZQgwWfDcoM7KzErBE6Nvq4IVf4iaX2icrUQ/0?wx_fmt=gif'], + 'weixin.jpeg' => ['media_id' => 'Cn8zlXvVB5DwjcA9h40z9VDBX-gpcy4OA13l_atzNZ8NLWvSV7YA82IlpP6Q1672','url' => 'http://mmbiz.qpic.cn/mmbiz_jpg/QHFVW13lONaQJxK9QbHU9CtrvTS2ModZknGn1cCteibInoxTDzD0EGt5mL7S170R99QGv7ibwWnQFJRZFLN7iaD5g/0?wx_fmt=jpeg'], + ]; + protected $aLogo = ['media_id' => 'Cn8zlXvVB5DwjcA9h40z9fprHDoc3Jqv97SwrInpmyYiilkeRdKvpD63cWqTYHfz','url' => 'http://mmbiz.qpic.cn/mmbiz_jpg/QHFVW13lONaQJxK9QbHU9CtrvTS2ModZnUyeAvuVN67t8XP85DxVJwDJf2YxCTalrsr17jS080xM6xQv5yGiaEQ/0?wx_fmt=jpeg'];//默认头像 + protected $sAppID = 'wx03cb871b66e34e10'; + protected $sAppSecret = 'f59ccaf00383dcfab489292c4697620a'; + protected $sWechatAccessToken = 'wechat_access_token'; protected $proxy; protected $sUrl; protected $curl; protected $sResponesData; protected $sError; protected $timeout = 60; - protected $aAiFileds = ['article_id','title_english','title_chinese','journal_id','cite','covered','digest','research_result','content','highlights','discussion_prospect','journal_content','research_background']; + protected $aAiFileds = ['article_id','title_english','title_chinese','journal_id','cite','covered','digest','research_result','content','highlights','discussion','prospect','journal_content','research_background','journal_topic']; protected $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php';//'http://zmzm.journal.dev.com'; // protected $sJournalUsx = 'https://www.tmrjournals.com'; @@ -55,25 +65,25 @@ class Aiarticle extends Base 发病率+当前治疗缺口(如5年OS<20%) 引用2-3篇高被引论文的矛盾结论(如Nature vs Cell观点分歧) 基于团队前期工作(如预实验发现X调控Y) - 4 结论与展望撰写 - 结论部分:与TOP3高被引文献的对比 - 展望部分: - 现有方法的可扩展性(如空间组学升级计划) + 4 针对稿件内容进行结论撰写 + 与TOP3高被引文献的对比(用"与A研究的X结论不同..."句式) 机制解释的3级证据链(如:基因敲除→通路抑制→表型逆转) 临床转化的可行性路径(如:基于RECIST标准的ORR提升)研究局限性(分方法学/样本量/随访维度) + 5 针对稿件内容进行展望撰写 + 现有方法的可扩展性(如空间组学升级计划) - 5 按点总结归纳研究结果并做简要阐述【3点以上】 - 6 总结归纳亮点【3点以上】 - 7 禁用清单 + 6 按点总结归纳研究结果并做简要阐述【3点以上】 + 7 总结归纳亮点【3点以上】 + 8 禁用清单 直接复制讨论部分的原文 未达到统计学显著性的趋势描述 稿件内未提及的内容一定不要总结归纳出来 "可能""或许"等不确定性词汇 单纯古籍原文翻译(需结合现代数据解读) 未经验证的因果断言(如"证明XX药治愈癌症") - 8 请将标题翻译成中文 + 9 请将标题翻译成中文 {#title_chinese#} - 9 请将稿件内容翻译成中文 + 10 请将稿件内容翻译成中文 {#content#} - 10 请将稿件所属期刊简介翻译 + 11 请将稿件所属期刊简介翻译 {#journal_content#} **稿件关键信息** @@ -91,9 +101,10 @@ class Aiarticle extends Base "covered": "【总字数<=100】", "digest": "【总字数<=500】", "research_background": "", - "discussion_prospect": "", "research_result": "", "highlights": "", + "prospect": "", + "discussion": "" }' ]; //"highlights": { @@ -264,6 +275,7 @@ class Aiarticle extends Base $aSearch['{#abstract#}'] = $this->basic_html_filter($aArticle['abstract']); $aSearch['{#title_chinese#}'] = $this->basic_html_filter($aArticle['title']); $aSearch['{#journal_content#}'] = $this->basic_html_filter($aJournal['journal_content'] ?? ''); + $aSearch['{#journal_content#}'] = trim(trim($aSearch['{#journal_content#}'],'.'),'。'); $aResult = $this->_createContentForOpenAI($aSearch,2); $aResult = json_decode($aResult,true); if($aResult['status'] != 1){ @@ -546,32 +558,53 @@ class Aiarticle extends Base public function updateAiArticle($aParam = array()){ //返回数组 $aResult = ['status' => 1,'msg' => 'AI article updated successfully','data' => []]; + + //获取参数 + $aParam = $this->request->post(); + + //主键ID + $iAiArticleId = empty($aParam['ai_article_id']) ? 0 : $aParam['ai_article_id']; + + //文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + + //查询内容是否存在 + $aWhere = ['is_delete' => 2]; + if(empty($iArticleId) && empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article to be modified']); + } + if(!empty($iArticleId)){ + $aWhere['article_id'] = $iArticleId; + } + if(!empty($iAiArticleId)){ + $aWhere['ai_article_id'] = $iAiArticleId; + } + $aAiArticle = Db::name('ai_article')->where($aWhere)->find(); + if(empty($aAiArticle)){ + return json_encode(['status' => 3,'msg' => 'he article content of WeChat official account has not been generated']); + } + + //必填参数验证 - $aFields = array_merge(['ai_article_id'],$this->aAiFileds); + $aFields = $this->aAiFileds; $bStatus = true; $sFiled = ''; $aUpdateParam = []; - $iAiArticleId = ''; foreach($aFields as $val){ + if(!isset($aParam[$val])){ + continue; + } if(empty($aParam[$val])){ $bStatus = false; $sFiled = $val; break; } - if($val == 'article_id'){ - continue; - } - if($val == 'ai_article_id'){ - $iAiArticleId = $aParam[$val]; - continue; - } $aUpdateParam[$val] = addslashes(strip_tags($aParam[$val])); } if($bStatus == false){ return json_encode(['status' => 2,'msg' => $sFiled.'cannot be empty']); } - - if(empty($iAiArticleId) || empty($aUpdateParam)){ + if(empty($aUpdateParam)){ return json_encode(['status' => 1,'msg' => 'No data currently being processed']); } @@ -585,9 +618,14 @@ class Aiarticle extends Base $aResult['data'] = $aUpdateParam; //更新作者信息 - if(!empty($aParam['author_list'])){ - foreach ($aParam['author_list'] as $key => $value) { - $aWhere = ['article_id' => $value['article_id'],'email' => $value['email']]; + $aAuthorList = empty($aParam['author_list']) ? []: $aParam['author_list']; + $aAuthorList = is_array($aParam['author_list']) ? $aAuthorList: json_decode($aAuthorList,true); + if(!empty($aAuthorList)){ + foreach ($aAuthorList as $key => $value) { + if(empty($value['email'])){ + continue; + } + $aWhere = ['article_id' => $iArticleId,'email' => $value['email']]; unset($value['article_id']); unset($value['email']); $value['update_time'] = time(); @@ -603,8 +641,9 @@ class Aiarticle extends Base * 文章内容选择模版生成数据 * @param article_id 文章ID * @param template_id 模版ID + * @param $iIsSync 是否同步素材到微信 1是2否 */ - public function getTemplateContent($iArticleId = '',$iTemplateId = ''){ + public function getTemplateContent($iArticleId = '',$iTemplateId = '',$iIsSync = 2){ //获取参数 $aParam = $this->request->post(); @@ -621,7 +660,20 @@ class Aiarticle extends Base return json_encode(['status' => 2, 'msg' => 'Please select a template']); } - //获取文章是否生成AI内容 + //获取AI生成文章内容 + $aAiContent = json_decode($this->getAiArticle($iArticleId),true); + $aAiContent = empty($aAiContent['data']) ? [] : $aAiContent['data']; + $aAiArticle = empty($aAiContent['ai_article']) ? [] : $aAiContent['ai_article']; + //AI通讯作者 + $aAiAuthor = empty($aAiContent['ai_article_author']) ? [] : $aAiContent['ai_article_author']; + //判断是否生成AI内容 + if(empty($aAiArticle)){ + return json_encode(['status' => 3, 'msg' => 'The article content of WeChat official account has not been generated']); + } + //模版ID + $iTemplateId = empty($iTemplateId) ? $aAiArticle['template_id'] : $iTemplateId; + + //获取文章内容 $aResult = json_decode($this->getArticle($iArticleId),true); if($aResult['status'] != 1){ return json_encode($aResult); @@ -635,37 +687,77 @@ class Aiarticle extends Base //期刊数据 $aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal']; - //子期刊数据 - $aJournalStage = empty($aArticleContent['journal_stage']) ? [] : $aArticleContent['journal_stage']; + //文章图片 + $sArticleIcon = trim($this->sJournalUsx,'/').'/public/articleicon/'.$aArticle['article_icon']; + //期刊图片 + $sJournalIcon = trim($this->sJournalUsx,'/').'/public/journalicon/'.$aJournal['journal_icon']; + //获取期刊图片二维码 + $aJournalQrCode = $this->createJournalQrCode($aJournal); + $sJournalCode = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url']; + $aAiArticle['journal_qrcode'] = $sJournalCode; - //获取AI生成文章内容 - $aAiContent = json_decode($this->getAiArticle($iArticleId),true); - $aAiContent = empty($aAiContent['data']) ? [] : $aAiContent['data']; - $aAiArticle = empty($aAiContent['ai_article']) ? [] : $aAiContent['ai_article']; - //AI通讯作者 - $aAiAuthor = empty($aAiContent['ai_article_author']) ? [] : $aAiContent['ai_article_author']; + //文章图片二维码 + $aArticleQrCode = $this->createArticleQrCode($aArticle); + $sArticleCode = empty($aArticleQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aArticleQrCode['qrcode_url']; + $aAiArticle['article_qrcode'] = $sArticleCode; + + // //上传素材到微信 + if($iIsSync == 1){ + + //文章图片上传 + $aUpload = ['article_id' => $iArticleId,'icon' => $sArticleIcon]; + $aArticleResult = json_decode($this->_addArticleMaterial($aUpload),true); + $aArticleData = empty($aArticleResult['data']) ? [] : $aArticleResult['data']; + $aAiArticle['article_icon'] = empty($aArticleData['media_url']) ? $sArticleIcon : $aArticleData['media_url']; + + //期刊图片上传 + $aUpload = ['journal_id' => $aAiArticle['journal_id'],'icon' => $sJournalIcon]; + $aJournalResult = json_decode($this->_addJournalMaterial($aUpload),true); + $aJournalData = empty($aJournalResult['data']) ? [] : $aJournalResult['data']; + $aAiArticle['journal_icon'] = empty($aJournalData['media_url']) ? $sJournalIcon : $aJournalData['media_url']; + + //期刊二维码图片上传 + $aUpload = ['journal_id' => $aAiArticle['journal_id']]; + $aJournalQrCodeResult = json_decode($this->_updateJournalQrcode($aUpload),true); + $aJournalQrCodeData = empty($aJournalQrCodeResult['data']) ? [] : $aJournalQrCodeResult['data']; + $aAiArticle['journal_qrcode'] = empty($aJournalQrCodeData['media_url']) ? $sJournalIcon : $aJournalQrCodeData['media_url']; + + //文章二维码图片上传 + $aUpload = ['article_id' => $iArticleId]; + $aArticleQrCodeResult = json_decode($this->_updateArticleQrcode($aUpload),true); + $aArticleQrCodeData = empty($aArticleQrCodeResult['data']) ? [] : $aArticleQrCodeResult['data']; + $aAiArticle['article_qrcode'] = empty($aArticleQrCodeData['media_url']) ? $sArticleIcon : $aArticleQrCodeData['media_url']; + + //作者图片上传 + if(!empty($aAiAuthor)){ + foreach ($aAiAuthor as $key => $value) { + if(empty($value['icon'])){ + continue; + } + //文章二维码图片上传 + $aUpload = ['email' => $value['email'],'icon' => $value['icon']]; + $aAuthorResult = json_decode($this->_updateArticleAuthor($aUpload),true); + $aAuthorData = empty($aAuthorResult['data']) ? [] : $aAuthorResult['data']; + $aAiAuthor[$key]['icon'] = empty($aAuthorData['media_url']) ? $value['icon'] : $aAuthorData['media_url']; + } + } + }else{ + + //处理文章图片地址数据 + $aAiArticle['article_icon'] = $sArticleIcon; + //处理文章期刊图片地址数据 + $aAiArticle['journal_icon'] = $sJournalIcon; - //判断是否生成AI内容 - if(empty($aAiArticle)){ - return json_encode(['status' => 3, 'msg' => 'The article content of WeChat official account has not been generated']); } - //期刊访问地址 - $journal_usx = $this->sJournalUsx; + $journal_usx = trim($this->sJournalUsx,'/').'/'; if(!empty($aJournal['journal_usx'])){ //地址 $journal_usx .= $aJournal['journal_usx']??''.'/'; } $aAiArticle['journal_usx_url'] = trim($journal_usx); $aAiArticle += $aJournal; - - - //获取期刊图片二维码 - $aJournalQrCode = $this->createJournalQrCode($aJournal); - $aAiArticle['journal_qrcode'] = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url']; - //获取期刊图片二维码 - $aArticleQrCode = $this->createArticleQrCode($aArticle); - $aAiArticle['article_qrcode'] = empty($aArticleQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aArticleQrCode['qrcode_url']; + //获取模版信息 $sTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'.html'; @@ -682,9 +774,8 @@ class Aiarticle extends Base //数据处理 $aSearch = []; foreach ($aAiArticle as $key => $value) { - $aSearch['{###'.$key.'###}'] = htmlspecialchars(trim(trim(trim($value),'【'),'】')); + $aSearch['{###'.$key.'###}'] = htmlspecialchars(strip_tags($value)); } - //处理通讯作者信息数据 $aAuthorInfo = json_decode($this->dealTemplateAuthor($aAiAuthor,$iTemplateId),true); $aSearch['{###author_info###}'] = empty($aAuthorInfo['data']['author_info']) ? ' ' : implode("\n", $aAuthorInfo['data']['author_info']); @@ -720,14 +811,13 @@ class Aiarticle extends Base $aSearch['{###topic_name_summary###}'] = $sSummaryTemplate; } - //处理文章图片地址数据 - $aSearch['{###article_icon###}'] = $this->sJournalUsx.'/public/articleicon/'.$aArticle['article_icon']??''; - //处理文章期刊图片地址数据 - $aSearch['{###journal_icon###}'] = $this->sJournalUsx.'/public/journalicon/'.$aJournal['journal_icon']??''; //模版替换变量 if(empty($aSearch)){ return json_encode(['status' => 6, 'msg' => '模版内容不能为空']); } + + $aSearch['{###jabbr###}'] = trim(trim($aSearch['{###jabbr###}'],'.'),'。'); + $sTemplate = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplate); file_put_contents(ROOT_PATH.'public/template_info.html', $sTemplate); return json_encode(['status' => 1, 'msg' => '模版生成成功','data' => ['template' => $sTemplate]]); @@ -758,13 +848,19 @@ class Aiarticle extends Base //处理模版变量 $aAuthorSerachInfo = []; $sAuthorInfo = ''; + $aLogo = $this->aLogo; foreach ($aAuthor as $key => $value) { $aAuthorSerach = []; foreach ($value as $k => $val) { if($k == 'icon'){ - $aAuthorSerach['{###'.$k.'###}'] = $this->sSubmissionUrl.trim($val); + if($val == $aLogo['url']){ + $aAuthorSerach['{###'.$k.'###}'] = $val; + }else{ + $aAuthorSerach['{###'.$k.'###}'] = trim($this->sSubmissionUrl,'/').$val; + } + $aAuthorSerach['{###'.$k.'###}'] = trim($aAuthorSerach['{###'.$k.'###}'],'/'); }else{ - $aAuthorSerach['{###'.$k.'###}'] = trim($val); + $aAuthorSerach['{###'.$k.'###}'] = trim($val,'/'); } } $aAuthorSerachInfo[] = str_replace(array_keys($aAuthorSerach), array_values($aAuthorSerach), $sAuthorTemplate); @@ -869,18 +965,29 @@ class Aiarticle extends Base } //获取关联文章信息 - $aWhere = ['article_id' => ['in',json_decode($aArticle['related'],true)],'is_publish' => 1,'is_delete' => 2]; - $aRecommend = Db::name('ai_article')->field('article_id,media_id,wechat_url')->where($aWhere)->select(); + $aWhere = ['article_id' => ['in',json_decode($aArticle['related'],true)],'is_delete' => 2]; + $aRecommend = Db::name('ai_article')->field('article_id')->where($aWhere)->select(); $aSearchInfo = []; if(!empty($aRecommend)){ - //查询文章图片 $aId = array_column($aRecommend, 'article_id'); + + //查询是否推送到微信公众号并且已发布 + $aWhere['template_id'] = $iTemplateId;//,'is_publish' => 1 + $aWechatArticle = Db::name('ai_wechat_article')->where($aWhere)->column('article_id'); + if(!empty($aWechatArticle)){ + return json_encode(['status' => 6, 'msg' => 'No article published on WeChat official account was found']); + } + + //查询文章图片 $aWhere = ['w_article_id' => ['in',$aId]]; $aProductionArticle = Db::name('production_article')->where($aWhere)->column('w_article_id,icon'); foreach ($aRecommend as $key => $value) { + if(!in_array($value['article_id'], $aWechatArticle)){ + continue; + } $aSerach['{###wechat_url###}'] = $value['wechat_url']; - $sIcon = empty($aProductionArticle[$value['article_id']]) ? '' : $this->sJournalUsx.'/public/articleicon/'.$aProductionArticle[$value['article_id']]; + $sIcon = empty($aProductionArticle[$value['article_id']]) ? '' : trim($this->sJournalUsx,'/').'/public/articleicon/'.$aProductionArticle[$value['article_id']]; $aSerach['{###wechat_media_url###}'] = empty($value['wechat_media_url']) ? $sIcon : $value['wechat_media_url']; $aSearchInfo[] = str_replace(array_keys($aSerach), array_values($aSerach), $sTemplate); } @@ -896,7 +1003,7 @@ class Aiarticle extends Base $iJournalId = empty($aJournal['journal_id']) ? 0 : $aJournal['journal_id']; //判断期刊二维码是否生成 $aWhere = ['journal_id' => $iJournalId]; - $aQrCode = Db::name('journal_qrcode')->where($aWhere)->find(); + $aQrCode = Db::name('ai_journal_qrcode')->where($aWhere)->find(); if(!empty($aQrCode)){ return $aQrCode; } @@ -911,14 +1018,14 @@ class Aiarticle extends Base //地址 $journal_usx = empty($aJournal['journal_usx']) ? '' : $aJournal['journal_usx']; - $sUrl = $this->sJournalUsx.'/'.$journal_usx.'/'; + $sUrl = trim($this->sJournalUsx,'/').'/'.$journal_usx.'/'; //二维码中间图片 $sLogo = empty($aJournal['journal_icon']) ? '' : $aJournal['journal_icon']; if(empty($sLogo)){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); }else{ - $sLogo = $this->sJournalUsx.'/public/journalicon/'.$sLogo; + $sLogo = trim($this->sJournalUsx,'/').'/public/journalicon/'.$sLogo; $aImageInfo = json_decode($this->getImage($sLogo,$iJournalId,'journal'),true); if(empty($aImageInfo['data'])){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); @@ -928,7 +1035,7 @@ class Aiarticle extends Base //插入期刊二维码表 $aParam = ['journal_id' => $iJournalId,'qrcode_url' => $sImagePath,'create_time' => time()]; - $result = Db::name('journal_qrcode')->insertGetId($aParam); + $result = Db::name('ai_journal_qrcode')->insertGetId($aParam); return $aParam; } @@ -941,7 +1048,7 @@ class Aiarticle extends Base $iArticleId = empty($aArticle['article_id']) ? 0 : $aArticle['article_id']; //判断期刊二维码是否生成 $aWhere = ['article_id' => $iArticleId]; - $aQrCode = Db::name('article_qrcode')->where($aWhere)->find(); + $aQrCode = Db::name('ai_article_qrcode')->where($aWhere)->find(); if(!empty($aQrCode)){ return $aQrCode; } @@ -955,14 +1062,14 @@ class Aiarticle extends Base return ['qrcode_url' => $sImagePath]; } //地址 - $sUrl = $this->sJournalUsx.'/'.'article.html?J_num='.$aArticle['journal_id'].'&a_id='.$iArticleId; + $sUrl = trim($this->sJournalUsx,'/').'/'.'article.html?J_num='.$aArticle['journal_id'].'&a_id='.$iArticleId; //二维码中间图片 $sLogo = $aArticle['article_icon']; if(empty($sLogo)){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); }else{ - $sLogo = $this->sJournalUsx.'/public/articleicon/'.$sLogo; + $sLogo = trim($this->sJournalUsx,'/').'/public/articleicon/'.$sLogo; $aImageInfo = json_decode($this->getImage($sLogo,$iArticleId,'article'),true); if(empty($aImageInfo['data'])){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); @@ -972,7 +1079,7 @@ class Aiarticle extends Base //插入期刊二维码表 $aParam = ['article_id' => $iArticleId,'qrcode_url' => $sImagePath,'create_time' => time()]; - $result = Db::name('article_qrcode')->insertGetId($aParam); + $result = Db::name('ai_article_qrcode')->insertGetId($aParam); return $aParam; } @@ -1050,4 +1157,588 @@ class Aiarticle extends Base } + /** + * 文章同步到微信公众号草稿箱 + * @param article_id 文章ID + */ + public function syncWechat(){ + + //获取参数 + $aParam = $this->request->post(); + + //文章ID + $iArticleId = empty($iArticleId) ? $aParam['article_id'] ?? '' : $iArticleId; + //模版ID + $iTemplateId = empty($iTemplateId) ? $aParam['template_id'] ?? '' : $iTemplateId; + + //必填参数验证 + if(empty($iArticleId)){ + return json_encode(['status' => 2, 'msg' => 'Please select an article']); + } + if(empty($iTemplateId)){ + return json_encode(['status' => 2, 'msg' => 'Please select a template']); + } + + //获取模版生成内容 + $aResult = json_decode($this->getTemplateContent($iArticleId,$iTemplateId,1),true); + $iStatus = empty($aResult['status']) ? 0 : $aResult['status'];//状态 + $sMsg = empty($aResult['msg']) ? 'The content is empty' : $aResult['msg']; + if($iStatus != 1){ + return json_encode(['status' => 3, 'msg' => $sMsg]); + } + $aData = empty($aResult['data']) ? [] : $aResult['data']; + if(empty($aData['template'])){ + return json_encode(['status' => 4, 'msg' => $sMsg]); + } + + //请求微信公众号接口推送 + $aParam['template_content'] = $aData['template']; + $aParam['template_id'] = $iTemplateId; + $aResult = $this->addDraft($aParam); + return $aResult; + } + + /** + * CURL 发送请求获取Token + * @param $appid AppID(小程序ID) + * @param $secret AppSecret(小程序密钥) + */ + + private function getAccessToken() { + //Token缓存值 + $sToken = Cache::get($this->sWechatAccessToken); + //判断缓存是否存在 + if (!$sToken) { //不存在 + //组装接口地址 + $sUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + . $this->sAppID . "&secret=" . $this->sAppSecret; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $sUrl); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout); + $result = curl_exec($curl); + //请求失败 + if (curl_errno($curl)){ + $this->sError = curl_errno($curl); + curl_close($curl); + return FALSE; + } + $result = json_decode($result, true); + if (!empty($result['access_token'])) { + $sToken = $result['access_token']; + Cache::set($this->sWechatAccessToken, $sToken, 7000); // 有效期7200秒 + } + curl_close($curl); + } + return $sToken; + } + + /** + * CURL 发送请求上传永久素材 + * @param $sToken Token + * @param $sPath 图片地址 + */ + public function uploadMaterial($sPath = '') { + + $aParam = $this->request->post(); + + $sPath = empty($sPath) ? $aParam['path'] : $sPath; + // $sPath = ROOT_PATH.'static/img/'.$sPath; + // return json_encode(['status' => 1,'data' => ['media_id' => '1111111','url' => '22222']]); + //返回结果数组 + $aResult = ['status' => 1,'msg' => '上传素材成功','data' => []]; + + $sPath = empty($sPath) ? $aParam['image_path']?? '' : $sPath;//文件地址 + $sType = empty($aParam['type']) ? 'image' : $aParam['type'];//文件类型 + + // 验证文件有效性 + if (!file_exists($sPath)) { + return json_encode(['status' => 2,'msg' => '素材不存在'.$sPath]); + } + if (!is_readable($sPath)) { + return json_encode(['status' => 3,'msg' => '素材不可读']); + } + if (filesize($sPath) > 10 * 1024 * 1024) { + return json_encode(['status' => 4,'msg' => '素材不能超过10MB']); + } + + //获取Token + $sToken = $this->getAccessToken(); + if (empty($sToken)) { + return json_encode(['status' => 5, 'msg' => '获取access_token失败']); + } + + //CURL 请求接口 + //文件参数 + $data = [ + 'media' => new \CURLFile( + realpath($sPath), + mime_content_type($sPath), // 自动检测MIME类型 + basename($sPath) // 上传后的文件名 + ), // 关键:使用CURLFile对象 + ]; + $sUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$sToken}&type={$sType}"; + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $sUrl); + curl_setopt($curl, CURLOPT_POST, true); //设置为POST方式 + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE) ; // 获取数据返回 + curl_setopt($curl, CURLOPT_PROXY,$this->proxy); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,false); + //执行 + $response = curl_exec($curl); + + //请求失败 + if (curl_errno($curl)){ + curl_close($curl); + return json_encode(['status' => 6,'msg' => "网络请求失败: " . curl_errno($curl)]); + } + curl_close($curl);//关闭请求 + + //获取返回结果 + $response = json_decode($response, true); + if (!empty($response['errcode']) && $response['errcode'] != 0) { + return json_encode(['status' => 7,'msg' => "微信接口错误: [{$response['errcode']}] {$response['errmsg']}"]); + } + + //插入数据库 + if(empty($response['media_id'])){ + return json_encode(['status' => 8,'msg' => "未获取到上传素材"]); + } + return json_encode(['status' => 1,'msg' => 'success','data' => $response]); + } + + /** + * 添加文章素材 + * @param article_id 文章ID + * @param media_id 微信公众号素材media_id + * @param media_url 微信公众号素材地址 + * @param sType select 查询|add 新增 + * @param $sPath 图片地址 + */ + private function _addArticleMaterial($aParam = []){ + + //文章ID + $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id']; + //文章图片 + $sIcon = empty($aParam['icon']) ? '' : $aParam['icon']; + //必填验证 + if(empty($iArticleId) || empty($sIcon)){ + return json_encode(['status' => 2,'msg' => 'article_id or article_image is empty']); + } + //查询是否添加素材 + $aWhere = ['article_id' => $iArticleId,'is_delete' => 2]; + $aMaterial = Db::name('ai_article_material')->field('media_id,media_url')->where($aWhere)->find(); + if(!empty($aMaterial)){ + return json_encode(['status' => 1,'msg' => 'added','data' => $aMaterial]); + } + + //处理图片地址 + $aImageInfo = pathinfo($sIcon); + //图片后缀名 + $sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension']; + $sImagePath = 'article/imgae_'.$iArticleId.'.'.$sExtension; + $sImagePath = ROOT_PATH.'public/qrcode/'.$sImagePath; + if (!file_exists($sImagePath)) {//下载图片 + $aImageInfo = json_decode($this->getImage($sIcon,$iArticleId,'article'),true); + if(empty($aImageInfo['data'])){ + return json_encode(['status' => 3,'msg' => 'Image download failed']); + } + } + + //调用微信新增素材接口上传 + $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true); + $iStatus = empty($aUploadResult['status']) ? 0 : $aUploadResult['status']; + $sMsg = empty($aUploadResult['msg']) ? 'Failed to upload materials' : $aUploadResult['msg']; + if($iStatus != 1){ + return json_encode(['status' => 4,'msg' => $sMsg]); + } + $aData = empty($aUploadResult['data']) ? [] : $aUploadResult['data']; + if(empty($aData['url'])){ + return json_encode(['status' => 5,'msg' => 'Material not obtained']); + } + + //处理入库数据 + $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id']; + $sMediaUrl = empty($aData['url']) ? [] : $aData['url']; + $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at']; + //入库数据组装 + $aInsert = ['type' => 'image','media_id' => $sMediaId,'create_time' => $iTime,'article_id' => $iArticleId,'media_url' => $sMediaUrl]; + $response = Db::name('ai_article_material')->insert($aInsert); + if($response === false){ + return json_encode(['status' => 6,'msg' => 'Add fail']); + } + return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]); + } + /** + * 添加期刊素材 + * @param $sToken Token + * @param $sPath 图片地址 + */ + private function _addJournalMaterial($aParam = []){ + + //期刊ID + $iJournalId = empty($aParam['journal_id']) ? '' : $aParam['journal_id']; + //期刊图片 + $sIcon = empty($aParam['icon']) ? '' : $aParam['icon']; + if(empty($iJournalId) || empty($sIcon)){ + return json_encode(['status' => 2,'msg' => 'journal_id or image is empty']); + } + //查询是否添加素材 + $aWhere = ['journal_id' => $iJournalId,'is_delete' => 2]; + $aMaterial = Db::name('ai_journal_material')->field('media_id,media_url')->where($aWhere)->find(); + if(!empty($aMaterial)){ + return json_encode(['status' => 1,'msg' => 'success','data' => $aMaterial]); + } + + //处理图片地址 + $aImageInfo = pathinfo($sIcon); + //图片后缀名 + $sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension']; + $sImagePath = 'journal/imgae_'.$iJournalId.'.'.$sExtension; + $sImagePath = ROOT_PATH.'public/qrcode/'.$sImagePath; + if (!file_exists($sImagePath)) {//下载图片 + $aImageInfo = json_decode($this->getImage($sIcon,$iJournalId,'journal'),true); + if(empty($aImageInfo['data'])){ + return json_encode(['status' => 3,'msg' => 'Image download failed']); + } + } + + //调用微信新增素材接口上传 + $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true); + $iStatus = empty($aUploadResult['status']) ? 0 : $aUploadResult['status']; + $sMsg = empty($aUploadResult['msg']) ? 'Failed to upload materials' : $aUploadResult['msg']; + if($iStatus != 1){ + return json_encode(['status' => 4,'msg' => $sMsg]); + } + $aData = empty($aUploadResult['data']) ? [] : $aUploadResult['data']; + if(empty($aData['url'])){ + return json_encode(['status' => 5,'msg' => 'Material not obtained']); + } + + //处理入库数据 + $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id']; + $sMediaUrl = empty($aData['url']) ? [] : $aData['url']; + $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at']; + //入库数据组装 + $aInsert = ['type' => 'image','media_id' => $sMediaId,'create_time' => $iTime,'journal_id' => $iJournalId,'media_url' => $sMediaUrl]; + $response = Db::name('ai_journal_material')->insert($aInsert); + if($response === false){ + return json_encode(['status' => 6,'msg' => 'Add fail']); + } + return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]); + } + /** + * 更新期刊二维码关联微信公众号素材 + */ + private function _updateJournalQrcode($aParam = []){ + + //期刊ID + $iJournalId = empty($aParam['journal_id']) ? '' : $aParam['journal_id']; + if(empty($iJournalId)){ + return json_encode(['status' => 2,'msg' => 'journal_id or image is empty']); + } + + //查询是否生成二维码 + $aWhere = ['journal_id' => $iJournalId,'is_delete' => 2]; + $aMaterial = Db::name('ai_journal_qrcode')->field('qrcode_url,media_id,media_url')->where($aWhere)->find(); + if(empty($aMaterial)){ + return json_encode(['status' => 3,'msg' => 'data is null']); + } + if(!empty($aMaterial['media_url'])){ + return json_encode(['status' => 1,'msg' => 'success','data' => $aMaterial]); + } + + //处理图片地址 + $sImagePath = ROOT_PATH.'public/qrcode/'.$aMaterial['qrcode_url']; + + //调用微信新增素材接口上传 + $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true); + $iStatus = empty($aUploadResult['status']) ? 0 : $aUploadResult['status']; + $sMsg = empty($aUploadResult['msg']) ? 'Failed to upload materials' : $aUploadResult['msg']; + if($iStatus != 1){ + return json_encode(['status' => 4,'msg' => $sMsg]); + } + $aData = empty($aUploadResult['data']) ? [] : $aUploadResult['data']; + if(empty($aData['url'])){ + return json_encode(['status' => 5,'msg' => 'Material not obtained']); + } + + $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id']; + $sMediaUrl = empty($aData['url']) ? [] : $aData['url']; + $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at']; + $aUpdate = ['media_id' => $sMediaId,'media_url' => $sMediaUrl,'update_time' => $iTime]; + $response = Db::name('ai_journal_qrcode')->where('journal_id',$iJournalId)->limit(1)->update($aUpdate); + if($response === false){ + return json_encode(['status' => 3,'msg' => 'fail']); + } + return json_encode(['status' => 1,'msg' => 'success','data' => $aUpdate]); + } + + /** + * 更新文章二维码关联微信公众号素材 + */ + private function _updateArticleQrcode($aParam = []){ + + $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'article_id is empty']); + } + //查询是否添加素材 + $aWhere = ['article_id' => $iArticleId,'is_delete' => 2]; + $aMaterial = Db::name('ai_article_qrcode')->field('qrcode_url,media_id,media_url')->where($aWhere)->find(); + if(empty($aMaterial)){ + return json_encode(['status' => 3,'msg' => 'data is null']); + } + if(!empty($aMaterial['media_url'])){ + return json_encode(['status' => 1,'msg' => 'success','data' => $aMaterial]); + } + + //处理图片地址 + $sImagePath = ROOT_PATH.'public/qrcode/'.$aMaterial['qrcode_url']; + + //调用微信新增素材接口上传 + $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true); + $iStatus = empty($aUploadResult['status']) ? 0 : $aUploadResult['status']; + $sMsg = empty($aUploadResult['msg']) ? 'Failed to upload materials' : $aUploadResult['msg']; + if($iStatus != 1){ + return json_encode(['status' => 4,'msg' => $sMsg]); + } + $aData = empty($aUploadResult['data']) ? [] : $aUploadResult['data']; + if(empty($aData['url'])){ + return json_encode(['status' => 5,'msg' => 'Material not obtained']); + } + + //更新 + $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id']; + $sMediaUrl = empty($aData['url']) ? [] : $aData['url']; + $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at']; + $aUpdate = ['media_id' => $sMediaId,'media_url' => $sMediaUrl,'update_time' => $iTime]; + $response = Db::name('ai_article_qrcode')->where('article_id',$iArticleId)->limit(1)->update($aUpdate); + if($response === false){ + return json_encode(['status' => 3,'msg' => 'update fail']); + } + return json_encode(['status' => 1,'msg' => 'success','data' => $aUpdate]); + } + + /** + * 更新通讯作者关联微信公众号素材 + */ + private function _updateArticleAuthor($aParam = []){ + + $sEmail = empty($aParam['email']) ? '' : $aParam['email']; + //文章图片 + $sIcon = empty($aParam['icon']) ? '' : $aParam['icon']; + + if(empty($sEmail) || empty($sIcon)){ + return json_encode(['status' => 2,'msg' => 'email is empty']); + } + //查询是否添加素材 + $aWhere = ['email' => $sEmail]; + $aMaterial = Db::name('ai_article_author')->field('media_id,media_url')->where($aWhere)->find(); + if(empty($aMaterial)){ + return json_encode(['status' => 3,'msg' => 'data is null']); + } + if(!empty($aMaterial['media_url'])){ + return json_encode(['status' => 1,'msg' => 'success','data' => $aMaterial]); + } + + //处理图片地址 + $sImagePath = ROOT_PATH.trim($sIcon,'/'); + + if(trim($sIcon) != '/static/img/userImg.f3d9bc3b.jpg'){//非默认头像 + //调用微信新增素材接口上传 + $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true); + $iStatus = empty($aUploadResult['status']) ? 0 : $aUploadResult['status']; + $sMsg = empty($aUploadResult['msg']) ? 'Failed to upload materials' : $aUploadResult['msg']; + if($iStatus != 1){ + return json_encode(['status' => 4,'msg' => $sMsg]); + } + $aData = empty($aUploadResult['data']) ? [] : $aUploadResult['data']; + if(empty($aData['url'])){ + return json_encode(['status' => 5,'msg' => 'Material not obtained']); + } + } + if(trim($sIcon) == '/static/img/userImg.f3d9bc3b.jpg'){//默认头像 + $aData = $this->aLogo; + } + //更新 + $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id']; + $sMediaUrl = empty($aData['url']) ? [] : $aData['url']; + $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at']; + $aUpdate = ['media_id' => $sMediaId,'media_url' => $sMediaUrl,'update_time' => $iTime]; + $response = Db::name('ai_article_author')->where('email',$sEmail)->limit(1)->update($aUpdate); + if($response === false){ + return json_encode(['status' => 3,'msg' => 'fail']); + } + return json_encode(['status' => 1,'msg' => 'success','data' => $aUpdate]); + } + + /** + * CURL 添加文章到草稿箱 + * @param $sToken Token + * @param $sPath 图片地址 + */ + public function addDraft($aParam = []){ + //返回结果数组 + $aResult = ['status' => 1,'msg' => 'Upload draft box successfully','data' => []]; + + //文章ID + $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id']; + + //模版ID + $iTemplateId = empty($aParam['template_id']) ? '' : $aParam['template_id']; + + //生成模版内容 + $sContent = empty($aParam['template_content']) ? '' : $aParam['template_content']; + if(empty($iArticleId) || empty($sContent)){ + return json_encode(['status' => 2,'msg' => 'article_id OR template_content is empty']); + } + + //查询文章是否存在 + $aWhere = ['article_id' => $iArticleId,'is_delete' => 2]; + $aAiArticle = Db::name('ai_article')->field('title_chinese as title,author,journal_id')->where($aWhere)->find(); + if(empty($aAiArticle)){ + return json_encode(['status' => 3, 'msg' => 'The article does not exist']); + } + + //查询该模版是否推送到微信公众号 + $aWhere['template_id'] = $iTemplateId; + $aWechatArticle = Db::name('ai_wechat_article')->where($aWhere)->find(); + if(!empty($aWechatArticle)){ + return json_encode(['status' => 4, 'msg' => 'Already uploaded to draft box']); + } + //查询文章封面 + $aMaterial = Db::name('ai_article_material')->field('media_id as thumb_media_id')->where('article_id',$iArticleId)->find(); + if(!empty($aMaterial)){ + $aAiArticle += $aMaterial; + } + $aAiArticle['content'] = $sContent; + + unset($aAiArticle['journal_id']); + //获取Token + $sToken = $this->getAccessToken(); + if (empty($sToken)) { + return json_encode(['status' => 5, 'msg' => 'Failed to obtain access_token']); + } + //发送CURL请求 + $sUrl = "https://api.weixin.qq.com/cgi-bin/draft/add?access_token={$sToken}"; + //参数组装 + $sJsonData = json_encode([ + 'articles' => [$aAiArticle] + ], JSON_UNESCAPED_UNICODE); + $aCurlResult = $this->curlWechatApi($sUrl,$sJsonData); + if($aCurlResult['status'] != 1){ + return $aCurlResult; + } + $response = empty($aCurlResult['data']) ? [] : $aCurlResult['data']; + //判断是否推送成功 + if(empty($response['media_id'])){ + return json_encode(['status' => 5,'msg' => "Unable to obtain the uploaded draft"]); + } + + //判断文章类型 + $article_type = empty($aParam['article_type']) ? 'news' : $aParam['article_type']; + if(!in_array($article_type, ['news','newspic'])){ + return json_encode(['status' => 6,'msg' => "The article type does not match"]); + } + + //是否打开评论,0不打开(默认),1打开 + $need_open_comment = empty($aParam['need_open_comment']) ? 0 : $aParam['need_open_comment']; + + //是否粉丝才可评论,0所有人可评论(默认),1粉丝才可评论 + $only_fans_can_comment = empty($aParam['only_fans_can_comment']) ? 0 : $aParam['only_fans_can_comment']; + + //插入文章表 + $aParam = ['media_id' => $response['media_id'],'update_time' => time(),'template_id' => $iTemplateId,'template_content' => $aParam['template_content'],'article_id' => $iArticleId,'article_type' => $article_type,'need_open_comment' => $need_open_comment,'only_fans_can_comment' => $only_fans_can_comment,'template_id' => $iTemplateId,'create_time' => time()]; + $result = Db::name('ai_wechat_article')->insert($aParam); + if($result === false){ + return json_encode(['status' => 8,'msg' => "Article data insertion failed"]); + } + return json_encode($aResult); + } + + /** + * CURL 获取草稿箱的文章 + * @param $sToken Token + * @param article_id int 文章ID + */ + public function getDraft($sMediaId = ''){ + //返回结果数组 + $aResult = ['status' => 1,'msg' => 'Successfully obtained draft','data' => []]; + + //获取参数 + $aParam = $this->request->post(); + $sMediaId = empty($sMediaId) ? $aParam['media_id'] : $sMediaId; + if(empty($sMediaId)){ + return json_encode(['status' => 2, 'msg' => 'Parameter: media_id cannot be empty']); + } + + //查询关联文章信息 + $aArticle = Db::name('ai_article')->field('media_id')->where(['media_id'=>$sMediaId])->find(); + if(empty($aArticle)){ + return json_encode(['status' => 3,'msg' => 'The article does not exist']); + } + + //获取Token + $sToken = $this->getAccessToken(); + if (empty($sToken)) { + return json_encode(['status' => 4, 'msg' => '获取access_token失败']); + } + + //CURL请求 + $sUrl = "https://api.weixin.qq.com/cgi-bin/draft/get?access_token={$sToken}"; + //参数组装 + $sJsonData = json_encode([ + 'media_id' => $aArticle['media_id'] + ], JSON_UNESCAPED_UNICODE); + //发送CURL请求 + $aCurlResult = $this->curlWechatApi($sUrl,$sJsonData); + if($aCurlResult['status'] != 1){ + return json_encode(['status' => 5,'msg' => 'Acquisition failed']); + } + + $response = empty($aCurlResult['data']) ? [] : $aCurlResult['data']; + $aResult['data'] = $response['news_item'] ?? []; + return json_encode($aResult); + } + + /** + * CURL 发送请求到 微信公众号 + * @param $messages 内容 + * @param $model 模型类型 + */ + private function curlWechatApi($sUrl = '',$sJsonData = ''){ + + //发送CURL请求 + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $sUrl); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $sJsonData); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json', + 'Content-Length: ' . strlen($sJsonData) + ]); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); // 关闭SSL验证(生产环境建议开启) + $response = curl_exec($curl); + //请求失败 + if (curl_errno($curl)){ + curl_close($curl); + return ['status' => 2,'msg' => "网络请求失败: " . curl_errno($curl)]; + } + curl_close($curl);//关闭请求 + + // 数据处理 + $response = json_decode($response, true); + if (!empty($response['errcode'])) { + return ['status' => 3, 'msg' => '接口请求异常'.$response['errmsg'] ?? $response['errcode']]; + } + + return ['status' => 1,'msg' => '接口请求成功','data' => $response]; + } } From 03928363acda0b4987b338ca5da667298e07b411 Mon Sep 17 00:00:00 2001 From: chengxl Date: Tue, 13 May 2025 17:53:26 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Aiarticle.php | 757 ++++++++++++++--------- 1 file changed, 448 insertions(+), 309 deletions(-) diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php index ca00917..5a9c856 100644 --- a/application/api/controller/Aiarticle.php +++ b/application/api/controller/Aiarticle.php @@ -30,7 +30,7 @@ class Aiarticle extends Base protected $sResponesData; protected $sError; protected $timeout = 60; - protected $aAiFileds = ['article_id','title_english','title_chinese','journal_id','cite','covered','digest','research_result','content','highlights','discussion','prospect','journal_content','research_background','journal_topic']; + protected $aAiFileds = ['article_id','title_english','title_chinese','journal_id','covered','digest','research_result','content','highlights','discussion','prospect','research_background',]; protected $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php';//'http://zmzm.journal.dev.com'; // protected $sJournalUsx = 'https://www.tmrjournals.com'; @@ -83,8 +83,6 @@ class Aiarticle extends Base {#title_chinese#} 10 请将稿件内容翻译成中文 {#content#} - 11 请将稿件所属期刊简介翻译 - {#journal_content#} **稿件关键信息** - 稿件简介:{#abstract#} @@ -97,7 +95,6 @@ class Aiarticle extends Base { "title_chinese": "", "content": "", - "journal_content": "", "covered": "【总字数<=100】", "digest": "【总字数<=500】", "research_background": "", @@ -107,6 +104,11 @@ class Aiarticle extends Base "discussion": "" }' ]; + + //文章图片icon地址 + protected $sArticleIcon = '/public/articleicon/'; + //期刊图片icon地址 + protected $sJournalIcon = '/public/journalicon/'; //"highlights": { // "theory_innovation": "【中西医理论结合点】", // "methodology": "【关键技术+量化指标】", @@ -290,20 +292,16 @@ class Aiarticle extends Base $aContent['article_id'] = $iArticleId; $aContent['title_english'] = $aArticle['title']; $aContent['journal_id'] = $aArticle['journal_id']; - //文章引用 - $aContent['cite'] = $this->_cite($aArticle,$aJournal,$aJournalStage); - if(!empty($aJournal['journal_topic'])){ - $aContent['journal_topic'] = $aJournal['journal_topic']; - } + //获取AI生成表里的数据判断是新增或更新 - $aAiContent = json_decode($this->getAiArticle($iArticleId),true); + $aAiContent = json_decode($this->getAiArticle($iArticleId,1),true); $aAiContent = empty($aAiContent['data']) ? [] : $aAiContent['data']; $aAiArticle = empty($aAiContent['ai_article']) ? [] : $aAiContent['ai_article']; $aAiAuthor = empty($aAiContent['ai_article_autho']) ? [] : $aAiContent['ai_article_autho']; if(empty($aAiArticle)){//新增 //执行数据入库 - $aResult = $this->addAiArticle($aContent,$aAuthor); + $aResult = $this->addAiArticle($aContent); } if(!empty($aAiArticle)){//更新 if(empty($aAiArticle['ai_article_id'])){ @@ -353,7 +351,7 @@ class Aiarticle extends Base $iArticleId = $aArticleId[0]; $aEmail = array_unique(array_column($aAuthor, 'email')); $aWhere = ['email' => ['in',$aEmail]]; - $aUser = Db::name('user')->field('user_id,realname,email,localname')->where($aWhere)->select(); + $aUser = Db::name('user')->field('user_id,realname,email,localname,icon')->where($aWhere)->select(); if(empty($aUser)){ return []; } @@ -372,8 +370,8 @@ class Aiarticle extends Base //姓名 $sName = empty($aAuthor[$value['email']]['author_name']) ? '' : $aAuthor[$value['email']]['author_name']; - $sName = empty($sName) ? $value['realname'] : $sName; $sName = empty($sName) ? $value['localname'] : $sName; + $sName = empty($sName) ? $value['realname'] : $sName; //单位 $sCompany = empty($aAuthor[$value['email']]['company']) ? '' : $aAuthor[$value['email']]['company']; @@ -385,20 +383,7 @@ class Aiarticle extends Base //简介 $sIntroduction = empty($aUserInfo[$value['user_id']]['introduction']) ? '' : $aUserInfo[$value['user_id']]['introduction']; - //请求AI翻译 - // $aSearch['{#author_name#}'] = $sName; - // $aSearch['{#company#}'] = $sCompany; - // $aSearch['{#technical#}'] = $sTechnical; - // $aSearch['{#introduction#}'] = $sIntroduction; - // $aResult = $this->_createContentForOpenAI($aSearch,1); - // $aResult = json_decode($aResult,true); - // if($aResult['status'] == 1){ - // $aContent = empty($aResult['data']) ? [] : $aResult['data']; - // $sCompany = empty($aContent['company']) ? $sCompany : $aContent['company']; - // $sTechnical = empty($aContent['technical']) ? $sTechnical : $aContent['technical']; - // $sIntroduction = empty($aContent['introduction']) ? $sIntroduction : $aContent['introduction']; - // } - $aInfo[] = ['email' => $value['email'],'author_name' => $sName,'technical' => $sTechnical,'introduction' => $sIntroduction,'company' => $sCompany,'article_id' => $iArticleId,'create_time' => time()]; + $aInfo[] = ['user_id' => $value['user_id'],'email' => $value['email'],'author_name' => $sName,'technical' => $sTechnical,'introduction' => $sIntroduction,'company' => $sCompany,'article_id' => $iArticleId,'create_time' => time(),'icon' => $value['icon']]; } return $aInfo; @@ -442,27 +427,39 @@ class Aiarticle extends Base * 获取Ai生成文章信息 * @param article_id 文章ID */ - public function getAiArticle($iArticleId = 0){ + public function getAiArticle($iArticleId = 0,$iSelectAuthor = 2){ $aParam = $this->request->post(); $iArticleId = empty($iArticleId) ? $aParam['article_id'] : $iArticleId; //查询AI生成的文章内容 - $aParam['article_id'] = $iArticleId; - $aParam['is_delete'] = 2; - $aAiArticle = Db::name('ai_article')->where($aParam)->find(); + $aWhere['article_id'] = $iArticleId; + $aWhere['is_delete'] = 2; + $aAiArticle = Db::name('ai_article')->where($aWhere)->find(); if(empty($aAiArticle)){ return json_encode(['status' => 1,'msg' => 'data is null','data' => ['ai_article' => []]]); } + //查询文章通讯作者 - if($aAuthorInfo = Db::name('ai_article_author')->where(['article_id' => $iArticleId])->select()){ - //查询头像 - $aEmail = array_column($aAuthorInfo, 'email'); - $aUser = Db::name('user')->where(['email' => ['in',$aEmail]])->column('email,icon'); - foreach ($aAuthorInfo as $key => $value) { - $aAuthorInfo[$key]['icon'] = empty($aUser[$value['email']]) ? '/static/img/userImg.f3d9bc3b.jpg' : '/public/usericon/'.$aUser[$value['email']]; + $aAiAuthor = []; + if($iSelectAuthor == 2){ + $aResult = json_decode($this->getArticle($iArticleId),true); + if($aResult['status'] == 1){ + //获取数据 + $aArticleContent = empty($aResult['data']) ? [] : $aResult['data']; + //通讯作者 + $aAuthor = empty($aArticleContent['author']) ? [] : $aArticleContent['author']; + if(!empty($aAuthor)){ + $aAiAuthor = $this->_dealAuthor($aAuthor); + if(!empty($aAiAuthor)){ + foreach ($aAiAuthor as $key => $value) { + $aAiAuthor[$key]['icon_path'] = empty($value['icon']) ? '/static/img/userImg.f3d9bc3b.jpg' : '/public/usericon/'.$value['icon']; + } + } + } + } } - return json_encode(['status' => 1,'msg' => 'success','data' => ['ai_article' => $aAiArticle,'ai_article_author' => $aAuthorInfo]]); + return json_encode(['status' => 1,'msg' => 'success','data' => ['ai_article' => $aAiArticle,'ai_article_author' => $aAiAuthor]]); } /** * 基础HTML过滤 @@ -518,35 +515,10 @@ class Aiarticle extends Base //作者判断空值 $aInsertParam['author'] = empty($aInsertParam['author']) ? 'TMR编辑部' : $aInsertParam['author']; - Db::startTrans(); if(!$iId = Db::name('ai_article')->insertGetId($aInsertParam)){ return ['status' => 3,'msg' => 'Adding AI article failed']; } $aResult['data'] = array_merge($aInsertParam,['ai_article_id' => $iId]); - if(!empty($aAuthor)){ - $aInfo = $this->_dealAuthor($aAuthor); - - if(!empty($aInfo)){ - - foreach ($aInfo as $key => $value) { - //请求AI翻译 - $aSearch['{#author_name#}'] = $value['author_name']; - $aSearch['{#company#}'] = $value['company']; - $aSearch['{#technical#}'] = $value['technical']; - $aSearch['{#introduction#}'] = $value['introduction']; - $aResultInfo = $this->_createContentForOpenAI($aSearch,1); - $aResultInfo = json_decode($aResultInfo,true); - if($aResultInfo['status'] == 1){ - $aContent = empty($aResultInfo['data']) ? [] : $aResultInfo['data']; - $aInfo[$key]['company'] = empty($aContent['company']) ? $value['company'] : $aContent['company']; - $aInfo[$key]['technical'] = empty($aContent['technical']) ? $value['technical'] : $aContent['technical']; - $aInfo[$key]['introduction'] = empty($aContent['introduction']) ? $value['introduction'] : $aContent['introduction']; - } - } - Db::name('ai_article_author')->insertAll($aInfo); - } - } - Db::commit(); return json_encode($aResult); } @@ -587,28 +559,18 @@ class Aiarticle extends Base //必填参数验证 $aFields = $this->aAiFileds; - $bStatus = true; $sFiled = ''; $aUpdateParam = []; foreach($aFields as $val){ if(!isset($aParam[$val])){ continue; } - if(empty($aParam[$val])){ - $bStatus = false; - $sFiled = $val; - break; - } $aUpdateParam[$val] = addslashes(strip_tags($aParam[$val])); } - if($bStatus == false){ - return json_encode(['status' => 2,'msg' => $sFiled.'cannot be empty']); - } if(empty($aUpdateParam)){ return json_encode(['status' => 1,'msg' => 'No data currently being processed']); } - Db::startTrans(); //执行入库 $aUpdateParam['update_time'] = time(); $result = Db::name('ai_article')->where('ai_article_id',$iAiArticleId)->limit(1)->update($aUpdateParam); @@ -616,23 +578,6 @@ class Aiarticle extends Base $aResult = json_encode(['status' => 3,'msg' => 'UPDATEING AI article failed']); } $aResult['data'] = $aUpdateParam; - - //更新作者信息 - $aAuthorList = empty($aParam['author_list']) ? []: $aParam['author_list']; - $aAuthorList = is_array($aParam['author_list']) ? $aAuthorList: json_decode($aAuthorList,true); - if(!empty($aAuthorList)){ - foreach ($aAuthorList as $key => $value) { - if(empty($value['email'])){ - continue; - } - $aWhere = ['article_id' => $iArticleId,'email' => $value['email']]; - unset($value['article_id']); - unset($value['email']); - $value['update_time'] = time(); - Db::name('ai_article_author')->where($aWhere)->limit(1)->update($value); - } - } - Db::commit(); return json_encode($aResult); } @@ -661,11 +606,9 @@ class Aiarticle extends Base } //获取AI生成文章内容 - $aAiContent = json_decode($this->getAiArticle($iArticleId),true); + $aAiContent = json_decode($this->getAiArticle($iArticleId,1),true); $aAiContent = empty($aAiContent['data']) ? [] : $aAiContent['data']; $aAiArticle = empty($aAiContent['ai_article']) ? [] : $aAiContent['ai_article']; - //AI通讯作者 - $aAiAuthor = empty($aAiContent['ai_article_author']) ? [] : $aAiContent['ai_article_author']; //判断是否生成AI内容 if(empty($aAiArticle)){ return json_encode(['status' => 3, 'msg' => 'The article content of WeChat official account has not been generated']); @@ -687,10 +630,17 @@ class Aiarticle extends Base //期刊数据 $aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal']; + //子期刊数据 + $aJournalStage = empty($aArticleContent['journal_stage']) ? [] : $aArticleContent['journal_stage']; + + //通讯作者 + $aAuthor = empty($aArticleContent['author']) ? [] : $aArticleContent['author']; + //文章图片 - $sArticleIcon = trim($this->sJournalUsx,'/').'/public/articleicon/'.$aArticle['article_icon']; + $sArticleIcon = trim($this->sJournalUsx,'/').$this->sArticleIcon.$aArticle['article_icon']; //期刊图片 - $sJournalIcon = trim($this->sJournalUsx,'/').'/public/journalicon/'.$aJournal['journal_icon']; + $sJournalIcon = trim($this->sJournalUsx,'/').$this->sJournalIcon.$aJournal['journal_icon']; + //获取期刊图片二维码 $aJournalQrCode = $this->createJournalQrCode($aJournal); $sJournalCode = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url']; @@ -701,6 +651,9 @@ class Aiarticle extends Base $sArticleCode = empty($aArticleQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aArticleQrCode['qrcode_url']; $aAiArticle['article_qrcode'] = $sArticleCode; + //文章cite + $aAiArticle['cite'] = $this->_cite($aArticle,$aJournal,$aJournalStage); + // //上传素材到微信 if($iIsSync == 1){ @@ -729,13 +682,14 @@ class Aiarticle extends Base $aAiArticle['article_qrcode'] = empty($aArticleQrCodeData['media_url']) ? $sArticleIcon : $aArticleQrCodeData['media_url']; //作者图片上传 - if(!empty($aAiAuthor)){ - foreach ($aAiAuthor as $key => $value) { - if(empty($value['icon'])){ + if(!empty($aAuthor)){ + $aAuthor = $this->_dealAuthor($aAuthor); + foreach ($aAuthor as $key => $value) { + if(empty($value['icon'])){ continue; - } + } //文章二维码图片上传 - $aUpload = ['email' => $value['email'],'icon' => $value['icon']]; + $aUpload = ['email' => $value['email'],'icon' => $value['icon'],'user_id' => $value['user_id']]; $aAuthorResult = json_decode($this->_updateArticleAuthor($aUpload),true); $aAuthorData = empty($aAuthorResult['data']) ? [] : $aAuthorResult['data']; $aAiAuthor[$key]['icon'] = empty($aAuthorData['media_url']) ? $value['icon'] : $aAuthorData['media_url']; @@ -756,8 +710,12 @@ class Aiarticle extends Base $journal_usx .= $aJournal['journal_usx']??''.'/'; } $aAiArticle['journal_usx_url'] = trim($journal_usx); + + //处理期刊内容 + if(empty($aJournal['journal_content'])){ + $aJournal['journal_content'] = empty($aJournal['journal_content']) ? $aJournal['journal_content_english'] : $aJournal['journal_content']; + } $aAiArticle += $aJournal; - //获取模版信息 $sTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'.html'; @@ -777,14 +735,11 @@ class Aiarticle extends Base $aSearch['{###'.$key.'###}'] = htmlspecialchars(strip_tags($value)); } //处理通讯作者信息数据 - $aAuthorInfo = json_decode($this->dealTemplateAuthor($aAiAuthor,$iTemplateId),true); + $aAuthorInfo = json_decode($this->dealTemplateAuthor($aAuthor,$iTemplateId),true); + $aSearch['{###author_info###}'] = empty($aAuthorInfo['data']['author_info']) ? ' ' : implode("\n", $aAuthorInfo['data']['author_info']); $aSearch['{###author###}'] = empty($aAuthorInfo['data']['author']) ? ' ' : $aAuthorInfo['data']['author']; - // //处理公众号推荐 - // $aRecommend = json_decode($this->dealTemplateWechatRecommend($aArticle['journal_id'],$iTemplateId),true); - // $aSearch['{###wechat_recommend###}'] = empty($aRecommend['data']) ? ' ' : implode("\n", $aRecommend['data']); - //处理往期推荐数据 $aPreviousRecommend = json_decode($this->dealTemplatePreviousRecommend($aArticle,$iTemplateId),true); if(empty($aPreviousRecommend['data'])){ @@ -799,7 +754,8 @@ class Aiarticle extends Base //处理期刊主题数据 - $aTopic = json_decode($this->dealTemplateTopic($aAiArticle['journal_topic'],$iTemplateId),true); + $sJournalTopic = empty($aJournal['journal_topic']) ? '' : $aJournal['journal_topic']; + $aTopic = json_decode($this->dealTemplateTopic($sJournalTopic,$iTemplateId),true); if(empty($aTopic['data'])){ $aSearch['{###topic_name_summary###}'] = ''; }else{ @@ -817,7 +773,8 @@ class Aiarticle extends Base } $aSearch['{###jabbr###}'] = trim(trim($aSearch['{###jabbr###}'],'.'),'。'); - + $aSearch['{###free_year###}'] = date('Y'); + $aSearch['{###covered###}'] = '内容涵盖'.str_replace('研究涵盖', '', $aSearch['{###covered###}']); $sTemplate = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplate); file_put_contents(ROOT_PATH.'public/template_info.html', $sTemplate); return json_encode(['status' => 1, 'msg' => '模版生成成功','data' => ['template' => $sTemplate]]); @@ -834,6 +791,9 @@ class Aiarticle extends Base return json_encode(['status' => 2,'msg' => 'Corresponding author or template does not exist']); } + //处理作者 + $aAuthor = $this->_dealAuthor($aAuthor); + //获取通讯作者模版 $sAuthorTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_author.html'; if (!file_exists($sAuthorTemplatePath)) { @@ -850,60 +810,41 @@ class Aiarticle extends Base $sAuthorInfo = ''; $aLogo = $this->aLogo; foreach ($aAuthor as $key => $value) { + + //请求AI翻译 + $aSearch['{#company#}'] = empty($value['company']) ? '' : $value['company']; + $aSearch['{#technical#}'] = empty($value['technical']) ? '' : $value['technical']; + $aSearch['{#introduction#}'] = empty($value['introduction']) ? '' : $value['introduction']; + $aResult = $this->_createContentForOpenAI($aSearch,1); + $aResult = json_decode($aResult,true); + if($aResult['status'] == 1){ + $aContent = empty($aResult['data']) ? [] : $aResult['data']; + $value['company'] = empty($aContent['company']) ? $value['company'] : $aContent['company']; + $value['technical'] = empty($aContent['technical']) ? $value['technical'] : $aContent['technical']; + $value['introduction'] = empty($aContent['introduction']) ? $value['introduction'] : $aContent['introduction']; + } $aAuthorSerach = []; + if(!empty($value['company'])){ + $value['company'] =str_replace(',', ',', $value['company']); + $aCompany = explode(',', $value['company']); + } + $value['company'] = empty($aCompany[0]) ? $value['company'] : trim($aCompany[0],','); foreach ($value as $k => $val) { if($k == 'icon'){ - if($val == $aLogo['url']){ - $aAuthorSerach['{###'.$k.'###}'] = $val; - }else{ - $aAuthorSerach['{###'.$k.'###}'] = trim($this->sSubmissionUrl,'/').$val; - } - $aAuthorSerach['{###'.$k.'###}'] = trim($aAuthorSerach['{###'.$k.'###}'],'/'); + $aAuthorSerach['{###icon_path###}'] = empty($val) ? $aLogo['url'] : trim($this->sSubmissionUrl,'/').'/public/usericon/'.$val; + $aAuthorSerach['{###icon_path###}'] = trim($aAuthorSerach['{###icon_path###}'],'/'); }else{ $aAuthorSerach['{###'.$k.'###}'] = trim($val,'/'); } } $aAuthorSerachInfo[] = str_replace(array_keys($aAuthorSerach), array_values($aAuthorSerach), $sAuthorTemplate); - $sAuthorInfo = $value['company'].' '.$value['author_name'].';'; + $sTechnical = empty($value['technical']) ? '老师' : $value['technical']; + $sAuthorInfo .= $value['company'].$value['author_name'].$sTechnical.','; } + $sAuthorInfo = trim($sAuthorInfo,','); return json_encode(['status' => 1,'msg' => 'success','data' => ['author_info' => $aAuthorSerachInfo,'author' => trim($sAuthorInfo,';')]]); } - // /** - // * 处理公众号推荐 - // * @param article_id 文章ID - // */ - // private function dealTemplateWechatRecommend($iJournalId = 0,$iTemplateId = 0){ - - // if(empty($iTemplateId)){ - // return json_encode(['status' => 2,'msg' => 'template does not exist']); - // } - // //获取通讯作者 - // $sTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_wechat_recommend.html'; - // if (!file_exists($sTemplatePath)) { - // return json_encode(['status' => 4, 'msg' => 'Corresponding author template does not exist','data' => '']); - // } - // if (!is_readable($sTemplatePath)) { - // return json_encode(['status' => 5, 'msg' => 'The corresponding author template is unreadable','data' => '']); - // } - // $sTemplate = file_get_contents($sTemplatePath); - - // //查询公众号推荐 - // $aRecommend = Db::name('ai_article')->field('article_id,title_chinese,covered,digest')->where('journal_id',$iJournalId)->select(); - - // $aSearchInfo = []; - // if(!empty($aRecommend)){ - // foreach ($aRecommend as $key => $value) { - // $aSerach = []; - // foreach ($value as $k => $val) { - // $aSerach['{###'.$k.'###}'] = trim(trim(trim($val),'【'),'】'); - // } - // $aSearchInfo[] = str_replace(array_keys($aSerach), array_values($aSerach), $sTemplate); - // } - // } - // return json_encode(['status' => 1,'msg' => 'success','data' => $aSearchInfo]); - // } - /** * 处理模版主题 * @param article_id 文章ID @@ -987,7 +928,7 @@ class Aiarticle extends Base continue; } $aSerach['{###wechat_url###}'] = $value['wechat_url']; - $sIcon = empty($aProductionArticle[$value['article_id']]) ? '' : trim($this->sJournalUsx,'/').'/public/articleicon/'.$aProductionArticle[$value['article_id']]; + $sIcon = empty($aProductionArticle[$value['article_id']]) ? '' : trim($this->sJournalUsx,'/').$this->sArticleIcon.$aProductionArticle[$value['article_id']]; $aSerach['{###wechat_media_url###}'] = empty($value['wechat_media_url']) ? $sIcon : $value['wechat_media_url']; $aSearchInfo[] = str_replace(array_keys($aSerach), array_values($aSerach), $sTemplate); } @@ -1025,7 +966,7 @@ class Aiarticle extends Base if(empty($sLogo)){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); }else{ - $sLogo = trim($this->sJournalUsx,'/').'/public/journalicon/'.$sLogo; + $sLogo = trim($this->sJournalUsx,'/').$this->sJournalIcon.$sLogo; $aImageInfo = json_decode($this->getImage($sLogo,$iJournalId,'journal'),true); if(empty($aImageInfo['data'])){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); @@ -1069,7 +1010,7 @@ class Aiarticle extends Base if(empty($sLogo)){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); }else{ - $sLogo = trim($this->sJournalUsx,'/').'/public/articleicon/'.$sLogo; + $sLogo = trim($this->sJournalUsx,'/').$this->sArticleIcon.$sLogo; $aImageInfo = json_decode($this->getImage($sLogo,$iArticleId,'article'),true); if(empty($aImageInfo['data'])){ $sImg = QrCodeImage::generate($sUrl,500,$sQrCodeUrl); @@ -1181,6 +1122,7 @@ class Aiarticle extends Base //获取模版生成内容 $aResult = json_decode($this->getTemplateContent($iArticleId,$iTemplateId,1),true); + $iStatus = empty($aResult['status']) ? 0 : $aResult['status'];//状态 $sMsg = empty($aResult['msg']) ? 'The content is empty' : $aResult['msg']; if($iStatus != 1){ @@ -1195,123 +1137,10 @@ class Aiarticle extends Base $aParam['template_content'] = $aData['template']; $aParam['template_id'] = $iTemplateId; $aResult = $this->addDraft($aParam); + echo '
';var_dump($aResult);exit;
         return $aResult;
     }
 
-    /**
-     * CURL 发送请求获取Token
-     * @param $appid AppID(小程序ID)
-     * @param $secret AppSecret(小程序密钥)
-     */
-
-    private function getAccessToken() {
-        //Token缓存值
-        $sToken = Cache::get($this->sWechatAccessToken);
-        //判断缓存是否存在
-        if (!$sToken) { //不存在
-            //组装接口地址
-            $sUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" 
-                 . $this->sAppID . "&secret=" . $this->sAppSecret;
-
-            $curl = curl_init();
-            curl_setopt($curl, CURLOPT_URL, $sUrl);
-            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
-            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
-            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
-            curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
-            $result = curl_exec($curl);
-            //请求失败
-            if (curl_errno($curl)){
-                $this->sError = curl_errno($curl);
-                curl_close($curl);
-                return FALSE;
-            }
-            $result = json_decode($result, true);
-            if (!empty($result['access_token'])) {
-                $sToken = $result['access_token'];
-                Cache::set($this->sWechatAccessToken, $sToken, 7000); // 有效期7200秒
-            }
-            curl_close($curl);
-        }
-        return $sToken;
-    }
-
-    /**
-     * CURL 发送请求上传永久素材
-     * @param $sToken Token
-     * @param $sPath 图片地址
-     */
-    public function uploadMaterial($sPath = '') {
-
-        $aParam = $this->request->post();
-
-        $sPath = empty($sPath) ? $aParam['path'] : $sPath;
-        // $sPath = ROOT_PATH.'static/img/'.$sPath;
-        // return json_encode(['status' => 1,'data' => ['media_id' => '1111111','url' => '22222']]);
-        //返回结果数组
-        $aResult = ['status' => 1,'msg' => '上传素材成功','data' => []];
-
-        $sPath = empty($sPath) ? $aParam['image_path']?? '' : $sPath;//文件地址
-        $sType = empty($aParam['type']) ? 'image' : $aParam['type'];//文件类型
-
-        // 验证文件有效性
-        if (!file_exists($sPath)) {
-            return json_encode(['status' => 2,'msg' => '素材不存在'.$sPath]);
-        }
-        if (!is_readable($sPath)) {
-            return json_encode(['status' => 3,'msg' => '素材不可读']);
-        }
-        if (filesize($sPath) > 10 * 1024 * 1024) {
-            return json_encode(['status' => 4,'msg' => '素材不能超过10MB']);
-        }
-
-        //获取Token
-        $sToken = $this->getAccessToken();
-        if (empty($sToken)) {
-            return json_encode(['status' => 5, 'msg' => '获取access_token失败']);
-        }
-
-        //CURL 请求接口
-        //文件参数
-        $data = [
-            'media' => new \CURLFile(
-                    realpath($sPath),
-                    mime_content_type($sPath), // 自动检测MIME类型
-                    basename($sPath)           // 上传后的文件名
-            ), // 关键:使用CURLFile对象
-        ];
-        $sUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$sToken}&type={$sType}";
-        $curl = curl_init();
-        curl_setopt($curl, CURLOPT_URL, $sUrl);
-        curl_setopt($curl, CURLOPT_POST, true); //设置为POST方式
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE) ; // 获取数据返回
-        curl_setopt($curl, CURLOPT_PROXY,$this->proxy);
-        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,true);
-        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,false);
-        //执行
-        $response = curl_exec($curl);
-        
-        //请求失败
-        if (curl_errno($curl)){
-            curl_close($curl);
-            return json_encode(['status' => 6,'msg' => "网络请求失败: " . curl_errno($curl)]);
-        }
-        curl_close($curl);//关闭请求
-
-        //获取返回结果
-        $response = json_decode($response, true);
-        if (!empty($response['errcode']) && $response['errcode'] != 0) {
-            return json_encode(['status' => 7,'msg' => "微信接口错误: [{$response['errcode']}] {$response['errmsg']}"]);
-        }
-
-        //插入数据库
-        if(empty($response['media_id'])){
-            return json_encode(['status' => 8,'msg' => "未获取到上传素材"]);
-        }
-        return json_encode(['status' => 1,'msg' => 'success','data' => $response]);
-    }
-
     /**
      * 添加文章素材
      * @param article_id 文章ID
@@ -1376,8 +1205,6 @@ class Aiarticle extends Base
     }
     /**
      * 添加期刊素材
-     * @param $sToken Token
-     * @param $sPath 图片地址
      */
     private function _addJournalMaterial($aParam = []){
 
@@ -1539,16 +1366,13 @@ class Aiarticle extends Base
         }
         //查询是否添加素材
         $aWhere = ['email' => $sEmail];
-        $aMaterial = Db::name('ai_article_author')->field('media_id,media_url')->where($aWhere)->find();
-        if(empty($aMaterial)){
-            return json_encode(['status' => 3,'msg' => 'data is null']);
-        }
+        $aMaterial = Db::name('ai_author_material')->field('media_id,media_url')->where($aWhere)->find();
         if(!empty($aMaterial['media_url'])){
             return json_encode(['status' => 1,'msg' => 'success','data' => $aMaterial]);
         }
 
         //处理图片地址
-        $sImagePath = ROOT_PATH.trim($sIcon,'/');
+        $sImagePath = ROOT_PATH.'/public/usericon/'.trim($sIcon,'/');
 
         if(trim($sIcon) != '/static/img/userImg.f3d9bc3b.jpg'){//非默认头像
             //调用微信新增素材接口上传
@@ -1566,16 +1390,167 @@ class Aiarticle extends Base
         if(trim($sIcon) == '/static/img/userImg.f3d9bc3b.jpg'){//默认头像
             $aData = $this->aLogo;
         }
-       //更新
+        //更新
         $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id'];
         $sMediaUrl = empty($aData['url']) ? [] : $aData['url'];
         $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at'];
-        $aUpdate = ['media_id' => $sMediaId,'media_url' => $sMediaUrl,'update_time' => $iTime];
-        $response = Db::name('ai_article_author')->where('email',$sEmail)->limit(1)->update($aUpdate);
+        $aInsert = ['media_id' => $sMediaId,'media_url' => $sMediaUrl,'create_time' => $iTime,'email' => $sEmail,'user_id' => $aParam['user_id']];
+        $response = Db::name('ai_author_material')->insert($aInsert);
         if($response === false){
             return json_encode(['status' => 3,'msg' => 'fail']);
         }
-        return json_encode(['status' => 1,'msg' => 'success','data' => $aUpdate]);
+        return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]);
+    }
+
+    /**
+     * CURL 发送请求获取Token
+     * @param $appid AppID(小程序ID)
+     * @param $secret AppSecret(小程序密钥)
+     */
+
+    private function getAccessToken() {
+        //Token缓存值
+        $sToken = Cache::get($this->sWechatAccessToken);
+        //判断缓存是否存在
+        if (!$sToken) { //不存在
+            //组装接口地址
+            $sUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" 
+                 . $this->sAppID . "&secret=" . $this->sAppSecret;
+
+            $curl = curl_init();
+            curl_setopt($curl, CURLOPT_URL, $sUrl);
+            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+            curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
+            $result = curl_exec($curl);
+            //请求失败
+            if (curl_errno($curl)){
+                $this->sError = curl_errno($curl);
+                curl_close($curl);
+                return FALSE;
+            }
+var_dump($this->sError,$result);
+            $result = json_decode($result, true);
+
+            if (!empty($result['access_token'])) {
+                $sToken = $result['access_token'];
+                Cache::set($this->sWechatAccessToken, $sToken, 7000); // 有效期7200秒
+            }
+            curl_close($curl);
+        }
+        return $sToken;
+    }
+
+    /**
+     * CURL 发送请求上传永久素材
+     * @param $sToken Token
+     * @param $sPath 图片地址
+     */
+    public function uploadMaterial($sPath = '') {
+
+        $aParam = $this->request->post();
+
+        $sPath = empty($sPath) ? $aParam['path'] : $sPath;
+        // $sPath = ROOT_PATH.'static/img/'.$sPath;
+        // return json_encode(['status' => 1,'data' => ['media_id' => '1111111','url' => '22222']]);
+        //返回结果数组
+        $aResult = ['status' => 1,'msg' => '上传素材成功','data' => []];
+
+        $sPath = empty($sPath) ? $aParam['image_path']?? '' : $sPath;//文件地址
+        $sType = empty($aParam['type']) ? 'image' : $aParam['type'];//文件类型
+
+        // 验证文件有效性
+        if (!file_exists($sPath)) {
+            return json_encode(['status' => 2,'msg' => '素材不存在'.$sPath]);
+        }
+        if (!is_readable($sPath)) {
+            return json_encode(['status' => 3,'msg' => '素材不可读']);
+        }
+        if (filesize($sPath) > 10 * 1024 * 1024) {
+            return json_encode(['status' => 4,'msg' => '素材不能超过10MB']);
+        }
+
+        //获取Token
+        $sToken = $this->getAccessToken();
+        if (empty($sToken)) {
+            return json_encode(['status' => 5, 'msg' => '获取access_token失败']);
+        }
+
+        //CURL 请求接口
+        //文件参数
+        $data = [
+            'media' => new \CURLFile(
+                    realpath($sPath),
+                    mime_content_type($sPath), // 自动检测MIME类型
+                    basename($sPath)           // 上传后的文件名
+            ), // 关键:使用CURLFile对象
+        ];
+        $sUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$sToken}&type={$sType}";
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $sUrl);
+        curl_setopt($curl, CURLOPT_POST, true); //设置为POST方式
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE) ; // 获取数据返回
+        curl_setopt($curl, CURLOPT_PROXY,$this->proxy);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,true);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,false);
+        //执行
+        $response = curl_exec($curl);
+        
+        //请求失败
+        if (curl_errno($curl)){
+            curl_close($curl);
+            return json_encode(['status' => 6,'msg' => "网络请求失败: " . curl_errno($curl)]);
+        }
+        curl_close($curl);//关闭请求
+
+        //获取返回结果
+        $response = json_decode($response, true);
+        if (!empty($response['errcode']) && $response['errcode'] != 0) {
+            return json_encode(['status' => 7,'msg' => "微信接口错误: [{$response['errcode']}] {$response['errmsg']}"]);
+        }
+
+        //插入数据库
+        if(empty($response['media_id'])){
+            return json_encode(['status' => 8,'msg' => "未获取到上传素材"]);
+        }
+        return json_encode(['status' => 1,'msg' => 'success','data' => $response]);
+    }
+
+    /**
+     * CURL 发送请求到 微信公众号
+     * @param $messages 内容
+     * @param $model 模型类型
+     */
+    private function curlWechatApi($sUrl = '',$sJsonData = ''){
+
+        //发送CURL请求
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $sUrl);
+        curl_setopt($curl, CURLOPT_POST, true);
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $sJsonData);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($curl, CURLOPT_HTTPHEADER, [
+            'Content-Type: application/json',
+            'Content-Length: ' . strlen($sJsonData)
+        ]);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); // 关闭SSL验证(生产环境建议开启)
+        $response = curl_exec($curl);
+        //请求失败
+        if (curl_errno($curl)){
+            curl_close($curl);
+            return ['status' => 2,'msg' => "网络请求失败: " . curl_errno($curl)];
+        }
+        curl_close($curl);//关闭请求
+
+        // 数据处理
+        $response = json_decode($response, true);
+        if (!empty($response['errcode'])) {
+            return ['status' => 3, 'msg' => '接口请求异常'.$response['errmsg'] ?? $response['errcode']];
+        }
+
+        return ['status' => 1,'msg' => '接口请求成功','data' => $response];
     }
 
     /**
@@ -1595,7 +1570,7 @@ class Aiarticle extends Base
 
         //生成模版内容
         $sContent = empty($aParam['template_content']) ? '' : $aParam['template_content'];
-        if(empty($iArticleId) || empty($sContent)){
+        if(empty($iArticleId) || empty($iTemplateId) || empty($sContent)){
             return json_encode(['status' => 2,'msg' => 'article_id OR template_content is empty']);
         }
 
@@ -1633,7 +1608,7 @@ class Aiarticle extends Base
         ], JSON_UNESCAPED_UNICODE);
         $aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
         if($aCurlResult['status'] != 1){
-            return $aCurlResult;
+            return json_encode($aCurlResult);
         }
         $response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
         //判断是否推送成功
@@ -1665,7 +1640,7 @@ class Aiarticle extends Base
     /**
      * CURL 获取草稿箱的文章
      * @param $sToken Token
-     * @param article_id int 文章ID
+     * @param media_id string 微信公众号media_id
      */
      public function getDraft($sMediaId = ''){
         //返回结果数组
@@ -1679,7 +1654,7 @@ class Aiarticle extends Base
         }
 
         //查询关联文章信息
-        $aArticle = Db::name('ai_article')->field('media_id')->where(['media_id'=>$sMediaId])->find();
+        $aArticle = Db::name('ai_wechat_article')->field('media_id')->where(['media_id'=>$sMediaId])->find();
         if(empty($aArticle)){
             return json_encode(['status' => 3,'msg' => 'The article does not exist']);
         }
@@ -1687,7 +1662,7 @@ class Aiarticle extends Base
         //获取Token
         $sToken = $this->getAccessToken();
         if (empty($sToken)) {
-            return json_encode(['status' => 4, 'msg' => '获取access_token失败']);
+            return json_encode(['status' => 4, 'msg' => 'Failed to obtain access_token']);
         }
 
         //CURL请求
@@ -1708,37 +1683,201 @@ class Aiarticle extends Base
     }
 
     /**
-     * CURL 发送请求到 微信公众号
-     * @param $messages 内容
-     * @param $model 模型类型
+     * CURL 发布草稿箱的文章
+     * @param $sToken Token
+     * @param article_id int 文章ID
      */
-    private function curlWechatApi($sUrl = '',$sJsonData = ''){
+     public function publishDraft($sMediaId = ''){
+        //返回结果数组
+        $aResult = ['status' => 1,'msg' => 'Draft box article successfully published','data' => []];
 
-        //发送CURL请求
-        $curl = curl_init();
-        curl_setopt($curl, CURLOPT_URL, $sUrl);
-        curl_setopt($curl, CURLOPT_POST, true);
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $sJsonData);
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-        curl_setopt($curl, CURLOPT_HTTPHEADER, [
-            'Content-Type: application/json',
-            'Content-Length: ' . strlen($sJsonData)
-        ]);
-        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); // 关闭SSL验证(生产环境建议开启)
-        $response = curl_exec($curl);
-        //请求失败
-        if (curl_errno($curl)){
-            curl_close($curl);
-            return ['status' => 2,'msg' => "网络请求失败: " . curl_errno($curl)];
+        //获取参数
+        $aParam = $this->request->post();
+
+        $sMediaId = empty($sMediaId) ? $aParam['media_id'] : $sMediaId;
+
+        if(empty($sMediaId)){//为空
+            //必填参数验证
+            //文章ID
+            $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
+            //模版ID
+            $iTemplateId = empty($aParam['template_id']) ? '' : $aParam['template_id'];
+            if(empty($iArticleId) || empty($iTemplateId)){
+                return json_encode(['status' => 2,'msg' => 'Please select the article or article template to publish']);
+            }
+
+            //获取文章信息
+            $aAiContent = json_decode($this->getAiArticle($iArticleId,1),true);
+            $aAiContent = empty($aAiContent['data']) ? [] : $aAiContent['data'];
+            $aAiArticle = empty($aAiContent['ai_article']) ? [] : $aAiContent['ai_article'];
+            //判断是否生成AI内容
+            if(empty($aAiArticle)){
+                return json_encode(['status' => 3, 'msg' => 'The article content of WeChat official account has not been generated']);
+            }
+
+            //查询该模版是否推送到微信公众号
+            $aWhere['article_id'] = $iArticleId;
+            $aWhere['template_id'] = $iTemplateId;
         }
-        curl_close($curl);//关闭请求
+        if(!empty($sMediaId)){
+            $aWhere['media_id'] = $sMediaId;
+        }
+        
+        $aWechatArticle = Db::name('ai_wechat_article')->field('id,is_publish,media_id,publish_status')->where($aWhere)->find();
+        if(empty($aWechatArticle)){
+            return json_encode(['status' => 4, 'msg' => 'The article was not found in the draft box of WeChat official account']);
+        }
+        $iId = empty($aWechatArticle['id']) ? 0 : $aWechatArticle['id'];
 
-        // 数据处理
-        $response = json_decode($response, true);
-        if (!empty($response['errcode'])) {
-            return ['status' => 3, 'msg' => '接口请求异常'.$response['errmsg'] ?? $response['errcode']];
+        //判断是否发布
+        if($aWechatArticle['publish_status'] != '-1'){
+            return json_encode(['status' => 5, 'msg' => 'The article has been published, please confirm']);
+        }
+        //判断微信公众号media_id 是否为空
+        $sMediaId = empty($aWechatArticle['media_id']) ? '' : $aWechatArticle['media_id'];
+        if(empty($sMediaId)){
+            return json_encode(['status' => 5,'msg' => 'The article has not been pushed to the draft box of WeChat official account, please confirm'],true);
         }
 
-        return ['status' => 1,'msg' => '接口请求成功','data' => $response];
+        //获取Token
+        $sToken = $this->getAccessToken();
+        if (empty($sToken)) {
+            return json_encode(['status' => 6, 'msg' => '获取access_token失败']);
+        }
+
+        //验证公众号是否存在该文章
+        $aInfo = json_decode($this->getDraft($sMediaId),true);
+        if($aInfo['status'] != 1){
+            return json_encode($aInfo);
+        }
+
+        // //CURL请求
+        // $sUrl = "https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token={$sToken}";
+        // //参数组装
+        // $sJsonData = json_encode([
+        //     'media_id' => $sMediaId
+        // ], JSON_UNESCAPED_UNICODE);
+        // //发送CURL请求
+        // $aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
+        // if($aCurlResult['status'] != 1){
+        //     return $aCurlResult;
+        // }
+        // $response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
+
+        // //判断是否推送成功
+        // if(empty($response['publish_id'])){
+        //     return json_encode(['status' => 9,'msg' => "未获取到发布草稿的publish_id"]);
+        // }
+$response['publish_id'] = '100000001';
+        //更新文章表publish_id
+        $aUpdate = ['update_time' => time(),'is_publish' => 1,'publish_id' => $response['publish_id'],'publish_status' => 1];
+        $result = Db::name('ai_wechat_article')->where('id',$iId)->limit(1)->update($aUpdate);
+        if($result === false){
+            return json_encode(['status' => 9,'msg' => "Failed to update the status of the published article"]);
+        }
+        return json_encode($aResult);
+    }
+
+    /**
+     * CURL 查询文章的发布状态
+     * @param $sToken Token
+     * @param article_id array 文章ID
+     */
+     public function freePublish(){
+        //返回结果数组
+        $aResult = ['status' => 1,'msg' => 'Successfully synchronized the publishing status of the article','data' => []];
+
+        //获取参数
+        $aParam = $this->request->post();
+        $aWhere = ['is_publish' => 1,'publish_id' => ['<>',''],'publish_status' => 1,'is_delete' => 2];
+        if(!empty($aParam['article_id'])){
+            $aWhere['id'] = $aParam['article_id'];
+        }
+        //查询文章发布ID
+        $aArticlePublishId = Db::name('ai_wechat_article')->where($aWhere)->column('publish_id');
+        if(empty($aArticlePublishId)){
+            return json_encode(['status' => 2,'msg' => 'No articles requiring synchronization status were found'],true);
+        }
+
+        //循环查询
+        $aInsert = $aUpdate = [];
+        foreach ($aArticlePublishId as $key => $value) {
+            if(empty($value)){
+                continue;
+            }
+            $aResult = json_decode($this->_freePublish(100000001),true);
+            if($aResult['status'] != 1){
+                continue;
+            }
+            $aData = empty($aResult['data']) ? [] : $aResult['data'];
+
+            if(empty($aData)){
+                continue;
+            }
+            $aInsert[] = $aData;
+            $aUpdate[$aData['publish_status']][] = $value;
+        }
+        //插入日志表
+        if(!empty($aInsert)){
+            $result = Db::name('wechat_article_publish_log')->insertAll($aInsert);
+        }
+        //更新文章表的发布状态
+        if(!empty($aUpdate)){
+            Db::startTrans();
+            foreach ($aUpdate as $key => $value) {
+                if(empty($value)){
+                    continue;
+                }
+                $result = Db::name('ai_wechat_article')->whereIn('publish_id',$value)->limit(count($value))->update(['publish_status' => $key,'update_time' => time()]);
+            }
+            Db::commit();
+        }
+        return json_encode($aResult);
+    }
+    private function _freePublish($sPublishId = '100000001'){
+
+         //获取参数
+        // $aParam = $this->request->post();
+        // $sPublishId = empty($sPublishId) ? $aParam['publish_id']?? '' : $sPublishId;//文件地址
+
+        // if(empty($sPublishId)){
+        //     return json_encode(['status' => 2, 'msg' => '请选择要查询的文章发布ID']);
+        // }
+        // //获取Token
+        // $sToken = $this->getAccessToken();
+        // if (empty($sToken)) {
+        //     return json_encode(['status' => 3, 'msg' => '获取access_token失败']);
+        // }
+
+        // //CURL请求
+        // $sUrl = "https://api.weixin.qq.com/cgi-bin/freepublish/get?access_token={$sToken}";
+        // //参数组装
+        // $sJsonData = json_encode([
+        //     'publish_id' => $sPublishId
+        // ], JSON_UNESCAPED_UNICODE);
+        // //发送CURL请求
+        // $aCurlResult = $this->curlWechatApi($sUrl,$sJsonData);
+        // if($aCurlResult['status'] != 1){
+        //     return $aCurlResult;
+        // }
+        // $response = empty($aCurlResult['data']) ? [] : $aCurlResult['data'];
+        $response = ['publish_id' => '1000001','publish_status' => 2,'article_id'=> '','article_detail','fail_idx' => [1,2]];
+        //log日志需要参数
+        $aField = ['publish_id','publish_status'  ,'article_id'  ,'article_detail' ,'fail_idx'  ,'create_time'];
+
+        $aInsert = [];
+        foreach ($aField as $value) {
+            if($value == 'create_time'){
+                $aInsert[$value] = time();
+                continue;
+            }
+            $aInsert[$value] =  empty($response[$value]) ? ' ' : $response[$value];
+            if(is_array($aInsert[$value])){
+                $aInsert[$value] = json_encode($aInsert[$value]);
+            }
+        }
+        $aResult['status'] = 1;
+        $aResult['data'] = $aInsert;
+        return json_encode($aResult);
     }
 }

From 267a645e273819e2725f683bfab47c61c549f2db Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Wed, 14 May 2025 16:57:22 +0800
Subject: [PATCH 03/10] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Aiarticle.php | 335 +++++++++++++++++++----
 1 file changed, 276 insertions(+), 59 deletions(-)

diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php
index 5a9c856..6927d27 100644
--- a/application/api/controller/Aiarticle.php
+++ b/application/api/controller/Aiarticle.php
@@ -32,31 +32,15 @@ class Aiarticle extends Base
     protected $timeout = 60;
     protected $aAiFileds = ['article_id','title_english','title_chinese','journal_id','covered','digest','research_result','content','highlights','discussion','prospect','research_background',];
 
-    protected $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php';//'http://zmzm.journal.dev.com'; //
+    protected $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php';//'http://zmzm.journal.dev.com'; // 
     protected $sJournalUsx = 'https://www.tmrjournals.com';
     protected $sSubmissionUrl = 'https://submission.tmrjournals.com/';
     protected $aOpenAiAsk = [ 
            1 => '
-            **核心要求**
-                1️ 请将姓名翻译成中文
-                    {#author_name#}
-                2 请将单位翻译成中文
-                    {#company#}
-                3 请将简介翻译成中文
-                    {#introduction#}
-                4 请将职称翻译成中文
-                    {#technical#}
-
-            **输出格式**
-                格式内容
-                    ```json
-                    {
-                        "author_name": "",
-                        "company": "",
-                        "introduction": "",
-                        "technical": ""
-                    }
-            ',
+             **核心要求**
+                "将以下内容翻译为中文,仅返回翻译结果,不要解释:\n {#content#}"
+           ',
+                
             2 => '
             **核心要求**
                 1️  ​内容涵盖哪些学科及方法请罗列
@@ -236,11 +220,79 @@ class Aiarticle extends Base
 
         //获取文章是否生成AI内容
         $aResult = json_decode($this->getArticle($iArticleId),true);
-        if($aResult['status'] != 1){
+        $iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
+        if($iStatus != 1){
             return json_encode($aResult);
         }
+
         //获取数据
         $aArticleContent = empty($aResult['data']) ? [] : $aResult['data'];
+        //文章数据
+        $aArticle = empty($aArticleContent['article']) ? [] : $aArticleContent['article'];
+        if(empty($aArticle)){
+            return json_encode(['status' => 3,'msg' => 'The content of the article is empty']);
+        }
+
+        //查询AI内容是否生成
+        $aAiArticle = json_decode($this->getAiArticle($iArticleId),true);
+        $aAiArticleContent = empty($aAiArticle['data']) ? [] : $aAiArticle['data'];
+        $aAiArticle = empty($aAiArticleContent['ai_article']) ? [] : $aAiArticleContent['ai_article'];
+
+        $iId = empty($aAiArticle['ai_article_id']) ? 0 : $aAiArticle['ai_article_id'];
+        if(empty($aAiArticle)){
+            //插入t_ai_article数据
+            $aInsert = ['title_english' => $aArticle['title'],'article_id' => $iArticleId,'create_time' => time()];
+            $iId = Db::name('ai_article')->insertGetId($aInsert);
+            if($iId === false){
+                return json_encode(['status' => 4,'msg' => 'Data insertion failed']);
+            }
+        }
+
+        //判断是否生成
+        if($aAiArticle['is_generate'] == 1){
+            return json_encode(['status' => 5,'msg' => 'The data has been generated, please proceed with the next steps']);
+        }
+
+        //请求OPENAI
+        return $this->createForOpenAi($aArticleContent,$aAiArticle);
+        // //返回数据
+        // return json_encode(['status' => 1,'msg' => 'Data generation takes some time, please do not cancel this operation','data' => ['ai_article_id' => $iId]]);
+    }
+
+    public function createForOpenAi($aArticleContent = [],$aAiArticle = []){
+
+        if(empty($aArticleContent)){
+
+            $aParam = $this->request->post();
+
+            $iId = empty($aParam['ai_article_id']) ? 0 : $aParam['ai_article_id'];
+
+            //查询AI内容是否生成
+            $aAiArticle = json_decode($this->getAiArticle(0,1,$iId),true);
+            $aAiArticleContent = empty($aAiArticle['data']) ? [] : $aAiArticle['data'];
+            $aAiArticle = empty($aAiArticleContent['ai_article']) ? [] : $aAiArticleContent['ai_article'];
+            if(empty($aAiArticle)){
+                return json_encode(['status' => 4,'msg' => 'The article has not been generated, please confirm']);
+            }
+            //判断是否生成
+            if($aAiArticle['is_generate'] == 1){
+                return json_encode(['status' => 5,'msg' => 'The data has been generated, please proceed with the next steps']);
+            }
+            $iArticleId = empty($aAiArticle['article_id']) ? '' : $aAiArticle['article_id'];
+
+            //获取文章是否生成AI内容
+            $aResult = json_decode($this->getArticle($iArticleId),true);
+            $iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
+            if($iStatus != 1){
+                return json_encode($aResult);
+            }
+            //获取数据
+            $aArticleContent = empty($aResult['data']) ? [] : $aResult['data'];
+        }
+
+        $iId = empty($aAiArticle['ai_article_id']) ? 0 : $aAiArticle['ai_article_id'];
+
+        $iArticleId = empty($aAiArticle['article_id']) ? 0 : $aAiArticle['article_id'];
 
         //文章数据
         $aArticle = empty($aArticleContent['article']) ? [] : $aArticleContent['article'];
@@ -294,27 +346,76 @@ class Aiarticle extends Base
         $aContent['journal_id'] = $aArticle['journal_id'];
        
 
-        //获取AI生成表里的数据判断是新增或更新
-        $aAiContent = json_decode($this->getAiArticle($iArticleId,1),true);
-        $aAiContent = empty($aAiContent['data']) ? [] : $aAiContent['data'];
-        $aAiArticle = empty($aAiContent['ai_article']) ? [] : $aAiContent['ai_article'];
-        $aAiAuthor = empty($aAiContent['ai_article_autho']) ? [] : $aAiContent['ai_article_autho'];
-        if(empty($aAiArticle)){//新增
-            //执行数据入库
-            $aResult = $this->addAiArticle($aContent);
-        }
-        if(!empty($aAiArticle)){//更新
-            if(empty($aAiArticle['ai_article_id'])){
-                return json_encode(array('status' => 8,'msg' => 'No AI article found to update'));
-            }
-            //执行数据入库
-            $aContent['ai_article_id'] = $aAiArticle['ai_article_id'];
-            $aContent['author_list'] = $aAuthor;
-            $aResult = $this->updateAiArticle($aContent);
-        }
-
+        //更新数据库
+        $aContent['ai_article_id'] = $iId;
+        $aResult = $this->updateAiArticle($aContent);
         return $aResult;
     }
+    // public function createForOpenAi($aArticleContent = [],$iId = 0){
+
+
+    //     if(empty($aArticleContent) || empty($iId)){
+    //         return json_encode(['status' => 2,'msg' => 'data is empty']);
+    //     }
+
+
+    //     //文章数据
+    //     $aArticle = empty($aArticleContent['article']) ? [] : $aArticleContent['article'];
+
+    //     //期刊数据
+    //     $aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal'];
+
+    //     //子期刊数据
+    //     $aJournalStage = empty($aArticleContent['journal_stage']) ? [] : $aArticleContent['journal_stage'];
+
+    //     //通讯作者
+    //     $aAuthor = empty($aArticleContent['author']) ? [] : $aArticleContent['author'];
+
+
+    //     //生成期刊图片二维码
+    //     $aJournalQrCode = $this->createJournalQrCode($aJournal);
+    //     if(empty($aJournalQrCode['qrcode_url'])){
+    //         return json_encode(['status' => 3,'msg' => 'Journal QR code not generated']);
+    //     }
+      
+    //     //生成文章图片二维码
+    //     $aArticleQrCode = $this->createArticleQrCode($aArticle);
+    //     if(empty($aArticleQrCode['qrcode_url'])){
+    //         return json_encode(['status' => 4,'msg' => 'Article QR code not generated']);
+    //     }
+
+    //     //查询文章内容
+    //     $aMain = empty($aArticleContent['main']) ? [] : $aArticleContent['main'];;
+    //     $sContent = empty($aMain) ? '' : implode(',', $aMain);
+
+    //     //请求OPENAI生成微信公众号文章内容
+    //     $aSearch = [];
+    //     $aSearch['{#content#}'] = $this->basic_html_filter($sContent);
+    //     $aSearch['{#abstract#}'] = $this->basic_html_filter($aArticle['abstract']);
+    //     $aSearch['{#title_chinese#}'] = $this->basic_html_filter($aArticle['title']);
+    //     $aSearch['{#journal_content#}'] = $this->basic_html_filter($aJournal['journal_content'] ?? '');
+    //     $aSearch['{#journal_content#}'] = trim(trim($aSearch['{#journal_content#}'],'.'),'。');
+    //     $aResult = $this->_createContentForOpenAI($aSearch,2);
+    //     $aResult = json_decode($aResult,true);
+    //     if($aResult['status'] != 1){
+    //         return json_encode($aResult);
+    //     }
+    //     $aContent = empty($aResult['data']) ? [] : $aResult['data'];
+    //     if(empty($aContent)){
+    //         return json_encode(['status' => 4,'msg' => 'Data is empty']);
+    //     }
+
+    //     //组装数据
+    //     $aContent['article_id'] = $iArticleId;
+    //     $aContent['title_english'] = $aArticle['title'];
+    //     $aContent['journal_id'] = $aArticle['journal_id'];
+       
+
+    //     //更新数据库
+    //     $aContent['ai_article_id'] = $iId;
+    //     $aResult = $this->updateAiArticle($aContent);
+    //     return $aResult;
+    // }
 
     /**
      * 处理文章引用
@@ -427,17 +528,36 @@ class Aiarticle extends Base
      * 获取Ai生成文章信息
      * @param article_id 文章ID
      */
-    public function getAiArticle($iArticleId = 0,$iSelectAuthor = 2){
+    public function getAiArticle($iArticleId = 0,$iSelectAuthor = 2,$iAiArticleId = 0){
 
         $aParam = $this->request->post();
-        $iArticleId = empty($iArticleId) ? $aParam['article_id'] : $iArticleId;
+
+        //文章ID
+        $iArticleId = empty($iArticleId) ? '' : $iArticleId;
+        $iArticleIdParam = empty($aParam['article_id']) ? '' : $aParam['article_id'];
+        $iArticleId = empty($iArticleId) ? $iArticleIdParam : $iArticleId;
+        //AI生成文章ID
+        $iAiArticleId = empty($iAiArticleId) ? '' : $iAiArticleId;
+        $iAiArticleIdParam = empty($aParam['ai_article_id']) ? '' : $aParam['ai_article_id'];
+        $iAiArticleId = empty($iAiArticleId) ? $iAiArticleIdParam : $iAiArticleId;
+
+        if(empty($iArticleId) && empty($iAiArticleId)){
+            return json_encode(['status' => 2,'msg' => 'Please select the article to be generated']);
+        }
+
         //查询AI生成的文章内容
-        $aWhere['article_id'] = $iArticleId;
-        $aWhere['is_delete'] = 2;
+        $aWhere = ['is_delete' => 2];
+        if(!empty($iArticleId)){
+            $aWhere['article_id'] = $iArticleId;
+        }
+        if(!empty($iAiArticleId)){
+            $aWhere['ai_article_id'] = $iAiArticleId;
+        }
         $aAiArticle = Db::name('ai_article')->where($aWhere)->find();
         if(empty($aAiArticle)){
             return json_encode(['status' => 1,'msg' => 'data is null','data' => ['ai_article' => []]]);
         }
+        $iArticleId = empty($aAiArticle['article_id']) ? 0 : $aAiArticle['article_id'];
 
         //查询文章通讯作者
         $aAiAuthor = [];
@@ -532,7 +652,7 @@ class Aiarticle extends Base
         $aResult = ['status' => 1,'msg' => 'AI article updated successfully','data' => []];
 
         //获取参数
-        $aParam = $this->request->post();
+        $aParam = empty($aParam) ? $this->request->post() : $aParam;
 
         //主键ID
         $iAiArticleId = empty($aParam['ai_article_id']) ? 0 : $aParam['ai_article_id'];
@@ -571,13 +691,78 @@ class Aiarticle extends Base
             return json_encode(['status' => 1,'msg' => 'No data currently being processed']);
         }
 
+        Db::startTrans();
         //执行入库
         $aUpdateParam['update_time'] = time();
+        $aUpdateParam['is_generate'] = 1;
         $result = Db::name('ai_article')->where('ai_article_id',$iAiArticleId)->limit(1)->update($aUpdateParam);
         if($result === false){
            $aResult =  json_encode(['status' => 3,'msg' => 'UPDATEING AI article failed']);
         }
         $aResult['data'] = $aUpdateParam;
+
+        //更新作者信息
+        $aAuthorList = empty($aParam['author_list']) ? []: $aParam['author_list'];
+        $aAuthorList = is_array( $aAuthorList) ? $aAuthorList: json_decode($aAuthorList,true);
+        if(!empty($aAuthorList)){
+
+            $aAuthorList = array_column($aAuthorList, null,'email');
+            //根据邮箱查询作者信息
+            $aEmail = array_keys($aAuthorList);
+
+            $aUserInfo = $aUserReviewer = [];
+            if(!empty($aEmail)){
+                $aUserParam = ['email' => ['in',$aEmail]];
+                $aUserInfo = Db::name('user')->field('email,user_id')->where($aUserParam)->select();
+                if(!empty($aUserInfo)){
+                    $aUserId = array_column($aUserInfo, 'user_id');
+                    //查询用户附表
+                    $aWhere = ['reviewer_id' => ['in',$aUserId]];
+                    $aUserReviewer = Db::name('user_reviewer_info')->where($aWhere)->column('reviewer_id');
+                }
+            }
+
+            //更新用户信息
+            if(!empty($aUserInfo)){
+                foreach ($aUserInfo as $key => $value) {
+
+                    $aUser = empty($aAuthorList[$value['email']]) ? [] : $aAuthorList[$value['email']];
+                    if(empty($aUser)){
+                        continue;
+                    }
+                    //更新作者名字
+                    if(!empty($aUser['author_name'])){
+                        $aUpdate = ['localname' => $aUser['author_name']];
+                        Db::name('user')->where('user_id',$value['user_id'])->limit(1)->update($aUpdate);
+                    }
+                    //更新作者简介和单位
+                    $aUpdateReviewer = [];
+                    if(!empty($aUser['technical'])){
+                        $aUpdateReviewer['technical'] = $aUser['technical'];
+                    }
+                    if(!empty($aUser['introduction'])){
+                        $aUpdateReviewer['introduction'] = $aUser['introduction'];
+                    }
+                    if(!empty($aUser['company'])){
+                        $aUpdateReviewer['company'] = $aUser['company'];
+                    }
+                    if(!empty($aUpdateReviewer)){
+
+                        if(in_array($value['user_id'], $aUserReviewer)){//更新
+                            Db::name('user_reviewer_info')->where('reviewer_id',$value['user_id'])->limit(1)->update($aUpdateReviewer);
+                        }
+                       
+                        if(!in_array($value['user_id'], $aUserReviewer)){//插入
+                            $aUpdateReviewer['reviewer_id'] = $value['user_id'];
+                            Db::name('user_reviewer_info')->insert($aUpdateReviewer);
+                        }
+                    }
+                }
+            }
+     
+        }
+        Db::commit();
+        $aResult['data'] = $aUpdateParam;
         return json_encode($aResult);
     }
 
@@ -809,26 +994,32 @@ class Aiarticle extends Base
         $aAuthorSerachInfo = [];
         $sAuthorInfo = '';
         $aLogo = $this->aLogo;
+
+        //请求AI翻译
+        $sContent = '';
+        $aSearch['{#content#}'] = json_encode($aAuthor);
+        $aResult = json_decode($this->_createContentForOpenAI($aSearch,1),true);
+        $aContent = empty($aResult['data']) ? [] : array_column($aResult['data'], null,'email');
+
         foreach ($aAuthor as $key => $value) {
 
             //请求AI翻译
-            $aSearch['{#company#}'] = empty($value['company']) ? '' : $value['company'];
-            $aSearch['{#technical#}'] = empty($value['technical']) ? '' : $value['technical'];
-            $aSearch['{#introduction#}'] = empty($value['introduction']) ? '' : $value['introduction'];
-            $aResult = $this->_createContentForOpenAI($aSearch,1);
-            $aResult = json_decode($aResult,true);
-            if($aResult['status'] == 1){
-                $aContent = empty($aResult['data']) ? [] : $aResult['data'];
-                $value['company'] = empty($aContent['company']) ? $value['company'] : $aContent['company'];
-                $value['technical'] = empty($aContent['technical']) ? $value['technical'] : $aContent['technical'];
-                $value['introduction'] = empty($aContent['introduction']) ? $value['introduction'] : $aContent['introduction'];
-            }
+            $aInfo = empty($aContent[$value['email']]) ? [] : $aContent[$value['email']];
             $aAuthorSerach = [];
+
+            //所属单位处理
+            $value['company'] = empty($aInfo['company']) ? $value['company'] : $aInfo['company'];
             if(!empty($value['company'])){
                 $value['company'] =str_replace(',', ',', $value['company']);
                 $aCompany = explode(',', $value['company']);
             } 
             $value['company'] = empty($aCompany[0]) ? $value['company'] : trim($aCompany[0],',');
+
+            //职称处理
+            $value['technical'] = empty($aInfo['technical']) ? $value['technical'] : $aInfo['technical'];
+            //简介处理
+            $value['introduction'] = empty($aInfo['introduction']) ? $value['introduction'] : $aInfo['introduction'];
+
             foreach ($value as $k => $val) {
                 if($k == 'icon'){
                     $aAuthorSerach['{###icon_path###}'] = empty($val) ? $aLogo['url'] : trim($this->sSubmissionUrl,'/').'/public/usericon/'.$val;
@@ -1137,7 +1328,6 @@ class Aiarticle extends Base
         $aParam['template_content'] = $aData['template'];
         $aParam['template_id'] = $iTemplateId;
         $aResult = $this->addDraft($aParam);
-        echo '
';var_dump($aResult);exit;
         return $aResult;
     }
 
@@ -1430,7 +1620,6 @@ class Aiarticle extends Base
                 curl_close($curl);
                 return FALSE;
             }
-var_dump($this->sError,$result);
             $result = json_decode($result, true);
 
             if (!empty($result['access_token'])) {
@@ -1880,4 +2069,32 @@ $response['publish_id'] = '100000001';
         $aResult['data'] = $aInsert;
         return json_encode($aResult);
     }
+
+    /**
+     * 获取Ai生成文章状态
+     * @param article_id 文章ID
+     */
+    public function getAiArticleStatus(){
+
+        $aParam = $this->request->post();
+
+        //AI生成文章ID
+        $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
+        if(empty($iArticleId)){
+            return json_encode(['status' => 2,'msg' => 'Please select the article to be generated']);
+        }
+
+        //查询AI生成的文章内容
+        $aWhere = ['is_delete' => 2];
+        if(!empty($iArticleId)){
+            $aWhere['article_id'] = $iArticleId;
+        }
+        $aAiArticle = Db::name('ai_article')->field('is_generate')->where($aWhere)->find();
+
+        // 生成状态
+        $aMsg = [1 => 'The data has been generated, please proceed with the next steps',2 => 'AI content generation in progress',3 => 'AI content not generated'];
+        $iStatus = empty($aAiArticle['is_generate']) ? 3 : $aAiArticle['is_generate'];
+        $sMsg = empty($aMsg[$iStatus]) ? 'illegal request' : $aMsg[$iStatus];
+        return json_encode(['status' => 1,'msg' => $sMsg,'data' => ['is_generate' => $iStatus]]);
+    }
 }

From 51aed0c4bb3701ae210c379514a3694f27abc66b Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Wed, 14 May 2025 17:02:20 +0800
Subject: [PATCH 04/10] =?UTF-8?q?=E6=9C=9F=E5=88=8A=E8=A1=A8=E5=AD=97?=
 =?UTF-8?q?=E6=AE=B5=E6=96=B0=E5=A2=9E=E8=AF=9D=E9=A2=98=E5=92=8C=E4=B8=AD?=
 =?UTF-8?q?=E6=96=87=E7=AE=80=E4=BB=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Journal.php | 42 +++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/application/api/controller/Journal.php b/application/api/controller/Journal.php
index ed87143..e8858dd 100644
--- a/application/api/controller/Journal.php
+++ b/application/api/controller/Journal.php
@@ -13,6 +13,8 @@ use app\api\controller\User as usercontroller;
 class Journal extends Base {
 
 
+    protected $sJournalUrl = 'http://zmzm.journal.dev.com/';
+
     public function __construct(\think\Request $request = null) {
         parent::__construct($request);
     }
@@ -65,6 +67,11 @@ class Journal extends Base {
 
     public function getAllJournal(){
         $list = $this->journal_obj->where('state',0)->select();
+        //接口请求获取journal_topic 和 abstract_chinese chengxiaoling 20250514 start
+        if(!empty($list)){
+           $list = $this->_getJournalForApi($list);
+        }
+        //接口请求获取journal_topic 和 abstract_chinese chengxiaoling 20250514 end
         $re['journals'] = $list;
         return jsonSuccess($re);
     }
@@ -197,11 +204,17 @@ class Journal extends Base {
     {
         $user_id = $this->request->post('user_id');
         $list = $this->journal_obj->where('editor_id',$user_id)->where("state",0)->select();
+
+        //接口请求获取journal_topic 和 abstract_chinese chengxiaoling 20250514 start
+        if(!empty($list)){
+           $list = $this->_getJournalForApi($list);
+        }
+        //接口请求获取journal_topic 和 abstract_chinese chengxiaoling 20250514 end
+
         $re['journals'] = $list;
         return jsonSuccess($re);
     }
 
-
     /**
      * 获取可申请审稿人的期刊
      */
@@ -265,6 +278,9 @@ class Journal extends Base {
                 $update['journal_topic'] =  $data['journal_topic'];
             }
         }
+        if(isset($data['abstract_chinese'])){
+            $update['abstract_chinese'] =  $data['abstract_chinese'];
+        }
         //新增字段期刊涵盖主题多个逗号分隔 chengxiaoling 20250507 end
         if(isset($data['fee'])&&$data['fee']!=0){
             $update['fee'] = $data['fee'];
@@ -311,4 +327,28 @@ class Journal extends Base {
     }
 
 
+
+    /**
+     * 接口请求获取Journal数据库里的期刊话题及中文简介
+     */
+    private function _getJournalForApi($list = []){
+        if(empty($list)){
+            return [];
+        }
+        $aIssn = array_column($list, 'issn');
+        $sUrl = $this->sJournalUrl."master/Journal/getJournals";
+        $aParam['issn'] = $aIssn;
+        $aResult = object_to_array(json_decode(myPost1($sUrl,$aParam)));
+        $aData = empty($aResult['data']) ? [] : $aResult['data'];
+        $aJournal = empty($aData['journals']) ? [] : array_column($aData['journals'],null,'issn');
+        foreach ($list as $key => $value) {
+            $aJournalInfo = empty($aJournal[$value['issn']]) ? [] : $aJournal[$value['issn']];
+
+            $list[$key]['journal_topic'] = empty($aJournalInfo['journal_topic']) ? '' : $aJournalInfo['journal_topic'];
+            $list[$key]['abstract_chinese'] = empty($aJournalInfo['abstract_chinese']) ? '' : $aJournalInfo['abstract_chinese'];
+        }
+        return $list;
+    }
+
+
 }

From 384955402069fde49abecf5cbad63c14bd2239a6 Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Wed, 14 May 2025 17:11:15 +0800
Subject: [PATCH 05/10] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Aiarticle.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php
index 6927d27..a1bd685 100644
--- a/application/api/controller/Aiarticle.php
+++ b/application/api/controller/Aiarticle.php
@@ -731,22 +731,22 @@ class Aiarticle extends Base
                         continue;
                     }
                     //更新作者名字
-                    if(!empty($aUser['author_name'])){
+                    if(isset($aUser['author_name'])){
                         $aUpdate = ['localname' => $aUser['author_name']];
                         Db::name('user')->where('user_id',$value['user_id'])->limit(1)->update($aUpdate);
                     }
                     //更新作者简介和单位
                     $aUpdateReviewer = [];
-                    if(!empty($aUser['technical'])){
+                    if(isset($aUser['technical'])){
                         $aUpdateReviewer['technical'] = $aUser['technical'];
                     }
-                    if(!empty($aUser['introduction'])){
+                    if(isset($aUser['introduction'])){
                         $aUpdateReviewer['introduction'] = $aUser['introduction'];
                     }
-                    if(!empty($aUser['company'])){
+                    if(isset($aUser['company'])){
                         $aUpdateReviewer['company'] = $aUser['company'];
                     }
-                    if(!empty($aUpdateReviewer)){
+                    if(isset($aUpdateReviewer)){
 
                         if(in_array($value['user_id'], $aUserReviewer)){//更新
                             Db::name('user_reviewer_info')->where('reviewer_id',$value['user_id'])->limit(1)->update($aUpdateReviewer);

From 4391b2c86d5e0fd170d5628042ac62a576353751 Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Wed, 14 May 2025 18:05:19 +0800
Subject: [PATCH 06/10] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Aiarticle.php | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php
index a1bd685..1415711 100644
--- a/application/api/controller/Aiarticle.php
+++ b/application/api/controller/Aiarticle.php
@@ -246,10 +246,11 @@ class Aiarticle extends Base
             if($iId === false){
                 return json_encode(['status' => 4,'msg' => 'Data insertion failed']);
             }
+            $aAiArticle = array_merge(['ai_article_id' => $iId,'article_id' => $iArticleId,'is_generate' => 2],$aInsert);
         }
 
         //判断是否生成
-        if($aAiArticle['is_generate'] == 1){
+        if(!empty($aAiArticle['is_generate']) && $aAiArticle['is_generate'] == 1){
             return json_encode(['status' => 5,'msg' => 'The data has been generated, please proceed with the next steps']);
         }
 
@@ -694,6 +695,7 @@ class Aiarticle extends Base
         Db::startTrans();
         //执行入库
         $aUpdateParam['update_time'] = time();
+        $aUpdateParam['author'] = empty($aUpdateParam['author']) ? 'TMR编辑部' : $aUpdateParam['author'];
         $aUpdateParam['is_generate'] = 1;
         $result = Db::name('ai_article')->where('ai_article_id',$iAiArticleId)->limit(1)->update($aUpdateParam);
         if($result === false){

From 4cabe79a589135e68c9d274ef38633aadcd0f60d Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Thu, 15 May 2025 15:32:08 +0800
Subject: [PATCH 07/10] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Aiarticle.php | 134 +++++++++++++++++++----
 1 file changed, 111 insertions(+), 23 deletions(-)

diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php
index 1415711..ba6dabe 100644
--- a/application/api/controller/Aiarticle.php
+++ b/application/api/controller/Aiarticle.php
@@ -93,6 +93,8 @@ class Aiarticle extends Base
     protected $sArticleIcon = '/public/articleicon/';
     //期刊图片icon地址
     protected $sJournalIcon = '/public/journalicon/';
+    //期刊编辑二维码地址
+    protected $sJournalEditorQrcode = '/public/journaleditorqrcode/';
     //"highlights": {
     // "theory_innovation": "【中西医理论结合点】",
     // "methodology": "【关键技术+量化指标】",
@@ -349,6 +351,7 @@ class Aiarticle extends Base
 
         //更新数据库
         $aContent['ai_article_id'] = $iId;
+        $aContent['author'] = empty($aJournal['publish_author']) ? 'TMR编辑部' : $aJournal['publish_author'];
         $aResult = $this->updateAiArticle($aContent);
         return $aResult;
     }
@@ -580,6 +583,13 @@ class Aiarticle extends Base
 
             }
         }
+
+        //查询是否上传到微信草稿箱
+        if(!empty($iArticleId)){
+            $aDraft = Db::name('ai_wechat_article')->where(['article_id' => $iArticleId,'is_delete' => 2])->column('template_id');
+            $aAiArticle['upload_draft'] = $aDraft;
+        }
+       
         return json_encode(['status' => 1,'msg' => 'success','data' => ['ai_article' => $aAiArticle,'ai_article_author' => $aAiAuthor]]);
     }
     /**
@@ -589,7 +599,7 @@ class Aiarticle extends Base
      */
     private function basic_html_filter($html) {
         // 移除所有HTML标签及PHP标签
-        $text = strip_tags($html);
+        $text = empty($html) ? '' : strip_tags($html);
         
         // 转换HTML实体
         $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
@@ -626,7 +636,7 @@ class Aiarticle extends Base
                 $aInsertParam[$val] = $aParam[$val];
                 continue;
             }
-            $aInsertParam[$val] = addslashes(strip_tags($aParam[$val]));
+            $aInsertParam[$val] = empty($aParam[$val]) ? '' : addslashes(strip_tags($aParam[$val]));
         }
         if($bStatus == false){
             return json_encode(['status' => 2,'msg' => $sFiled.'cannot be empty']);
@@ -686,7 +696,7 @@ class Aiarticle extends Base
             if(!isset($aParam[$val])){
                 continue;
             }
-            $aUpdateParam[$val] = addslashes(strip_tags($aParam[$val]));
+            $aUpdateParam[$val] = empty($aParam[$val]) ? '' : addslashes(strip_tags($aParam[$val]));
         }
         if(empty($aUpdateParam)){
             return json_encode(['status' => 1,'msg' => 'No data currently being processed']);
@@ -695,7 +705,7 @@ class Aiarticle extends Base
         Db::startTrans();
         //执行入库
         $aUpdateParam['update_time'] = time();
-        $aUpdateParam['author'] = empty($aUpdateParam['author']) ? 'TMR编辑部' : $aUpdateParam['author'];
+        // $aUpdateParam['author'] = empty($aUpdateParam['author']) ? 'TMR编辑部' : $aUpdateParam['author'];
         $aUpdateParam['is_generate'] = 1;
         $result = Db::name('ai_article')->where('ai_article_id',$iAiArticleId)->limit(1)->update($aUpdateParam);
         if($result === false){
@@ -828,6 +838,10 @@ class Aiarticle extends Base
         //期刊图片
         $sJournalIcon = trim($this->sJournalUsx,'/').$this->sJournalIcon.$aJournal['journal_icon'];
 
+        //期刊编辑二维码
+        $sEditorQrcode = empty($aJournal['editor_qrcode']) ? '' : $aJournal['editor_qrcode'];
+        $sEditorQrcode = trim($this->sSubmissionUrl,'/').$this->sJournalEditorQrcode.$sEditorQrcode;
+
         //获取期刊图片二维码
         $aJournalQrCode = $this->createJournalQrCode($aJournal);
         $sJournalCode = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url'];
@@ -882,12 +896,20 @@ class Aiarticle extends Base
                     $aAiAuthor[$key]['icon'] = empty($aAuthorData['media_url']) ? $value['icon'] : $aAuthorData['media_url'];
                 }
             }
+
+            //上传期刊编辑二维码
+            $aUpload = ['editor_qrcode' => $aJournal['editor_qrcode']??'','journal_id' => $aAiArticle['journal_id']];
+            $aJournalEditorQrCodeResult = json_decode($this->_updateJournalEditorQrcode($aUpload),true);
+            $aJournalEditorQrCodeData = empty($aJournalEditorQrCodeResult['data']) ? [] : $aJournalEditorQrCodeResult['data'];
+            $aAiArticle['editor_qrcode'] = empty($aJournalEditorQrCodeData['media_url']) ? $sEditorQrcode : $aJournalEditorQrCodeData['media_url'];
         }else{
 
              //处理文章图片地址数据
             $aAiArticle['article_icon'] = $sArticleIcon;
             //处理文章期刊图片地址数据
             $aAiArticle['journal_icon'] = $sJournalIcon;
+            //期刊编辑二维码图片地址数据
+            $aAiArticle['editor_qrcode'] = $sEditorQrcode;
 
         }
         //期刊访问地址
@@ -919,7 +941,10 @@ class Aiarticle extends Base
         //数据处理
         $aSearch = [];
         foreach ($aAiArticle as $key => $value) {
-            $aSearch['{###'.$key.'###}'] = htmlspecialchars(strip_tags($value));
+            if(is_array($value)){
+                continue;
+            }
+            $aSearch['{###'.$key.'###}'] = empty($value) ? '' : htmlspecialchars(strip_tags($value));
         }
         //处理通讯作者信息数据
         $aAuthorInfo = json_decode($this->dealTemplateAuthor($aAuthor,$iTemplateId),true);
@@ -1407,12 +1432,6 @@ class Aiarticle extends Base
         if(empty($iJournalId) || empty($sIcon)){
             return json_encode(['status' => 2,'msg' => 'journal_id or image is empty']);
         }
-        //查询是否添加素材
-        $aWhere = ['journal_id' => $iJournalId,'is_delete' => 2];
-        $aMaterial = Db::name('ai_journal_material')->field('media_id,media_url')->where($aWhere)->find();
-        if(!empty($aMaterial)){
-            return json_encode(['status' => 1,'msg' => 'success','data' => $aMaterial]);
-        }
 
         //处理图片地址
         $aImageInfo = pathinfo($sIcon);
@@ -1420,12 +1439,12 @@ class Aiarticle extends Base
         $sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension'];
         $sImagePath = 'journal/imgae_'.$iJournalId.'.'.$sExtension;
         $sImagePath = ROOT_PATH.'public/qrcode/'.$sImagePath;
-        if (!file_exists($sImagePath)) {//下载图片
-            $aImageInfo = json_decode($this->getImage($sIcon,$iJournalId,'journal'),true);
-            if(empty($aImageInfo['data'])){
-                return json_encode(['status' => 3,'msg' => 'Image download failed']);
-            }
+        // if (!file_exists($sImagePath)) {//下载图片
+        $aImageInfo = json_decode($this->getImage($sIcon,$iJournalId,'journal'),true);
+        if(empty($aImageInfo['data'])){
+            return json_encode(['status' => 3,'msg' => 'Image download failed']);
         }
+        // }
 
         //调用微信新增素材接口上传
         $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true);
@@ -1439,16 +1458,31 @@ class Aiarticle extends Base
              return json_encode(['status' => 5,'msg' => 'Material not obtained']);
         }
 
+        //查询是否添加素材
+        $aWhere = ['journal_id' => $iJournalId,'is_delete' => 2];
+        $aMaterial = Db::name('ai_journal_material')->field('id,media_id,media_url')->where($aWhere)->find();
+
         //处理入库数据
         $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id'];
         $sMediaUrl = empty($aData['url']) ? [] : $aData['url'];
         $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at'];
-        //入库数据组装
-        $aInsert = ['type' => 'image','media_id' => $sMediaId,'create_time' =>  $iTime,'journal_id' => $iJournalId,'media_url' => $sMediaUrl];
-        $response = Db::name('ai_journal_material')->insert($aInsert);
-        if($response === false){
-            return json_encode(['status' => 6,'msg' => 'Add fail']);
+
+
+        //操作数据组装
+        $aInsert = ['type' => 'image','media_id' => $sMediaId,'journal_id' => $iJournalId,'media_url' => $sMediaUrl];
+
+        Db::startTrans();
+
+        $aInsert['create_time'] =  $iTime;
+        $responseInsert = Db::name('ai_journal_material')->insert($aInsert);
+
+        if(!empty($aMaterial)){
+            $aUpdate['update_time'] =  $iTime;
+            $aUpdate['is_delete'] = 1;
+            $responseUpdate = Db::name('ai_journal_material')->where('id',$aMaterial['id'])->limit(1)->update($aUpdate);
         }
+        Db::commit();
+     
         return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]);
     }
     /**
@@ -1594,6 +1628,60 @@ class Aiarticle extends Base
         return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]);
     }
 
+    /**
+     * 更新通讯作者关联微信公众号素材
+     */
+    private function _updateJournalEditorQrcode($aParam = []){
+
+        $iJournalId = empty($aParam['journal_id']) ? '' : $aParam['journal_id'];
+        //文章图片
+        $sIcon = empty($aParam['editor_qrcode']) ? '20250515/103a7cdf2f76dc4d522b7273d4b149e5.jpg' : $aParam['editor_qrcode'];
+
+        if(empty($iJournalId) || empty($sIcon)){
+            return json_encode(['status' => 2,'msg' => 'The journal editor did not upload the QR code']);
+        }
+
+        //处理图片地址
+        $sImagePath = ROOT_PATH.'/public/journaleditorqrcode/'.trim($sIcon,'/');
+
+        //调用微信新增素材接口上传
+        $aUploadResult = json_decode($this->uploadMaterial($sImagePath),true);
+        $iStatus = empty($aUploadResult['status']) ? 0 : $aUploadResult['status'];
+        $sMsg = empty($aUploadResult['msg']) ? 'Failed to upload materials' : $aUploadResult['msg'];
+        if($iStatus != 1){
+             return json_encode(['status' => 4,'msg' => $sMsg]);
+        }
+        $aData = empty($aUploadResult['data']) ? [] : $aUploadResult['data'];
+        if(empty($aData['url'])){
+             return json_encode(['status' => 5,'msg' => 'Material not obtained']);
+        } 
+        //查询是否添加素材
+        $aWhere = ['journal_id' => $iJournalId,'is_delete' => 2];
+        $aMaterial = Db::name('ai_journal_editor_material')->field('id,media_id,media_url')->where($aWhere)->find();
+
+        //处理入库数据
+        $sMediaId = empty($aData['media_id']) ? [] : $aData['media_id'];
+        $sMediaUrl = empty($aData['url']) ? [] : $aData['url'];
+        $iTime = empty($aUploadResult['created_at']) ? time() : $aUploadResult['created_at'];
+
+
+        //操作数据组装
+        $aInsert = ['type' => 'image','media_id' => $sMediaId,'journal_id' => $iJournalId,'media_url' => $sMediaUrl];
+
+        Db::startTrans();
+
+        $aInsert['create_time'] =  $iTime;
+        $responseInsert = Db::name('ai_journal_editor_material')->insert($aInsert);
+
+        if(!empty($aMaterial)){
+            $aUpdate['update_time'] =  $iTime;
+            $aUpdate['is_delete'] = 1;
+            $responseUpdate = Db::name('ai_journal_editor_material')->where('id',$aMaterial['id'])->limit(1)->update($aUpdate);
+        }
+        Db::commit();
+        return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]);
+    }
+
     /**
      * CURL 发送请求获取Token
      * @param $appid AppID(小程序ID)
@@ -1814,10 +1902,10 @@ class Aiarticle extends Base
         }
 
         //是否打开评论,0不打开(默认),1打开
-        $need_open_comment = empty($aParam['need_open_comment']) ? 0 : $aParam['need_open_comment'];
+        $need_open_comment = empty($aParam['need_open_comment']) ? 1 : $aParam['need_open_comment'];
 
         //是否粉丝才可评论,0所有人可评论(默认),1粉丝才可评论
-        $only_fans_can_comment = empty($aParam['only_fans_can_comment']) ? 0 : $aParam['only_fans_can_comment'];
+        $only_fans_can_comment = empty($aParam['only_fans_can_comment']) ? 1 : $aParam['only_fans_can_comment'];
 
         //插入文章表
         $aParam = ['media_id' => $response['media_id'],'update_time' => time(),'template_id' => $iTemplateId,'template_content' => $aParam['template_content'],'article_id' => $iArticleId,'article_type' => $article_type,'need_open_comment' => $need_open_comment,'only_fans_can_comment' => $only_fans_can_comment,'template_id' => $iTemplateId,'create_time' => time()];

From 04d0c13ebf4dd3d711c24e7ad7aa5df07e5eca7d Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Thu, 15 May 2025 15:32:41 +0800
Subject: [PATCH 08/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9C=9F=E5=88=8A?=
 =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Journal.php | 40 ++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/application/api/controller/Journal.php b/application/api/controller/Journal.php
index e8858dd..a01b1de 100644
--- a/application/api/controller/Journal.php
+++ b/application/api/controller/Journal.php
@@ -13,7 +13,7 @@ use app\api\controller\User as usercontroller;
 class Journal extends Base {
 
 
-    protected $sJournalUrl = 'http://zmzm.journal.dev.com/';
+    protected $sJournalUrl = 'http://journalapi.tmrjournals.com/public/index.php/';//'http://zmzm.journal.dev.com/';
 
     public function __construct(\think\Request $request = null) {
         parent::__construct($request);
@@ -270,16 +270,35 @@ class Journal extends Base {
         $update['epassword'] = $data['epassword'];
         $update['kfen'] = $data['kfen'];
 
-        //新增字段期刊涵盖主题多个逗号分隔 chengxiaoling 20250507 start
+        //新增字段期刊涵盖主题多个逗号分隔\中文简介\发布作者\编辑二维码 chengxiaoling 20250507 start
         if(isset($data['journal_topic'])){
             if(is_array($data['journal_topic'])){
                 $update['journal_topic'] = implode(',', $data['journal_topic']);
             }else{
                 $update['journal_topic'] =  $data['journal_topic'];
             }
+            $aJournalUpdate['journal_topic'] = $update['journal_topic'];
         }
         if(isset($data['abstract_chinese'])){
             $update['abstract_chinese'] =  $data['abstract_chinese'];
+            $aJournalUpdate['abstract_chinese'] = $update['abstract_chinese'];
+        }
+        if(isset($data['publish_author'])){
+            $update['publish_author'] =  $data['publish_author'];
+            $aJournalUpdate['publish_author'] = $update['publish_author'];
+        }
+        if(isset($data['editor_qrcode'])){
+            $update['editor_qrcode'] =  $data['editor_qrcode'];
+            $aJournalUpdate['editor_qrcode'] = $update['editor_qrcode'];
+        }
+
+        if(!empty($aJournalUpdate)){
+            $aJournalUpdate['issn'] = $journal_info['issn'];
+            $sUrl = $this->sJournalUrl."wechat/Article/updateJournal";
+            $program['issn'] = $journal_info['issn'];
+            $res = object_to_array(json_decode(myPost($sUrl,$aJournalUpdate)));
+            var_dump($res);exit;
+
         }
         //新增字段期刊涵盖主题多个逗号分隔 chengxiaoling 20250507 end
         if(isset($data['fee'])&&$data['fee']!=0){
@@ -346,9 +365,26 @@ class Journal extends Base {
 
             $list[$key]['journal_topic'] = empty($aJournalInfo['journal_topic']) ? '' : $aJournalInfo['journal_topic'];
             $list[$key]['abstract_chinese'] = empty($aJournalInfo['abstract_chinese']) ? '' : $aJournalInfo['abstract_chinese'];
+            $list[$key]['publish_author'] = empty($aJournalInfo['publish_author']) ? '' : $aJournalInfo['publish_author'];
+            $list[$key]['editor_qrcode'] = empty($aJournalInfo['editor_qrcode']) ? '' : $aJournalInfo['editor_qrcode'];
         }
         return $list;
     }
 
+    /**
+     * 上传期刊编辑的二维码
+     */
+    public function uploadEditorQrcode()
+    {
+        $file = request()->file('qrcode_url');
+        if ($file) {
+            $info = $file->move(ROOT_PATH . 'public' . DS . 'journaleditorqrcode');
+            if ($info) {
+                return json(['code' => 0, 'upurl' => str_replace("\\", "/", $info->getSaveName())]);
+            } else {
+                return json(['code' => 1, 'msg' => $file->getError()]);
+            }
+        }
+    }
 
 }

From 2cb3f6f78234698b70fb057e888b5be513d30650 Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Thu, 15 May 2025 15:35:07 +0800
Subject: [PATCH 09/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=97=E7=AC=A6?=
 =?UTF-8?q?=E4=B8=B2=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Base.php | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/application/api/controller/Base.php b/application/api/controller/Base.php
index ef79fa7..390c8a8 100644
--- a/application/api/controller/Base.php
+++ b/application/api/controller/Base.php
@@ -617,10 +617,29 @@ class Base extends Controller
     }
 
 
+    // public function blueIntegerChange($string){
+    //     return preg_replace_callback('/\[(\d+)\]/', function($matches) {
+    //         var_dump($matches);
+    //         return '[' . $matches[1] . ']';
+    //     }, $string);
+    // }
+
     public function blueIntegerChange($string){
-        return preg_replace_callback('/\[(\d+)\]/', function($matches) {
-            return '[' . $matches[1] . ']';
-        }, $string);
+
+        $pattern = '/\[(\d+)-(\d+)\]/';
+        $replacement = '[\1–\2]'; // 使用反向引用 \1 和 \2 来保持数字不变,只替换中间的短横线
+        $result = preg_replace($pattern, $replacement, $string);
+
+        $result = preg_replace_callback('/\[-?\d+(?:,|,\s*\d+)?(?:–|\s*–\s*\d+)?\]<\/blue>/', function($matches) {
+            // if(!empty($matches[1])){
+            //     return '['.$matches[1].']';
+            // }
+            return strip_tags($matches[0]);
+        }, $result);
+        $pattern = '/\[-?\d+(?:,|,\s*\d+)?(?:–|\s*–\s*\d+)?\]/';
+        $replacement = '$0';
+        $result = preg_replace($pattern, $replacement, $result);
+        return $result;
     }
 
     public function getBoardsForJournal($journal_id, $aar = false)

From 7dd223b497005a4dcffbafda1698abbb2731037b Mon Sep 17 00:00:00 2001
From: chengxl 
Date: Thu, 15 May 2025 17:17:27 +0800
Subject: [PATCH 10/10] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/api/controller/Aiarticle.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php
index ba6dabe..708560e 100644
--- a/application/api/controller/Aiarticle.php
+++ b/application/api/controller/Aiarticle.php
@@ -745,7 +745,7 @@ class Aiarticle extends Base
                     //更新作者名字
                     if(isset($aUser['author_name'])){
                         $aUpdate = ['localname' => $aUser['author_name']];
-                        Db::name('user')->where('user_id',$value['user_id'])->limit(1)->update($aUpdate);
+                        Db::name('user')->where('user_id',$value['user_id'])->update($aUpdate);
                     }
                     //更新作者简介和单位
                     $aUpdateReviewer = [];