diff --git a/application/api/controller/Aiarticle.php b/application/api/controller/Aiarticle.php index 708560e..cf6e1bc 100644 --- a/application/api/controller/Aiarticle.php +++ b/application/api/controller/Aiarticle.php @@ -4,6 +4,8 @@ use app\api\controller\Base; use think\Controller; use think\Db; use app\common\QrCodeImage; +use app\common\Wechat; +use app\common\Material; use think\Cache; /** @@ -13,37 +15,36 @@ use think\Cache; */ class Aiarticle extends Base { - - 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; + + /**OPENAI相关配置----------start**/ + //OPENAI接口地址 + protected $sUrl = 'https://api.openai.com/v1/chat/completions'; + //OPENAI接口key + protected $sApiKey = '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'; + protected $proxy = ''; + //接口返回对象 + protected $sResponesData; + //接口返回错误信息 + protected $sError; + //接口超时请求 + protected $timeout = 60; + /**OPENAI相关配置----------end**/ + + //数据表必填字段[ai_article] 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'; // 'http://zmzm.journal.dev.com'; // '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 => ' - **核心要求** - "将以下内容翻译为中文,仅返回翻译结果,不要解释:\n {#content#}" - ', - + 1 => '"将以下内容翻译为中文,仅返回翻译结果,不要解释:\n {#content#}"', 2 => ' **核心要求** - 1️ ​内容涵盖哪些学科及方法请罗列 + 1️ 内容涵盖哪些学科及方法请罗列 2 结构化摘要生成【四要素模版】 3 研究背景提炼【三段式结构】 发病率+当前治疗缺口(如5年OS<20%) @@ -53,7 +54,6 @@ class Aiarticle extends Base 与TOP3高被引文献的对比(用"与A研究的X结论不同..."句式) 机制解释的3级证据链(如:基因敲除→通路抑制→表型逆转) 临床转化的可行性路径(如:基于RECIST标准的ORR提升)研究局限性(分方法学/样本量/随访维度) 5 针对稿件内容进行展望撰写 现有方法的可扩展性(如空间组学升级计划) - 6 按点总结归纳研究结果并做简要阐述【3点以上】 7 总结归纳亮点【3点以上】 8 禁用清单 @@ -67,26 +67,13 @@ class Aiarticle extends Base {#title_chinese#} 10 请将稿件内容翻译成中文 {#content#} - **稿件关键信息** - 稿件简介:{#abstract#} - 稿件内容:{#content#} **输出格式** - 中文格式[英文简写忽略首字母大写] 格式内容 - ```json - { - "title_chinese": "", - "content": "", - "covered": "【总字数<=100】", - "digest": "【总字数<=500】", - "research_background": "", - "research_result": "", - "highlights": "", - "prospect": "", - "discussion": "" - }' + ```json{ "title_chinese": "", "content": "", "covered": "【总字数<=100】", "digest": "【总字数<=500】", "research_background": "", "research_result": "", "highlights": "", "prospect": "", "discussion": ""}' ]; //文章图片icon地址 @@ -95,17 +82,14 @@ class Aiarticle extends Base protected $sJournalIcon = '/public/journalicon/'; //期刊编辑二维码地址 protected $sJournalEditorQrcode = '/public/journaleditorqrcode/'; - //"highlights": { - // "theory_innovation": "【中西医理论结合点】", - // "methodology": "【关键技术+量化指标】", - // "data_strength": "【数据规模/古籍分析深度】" - // } + //作者头像地址 + protected $sUserIcon = '/public/usericon/'; + //默认头像 + protected $sDefaultUserIcon = '/static/img/userImg.f3d9bc3b.jpg'; public function __construct(\think\Request $request = null) { - // 从配置读取敏感信息(非硬编码) - $this->sApiKey = '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'; + $this->proxy = ''; - $this->sUrl = 'https://api.openai.com/v1/chat/completions'; parent::__construct($request); } @@ -125,34 +109,34 @@ class Aiarticle extends Base 'temperature' => 0.7 ]; - $this->curl = curl_init(); + $oCurl = curl_init(); // 通用配置 - curl_setopt($this->curl, CURLOPT_URL, $sUrl); + curl_setopt($oCurl, CURLOPT_URL, $sUrl); // 设置头信息 - curl_setopt($this->curl, CURLOPT_HTTPHEADER, [ + curl_setopt($oCurl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: Bearer ' . $this->sApiKey ]); - curl_setopt($this->curl, CURLOPT_PROXY,$this->proxy); - curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,true); - curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST,2); - curl_setopt($this->curl, CURLOPT_POST, true); //设置为POST方式 - curl_setopt($this->curl, CURLOPT_POSTFIELDS,json_encode($data)); - curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE) ; // 获取数据返回 - // curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($oCurl, CURLOPT_PROXY,$this->proxy); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER,true); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST,2); + curl_setopt($oCurl, CURLOPT_POST, true); //设置为POST方式 + curl_setopt($oCurl, CURLOPT_POSTFIELDS,json_encode($data)); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, TRUE) ; // 获取数据返回 + // curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->timeout); - $result = curl_exec($this->curl); + $result = curl_exec($oCurl); //请求失败 - if (curl_errno($this->curl)){ - $this->sError = curl_errno($this->curl); - curl_close($this->curl); + if (curl_errno($oCurl)){ + $this->sError = curl_errno($oCurl); + curl_close($oCurl); return FALSE; } $this->sResponesData = json_decode($result); - curl_close($this->curl); + curl_close($oCurl); return TRUE; } /** @@ -212,7 +196,6 @@ class Aiarticle extends Base */ public function create(){ - //获取参数 $aParam = $this->request->post(); $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id']; @@ -258,10 +241,14 @@ class Aiarticle extends Base //请求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]]); } + /** + * @title 请求OPENAI生成内容 + * @param article_id 文章ID + * @param model 接口模型 + * @param stream 是否流式输出 true是false否 + */ public function createForOpenAi($aArticleContent = [],$aAiArticle = []){ if(empty($aArticleContent)){ @@ -309,19 +296,6 @@ class Aiarticle extends Base //通讯作者 $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); @@ -355,71 +329,6 @@ class Aiarticle extends Base $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; - // } /** * 处理文章引用 @@ -441,6 +350,94 @@ class Aiarticle extends Base return $sCite; } + + /** + * 接口请求获取Journal数据库文章信息 + * @param article_id 文章ID + */ + + public function getArticle($iArticleId = ''){ + $aParam = $this->request->post(); + $iArticleId = empty($iArticleId) ? $aParam['article_id'] : $iArticleId; + + //接口请求地址 + $sUrl = $this->sJournalUrl.'/wechat/Article/getArticle'; + + //请求接口 + $aParam['article_id'] = $iArticleId; + $aResult = object_to_array(json_decode(myPost($sUrl, $aParam))); + $iStatus = empty($aResult['status']) ? 0 : $aResult['status']; + + if($iStatus != 1){ + return json_encode(['status' => 0,'msg' => $aResult['msg'] ?? '操作异常']); + } + + $aContent = empty($aResult['data']) ? [] : $aResult['data']; + + if(!empty($aContent['journal'])){ + $aJournal = $aContent['journal']; + //查询期刊主题 + $aWhere['issn'] = $aJournal['issn']; + $aJournalInfo = Db::name('journal')->field('journal_topic')->where($aWhere)->find(); + $aContent['journal']+=$aJournalInfo; + } + return json_encode(['status' => 1,'msg' => 'success','data' => $aContent]); + } + + /** + * 获取Ai生成文章信息 + * @param article_id 文章ID + */ + public function getAiArticle($iArticleId = 0,$iSelectAuthor = 2,$iAiArticleId = 0){ + + $aParam = $this->request->post(); + + //文章ID + $iArticleId = empty($iArticleId) ? '' : $iArticleId; + $iArticleIdParam = empty($aParam['article_id']) ? '' : $aParam['article_id']; + $iArticleId = empty($iArticleId) ? $iArticleIdParam : $iArticleId; + + 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')->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 = []; + if($iSelectAuthor == 2){ + $aResult = json_decode($this->getArticle($iArticleId),true); + //获取数据 + $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']) ? $this->sDefaultUserIcon : $this->sUserIcon.$value['icon']; + } + } + } + } + + //查询是否上传到微信草稿箱 + 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]]); + } /** * @title 处理作者数据 * @param article_id 文章ID @@ -493,105 +490,6 @@ class Aiarticle extends Base } return $aInfo; } - - - /** - * 接口请求获取Journal数据库文章信息 - * @param article_id 文章ID - */ - - public function getArticle($iArticleId = ''){ - $aParam = $this->request->post(); - $iArticleId = empty($iArticleId) ? $aParam['article_id'] : $iArticleId; - - //接口请求地址 - $sUrl = $this->sJournalUrl.'/wechat/Article/getArticle'; - - //请求接口 - $aParam['article_id'] = $iArticleId; - $aResult = object_to_array(json_decode(myPost($sUrl, $aParam))); - $iStatus = empty($aResult['status']) ? 0 : $aResult['status']; - - if($iStatus != 1){ - return json_encode(['status' => 0,'msg' => $aResult['msg'] ?? '操作异常']); - } - - $aContent = empty($aResult['data']) ? [] : $aResult['data']; - - if(!empty($aContent['journal'])){ - $aJournal = $aContent['journal']; - //查询期刊主题 - $aWhere['issn'] = $aJournal['issn']; - $aJournalInfo = Db::name('journal')->field('journal_topic')->where($aWhere)->find(); - $aContent['journal']+=$aJournalInfo; - } - return json_encode(['status' => 1,'msg' => 'success','data' => $aContent]); - } - - /** - * 获取Ai生成文章信息 - * @param article_id 文章ID - */ - public function getAiArticle($iArticleId = 0,$iSelectAuthor = 2,$iAiArticleId = 0){ - - $aParam = $this->request->post(); - - //文章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 = ['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 = []; - 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']; - } - } - } - - } - } - - //查询是否上传到微信草稿箱 - 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]]); - } /** * 基础HTML过滤 * @param string $html @@ -611,48 +509,6 @@ class Aiarticle extends Base } - /** - * @title AI生成稿件内容入库 - * @param article_id 文章ID - * @param content 内容 - */ - protected function addAiArticle($aParam = array(),$aAuthor = []){ - - - //返回数组 - $aResult = ['status' => 1,'msg' => 'AI article added successfully','data' => []]; - //必填参数验证 - $aFields = $this->aAiFileds; - $bStatus = true; - $sFiled = ''; - $aInsertParam = []; - foreach($aFields as $val){ - if(empty($aParam[$val])){ - $bStatus = false; - $sFiled = $val; - break; - } - if($val == 'article_id'){ - $aInsertParam[$val] = $aParam[$val]; - continue; - } - $aInsertParam[$val] = empty($aParam[$val]) ? '' : addslashes(strip_tags($aParam[$val])); - } - if($bStatus == false){ - return json_encode(['status' => 2,'msg' => $sFiled.'cannot be empty']); - } - //执行入库 - $aInsertParam['create_time'] = time(); - - //作者判断空值 - $aInsertParam['author'] = empty($aInsertParam['author']) ? 'TMR编辑部' : $aInsertParam['author']; - 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]); - return json_encode($aResult); - } - /** * @title AI生成稿件内容入库 * @param article_id 文章ID @@ -705,7 +561,6 @@ 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){ @@ -785,15 +640,18 @@ class Aiarticle extends Base * @param template_id 模版ID * @param $iIsSync 是否同步素材到微信 1是2否 */ - public function getTemplateContent($iArticleId = '',$iTemplateId = '',$iIsSync = 2){ + public function getTemplateContent($aParam = []){ //获取参数 - $aParam = $this->request->post(); + $aParam = empty($aParam) ? $this->request->post() : $aParam; //文章ID - $iArticleId = empty($iArticleId) ? $aParam['article_id'] ?? '' : $iArticleId; + $iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id']; //模版ID - $iTemplateId = empty($iTemplateId) ? $aParam['template_id'] ?? '' : $iTemplateId; + $iTemplateId = empty($aParam['template_id']) ? '' : $aParam['template_id']; + //模版ID + $iIsSync = empty($aParam['is_sync']) ? 2 : $aParam['is_sync']; + //必填参数验证 if(empty($iArticleId)){ return json_encode(['status' => 2, 'msg' => 'Please select an article']); @@ -842,13 +700,14 @@ class Aiarticle extends Base $sEditorQrcode = empty($aJournal['editor_qrcode']) ? '' : $aJournal['editor_qrcode']; $sEditorQrcode = trim($this->sSubmissionUrl,'/').$this->sJournalEditorQrcode.$sEditorQrcode; - //获取期刊图片二维码 - $aJournalQrCode = $this->createJournalQrCode($aJournal); + //获取期刊二维码 + $oMaterial = new Material; + $aJournalQrCode = $oMaterial->createJournalQrCode($aJournal); $sJournalCode = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url']; $aAiArticle['journal_qrcode'] = $sJournalCode; - //文章图片二维码 - $aArticleQrCode = $this->createArticleQrCode($aArticle); + //文章二维码 + $aArticleQrCode = $oMaterial->createArticleQrCode($aArticle); $sArticleCode = empty($aArticleQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aArticleQrCode['qrcode_url']; $aAiArticle['article_qrcode'] = $sArticleCode; @@ -859,26 +718,28 @@ class Aiarticle extends Base if($iIsSync == 1){ //文章图片上传 - $aUpload = ['article_id' => $iArticleId,'icon' => $sArticleIcon]; - $aArticleResult = json_decode($this->_addArticleMaterial($aUpload),true); + $sWechatAppId = empty($aParam['wechat_app_id']) ? '' : $aParam['wechat_app_id']; + $sWechatAppSecret = empty($aParam['wechat_app_secret']) ? '' : $aParam['wechat_app_secret']; + $aUpload = ['article_id' => $iArticleId,'icon' => $sArticleIcon,'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret]; + $aArticleResult = json_decode($oMaterial->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); + $aUpload = ['journal_id' => $aAiArticle['journal_id'],'icon' => $sJournalIcon,'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret]; + $aJournalResult = json_decode($oMaterial->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); + $aUpload = ['journal_id' => $aAiArticle['journal_id'],'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret]; + $aJournalQrCodeResult = json_decode($oMaterial->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); + $aUpload = ['article_id' => $iArticleId,'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret]; + $aArticleQrCodeResult = json_decode($oMaterial->updateArticleQrcode($aUpload),true); $aArticleQrCodeData = empty($aArticleQrCodeResult['data']) ? [] : $aArticleQrCodeResult['data']; $aAiArticle['article_qrcode'] = empty($aArticleQrCodeData['media_url']) ? $sArticleIcon : $aArticleQrCodeData['media_url']; @@ -890,16 +751,16 @@ class Aiarticle extends Base continue; } //文章二维码图片上传 - $aUpload = ['email' => $value['email'],'icon' => $value['icon'],'user_id' => $value['user_id']]; - $aAuthorResult = json_decode($this->_updateArticleAuthor($aUpload),true); + $aUpload = ['email' => $value['email'],'icon' => $value['icon'],'user_id' => $value['user_id'],'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret]; + $aAuthorResult = json_decode($oMaterial->updateArticleAuthor($aUpload),true); $aAuthorData = empty($aAuthorResult['data']) ? [] : $aAuthorResult['data']; - $aAiAuthor[$key]['icon'] = empty($aAuthorData['media_url']) ? $value['icon'] : $aAuthorData['media_url']; + $aAuthor[$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); + $aUpload = ['editor_qrcode' => $aJournal['editor_qrcode']??'','journal_id' => $aAiArticle['journal_id'],'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret]; + $aJournalEditorQrCodeResult = json_decode($oMaterial->updateJournalEditorQrcode($aUpload),true); $aJournalEditorQrCodeData = empty($aJournalEditorQrCodeResult['data']) ? [] : $aJournalEditorQrCodeResult['data']; $aAiArticle['editor_qrcode'] = empty($aJournalEditorQrCodeData['media_url']) ? $sEditorQrcode : $aJournalEditorQrCodeData['media_url']; }else{ @@ -911,6 +772,11 @@ class Aiarticle extends Base //期刊编辑二维码图片地址数据 $aAiArticle['editor_qrcode'] = $sEditorQrcode; + //作者信息处理 + if(!empty($aAuthor)){ + $aAuthor = $this->_dealAuthor($aAuthor); + } + } //期刊访问地址 $journal_usx = trim($this->sJournalUsx,'/').'/'; @@ -926,18 +792,21 @@ class Aiarticle extends Base } $aAiArticle += $aJournal; + //获取模版信息 - $sTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'.html'; + $sTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId; + + //index模版目录 + $sTemplateIndexPath = $sTemplatePath.'/index.html'; // 验证文件有效性 - if (!file_exists($sTemplatePath)) { + if (!file_exists($sTemplateIndexPath)) { return json_encode(['status' => 4, 'msg' => 'Article template does not exist']); } - if (!is_readable($sTemplatePath)) { + if (!is_readable($sTemplateIndexPath)) { return json_encode(['status' => 5, 'msg' => 'The article template is unreadable']); } //获取模版内容 - $sTemplate = file_get_contents($sTemplatePath); - + $sTemplate = file_get_contents($sTemplateIndexPath); //数据处理 $aSearch = []; foreach ($aAiArticle as $key => $value) { @@ -946,37 +815,38 @@ class Aiarticle extends Base } $aSearch['{###'.$key.'###}'] = empty($value) ? '' : htmlspecialchars(strip_tags($value)); } + //处理通讯作者信息数据 $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']; - + $aAuthorInfo = empty($aAuthorInfo['data']) ? [] : $aAuthorInfo['data']; + $aSearch['{###author_summary###}'] = empty($aAuthorInfo['author_info']) ? '' : $aAuthorInfo['author_info']; + //处理往期推荐数据 $aPreviousRecommend = json_decode($this->dealTemplatePreviousRecommend($aArticle,$iTemplateId),true); - if(empty($aPreviousRecommend['data'])){ - $aSearch['{###previous_recommend_summary###}'] = ''; - }else{ - $sSummaryTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_previous_recommend_summary.html'; - $sSummaryTemplate = file_get_contents($sSummaryTemplatePath); - $aSearchInfo['{###previous_recommend###}'] = empty($aPreviousRecommend['data']) ? ' ' : implode("\n", $aPreviousRecommend['data']); - $sSummaryTemplate = str_replace(array_keys($aSearchInfo), array_values($aSearchInfo), $sSummaryTemplate); - $aSearch['{###previous_recommend_summary###}'] = $sSummaryTemplate; - } + $aSearch['{###previous_recommend_summary###}'] = empty($aPreviousRecommend['data']) ? '' : $aPreviousRecommend['data']; - //处理期刊主题数据 $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{ + $aSearch['{###topic_name_summary###}'] = empty($aTopic['data']) ? '' : $aTopic['data']; + + //公众号名字处理 + $aSearch['{###wechat_name###}'] = empty($aSearch['{###wechat_name###}']) ? '“'.$aSearch['{###journal_title###}'].'“' : '“'.$aSearch['{###wechat_name###}'].'“'; - $sSummaryTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_topic_summary.html'; - $sSummaryTemplate = file_get_contents($sSummaryTemplatePath); - $aSearchInfo['{###topic_name###}'] = empty($aTopic['data']) ? ' ' : implode("\n", $aTopic['data']); - $sSummaryTemplate = str_replace(array_keys($aSearchInfo), array_values($aSearchInfo), $sSummaryTemplate); - $aSearch['{###topic_name_summary###}'] = $sSummaryTemplate; + //是否显示文章来源 + $aSearch['{###article_from###}'] = ''; + if(!empty($aParam['wechat_id']) && $aParam['wechat_id'] != $aJournal['issn']){ + $sTemplateFromPath = $sTemplatePath.'/article_from.html'; + if (file_exists($sTemplateFromPath) && is_readable($sTemplateFromPath)) { + $sTemplateFromPath = file_get_contents($sTemplateFromPath); + $aSearch['{###article_from###}'] = str_replace('{###journal_title###}', $aJournal['journal_title'], $sTemplateFromPath); + } + + //获取推送公众号名称 + $aJournalInfo = Db::name('journal')->field('title,wechat_name')->where('issn',$aParam['wechat_id'])->find(); + $sWechatName = empty($aJournalInfo['wechat_name']) ? '' : '“'.$aJournalInfo['wechat_name'].'“'; + $sTitle = empty($aJournalInfo['title']) ? '' : '“'.$aJournalInfo['title'].'“'; + $aSearch['{###wechat_name###}'] = empty($sWechatName) ? $sTitle : $sWechatName; } //模版替换变量 @@ -987,6 +857,7 @@ 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]]); @@ -1004,10 +875,9 @@ class Aiarticle extends Base } //处理作者 - $aAuthor = $this->_dealAuthor($aAuthor); - + // $aAuthor = $this->_dealAuthor($aAuthor); //获取通讯作者模版 - $sAuthorTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_author.html'; + $sAuthorTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId.'/author.html'; if (!file_exists($sAuthorTemplatePath)) { return json_encode(['status' => 3, 'msg' => 'Corresponding author template does not exist','data' => '']); } @@ -1016,7 +886,6 @@ class Aiarticle extends Base } $sAuthorTemplate = file_get_contents($sAuthorTemplatePath); - //处理模版变量 $aAuthorSerachInfo = []; $sAuthorInfo = ''; @@ -1032,8 +901,9 @@ class Aiarticle extends Base //请求AI翻译 $aInfo = empty($aContent[$value['email']]) ? [] : $aContent[$value['email']]; - $aAuthorSerach = []; + //替换模版 + $aAuthorSerach = []; //所属单位处理 $value['company'] = empty($aInfo['company']) ? $value['company'] : $aInfo['company']; if(!empty($value['company'])){ @@ -1041,34 +911,58 @@ class Aiarticle extends Base $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']; + //职称处理 + $value['technical'] = empty($aInfo['technical']) ? $value['technical'] : $aInfo['technical']; + if(empty($value['introduction'])){//简介为空不处理 + $sTechnical = empty($value['technical']) ? '老师' : $value['technical']; + $sAuthorInfo .= $value['company'].$value['author_name'].$sTechnical.','; + continue; + } + //缓缓处理进行模版替换 foreach ($value as $k => $val) { - if($k == 'icon'){ - $aAuthorSerach['{###icon_path###}'] = empty($val) ? $aLogo['url'] : trim($this->sSubmissionUrl,'/').'/public/usericon/'.$val; + if($k == 'icon'){//头像拼接处理 + $sIconInfo = empty($val) ? $aLogo['url'] : $val; + $aParsedUrl = parse_url($sIconInfo); + if(empty($aParsedUrl['scheme'])){ + $aAuthorSerach['{###icon_path###}'] = trim($this->sSubmissionUrl,'/').$this->sUserIcon.$val; + }else{ + $aAuthorSerach['{###icon_path###}'] = $val; + } $aAuthorSerach['{###icon_path###}'] = trim($aAuthorSerach['{###icon_path###}'],'/'); }else{ $aAuthorSerach['{###'.$k.'###}'] = trim($val,'/'); } } $aAuthorSerachInfo[] = str_replace(array_keys($aAuthorSerach), array_values($aAuthorSerach), $sAuthorTemplate); - $sTechnical = empty($value['technical']) ? '老师' : $value['technical']; - $sAuthorInfo .= $value['company'].$value['author_name'].$sTechnical.','; } + + //通讯作者列表 + //获取通讯作者汇总模版 + $sAuthorTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId.'/author_summary.html'; + if (!file_exists($sAuthorTemplatePath)) { + return json_encode(['status' => 3, 'msg' => 'Corresponding author template does not exist','data' => '']); + } + if (!is_readable($sAuthorTemplatePath)) { + return json_encode(['status' => 4, 'msg' => 'The corresponding author template is unreadable','data' => '']); + } + $sAuthorTemplate = file_get_contents($sAuthorTemplatePath); + //数据处理内容替换 + $sInfo = empty($aAuthorSerachInfo) ? '' : implode("\n", $aAuthorSerachInfo); + $sAuthorTemplate = empty($sInfo) ? '' : str_replace('{###author_info###}', $sInfo, $sAuthorTemplate); + + //通讯作者字符串处理 $sAuthorInfo = trim($sAuthorInfo,','); - return json_encode(['status' => 1,'msg' => 'success','data' => ['author_info' => $aAuthorSerachInfo,'author' => trim($sAuthorInfo,';')]]); + return json_encode(['status' => 1,'msg' => 'success','data' => ['author_info' => $sAuthorTemplate,'author' => trim($sAuthorInfo,';')]]); } /** - * 处理模版主题 + * 处理期刊主题模版 * @param article_id 文章ID */ private function dealTemplateTopic($sTopic = '',$iTemplateId = 0){ - if(empty($iTemplateId)){ return json_encode(['status' => 2,'template does not exist']); } @@ -1077,7 +971,7 @@ class Aiarticle extends Base } //获取主题模版 - $sTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_topic.html'; + $sTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId.'/topic.html'; if (!file_exists($sTemplatePath)) { return json_encode(['status' => 4, 'msg' => 'Corresponding author template does not exist']); } @@ -1092,11 +986,26 @@ class Aiarticle extends Base $aSearchInfo = []; if(!empty($aTopic)){ foreach ($aTopic as $key => $value) { - $aSerach['{###topic_name###}'] = trim(trim(trim($value),'【'),'】'); + $aSerach['{###topic_name###}'] = empty($value) ? '' : strip_tags($value); $aSearchInfo[] = str_replace(array_keys($aSerach), array_values($aSerach), $sTemplate); } } - return json_encode(['status' => 1,'msg' => 'success','data' => $aSearchInfo]); + + //获取期刊主题汇总模版 + $sTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId.'/topic_summary.html'; + if (!file_exists($sTemplatePath)) { + return json_encode(['status' => 4, 'msg' => 'Corresponding author template does not exist']); + } + if (!is_readable($sTemplatePath)) { + return json_encode(['status' => 5, 'msg' => 'The corresponding author template is unreadable']); + } + $sTemplate = file_get_contents($sTemplatePath); + + //模版数据替换 + $sTopicName = empty($aSearchInfo) ? '' : implode("\n", $aSearchInfo); + $sTemplate = empty($sTopicName) ? '' : str_replace('{###topic_name###}', $sTopicName, $sTemplate); + + return json_encode(['status' => 1,'msg' => 'success','data' => $sTemplate]); } /** @@ -1109,7 +1018,7 @@ class Aiarticle extends Base return json_encode(['status' => 2,'template does not exist']); } //获取往期推荐模版 - $sTemplatePath = ROOT_PATH."public/wechatTemplate/".$iTemplateId.'_previous_recommend.html'; + $sTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId.'/previous_recommend.html'; if (!file_exists($sTemplatePath)) { return json_encode(['status' => 3, 'msg' => 'Corresponding author template does not exist']); } @@ -1133,188 +1042,39 @@ class Aiarticle extends Base //查询是否推送到微信公众号并且已发布 $aWhere['template_id'] = $iTemplateId;//,'is_publish' => 1 - $aWechatArticle = Db::name('ai_wechat_article')->where($aWhere)->column('article_id'); - if(!empty($aWechatArticle)){ + $aWechatArticle = Db::name('ai_wechat_article')->field('article_id,media_url')->where($aWhere)->select(); + 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']]) ? '' : 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); + $aWhere = ['article_id' => ['in',$aId],'is_delete' => 2]; + $aArticleMaterial = Db::name('ai_article_material')->where($aWhere)->column('article_id,media_url'); + foreach ($aWechatArticle as $key => $value) { + $aSearch['{###wechat_url###}'] = $value['media_url']; + $sIcon = empty($aArticleMaterial[$value['article_id']]) ? '' : $aArticleMaterial[$value['article_id']]; + $aSearch['{###wechat_media_url###}'] = $sIcon; + $aSearchInfo[] = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplate); } } - return json_encode(['status' => 1,'msg' => 'success','data' => $aSearchInfo]); + + //获取往期推荐汇总模版 + $sTemplatePath = ROOT_PATH."public/wechatTemplate/template_".$iTemplateId.'/previous_recommend_summary.html'; + if (!file_exists($sTemplatePath)) { + return json_encode(['status' => 3, 'msg' => 'Corresponding author template does not exist']); + } + if (!is_readable($sTemplatePath)) { + return json_encode(['status' => 4, 'msg' => 'The corresponding author template is unreadable']); + } + $sTemplate = file_get_contents($sTemplatePath); + + //数据处理内容替换 + $sInfo = empty($aSearchInfo) ? '' : implode("\n", $aSearchInfo); + $sTemplate = empty($sInfo) ? '' : str_replace('{###previous_recommend###}', $sInfo, $sTemplate); + + return json_encode(['status' => 1,'msg' => 'success','data' => $sTemplate]); } - /** - * @title 文章AI生成稿件内容查询 - * @param aJournal 期刊信息 - */ - private function createJournalQrCode($aJournal = []){ - $iJournalId = empty($aJournal['journal_id']) ? 0 : $aJournal['journal_id']; - //判断期刊二维码是否生成 - $aWhere = ['journal_id' => $iJournalId]; - $aQrCode = Db::name('ai_journal_qrcode')->where($aWhere)->find(); - if(!empty($aQrCode)){ - return $aQrCode; - } - //创建二维码 - //生成图片地址 - $sImagePath = 'journal/'.$iJournalId.'.jpg'; - $sQrCodeUrl = ROOT_PATH.'public/qrcode/'.$sImagePath; - // 验证图片是否存在 - if (file_exists($sQrCodeUrl)) { - return ['qrcode_url' => $sImagePath]; - } - - //地址 - $journal_usx = empty($aJournal['journal_usx']) ? '' : $aJournal['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 = 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); - } - $sImg = QrCodeImage::withLogo($sUrl,$aImageInfo['data'],500,100, $sQrCodeUrl); - } - - //插入期刊二维码表 - $aParam = ['journal_id' => $iJournalId,'qrcode_url' => $sImagePath,'create_time' => time()]; - $result = Db::name('ai_journal_qrcode')->insertGetId($aParam); - return $aParam; - } - - /** - * @title 文章AI生成稿件内容查询 - * @param aArticle 文章信息 - */ - private function createArticleQrCode($aArticle = []){ - - $iArticleId = empty($aArticle['article_id']) ? 0 : $aArticle['article_id']; - //判断期刊二维码是否生成 - $aWhere = ['article_id' => $iArticleId]; - $aQrCode = Db::name('ai_article_qrcode')->where($aWhere)->find(); - if(!empty($aQrCode)){ - return $aQrCode; - } - - //创建二维码 - //生成图片地址 - $sImagePath = 'article/'.$iArticleId.'.jpg'; - $sQrCodeUrl = ROOT_PATH.'public/qrcode/'.$sImagePath; - // 验证图片是否存在 - if (file_exists($sQrCodeUrl)) { - return ['qrcode_url' => $sImagePath]; - } - //地址 - $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 = 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); - } - $sImg = QrCodeImage::withLogo($sUrl,$aImageInfo['data'],500,100, $sQrCodeUrl); - } - - //插入期刊二维码表 - $aParam = ['article_id' => $iArticleId,'qrcode_url' => $sImagePath,'create_time' => time()]; - $result = Db::name('ai_article_qrcode')->insertGetId($aParam); - return $aParam; - } - - /** - * @title 请求OPENAI翻译内容 - * @param article_id 文章ID - */ - public function translate($param = [],$url=''){ - - if (!is_array($param)) { - - throw new Exception("参数必须为array"); - } - - $httph = curl_init($url); - - // curl_setopt($httph, CURLOPT_SSL_VERIFYPEER, 0); - // curl_setopt($httph, CURLOPT_SSL_VERIFYHOST, 1); - - curl_setopt($httph, CURLOPT_RETURNTRANSFER, 1); - - curl_setopt($httph, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); - - curl_setopt($httph, CURLOPT_POST, 1); //设置为POST方式 - - curl_setopt($httph, CURLOPT_POSTFIELDS, $param); - - curl_setopt($httph, CURLOPT_SSL_VERIFYPEER, false); - - // curl_setopt($httph, CURLOPT_RETURNTRANSFER,0); - // curl_setopt($httph, CURLOPT_HEADER,1); - - $rst = curl_exec($httph); - - curl_close($httph); - - return json_decode($rst,true); - } - - /** - * @title curl 请求获取图片保存到本地 - * @param sPath 图片链接地址 - */ - public function getImage($sPath = '',$iId = 0,$sType = 'journal'){ - //判断参数 - if(empty($sPath)){ - return json_encode(['status' => 2,'msg' => 'url is empty','data' => '']); - } - - //获取图片名称 - $aImageInfo = pathinfo($sPath); - - //图片后缀名 - $sExtension = empty($aImageInfo['extension']) ? 'jpg' : $aImageInfo['extension']; - - //图片地址 - $sImagePath = $sType.'/imgae_'.$iId.'.'.$sExtension; - $sImagePath = ROOT_PATH.'public/qrcode/'.$sImagePath; - if (file_exists($sImagePath)) { - return json_encode(['status' => 1,'msg' => 'success','data' => $sImagePath]); - } - //curl 请求 - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL,$sPath); // 设置请求URL - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 设置返回数据而不是直接输出 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用SSL验证 - $response = curl_exec($ch); - if (curl_errno($ch)) { - return json_encode(['status' => 3,'msg' => 'Error:' . curl_error($ch),'data' => $sImagePath]); - } - //保存图片 - file_put_contents($sImagePath, $response); - curl_close($ch); - return json_encode(['status' => 1,'msg' => 'success','data' => $sImagePath]); - - } /** * 文章同步到微信公众号草稿箱 @@ -1326,9 +1086,11 @@ class Aiarticle extends Base $aParam = $this->request->post(); //文章ID - $iArticleId = empty($iArticleId) ? $aParam['article_id'] ?? '' : $iArticleId; - //模版ID - $iTemplateId = empty($iTemplateId) ? $aParam['template_id'] ?? '' : $iTemplateId; + $iArticleId = empty($aParam['article_id'] ) ? '' : $aParam['article_id']; + //模版ID + $iTemplateId = empty($aParam['template_id']) ? '' : $aParam['template_id']; + //推送公众号Id + $sWechatId = empty($aParam['wechat_id']) ? '' : $aParam['wechat_id']; //必填参数验证 if(empty($iArticleId)){ @@ -1337,522 +1099,9 @@ class Aiarticle extends Base 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]); + if(empty($sWechatId)){ + return json_encode(['status' => 2, 'msg' => 'Please select the WeChat official account to push']); } - $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; - } - - /** - * 添加文章素材 - * @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]); - } - /** - * 添加期刊素材 - */ - 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']); - } - - //处理图片地址 - $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']); - } - - //查询是否添加素材 - $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,'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]); - } - /** - * 更新期刊二维码关联微信公众号素材 - */ - 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_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.'/public/usericon/'.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']; - $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' => $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) - * @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]); - } - - /** - * 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]; - } - - /** - * 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($iTemplateId) || 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(); @@ -1862,6 +1111,7 @@ class Aiarticle extends Base //查询该模版是否推送到微信公众号 $aWhere['template_id'] = $iTemplateId; + $aWhere['wechat_id'] = $sWechatId; $aWechatArticle = Db::name('ai_wechat_article')->where($aWhere)->find(); if(!empty($aWechatArticle)){ return json_encode(['status' => 4, 'msg' => 'Already uploaded to draft box']); @@ -1871,294 +1121,34 @@ class Aiarticle extends Base 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 json_encode($aCurlResult); - } - $response = empty($aCurlResult['data']) ? [] : $aCurlResult['data']; - //判断是否推送成功 - if(empty($response['media_id'])){ - return json_encode(['status' => 5,'msg' => "Unable to obtain the uploaded draft"]); + $aParam += $aAiArticle; + + //查询期刊微信公众号配置 + $aJournalInfo = Db::name('journal')->field('wechat_app_id,wechat_app_secret')->where('issn',$sWechatId)->find(); + if(empty($aJournalInfo['wechat_app_id']) || empty($aJournalInfo['wechat_app_secret'])){ + return json_encode(['status' => 3, 'msg' => 'WeChat official account interface docking account is not configured, please confirm']); + } + + //获取模版生成内容 + $aTemplateParam = ['article_id' => $iArticleId,'template_id' => $iTemplateId,'is_sync' => 1,'wechat_id' => $sWechatId]; + $aTemplateParam += $aJournalInfo; + $aResult = json_decode($this->getTemplateContent($aTemplateParam),true); + $sMsg = empty($aResult['msg']) ? 'The content is empty' : $aResult['msg']; + $aData = empty($aResult['data']) ? [] : $aResult['data']; + if(empty($aData['template'])){ + return json_encode(['status' => 4, 'msg' => $sMsg]); } - //判断文章类型 - $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']) ? 1 : $aParam['need_open_comment']; - - //是否粉丝才可评论,0所有人可评论(默认),1粉丝才可评论 - $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()]; - $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); + //请求微信公众号接口推送 + $aParam['content'] = $aData['template']; + $aParam['template_id'] = $iTemplateId; + $aParam += $aJournalInfo; + $oWechat = new Wechat; + $aResult = $oWechat->addDraft($aParam); + return $aResult; } - /** - * CURL 获取草稿箱的文章 - * @param $sToken Token - * @param media_id string 微信公众号media_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_wechat_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' => 'Failed to obtain 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 $sToken Token - * @param article_id int 文章ID - */ - public function publishDraft($sMediaId = ''){ - //返回结果数组 - $aResult = ['status' => 1,'msg' => 'Draft box article successfully published','data' => []]; - - //获取参数 - $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; - } - 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']; - - //判断是否发布 - 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); - } - - //获取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); - } /** * 获取Ai生成文章状态 @@ -2187,4 +1177,15 @@ $response['publish_id'] = '100000001'; $sMsg = empty($aMsg[$iStatus]) ? 'illegal request' : $aMsg[$iStatus]; return json_encode(['status' => 1,'msg' => $sMsg,'data' => ['is_generate' => $iStatus]]); } + + /** + * 获取公众号信息 + */ + public function getWechatLists(){ + + $aWhere = ['state' => 0,'wechat_app_id' => ['<>',''],'wechat_app_secret' => ['<>','']]; + $aJournal = Db::name('journal')->field('issn,wechat_name')->where($aWhere)->select(); + return json_encode(['status' => 1,'msg' => 'success','data' => $aJournal]); + } + }