1511 lines
69 KiB
PHP
1511 lines
69 KiB
PHP
<?php
|
||
namespace app\api\controller;
|
||
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;
|
||
use think\Queue;
|
||
use app\common\OpenAi;
|
||
/**
|
||
* @title 数据库接口
|
||
* @description 数据库接口
|
||
* @group 数据库接口
|
||
*/
|
||
class Aiarticle extends Base
|
||
{
|
||
protected $aLogo = ['media_id' => 'Cn8zlXvVB5DwjcA9h40z9fprHDoc3Jqv97SwrInpmyYiilkeRdKvpD63cWqTYHfz','url' => 'http://mmbiz.qpic.cn/mmbiz_jpg/QHFVW13lONaQJxK9QbHU9CtrvTS2ModZnUyeAvuVN67t8XP85DxVJwDJf2YxCTalrsr17jS080xM6xQv5yGiaEQ/0?wx_fmt=jpeg'];//默认头像
|
||
|
||
//数据表必填字段[ai_article]
|
||
protected $aAiFileds = ['article_id','title_english','title_chinese','journal_issn','covered','digest','research_result','content','highlights','discussion','prospect','research_background','discussion_results','research_method','overview','summary'];
|
||
|
||
//期刊接口地址
|
||
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/';
|
||
|
||
//文章图片icon地址
|
||
protected $sArticleIcon = '/public/articleicon/';
|
||
//期刊图片icon地址
|
||
protected $sJournalIcon = '/public/journalicon/';
|
||
//期刊编辑二维码地址
|
||
protected $sJournalEditorQrcode = '/public/journaleditorqrcode/';
|
||
//作者头像地址
|
||
protected $sUserIcon = '/public/usericon/';
|
||
//默认头像
|
||
protected $sDefaultUserIcon = '/static/img/userImg.f3d9bc3b.jpg';
|
||
//默认公众号配置
|
||
protected $aWechatConfig = [
|
||
'issn' => 'default',
|
||
'wechat_name' => 'TMR Publishing Group',
|
||
'wechat_app_id' => 'wxda4cc30fe32e6313',
|
||
'wechat_app_secret' => 'd5e6002b8b48de46f64dc9a02312f944'
|
||
];
|
||
|
||
//生成AI文章状态
|
||
protected $sGenerateStatusName = 'generate_status_article_id';
|
||
public function __construct(\think\Request $request = null) {
|
||
parent::__construct($request);
|
||
}
|
||
|
||
/**
|
||
* @title 请求OPENAI
|
||
* @param aSearch array 模版内容
|
||
* @param iTemplateId 模版ID
|
||
*/
|
||
private function _createContentForOpenAI($aSearch = [],$sArticleType = 'default',$isTranslate = 2){
|
||
|
||
if(empty($aSearch) || empty($sArticleType)){
|
||
return json_encode(array('status' => 2,'msg' => 'Please select a template or enter the content you want to consult'));
|
||
}
|
||
//组织参数
|
||
if(in_array($sArticleType, ['Mini Review','Review'])){
|
||
$sArticleType = 'Review';
|
||
}else{
|
||
$sArticleType = 'default';
|
||
}
|
||
if($isTranslate == 1){
|
||
$sArticleType = 1;
|
||
}
|
||
|
||
//获取问答内容
|
||
$oOpenAi = new OpenAi;
|
||
if($sArticleType == 'default'){
|
||
$aMessage = $oOpenAi->buildDefaultPrompt($aSearch);
|
||
}
|
||
if($sArticleType == 'Review'){
|
||
$aMessage = $oOpenAi->buildReviewPrompt($aSearch);
|
||
}
|
||
if($sArticleType == 1){
|
||
$aMessage = $oOpenAi->buildTranslatePrompt($aSearch);
|
||
}
|
||
if(empty($aMessage)){
|
||
return json_encode(['status' => 5,'msg' => 'AI Q&A content not obtained']);
|
||
}
|
||
|
||
//请求OPENAI接口
|
||
$aParam = ['messages' => $aMessage,'model' => empty($aParam['api_model']) ? 'gpt-4.1' : $aParam['api_model'],'redis_id' => $aSearch['article_id']];
|
||
$aResult = json_decode($oOpenAi->createWechatContent($aParam),true);
|
||
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
|
||
if($iStatus != 1){
|
||
return json_encode($aResult);
|
||
}
|
||
return json_encode(array('status' => 1,'msg' => 'Content is being generated, please wait'));
|
||
}
|
||
|
||
public function create($aParam = []){
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
|
||
if(empty($iArticleId)){
|
||
return json_encode(array('status' => 2,'msg' => 'Please select an article'.json_encode($aParam) ));
|
||
}
|
||
//媒体类型
|
||
$iMediaType = empty($aParam['media_type']) ? 1 : $aParam['media_type'];
|
||
//获取文章是否生成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'];
|
||
//文章数据
|
||
$aArticle = empty($aArticleContent['article']) ? [] : $aArticleContent['article'];
|
||
|
||
if(empty($aArticle)){
|
||
return json_encode(['status' => 3,'msg' => 'The content of the article is empty']);
|
||
}
|
||
//期刊数据
|
||
$aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal'];
|
||
if(empty($aJournal)){
|
||
return json_encode(['status' => 3,'msg' => 'The journal to which the article belongs does not exist or has been closed']);
|
||
}
|
||
|
||
//查询AI内容是否生成
|
||
$aAiArticle = json_decode($this->getAiArticle(['article_id' => $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数据
|
||
$sIssn = empty($aJournal['issn']) ? '' : $aJournal['issn'];
|
||
$aInsert = ['title_english' => $aArticle['title'],'article_id' => $iArticleId,'create_time' => time(),'journal_issn' => $sIssn,'journal_id' => $aArticle['journal_id'],'article_type' => $aArticle['type'],'media_type' => $iMediaType,'journal_issn' => empty($aJournal['issn']) ? '' :$aJournal['issn']];
|
||
$iId = Db::name('ai_article')->insertGetId($aInsert);
|
||
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(!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']);
|
||
}
|
||
//请求OPENAI
|
||
$aResult = json_decode($this->createForOpenAi($aArticleContent,$aAiArticle),true);
|
||
return json_encode($aResult);
|
||
|
||
}
|
||
|
||
/**
|
||
* @title 请求OPENAI生成内容
|
||
* @param article_id 文章ID
|
||
* @param model 接口模型
|
||
* @param stream 是否流式输出 true是false否
|
||
*/
|
||
public function createForOpenAi($aArticleContent = [],$aAiArticle = []){
|
||
|
||
|
||
$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'];
|
||
|
||
//期刊数据
|
||
$aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal'];
|
||
|
||
//子期刊数据
|
||
$aJournalStage = empty($aArticleContent['journal_stage']) ? [] : $aArticleContent['journal_stage'];
|
||
|
||
//通讯作者
|
||
$aAuthor = empty($aArticleContent['author']) ? [] : $aArticleContent['author'];
|
||
|
||
//查询文章内容
|
||
$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#}'],'.'),'。');
|
||
|
||
//写入Redis 标识已经开始请求OPENAI处理
|
||
$sArticleType = empty($aArticle['type']) ? 'default' : $aArticle['type'];
|
||
$aSearch['article_id'] = $iArticleId;
|
||
$aResult = $this->_createContentForOpenAI($aSearch,$sArticleType);
|
||
return $aResult;
|
||
}
|
||
|
||
/**
|
||
* 处理文章引用
|
||
* @param string $html
|
||
* @return string
|
||
*/
|
||
private function _cite($aArticle = [],$aJournal = [],$aJournalStage = []){
|
||
$no = empty($aJournalStage['stage_no']) ? ':' : '(' . $aJournalStage['stage_no'] . '):';
|
||
$jabbr = empty($aJournal['jabbr']) ? '' : $aJournal['jabbr'];
|
||
$stage_year = empty($aJournalStage['stage_year']) ? '' : $aJournalStage['stage_year'];
|
||
$stage_vol = empty($aJournalStage['stage_vol']) ? '' : $aJournalStage['stage_vol'];
|
||
|
||
$sCite = '';
|
||
if ($aArticle['journal_id'] == 22) {
|
||
$sCite = $aArticle['abbr'] . '. ' . $aArticle['title'] . '[J]. ' . choiseJabbr($aArticle['article_id'],$jabbr) . ',' . $stage_year . ',' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
|
||
} else {
|
||
$sCite = $aArticle['abbr'] . '. ' . $aArticle['title'] . '. <i>' . choiseJabbr($aArticle['article_id'], $jabbr) . '</i>. ' . $stage_year . ';' . $stage_vol . $no . $aArticle['npp'] . '. doi:' . $aArticle['doi'];
|
||
}
|
||
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
|
||
* @param $iSelectAuthor 是否查询作者 1是2否
|
||
*/
|
||
public function getAiArticle($aParam = []){
|
||
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//文章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']);
|
||
}
|
||
//是否查询作者 1是2否
|
||
$iSelectAuthor = empty($aParam['is_select_author']) ? 2 : $aParam['is_select_author'];
|
||
//查询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'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return json_encode(['status' => 1,'msg' => 'success','data' => ['ai_article' => $aAiArticle,'ai_article_author' => $aAiAuthor]]);
|
||
}
|
||
/**
|
||
* @title 处理作者数据
|
||
* @param article_id 文章ID
|
||
* @param content 内容
|
||
*/
|
||
protected function _dealAuthor($aAuthor = array()){
|
||
//返回数组
|
||
if(empty($aAuthor)){
|
||
return [];
|
||
}
|
||
//根据邮箱查询作者信息
|
||
$aArticleId = array_unique(array_column($aAuthor, 'article_id'));
|
||
$iArticleId = $aArticleId[0];
|
||
$aEmail = array_unique(array_column($aAuthor, 'email'));
|
||
$aWhere = ['email' => ['in',$aEmail]];
|
||
$aUser = Db::name('user')->field('user_id,realname,email,localname,icon')->where($aWhere)->select();
|
||
if(empty($aUser)){
|
||
return [];
|
||
}
|
||
//查询作者详情
|
||
$aUserId = array_column($aUser, 'user_id');
|
||
$aWhere = ['reviewer_id' => ['in',$aUserId]];
|
||
$aUserInfo = DB::name('user_reviewer_info')->field('reviewer_id,technical,introduction,company')->where($aWhere)->select();
|
||
if(empty($aUserInfo)){
|
||
return [];
|
||
}
|
||
//数据处理
|
||
$aUserInfo = array_column($aUserInfo, null,'reviewer_id');
|
||
$aAuthor = array_column($aAuthor, null,'email');
|
||
$aInfo = [];
|
||
foreach ($aUser as $key => $value) {
|
||
|
||
//姓名
|
||
$sName = empty($aAuthor[$value['email']]['author_name']) ? '' : $aAuthor[$value['email']]['author_name'];
|
||
$sName = empty($sName) ? $value['localname'] : $sName;
|
||
$sName = empty($sName) ? $value['realname'] : $sName;
|
||
|
||
//单位
|
||
$sCompany = empty($aAuthor[$value['email']]['company']) ? '' : $aAuthor[$value['email']]['company'];
|
||
$sCompany1 = empty($aUserInfo[$value['user_id']]['company']) ? '' : $aUserInfo[$value['user_id']]['company'];
|
||
$sCompany = empty($sCompany) ? $sCompany1 : $sCompany;
|
||
|
||
//职称
|
||
$sTechnical = empty($aUserInfo[$value['user_id']]['technical']) ? '' : $aUserInfo[$value['user_id']]['technical'];
|
||
//简介
|
||
$sIntroduction = empty($aUserInfo[$value['user_id']]['introduction']) ? '' : $aUserInfo[$value['user_id']]['introduction'];
|
||
|
||
$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;
|
||
}
|
||
/**
|
||
* 基础HTML过滤
|
||
* @param string $html
|
||
* @return string
|
||
*/
|
||
private function basic_html_filter($html) {
|
||
// 移除所有HTML标签及PHP标签
|
||
$text = empty($html) ? '' : strip_tags($html);
|
||
|
||
// 转换HTML实体
|
||
$text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||
|
||
// 合并连续空白字符
|
||
$text = preg_replace('/\s+/u', ' ', $text);
|
||
|
||
return trim($text);
|
||
}
|
||
|
||
|
||
/**
|
||
* @title AI生成稿件内容入库
|
||
* @param article_id 文章ID
|
||
* @param content 内容
|
||
*/
|
||
public function updateAiArticle($aParam = array()){
|
||
//返回数组
|
||
$aResult = ['status' => 1,'msg' => 'AI article updated successfully','data' => []];
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//主键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 = $this->aAiFileds;
|
||
$sFiled = '';
|
||
$aUpdateParam = [];
|
||
foreach($aFields as $val){
|
||
if(!isset($aParam[$val])){
|
||
continue;
|
||
}
|
||
if(is_array($aParam[$val])){
|
||
$aParam[$val] = implode(";",$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']);
|
||
}
|
||
|
||
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(isset($aUser['author_name'])){
|
||
$aUpdate = ['localname' => $aUser['author_name']];
|
||
Db::name('user')->where('user_id',$value['user_id'])->update($aUpdate);
|
||
}
|
||
//更新作者简介和单位
|
||
$aUpdateReviewer = [];
|
||
if(isset($aUser['technical'])){
|
||
$aUpdateReviewer['technical'] = $aUser['technical'];
|
||
}
|
||
if(isset($aUser['introduction'])){
|
||
$aUpdateReviewer['introduction'] = $aUser['introduction'];
|
||
}
|
||
if(isset($aUser['company'])){
|
||
$aUpdateReviewer['company'] = $aUser['company'];
|
||
}
|
||
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);
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
|
||
/**
|
||
* 文章内容选择模版生成数据
|
||
* @param article_id 文章ID
|
||
* @param template_id 模版ID
|
||
* @param $iIsSync 是否同步素材到微信 1是2否
|
||
*/
|
||
public function getTemplateContent($aParam = [],$iIsSync = 2){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//文章ID
|
||
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
|
||
|
||
//模版ID
|
||
$iIsSync = empty($aParam['is_sync']) ? 2 : $aParam['is_sync'];
|
||
|
||
//必填参数验证
|
||
if(empty($iArticleId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Please select an article']);
|
||
}
|
||
|
||
//获取AI生成文章内容
|
||
$aAiContent = json_decode($this->getAiArticle(['article_id' => $iArticleId,'is_select_author' => 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']);
|
||
}
|
||
|
||
//获取文章内容
|
||
$aResult = json_decode($this->getArticle($iArticleId),true);
|
||
//获取数据
|
||
$aArticleContent = empty($aResult['data']) ? [] : $aResult['data'];
|
||
if(empty($aArticleContent)){
|
||
return json_encode($aResult);
|
||
}
|
||
|
||
//文章数据
|
||
$aArticle = empty($aArticleContent['article']) ? [] : $aArticleContent['article'];
|
||
if(empty($aArticle)){
|
||
return json_encode(['status' => 4,'msg' => 'Article data is empty']);
|
||
}
|
||
//期刊数据
|
||
$aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal'];
|
||
if(empty($aJournal)){
|
||
return json_encode(['status' => 4,'msg' => 'Journal data is empty']);
|
||
}
|
||
|
||
//子期刊数据
|
||
$aJournalStage = empty($aArticleContent['journal_stage']) ? [] : $aArticleContent['journal_stage'];
|
||
|
||
//通讯作者
|
||
$aAuthor = empty($aArticleContent['author']) ? [] : $aArticleContent['author'];
|
||
|
||
//文章图片
|
||
$sArticleIcon = trim($this->sJournalUsx,'/').$this->sArticleIcon.$aArticle['article_icon'];
|
||
//期刊图片
|
||
$sJournalStageIcon = empty($aJournalStage['stage_icon']) ? '' : '/public/'.$aJournalStage['stage_icon'];
|
||
$sJournalIcon = empty($aJournal['journal_icon']) ? '' : $this->sJournalIcon.$aJournal['journal_icon'];
|
||
$sJournalIcon = empty($sJournalStageIcon) ? $sJournalIcon : $sJournalStageIcon;
|
||
$sJournalIcon = trim($this->sJournalUsx,'/').$sJournalIcon;
|
||
|
||
//期刊编辑二维码
|
||
$sEditorQrcode = empty($aJournal['editor_qrcode']) ? '' : $aJournal['editor_qrcode'];
|
||
$sEditorQrcode = trim($this->sSubmissionUrl,'/').$this->sJournalEditorQrcode.$sEditorQrcode;
|
||
|
||
//获取期刊二维码
|
||
$oMaterial = new Material;
|
||
$aJournal['icon'] = $sJournalIcon;
|
||
$aJournal['journal_stage_id'] = empty($aArticle['journal_stage_id']) ? 0 : $aArticle['journal_stage_id'];
|
||
$aJournalQrCode = $oMaterial->createJournalQrCode($aJournal);
|
||
$sJournalCode = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url'];
|
||
$aAiArticle['journal_qrcode'] = $sJournalCode;
|
||
//文章二维码
|
||
$aArticleQrCode = $oMaterial->createArticleQrCode($aArticle);
|
||
$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){
|
||
|
||
//查询参数组装
|
||
$aQueryParam = ['article_id' => $iArticleId,'journal_id' => $aArticle['journal_id']];
|
||
//组装作者数据
|
||
if(!empty($aAuthor)){
|
||
$aAuthor = $this->_dealAuthor($aAuthor);
|
||
$aQueryParam['author_info'] = $aAuthor;
|
||
}
|
||
|
||
//获取素材信息
|
||
$oMaterial = new Material;
|
||
$aReturnDataResult = json_decode($oMaterial->getMaterial($aQueryParam),true);
|
||
$aReturnData = empty($aReturnDataResult['data']) ? [] : $aReturnDataResult['data'];
|
||
//文章图片
|
||
$aDataInfo = empty($aReturnData['ai_article_material']) ? [] : $aReturnData['ai_article_material'];
|
||
$aAiArticle['article_icon'] = empty($aDataInfo['media_url']) ? $sArticleIcon : $aDataInfo['media_url'];
|
||
//文章二维码图片
|
||
$aDataInfo = empty($aReturnData['ai_article_qrcode']) ? [] : $aReturnData['ai_article_qrcode'];
|
||
$aAiArticle['article_qrcode'] = empty($aDataInfo['media_url']) ? $sArticleIcon : $aDataInfo['media_url'];
|
||
//期刊图片
|
||
$aDataInfo = empty($aReturnData['ai_journal_material']) ? [] : $aReturnData['ai_journal_material'];
|
||
$aAiArticle['journal_icon'] = empty($aDataInfo['media_url']) ? $sJournalIcon : $aDataInfo['media_url'];
|
||
//期刊二维码图片
|
||
$aDataInfo = empty($aReturnData['ai_journal_qrcode']) ? [] : $aReturnData['ai_journal_qrcode'];
|
||
$aAiArticle['journal_qrcode'] = empty($aDataInfo['media_url']) ? $sJournalIcon : $aDataInfo['media_url'];
|
||
//期刊编辑二维码
|
||
$aDataInfo = empty($aReturnData['ai_journal_editor_material']) ? [] : $aReturnData['ai_journal_editor_material'];
|
||
$aAiArticle['editor_qrcode'] = empty($aDataInfo['media_url']) ? $sEditorQrcode : $aDataInfo['media_url'];
|
||
//作者图片上传
|
||
$aDataInfo = empty($aReturnData['ai_author_material']) ? [] : $aReturnData['ai_author_material'];
|
||
if(!empty($aDataInfo) && $aAuthor){
|
||
$aDataInfo = array_column($aDataInfo, null,'email');
|
||
foreach ($aAuthor as $key => $value) {
|
||
$aAuthorData = empty($aDataInfo[$value['email']]) ? [] : $aDataInfo[$value['email']];
|
||
if(empty($aAuthorData)){
|
||
continue;
|
||
}
|
||
$aAuthor[$key]['icon'] = empty($aAuthorData['media_url']) ? $value['icon'] : $aAuthorData['media_url'];
|
||
}
|
||
}
|
||
|
||
}else{
|
||
|
||
//处理文章图片地址数据
|
||
$aAiArticle['article_icon'] = $sArticleIcon;
|
||
//处理文章期刊图片地址数据
|
||
$aAiArticle['journal_icon'] = $sJournalIcon;
|
||
//期刊编辑二维码图片地址数据
|
||
$aAiArticle['editor_qrcode'] = $sEditorQrcode;
|
||
|
||
//作者信息处理
|
||
if(!empty($aAuthor)){
|
||
$aAuthor = $this->_dealAuthor($aAuthor);
|
||
}
|
||
|
||
}
|
||
//期刊访问地址
|
||
$journal_usx = trim($this->sJournalUsx,'/').'/';
|
||
if(!empty($aJournal['journal_usx'])){
|
||
//地址
|
||
$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;
|
||
|
||
|
||
//获取模版信息
|
||
$sJournalIssn = empty($aJournal['issn']) ? 'default' : $aJournal['issn'];//期刊issn
|
||
$sArticleType = empty($aArticle['type']) ? 'default' : $aArticle['type'];//文章类型
|
||
if(in_array($sArticleType, ['review','Mini Review'])){
|
||
$sArticleType = "Review";
|
||
}
|
||
$sTemplatePath = ROOT_PATH."public/ArticleTemplate/".$sJournalIssn."/".$sArticleType;
|
||
if (!is_dir($sTemplatePath)) {//默认模版信息
|
||
$sTemplatePath = ROOT_PATH."public/ArticleTemplate/default/".$sArticleType;
|
||
}
|
||
//index模版目录
|
||
$sTemplateIndexPath = $sTemplatePath.'/index.html';
|
||
|
||
// 验证文件有效性
|
||
if (!file_exists($sTemplateIndexPath)) {
|
||
return json_encode(['status' => 4, 'msg' => 'Article template does not exist']);
|
||
}
|
||
if (!is_readable($sTemplateIndexPath)) {
|
||
return json_encode(['status' => 5, 'msg' => 'The article template is unreadable']);
|
||
}
|
||
//获取模版内容
|
||
$sTemplate = file_get_contents($sTemplateIndexPath);
|
||
//数据处理
|
||
$aSearch = [];
|
||
foreach ($aAiArticle as $key => $value) {
|
||
if(is_array($value)){
|
||
continue;
|
||
}
|
||
$aSearch['{###'.$key.'###}'] = empty($value) ? '' : htmlspecialchars(strip_tags($value));
|
||
}
|
||
|
||
//处理通讯作者信息数据
|
||
$aAuthorInfo = json_decode($this->dealTemplateAuthor($aAuthor,$sTemplatePath),true);
|
||
$aAuthorInfo = empty($aAuthorInfo['data']) ? [] : $aAuthorInfo['data'];
|
||
$aSearch['{###author_summary###}'] = empty($aAuthorInfo['author_info']) ? '' : $aAuthorInfo['author_info'];
|
||
|
||
$aSearch['{###author_string###}'] = empty($aAuthorInfo['author_string']) ? '' : ',通讯作者为'.$aAuthorInfo['author_string'];
|
||
|
||
//处理往期推荐数据
|
||
$aPreviousRecommend = json_decode($this->dealTemplatePreviousRecommend($aArticle,$sTemplatePath),true);
|
||
$aSearch['{###previous_recommend_summary###}'] = empty($aPreviousRecommend['data']) ? '' : $aPreviousRecommend['data'];
|
||
|
||
//处理期刊主题数据
|
||
$sJournalTopic = empty($aJournal['journal_topic']) ? '' : $aJournal['journal_topic'];
|
||
$aTopic = json_decode($this->dealTemplateTopic($sJournalTopic,$sTemplatePath),true);
|
||
$aSearch['{###topic_name_summary###}'] = empty($aTopic['data']) ? '' : $aTopic['data'];
|
||
|
||
//公众号名字处理
|
||
$aSearch['{###wechat_name###}'] = empty($aSearch['{###wechat_name###}']) ? '“'.$aSearch['{###journal_title###}'].'“' : '“'.$aSearch['{###wechat_name###}'].'“';
|
||
|
||
//是否显示文章来源
|
||
//查询app_id和app_secret
|
||
$sIssn = empty($aJournal['issn']) ? '' : $aJournal['issn'];
|
||
$aTougaoJournal = Db::name('journal')->field('wechat_app_id,wechat_app_secret')->where('issn',$sIssn)->find();
|
||
if(!empty($aJournal)){
|
||
$wechat_app_id = empty($aTougaoJournal['wechat_app_id']) ? '' : $aTougaoJournal['wechat_app_id'];
|
||
$aJournal['wechat_app_id'] = empty($aJournal['wechat_app_id']) ? $wechat_app_id : $aJournal['wechat_app_id'];
|
||
$wechat_app_secret = empty($aTougaoJournal['wechat_app_secret']) ? '' : $aTougaoJournal['wechat_app_secret'];
|
||
$aJournal['wechat_app_secret'] = empty($aJournal['wechat_app_secret']) ? $wechat_app_secret : $aJournal['wechat_app_secret'];
|
||
}
|
||
$aSearch['{###article_from###}'] = '';
|
||
if(empty($aJournal['wechat_app_id']) || empty($aJournal['wechat_app_secret'])){//获取默认推送公众号
|
||
$sTemplateFromPath = $sTemplatePath.'/article_from.html';
|
||
//获取默认推送公众号配置
|
||
$aWechatConfig = $this->aWechatConfig;
|
||
if (file_exists($sTemplateFromPath) && is_readable($sTemplateFromPath)) {
|
||
$sTemplateFromPath = file_get_contents($sTemplateFromPath);
|
||
$aSearch['{###article_from###}'] = str_replace('{###journal_title###}', $aJournal['wechat_name']??$aWechatConfig['wechat_name'], $sTemplateFromPath);
|
||
}
|
||
|
||
$aSearch['{###wechat_name###}'] = '“'.$aWechatConfig['wechat_name'].'“';
|
||
}
|
||
|
||
//模版替换变量
|
||
if(empty($aSearch)){
|
||
return json_encode(['status' => 6, 'msg' => '模版内容不能为空']);
|
||
}
|
||
|
||
$aSearch['{###jabbr###}'] = trim(trim($aSearch['{###jabbr###}'],'.'),'。');
|
||
// $aSearch['{###free_year###}'] = date('Y');
|
||
// $aSearch['{###covered###}'] = '内容涵盖'.str_replace('研究涵盖', '', $aSearch['{###covered###}']);
|
||
if(!empty($aSearch['{###covered###}']) && strpos($aSearch['{###covered###}'], '涵盖') === false){
|
||
$aSearch['{###covered###}'] = '内容涵盖'.str_replace('研究涵盖', '', $aSearch['{###covered###}']);
|
||
}
|
||
|
||
//期刊封面
|
||
$aSearch['{###journal_icon_info###}'] = $aSearch['{###journal_icon_details###}'] = '';
|
||
if(!empty($sJournalIcon)){
|
||
$sTemplateJournalInfo = $sTemplatePath.'/journal_icon_info.html';
|
||
if(file_exists($sTemplateJournalInfo) && is_readable($sTemplateJournalInfo)) {
|
||
$sTemplateJournalInfo = file_get_contents($sTemplateJournalInfo);
|
||
$aSearch['{###journal_icon_info###}'] = str_replace('{###journal_icon###}', $aAiArticle['journal_icon']??'', $sTemplateJournalInfo);
|
||
}
|
||
$sTemplateJournalInfo = $sTemplatePath.'/journal_icon_details.html';
|
||
if(file_exists($sTemplateJournalInfo) && is_readable($sTemplateJournalInfo)) {
|
||
$sTemplateJournalInfo = file_get_contents($sTemplateJournalInfo);
|
||
$aSearch['{###journal_icon_details###}'] = str_replace('{###journal_icon###}', $aAiArticle['journal_icon']??'', $sTemplateJournalInfo);
|
||
}
|
||
}
|
||
|
||
$sTemplate = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplate);
|
||
// $this->writeFile($sTemplate,ROOT_PATH.'public/template_info.html');
|
||
return json_encode(['status' => 1, 'msg' => '模版生成成功','data' => ['template' => $sTemplate]]);
|
||
}
|
||
|
||
/**
|
||
* 处理模版通讯作者
|
||
* @param article_id 文章ID
|
||
*/
|
||
private function dealTemplateAuthor($aAuthor = [],$sTemplatePath = ''){
|
||
|
||
//必填字段判断
|
||
if(empty($aAuthor) || empty($sTemplatePath)){
|
||
return json_encode(['status' => 2,'msg' => 'Corresponding author or template does not exist']);
|
||
}
|
||
|
||
//获取通讯作者模版
|
||
$sAuthorTemplatePathAuthor = $sTemplatePath.'/author.html';
|
||
if (!file_exists($sAuthorTemplatePathAuthor)) {
|
||
return json_encode(['status' => 3, 'msg' => 'Corresponding author template does not exist','data' => '']);
|
||
}
|
||
if (!is_readable($sAuthorTemplatePathAuthor)) {
|
||
return json_encode(['status' => 4, 'msg' => 'The corresponding author template is unreadable','data' => '']);
|
||
}
|
||
$sAuthorTemplate = file_get_contents($sAuthorTemplatePathAuthor);
|
||
|
||
//处理模版变量
|
||
$aAuthorSerachInfo = [];
|
||
$sAuthorInfo = '';
|
||
$aLogo = $this->aLogo;
|
||
|
||
//请求AI翻译
|
||
$sContent = '';
|
||
$aSearch['{#content#}'] = json_encode($aAuthor);
|
||
$aResult = json_decode($this->_createContentForOpenAI($aSearch,1,1),true);
|
||
$aContent = empty($aResult['data']) ? [] : array_column($aResult['data'], null,'email');
|
||
foreach ($aAuthor as $key => $value) {
|
||
|
||
//请求AI翻译
|
||
$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['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'){//头像拼接处理
|
||
$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###}'] = $sIconInfo;
|
||
}
|
||
$aAuthorSerach['{###icon_path###}'] = trim($aAuthorSerach['{###icon_path###}'],'/');
|
||
}else{
|
||
$aAuthorSerach['{###'.$k.'###}'] = trim($val,'/');
|
||
}
|
||
}
|
||
$aAuthorSerachInfo[] = str_replace(array_keys($aAuthorSerach), array_values($aAuthorSerach), $sAuthorTemplate);
|
||
}
|
||
|
||
//通讯作者列表
|
||
//获取通讯作者汇总模版
|
||
$sAuthorTemplatePath = $sTemplatePath.'/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' => $sAuthorTemplate,'author_string' => trim($sAuthorInfo,';')]]);
|
||
}
|
||
|
||
/**
|
||
* 处理期刊主题模版
|
||
* @param article_id 文章ID
|
||
*/
|
||
private function dealTemplateTopic($sTopic = '',$sTemplatePath = ''){
|
||
if(empty($sTemplatePath)){
|
||
return json_encode(['status' => 2,'template does not exist']);
|
||
}
|
||
if(empty($sTopic)){
|
||
return json_encode(['status' => 2,'topic does not exist']);
|
||
}
|
||
|
||
//获取主题模版
|
||
$sTemplatePathTopic = $sTemplatePath.'/topic.html';
|
||
if (!file_exists($sTemplatePathTopic)) {
|
||
return json_encode(['status' => 4, 'msg' => 'Corresponding author template does not exist']);
|
||
}
|
||
if (!is_readable($sTemplatePathTopic)) {
|
||
return json_encode(['status' => 5, 'msg' => 'The corresponding author template is unreadable']);
|
||
}
|
||
$sTemplate = file_get_contents($sTemplatePathTopic);
|
||
|
||
//数据处理
|
||
$sTopic = trim($sTopic);
|
||
$aTopic = empty($sTopic) ? [] : explode(',', $sTopic);
|
||
$aSearchInfo = [];
|
||
if(!empty($aTopic)){
|
||
foreach ($aTopic as $key => $value) {
|
||
$aSerach['{###topic_name###}'] = empty($value) ? '' : strip_tags($value);
|
||
$aSearchInfo[] = str_replace(array_keys($aSerach), array_values($aSerach), $sTemplate);
|
||
}
|
||
}
|
||
|
||
//获取期刊主题汇总模版
|
||
$sTemplatePath = $sTemplatePath.'/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]);
|
||
}
|
||
|
||
/**
|
||
* 处理往期推荐
|
||
* @param article_id 文章ID
|
||
*/
|
||
private function dealTemplatePreviousRecommend($aArticle=[],$sTemplatePath = ''){
|
||
|
||
if(empty($sTemplatePath)){
|
||
return json_encode(['status' => 2,'template does not exist']);
|
||
}
|
||
//获取往期推荐模版
|
||
$sTemplatePathRecommend = $sTemplatePath.'/previous_recommend.html';
|
||
if (!file_exists($sTemplatePathRecommend)) {
|
||
return json_encode(['status' => 3, 'msg' => 'Corresponding author template does not exist']);
|
||
}
|
||
if (!is_readable($sTemplatePathRecommend)) {
|
||
return json_encode(['status' => 4, 'msg' => 'The corresponding author template is unreadable']);
|
||
}
|
||
$sTemplate = file_get_contents($sTemplatePathRecommend);
|
||
|
||
//判断是否关联文章
|
||
if(empty($aArticle['related'])){
|
||
return json_encode(['status' => 6, 'msg' => 'Unrelated articles']);
|
||
}
|
||
|
||
//获取关联文章信息
|
||
$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['is_publish'] = 1;
|
||
$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 = ['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);
|
||
}
|
||
}
|
||
|
||
//获取往期推荐汇总模版
|
||
$sTemplatePath = $sTemplatePath.'/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]);
|
||
}
|
||
|
||
|
||
/**
|
||
* 文章同步到微信公众号草稿箱
|
||
* @param article_id 文章ID
|
||
*/
|
||
public function syncWechat($aParam = []){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//文章ID
|
||
$iArticleId = empty($aParam['article_id'] ) ? '' : $aParam['article_id'];
|
||
|
||
//必填参数验证
|
||
if(empty($iArticleId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Please select an article']);
|
||
}
|
||
|
||
//判断草稿箱是否上传
|
||
$oMaterial = new Material;
|
||
$aLog = json_decode($oMaterial->getWechatLog(['article_id' => $iArticleId,'type' => 2,'status' =>1]),true);
|
||
if(!empty($aLog['data'])){
|
||
return json_encode(['status' => 1,'msg' => 'Already uploaded to draft box','data' => []]);
|
||
}
|
||
|
||
//判断文章类型
|
||
$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"]);
|
||
}
|
||
//查询文章是否存在
|
||
$aWhere = ['article_id' => $iArticleId,'is_delete' => 2];
|
||
$aAiArticle = Db::name('ai_article')->field('ai_article_id,title_chinese as title,journal_issn,digest,article_type')->where($aWhere)->find();
|
||
if(empty($aAiArticle)){
|
||
return json_encode(['status' => 3, 'msg' => 'The article does not exist']);
|
||
}
|
||
$sWechatId = empty($aAiArticle['journal_issn']) ? '' : $aAiArticle['journal_issn'];
|
||
if(empty($sWechatId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Please select the WeChat official account to push']);
|
||
}
|
||
|
||
//获取模版
|
||
$sTemplate = empty($aAiArticle['article_type']) ? 'default' : $aAiArticle['article_type'];//文章类型
|
||
if(in_array($sTemplate, ['review','Mini Review'])){
|
||
$sTemplate = "Review";
|
||
}
|
||
|
||
//查询期刊微信公众号配置
|
||
$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'])){
|
||
//获取默认配置
|
||
$aJournalInfo = $this->aWechatConfig;
|
||
$sWechatId = $aJournalInfo['issn'] ?? 'default';
|
||
}
|
||
|
||
//查询该模版是否推送到微信公众号
|
||
$aWhere['wechat_id'] = $sWechatId;
|
||
$aWhere['template_id'] = $sTemplate;
|
||
$aWhere['wechat_id'] = $aAiArticle['journal_issn'];
|
||
$aWechatArticle = Db::name('ai_wechat_article')->where($aWhere)->find();
|
||
if(!empty($aWechatArticle)){
|
||
return json_encode(['status' => 4, 'msg' => 'Already uploaded to draft box']);
|
||
}
|
||
|
||
//数据处理-标题
|
||
$sTitle = empty($aAiArticle['title']) ? '' : $aAiArticle['title'];
|
||
$sTitle = mb_convert_encoding($sTitle, 'UTF-8', 'auto');
|
||
$aAiArticle['title'] = $this->truncateByBytes($sTitle);
|
||
//数据处理-摘要
|
||
$sDigest = empty($aAiArticle['digest']) ? '' : $aAiArticle['digest'];
|
||
$sDigest = mb_convert_encoding($sDigest, 'UTF-8', 'auto');
|
||
$aAiArticle['digest'] = $this->truncateByBytes($sDigest, 120);
|
||
//是否打开评论,0不打开(默认),1打开
|
||
$aParam['need_open_comment'] = empty($aParam['need_open_comment']) ? 1 : $aParam['need_open_comment'];
|
||
//是否粉丝才可评论,0所有人可评论(默认),1粉丝才可评论
|
||
$aParam['only_fans_can_comment'] = empty($aParam['only_fans_can_comment']) ? 1 : $aParam['only_fans_can_comment'];
|
||
|
||
//查询文章封面
|
||
$aMaterial = Db::name('ai_article_material')->field('media_id as thumb_media_id')->where('article_id',$iArticleId)->find();
|
||
if(!empty($aMaterial)){
|
||
$aAiArticle += $aMaterial;
|
||
}
|
||
$aParam += $aAiArticle;
|
||
//获取模版生成内容
|
||
$aTemplateParam = ['article_id' => $iArticleId,'template_id' => $sTemplate,'is_sync' => 1,'wechat_id' => $sWechatId];
|
||
$aTemplateParam += $aJournalInfo;
|
||
$aResult = json_decode($this->getTemplateContent($aTemplateParam,1),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]);
|
||
}
|
||
|
||
//请求微信公众号接口推送
|
||
$aParam['content'] = $aData['template'];
|
||
$aParam += $aJournalInfo;
|
||
$oWechat = new Wechat;
|
||
$aResult = json_decode($oWechat->addDraft($aParam),true);
|
||
$aData = empty($aResult['data']) ? [] : $aResult['data'];
|
||
//插入操作日志
|
||
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
|
||
$sMsg = empty($aResult['msg']) ? '' : $aResult['msg'];
|
||
if ($iStatus != 1) {
|
||
$iStatus = 2;
|
||
$sMsg = empty($sMsg) ? '草稿箱推送失败' : $sMsg;
|
||
}
|
||
//插入日志记录
|
||
$oMaterial = new Material;
|
||
$aLogInfo = ['article_id' => $iArticleId,'type' => 2,'msg' =>$sMsg,'status' => $iStatus,'create_time' => time()];
|
||
$result = json_decode($oMaterial->addWechatLog($aLogInfo),true);
|
||
if(empty($aData)){
|
||
return json_encode($aResult);
|
||
}
|
||
//插入记录表
|
||
$aParam = ['media_id' => $aData['media_id'],'update_time' => time(),'template_id' => $sTemplate,'template_content' => $aParam['content'],'article_id' => $iArticleId,'article_type' => $article_type,'need_open_comment' => $aParam['need_open_comment'],'only_fans_can_comment' => $aParam['only_fans_can_comment'],'create_time' => time(),'wechat_id' => $sWechatId,'ai_article_id' => $aAiArticle['ai_article_id']];
|
||
$result = Db::name('ai_wechat_article')->insert($aParam);
|
||
if($result === false){
|
||
return json_encode(['status' => 5,'msg' => "Article data insertion failed"]);
|
||
}
|
||
|
||
//写入发布队列
|
||
// Queue::later(60,'app\api\job\WechatPublishDraft@fire', ['article_id' => $iArticleId], 'WechatDraftPublish');
|
||
return json_encode(['status' => 1,'msg' => 'Upload draft box successfully','data' => []]);
|
||
}
|
||
|
||
/**
|
||
* 字符串处理
|
||
* @param article_id 文章ID
|
||
*/
|
||
private function truncateByBytes($str, $maxLength = 64) {
|
||
$totalChars = mb_strlen($str, 'UTF-8');
|
||
if($totalChars >= $maxLength){
|
||
return mb_substr($str,0,$maxLength);
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
/**
|
||
* 获取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']);
|
||
}
|
||
|
||
//返回数据定义
|
||
$aResult = ['generate_status' => 3,'draft_status' => 2,'publish_status' => -1];
|
||
|
||
//查询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',4 => 'The article has been pushed to the draft box',6 => 'The article has been pushed to the draft box'];
|
||
$iStatus = empty($aAiArticle['is_generate']) ? 3 : $aAiArticle['is_generate'];
|
||
$sMsg = empty($aMsg[$iStatus]) ? 'illegal request' : $aMsg[$iStatus];
|
||
$aResult['generate_status'] = $iStatus;
|
||
|
||
if(!empty($aAiArticle)){
|
||
|
||
$aMsg = [1 => 'The article has been pushed to the draft box',2 => 'Not pushed to the draft box',3 => 'Material upload in progress',4 => 'Material upload completed'];
|
||
//获取Redis内容,判断是否上传素材成功
|
||
$oMaterial = new Material;
|
||
$sUploadInfo = $oMaterial->getStepForRedis($iArticleId);
|
||
$sErrorInfo = '';
|
||
if(!empty($sUploadInfo) && $sUploadInfo != 'finish'){
|
||
$iStatus = 3;//素材上传中
|
||
$sErrorInfo = $oMaterial->getErrorForRedis($iArticleId);
|
||
if(!empty($sErrorInfo)){
|
||
$iStatus = 5;
|
||
return json_encode(['status' => 5,'msg' => $sErrorInfo]);
|
||
}
|
||
|
||
}
|
||
if(!empty($sUploadInfo) && $sUploadInfo == 'finish'){
|
||
$iStatus = 4;//素材上传完成
|
||
}
|
||
//判断是否推送到草稿箱
|
||
if(empty($sUploadInfo) || $iStatus == 4){
|
||
if(!empty($aParam['template_id'])){
|
||
$aWhere['template_id'] = $aParam['template_id'];
|
||
}
|
||
$aDraft = Db::name('ai_wechat_article')->field('is_publish,publish_status,article_id,template_id,wechat_id')->where($aWhere)->find();
|
||
$iStatus = empty($aDraft) ? 2 : 1;
|
||
}
|
||
$aResult['draft_status'] = $iStatus;
|
||
|
||
if(!empty($aDraft)){
|
||
$aMsg = [0 => 'Article successfully published', 1 => 'Article is being published',2 => 'Original article creation failed', 3 => 'Article conventional failure', 4 => 'WeChat official account platform review failed', 5 => 'After success, the user deletes all articles', 6 => 'After success, the system will ban all articles','-1' => 'Draft box article not published'];
|
||
|
||
//查询微信接口获取发布状态
|
||
if($aDraft['publish_status'] == 1){
|
||
$aReturnData = json_decode($this->queryStatus($aDraft),true);
|
||
$aData = empty($aReturnData['data']['data']) ? [] : $aReturnData['data']['data'];
|
||
}
|
||
$iStatus = empty($aData['publish_status']) ? $aDraft['publish_status'] : $aData['publish_status'];
|
||
$aResult['publish_status'] = $iStatus;
|
||
}
|
||
}
|
||
$sMsg = empty($aMsg[$iStatus]) ? 'illegal request' : $aMsg[$iStatus];
|
||
return json_encode(['status' => 1,'msg' => $sMsg,'data' => $aResult]);
|
||
}
|
||
|
||
/**
|
||
* 获取公众号信息
|
||
*/
|
||
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]);
|
||
}
|
||
|
||
/**
|
||
* 公众号文章发布
|
||
*/
|
||
public function publishDraft($aParam = []){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
//文章ID
|
||
$iArticleId = empty($aParam['article_id'] ) ? '' : $aParam['article_id'];
|
||
//必填参数验证
|
||
if(empty($iArticleId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Please select an article']);
|
||
}
|
||
|
||
//查询文章是否存在
|
||
$aWhere = ['article_id' => $iArticleId,'is_delete' => 2];
|
||
$aAiArticle = Db::name('ai_article')->field('article_type')->where($aWhere)->find();
|
||
if(empty($aAiArticle)){
|
||
return json_encode(['status' => 3, 'msg' => 'The article does not exist']);
|
||
}
|
||
|
||
//查询是否上传到草稿箱
|
||
$aWhere = ['article_id' => $iArticleId,'template_id' => $aAiArticle['article_type']];
|
||
$aWechatArticle = Db::name('ai_wechat_article')->field('id,is_publish,media_id,publish_status,wechat_id')->where($aWhere)->find();
|
||
$sMediaId = empty($aWechatArticle['media_id']) ? '' : $aWechatArticle['media_id'];
|
||
if(empty($sMediaId)){
|
||
return json_encode(['status' => 3, 'msg' => 'The article was not found in the draft box of WeChat official account']);
|
||
}
|
||
$iId = empty($aWechatArticle['id']) ? 0 : $aWechatArticle['id'];
|
||
|
||
//推送公众号Id
|
||
$sWechatId = empty($aWechatArticle['wechat_id']) ? '' : $aWechatArticle['wechat_id'];
|
||
//判断是否发布
|
||
if($aWechatArticle['publish_status'] != '-1'){
|
||
return json_encode(['status' => 5, 'msg' => 'The article has been published, please confirm']);
|
||
}
|
||
|
||
//查询期刊微信公众号配置
|
||
$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'])){
|
||
//获取默认配置
|
||
$aJournalInfo = $this->aWechatConfig;
|
||
}
|
||
$aJournalInfo['media_id'] = $sMediaId;
|
||
//调用发布接口
|
||
$oWechat = new Wechat;
|
||
$aResult = json_decode($oWechat->publishDraft($aJournalInfo),true);
|
||
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
|
||
$sMsg = empty($aResult['msg']) ? '' : $aResult['msg'];
|
||
if ($iStatus != 1) {
|
||
$iStatus = 2;
|
||
$sMsg = empty($sMsg) ? '发布失败' : $sMsg;
|
||
}
|
||
|
||
//插入日志记录
|
||
$oMaterial = new Material;
|
||
$aLogInfo = ['article_id' => $iArticleId,'type' => 3,'msg' =>$sMsg,'status' => $iStatus,'create_time' => time()];
|
||
$result = json_decode($oMaterial->addWechatLog($aLogInfo),true);
|
||
if($iStatus != 1){
|
||
return json_encode($aResult);
|
||
}
|
||
|
||
//更新数据表
|
||
//更新文章表publish_id
|
||
$aData = empty($aResult['data']) ? [] : $aResult['data'];
|
||
$aUpdate = ['update_time' => time(),'is_publish' => 1,'publish_id' => $aData['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' => 5,'msg' => "Failed to update the status of the published article"]);
|
||
}
|
||
|
||
//发布成功查询状态
|
||
$iDelaySeconds = 30;//4 * 3600; // 30秒数
|
||
Queue::later($iDelaySeconds,'app\api\job\WechatQueryStatus@fire', ['article_id' => $iArticleId], 'WechatQueryStatus');
|
||
return json_encode(['status' => 1,'msg' => 'Draft box article successfully published','data' => []]);
|
||
}
|
||
/**
|
||
* CURL 查询文章的发布状态
|
||
* @param $sToken Token
|
||
* @param article_id array 文章ID
|
||
*/
|
||
public function queryStatus($aParam = []){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//查询条件
|
||
$aWhere = ['is_publish' => 1,'publish_id' => ['<>',''],'publish_status' => 1,'is_delete' => 2];
|
||
//文章ID
|
||
if(!empty($aParam['article_id'])){
|
||
$aWhere['article_id'] = $aParam['article_id'];
|
||
}
|
||
//模版ID
|
||
if(!empty($aParam['template_id'])){
|
||
$aWhere['template_id'] = $aParam['template_id'];
|
||
}
|
||
//推送公众号Id
|
||
if(!empty($aParam['wechat_id'])){
|
||
$aWhere['wechat_id'] = $aParam['wechat_id'];
|
||
}
|
||
//查询待发布文章信息
|
||
$aWechatArticle = Db::name('ai_wechat_article')->where($aWhere)->field('id,article_id,template_id,wechat_id,publish_id')->select();
|
||
if(empty($aWechatArticle)){
|
||
return json_encode(['status' => 2,'msg' => 'No articles requiring synchronization status were found'],true);
|
||
}
|
||
|
||
//查询期刊微信公众号配置
|
||
$aIssn = array_unique(array_column($aWechatArticle, 'wechat_id'));
|
||
if(empty($aIssn)){
|
||
return json_encode(['status' => 3,'msg' => 'Official account information is empty']);
|
||
}
|
||
$aWhere = ['issn' => ['in',$aIssn]];
|
||
$aJournalInfo = Db::name('journal')->field('issn,wechat_app_id,wechat_app_secret')->where($aWhere)->select();
|
||
if(!empty($aJournalInfo)){
|
||
$aJournalInfo = array_column($aJournalInfo, null,'issn');
|
||
}
|
||
|
||
//循环处理
|
||
$oWechat = new Wechat;
|
||
$aInsert = [];
|
||
Db::startTrans();
|
||
foreach ($aWechatArticle as $key => $value) {
|
||
if(empty($value['wechat_id']) || empty($value['publish_id'])){
|
||
continue;
|
||
}
|
||
//账号信息
|
||
$aAccount = empty($aJournalInfo[$value['wechat_id']]) ? [] : $aJournalInfo[$value['wechat_id']];
|
||
if(empty($aAccount['wechat_app_id']) || empty($aAccount['wechat_app_secret'])){
|
||
$aAccount = $this->aWechatConfig;
|
||
}
|
||
$aAccount['publish_id'] = $value['publish_id'];
|
||
$aResult = json_decode($oWechat->queryStatus($aAccount),true);
|
||
$aData = empty($aResult['data']) ? [] : $aResult['data'];
|
||
if(empty($aData)){
|
||
continue;
|
||
}
|
||
//日志记录
|
||
$aData = $this->dealStatusData($aData);
|
||
$aLog = empty($aData['log']) ? [] : $aData['log'];
|
||
if(!empty($aLog)){
|
||
$aInsert[] = $aData['log'];
|
||
}
|
||
//更新状态
|
||
$aDetail = empty($aData['article_detail']) ? [] : $aData['article_detail'];
|
||
$iStatus = isset($aLog['publish_status']) ? $aLog['publish_status'] : $value['publish_status'];
|
||
//微信文章链接
|
||
$sUrl = empty($aDetail[0]['article_url']) ? '' : $aDetail[0]['article_url'];
|
||
$updateResult = Db::name('ai_wechat_article')->where('id',$value['id'])->limit(1)->update(['publish_status' => $iStatus,'wechat_article_url' => $sUrl,'update_time' => time()]);
|
||
}
|
||
//插入日志表
|
||
if(!empty($aInsert)){
|
||
$insertResult = Db::name('wechat_article_publish_log')->insertAll($aInsert);
|
||
}
|
||
Db::commit();
|
||
return json_encode(['status' => 1,'msg' => 'success']);
|
||
}
|
||
|
||
/**
|
||
* 发布日志数据处理
|
||
* @param $sToken Token
|
||
* @param article_id array 文章ID
|
||
*/
|
||
private function dealStatusData($aParam = []){
|
||
|
||
//log日志需要参数
|
||
$aField = ['publish_id' => '','publish_status' => '' ,'article_id' => '' ,'article_detail' => '' ,'fail_idx' => ''];
|
||
|
||
$aDetail = [];
|
||
foreach ($aParam as $key => $value) {
|
||
if($key == 'article_detail'){
|
||
$aDetail = empty($value) ? [] : $value;
|
||
$aDetail = empty($aDetail['item']) ? [] : $aDetail['item'];
|
||
}
|
||
$aField[$key] = empty($value) ? '' : $value;
|
||
$aField[$key] = is_array($aField[$key]) ? json_encode($aField[$key]) : $aField[$key];
|
||
}
|
||
$aField['create_time'] = time();
|
||
return ['article_detail' => $aDetail,'log' => $aField];
|
||
}
|
||
|
||
/**
|
||
* 上传素材
|
||
* @param $sToken Token
|
||
* @param article_id array 文章ID
|
||
*/
|
||
|
||
public function uploadMaterial($aParam = []){
|
||
|
||
//获取参数
|
||
$aParam = empty($aParam) ? $this->request->post() : $aParam;
|
||
|
||
//文章ID
|
||
$iArticleId = empty($aParam['article_id']) ? '' : $aParam['article_id'];
|
||
|
||
//必填参数验证
|
||
if(empty($iArticleId)){
|
||
return json_encode(['status' => 2, 'msg' => 'Please select an article']);
|
||
}
|
||
|
||
//判断素材是否上传
|
||
$oMaterial = new Material;
|
||
$aLog = json_decode($oMaterial->getWechatLog(['article_id' => $iArticleId,'type' => 1,'status' =>1]),true);
|
||
if(!empty($aLog['data'])){
|
||
$aLog = json_decode($oMaterial->getWechatLog(['article_id' => $iArticleId,'type' => 2,'status' =>1]),true);
|
||
if(empty($aLog['data'])){ //推送到草稿箱
|
||
Queue::push('app\api\job\WechatDraft@fire', ['article_id' => $iArticleId], 'WechatDraft');
|
||
return json_encode(['status' => 1,'msg' => 'The article material has been pushed into the draft box queue','data' => []]);
|
||
}
|
||
return json_encode(['status' => 1,'msg' => 'The material has been uploaded','data' => []]);
|
||
}
|
||
|
||
//获取AI生成文章内容
|
||
$aAiContent = json_decode($this->getAiArticle(['article_id' => $iArticleId,'is_select_author' => 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']);
|
||
}
|
||
|
||
//获取文章内容
|
||
$aResult = json_decode($this->getArticle($iArticleId),true);
|
||
//获取数据
|
||
$aArticleContent = empty($aResult['data']) ? [] : $aResult['data'];
|
||
if(empty($aArticleContent)){
|
||
return json_encode($aResult);
|
||
}
|
||
|
||
//文章数据
|
||
$aArticle = empty($aArticleContent['article']) ? [] : $aArticleContent['article'];
|
||
if(empty($aArticle)){
|
||
return json_encode(['status' => 4,'msg' => 'Article data is empty']);
|
||
}
|
||
//期刊数据
|
||
$aJournal = empty($aArticleContent['journal']) ? [] : $aArticleContent['journal'];
|
||
if(empty($aJournal)){
|
||
return json_encode(['status' => 4,'msg' => 'Journal data is empty']);
|
||
}
|
||
|
||
//通讯作者
|
||
$aAuthor = empty($aArticleContent['author']) ? [] : $aArticleContent['author'];
|
||
|
||
//文章图片
|
||
$sArticleIcon = trim($this->sJournalUsx,'/').$this->sArticleIcon.$aArticle['article_icon'];
|
||
|
||
//子期刊数据
|
||
$aJournalStage = empty($aArticleContent['journal_stage']) ? [] : $aArticleContent['journal_stage'];
|
||
//期刊图片
|
||
$sJournalStageIcon = empty($aJournalStage['stage_icon']) ? '' : '/public/'.$aJournalStage['stage_icon'];
|
||
$sJournalIcon = empty($aJournal['journal_icon']) ? '' : $this->sJournalIcon.$aJournal['journal_icon'];
|
||
$sJournalIcon = empty($sJournalStageIcon) ? $sJournalIcon : $sJournalStageIcon;
|
||
$sJournalIcon = trim($this->sJournalUsx,'/').$sJournalIcon;
|
||
|
||
//期刊编辑二维码
|
||
$editor_qrcode = empty($aJournal['editor_qrcode']) ? '' : $aJournal['editor_qrcode'];
|
||
$sEditorQrcode = trim($this->sSubmissionUrl,'/').$this->sJournalEditorQrcode.$editor_qrcode;
|
||
|
||
//获取期刊二维码
|
||
$oMaterial = new Material;
|
||
$aJournal['journal_stage_id'] = empty($aArticle['journal_stage_id']) ? 0 : $aArticle['journal_stage_id'];
|
||
$aJournalQrCode = $oMaterial->createJournalQrCode($aJournal);
|
||
$sJournalCode = empty($aJournalQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aJournalQrCode['qrcode_url'];
|
||
$aAiArticle['journal_qrcode'] = $sJournalCode;
|
||
|
||
//文章二维码
|
||
$aArticleQrCode = $oMaterial->createArticleQrCode($aArticle);
|
||
$sArticleCode = empty($aArticleQrCode['qrcode_url']) ? '' : $this->sSubmissionUrl.'public/qrcode/'.$aArticleQrCode['qrcode_url'];
|
||
$aAiArticle['article_qrcode'] = $sArticleCode;
|
||
|
||
// //上传素材到微信
|
||
//组装文章数据
|
||
$aWechatConfig = $this->aWechatConfig;
|
||
$sWechatAppId = empty($aJournal['wechat_app_id']) ? $aWechatConfig['wechat_app_id'] : $aJournal['wechat_app_id'];
|
||
$sWechatAppSecret = empty($aJournal['wechat_app_secret']) ? $aWechatConfig['wechat_app_secret'] : $aJournal['wechat_app_secret'];
|
||
$aUpload['article_info'] = ['icon' => $sArticleIcon];
|
||
|
||
//组装期刊数据
|
||
$aUpload['journal_info'] = ['icon' => $sJournalIcon,'editor_qrcode' => $editor_qrcode,'journal_stage_id' => $aArticle['journal_stage_id']];
|
||
|
||
//组装作者数据
|
||
if(!empty($aAuthor)){
|
||
$aUpload['author_info'] = $this->_dealAuthor($aAuthor);
|
||
}
|
||
//上传微信公众号用到的素材
|
||
$aUpload += ['article_id' => $iArticleId,'journal_id' => $aArticle['journal_id'],'wechat_app_id' => $sWechatAppId,'wechat_app_secret' => $sWechatAppSecret];
|
||
$aResult = json_decode($oMaterial->uploadMaterial($aUpload),true);
|
||
$iStatus = empty($aResult['status']) ? 0 : $aResult['status'];
|
||
$sMsg = empty($aResult['msg']) ? '' : $aResult['msg'];
|
||
if ($iStatus != 1) {
|
||
$iStatus = 2;
|
||
$sMsg = empty($sMsg) ? '素材上传失败' : $sMsg;
|
||
}
|
||
//插入日志记录
|
||
$aLogInfo = ['article_id' => $iArticleId,'type' => 1,'msg' =>$sMsg,'status' => $iStatus,'create_time' => time()];
|
||
$result = json_decode($oMaterial->addWechatLog($aLogInfo),true);
|
||
|
||
//素材上传成功调用上传草稿箱的任务
|
||
if($iStatus == 1){
|
||
//1分钟后推送草稿箱
|
||
$iDelaySeconds = 60;//4 * 3600; // 1分钟的秒数
|
||
Queue::later($iDelaySeconds,'app\api\job\WechatDraft@fire', ['article_id' => $iArticleId], 'WechatDraft');
|
||
}
|
||
return json_encode(['status' => $iStatus,'msg' => $sMsg,'data' => $aLogInfo]);
|
||
}
|
||
|
||
/**
|
||
* 获取文章对应模版
|
||
*/
|
||
|
||
private function writeFile($sContent,$sPath = ''){
|
||
|
||
$chunkSize = 1024 * 1024; // 例如,每次写入1MB
|
||
$file = fopen($sPath, "w");
|
||
for ($i = 0; $i < strlen($sContent); $i += $chunkSize) {
|
||
$chunk = substr($sContent, $i, $chunkSize);
|
||
fwrite($file, $chunk);
|
||
}
|
||
|
||
fclose($file);
|
||
}
|
||
}
|