作者 赵彬吉
... ... @@ -11,7 +11,6 @@ namespace App\Console\Commands\Domain;
use Illuminate\Console\Command;
use App\Models\Domain\DomainInfo as DomainInfoModel;
use Illuminate\Support\Facades\Log;
class DomainInfo extends Command
{
... ... @@ -36,37 +35,106 @@ class DomainInfo extends Command
* @method :post
* @time :2023/9/11 15:09
*/
public function handle(){
public function handle()
{
//更新域名到期时间
$this->startUpdateDomain();
//主站证书到期更新
$this->startUpdateCert();
//AMP站证书到期更新
$this->startUpdateAmpCert();
return true;
}
/**
* 更新域名到期时间
* @author Akun
* @date 2024/02/26 10:26
*/
public function startUpdateDomain()
{
$domainModel = new DomainInfoModel();
$map = ['status'=>['!=',2]];
$list = $domainModel->list($map);
foreach ($list as $v){
if(empty($v['private_key']) || empty($v['private_cert'])){
//域名结束时间<2天时,重新生成
if(!empty($v['certificate_end_time'])){
if(($v['certificate_end_time'] > date('Y-m-d H:i:s',time() + 24*3600)) || ($v['certificate_end_time'] < date('Y-m-d H:i:s',time()))){
$this->updatePrivate($v);
}
}
}
$ssl = $this->updateDomainSsl($v['domain']);
$list = $domainModel->where('status', '!=', 2)->where(function ($query) {
$query->whereNull('domain_end_time')->orWhere('domain_end_time', '<', date('Y-m-d H:i:s'));
})->get()->toArray();
foreach ($list as $v) {
$time = $this->updateDomain($v['domain']);
if(!empty($time['start']) && !empty($time['end'])){
$data = [
'certificate_start_time'=>$ssl['from'],
'certificate_end_time'=>$ssl['to'],
'domain_start_time'=>$time['start'],
'domain_end_time'=>$time['end']
];
}else{
$data = [
'domain_start_time'=>$time['start'],
'domain_end_time'=>$time['end']
];
$data = [
'domain_start_time' => $time['start'],
'domain_end_time' => $time['end']
];
$domainModel->edit($data, ['id' => $v['id']]);
}
}
/**
* 主站证书到期更新
* @author Akun
* @date 2024/02/26 10:26
*/
public function startUpdateCert()
{
$domainModel = new DomainInfoModel();
$end_day = date('Y-m-d H:i:s', time() + 2 * 24 * 3600);//2天后到期
$list = $domainModel->where('status', '!=', 2)->where(function ($query) use ($end_day) {
$query->whereNull('certificate_end_time')->orWhere('certificate_end_time', '<', $end_day);
})->get()->toArray();
foreach ($list as $v) {
//更新证书到期时间
$data = [];
$ssl = $this->updateDomainSsl($v['domain']);
$ssl['from'] && $data['certificate_start_time'] = $ssl['from'];
$ssl['to'] && $data['certificate_end_time'] = $ssl['to'];
$domainModel->edit($data, ['id' => $v['id']]);
if ($v['type'] == 1 && ($data['certificate_end_time'] ?? '') < $end_day) {
//申请免费证书
$this->updatePrivate($v);
}
}
}
/**
* AMP站证书到期更新
* @author Akun
* @date 2024/02/26 10:26
*/
public function startUpdateAmpCert()
{
$domainModel = new DomainInfoModel();
$end_day = date('Y-m-d H:i:s', time() + 2 * 24 * 3600);//2天后到期
$list = $domainModel->where('status', '!=', 2)->where('amp_status', 1)->where(function ($query) use ($end_day) {
$query->whereNull('amp_certificate_end_time')->orWhere('amp_certificate_end_time', '<', $end_day);
})->get()->toArray();
foreach ($list as $v) {
//更新amp站点证书到期时间
$domain_array = parse_url($v['domain']);
$host = $domain_array['host'] ?? $domain_array['path'];
$host_array = explode('.', $host);
if (count($host_array) <= 2) {
array_unshift($host_array, 'm');
} else {
$host_array[0] = 'm';
}
$amp_domain = implode('.', $host_array);
$data = [];
$ssl = $this->updateDomainSsl($amp_domain);
$ssl['from'] && $data['amp_certificate_start_time'] = $ssl['from'];
$ssl['to'] && $data['amp_certificate_start_time'] = $ssl['to'];
$domainModel->edit($data, ['id' => $v['id']]);
if ($v['amp_type'] == 1 && ($data['amp_certificate_start_time'] ?? '') < $end_day) {
//申请免费证书
$this->updateAmpPrivate($v['domain']);
}
$domainModel->edit($data,['id'=>$v['id']]);
}
return 1;
}
/**
... ... @@ -78,7 +146,7 @@ class DomainInfo extends Command
*/
public function updatePrivate($param)
{
$url = 'https://' . $param['domain']. '/api/applySsl/';
$url = 'https://' . $param['domain'] . '/api/applySsl/';
$top_domain = $this->getTopDomain($param['domain']);
if ((empty($extend_config) || empty($extend_config[0]['origin'])) && $param['id'] != 3) {
$extend_config = [
... ... @@ -89,21 +157,40 @@ class DomainInfo extends Command
'project_id' => $param['project_id'],
'type' => 1,
'route' => 1,
"domain" =>$param['domain'],
"rewrite"=> $extend_config ?? [],
"domain" => $param['domain'],
"rewrite" => $extend_config ?? [],
'other_domain' => [$top_domain, '*.' . $top_domain],
'private_key' => '',
'cert' => ''
];
$result = $this->curlRequest($url, $param);
return $this->curlRequest($url, $param);
}
public static function getTopDomain ($url) {
/**
* 更新证书
* @param $domain
* @return array
* @author Akun
* @date 2024/02/26 10:25
*/
public function updateAmpPrivate($domain)
{
$url = 'https://' . $domain . '/api/createSiteAmp/';
$param = [
"domain" => $domain,
'private_key' => '',
'cert' => ''
];
return $this->curlRequest($url, $param);
}
public static function getTopDomain($url)
{
$url = strtolower($url); //首先转成小写
$url = mb_ereg_replace('^( | )+', '', trim($url));
$url = mb_ereg_replace('( | )+$', '', $url);
if (!preg_match('/^(http:\/\/|https)/', $url)) {
$url = "https://".$url;
$url = "https://" . $url;
}
$hosts = parse_url($url);
$host = $hosts['host'] ?? '';
... ... @@ -117,10 +204,10 @@ class DomainInfo extends Command
$preg = '/[\w].+\.(com|net|org|gov|edu|co|ne)\.[\w]/';
if (($n > 2) && preg_match($preg, $host)) {
//双后缀取后3位
$host = $data[$n - 3].'.'.$data[$n - 2].'.'.$data[$n - 1];
$host = $data[$n - 3] . '.' . $data[$n - 2] . '.' . $data[$n - 1];
} else {
//非双后缀取后两位
$host = $data[$n - 2].'.'.$data[$n - 1];
$host = $data[$n - 2] . '.' . $data[$n - 1];
}
return $host;
}
... ... @@ -155,30 +242,33 @@ class DomainInfo extends Command
* @method :post
* @time :2023/9/11 15:07
*/
public function updateDomainSsl($domain){
public function updateDomainSsl($domain)
{
try {
$context = stream_context_create([
'ssl' => [
'capture_peer_cert' => true,
'capture_peer_cert_chain' => false,
'verify_peer' => false,
'verify_peer_name' => false
],
]);
$stream = stream_socket_client('ssl://'.$domain.':443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
if(!$stream) {
$stream = stream_socket_client('ssl://' . $domain . ':443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
if (!$stream) {
die("Failed to connect: $errno - $errstr");
}
$remote_cert = stream_context_get_params($stream)['options']['ssl']['peer_certificate'];
if(!$remote_cert) {
if (!$remote_cert) {
die("Failed to retrieve certificate");
}
$valid_from = date('Y-m-d H:i:s', openssl_x509_parse($remote_cert)['validFrom_time_t']);
$valid_to = date('Y-m-d H:i:s', openssl_x509_parse($remote_cert)['validTo_time_t']);
fclose($stream);
}catch (\Exception $e){
} catch (\Exception $e) {
$valid_from = '';
$valid_to = '';
}
return ['from'=>$valid_from,'to'=>$valid_to];
return ['from' => $valid_from, 'to' => $valid_to];
}
/**
... ... @@ -188,15 +278,16 @@ class DomainInfo extends Command
* @method :post
* @time :2023/9/11 15:11
*/
public function updateDomain($domain){
$url = 'http://openai.waimaoq.com/v1/whois_api?domain='.$domain;
public function updateDomain($domain)
{
$url = 'http://openai.waimaoq.com/v1/whois_api?domain=' . $domain;
$response = http_get($url);
$start = date('Y-m-d H:i:s');
$end = date('Y-m-d H:i:s');
if($response['code'] == 200){
if ($response['code'] == 200) {
$start = $response['text']['creation_date'];
$end = $response['text']['expiration_date'];
}
return ['start'=>$start,'end'=>$end];
return ['start' => $start, 'end' => $end];
}
}
... ...
<?php
/**
* Created by PhpStorm.
* User: zhl
* Date: 2024/02/26
* Time: 10:13
*/
namespace App\Console\Commands\KeywordInVideo;
use App\Console\Commands\Model;
use App\Console\Commands\TaskSub;
use App\Models\Com\KeywordVideoTask;
use App\Models\Com\KeywordVideoTaskLog;
use App\Models\Product\Keyword;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class VideoTask extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'video_task';
/**
* The console command description.
*
* @var string
*/
protected $description = '视频推广任务';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* @var int 最大子任务
*/
public $max_sub_task = 800;
/**
* @return bool
*/
public function handle()
{
Log::info('开始视频推广任务');
$this->createSubTask();
$this->sendSubTask();
Log::info('结束视频推广任务');
return true;
}
/**
* 创建子任务
* TODO 获取需要生成子任务的项目,获取项目中未生成视频的关键词,通过关键词生成初始化子任务
* @return bool
*/
public function createSubTask()
{
$sub_task_num = $this->max_sub_task;
while (true) {
if ($sub_task_num <= 0){
break;
}
$task_project = KeywordVideoTask::where(['status' => KeywordVideoTask::STATUS_OPEN])->orderBy('sort', 'desc')->first();
if (empty($task_project)){
break;
}
ProjectServer::useProject($task_project->project_id);
$keyword = $this->getProjectKeyword();
// 已经没有需要生成视频的关键词
if (FALSE == $keyword->isEmpty()) {
$task_project->status = KeywordVideoTask::STATUS_CLOSE;
$task_project->save();
continue;
}
foreach ($keyword as $val) {
$log = KeywordVideoTaskLog::where(['project_id' => $task_project->project_id, 'keyword_id' => $val->id])->first();
if ($log){
continue;
}
$array = [
'project_id' => $task_project->project_id,
'keyword_id' => $val->id,
'keyword' => $val->title,
'data' => json_encode(['url' => '', 'description' => '', 'images' => [], 'keywords' => []]),
'status' => KeywordVideoTaskLog::STATUS_INIT,
'updated_at' => date('Y-m-d H:i:s'),
'created_at' => date('Y-m-d H:i:s'),
];
KeywordVideoTaskLog::insert($array);
$sub_task_num--;
}
$task_project->status = KeywordVideoTask::STATUS_CLOSE;
$task_project->save();
}
return true;
}
/**
* 发送子任务
* @return bool
*/
public function sendSubTask()
{
$subTask = KeywordVideoTaskLog::where(['status' => TaskSub::STATUS_INIT])->orderBy('id', 'asc')->limit($this->max_sub_task)->get();
if ($subTask->isEmpty())
return true;
foreach ($subTask as $val) {
$task_id = 'v6-' . uniqid();
$data = [
'project_data' => [
'tag_url' => '',
'title' => '',
'keywords' => [],
'description' => '',
'images' => ''
],
'task_id' => $task_id,
'callback_url' => '',
];
$result = Http::post('http://216.250.255.116:7866/create_task', $data);
$val->task_id = $task_id;
$val->status = STATUS_RUNING::STATUS_RUNING;
$val->request_result = $result;
$val->save();
}
return true;
}
/**
* 获取未生成页面的关键词
* @return mixed
*/
public function getProjectKeyword()
{
$keyword = Keyword::where('video', null)->whereNotNull('keyword_content')->inRandomOrder()->take(100)->get();
return $keyword;
}
/**
* 获取需要处理的任务
* @return int
*/
public function getTaskProject()
{
// $task_project = Model::where(['status' => Model::STATUS_OPEN])->orderBy('sort', 'desc')->first();
$project_id = 110;
return $project_id;
}
}
... ...
... ... @@ -11,6 +11,7 @@ namespace App\Console\Commands\MonthlyCount;
use App\Helper\FormGlobalsoApi;
use App\Models\Com\UpdateOldInfo;
use App\Models\Domain\DomainInfo;
use App\Models\HomeCount\MonthCount;
use App\Models\Project\Project;
use App\Models\Visit\Visit;
... ... @@ -39,7 +40,13 @@ class UpgradeProjectCount extends Command
$project_id = $this->argument('project_id');
$oldModel = new UpdateOldInfo();
$info = $oldModel->read(['project_id'=>$project_id]);
$url = $info['old_domain_online'];
if($info !== false){
$url = $info['old_domain_online'];
}else{
$domainModel = new DomainInfo();
$info = $domainModel->read(['project_id'=>$project_id]);
$url = $info['domain'];
}
ProjectServer::useProject($project_id);
$this->count($project_id,$url);
DB::disconnect('custom_mysql');
... ...
... ... @@ -139,11 +139,14 @@ class IndexController extends BaseController
$product_image = [];
foreach ($productList as $k => $v){
$image = [];
$image['title'] = $v['title'];
if(!empty($v['thumb']) && !empty($v['thumb']['url'])){
$image['image'] = getImageUrl($v['thumb']['url']);
$image['title'] = $v['title'];
$product_image[] = $image;
}
if(count($product_image) > 6){
break;
}
$product_image[] = $image;
}
$data = [
'title'=>$keywordInfo['title'],
... ...
<?php
/**
* @remark :
* @name :KeywordVideoController.php
* @author :lyh
* @method :post
* @time :2024/2/26 9:23
*/
namespace App\Http\Controllers\Aside\Com;
use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Models\Com\KeywordVideoTask;
class KeywordVideoController extends BaseController
{
/**
* @remark :任务列表
* @name :lists
* @author :lyh
* @method :post
* @time :2024/2/26 11:36
*/
public function lists(){
$keywordModel = new KeywordVideoTask();
$lists = $keywordModel->lists($this->map,$this->page,$this->row);
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :创建关键字任务池子
* @name :saveKeyword
* @author :lyh
* @method :post
* @time :2024/2/26 9:24
*/
public function createKeywordTask(){
$this->request->validate([
'project_id'=>'required',
'number'=>'required'
], [
'project_id.required' => '项目唯一标识不为空',
'number.required' => 'number不为空',
]);
$keywordModel = new KeywordVideoTask();
$rs = $keywordModel->add($this->param);
if($rs === false){
$this->response('添加失败',Code::SYSTEM_ERROR);
}
$this->response('success');
}
/**
* @remark :修改项目
* @name :editSort
* @author :lyh
* @method :post
* @time :2024/2/26 11:35
*/
public function edit(){
$this->request->validate([
'id'=>'required'
], [
'id.required' => '主键标识不为空',
]);
$keywordModel = new KeywordVideoTask();
$rs = $keywordModel->edit(['sort'=>$this->param['sort']],['id'=>$this->param['id']]);
if($rs === false){
$this->response('编辑失败',Code::SYSTEM_ERROR);
}
$this->response('success');
}
}
... ...
... ... @@ -15,7 +15,7 @@ use App\Rules\Ids;
use Illuminate\Http\Request;
/**
* Class KeywordController
* Class KeywordVideoController
* @package App\Http\Controllers\Bside
* @author zbj
* @date 2023/4/15
... ...
... ... @@ -52,6 +52,12 @@ class UserLogic extends BaseLogic
//验证一个项目是否只有一个超级管理员
$this->verifyRole($this->param);
if (isset($this->param['id']) && !empty($this->param['id'])) {
$info = $this->model->read(['id'=>$this->param['id']]);
if($info['role_id'] == 0){
//更新项目信息
$projectModel = new Project();
$projectModel->edit(['lead_name'=>$this->param['name'],'mobile'=>$this->param['mobile']],['id'=>$info['project_id']]);
}
$this->param = $this->editPassword($this->param);
$rs = $this->model->edit($this->param, ['id' => $this->param['id']]);
} else {
... ...
... ... @@ -147,7 +147,7 @@ class CountLogic extends BaseLogic
public function referrer_count(){
$customerVisitModel = new Visit();
$data = $customerVisitModel->select('referrer_url', DB::raw('COUNT(*) as count'))
->groupBy('referrer_url')->where(['domain'=>$this->user['domain']])
->groupBy('referrer_url')->where(['domain'=>trim(str_replace('https://','',$this->user['domain']),'/')])
->orderByDesc('count')->limit(9)->get()->toArray();
$total = $customerVisitModel->count();
if(!empty($data)){
... ...
... ... @@ -30,6 +30,7 @@ class MonthCountLogic extends BaseLogic
*/
public function getCountLists($map,$order = 'created_at',$filed = ['*']){
$map['project_id'] = $this->user['project_id'];
$new = $this->currentMonthCount();
$lists = $this->model->list($map,$order,$filed,'desc',10);
if(isset($this->project['is_record_china_visit']) && ($this->project['is_record_china_visit'] == 0)){
foreach ($lists as $k => $v){
... ... @@ -44,10 +45,11 @@ class MonthCountLogic extends BaseLogic
}
}
$v['source_country'] = json_encode(array_values($source_country));
$v['total'] = $new['total'] ?? $v['total'];
$lists[$k] = $v;
}
}
$lists['new'] = $this->currentMonthCount();
$lists['new'] = $new;
return $this->success($lists);
}
... ... @@ -151,6 +153,7 @@ class MonthCountLogic extends BaseLogic
$source = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('referrer_url', DB::raw('COUNT(*) as count'))
->groupBy('referrer_url')
->where('referrer_url','!=','')
->whereBetween('updated_date', [$startTime,$endTime])
->orderByDesc('count')->limit(10)->get()->toArray();
$arr['source'] = $source;
... ...
... ... @@ -12,6 +12,7 @@ namespace App\Http\Logic\Bside\Scoring;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Scoring\RatingQuestion;
use App\Models\Scoring\ScoringSystem;
use AWS\CRT\Log;
class RatingLogic extends BaseLogic
{
... ... @@ -77,6 +78,9 @@ class RatingLogic extends BaseLogic
}
$str = trim($str,'&');
$url = "http://www.quanqiusou.cn/extend_api/api/service_score.php?postid=$postId&token=$token&ftype=$fType&$str";
return http_get($url,['charset=utf-8']);
$rs = http_get($url,['charset=utf-8']);
@file_put_contents(storage_path('logs/lyh_error.log'), var_export($url, true) . PHP_EOL, FILE_APPEND);
@file_put_contents(storage_path('logs/lyh_error.log'), var_export($rs, true) . PHP_EOL, FILE_APPEND);
return $rs;
}
}
... ...
... ... @@ -228,11 +228,13 @@ class TranslateLogic extends BaseLogic
*/
public function translateSave(){
$data = [];
//处理传递的data
foreach ($this->param['data'] as $k => $v){
if(!empty($v) && is_array($v)){
foreach ($v as $text => $translate){
$data[$text] = $translate;
if(!empty($this->param['data'])){
//处理传递的data
foreach ($this->param['data'] as $k => $v){
if(!empty($v) && is_array($v)){
foreach ($v as $text => $translate){
$data[$text] = $translate;
}
}
}
}
... ...
... ... @@ -160,7 +160,7 @@ class CopyProjectJob implements ShouldQueue
$sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");
DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
}
DB::connection('custom_mysql')->table($table)->truncate(); // 清空目标表数据
// DB::connection('custom_mysql')->table($table)->truncate(); // 清空目标表数据
DB::connection('custom_mysql')->table($table)->insertUsing(
[], // 列名数组,留空表示插入所有列
function ($query) use ($table,$project_id) {
... ...
... ... @@ -40,7 +40,7 @@ class CollectTask extends Base
'project_id' => $project_id,
'source' => $source,
'source_id' => $source_id,
'domain' => $url_arr['host'] ?? $domain,
'domain' => $domain,
'route' => substr($url_arr['path'], 0, 1) == '/' ? $url_arr['path'] : '/' . $url_arr['path'],
'language' => '',
'created_at' => $now,
... ...
<?php
/**
* @remark :
* @name :KeywordVideoTask.php
* @author :lyh
* @method :post
* @time :2024/2/26 9:33
*/
namespace App\Models\Com;
use App\Models\Base;
class KeywordVideoTask extends Base
{
const STATUS_OPEN = 0;
const STATUS_CLOSE = 1;//停止
protected $table = 'gl_promotion_keyword_task';
}
... ...
<?php
/**
* @remark :
* @name :KeywordVideoTask.php
* @author :lyh
* @method :post
* @time :2024/2/26 9:33
*/
namespace App\Models\Com;
use App\Models\Base;
class KeywordVideoTaskLog extends Base
{
const STATUS_INIT = 0;
const STATUS_RUNING = 0;
protected $table = 'gl_keyword_video_task_log';
}
... ...
... ... @@ -326,6 +326,15 @@ Route::middleware(['aloginauth'])->group(function () {
Route::any('/del', [\App\Http\Controllers\Aside\CustomModule\CustomModuleController::class, 'del'])->name('custom_del');
});
/**
* 生成视频的项目
*/
Route::prefix('keyword_video')->group(function () {
Route::any('/', [Aside\Com\KeywordVideoController::class, 'lists'])->name('promotion_keyword_lists');
Route::any('/createKeywordTask', [Aside\Com\KeywordVideoController::class, 'createKeywordTask'])->name('promotion_keyword_createKeywordTask');
Route::any('/edit', [Aside\Com\KeywordVideoController::class, 'edit'])->name('promotion_keyword_edit');
});
// 公共主题模版
Route::prefix('template')->group(function () {
Route::any('/', [Aside\Template\ATemplateController::class, 'lists'])->name('admin.ATemplate_lists');
... ...