作者 zhl

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

... ... @@ -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;
}
}
... ...
<?php
/**
* @remark :
* @name :AiVideoTask.php
* @author :lyh
* @method :post
* @time :2025/4/30 11: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;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
class AiVideoTask extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'save_ai_video';
public $updateProject = [];//需更新的列表
public $routes = [];//需要更新的路由
/**
* The console command description.
*
* @var string
*/
protected $description = '查询ai_video是否已经生成';
/**
* @return bool
* @throws \Exception
*/
public function handle(){
while (true){
//获取任务id
$task_id = $this->getTaskId();
if(empty($task_id)){
sleep(300);
continue;
}
$this->_action($task_id);
}
return true;
}
/**
* 获取任务id
* @param int $finish_at
* @return mixed
*/
public function getTaskId($finish_at = 2)
{
$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)){
// $this->updateRoutes($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');
if(!empty($ids)){
foreach ($ids as $id) {
Redis::lpush('ai_video_task', $id);
}
}
$task_id = Redis::rpop('ai_video_task');
}
return $task_id;
}
/**
* @remark :请求
* @name :sendRequest
* @author :lyh
* @method :post
* @time :2025/4/30 11:31
*/
public function _action($task_id){
$aiVideoTaskModel = new AiVideoTaskModel();
$item = $aiVideoTaskModel->read(['id'=>$task_id]);
$this->output('ai_video->start:project ID: ' . $item['project_id'] . ',task ID: ' . $task_id);
$aiVideoService = new AiVideoService($item['project_id']);
$aiVideoService->task_id = $item['task_id'];
//拉取文章数据
$result = $aiVideoService->getVideoDetail();
if(empty($result['status']) || ($result['status'] != 200)){
if($item['number'] < 5){
$aiVideoTaskModel->edit(['number'=>$item['number'] + 1],['id'=>$item['id']]);
}else{
$aiVideoTaskModel->edit(['status'=>9],['id'=>$item['id']]);
// 钉钉通知
$dingService = new DingService();
$body = [
'keyword' => 'AI_VIDEO获取失败',
'msg' => '任务ID:' . $item['task_id'] . PHP_EOL . '返回信息:' . json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
'isAtAll' => false, // 是否@所有人
];
$dingService->handle($body);
}
$this->output('error: 数据获取失败,status:' . $result['status'] . ',message: ' . ($result['message'] ?? 'null'));
return false;
}
//保存当前项目ai_blog数据
ProjectServer::useProject($item['project_id']);
$aiVideoModel = new AiVideo();
$aiVideoInfo = $aiVideoModel->read(['task_id'=>$item['task_id']],['id','route']);
if($aiVideoInfo === false){
// 钉钉通知
$dingService = new DingService();
$body = [
'keyword' => 'AI_VIDEO生成错误',
'msg' => '任务ID:' . $item['task_id'] . ', 子库获取数据失败, 检查子库数据是否被删除!',
'isAtAll' => false, // 是否@所有人
];
$dingService->handle($body);
$this->output('error: 子库获取数据失败, task id: ' . $task_id);
$aiVideoTaskModel->edit(['status'=>9],['id'=>$item['id']]);
DB::disconnect('custom_mysql');
return false;
}
//拿到返回的路由查看是否重复
$route = RouteMap::setRoute($result['data']['url'], RouteMap::SOURCE_AI_VIDEO, $aiVideoInfo['id'], $item['project_id']);
if($route != $result['data']['url']){
$aiVideoService->updateDetail(['route'=>$route,'task_id'=>$item['task_id']]);
}
$saveData = [
'title'=>$result['data']['title'],
'image'=>$result['data']['thumb'],
'video_url'=>$result['data']['video_url'],
'route'=>$route,
'author_id'=>$result['data']['author_id'],
'keyword'=>json_encode($result['data']['keyword'],true),
'content'=>$result['data']['content'],
'text'=>$result['data']['section'],
'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);
return true;
}
/**
* @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
*/
public function output($message)
{
$message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
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;
}
}
... ...
... ... @@ -68,6 +68,7 @@ class AfterDayCount extends Command
$idArr = $this->managerHrModel->selectField(['name'=>['in',$valM]],'id');
$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)
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
... ... @@ -77,6 +78,7 @@ class AfterDayCount extends Command
->count();
$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.is_remain_today',1)
->where('gl_project_deploy_build.plan','!=',0)
... ... @@ -88,10 +90,12 @@ class AfterDayCount extends Command
->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-d', strtotime('-3 months'));
$three_project_count = $projectModel->where('gl_project.extend_type',0)
->where('gl_project.delete_status',0)
->where('gl_project.created_at','<=',$threeMonthsAgo)
->where('gl_project.old_project_id',0)
->where('gl_project.created_at','>=',$threeMonthsAgo.' 00:00:00')
->where('gl_project.created_at','<=',$threeMonthsAgo.' 23:59:59')
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
... ... @@ -101,7 +105,9 @@ class AfterDayCount extends Command
$three_qualified_count = $projectModel->where('gl_project.extend_type',0)
->whereIn('gl_project.id',$projectIdArr)
->where('gl_project.delete_status',0)
->where('gl_project.created_at','<=',$threeMonthsAgo)
->where('gl_project.old_project_id',0)
->where('gl_project.created_at','>=',$threeMonthsAgo.' 00:00:00')
->where('gl_project.created_at','<=',$threeMonthsAgo.' 23:59:59')
->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
->whereIn('gl_project.type',[2,4])
->where('gl_project_deploy_build.plan','!=',0)
... ... @@ -120,7 +126,7 @@ class AfterDayCount extends Command
->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,
... ...
... ... @@ -68,9 +68,10 @@ class DomainInfo extends Command
$domainModel = new DomainInfoModel();
$projectModel = new Project();
$serverIpModel = new ServersIp();
$domainCreateTaskModel = new DomainCreateTask();
$list = $domainModel->where('status', '=', 1)->get();
foreach ($list as $v) {
$project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id']);
$project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id', 'project_type']);
if (!$project_info) {
continue;
}
... ... @@ -89,6 +90,17 @@ class DomainInfo extends Command
}
}
//判断是否已经建站
if ($project_info['project_type'] == Project::PROJECT_TYPE_SEO) {
$type = DomainCreateTask::TYPE_BLOG;
} else {
$type = DomainCreateTask::TYPE_MAIN;
}
$task_info = $domainCreateTaskModel->read(['type' => $type, 'domain_id' => $v['id'], 'status' => DomainCreateTask::STATUS_SUC], ['id']);
if (!$task_info) {
continue;
}
//获取主站证书有效期并更新
$ssl_time = $this->getDomainSslTime($v['domain']);
if ($ssl_time['from'] && $ssl_time['to']) {
... ... @@ -168,7 +180,7 @@ class DomainInfo extends Command
}
//创建更新站点证书任务
$task_info = $domainCreateTaskModel->read(['type' => $type, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]]);
$task_info = $domainCreateTaskModel->read(['type' => $type, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);
if (!$task_info) {
$domainCreateTaskModel->add([
'server_id' => $servers_ip_info['servers_id'],
... ... @@ -225,7 +237,7 @@ class DomainInfo extends Command
}
//创建更新站点证书任务
$task_info = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_AMP, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]]);
$task_info = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_AMP, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);
if (!$task_info) {
$domainCreateTaskModel->add([
'server_id' => $servers_ip_info['servers_id'],
... ... @@ -273,7 +285,7 @@ class DomainInfo extends Command
}
//创建更新站点证书任务
$task_info = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_CUSTOM, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]]);
$task_info = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_CUSTOM, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);
if (!$task_info) {
$domainCreateTaskModel->add([
'server_id' => $servers_ip_info['servers_id'],
... ...
... ... @@ -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,
... ...
... ... @@ -12,6 +12,7 @@ namespace App\Console\Commands\LyhTest;
use App\Helper\Arr;
use App\Helper\Translate;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Blog\Blog;
use App\Models\Com\WordCountry;
use App\Models\CustomModule\CustomModuleContent;
... ... @@ -67,7 +68,7 @@ class UpdateRoute extends Command
*/
public function handle()
{
return $this->getNullRoute();
return $this->getAiBlog();
}
/**
... ... @@ -77,16 +78,18 @@ class UpdateRoute extends Command
* @method :post
* @time :2025/4/21 11:52
*/
public function getNullRoute(){
public function getAiBlog(){
$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']);
$keywordModel = new Keyword();
$info = $keywordModel->read(['route'=>'']);
if($info !== false){
echo '存在路由为空--项目id:'.$val['id'].PHP_EOL;
$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');
}
... ... @@ -151,7 +154,7 @@ class UpdateRoute extends Command
* @method :post
* @time :2025/3/21 17:45
*/
public function getAiBlog($project_id){
public function getAiBlogs($project_id){
$aiBlogModel = new AiBlog();
$lists = $aiBlogModel->list(['updated_at'=>['<=','2025-03-21 00:00:00']]);
if(!empty($lists)){
... ...
... ... @@ -84,7 +84,11 @@ class CopyOldProject extends Command
'gl_customer_visit_item',
'gl_inquiry_other',
'gl_inquiry_form_data',
'gl_inquiry_form'
'gl_inquiry_form',
'gl_ai_blog',
'gl_ai_blog_author',
'gl_ai_blog_list',
'gl_ai_blog_log',
])) {
continue;
}
... ...
... ... @@ -238,17 +238,20 @@ class CopyProject extends Command
$tables = array_column($tables, 'Tables_in_' . $database_name);
foreach ($tables as $table) {
// 1. 删除目标数据库中的表
DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS {$table}");
$result = DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS {$table}");
@file_put_contents(storage_path('logs/copy_mysql_error.log'), var_export('先删除对应数据库的对应表返回结果:'.$result, true) . PHP_EOL, FILE_APPEND);
// 2. 复制建表 SQL
$sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE `{$table}`");
DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
$result1 = DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
@file_put_contents(storage_path('logs/copy_mysql_error.log'), var_export('创建对应表数据:'.$result1, true) . PHP_EOL, FILE_APPEND);
// 3. 跳过指定的表
if (in_array($table, ['gl_customer_visit', 'gl_customer_visit_item', 'gl_inquiry_other', 'gl_inquiry_form_data', 'gl_inquiry_form'])) {
if (in_array($table, ['gl_customer_visit', 'gl_customer_visit_item', 'gl_inquiry_other', 'gl_inquiry_form_data', 'gl_inquiry_form','gl_ai_blog', 'gl_ai_blog_author', 'gl_ai_blog_list','gl_ai_blog_log'])) {
continue;
}
// 4. 原生 SQL 插入数据(完全复制)
$insert_sql = "INSERT INTO `{$table}` SELECT * FROM `gl_data_{$project_id}`.`{$table}`";
DB::connection('custom_mysql')->statement($insert_sql);
$result2 = DB::connection('custom_mysql')->statement($insert_sql);
@file_put_contents(storage_path('logs/copy_mysql_error.log'), var_export('对应表插入数据:'.$result2, true) . PHP_EOL, FILE_APPEND);
// 5. 更新 project_id(如果存在)
if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) {
DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]);
... ...
... ... @@ -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){
... ...
... ... @@ -34,7 +34,7 @@ class UpdateSeoTdkCrontab extends Command
*/
public function handle()
{
$project_ids = Project::where('type', Project::TYPE_TWO)->pluck('id')->toArray();
$project_ids = Project::where('type', Project::TYPE_TWO)->where('uptime', '<=', date('Y-m-d H:i:s'))->pluck('id')->toArray();
foreach ($project_ids as $project_id){
try {
ProjectUpdateTdk::add_task($project_id);
... ...
... ... @@ -39,8 +39,9 @@ class Temp extends Command
*/
protected $description = '临时脚本(akun)';
public function handle(){
public function handle()
{
$this->create_all_amp_notify();
}
/**
... ... @@ -89,7 +90,6 @@ class Temp extends Command
}
/**
* 未被标注 特殊前后缀 && 未达标项目 && 优化开始时间 > 2025-01-01 00:00:00 ,开启自动添加聚合页关键词的前后缀关键词配置
* @author Akun
... ...
... ... @@ -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'];
}
... ...
... ... @@ -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);
}
... ... @@ -86,6 +89,25 @@ class AiBlogController extends BaseController
}
/**
* @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
{
... ... @@ -24,7 +25,7 @@ class AiVideoController extends BaseController
* @time :2025/3/5 14:12
*/
public function lists(AiVideo $aiVideo){
$lists = $aiVideo->lists($this->map,$this->page,$this->row,'id',['id','keyword','new_title','route','image','task_id','status','created_at','updated_at']);
$lists = $aiVideo->lists($this->map,$this->page,$this->row,'id',['id','title','route','video_url','image','task_id','status','created_at','updated_at']);
if(!empty($lists) && !empty($lists['list'])){
foreach ($lists['list'] as $k => $v){
$v['image'] = getImageUrl($v['image']);
... ... @@ -51,7 +52,8 @@ class AiVideoController extends BaseController
'id.required' => '主键不能为空',
]);
$info = $aiVideo->read(['id'=>$this->param['id']]);
$info['image'] = getImageUrl($info['image']);
$info['anchor'] = json_decode($info['anchor'] ?? [],true);
$info['images'] = json_decode($info['images'] ?? [],true);
$this->response('success',Code::SUCCESS,$info);
}
... ... @@ -64,11 +66,13 @@ class AiVideoController extends BaseController
*/
public function sendTask(AiVideoLogic $aiVideoLogic){
$this->request->validate([
'keyword'=>['required'],
'type'=>['required'],
'title'=>['required'],
'description'=>['required'],
'images'=>['required'],
],[
'keyword.required' => '关键字不能为空',
'type.required' => '场景不能为空',
'title.required' => '标题不能为空',
'description.required' => '短描述不能为空',
'images.required' => '图片集合不能为空',
]);
$result = $aiVideoLogic->sendTask();
$this->response('success',Code::SUCCESS,$result);
... ... @@ -108,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 :登录用户编辑资料/修改密码
... ...
... ... @@ -28,6 +28,7 @@ use App\Models\Project\Project;
use App\Models\Project\ProjectAiSetting;
use App\Models\RouteMap\RouteMap;
use App\Services\AiBlogService;
use App\Services\AiVideoService;
use App\Services\RapIdApIService;
use App\Services\ProjectServer;
use Illuminate\Support\Facades\DB;
... ... @@ -42,8 +43,16 @@ class TestController extends BaseController
* @time :2025/2/13 16:34
*/
public function ceshi(){
//获取上一周询盘数量
$transData = Translate::tran(['heidenhain programming','heidenhain tnc 620'], 'zh');
$this->response('success',Code::SUCCESS,$transData);
$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);
}
}
... ...
... ... @@ -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
... ... @@ -268,12 +270,13 @@ class ProjectLogic extends BaseLogic
public function checkAiBlog($param){
$main_lang_id = $param['main_lang_id'] ?? 0;
$is_ai_blog = $param['is_ai_blog'] ?? 0;
$is_ai_video = $param['is_ai_video'] ?? 0;
$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){
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_blog--请填写主语种+公司名称+公司英文名称+公司英文介绍');
$this->fail('开启ai博客/视频功能--请填写主语种+公司名称+公司英文名称+公司英文介绍');
}
}
return true;
... ... @@ -286,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();
}
... ...
... ... @@ -7,9 +7,11 @@ use App\Http\Logic\Bside\BaseLogic;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Ai\AiVideo;
use App\Models\Project\AiBlogTask;
use App\Models\Project\AiVideoTask;
use App\Models\Project\ProjectAiSetting;
use App\Models\RouteMap\RouteMap;
use App\Services\AiBlogService;
use App\Services\AiVideoService;
/**
* @remark :视频模块
... ... @@ -27,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发布博客
... ... @@ -52,16 +39,14 @@ class AiVideoLogic extends BaseLogic
*/
public function videoSave(){
try {
if(!empty($this->param['image'])){
$this->param['image'] = str_replace_url($this->param['image']);
}
$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('保存失败,请联系管理员');
}
... ... @@ -74,20 +59,16 @@ class AiVideoLogic extends BaseLogic
* @author :lyh
* @method :post
* @time :2025/2/14 10:28
* @detail :createTask =>type=2/生成文章
* @detail :status=1/待执行
*/
public function sendTask(){
$aiSettingInfo = $this->getProjectAiSetting();
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$aiBlogService->route = generateRoute(Translate::tran($this->param['keyword'], 'en'));
$result = $aiBlogService->createTask($this->param['keyword'],2,'video',$this->param['anchor'] ?? []);
$aiVideoService = new AiVideoService($this->user['project_id']);
$result = $aiVideoService->createTask($this->param['title'],$this->param['description'],$this->param['images'],$this->param['anchor'] ?? []);
if($result['status'] == 200){
$aiBlogTaskModel = new AiBlogTask();
$aiBlogTaskModel->addReturnId(['project_id'=>$this->user['project_id'],'type'=>3,'task_id'=>$result['data']['task_id'],'status'=>1]);
$this->model->addReturnId(['keyword'=>$this->param['keyword'],'status'=>1,'task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id'],'anchor'=>json_encode($this->param['anchor'] ?? [],true)]);
$aiVideoTaskModel = new AiVideoTask();
$aiVideoTaskModel->addReturnId(['task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id']]);
$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();
}
... ... @@ -101,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);
... ...
... ... @@ -21,4 +21,6 @@ use App\Models\Base;
class AiVideo extends Base
{
protected $table = 'gl_ai_video';
//连接数据库
protected $connection = 'custom_mysql';
}
... ...
<?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';
}
... ...
... ... @@ -27,6 +27,9 @@ class GoogleKeywordInsightDetail extends Base
$saveData = [];
$textArr = array_column($data, 'text');
$transData = Translate::tran($textArr, 'zh');
if(!is_array($transData)){
$transData = [$transData];
}
foreach ($data as $key => $val){
$saveData[] = [
'search'=>$keyword,
... ...
... ... @@ -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){
$arr[$item['domain']] = $item['globalso_domain'];
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) {
... ...
<?php
/**
* @remark :
* @name :AiVideoTask.php
* @author :lyh
* @method :post
* @time :2025/4/30 9:41
*/
namespace App\Models\Project;
use App\Models\Base;
class AiVideoTask extends Base
{
protected $table = 'gl_ai_video_task';
/**
* 任务状态
*/
const STATUS_RUNNING = 1;
const STATUS_FINISH = 2;
}
... ...
... ... @@ -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';
... ...
<?php
/**
* @remark :
* @name :AiVideoService.php
* @author :lyh
* @method :post
* @time :2025/4/29 17:39
*/
namespace App\Services;
use App\Helper\Translate;
use App\Models\Project\ProjectAiSetting;
class AiVideoService
{
public $url = 'https://ai-extend.ai.cc/';
public $mch_id = 1;//默认配置
public $sign = '';//签名
public $key = 'b3e4c722b821';//默认key
public $route = '';//回调地址
public $task_id = '';//任务id
public $author_id = '';//作者id
public function __construct($project_id = 0)
{
if($project_id){
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]);
$this->mch_id = $aiSettingInfo['mch_id'];
$this->key = $aiSettingInfo['key'];
}
}
/**
* @remark :设置路由
* @name :setRoute
* @author :lyh
* @method :post
* @time :2025/3/25 9:45
*/
public function setRoute($keyword)
{
$this->route = generateRoute(Translate::tran($keyword, 'en'));
return $this;
}
/**
* @remark :创建任务
* @name :createTask
* @author :lyh
* @method :post
* @time :2025/4/29 17:59
*/
public function createTask($title,$description,$images = [],$anchor = []){
$request_url = $this->url.'api/video/create';
$param = ['title'=>$title, 'description'=>$description, 'images'=>$images,'anchor'=>$anchor];
$param['mch_id'] = $this->mch_id;
$this->sign = $this->generateSign($param,$this->key);
$param['sign'] = $this->sign;
return http_post($request_url,json_encode($param,true));
}
/**
* @remark :获取视频详情
* @name :getVideoDetail
* @author :lyh
* @method :post
* @time :2025/2/14 11:23
*/
public function getVideoDetail(){
$request_url = $this->url.'api/video/detail';
$param = [
'mch_id'=>$this->mch_id,
'task_id'=>$this->task_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 :updateDetail
* @author :lyh
* @method :post
* @time :2025/2/21 14:38
* @param :task_id , title , video_url ,thumb , content , author_id , url ,
*/
public function updateDetail($param){
$request_url = $this->url.'api/video/save';
$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 :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
* @method :post
* @time :2025/2/13 15:07
*/
public function generateSign($params, $key)
{
// 去除数组中所有值为空的项
array_filter($params);
// 按照key值的ASCII码从小到大排序
ksort($params);
// 生成URL的查询字符串
$string = http_build_query($params);
// 生成签名
$sign = md5($string . $key);
// 转换成大写
$sign = strtoupper($sign);
return $sign;
}
}
... ...
... ... @@ -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');
... ...