作者 刘锟

Merge remote-tracking branch 'origin/master' into akun

... ... @@ -79,6 +79,7 @@ class AiBlogAuthorTask extends Command
ProjectServer::useProject($info['project_id']);
$this->saveAiBlogAuthor($result['data'] ?? [],$info['project_id']);
RouteMap::setRoute('top-blog',RouteMap::SOURCE_AI_BLOG_LIST,0,$info['project_id']);//写一条列表页路由
RouteMap::setRoute('top-video',RouteMap::SOURCE_AI_VIDEO_LIST,0,$info['project_id']);//写一条列表页路由
DB::disconnect('custom_mysql');
//修改任务状态
$aiBlogTaskModel->edit(['status'=>2],['id'=>$info['id']]);
... ...
<?php
/**
* @remark :
* @name :AiBlogTask.php
* @author :lyh
* @method :post
* @time :2025/2/14 11:14
*/
namespace App\Console\Commands\Ai;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Ai\AiBlogList;
use App\Models\Ai\AiVideoList;
use App\Models\Domain\DomainInfo;
use App\Models\Project\ProjectAiSetting;
use App\Models\RouteMap\RouteMap;
use App\Services\AiBlogService;
use App\Services\AiVideoService;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use App\Models\Project\AiBlogTask as AiBlogTaskModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use function Symfony\Component\String\s;
/***
* @remark :根据项目更新blog列表
* @name :AiBlogListTask
* @author :lyh
* @method :post
* @time :2025/3/6 9:45
*/
class AiVideoListTask extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'save_ai_video_list {project_id}';
/**
* The console command description.
*
* @var string
*/
protected $description = '生成video列表';
public function handle(){
$project_id = $this->argument('project_id');
@file_put_contents(storage_path('logs/lyh_error.log'), var_export('执行的项目id->'.$project_id, true) . PHP_EOL, FILE_APPEND);
ProjectServer::useProject($project_id);
$this->updateBlogList($project_id);
// $this->curlDelRoute($project_id);
DB::disconnect('custom_mysql');
return true;
}
/**
* @remark :更新列表页数据
* @name :updateBlogList
* @author :lyh
* @method :post
* @time :2025/3/5 11:07
*/
public function updateBlogList($project_id){
$aiVideoService = new AiVideoService($project_id);
$page = 1;
$saveData = [];
$result = $aiVideoService->getAiVideoList($page,15);
if(!isset($result['status']) && $result['status'] != 200){
return true;
}
$total_page = $result['data']['total_page'];
//组装数据保存
$saveData[] = [
'route'=>$page,
'text'=>$result['data']['section'],
];
while ($total_page > $page){
$page++;
$result = $aiVideoService->getAiVideoList($page,15);
if(isset($result['status']) && $result['status'] == 200){
$saveData[] = [
'route'=>$page,
'text'=>$result['data']['section'],
];
}
}
$aiVideoListModel = new AiVideoList();
if(!empty($saveData)){
//写一条路由信息
$aiVideoListModel->truncate();
$aiVideoListModel->insertAll($saveData);
}
return true;
}
/**
* @remark :通知C端生成界面
* @name :sendNotice
* @author :lyh
* @method :post
* @time :2025/3/6 11:51
*/
public function curlDelRoute($project_id){
$domainModel = new DomainInfo();
//获取项目域名
$domain = $domainModel->getProjectIdDomain($project_id);
if(!empty($domain)){
$c_url = $domain.'api/update_page/';
$param = [
'project_id' => $project_id,
'type' => 1,
'route' => 3,
'url' => ['top-blog'],
'language'=> [],
'is_sitemap' => 0
];
http_post($c_url, json_encode($param));
}
return true;
}
}
... ...
... ... @@ -9,9 +9,18 @@
namespace App\Console\Commands\Ai;
use App\Helper\Arr;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Ai\AiVideo;
use App\Models\Ai\AiVideoList;
use App\Models\Com\Notify;
use App\Models\Devops\ServerConfig;
use App\Models\Devops\ServersIp;
use App\Models\Domain\DomainInfo;
use App\Models\Project\AiVideoTask as AiVideoTaskModel;
use App\Models\Project\Project;
use App\Models\RouteMap\RouteMap;
use App\Services\AiBlogService;
use App\Services\AiVideoService;
use App\Services\DingService;
use App\Services\ProjectServer;
... ... @@ -30,14 +39,12 @@ class AiVideoTask extends Command
public $updateProject = [];//需更新的列表
public $routes = [];//需要更新的路由
/**
* The console command description.
*
* @var string
*/
protected $description = '查询ai_video是否已经生成';
/**
* @return bool
* @throws \Exception
... ... @@ -64,14 +71,14 @@ class AiVideoTask extends Command
{
$task_id = Redis::rpop('ai_video_task');
if (empty($task_id)) {
// if(!empty($this->updateProject)){
// $this->updateProject($this->updateProject);
// $this->updateProject = [];
// }
// if(!empty($this->routes)){
if(!empty($this->updateProject)){
$this->updateProject($this->updateProject);
$this->updateProject = [];
}
if(!empty($this->routes)){
// $this->updateRoutes($this->routes);
// $this->routes = [];
// }
$this->routes = [];
}
$aiVideoTaskModel = new AiVideoTaskModel();
$finish_at = date('Y-m-d H:i:s', strtotime('-' . $finish_at . ' hour'));
$ids = $aiVideoTaskModel->formatQuery(['status'=>$aiVideoTaskModel::STATUS_RUNNING,'updated_at'=>['<=',$finish_at]])->pluck('id');
... ... @@ -152,6 +159,13 @@ class AiVideoTask extends Command
'status'=>$aiVideoTaskModel::STATUS_FINISH
];
$aiVideoModel->edit($saveData,['task_id'=>$item['task_id']]);
//需要更新的路由
if (!in_array($result['data']['author_id'], $this->updateProject[$item['project_id']] ?? [])) {
$this->updateProject[$item['project_id']][] = $result['data']['author_id'];
}
if (!in_array($route, $this->routes[$item['project_id']] ?? [])) {
$this->routes[$item['project_id']][] = $route;
}
DB::disconnect('custom_mysql');
$aiVideoTaskModel->edit(['status'=>$aiVideoTaskModel::STATUS_FINISH],['id'=>$item['id']]);
$this->output('success: task id: ' . $task_id);
... ... @@ -159,6 +173,103 @@ class AiVideoTask extends Command
}
/**
* @remark :更新项目作者页面及列表页
* @name :updateProject
* @author :lyh
* @method :post
* @time :2025/4/30 15:43
*/
public function updateProject($updateProject){
if(empty($updateProject)){
return true;
}
foreach ($updateProject as $project_id => $author){
ProjectServer::useProject($project_id);
$this->output('sync: list start, project_id: ' . $project_id);
$this->updateBlogList($project_id);
$this->output('sync: list end');
//更新作者
$this->output('sync: author start, project_id: ' . $project_id);
foreach ($author as $val){
$this->updateAiBlogAuthor($val,$project_id);
}
$this->output('sync: author end');
DB::disconnect('custom_mysql');
}
return true;
}
/**
* @remark :更新作者页面
* @name :updateAiBlogAuthor
* @author :lyh
* @method :post
* @time :2025/4/30 15:52
*/
public function updateAiBlogAuthor($author_id,$project_id){
if(empty($author_id)){
return true;
}
$aiBlogService = new AiBlogService($project_id);
$aiBlogService->author_id = $author_id;
$result = $aiBlogService->getAuthorDetail();
if(isset($result['status']) && $result['status'] == 200){
//当前作者的页面
$aiBlogAuthorModel = new AiBlogAuthor();
$authorInfo = $aiBlogAuthorModel->read(['author_id'=>$author_id],['id','route']);
if($authorInfo !== false && !empty($result['data']['section'])){
//需要更新的路由
if (!in_array($authorInfo['route'], $this->routes[$project_id] ?? [])) {
$this->routes[$project_id][] = $authorInfo['route'];
}
$aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$author_id]);
}
}
return true;
}
/**
* @remark :更新
* @name :updateBlogList
* @author :lyh
* @method :post
* @time :2025/4/30 15:45
*/
public function updateBlogList($project_id){
$aiVideoService = new AiVideoService($project_id);
$page = 1;
$saveData = [];
$result = $aiVideoService->getAiVideoList($page,15);
if(!isset($result['status']) && $result['status'] != 200){
return true;
}
$total_page = $result['data']['total_page'];
//组装数据保存
$saveData[] = [
'route'=>$page,
'text'=>$result['data']['section'],
];
while ($total_page > $page){
$page++;
$result = $aiVideoService->getAiVideoList($page,15);
if(isset($result['status']) && $result['status'] == 200){
$saveData[] = [
'route'=>$page,
'text'=>$result['data']['section'],
];
}
}
$aiVideoListModel = new AiVideoList();
if(!empty($saveData)){
//写一条路由信息
RouteMap::setRoute('top-video',RouteMap::SOURCE_AI_VIDEO_LIST,0,$project_id);//写一条列表页路由
$aiVideoListModel->truncate();
$aiVideoListModel->insertAll($saveData);
}
return true;
}
/**
* 输入日志
* @param $message
* @return bool
... ... @@ -169,4 +280,64 @@ class AiVideoTask extends Command
echo $message;
return true;
}
/**
* 通知C端生成界面
* @param $project_id
* @return bool
*/
public function updateRoutes($routes){
$domainModel = new DomainInfo();
$project_model = new Project();
foreach ($routes as $project_id => $route){
$route[] = 'top-video';
$domain = $domainModel->getProjectIdDomain($project_id);
if (empty($domain)) {
$this->output('send: 域名不存在, project id: ' . $project_id);
continue;
}
//判断是否是自建站服务器,如果是,不请求C端接口,数据直接入库
$project_info = $project_model->read(['id'=>$project_id],['serve_id']);
if(!$project_info){
$this->output('send: 项目不存在, project id: ' . $project_id);
continue;
}
$serve_ip_model = new ServersIp();
$serve_ip_info = $serve_ip_model->read(['id'=>$project_info['serve_id']],['servers_id']);
$servers_id = $serve_ip_info ? $serve_ip_info['servers_id'] : 0;
if($servers_id == ServerConfig::SELF_SITE_ID){
//判断是否已有更新进行中
$notify_model = new Notify();
$data = [
'project_id' => $project_id,
'type' => Notify::TYPE_MASTER,
'route' => Notify::ROUTE_AI_BLOG,
'server_id' => ServerConfig::SELF_SITE_ID,
'status' => ['!=',Notify::STATUS_FINISH_SITEMAP]
];
$notify = $notify_model->read($data,['id']);
if(!$notify){
$domain_array = parse_url($domain);
$data['data'] = Arr::a2s(['domain'=>$domain_array['host'],'url'=>$route,'language'=>[]]);
$data['status'] = Notify::STATUS_INIT;
$data['sort'] = 2;
$notify_model->add($data);
}
$this->output('send: 自建站项目, project id: ' . $project_id);
}else{
$c_url = $domain.'api/update_page/';
$param = [
'project_id' => $project_id,
'type' => 1,
'route' => 3,
'url' => $route,
'language'=> [],
'is_sitemap' => 0
];
$res = http_post($c_url, json_encode($param,true));
$this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}
}
return true;
}
}
... ...
<?php
/**
* @remark :
* @name :CropImage.php
* @author :lyh
* @method :post
* @time :2025/5/8 9:19
*/
namespace App\Console\Commands\CropImage;
use App\Enums\Common\Code;
use App\Models\Domain\DomainInfo;
use App\Models\File\Image;
use App\Models\WebSetting\AggregationSetting;
use App\Models\WebSetting\WebSettingImage;
use App\Services\CosService;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class CropImage extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'crop_image {project_id}';
/**
* The console command description.
*
* @var string
*/
protected $description = '裁剪图片';
public function handle(){
echo '测试裁剪->cs-crop:'.PHP_EOL;
$project_id = $this->argument('project_id');
ProjectServer::useProject($project_id);
$data = $this->_keywordAction($project_id);
$this->_aiAction($project_id,$data[0] ?? []);
DB::disconnect('custom_mysql');
}
/**
* @remark :执行的方法
* @name :_action
* @author :lyh
* @method :post
* @time :2025/5/8 9:21
*/
public function _keywordAction($project_id){
$resData = [];
//聚合页裁剪
$data = $this->getKeywordImage($project_id);
$cosService = new CosService();
if(!empty($data)){
foreach ($data as $val){
//处理图片为相对路径
$image = str_replace_url($val);
$height = $cosService->getImageHeight($image);
if(empty($height)){
echo '未获取到图片高度。'.PHP_EOL;
continue;
}
echo '返回的图片高度:'.$height.PHP_EOL;
if($height > 220){
$result = $cosService->cropCosImage($image);
if(empty($result)){
continue;
}
$resData[] = $result['path'];
$this->saveMysql($project_id,$result['size'],$result['type'],$result['path'],$result['mime']);
}else{
$resData[] = $image;
}
}
}
$this->saveAggregationSetting($project_id,$resData);
return $resData;
}
/**
* @remark :ai执行方法
* @name :_aiAction
* @author :lyh
* @method :post
* @time :2025/5/8 16:12
*/
public function _aiAction($project_id,$keywordImage){
$cosService = new CosService();
//ai_blog裁剪
$ai_image = $this->getAiBlogImage($project_id,$keywordImage ?? []);
if(empty($ai_image)){
echo '当前图片不需要裁剪。'.PHP_EOL;
return true;
}
$height = $cosService->getImageHeight($ai_image);
if(empty($height)){
echo '未获取到AI_BLOG图片高度。'.PHP_EOL;
return true;
}
echo '返回的图片高度:'.$height.PHP_EOL;
if($height > 220){
$result = $cosService->cropCosImage($ai_image);
if(empty($result)){
return true;
}
$this->saveMysql($project_id,$result['size'],$result['type'],$result['path'],$result['mime']);
$webSettingImageModel = new WebSettingImage();
$webSettingImageModel->edit(['image'=>$result['path']],['project_id' => $project_id, 'type' => 4]);
}
return true;
}
/**
* @remark :保存数据
* @name :saveAggregationSetting
* @author :lyh
* @method :post
* @time :2025/5/8 16:24
*/
public function saveAggregationSetting($project_id,$data){
if(empty($data)){
return true;
}
//存全路径
foreach ($data as $key => $val){
$val = getImageUrl($val);
$data[$key] = $val;
}
$aggregationSettingModel = new AggregationSetting();
$info = $aggregationSettingModel->read(['project_id'=>$project_id]);
if($info === false){
$aggregationSettingModel->addReturnId(['project_id'=>$project_id,'top_banner'=>json_encode($data,true)]);
}else{
$aggregationSettingModel->edit(['top_banner'=>json_encode($data,true)],['id'=>$info['id']]);
}
return true;
}
/**
* @remark :获取aiBlog图片
* @name :getAiBlogImage
* @author :lyh
* @method :post
* @time :2025/5/8 10:42
*/
public function getAiBlogImage($project_id,$keywordImage){
// AI博客banner type:1:产品,2:博客,3:新闻,4:AIBlog
$webSettingImageModel = new WebSettingImage();
$aiBlogInfo = $webSettingImageModel->read(['project_id' => $project_id, 'type' => 4],['image']);
if($aiBlogInfo === false && !empty($keywordImage)){
$webSettingImageModel->addReturnId(['project_id'=>$project_id,'image'=>$keywordImage,'type'=>4]);
return '';
}
if(empty($aiBlogInfo['image']) && !empty($keywordImage)){
$webSettingImageModel->edit(['image'=>$keywordImage],['id'=>$aiBlogInfo['id']]);
return '';
}
$ai_image = str_replace_url($aiBlogInfo['image']);
return $ai_image;
}
/**
* @remark :获取聚合页图片
* @name :getImage
* @author :lyh
* @method :post
* @time :2025/5/8 9:21
*/
public function getKeywordImage($project_id){
$data = [];
// 聚合页banner
$aggregationSettingModel = new AggregationSetting();
$aggregationSettingInfo = $aggregationSettingModel->read(['project_id' => $project_id],['id','top_banner']);
if($aggregationSettingInfo !== false && !empty($aggregationSettingInfo['top_banner'])){
foreach ($aggregationSettingInfo['top_banner'] as $val){
if($val != 'jpg' && $val != 'png' && $val != 'webp'){
$data[] = $val;
}
}
}
if(empty($data)){
//重页面上获取首页banner
$data = $this->getDomImage($project_id);
}
return $data;
}
/**
* @remark :页面上获取图片
* @name :getDomImage
* @author :lyh
* @method :post
* @time :2025/5/8 10:32
*/
public function getDomImage($project_id){
$data = [];
echo '获取首页banner:' . $project_id . PHP_EOL;
$domainModel = new DomainInfo();
$domainInfo = $domainModel->read(['project_id' => $project_id, 'status' => 1]);
if ($domainInfo !== false) {
$dom = @file_get_html('https://' . $domainInfo['domain'] . '/');
if (empty($dom)) {
$this->output('获取HTML失败: ' . $project_id);
}else{
$banner_dom = $dom->find('main .section-banner-wrap-block img', 0);
$data[] = $banner_dom ? $banner_dom->src : '';
$dom->clear();
unset($dom);
}
}else{
$this->output('域名不存在: ' . $project_id);
}
return $data;
}
/**
* @remark :写入数据库
* @name :saveMysql
* @author :lyh
* @method :post
* @time :2025/5/8 14:59
*/
public function saveMysql($project_id,$size,$image_type,$path,$mime = ''){
$hash = md5($path);
$imageModel = new Image();
$info = $imageModel->read(['hash'=>$hash,'project_id'=>$project_id]);
$data = [
'path' => $path,
'size' => $size,
'hash' => $hash,
'type' => $image_type,
'refer'=> 0,
'mime' => $mime,
'project_id'=>$project_id,
'name'=>basename($path),
'en_name'=>basename($path)
];
if($info === false){
$imageModel->addReturnId($data);
}else{
$imageModel->edit($data,['id'=>$info['id']]);
}
return true;
}
/**
* @remark :记录日志
* @name :output
* @author :lyh
* @method :post
* @time :2025/5/8 9:57
*/
public function output($message, $log_file = 'logs/crop_image.log')
{
$message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
echo $message;
file_put_contents(storage_path($log_file), $message, FILE_APPEND);
return true;
}
}
... ...
... ... @@ -61,7 +61,7 @@ class AfterDayCount extends Command
$this->managerHrModel = new ManageHr();
$projectModel = new Project();
$rankDataLogModel = new RankDataLog();
$todayMidnight = date('Y-m-d 00:00:00', strtotime('today'));
$todayMidnight = date('Y-m-d', strtotime('today'));
$saveData = [];
$projectIdArr = $rankDataLogModel->selectField(['is_compliance'=>1,'lang'=>'','date'=>date('Y-m-d', strtotime('-3 months'))],'project_id');//3个月前达标的项目id
foreach ($this->after_manager as $key => $valM){
... ... @@ -69,9 +69,9 @@ class AfterDayCount extends Command
$project_count = $projectModel->where('gl_project.extend_type',0)
->where('gl_project.delete_status',0)
->where('gl_project.old_project_id',0)
->where('gl_project.created_at','<=',$todayMidnight)
->where('gl_project_deploy_optimize.start_date','<=',$todayMidnight)
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->whereIn('gl_project.type',[2,4,6])
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0")
->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0")
... ... @@ -79,24 +79,25 @@ class AfterDayCount extends Command
$qualified_count = $projectModel->where('gl_project.extend_type',0)
->where('gl_project.delete_status',0)
->where('gl_project.old_project_id',0)
->where('gl_project.created_at','<=',$todayMidnight)
->where('gl_project_deploy_optimize.start_date','<=',$todayMidnight)
->where('gl_project.is_remain_today',1)
->where('gl_project_deploy_build.plan','!=',0)
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->whereIn('gl_project.type',[2,4,6])
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id')
->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0")
->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0")
->count();
$rate = number_format($qualified_count / $project_count, 2);
$threeMonthsAgo = date('Y-m-d 00:00:00', strtotime('-3 months'));
$threeMonthsAgo = date('Y-m', strtotime('-3 months'));
$three_project_count = $projectModel->where('gl_project.extend_type',0)
->where('gl_project.delete_status',0)
->where('gl_project.old_project_id',0)
->where('gl_project.created_at','<=',$threeMonthsAgo)
->where('gl_project_deploy_optimize.start_date','>=',$threeMonthsAgo.'-01')
->where('gl_project_deploy_optimize.start_date','<=',$threeMonthsAgo.'-31')
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->whereIn('gl_project.type',[2,4,6])
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0")
->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0")
... ... @@ -105,26 +106,31 @@ class AfterDayCount extends Command
->whereIn('gl_project.id',$projectIdArr)
->where('gl_project.delete_status',0)
->where('gl_project.old_project_id',0)
->where('gl_project.created_at','<=',$threeMonthsAgo)
->where('gl_project_deploy_optimize.start_date','>=',$threeMonthsAgo.'-01')
->where('gl_project_deploy_optimize.start_date','<=',$threeMonthsAgo.'-31')
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->whereIn('gl_project.type',[2,4,6])
->where('gl_project_deploy_build.plan','!=',0)
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id')
->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0")
->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0")
->count();
if($three_project_count != 0){
$three_rate = number_format($three_qualified_count / $three_project_count, 2);
}else{
$three_rate = 0;
}
$data = $projectModel->where('gl_project.extend_type',0)
->where('gl_project.delete_status',0)
->where('gl_project.created_at','<=',$todayMidnight)
->where('gl_project_deploy_optimize.start_date','<=',$todayMidnight)
->where('gl_project.is_remain_today',1)
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->whereIn('gl_project.type',[2,4,6])
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
->whereRaw("FIND_IN_SET('2', gl_project.level) = 0 AND FIND_IN_SET('3', gl_project.level) = 0")
->whereRaw("FIND_IN_SET('7', gl_project_deploy_optimize.special) = 0 AND FIND_IN_SET('8', gl_project_deploy_optimize.special) = 0")
->pluck('gl_project.title')->toArray();
->select(['gl_project.title','gl_project.finish_remain_day','gl_project_deploy_optimize.start_date'])->get()->toArray();
$saveData[] = [
'date'=>date('Y-m-d', strtotime('yesterday')),
'type'=> $key,
... ...
... ... @@ -290,6 +290,7 @@ class postInquiry extends Command
Log::channel('inquiry_relay')->error('inquiry_relay shop inquiry error', [$res, $url, $data]);
return false;
}
return true;
}
public function FobInquiry($detail, $log){
... ... @@ -309,6 +310,7 @@ class postInquiry extends Command
Log::channel('inquiry_relay')->error('inquiry_relay fob inquiry error', [$res, 'https://fob.ai.cc/api/ad_to_scrm', $data]);
return false;
}
return true;
}
public function output($message)
... ...
... ... @@ -52,9 +52,9 @@ class LyhImportTest extends Command
* @time :2023/11/20 15:13
*/
public function handle(){
ProjectServer::useProject(3283);
ProjectServer::useProject(2140);
echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
$this->importProductCategory('https://ecdn6.globalso.com/upload/p/3283/file/2025-04/zhouyongpaxu.csv',3283);
$this->import2140CustomModule('https://ecdn6.globalso.com/upload/p/2140/file/2025-05/all-202557.csv',2140);
DB::disconnect('custom_mysql');
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
}
... ... @@ -463,7 +463,7 @@ class LyhImportTest extends Command
foreach ($line_of_text as $k => $item){
// try {
//添加内容
$contentId = $customContentModel->addReturnId(['name'=>$item[0],'image'=>'/upload/p/2140/image/'.$item[2],'module_id'=>2,'project_id'=>$project_id]);
$contentId = $customContentModel->addReturnId(['name'=>$item[0],'image'=>'/upload/p/2140/image/'.$item[2],'module_id'=>7,'project_id'=>$project_id]);
echo date('Y-m-d H:i:s') . '当前扩展数据id:'. $contentId . PHP_EOL;
//注册路由
$route = RouteMap::setRoute($item[0], RouteMap::SOURCE_MODULE,
... ...
... ... @@ -82,11 +82,13 @@ class UpdateRoute extends Command
$projectModel = new Project();
$lists = $projectModel->list(['delete_status' => 0,'extend_type'=>0,'type'=>['in',[1,2,3,4]]], 'id', ['id']);
foreach ($lists as $val) {
echo date('Y-m-d H:i:s') . '开始--项目的id:'. $val['id'] . PHP_EOL;
// echo date('Y-m-d H:i:s') . '开始--项目的id:'. $val['id'] . PHP_EOL;
ProjectServer::useProject($val['id']);
$aiBlogModel = new AiBlogAuthor();
$results = $aiBlogModel->whereColumn('title', '!=', 'seo_title')->get();
echo '项目id:'.json_encode($results,true).PHP_EOL;
if(!$results){
$aiBlogModel->edit(['seo_title'=>'','seo_keyword'=>'','seo_description'=>''],['id'=>['>',0]]);
echo '项目id:'.$val['id'].PHP_EOL;
}
DB::disconnect('custom_mysql');
... ...
... ... @@ -56,6 +56,8 @@ class SyncMobile extends Command
if(!empty($data)){
$userModel = new User();
try {
$data[] = '13083988828';
$data[] = '6591559603';
$userModel->edit(['status'=>1],['project_id'=>1,'mobile'=>['not in',$data]]);
$userModel->edit(['status'=>0],['project_id'=>1,'mobile'=>['in',$data]]);
}catch (\Exception $e){
... ...
... ... @@ -16,6 +16,7 @@ use App\Models\Domain\DomainInfo;
use App\Models\HomeCount\Count;
use App\Models\HomeCount\MonthCount;
use App\Models\Inquiry\InquiryFormData;
use App\Models\Inquiry\InquiryRelateDomain;
use App\Models\Project\Project;
use App\Models\RankData\ExternalLinks;
use App\Models\RankData\IndexedPages;
... ... @@ -290,7 +291,9 @@ class OptimizationReportController extends BaseController
//复制站点域名
$ext_projects = $this->getExtendProjects();
$flg_ext = $this->getExtFlag($ext_projects, $domain, $api_no);
$ext_domain = str_replace('www.', '', $this->getExtendProjects($api_no)['ext'] ?? '');
$ext_domain = str_replace('www.', '', $this->getExtendProjects($api_no)['ext'] ?? '');//关联域名
//关联域名
$relate_domain = str_replace('www.', '', InquiryRelateDomain::getRelateDomain($domain, 'globalso_domain'));
//AI站点域名
$ai_projects = $this->getAiProjects()['data'] ?? [];
$flg_ai = $this->getAiFlag($ai_projects, $domain);
... ... @@ -316,6 +319,8 @@ class OptimizationReportController extends BaseController
$domain_text = '星链域名:' . $ai_domain;
} else if ($last['r'] == $ext_domain) {
$domain_text = '主域名2:' . $ext_domain;
} else if ($last['r'] == $relate_domain) {
$domain_text = '主域名2:' . $relate_domain;
} else {
$domain_text = 'AI域名:' . $last['r'];
}
... ...
... ... @@ -13,11 +13,13 @@ use App\Models\Ai\AiBlog;
use App\Models\Blog\Blog;
use App\Models\Domain\DomainInfo;
use App\Models\Inquiry\InquiryRelateDomain;
use App\Models\Manage\ManageHr;
use App\Models\News\News;
use App\Models\Product\Category;
use App\Models\Product\CategoryRelated;
use App\Models\Product\Keyword;
use App\Models\Product\Product;
use App\Models\Project\DeployBuild;
use App\Models\Project\DeployOptimize;
use App\Models\Project\OnlineCheck;
use App\Models\Project\Project;
... ... @@ -491,4 +493,49 @@ class PrivateController extends BaseController
return $this->success($relate);
}
/**
* 根据域名获取项目人员配置信息
* @param Request $request
* @return false|string
*/
public function getProjectManageByDomain(Request $request)
{
$domain = trim($request->input('domain'));
$domain_parse = parse_url($domain);
$domain = $domain_parse['host'] ?? $domain;
if (empty($domain)) {
return $this->error('非法参数!');
}
$project = Project::getProjectByDomain($domain);
if (empty($project)) {
return $this->error('未找到当前域名对应的项目!');
}
$build = DeployBuild::select(['leader_mid', 'manager_mid', 'designer_mid', 'tech_mid'])->where(['project_id' => $project->id])->first();
$optimize = DeployOptimize::select(['manager_mid', 'optimist_mid', 'assist_mid', 'tech_mid', 'tech_leader', 'quality_mid', 'design_mid'])->where(['project_id' => $project->id])->first();
$build = $build ? $build->toArray() : [];
$optimize = $optimize ? $optimize->toArray() : [];
$manage_ids = array_merge(array_values($build), array_values($optimize));
$member = ManageHr::whereIn('id', $manage_ids)->pluck('name', 'id')->toArray();
$result = [
'build_leader' => $build && $build['leader_mid'] ? $member[$build['leader_mid']] : '', // 组长
'build_manager' => $build && $build['manager_mid'] ? $member[$build['manager_mid']] : '', // 项目经理
'build_designer' => $build && $build['designer_mid'] ? $member[$build['designer_mid']] : '', // 设计师
'build_tech' => $build && $build['tech_mid'] ? $member[$build['tech_mid']] : '', // 技术助理
'optimize_manager' => $optimize && $optimize['manager_mid'] ? $member[$optimize['manager_mid']] : '', // 优化经理
'optimize_optimist' => $optimize && $optimize['optimist_mid'] ? $member[$optimize['optimist_mid']] : '',// 优化师
'optimize_assist' => $optimize && $optimize['assist_mid'] ? $member[$optimize['assist_mid']] : '', // 优化师助理
'optimize_tech' => $optimize && $optimize['tech_mid'] ? $member[$optimize['tech_mid']] : '', // 售后技术
'optimize_leader' => $optimize && $optimize['tech_leader'] ? $member[$optimize['tech_leader']] : '', // 售后主管
'optimize_quality' => $optimize && $optimize['quality_mid'] ? $member[$optimize['quality_mid']] : '', // 品控
'optimize_design' => $optimize && $optimize['design_mid'] ? $member[$optimize['design_mid']] : '', // 平面设计
];
return $this->success($result);
}
}
... ...
... ... @@ -7,6 +7,7 @@ use App\Helper\Translate;
use App\Models\Product\Category;
use App\Models\Product\CategoryRelated;
use App\Models\Product\Product;
use App\Models\Project\ProjectAiSetting;
use App\Models\RouteMap\RouteMap;
use App\Services\CosService;
use App\Services\ProjectServer;
... ... @@ -251,4 +252,30 @@ class ProductController extends BaseController
return $suggestions;
}
/**
* 搜索给AI博客 产品推荐用
* 全文搜索 产品标题
* @author zbj
* @date 2025/5/8
*/
public function searchProductToAiBlog(Request $request){
$mch_id = $request->input('mch_id');
$key = $request->input('key');
$keyword = $request->input('keyword');
if(!$keyword){
$this->response('关键词不能为空', Code::SYSTEM_ERROR);
}
$project_id = ProjectAiSetting::where('mch_id', $mch_id)->where('key', $key)->value('project_id');
if(!$project_id){
$this->response('项目不存在', Code::SYSTEM_ERROR);
}
ProjectServer::useProject($project_id);
$product = Product::whereFullText('title', $keyword)->inRandomOrder()->select(['title', 'intro', 'thumb'])->first();
$this->response('success', Code::SUCCESS, $product?:[]);
}
}
... ...
... ... @@ -48,6 +48,9 @@ class AiBlogController extends BaseController
'id.required' => '主键不能为空',
]);
$info = $aiBlog->read(['id'=>$this->param['id']]);
if(!empty($info['anchor'])){
$info['anchor'] = json_decode($info['anchor'],true);
}
$info['image'] = getImageUrl($info['image']);
$this->response('success',Code::SUCCESS,$info);
}
... ... @@ -79,13 +82,32 @@ class AiBlogController extends BaseController
* @method :post
* @time :2023/7/5 14:33
*/
public function save(AiBlogRequest $aiBlogRequest,AiBlogLogic $aiBlogLogic){
$aiBlogRequest->validated();
public function save(AiBlogLogic $aiBlogLogic){
// $aiBlogRequest->validated();
$aiBlogLogic->blogSave();
$this->response('success');
}
/**
* @remark :
* @name :saveText
* @author :lyh
* @method :post
* @time :2025/4/30 18:05
*/
public function saveText(AiBlogLogic $aiBlogLogic){
$this->request->validate([
'id'=>['required'],
'text'=>['required'],
],[
'id.required' => '关键字不能为空',
'text.required' => '场景不能为空',
]);
$aiBlogLogic->blogSaveText();
$this->response('success');
}
/**
* @remark :获取作者列表
* @name :getAiBlogAuthor
* @author :lyh
... ...
... ... @@ -13,6 +13,7 @@ use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Ai\AiVideoLogic;
use App\Models\Ai\AiVideo;
use App\Models\Ai\AiVideoList;
class AiVideoController extends BaseController
{
... ... @@ -51,6 +52,8 @@ class AiVideoController extends BaseController
'id.required' => '主键不能为空',
]);
$info = $aiVideo->read(['id'=>$this->param['id']]);
$info['anchor'] = json_decode($info['anchor'] ?? [],true);
$info['images'] = json_decode($info['images'] ?? [],true);
$this->response('success',Code::SUCCESS,$info);
}
... ... @@ -109,4 +112,40 @@ class AiVideoController extends BaseController
$result = $aiVideoLogic->videoDelete();
$this->response('success',Code::SUCCESS,$result);
}
/**
* @remark :获取列表页数据
* @name :getAiBlogList
* @author :lyh
* @method :post
* @time :2025/2/21 16:22
*/
public function getAiVideoList(AiVideoList $aiVideoList){
$lists = $aiVideoList->lists($this->map,$this->page,$this->row,'id',['id','route','created_at','updated_at']);
if(!empty($lists) && !empty($lists['list'])){
foreach ($lists['list'] as $k => $v){
$v['route'] = $this->user['domain'] . 'top-video/' . (($v['route'] > 1) ? $v['route'] : '');
$lists['list'][$k] = $v;
}
}
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :获取列表页数据详情
* @name :getAiBlogListInfo
* @author :lyh
* @method :post
* @time :2025/2/21 16:26
*/
public function getAiBlogListInfo(AiVideoList $aiVideoList){
$this->request->validate([
'id'=>['required'],
],[
'id.required' => '主键不能为空',
]);
$info = $aiVideoList->read($this->map);
$this->response('success',Code::SUCCESS,$info);
}
}
... ...
... ... @@ -147,6 +147,10 @@ class ComController extends BaseController
if($is_blogs != 1){
$info['role_menu'] = trim(str_replace(',57,',',',','.$info['role_menu'].','),',');
}
$is_video = $this->getIsAiVideo();
if($is_video != 1){
$info['role_menu'] = trim(str_replace(',74,',',',','.$info['role_menu'].','),',');
}
$this->map = [
'status'=>0,
'is_role'=>0,
... ... @@ -195,6 +199,10 @@ class ComController extends BaseController
if($is_ai_blog != 1){
$data[] = 57;
}
$is_ai_video = $this->getIsAiVideo();
if($is_ai_video != 1){
$data[] = 74;
}
if(!empty($data)){
$this->map['id'] = ['not in',$data];
}
... ... @@ -291,6 +299,16 @@ class ComController extends BaseController
return $this->user['is_ai_blog'] ?? 0;
}
/**
* @remark :ai视频
* @name :getIsAiVideo
* @author :lyh
* @method :post
* @time :2025/5/6 14:33
*/
public function getIsAiVideo(){
return $this->user['is_ai_video'] ?? 0;
}
/**
* @name :登录用户编辑资料/修改密码
... ...
... ... @@ -43,16 +43,6 @@ class TestController extends BaseController
* @time :2025/2/13 16:34
*/
public function ceshi(){
$this->param = [
'title'=>'apple',
'description'=>'apples',
'images'=>[
['url'=>'https://ecdn6.globalso.com/upload/public/template/64e332671b32e25328.png','title'=>'apple'],
['url'=>'https://ecdn6.globalso.com/upload/public/template/64e32a24b314a39425.png','title'=>'apples'],
],
];
$aiVideoService = new AiVideoService(467);
$result = $aiVideoService->createTask($this->param['title'],$this->param['description'],$this->param['images'],$this->param['anchor'] ?? []);
$this->response('success',Code::SUCCESS,$result);
$this->response('success',Code::SUCCESS,[]);
}
}
... ...
... ... @@ -166,7 +166,7 @@ class ProjectLogic extends BaseLogic
}else{
$this->param = $this->handleLevelStr($this->param);//处理星级客户暂停优化默认参数
$this->saveSeoPlan($this->param);//保存seo白帽类型,上线保存一条审核记录
$this->checkAiBlog($this->param);//开启白帽验证参数
$this->checkAiBlog($this->param);//开启ai相关功能验证参数
DB::beginTransaction();
try {
//初始化项目
... ... @@ -174,8 +174,9 @@ class ProjectLogic extends BaseLogic
//双向绑定服务器,需放到保存项目的上方
$this->setServers($this->param['serve_id'],$this->param['id']);
//ai_blog
$this->setAiBlog($this->param['id'],$this->param['main_lang_id'],$this->param['is_ai_blog'],
$this->param['company']??"", $this->param['deploy_optimize']['company_en_name'] ?? '',$this->param['deploy_optimize']['company_en_description'] ?? '');
$this->setAiBlog($this->param['id'],$this->param['main_lang_id'],$this->param['is_ai_blog'] ?? 0,
$this->param['company']??"", $this->param['deploy_optimize']['company_en_name'] ?? '',
$this->param['deploy_optimize']['company_en_description'] ?? '',$this->param['is_ai_video'] ?? 0);
//保存项目信息
$this->saveProject($this->param);
//保存建站部署信息
... ... @@ -217,6 +218,7 @@ class ProjectLogic extends BaseLogic
if (in_array('2', $param['level']) || in_array('3', $param['level'])) {
//优化设置默认关闭
$param['is_ai_blog'] = 0;
$param['is_ai_video'] = 0;
$param['deploy_optimize']['is_ai_blog_send'] = 0;
$param['deploy_optimize']['is_auto_keywords'] = 0;
}
... ... @@ -259,7 +261,7 @@ class ProjectLogic extends BaseLogic
}
/**
* @remark :开启白帽验证参数
* @remark :开启ai博客及视频
* @name :checkAiBlog
* @author :lyh
* @method :post
... ... @@ -272,7 +274,7 @@ class ProjectLogic extends BaseLogic
$company = $param['company'] ?? '';
$company_en_name = $param['deploy_optimize']['company_en_name'] ?? '';
$company_en_description = $param['deploy_optimize']['company_en_description'] ?? '';
if($is_ai_blog == 1 || $is_ai_video){
if($is_ai_blog == 1 || $is_ai_video == 1){
if(empty($main_lang_id) || empty($company) || empty($company_en_name) || empty($company_en_description)){
$this->fail('开启ai博客/视频功能--请填写主语种+公司名称+公司英文名称+公司英文介绍');
}
... ... @@ -287,11 +289,11 @@ class ProjectLogic extends BaseLogic
* @method :post
* @time :2025/2/13 16:02
*/
public function setAiBlog($project_id,$main_lang_id,$is_ai_blog,$company,$company_en_name,$company_en_description){
if(empty($main_lang_id) || empty($is_ai_blog)){
public function setAiBlog($project_id,$main_lang_id,$is_ai_blog,$company,$company_en_name,$company_en_description,$is_ai_video = 0){
if(empty($main_lang_id) || (empty($is_ai_blog) && empty($is_ai_video))){
return true;
}
$projectInfo = $this->model->read(['id'=>$project_id],['title','is_ai_blog','main_lang_id','company']);
$projectInfo = $this->model->read(['id'=>$project_id],['title','main_lang_id','company']);
$projectOptimize = DeployOptimize::where('project_id', $project_id)->first();
//获取项目主语种
$languageModel = new WebLanguage();
... ...
... ... @@ -57,17 +57,18 @@ class AiBlogLogic extends BaseLogic
$this->param['image'] = str_replace_url($this->param['image']);
}
$this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_AI_BLOG, $this->param['id'], $this->user['project_id']);
$anchor = $this->param['anchor'] ?? [];
$this->param['anchor'] = json_encode($anchor,true);
$this->model->edit($this->param,['id'=>$this->param['id']]);
$aiSettingInfo = $this->getProjectAiSetting();
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$aiBlogService->updateDetail(['task_id'=>$this->param['task_id'],'title'=>$this->param['new_title'],'thumb'=>$this->param['image'],'route'=>$this->param['route'],'author_id'=>$this->param['author_id']]);
$aiBlogTaskModel = new AiBlogTask();
$aiBlogTaskModel->edit(['status'=>AiBlogTask::STATUS_RUNNING],['task_id'=>$this->param['task_id']]);//重新走拉取流程
$aiBlogService->updateDetail(['task_id'=>$this->param['task_id'],'title'=>$this->param['new_title'],'thumb'=>$this->param['image'],'route'=>$this->param['route'],'author_id'=>$anchor]);
}catch (\Exception $e){
$this->fail('保存失败,请联系管理员');
}
shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &");
return $this->success();
}
... ...
... ... @@ -29,21 +29,6 @@ class AiVideoLogic extends BaseLogic
$this->model = new AiVideo();
}
/**
* @remark :获取配置信息
* @name :getProjectAiSetting
* @author :lyh
* @method :post
* @time :2025/2/21 14:51
*/
public function getProjectAiSetting(){
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$this->user['project_id']]);
if($aiSettingInfo === false){
$this->fail('请先联系管理员开启Ai配置');
}
return $aiSettingInfo;
}
/**
* @remark :ai发布博客
... ... @@ -54,13 +39,14 @@ class AiVideoLogic extends BaseLogic
*/
public function videoSave(){
try {
$this->param['route'] = RouteMap::setRoute($this->param['tit'], RouteMap::SOURCE_AI_VIDEO, $this->param['id'], $this->user['project_id']);
$this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_AI_VIDEO, $this->param['id'], $this->user['project_id']);
$anchor = $this->param['anchor'] ?? [];
$this->param['anchor'] = json_encode($anchor,true);
$this->param['images'] = json_encode($this->param['images'],true);
$this->model->edit($this->param,['id'=>$this->param['id']]);
$aiSettingInfo = $this->getProjectAiSetting();
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$aiBlogService->updateDetail(['task_id'=>$this->param['task_id'],'title'=>$this->param['new_title'],'thumb'=>$this->param['image'],'route'=>$this->param['route'],'author_id'=>$this->param['author_id']]);
$aiVideoService = new AiVideoService($this->user['project_id']);
$aiVideoService->updateDetail(['task_id'=>$this->param['task_id'],'title'=>$this->param['title'],
'content'=>$this->param['content'] ?? '','video_url'=>$this->param['video_url'],'anchor'=>$anchor,'thumb'=>$this->param['image'],'url'=>$this->param['route'],'author_id'=>$this->param['author_id']]);
}catch (\Exception $e){
$this->fail('保存失败,请联系管理员');
}
... ... @@ -81,7 +67,7 @@ class AiVideoLogic extends BaseLogic
if($result['status'] == 200){
$aiVideoTaskModel = new AiVideoTask();
$aiVideoTaskModel->addReturnId(['task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id']]);
$id = $this->model->addReturnId(['task_id'=>$result['data']['task_id'],'description'=>$this->param['description'],'project_id'=>$this->user['project_id'],'images'=>json_encode($this->param['images'],true),'anchor'=>json_encode($this->param['anchor'] ?? [],true)]);
$id = $this->model->addReturnId(['title'=>$this->param['title'],'task_id'=>$result['data']['task_id'],'description'=>$this->param['description'],'project_id'=>$this->user['project_id'],'images'=>json_encode($this->param['images'],true),'anchor'=>json_encode($this->param['anchor'] ?? [],true)]);
return $this->success(['id'=>$id]);
}
return $this->success();
... ... @@ -96,13 +82,10 @@ class AiVideoLogic extends BaseLogic
*/
public function videoDelete(){
try {
$aiSettingInfo = $this->getProjectAiSetting();
$aiBlogService = new AiBlogService();
$aiBlogService = new AiVideoService($this->user['project_id']);
foreach ($this->param['ids'] as $id) {
$info = $this->model->read(['id'=>$id],['task_id']);
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$aiBlogService->delDetail($info['task_id']);
$aiBlogService->delVideoDetail($info['task_id']);
//删除路由映射
RouteMap::delRoute(RouteMap::SOURCE_AI_VIDEO, $id, $this->user['project_id']);
$this->model->del(['id'=>$id]);
... ...
... ... @@ -11,6 +11,7 @@ use App\Http\Logic\Aside\Project\DomainInfoLogic;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Domain\DomainInfo;
use App\Models\Inquiry\InquiryRelateDomain;
use App\Models\Project\DeployBuild;
use App\Models\Project\DeployOptimize;
use App\Models\Project\MinorLanguages;
... ... @@ -233,6 +234,8 @@ class RankDataLogic extends BaseLogic
$flg_ext = $this->getExtFlag($ext_projects, $domain, $api_no);
$ext_domain = str_replace('www.', '', $this->getExtendProjects($api_no)['ext'] ?? '');
$main_domain = str_replace('www.', '', $this->getExtendProjects($api_no)['url'] ?? '');
//关联域名
$relate_domain = str_replace('www.', '', InquiryRelateDomain::getRelateDomain($domain, 'globalso_domain'));
//AI站点域名
$ai_projects = $this->getAiProjects()['data'] ?? [];
$flg_ai = $this->getAiFlag($ai_projects, $domain);
... ... @@ -263,6 +266,8 @@ class RankDataLogic extends BaseLogic
$domain_text = '星链域名:' . $ai_domain;
} else if ($last['r'] == $ext_domain) {
$domain_text = '主域名2:' . $ext_domain;
} else if ($last['r'] == $relate_domain) {
$domain_text = '主域名2:' . $relate_domain;
} else {
$domain_text = 'AI域名:' . $last['r'];
}
... ... @@ -540,7 +545,7 @@ class RankDataLogic extends BaseLogic
$without_project_ids = []; //不用处理排名的项目
$without_extension_project_ids = [658]; //是否达标只统计主词的
$extension_project_ids = [354]; //扩展词也到达标的
$compliance_project_ids = [2163,257,823,1750]; //直接达标处理的
$compliance_project_ids = [2163,257,823,1750,497]; //直接达标处理的
$ceaseProjectId = [47, 354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250];//暂停的项目
$uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目
//一个项目多个api_no
... ...
... ... @@ -274,7 +274,8 @@ class UserLoginLogic
$info['is_show_blog'] = $project['is_show_blog'];
$info['upload_config'] = $project['upload_config'];
$info['main_lang_id'] = $project['main_lang_id'];
$info['is_ai_blog'] = $project['is_ai_blog'];
$info['is_ai_blog'] = $project['is_ai_blog'] ?? 0;
$info['is_ai_video'] = $project['is_ai_video'] ?? 0;
$info['image_max'] = $project['image_max'];
$info['is_del_inquiry'] = $project['is_del_inquiry'] ?? 0;
$info['uptime_type'] = $this->getHistory($project);
... ...
<?php
/**
* @remark :
* @name :AiBlogList.php
* @author :lyh
* @method :post
* @time :2025/2/21 15:57
*/
namespace App\Models\Ai;
use App\Models\Base;
class AiVideoList extends Base
{
protected $table = 'gl_ai_video_list';
//连接数据库
protected $connection = 'custom_mysql';
}
... ...
... ... @@ -28,8 +28,8 @@ class InquiryRelateDomain extends Base
* @author zbj
* @date 2025/4/12
*/
public static function getRelateDomain($domain){
$list_cache_key = 'RelateDomainList';
public static function getRelateDomain($domain, $k = 'domain'){
$list_cache_key = 'RelateDomainList_' . $k;
$data = Cache::get($list_cache_key);
if(!$data){
$data = [];
... ... @@ -41,7 +41,11 @@ class InquiryRelateDomain extends Base
$res = Arr::s2a($res);
$arr = [];
foreach ($res['data']['data'] as $item){
if($k == 'domain'){
$arr[$item['domain']] = $item['globalso_domain'];
}else{
$arr[$item['globalso_domain']] = $item['domain'];
}
}
$data = array_merge($data, $arr);
if ($res['data']['last_page'] == $page) {
... ...
... ... @@ -37,6 +37,7 @@ class RouteMap extends Base
const SOURCE_AI_VIDEO = 'ai_video';
const SOURCE_AI_BLOG_AUTHOR = 'ai_blog_author';//ai博客作者
const SOURCE_AI_BLOG_LIST = 'ai_blog_list';
const SOURCE_AI_VIDEO_LIST = 'ai_blog_video';
//自定义模块分类
const SOURCE_MODULE_CATE = 'module_category';
... ...
... ... @@ -99,6 +99,41 @@ class AiVideoService
}
/**
* @remark :获取列表页数据
* @name :getAiVideoList
* @author :lyh
* @method :post
* @time :2025/4/30 15:48
*/
public function getAiVideoList($page,$page_size){
$request_url = $this->url.'api/video/list';
$param['mch_id'] = $this->mch_id;
$param['page'] = $page;
$param['page_size'] = $page_size;
$this->sign = $this->generateSign($param,$this->key);
$param['sign'] = $this->sign;
$result = http_post($request_url,json_encode($param,true));
return $result;
}
/**
* @remark :删除详情数据
* @name :delDetail
* @author :lyh
* @method :post
* @time :2025/4/30 16:00
*/
public function delVideoDetail($task_id){
$param['task_id'] = $task_id;
$request_url = $this->url.'api/video/delete';
$param['mch_id'] = $this->mch_id;
$this->sign = $this->generateSign($param,$this->key);
$param['sign'] = $this->sign;
$result = http_post($request_url,json_encode($param,true));
return $result;
}
/**
* @remark :计算签名
* @name :generateSign
* @author :lyh
... ...
... ... @@ -312,4 +312,70 @@ class CosService
'HelveticaNeue.dfont'
];
}
/**
* @remark :获取cos图片高度
* @name :getImageHeight
* @author :lyh
* @method :post
* @time :2025/5/8 10:58
* @param :pathUrl->存储桶相对路径
*/
public function getImageHeight($pathUrl){
$cos = config('filesystems.disks.cos');
$url = 'https://' . $cos['bucket'] . '.cos.' . $cos['region'] . '.myqcloud.com/' . ltrim($pathUrl, '/') . '?image/info';
$imageInfo = @getimagesize($url);
if ($imageInfo) {
// $width = $imageInfo[0];
$height = $imageInfo[1];
return $height;
}
return '';
}
/**
* @remark :裁剪图片
* @name :cropCosImage
* @author :lyh
* @method :post
* @time :2025/5/8 11:06
*/
public function cropCosImage($cosUrl,$height = 220)
{
$cos = config('filesystems.disks.cos');
$cosClient = new Client([
'region' => $cos['region'],
'credentials' => [
'secretId' => $cos['credentials']['secretId'],
'secretKey' => $cos['credentials']['secretKey'],
],
]);
$pathInfo = pathinfo($cosUrl);
$newKey = $pathInfo['dirname'] . '/crop_' . $pathInfo['filename'] .'.'. $pathInfo['extension'];
$operations = [
'is_pic_info' => 0,
'rules' => [
[
// 注意 fileid 要 base64 编码,并与 Key 相同才能覆盖
'fileid' => $newKey,
'rule' => 'imageMogr2/crop/x'.$height.'/gravity/center'
]
]
];
// 执行裁剪并覆盖
$res = $cosClient->ImageProcess([
'Bucket' => $cos['bucket'],
'Key' => $cosUrl, // 要处理的对象路径
'PicOperations' => json_encode($operations),
]);
if($res){
return [
'path' => '/'.$res['ProcessResults']['Object'][0]['Key'] ?? '',
'size' => (int)$res['ProcessResults']['Object'][0]['Size'] ?? 0,
'mime' => 'image/'.($res['ProcessResults']['Object'][0]['Format'] ?? 'jpg'),
'type' => $res['ProcessResults']['Object'][0]['Format'] ?? 'jpg',
];
}
return [];
}
}
... ...
... ... @@ -286,9 +286,9 @@ class SyncSubmitTaskService
//转化询盘
Visit::isInquiry($data['ip']);
//推送企微消息
//推送企微消息 测试域名不发
Log::channel('inquiry')->info($task_id . '询盘结果', [$id]);
if($id){
if($id && !Str::contains($data['domain'], 'globalso.site')){
try {
$name = empty($data['data']['name']) ? '' : ' ' . $data['data']['name'];
MessagePush::addInquiryMessage($id, $data['project_id'], $data['country'], $name, $data['submit_at']);
... ...
... ... @@ -18,7 +18,6 @@
"laravel/framework": "^8.75",
"laravel/sanctum": "^2.11",
"laravel/tinker": "^2.5",
"mongodb/mongodb": "^1.6",
"mrgoon/aliyun-sms": "^2.0",
"phpoffice/phpspreadsheet": "^1.28",
"qcloud/cos-sdk-v5": "^v2.6.6",
... ...
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
... ... @@ -24,6 +24,7 @@ Route::get('get_project_route', [\App\Http\Controllers\Api\PrivateController::cl
Route::any('get_product_images', [\App\Http\Controllers\Api\ProductController::class, 'getImages'])->name('api.get_product_images');
Route::any('saveProduct', [\App\Http\Controllers\Api\ProductController::class, 'saveProduct'])->name('api.saveProduct');
Route::any('searchProduct', [\App\Http\Controllers\Api\ProductController::class, 'searchProduct'])->name('api.searchProduct');
Route::any('searchProductToAiBlog', [\App\Http\Controllers\Api\ProductController::class, 'searchProductToAiBlog'])->name('api.searchProductToAiBlog');
Route::post('inquiry_submit', [\App\Http\Controllers\Api\InquiryController::class, 'submit'])->name('api.inquiry_submit');
Route::post('editInquiryStatus', [\App\Http\Controllers\Api\InquiryController::class, 'editInquiryStatus'])->name('api.inquiry_editInquiryStatus');
Route::any('get_inquiry_random_ip', [\App\Http\Controllers\Api\InquiryController::class, 'getRandomIp'])->name('api.inquiry_getRandomIp');
... ... @@ -70,5 +71,5 @@ Route::any('/addRedirect',[\App\Http\Controllers\Api\NoticeController::class,'ad
//关联域名
Route::post('/inquiry_relate_domain', [\App\Http\Controllers\Api\PrivateController::class, 'inquiry_relate_domain']);
// 通过域名获取项目人员配置
Route::get('/get_manage_by_domain', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectManageByDomain']);
... ...
... ... @@ -157,7 +157,10 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'lists'])->name('ai_video_lists');
Route::any('/getInfo', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'getInfo'])->name('ai_video_getInfo');
Route::any('/sendTask', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'sendTask'])->name('ai_video_sendTask');
Route::any('/save', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'save'])->name('ai_video_save');
Route::any('/del', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'delete'])->name('ai_video_delete');
Route::any('/getAiVideoList', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'getAiVideoList'])->name('ai_video_getAiVideoList');
Route::any('/getAiBlogListInfo', [\App\Http\Controllers\Bside\Ai\AiVideoController::class, 'getAiBlogListInfo'])->name('ai_video_getAiBlogListInfo');
});
//ai
Route::any('/news/', [\App\Http\Controllers\Bside\Ai\AiNewsController::class, 'save'])->name('ai_news_save');
... ...