作者 李宇航

合并分支 'lyh-server' 到 'master'

Lyh server



查看合并请求 !2263
<?php
/**
* @remark :
* @name :GeoQuestionResController.php
* @author :lyh
* @method :post
* @time :2025/7/3 15:13
*/
namespace App\Console\Commands\Geo;
use App\Models\Geo\GeoPlatform;
use App\Models\Geo\GeoQuestion;
use App\Models\Geo\GeoQuestionLog;
use App\Models\Geo\GeoQuestionResult;
use App\Models\Project\Project;
use App\Services\Geo\GeoService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
class GeoQuestionRes extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'geo_question_result';
/**
* The console command description.
*
* @var string
*/
protected $description = 'geo设置请求获取结果';
public function handle(){
while (true){
$task_id = $this->getTaskId();
if(empty($task_id)){
echo '无数据'.PHP_EOL;
sleep(30);
continue;
}
$questionModel = new GeoQuestion();//问题
$info = $questionModel->read(['id'=>$task_id]);
//获取当前项目的执行频率
$projectModel = new Project();
$projectInfo = $projectModel->read(['id'=>$info['project_id']],['geo_status','geo_frequency']);
if($projectInfo['geo_status'] == 0){
$questionModel->edit(['status'=>0],['id'=>$task_id]);
continue;
}
$questionArr = $info['question'];
if(empty($questionArr)){
echo date('Y-m-d H:i:s').'当前任务不存在问题。'.PHP_EOL;
$questionModel->edit(['status'=>0],['id'=>$task_id]);
}
//获取平台信息
$platformModel = new GeoPlatform();//平台
$platformArr = $platformModel->selectField(['status'=>$platformModel::STATUS_ON],'en_name');
if(empty($platformArr)){
echo date('Y-m-d H:i:s').'请求平台为空。'.PHP_EOL;
continue;
}
$geoService = new GeoService();
$keywordArr = $info['keywords'] ?? [];
$urlArr = $info['url'] ?? [];
$geoResultModel = new GeoQuestionResult();
foreach ($questionArr as $q_item){
foreach ($platformArr as $p_item){
$keywords = [];//命中的关键词
$urls = [];//命中的网址
try {
$result_data = $geoService->setWebSearchChatAction($q_item,$p_item);
echo 'success:'.$result_data['code'].PHP_EOL;
if(isset($result_data) && $result_data['code'] == 200){
$keywords = $this->getKeywords($keywordArr,$result_data['text'] ?? []);
$urls = $this->getUrl($urlArr,$result_data['annotations'] ?? []);
}
}catch (\Exception $e){
echo $e->getMessage().PHP_EOL;
continue;
}
//查询当前是否已有执行保存记录
$resultInfo = $geoResultModel->read(['project_id'=>$info['project_id'],'question_id'=>$info['id'],'platform'=>$p_item,'question'=>$q_item],['id']);
//保存一条结果记录
$data = [
'project_id'=>$info['project_id'],
'question_id'=>$info['id'],
'platform'=>$p_item,
'question'=>$q_item,
'keywords'=>json_encode($keywords ?? [],true),//命中的关键词
'text'=>json_encode($result_data ?? [],true),
'url'=>json_encode($urls ?? [],true),//命中的网址
'type'=>$info['type'] ?? 1
];
if($resultInfo === false){
$geoResultModel->addReturnId($data);
}else{
$geoResultModel->edit($data,['id'=>$resultInfo['id']]);
}
$data_log = [
'project_id'=>$info['project_id'],
'question_id'=>$info['id'],
'platform'=>$p_item,
'question'=>$q_item,
'text'=>json_encode($result_data ?? [],true),
'type'=>$info['type'] ?? 1
];
$geoLogModel = new GeoQuestionLog();
$geoLogModel->addReturnId($data_log);
}
}
//更新下次执行时间
$questionModel->edit(['current_time'=>date('Y-m-d'),'next_time'=>date('Y-m-d', strtotime(date('Y-m-d') . ' +'.(int)$projectInfo['geo_frequency'].' days'))],['id'=>$info['id']]);
}
}
/**
* @remark :获取命中的url
* @name :getUrl
* @author :lyh
* @method :post
* @time :2025/7/3 16:38
*/
public function getUrl($urlArr = [],$result_annotations = [],$result_text = []){
$url = [];
if(!empty($urlArr)){
foreach ($urlArr as $u_item){
if(!empty($result_text)){
if (str_contains($result_text, $u_item)) {
$url[] = $u_item;
}
}
if(!empty($result_annotations)){
foreach ($result_annotations as $a_item){
echo 'url'.$a_item['url_citation']['url'].PHP_EOL.'当前的url:'.$u_item;
if (str_contains($a_item['url_citation']['url'], $u_item)) {
$url[] = $u_item;
}
}
}
}
}
return array_values(array_unique($url));
}
/**
* @remark :获取命中的关键词
* @name :getKeywords
* @author :lyh
* @method :post
* @time :2025/7/3 16:26
*/
public function getKeywords($keywordArr = [],$result_text = []){
$keywords = [];
if(!empty($keywordArr) && !empty($result_text)){
foreach ($keywordArr as $k_item){
if (str_contains($result_text, $k_item)) {
$keywords[] = $k_item;
}
}
}
return $keywords;
}
/**
* @remark :拉取任务id
* @name :getTaskId
* @author :lyh
* @method :post
* @time :2025/7/3 15:15
*/
public function getTaskId(){
$task_id = Redis::rpop('geo_question_result');
if(empty($task_id)){
$questionModel = new GeoQuestion();
$ids = $questionModel->selectField(['status'=>1,'next_time'=>['<=',date('Y-m-d')]],'id');
if(!empty($ids)){
foreach ($ids as $id) {
Redis::lpush('geo_question_result', $id);
}
}
$task_id = Redis::rpop('geo_question_result');
}
return $task_id;
}
}
... ...
... ... @@ -59,7 +59,11 @@ class GeneratePage extends Command
$noticeInfo = $noticeModel->read(['id'=>$task_id]);
try {
$this->output(' taskID: ' . $noticeInfo['id'] . ' start');
$notice_data = json_decode($noticeInfo['data'],true);
if(!is_array($noticeInfo['data'])){
$notice_data = json_decode($noticeInfo['data'],true);
}else{
$notice_data = $noticeInfo['data'];
}
$c_url = $notice_data['c_url'];
$c_params = json_encode($notice_data['c_params']);
$re = http_post($c_url, $c_params, [], true);
... ...
... ... @@ -19,14 +19,12 @@ use App\Models\News\NewsCategory;
use App\Models\Product\Category;
use App\Models\Product\Keyword;
use App\Models\Product\Product;
use App\Models\Project\Project;
use App\Models\RouteMap\RouteMap;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use PhpOffice\PhpSpreadsheet\IOFactory;
use function Aws\default_http_handler;
class UpdateProjectTdk extends Command
{
... ...
<?php
/**
* @remark :
* @name :GeoQuestionController.php
* @author :lyh
* @method :post
* @time :2025/7/2 17:42
*/
namespace App\Http\Controllers\Aside\Geo;
use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Http\Logic\Aside\Geo\GeoLogic;
use Illuminate\Http\Request;
/**
* @remark :项目geo设置
* @name :GeoQuestionController
* @author :lyh
* @method :post
* @time :2025/7/2 17:42
*/
class GeoQuestionController extends BaseController
{
public function __construct(Request $request)
{
parent::__construct($request);
$this->logic = new GeoLogic();
}
/**
* @remark :开启或关闭geo设置
* @name :setGeoStatus
* @author :lyh
* @method :post
* @time :2025/7/2 17:50
*/
public function setGeoStatus(){
$this->request->validate([
'project_id'=>'required',
'geo_status'=>'required',
'geo_frequency'=>'required',
],[
'project_id.required' => '项目ID不能为空',
'geo_status.required' => '项目开启与关闭不能为空',
'geo_frequency.required' => '项目发送频率不能为空',
]);
$data = $this->logic->setGeoStatus();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :获取类型
* @name :getType
* @author :lyh
* @method :post
* @time :2025/7/3 10:46
*/
public function getType(){
$data = $this->logic->getType();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :问题列表
* @name :getGeoQuestion
* @author :lyh
* @method :post
* @time :2025/7/3 9:09
*/
public function getGeoQuestionList(){
$this->request->validate([
'project_id'=>'required',
],[
'project_id.required' => '项目ID不能为空',
]);
$data = $this->logic->getGeoQuestionList($this->map,$this->page,$this->row,$this->order);
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :保存问题数据
* @name :saveGeoQuestion
* @author :lyh
* @method :post
* @time :2025/7/3 9:31
* @param : question->提交的问题
* @param : url->提交的网址
* @param : keywords->提交的关键字
* @param : status->状态(0:可执行 1:禁止执行)
* @param : project_id->项目id
* @param : type->类型(1:品牌 2:营销)
*/
public function saveGeoQuestion(){
$this->request->validate([
'project_id'=>'required',
'question'=>'required',
'keywords'=>'required',
'url'=>'required',
'status'=>'required',
'type'=>'required',
],[
'project_id.required' => '项目ID不能为空',
'question.required' => '项目ID不能为空',
'keywords.required' => '项目ID不能为空',
'url.required' => '项目ID不能为空',
'status.required' => '项目ID不能为空',
'type.required' => '类型不能为空',
]);
$data = $this->logic->saveGeoQuestion();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :删除问题
* @name :del
* @author :lyh
* @method :post
* @time :2025/7/3 10:11
* @param :id->主键
*/
public function delGeoQuestion(){
$this->request->validate([
'ids'=>'required|array',
],[
'ids.required' => 'ID集合不能为空',
'ids.array' => 'ID集合为数组',
]);
$data = $this->logic->delGeoQuestion();
$this->response('success',Code::SUCCESS,$data);
}
}
... ...
... ... @@ -58,8 +58,20 @@ class ComController extends BaseController
public function seo_get_menu(){
$seoMenuModel = new ProjectMenuSeo();
$this->map['status'] = 0;
$data = [];
$is_ai_blog = $this->getIsAiBlog();
if($is_ai_blog != 1){
$data[] = 57;
}
$is_ai_video = $this->getIsAiVideo();
if($is_ai_video != 1){
$data[] = 74;
}
if($this->user['login_source'] == User::LOGIN_PASSWORD_SOURCE){
$this->map['id'] = ['not in',[19]];
$data[] = 19;
}
if(!empty($data)){
$this->map['id'] = ['not in',$data];
}
$lists = $seoMenuModel->list($this->map,'sort');
$menu = array();
... ...
<?php
/**
* @remark :
* @name :GeoQuestionResController.php
* @author :lyh
* @method :post
* @time :2025/7/4 9:37
*/
namespace App\Http\Controllers\Bside\Geo;
use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Geo\GeoQuestionResLogic;
use Illuminate\Http\Request;
/**
* @remark :请求数据结果
* @name :GeoQuestionResController
* @author :lyh
* @method :post
* @time :2025/7/4 9:37
*/
class GeoQuestionResController extends BaseController
{
public function __construct(Request $request)
{
parent::__construct($request);
$this->logic = new GeoQuestionResLogic();
}
/**
* @remark :获取列表数据
* @name :getList
* @author :lyh
* @method :post
* @time :2025/7/4 9:38
*/
public function getList(){
$this->request->validate([
'project_id'=>'required',
'type'=>'required'
],[
'project_id.required' => 'project_id不能为空',
'type.required' => '品牌类型不能为空'
]);
$data = $this->logic->getResultList($this->map,$this->page,$this->row,$this->order);
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :
* @name :getInfo
* @author :lyh
* @method :post
* @time :2025/7/4 9:38
*/
public function getInfo(){
$this->request->validate([
'id'=>'required',
],[
'id.required' => 'id不能为空',
]);
$data = $this->logic->getResultInfo();
$this->response('success',Code::SUCCESS,$data);
}
}
... ...
<?php
/**
* @remark :
* @name :GeoLogic.php
* @author :lyh
* @method :post
* @time :2025/7/2 17:51
*/
namespace App\Http\Logic\Aside\Geo;
use App\Http\Logic\Aside\BaseLogic;
use App\Models\Geo\GeoPlatform;
use App\Models\Geo\GeoQuestion;
use App\Models\Project\Project;
class GeoLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->param = $this->requestAll;
$this->model = new GeoQuestion();
}
/**
* @remark :设置geo状态
* @name :setGeoStatus
* @author :lyh
* @method :post
* @time :2025/7/2 17:51
*/
public function setGeoStatus(){
$projectModel = new Project();
$data = $projectModel->edit(['geo_status'=>$this->param['geo_status'],'geo_frequency'=>$this->param['geo_frequency']],['id'=>$this->param['project_id']]);
$questionModel = new GeoQuestion();
$questionModel->edit(['status'=>$this->param['geo_status']],['project_id'=>$this->param['project_id']]);
return $this->success($data);
}
/**
* @remark :获取类型
* @name :getType
* @author :lyh
* @method :post
* @time :2025/7/3 10:47
*/
public function getType(){
$data['type'] = $this->model->brandType();
$data['frequency'] = $this->model->frequency;
$geoPlatformModel = new GeoPlatform();
$data['platform'] = $geoPlatformModel->getList();
return $this->success($data);
}
/**
* @remark :获取问题列表
* @name :getGeoQuestionList
* @author :lyh
* @method :post
* @time :2025/7/3 9:12
*/
public function getGeoQuestionList($map,$page,$row,$order,$field = ['*']){
$data = $this->model->lists($map,$page,$row,$order,$field);
if(!empty($data) && !empty($data['list'])){
foreach ($data['list'] as $key => $item){
$item['type_name'] = $this->model->brandType()[$item['type']];
$data['list'][$key] = $item;
}
}
return $this->success($data);
}
/**
* @remark :保存数据
* @name :saveGeoQuestion
* @author :lyh
* @method :post
* @time :2025/7/3 9:47
* @param : question->提交的问题
* @param : url->提交的网址
* @param : keywords->提交的关键字
* @param : project_id->项目id
*/
public function saveGeoQuestion(){
//处理数据
$this->param['question'] = json_encode($this->param['question'] ?? [],true);
$this->param['url'] = json_encode($this->param['url'] ?? [],true);
$this->param['keywords'] = json_encode($this->param['keywords'] ?? [],true);
//执行时间设置为今天
$this->param['next_time'] = date('Y-m-d');
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$this->model->edit($this->param,['id'=>$id]);
}else{
$id = $this->model->addReturnId($this->param);
}
return $this->success(['id'=>$id]);
}
/**
* @remark :删除数据
* @name :delGeoQuestion
* @author :lyh
* @method :post
* @time :2025/7/3 10:13
*/
public function delGeoQuestion(){
$data = $this->model->del(['id'=>['in',$this->param['ids']]]);
return $this->success($data);
}
}
... ...
... ... @@ -484,7 +484,7 @@ class ProjectLogic extends BaseLogic
}
$param['upload_config'] = json_encode($param['upload_config'] ?? []);
$param['web_traffic_config'] = json_encode($param['web_traffic_config'] ?? []);
unset($param['robots'],$param['is_analysis']);//项目不保存robots
unset($param['robots'],$param['is_analysis'],$param['geo_status'],$param['geo_frequency']);//项目单独保存的数据
$this->model->edit($param,['id'=>$param['id']]);
Common::del_user_cache($this->model->getTable(),$param['id']);
return $this->success();
... ...
<?php
/**
* @remark :
* @name :GeoQuestionResLogic.php
* @author :lyh
* @method :post
* @time :2025/7/4 9:47
*/
namespace App\Http\Logic\Bside\Geo;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Geo\GeoQuestionResult;
class GeoQuestionResLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->model = new GeoQuestionResult();
$this->param = $this->requestAll;
}
/**
* @remark :获取列表页数据
* @name :getResultList
* @author :lyh
* @method :post
* @time :2025/7/4 9:48
*/
public function getResultList($map = [],$page = 1,$row = 20,$order = 'id'){
$filed = ['id','project_id','question_id','platform','question','keywords','url'];
$data = $this->model->lists($map,$page,$row,$order,$filed);
return $this->success($data);
}
/**
* @remark :获取数据详情
* @name :getResultInfo
* @author :lyh
* @method :post
* @time :2025/7/4 10:19
*/
public function getResultInfo(){
$data = $this->model->read($this->param);
return $this->success($data);
}
}
... ...
<?php
/**
* @remark :
* @name :GeoPlatform.php
* @author :lyh
* @method :post
* @time :2025/7/3 11:16
*/
namespace App\Models\Geo;
use App\Models\Base;
use Illuminate\Support\Facades\Cache;
/**
* @remark :geo设置平台类型
* @name :GeoPlatform
* @author :lyh
* @method :post
* @time :2025/7/3 11:16
*/
class GeoPlatform extends Base
{
protected $table = 'gl_geo_platform';
const STATUS_ON = 1;
/**
* @remark :获取平台列表
* @name :getList
* @author :lyh
* @method :post
* @time :2025/7/3 11:18
*/
public function getList(){
// $data = Cache::get('geo_platform');
// if(empty($data)){
$data = $this->list(['status'=>$this::STATUS_ON],'id',['name','en_name','icon','sort'],'desc');
Cache::put('geo_platform',$data,'12 * 3600');
// }
return $data;
}
}
... ...
<?php
/**
* @remark :
* @name :GeoQuestion.php
* @author :lyh
* @method :post
* @time :2025/7/3 9:05
*/
namespace App\Models\Geo;
use App\Helper\Arr;
use App\Models\Base;
/**
* @remark :geo设置问题表
* @name :GeoQuestion
* @author :lyh
* @method :post
* @time :2025/7/3 9:05
*/
class GeoQuestion extends Base
{
protected $table = 'gl_geo_question';
public $frequency = [1,2,3,4,5,6,7,8,9,10];//类型
/**
* @remark :geo提交网址获取器
* @name :getUrlAttribute
* @author :lyh
* @method :post
* @time :2025/7/3 9:52
*/
public function getUrlAttribute($value)
{
if($value){
$value = Arr::s2a($value);
}
return $value;
}
/**
* @remark :geo提交问题获取器
* @name :getUrlAttribute
* @author :lyh
* @method :post
* @time :2025/7/3 9:53
*/
public function getQuestionAttribute($value)
{
if($value){
$value = Arr::s2a($value);
}
return $value;
}
/**
* @remark :geo提交关键字获取器
* @name :getUrlAttribute
* @author :lyh
* @method :post
* @time :2025/7/3 9:53
*/
public function getKeywordsAttribute($value)
{
if($value){
$value = Arr::s2a($value);
}
return $value;
}
/**
* @remark :品牌类型
* @name :brandType
* @author :lyh
* @method :post
* @time :2025/7/3 9:43
*/
public function brandType(){
return [
1=>'品牌数据',
2=>'营销数据'
];
}
}
... ...
<?php
/**
* @remark :
* @name :GeoQuestionLog.php
* @author :lyh
* @method :post
* @time :2025/7/4 9:31
*/
namespace App\Models\Geo;
use App\Models\Base;
/**
* @remark :geo设置请求日志
* @name :GeoQuestionLog
* @author :lyh
* @method :post
* @time :2025/7/4 9:32
*/
class GeoQuestionLog extends Base
{
protected $table = 'gl_geo_question_log';
}
... ...
<?php
/**
* @remark :
* @name :GeoQuestionResController.php
* @author :lyh
* @method :post
* @time :2025/7/3 16:01
*/
namespace App\Models\Geo;
use App\Helper\Arr;
use App\Models\Base;
/**
* @remark :geo设置请求结果
* @name :GeoQuestionResController
* @author :lyh
* @method :post
* @time :2025/7/3 16:01
*/
class GeoQuestionResult extends Base
{
protected $table = 'gl_geo_question_result';
/**
* @remark :geo提交关键字获取器
* @name :getUrlAttribute
* @author :lyh
* @method :post
* @time :2025/7/3 9:53
*/
public function getKeywordsAttribute($value)
{
if($value){
$value = Arr::s2a($value);
}
return $value;
}
/**
* @remark :geo提交网址获取器
* @name :getUrlAttribute
* @author :lyh
* @method :post
* @time :2025/7/3 9:52
*/
public function getUrlAttribute($value)
{
if($value){
$value = Arr::s2a($value);
}
return $value;
}
}
... ...
<?php
/**
* @remark :
* @name :GeoService.php
* @author :lyh
* @method :post
* @time :2025/7/3 14:21
*/
namespace App\Services\Geo;
class GeoService
{
public $api_key = '7yn!We6$&NnVA38bpGy*A@4TQ5iYLJcW';
public $api_url = 'https://api.cmer.com/';
/**
* @remark :请求的方法
* @name :requestAction
* @author :lyh
* @method :post
* @time :2025/7/3 14:26
*/
public function setWebSearchChatAction($content,$platform){
$route = 'v1/websearch_chat';
$url = $this->api_url.$route;
$header = [
'accept: application/json',
'X-CmerApi-Host: llm-chat.p.cmer.com',
'apikey: '.$this->api_key,
'Content-Type: application/json'
];
$message = [
'messages'=>[
[
'content'=>$content,
'role'=>'user'
],
],
'platform'=>$platform,
'security_check'=>true
];
$data = http_post($url,json_encode($message,true),$header);
return $data;
}
}
... ...
... ... @@ -553,7 +553,16 @@ Route::middleware(['aloginauth'])->group(function () {
Route::any('/', [Aside\PackDir\PackDirController::class, 'getTaskLists'])->name('admin.pack_dir_getTaskLists');
Route::any('/saveTask', [Aside\PackDir\PackDirController::class, 'saveTask'])->name('admin.pack_dir_saveTask');
});
//geo设置
Route::prefix('geo')->group(function () {
Route::any('/setGeoStatus', [Aside\Geo\GeoQuestionController::class, 'setGeoStatus'])->name('admin.geo_setGeoStatus');//开启与关闭geo设置
Route::any('/getType', [Aside\Geo\GeoQuestionController::class, 'getType'])->name('admin.geo_getType');//geo设置类型
Route::prefix('question')->group(function () {
Route::any('/getGeoQuestionList', [Aside\Geo\GeoQuestionController::class, 'getGeoQuestionList'])->name('admin.geo_question_getGeoQuestionList');
Route::any('/saveGeoQuestion', [Aside\Geo\GeoQuestionController::class, 'saveGeoQuestion'])->name('admin.geo_question_saveGeoQuestion');
Route::any('/delGeoQuestion', [Aside\Geo\GeoQuestionController::class, 'delGeoQuestion'])->name('admin.geo_question_delGeoQuestion');
});
});
// 任务相关
Route::prefix('task')->group(function () {
// FB广告相关路由
... ...
... ... @@ -748,6 +748,12 @@ Route::middleware(['bloginauth'])->group(function () {
Route::prefix('authority_score')->group(function () {
Route::any('/authorityScoreInfo', [\App\Http\Controllers\Bside\BCom\AuthorityScoreController::class,'AuthorityScoreInfo'])->name('authority_score_AuthorityScoreInfo');
});
//geo设置
Route::prefix('geo_result')->group(function () {
Route::any('/getList', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class,'getList'])->name('geo_result_getList');
Route::any('/getInfo', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class,'getInfo'])->name('geo_result_getInfo');
});
});
//无需登录验证的路由组
Route::group([], function () {
... ...