作者 赵彬吉
... ... @@ -56,11 +56,15 @@ class AiBlogAuthorTask extends Command
echo '开始->project_id:' . $info['project_id'] . PHP_EOL . date('Y-m-d H:i:s');
//获取配置
$aiSettingInfo = $this->getSetting($info['project_id']);
if(empty($aiSettingInfo)){
continue;
}
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$result = $aiBlogService->getAuthor();
if(!isset($result['status'])){
echo '错误:'.json_encode($result,true);
continue;
}
if($result['status'] != 200){
... ... @@ -68,15 +72,15 @@ class AiBlogAuthorTask extends Command
continue;
}
if(empty($result['data'])){
sleep(20);
echo '没有作者任务-'.PHP_EOL;
continue;
}
//保存当前项目ai_blog数据
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']);//写一条列表页路由
DB::disconnect('custom_mysql');
//修改任务状态
RouteMap::setRoute('top-blog',RouteMap::SOURCE_AI_BLOG_LIST,0,$info['project_id']);//写一条列表页路由
$aiBlogTaskModel->edit(['status'=>2],['id'=>$info['id']]);
echo '结束->任务id:' . $info['task_id'] . PHP_EOL . date('Y-m-d H:i:s');
}
... ... @@ -114,18 +118,23 @@ class AiBlogAuthorTask extends Command
return true;
}
$aiBlogAuthorModel = new AiBlogAuthor();
$info = $aiBlogAuthorModel->counts(['project_id'=>$project_id]);
if($info === false){
foreach ($data as $v){
foreach ($data as $v){
//查询当前数据是否存在
$info = $aiBlogAuthorModel->read(['author_id'=>$v['id']]);
if($info === false){
$param = [
'author_id'=>$v['id'],
'title'=>$v['title'],
'image'=>str_replace_url($v['picture']),
'description'=>$v['description'],
];
$id = $aiBlogAuthorModel->addReturnId($param);
$route = RouteMap::setRoute($v['route'] ?? $v['title'], RouteMap::SOURCE_AI_BLOG_AUTHOR, $id, $project_id);
$aiBlogAuthorModel->edit(['route'=>$route],['id'=>$id]);
try {
$id = $aiBlogAuthorModel->addReturnId($param);
$route = RouteMap::setRoute($v['route'] ?? $v['title'], RouteMap::SOURCE_AI_BLOG_AUTHOR, $id, $project_id);
$aiBlogAuthorModel->edit(['route'=>$route],['id'=>$id]);
}catch (\Exception $e){
echo 'error:'.$e->getMessage();
}
}
}
return true;
... ...
... ... @@ -42,11 +42,12 @@ class AiBlogTask extends Command
public function handle(){
$aiBlogTaskModel = new AiBlogTaskModel();
while (true){
$list = $aiBlogTaskModel->list(['status'=>1,'type'=>2, 'created_at' => ['<', date('Y-m-d H:i:s')]],'id',['*'],'asc',1000);
$list = $aiBlogTaskModel->formatQuery(['status'=>1,'type'=>2])->inRandomOrder()->limit(1000)->get();
if(empty($list)){
sleep(300);
continue;
}
$list = $list->toArray();
$updateProject = [];
foreach ($list as $item){
echo '开始->任务id:' . $item['task_id'] . PHP_EOL . date('Y-m-d H:i:s');
... ... @@ -57,8 +58,12 @@ class AiBlogTask extends Command
$aiBlogService->key = $aiSettingInfo['key'];
$aiBlogService->task_id = $item['task_id'];
$result = $aiBlogService->getDetail();
if(!isset($result['status']) || $result['status'] != 200){
sleep(5);
if(!isset($result['status'])){
echo json_encode($result,true).PHP_EOL;
continue;
}
if($result['status'] != 200){
echo '错误状态码:'.$result['status'].PHP_EOL;
continue;
}
//保存当前项目ai_blog数据
... ... @@ -66,6 +71,7 @@ class AiBlogTask extends Command
$aiBlogModel = new AiBlog();
$aiBlogInfo = $aiBlogModel->read(['task_id'=>$item['task_id']],['id']);
if($aiBlogInfo === false){
echo '任务id不存在:'.$item['task_id'].PHP_EOL;
$aiBlogTaskModel->edit(['status'=>2],['id'=>$item['id']]);
continue;
}
... ... @@ -80,10 +86,10 @@ class AiBlogTask extends Command
$aiBlogModel->edit(['new_title'=>$result['data']['title'], 'image'=>$result['data']['thumb'], 'text'=>$result['data']['section'], 'author_id'=>$result['data']['author_id'],'seo_title'=>$result['data']['title'],'seo_keyword'=>$result['data']['keyword'],'seo_description'=>$result['data']['description'], 'route'=>$route ,'status'=>2], ['task_id'=>$item['task_id']]);
DB::disconnect('custom_mysql');
$aiBlogTaskModel->edit(['status'=>2],['id'=>$item['id']]);
echo '结束->任务id:' . $item['task_id'] . PHP_EOL . date('Y-m-d H:i:s');
}
//TODO::更新列表页及作者
$this->updateProject($updateProject);
echo '结束->任务id:' . $item['task_id'] . PHP_EOL . date('Y-m-d H:i:s');
}
return true;
}
... ... @@ -121,13 +127,8 @@ class AiBlogTask extends Command
* @time :2025/2/14 11:27
*/
public function getSetting($project_id){
$ai_cache = Cache::get('ai_blog_'.$project_id);
if($ai_cache){
return $ai_cache;
}
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]);
Cache::put('ai_blog_'.$project_id,$aiSettingInfo,3600);
return $aiSettingInfo;
}
... ...
... ... @@ -329,7 +329,7 @@ class PostInquiryForward extends Command
'submit_time' => date('Y-m-d H:i:s'),
'source' => 5,
];
$url = 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f';
$url = 'https://form.globalso.com/api/external-interface/add/fa043f9cbec6b38f';
$res = Http::withoutVerifying()->timeout(30)->withHeaders(['User-Agent' => $detail['user_agent']])->post($url, $data)->json();
if (empty($res['status']) || $res['status'] != 200) {
$log->status = InquiryRelayDetailLog::STATUS_FAIL;
... ...
... ... @@ -54,7 +54,7 @@ class LyhImportTest extends Command
public function handle(){
ProjectServer::useProject(2837);
echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
$this->importCustomModule('https://ecdn6.globalso.com/upload/p/2837/file/2025-03/xindaxing-s-product-screening.csv',2837);
$this->importCustomModule('https://ecdn6.globalso.com/upload/p/2837/file/2025-03/2.csv',2837);
DB::disconnect('custom_mysql');
echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
}
... ...
... ... @@ -55,18 +55,11 @@ class CopyProject extends Command
$this->output('CopyProjectJob start, project_id: ' . $old_project_id);
$data = $this->copyProject($old_project_id);
$project_id = $data['project_id'];
$type = $data['type'];
$this->copyDeployBuild($old_project_id,$project_id);
$this->copyDeployOptimize($old_project_id,$project_id);
$this->copyPayment($old_project_id,$project_id);
$this->copyAfter($old_project_id,$project_id);
$this->copyUser($old_project_id,$project_id);
if($type != 0){
$this->copyMysql($old_project_id,$project_id);
}
//修改项目状态
$projectModel->edit(['delete_status'=>0],['id'=>$project_id]);
$this->output('CopyProjectJob end, old project_id: ' . $old_project_id . ', new project_id: ' . $project_id);
$item->status = NoticeLog::STATUS_SUCCESS;
$item->save();
}catch (\Exception $e){
... ... @@ -75,6 +68,14 @@ class CopyProject extends Command
$item->status = NoticeLog::STATUS_FAIL;
$item->save();
}
try {
$this->copyMysql($old_project_id,$project_id);
}catch (\Exception $e){
echo '复制数据库失败:'.$old_project_id . '<->'.$project_id;
}
//修改项目状态
$projectModel->edit(['delete_status'=>0],['id'=>$project_id]);
$this->output('CopyProjectJob end, old project_id: ' . $old_project_id . ', new project_id: ' . $project_id);
}
}
return true;
... ...
... ... @@ -624,7 +624,7 @@ class UpdateSeoTdk extends Command
$info = Cache::get($cache_key);
if(!$info){
$projectOptimizeModel = new DeployOptimize();
$info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description', 'keyword_prefix', 'keyword_suffix']);
$info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description', 'keyword_prefix', 'keyword_suffix', 'brand_keyword']);
$projectKeywordModel = new ProjectKeyword();
$keywordInfo = $projectKeywordModel->read(['project_id'=>$project_id]);
$info['main_keyword'] = '';
... ...
... ... @@ -90,7 +90,7 @@ class HtmlCollect extends Command
//采集html页面,下载资源到本地并替换
try {
$html = curl_c('https://' . $collect_info->domain . $collect_info->route, false);
$html = curl_code('https://' . $collect_info->domain . $collect_info->route, false);
if (strlen($html) < 4) {
if ($html == 404) {
... ...
... ... @@ -202,6 +202,43 @@ if (!function_exists('curl_c')) {
}
}
if (!function_exists('curl_code')) {
/**
* @param $url
* @param $is_array
* @return []
* @author Akun
* @date 2023/11/22 11:33
*/
function curl_code($url,$is_array=true){
$header = array(
'Expect:',
'Content-Type: application/json; charset=utf-8'
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246');
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLVERSION, 'all');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$content = curl_exec($ch);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
curl_close($ch);
if($http_code == 200){
return $is_array ? json_decode($content, true) : $content;
}else{
return $http_code;
}
}
}
if (!function_exists('_get_child')) {
/**
... ...
... ... @@ -9,6 +9,7 @@ namespace App\Http\Controllers\Api;
use App\Enums\Common\Code;
use App\Http\Logic\Bside\User\UserLoginLogic;
use App\Models\Ai\AiBlog;
use App\Models\Blog\Blog;
use App\Models\Domain\DomainInfo;
use App\Models\News\News;
... ... @@ -317,6 +318,7 @@ class PrivateController extends BaseController
$news = News::where(['status' => News::STATUS_ONE])->where('release_at', '>', $date)->pluck('url');
$blog = Blog::where(['status' => Blog::STATUS_ONE])->where('release_at', '>', $date)->pluck('url');
// $keyword = Keyword::where('created_at', '>', $date)->pluck('route');
$ai_blog = AiBlog::where(['status' => AiBlog::STATUS_FINISH])->where('updated_at', '>=', $date)->pluck('route');
// 组装链接
foreach ($product as $item) {
... ... @@ -335,6 +337,10 @@ class PrivateController extends BaseController
$url = 'https://' . $domain . '/blogs/' . $item;
array_push($result, $url);
}
foreach ($ai_blog as $item) {
$url = 'https://' . $domain . '/blog/' . $item;
array_push($result, $url);
}
return $this->success($result);
}
... ... @@ -453,7 +459,7 @@ class PrivateController extends BaseController
return $this->error('未找到当前域名对应的项目!');
}
$json = file_get_contents(storage_path('data/send_product_tag_keyword/' . $project->id . '.json'));
$json = @file_get_contents(storage_path('data/send_product_tag_keyword/' . $project->id . '.json'));
$result = json_decode($json, true) ?: [];
return $this->success($result);
}
... ...
<?php
/**
* @remark :
* @name :AggregateKeywordController.php
* @author :lyh
* @method :post
* @time :2025/3/17 16:03
*/
namespace App\Http\Controllers\Aside\Project;
use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Http\Logic\Aside\Project\AggregateKeywordLogic;
use App\Models\Project\AggregateKeyword;
/**
* @remark :聚合页关键词设置
* @name :AggregateKeywordController
* @author :lyh
* @method :post
* @time :2025/3/17 16:04
*/
class AggregateKeywordController extends BaseController
{
/**
* @remark :根据项目获取项目对应的聚合页关键词
* @name :lists
* @author :lyh
* @method :post
* @time :2025/3/17 16:04
*/
public function lists(AggregateKeyword $aggregateKeyword){
$this->request->validate([
'project_id'=>'required',
],[
'project_id.required' => 'project_id不能为空',
]);
$lists = $aggregateKeyword->list($this->map);
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :获取数据详情
* @name :info
* @author :lyh
* @method :post
* @time :2025/3/17 16:18
*/
public function info(AggregateKeyword $aggregateKeyword){
$this->request->validate([
'id'=>'required',
],[
'id.required' => '主键不能为空',
]);
$data = $aggregateKeyword->read($this->map);
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :保存数据
* @name :save
* @author :lyh
* @method :post
* @time :2025/3/17 16:05
* @param :created_at->创建使劲; operator->创建人; keywords->关键字一行一个; project_id->项目id
*/
public function save(AggregateKeywordLogic $logic){
$this->request->validate([
'project_id'=>'required',
'created_at'=>'required',
'operator'=>'required',
'keywords'=>'required',
],[
'project_id.required' => 'project_id不能为空',
'created_at.required' => 'created_at不能为空',
'operator.required' => 'operator不能为空',
'keywords.required' => 'keywords不能为空',
]);
$data = $logic->saveKeyword();
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :删除数据
* @name :del
* @author :lyh
* @method :post
* @time :2025/3/17 16:05
*/
public function del(AggregateKeyword $aggregateKeyword){
$this->request->validate([
'id'=>'required',
],[
'id.required' => '主键不能为空',
]);
$data = $aggregateKeyword->del($this->map);
$this->response('success',Code::SUCCESS,$data);
}
}
... ...
... ... @@ -83,6 +83,7 @@ class ProjectController extends BaseController
'gl_project.channel AS channel',
'gl_project.company AS company',
'gl_project.type AS type',
'gl_project.project_type AS project_type',
'gl_project.extend_type AS extend_type',
'gl_project.uptime AS uptime',
'gl_project.is_upgrade AS is_upgrade',
... ...
... ... @@ -7,8 +7,6 @@ use App\Exceptions\BsideGlobalException;
use App\Helper\Common;
use App\Http\Controllers\Controller;
use App\Http\Requests\Scene;
use App\Models\Project\DeployOptimize;
use App\Models\Project\ProjectKeyword;
use App\Models\Template\BTemplate;
use App\Models\Template\Setting;
use Illuminate\Http\JsonResponse;
... ...
<?php
/**
* @remark :
* @name :AggregateKeywordLogic.php
* @author :lyh
* @method :post
* @time :2025/3/17 16:10
*/
namespace App\Http\Logic\Aside\Project;
use App\Http\Logic\Aside\BaseLogic;
use App\Models\Project\AggregateKeyword;
class AggregateKeywordLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->param = $this->requestAll;
$this->model = new AggregateKeyword();
}
/**
* @remark :
* @name :saveKeyword
* @author :lyh
* @method :post
* @time :2025/3/17 16:11
*/
public function saveKeyword(){
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$this->model->edit($this->param,['id'=>$this->param['id']]);
}else{
$id = $this->model->addReturnId($this->param);
}
return $this->success(['id'=>$id]);
}
}
... ...
... ... @@ -11,7 +11,6 @@ class DeployBuildLogic extends BaseLogic
public function __construct()
{
parent::__construct();
$this->model = new DeployBuild();
}
}
... ...
... ... @@ -250,7 +250,7 @@ class ProjectLogic extends BaseLogic
public function createAuthor($project_id,$mch_id,$key){
//查看当前项目是否已经创建了作者
$aiBlogTaskModel = new AiBlogTask();
$count = $aiBlogTaskModel->counts(['project_id'=>$project_id]);
$count = $aiBlogTaskModel->counts(['project_id'=>$project_id,'type' => 1]);
if($count > 0){
return true;
}
... ... @@ -259,6 +259,7 @@ class ProjectLogic extends BaseLogic
$aiBlogService->key = $key;
$result = $aiBlogService->createAuthor();
if($result['status'] == 200){
//查看当前是否已有未执行的
$aiBlogTaskModel->add(['project_id'=>$project_id,'status'=>1,'type'=>1]);
}
return true;
... ...
... ... @@ -103,8 +103,7 @@ class AiBlogLogic extends BaseLogic
if($result['status'] == 200){
$aiBlogTaskModel = new AiBlogTask();
$aiBlogTaskModel->addReturnId(['project_id'=>$this->user['project_id'],'type'=>2,'task_id'=>$result['data']['task_id'],'status'=>1]);
$aiBlogModel = new AiBlog();
$aiBlogModel->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)
$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)
]);
}
return $this->success();
... ...
... ... @@ -274,6 +274,7 @@ class UserLoginLogic
$info['is_watermark'] = $project['is_watermark'];
$info['configuration'] = $project['deploy_build']['configuration'];
$info['project_type'] = $project['type'];
$info['project_seo_type'] = $project['project_type'];
$info['storage_type'] = $project['storage_type'];
$info['open_export_product'] = $project['open_export_product'];
$info['project_location'] = $project['project_location'];
... ...
... ... @@ -10,4 +10,7 @@ class AiBlog extends Base
//连接数据库
protected $connection = 'custom_mysql';
const STATUS_INIT = 0;
const STATUS_RUNNING = 1;
const STATUS_FINISH = 2;
}
... ...
... ... @@ -70,6 +70,28 @@ class Base extends Model
}
/**
* @remark :随机获取数据
* @name :limit_list
* @author :lyh
* @method :post
* @time :2025/3/17 17:26
*/
public function limit_list($map = [],$order = 'id',$fields = ['*'],$sort = 'desc',$row = 0): array
{
$query = $this->formatQuery($map);
if($row != 0){
$query = $query->limit($row);
}
$query = $this->sortOrder($query,$order,$sort);
$lists = $query->select($fields)->get();
if (empty($lists)) {
return [];
}
$lists = $lists->toArray();
return $lists;
}
/**
* @remark :获取数据详情
* @name :read
* @author :lyh
... ... @@ -96,7 +118,7 @@ class Base extends Model
*/
public function add($data){
$data = $this->filterRequestData($data);
$data['created_at'] = date('Y-m-d H:i:s');
$data['created_at'] = $data['created_at'] ?? date('Y-m-d H:i:s');
$data['updated_at'] = $data['created_at'];
return $this->insert($data);
}
... ...
<?php
/**
* @remark :
* @name :AggregateKeyword.php
* @author :lyh
* @method :post
* @time :2025/3/17 16:02
*/
namespace App\Models\Project;
use App\Models\Base;
/**
* @remark :聚合页关键词设置
* @name :AggregateKeyword
* @author :lyh
* @method :post
* @time :2025/3/17 16:02
*/
class AggregateKeyword extends Base
{
protected $table = 'gl_aggregate_keyword';
}
... ...
... ... @@ -533,6 +533,14 @@ Route::middleware(['aloginauth'])->group(function () {
Route::prefix('industry')->group(function () {
Route::any('/', [Aside\Project\ProjectController::class, 'industryList'])->name('admin.industryList');
});
//聚合页关键词设置
Route::prefix('aggregateKeyword')->group(function () {
Route::any('/', [Aside\Project\AggregateKeywordController::class, 'lists'])->name('admin.aggregateKeyword');
Route::any('/info', [Aside\Project\AggregateKeywordController::class, 'info'])->name('admin.aggregateKeyword_info');
Route::any('/save', [Aside\Project\AggregateKeywordController::class, 'save'])->name('admin.aggregateKeyword_save');
Route::any('/del', [Aside\Project\AggregateKeywordController::class, 'del'])->name('admin.aggregateKeyword_del');
});
});
//无需登录验证的路由组
... ...