Files
tougao/application/api/controller/Aireview.php
2025-04-02 13:21:15 +08:00

244 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\api\controller;
use app\api\controller\Base;
use think\Db;
/**
* @title AI审核文章
* @description 对接OPENAI接口
*/
class Aireview extends Base
{
protected $sApiKey;
protected $proxy;
protected $sUrl;
protected $curl;
protected $sResponesData;
protected $sError;
protected $timeout = 60;
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);
}
/**
* CURL 发送请求到 OpenAI
* @param $messages 内容
* @param $model 模型类型
*/
protected function curlOpenAI($messages, $model = 'gpt-4o'){
$sUrl = $this->sUrl;
$data = [
'model' => $model,
'messages' => $messages,
'temperature' => 0.7
];
$this->curl = curl_init();
// 通用配置
curl_setopt($this->curl, CURLOPT_URL, $sUrl);
// 设置头信息
curl_setopt($this->curl, 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);
$result = curl_exec($this->curl);
//请求失败
if (curl_errno($this->curl)){
$this->sError = curl_errno($this->curl);
curl_close($this->curl);
return FALSE;
}
$this->sResponesData = json_decode($result);
curl_close($this->curl);
return TRUE;
}
/**
* @title AI审核文章
* @param article_id 文章ID
* @param abstrart 摘要
* @param keywords 关键词
* @param model 接口模型
* @param stream 是否流式输出 true是false否
*/
public function review(){
//获取参数
$aParam = $this->request->post();
if(empty($aParam['article_id'])){
exit(json_encode(array('status' => 2,'msg' => 'Please select an article' )));
}
// if(empty($aParam['abstrart'])){
// exit(json_encode(array('status' => 2,'msg' => 'abstrart cannot be empty' )));
// }
// if(empty($aParam['keywords'])){
// exit(json_encode(array('status' => 2,'msg' => 'keywords cannot be empty' )));
// }
//查询文章
$aArticle = Db::table('t_article')->field('article_id,abstrart,keywords,journal_id')->where('article_id',$aParam['article_id'])->find();
if(empty($aArticle)){
exit(json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' )));
}
//获取文章评测内容
$aAiReview = Db::table('t_article_ai_review')->field('article_id,content')->where('article_id',$aParam['article_id'])->find();
if(!empty($aAiReview)){
exit(json_encode(array('status' => 1,'msg' => 'AI has been reviewed','data' => $aAiReview)));
}
$aParam['abstrart'] = empty($aParam['abstrart']) ? $aArticle['abstrart'] : $aParam['abstrart'];//简介
$aParam['keywords'] = empty($aParam['keywords']) ? $aArticle['keywords'] : $aParam['keywords'];//关键词
//根据期刊ID查询期刊信息
$aJournal = Db::table('t_journal')->field('zname')->where('journal_id',$aArticle['journal_id'])->find();
if(empty($aJournal)){
exit(json_encode(array('status' => 4,'msg' => 'This article is not associated with a journal' )));
}
//组织参数
$sContent = '';
$sContent .= '摘要:'.$aParam['abstrart'];
$sContent .= '关键词:'.$aParam['keywords'];
$sContent .= '以上这篇文章是否符合'.$aJournal['zname'].'?是否具有科学前沿性和创新性?请返回中文解释';
$messages = [
[
'role' => 'user', //角色platform平台;developer:开发者user:用户;guideline:模型规范“指南”部分:连接https://model-spec.openai.com/2025-02-12.html#chain_of_command
'content' => $sContent
]
];
//请求接口
$sModel = $aParam['api_model'] ?? 'gpt-4o';
$result = $this->curlOpenAI($messages,$sModel);
if($result == FALSE){
exit(json_encode(array('status' => 4,'msg' => 'Interface request failed'.$this->sError)));
}
//处理返回信息
$data = $this->sResponesData;
if(!is_object($data)){
exit(json_encode(array('status' => 5,'msg' => 'There is a misunderstanding in the data returned by the interface')));
}
$data = object_to_array($data);
$aChoices = $data['choices'] ?? [];
if(empty($aChoices)){
exit(json_encode(array('status' => 6,'msg' => 'OPENAI did not return data')));
}
$aChoicesInfo = $aChoices[0] ?? [];
$aMessage = $aChoicesInfo['message'] ?? [];
if(empty($aMessage['content'])){
exit(json_encode(array('status' => 7,'msg' => 'OPENAI returns empty data')));
}
//执行数据入库
$param = [];
$param['content'] = addslashes($aMessage['content']);
$param['article_id'] = $aParam['article_id'];
$aResult = $this->addAiReview($param);
exit(json_encode($aResult));
}
/**
* @title AI审核内容入库
* @param article_id 文章ID
* @param content 内容
*/
protected function addAiReview($aParam = array()){
//返回数组
$aResult = ['status' => 1,'msg' => 'AI review successful','data' => $aParam];
//必填参数验证
$aFields = ['article_id','content'];
$bStatus = true;
foreach($aFields as $val){
if(empty($aParam[$val])){
$aResult = ['status' => 2,'msg' => $val.'cannot be empty'];
$bStatus = false;
break;
}
}
if($bStatus == false){
return $aResult;
}
//执行入库
$aParam['create_time'] = date('Y-m-d H:i:s');
if(!Db::name('article_ai_review')->insert($aParam)){
$aResult = ['status' => 2,'msg' => 'Failed to add AI audit content'];
}
return $aResult;
}
/**
* @title 文章AI审核内容查询
* @param article_id 文章ID
*/
public function get(){
//获取参数
$aParam = $this->request->post();
if(empty($aParam['article_id'])){
exit(json_encode(array('status' => 2,'msg' => 'Please select an article' )));
}
//查询文章
$aArticle = Db::table('t_article')->field('article_id')->where('article_id',$aParam['article_id'])->find();
if(empty($aArticle)){
exit(json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' )));
}
//查询文章审核内容
$aAiReview = Db::table('t_article_ai_review')->field('content')->where('article_id',$aParam['article_id'])->find();
exit(json_encode(array('status' => 1,'msg' => 'Successfully obtained article review content','data' => $aAiReview)));
}
public function test(){
//获取参数
$aParam = $this->request->post();
if(empty($aParam['content'])){
exit(json_encode(array('status' => 2,'msg' => '请输入需要验证的字符串' )));
}
if(!$this->checkMinChars($aParam['content'],200)){
exit(json_encode(array('status' => 3,'msg' => '字符串长度未满足配置' )));
}
exit(json_encode(array('status' => 1,'msg' => '验证成功' )));
}
/**
* 验证字符长度
* @param $str 字符串
* @param $num 字符长度
* @return void
*/
private function checkMinChars($str = '',$num = 200) {
// 过滤非汉字和英文的字符(保留汉字、大小写字母)
$filteredStr = preg_replace('/[^\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', '', $str);
// 计算有效字符总数汉字按1个字符计英文和数字同理
$total = mb_strlen($filteredStr, 'UTF-8');
return $total >= $num;
}
}