作者 赵彬吉
<?php
namespace App\Console\Commands\Domain;
use App\Models\Devops\ServersIp;
use App\Services\AlibabaCloudService;
use Illuminate\Console\Command;
class EmergencyRecords extends Command
{
protected $signature = 'emergency_records {server_id} {type}';
protected $description = '紧急修改域名解析';
public function handle()
{
//服务器id
$server_id = $this->argument('server_id');
//类型,1受灾,2恢复
$type = $this->argument('type');
try {
//获取服务器的所有可用ip
$server_ip_model = new ServersIp();
$server_ip_list = $server_ip_model->where('servers_id', $server_id)->where('status', 0)->get();
if ($server_ip_list->count() > 0) {
foreach ($server_ip_list as $value) {
if (empty($value->ip) || empty($value->domain)) {
$this->output('ID ' . $value->id . ' 数据错误');
continue;
}
//获取解析记录
$domain_array = explode('.', $value->domain);
$domain_rr = $domain_array[0];
$record = AlibabaCloudService::describeDomainRecords('globalso.com', $domain_rr);
$record_status_code = $record['statusCode'] ?? 0;
if ($record_status_code != 200) {
$this->output('获取主机记录 ' . $domain_rr . ' 解析数据失败');
continue;
}
$record_detail = $record['body']['DomainRecords']['Record'][0] ?? [];
if (!$record_detail) {
$this->output('主机记录 ' . $domain_rr . ' 解析数据不存在');
continue;
}
//目标ip跟解析记录当前ip一样的数据,不用修改
$target_ip = $type == 1 ? '43.153.1.240' : $value->ip;
if ($target_ip == $record_detail['Value']) {
$this->output('主机记录 ' . $domain_rr . ' 的值已为 ' . $target_ip);
continue;
}
//修改解析记录
$record_id = $record_detail['RecordId'];
$record_rr = $record_detail['RR'];
$record_type = $record_detail['Type'];
$record_edit = AlibabaCloudService::updateDomainRecord($record_id, $record_rr, $record_type, $target_ip);
$record_edit_status_code = $record_edit['statusCode'] ?? 0;
if ($record_edit_status_code == 200) {
$this->output('修改主机记录 ' . $record_rr . ' 的值为 ' . $target_ip . ' 成功');
} else {
$this->output('修改主机记录 ' . $record_rr . ' 的值为 ' . $target_ip . ' 失败');
}
}
}
} catch (\Exception $e) {
$this->output($e->getMessage());
}
}
/**
* 输出处理日志
* @param $message
*/
public function output($message)
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
}
}
... ...
... ... @@ -47,17 +47,6 @@ class EmergencyRenewSite extends Command
continue;
}
//获取站点其他域名
$other_domain = [];
if (strpos($domain_info['domain'], 'www.') === 0) {
$other_domain[] = str_replace('www', '*', $domain_info['domain']);
$top_domain = str_replace('www.', '', $domain_info['domain']);
if ($this->check_cname($top_domain, $target_server)) {
$other_domain[] = $top_domain;
}
}
//创建目标服务器建站任务
$map_create = [
'type' => DomainCreateTask::TYPE_MAIN,
... ... @@ -68,7 +57,6 @@ class EmergencyRenewSite extends Command
];
$task_info = $create_model->read($map_create, ['id']);
if (!$task_info) {
$other_domain && $map_create['other_domain'] = json_encode($other_domain);
$create_model->add($map_create);
}
... ...
... ... @@ -275,7 +275,11 @@ class VideoTask extends Command
}
}else{
$product_all_id = Product::where('thumb','!=',null)->where("status",Product::STATUS_ON)->inRandomOrder()->take(20)->pluck('id')->toArray();
$products = Product::whereIn("id", $product_all_id)->orderByRaw(DB::raw("FIELD(id, " . implode(',', $product_all_id) . ")"))->get();
if(empty($product_all_id)){
$products = [];
}else{
$products = Product::whereIn("id", $product_all_id)->orderByRaw(DB::raw("FIELD(id, " . implode(',', $product_all_id) . ")"))->get();
}
}
$data = [];
if (!empty($products)){
... ...
<?php
/**
* @remark :
* @name :CountProject.php
* @author :lyh
* @method :post
* @time :2024/9/26 14:19
*/
namespace App\Console\Commands\Project;
use App\Models\Project\Project;
use Illuminate\Console\Command;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class countProject extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'month_count_project';
/**
* The console command description.
*
* @var string
*/
protected $description = '项目数据统计生成文件';
public function handle(){
$start = '2023-10';
$end = '2024-09';
$data = $this->exportDataProject($start,$end);
$result = $this->exportData($data);
echo date('Y-m-d H:i:s') . ' ' . json_encode($result) . PHP_EOL;
return $result;
}
public function exportData($data){
// 创建一个新的 Excel 电子表格实例
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 添加表头
$sheet->setCellValue('A1', '月份');
$sheet->setCellValue('B1', '开始时间');
$sheet->setCellValue('C1', '结束时间');
$sheet->setCellValue('D1', '创建项目数量');
$sheet->setCellValue('E1', '上线项目数量');
$sheet->setCellValue('F1', '上线比例');
$sheet->setCellValue('G1', '项目总数');
$sheet->setCellValue('H1', '上线项目总数');
$sheet->setCellValue('I1', '推广项目总数');
$sheet->setCellValue('J1', '建站项目总数');
$sheet->setCellValue('K1', '未上线项目数量');
$sheet->setCellValue('L1', '删除项目数量');
$sheet->setCellValue('M1', '上线最快时间');
$sheet->setCellValue('N1', '上线最慢');
$sheet->setCellValue('O1', '平均上线天数');
$rowCount = 2;
// $allData = $this->countAll();
foreach ($data as $v) {
$sheet->setCellValue('A' . $rowCount, $v['month']);
$sheet->setCellValue('B' . $rowCount, $v['start']);
$sheet->setCellValue('C' . $rowCount, $v['end']);
$sheet->setCellValue('D' . $rowCount, $v['month_create_project_count']);
$sheet->setCellValue('E' . $rowCount, $v['month_project_go_online_count']);
$sheet->setCellValue('F' . $rowCount, $v['month_project_online_rate']);
$sheet->setCellValue('G' . $rowCount, $v['count']);
$sheet->setCellValue('H' . $rowCount, $v['go_online_count']);
$sheet->setCellValue('I' . $rowCount, $v['promotion_web_count']);
$sheet->setCellValue('J' . $rowCount, $v['create_web_count']);
$sheet->setCellValue('K' . $rowCount, $v['no_go_oline_count']);
$sheet->setCellValue('L' . $rowCount, $v['delete_project_count']);
$sheet->setCellValue('M' . $rowCount, $v['min_project_count']);
$sheet->setCellValue('N' . $rowCount, $v['max_project_count']);
$sheet->setCellValue('O' . $rowCount, $v['average']);
$rowCount++;
}
// 创建一个新的 Excel Writer 对象
$writer = new Xlsx($spreadsheet);
$filename = time().'.xlsx';
// 设置导出文件的保存路径和文件名
$filePath = public_path('upload/excel/'.$filename);
// 导出 Excel 文件
$writer->save($filePath);
// 返回导出文件的响应
return ['file_link'=>url('upload/excel/'.$filename)];
}
/**
* @remark :获取所有月份
* @name :getMonthsBetween
* @author :lyh
* @method :post
* @time :2024/9/26 10:43
*/
public function getMonthsBetween($startDate, $endDate)
{
// 创建 DateTime 对象
$start = new \DateTime($startDate);
$end = new \DateTime($endDate);
// 确保结束时间是该月份的最后一天,以包含结束月份
$end->modify('first day of next month');
// 用于存储所有月份
$months = [];
// 循环遍历每个月
while ($start < $end) {
$months[] = $start->format('Y-m'); // 格式化成 YYYY-MM
$start->modify('+1 month'); // 增加一个月
}
return $months;
}
/**
* @remark :根据时间获取开始时间+结束时间
* @name :getStartAndEndOfMonth
* @author :lyh
* @method :post
* @time :2024/9/26 10:44
*/
public function getStartAndEndOfMonth($month) {
// 创建指定月份的 DateTime 对象
$start = new \DateTime($month . '-01'); // 月份的第一天
// 复制开始日期并获取该月的最后一天
$end = clone $start;
$end->modify('last day of this month'); // 修改为该月的最后一天
// 格式化成 'Y-m-d H:i:s'
$startTime = $start->format('Y-m-d 00:00:00'); // 开始时间,精确到天的开始
$endTime = $end->format('Y-m-d 23:59:59'); // 结束时间,精确到天的结束
return [
'start' => $startTime,
'end' => $endTime,
];
}
/**
* @remark :导出数据
* @name :exportData
* @author :lyh
* @method :post
* @time :2023/8/1 16:45
*/
public function exportDataProject($start_month,$end_month){
$data = [];
$monthData = $this->getMonthsBetween($start_month,$end_month);
$projectModel = new Project();
foreach ($monthData as $v){
$data[$v]['month'] = $v;
$timeArr = $this->getStartAndEndOfMonth($v);
$start_time = $timeArr['start'];
$end_time = $timeArr['end'];
$data[$v]['start'] = $start_time;
$data[$v]['end'] = $end_time;
//每月创建项目数据
$data[$v]['month_create_project_count'] = $projectModel->counts(['created_at'=>['between',[$start_time,$end_time]],'deleted_at'=>0]);//每月创建项目数量
$data[$v]['month_project_go_online_count'] = $projectModel->counts(['uptime'=>['between',[$start_time,$end_time]],'deleted_at'=>0]);//当月上线项目数量
$data[$v]['month_project_online_rate'] = 0;
if($data[$v]['month_create_project_count'] != 0){
$data[$v]['month_project_online_rate'] = round($data[$v]['month_project_go_online_count'] / $data[$v]['month_create_project_count'],2);//比例
}
$data[$v]['count'] = $projectModel->counts(['delete_status'=>0]);//所有项目总数
$data[$v]['go_online_count'] = $projectModel->counts(['uptime'=>['!=',null],'delete_status'=>0]);//上线项目总数
$data[$v]['promotion_web_count'] = $projectModel->counts(['type'=>3,'delete_status'=>0,'created_at'=>['between',[$start_time,$end_time]]]);//推广项目总数
$data[$v]['create_web_count'] = $projectModel->counts(['type'=>2,'delete_status'=>0,'created_at'=>['between',[$start_time,$end_time]]]);//建站项目总数
$data[$v]['no_go_oline_count'] = $projectModel->counts(['uptime'=>null,'delete_status'=>0,'created_at'=>['between',[$start_time,$end_time]]]);//未上线项目数量
$data[$v]['delete_project_count'] = $projectModel->counts(['delete_status'=>1,'created_at'=>['between',[$start_time,$end_time]]]);//删除
$min_info = $projectModel->select('*')
->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
->whereNotNull('uptime') // 确保 uptime 字段不为空
->where('created_at','<=',$end_time)
->whereBetween('created_at', [$start_time,$end_time])
->orderByRaw('diff ASC')
->first();
$data[$v]['min_project_count'] = $min_info['diff'];
$max_info = $projectModel->select('*')
->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
->whereNotNull('uptime') // 确保 uptime 字段不为空
->whereBetween('created_at', [$start_time,$end_time])
->orderByRaw('diff DESC')
->first();
$data[$v]['max_project_count'] = $max_info['diff'];
$data[$v]['average'] = ceil(($max_info['diff'] + $min_info['diff']) / 2);
}
return $data;
}
/**
* @remark :所有项目总数
* @name :countAll
* @author :lyh
* @method :post
* @time :2024/9/26 15:11
*/
public function countAll(){
$projectModel = new Project();
$data['count'] = $projectModel->counts(['deleted_at'=>0]);//所有项目总数
$data['go_online_count'] = $projectModel->counts(['uptime'=>['!=',null],'delete_status'=>0]);//上线项目总数
$data['promotion_web_count'] = $projectModel->counts(['type'=>3,'delete_status'=>0]);//推广项目总数
$data['create_web_count'] = $projectModel->counts(['type'=>2,'delete_status'=>0]);//建站项目总数
$data['no_go_oline_count'] = $projectModel->counts(['uptime'=>null,'delete_status'=>0]);//未上线项目数量
$data['delete_project_count'] = $projectModel->counts(['delete_status'=>1]);//删除项目数量
$min_info = $projectModel->select('*')
->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
->whereNotNull('uptime') // 确保 uptime 字段不为空
->orderByRaw('diff ASC')
->first();
$data['min_project_count'] = $min_info['diff'];
$max_info = $projectModel->select('*')
->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
->whereNotNull('uptime') // 确保 uptime 字段不为空
->orderByRaw('diff DESC')
->first();
$data['max_project_count'] = $max_info['diff'];
$data['average'] = ceil(($max_info['diff'] + $min_info['diff']) / 2);
return $data;
}
}
... ...
... ... @@ -69,7 +69,7 @@ class ReplaceHtml extends Command
foreach ($replaceHtmlList as $v){
ProjectServer::useProject($v['project_id']);
echo '开始,任务id:'.$v['id'].PHP_EOL;
if($v['source'] == 9){//单页面
if(($v['source'] == 9) && ($v['is_custom'] == 0)){//单页面
$count = $this->createReplacePageHtmlLog($v);
}else{
$count = $this->createReplaceHtmlLog($v);
... ... @@ -334,7 +334,7 @@ class ReplaceHtml extends Command
}
if($is_list == BTemplate::IS_LIST){
$categoryModel = new CustomModuleCategory();
$cateInfo = $categoryModel->read(['id'=>$source_id],['id','name']);
$cateInfo = $categoryModel->read(['id'=>$source_id],['id','name','route']);
if($cateInfo === false){
return false;
}
... ... @@ -342,7 +342,7 @@ class ReplaceHtml extends Command
$route = $cateInfo['route'];
}else{
$contentModel = new CustomModuleContent();
$contentInfo = $contentModel->read(['id'=>$source_id],['id','name']);
$contentInfo = $contentModel->read(['id'=>$source_id],['id','name','route']);
if($contentInfo === false){
return false;
}
... ...
... ... @@ -33,30 +33,26 @@ class SyncImage extends Command
// public function handle(){
// $str = $this->getProjectConfig(501);
// $str = $this->getProjectConfig(1808);
// $imageModel = new Image();
// $lists = $imageModel->list(['project_id'=>501]);
// $str_image = '/upload/p/1808/image_product/2024-09/ppp.png,/upload/p/1808/image_product/2024-09/86e4866b-7432-40c1-8c06-d335cd736e29.png,/upload/p/1808/image_product/2024-09/7fd109cc-56f4-457c-a9c4-c3fa8d8195b2.png,/upload/p/1808/image_product/2024-09/1.png,/upload/p/1808/image_product/2024-08/bxb12501-3-1.png,/upload/p/1808/image_product/2024-08/bxa10801-3-1.png,/upload/p/1808/image_product/2024-08/bxa007-3-1.png,/upload/p/1808/image_product/2024-08/auto-parts-rectifier-bxf1070-for-alternator-1-1.png,/upload/p/1808/image_product/2024-08/auto-parts-rectifier-bxd1102-for-alternator-2-1.png,/upload/p/1808/image_product/2024-08/11407-3-1.png,/upload/p/1808/image_product/2024-07/gfjty.jpg,/upload/p/1808/image_product/2024-07/bxn11508-g1-2.png,/upload/p/1808/image_product/2024-07/bxn11508-g1-1.png,/upload/p/1808/image_product/2024-07/bxb12501-2.png,/upload/p/1808/image_product/2024-07/bxb12501-1.png,/upload/p/1808/image_product/2024-07/bxb1209-2.png,/upload/p/1808/image_product/2024-07/bxb1209-1.png,/upload/p/1808/image_product/2024-07/bxa10801-2.png,/upload/p/1808/image_product/2024-07/bxa10801-1.png,/upload/p/1808/image_product/2024-07/bxa007-2.png,/upload/p/1808/image_product/2024-07/bxa007-1.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxf6102-for-alternator-2.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxf1070-for-alternator-3.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxf1070-for-alternator-2.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxd9410-for-alternator-1.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxd1102-for-alternator-3.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxd1102-for-alternator-1.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxb12807-for-alternator-2.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxb12807-for-alternator-1.png,/upload/p/1808/image_product/2024-07/11407-2.png,/upload/p/1808/image_product/2024-07/11407-1.png';
// $lists = explode(',',$str_image);
// $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
// foreach ($lists as $k => $v){
// if($v['path'] == '/upload/p/501/image_product/2024-09/6569ac3a212aa39368.png'){
// continue;
// }
// $url = $domain . $v['path'].'?'.$str;
// echo date('Y-m-d H:i:s') . '水印路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
// $this->coverOriginalImage($url,$v['path']);
// foreach ($lists as $v){
// $url = $domain . $v.'?'.$str;
// echo date('Y-m-d H:i:s') . '水印路径:'. $url . PHP_EOL;
// $cdu_url = $this->coverOriginalImage($url,$v);
// echo date('Y-m-d H:i:s') . '返回的url:'. $cdu_url . PHP_EOL;
// }
// return true;
// }
public function handle(){
$data = [];
$domain = 'https://ecdn6-nc.globalso.com/';
$domain = 'https://ecdn6.globalso.com/';
$imageModel = new Image();
$lists = $imageModel->list(['project_id'=>501]);
$lists = $imageModel->list(['project_id'=>1808]);
foreach ($lists as $k => $v){
if($v['path'] == '/upload/p/501/image_product/2024-09/6569ac3a212aa39368.png'){
continue;
}
$url = $domain . $v['path'];
echo date('Y-m-d H:i:s') . '刷新路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
$data[] = $url;
... ...
... ... @@ -8,7 +8,9 @@ use App\Models\Devops\ServerConfig;
use App\Models\Devops\ServersIp;
use App\Models\Domain\DomainInfo;
use App\Models\Project\Project;
use App\Services\BatchExportService;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
class Temp extends Command
{
... ... @@ -26,8 +28,124 @@ class Temp extends Command
*/
protected $description = '临时脚本';
/**
* 获取指定服务器所有项目
* @author Akun
* @date 2024/09/30 17:01
*/
public function handle()
{
$server_id = 1;
$server_ip_model = new ServersIp();
$server_ip_ids = $server_ip_model->where('servers_id', $server_id)->get()->pluck('id')->toArray();
$project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
$domain_model = new DomainInfo();
$data = [];
foreach ($project_list as $value) {
$domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
if (!$domain_info) {
//过滤未绑定正式域名的项目
continue;
}
$domain = $domain_info['domain'];
$data[] = [
$value->id,
$value->title,
$domain
];
}
$map = ['项目id', '名称', '域名'];
if ($data) {
$table = new BatchExportService("240云服务器项目");
$file = $table->head($map)->data($data)->save();
if (!$file) {
$this->output('文件生成失败,请重试');
} else {
$this->output('export success');
}
} else {
$this->output('no data');
}
}
/**
* 检查不在所属服务器解析上的域名
* @author Akun
* @date 2024/09/26 10:48
*/
public function handle1()
{
$server_id = 14;
$server_ip_model = new ServersIp();
$server_ip_ids = $server_ip_model->where('servers_id', $server_id)->get()->pluck('id')->toArray();
$project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
$domain_model = new DomainInfo();
$data = [];
foreach ($project_list as $value) {
$domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
if (!$domain_info) {
//过滤未绑定正式域名的项目
continue;
}
$domain = $domain_info['domain'];
$check = $this->check_cname($domain);
foreach ($check as $item) {
if (strpos($item, 'Address:') !== false) {
$ip = trim(str_replace('Address:', '', $item));
if (strpos($ip, '#') === false) {
$ip_info = $server_ip_model->read(['ip' => $ip]);
if ($ip_info === false || $ip_info['servers_id'] != $server_id) {
$data[] = [
$value->id,
$value->title,
$domain,
$ip,
$ip_info ? $ip_info['servers_id'] : '',
];
}
}
}
}
}
$map = ['项目id', '名称', '域名', 'IP', '服务器ID',];
if ($data) {
$table = new BatchExportService("美服2项目解析未在当前服务器项目");
$file = $table->head($map)->data($data)->save();
if (!$file) {
$this->output('文件生成失败,请重试');
} else {
$this->output('export success');
}
} else {
$this->output('no data');
}
}
public function check_cname($domain)
{
$process = new Process(['nslookup', '-qt=a', $domain]);
$process->run();
return explode(PHP_EOL, $process->getOutput());
}
/**
* 创建所有amp站页面生成任务
* @author Akun
* @date 2024/09/26 10:48
*/
public function handle2()
{
$notify_model = new Notify();
$project_model = new Project();
$serve_ip_model = new ServersIp();
... ...
... ... @@ -56,7 +56,7 @@ class UpdateRoute extends Command
*/
public function handle(){
$projectModel = new Project();
$list = $projectModel->list(['id'=>['in',[2350]]]);
$list = $projectModel->list(['id'=>['in',[1646]]]);
$data = [];
foreach ($list as $v){
echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL;
... ... @@ -222,18 +222,18 @@ class UpdateRoute extends Command
if(!empty($lists)){
foreach ($lists as $v){
if(!empty($v['route'])){
// $tag = "-product";
// if (!(substr($v['route'], -strlen($tag)) === $tag)) {
// echo date('Y-m-d H:i:s') . '拼接'.$tag . PHP_EOL;
// $route = $v['route'].$tag;
// // 如果不是以 '-product' 结尾,则拼接上 '-product'
// $route = RouteMap::setRoute($route, RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']);
// $productModel->edit(['route'=>$route],['id'=>$v['id']]);
// }else{
$tag = "-product";
if (!(substr($v['route'], -strlen($tag)) === $tag)) {
echo date('Y-m-d H:i:s') . '拼接'.$tag . PHP_EOL;
$route = $v['route'].$tag;
// 如果不是以 '-product' 结尾,则拼接上 '-product'
$route = RouteMap::setRoute($route, RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']);
$productModel->edit(['route'=>$route],['id'=>$v['id']]);
}else{
echo date('Y-m-d H:i:s') . 'id :'.$v['id'] . PHP_EOL;
$route = RouteMap::setRoute($v['title'], RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']);
$productModel->edit(['route'=>$route],['id'=>$v['id']]);
// }
}
continue;
}else{
echo date('Y-m-d H:i:s') . 'id :'.$v['id'] . PHP_EOL;
... ...
... ... @@ -135,6 +135,9 @@ class Common
if(isset($cache) && ($cache['is_cache'] == true)){
if(is_array($id)){
foreach ($id as $v){
if(is_array($v)){
continue;
}
$key = 'cache_'.$table.'_'.$v.'_type';
Cache::store('file')->pull($key);
}
... ...
... ... @@ -8,12 +8,15 @@
namespace App\Http\Controllers\Api;
use App\Models\Com\KeywordVideoTaskLog;
use App\Models\Domain\DomainInfo;
use App\Models\Domain\DomainRedirectTask;
use App\Models\Product\Keyword;
use App\Models\Visit\SyncSubmitTask;
use App\Models\Visit\Visit;
use App\Services\ProjectServer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\Process\Process;
/**
* Class NoticeController
... ... @@ -105,4 +108,79 @@ class NoticeController extends BaseController
DB::disconnect('custom_mysql');
return 200;
}
/**
* 创建301跳转任务
* @param Request $request
* @return false|string
* @author Akun
* @date 2024/10/08 15:24
*/
public function addRedirect(Request $request)
{
$origin_domain = $request->input('origin_domain', '');
$other_domain = $request->input('other_domain', []);
$target_domain = $request->input('target_domain', '');
if ($other_domain && !is_array($other_domain)) {
return $this->error('other_domain参数必须为数组');
}
if (empty($origin_domain)) {
return $this->error('origin_domain参数不能为空');
}
if (empty($target_domain)) {
return $this->error('target_domain参数不能为空');
}
if(!$this->check_a($origin_domain,DomainInfo::SERVER_IP_301)){
return $this->error($origin_domain . ' 未解析至 ' . DomainInfo::SERVER_IP_301);
}
if($other_domain){
foreach ($other_domain as $ov) {
if (!$this->check_a($ov, DomainInfo::SERVER_IP_301)) {
return $this->error($ov . ' 未解析至 ' . DomainInfo::SERVER_IP_301);
}
}
}
//新增重定向任务
$redirect_model = new DomainRedirectTask();
$task_redirect_info = $redirect_model->read(['origin_domain'=>$origin_domain]);
if(!$task_redirect_info){
$redirect_model->add([
'origin_domain'=> $origin_domain,
'other_domain' => json_encode($other_domain),
'target_domain' => $target_domain
]);
}
return $this->success();
}
/**
* 验证是否A记录解析到目标服务器
* @param $domain
* @param $ip
* @return bool
* @author Akun
* @date 2024/09/19 11:14
*/
public function check_a($domain, $ip)
{
$process = new Process(['nslookup', '-qt=a', $domain]);
$process->run();
$output = explode(PHP_EOL, $process->getOutput());
foreach ($output as $line) {
if ($line) {
$checkA = strpos($line, $ip) !== false;
if ($checkA) {
return $domain;
}
}
}
return false;
}
}
... ...
... ... @@ -21,6 +21,8 @@ use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
/**
* Class IndexController
... ... @@ -167,4 +169,6 @@ class IndexController extends BaseController
}
$this->response('success',Code::SUCCESS,['dynamic_password'=>$dynamic_password]);
}
}
... ...
<?php
namespace App\Http\Controllers\Aside\PackDir;
use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Models\Devops\Servers;
use App\Models\Devops\ServersIp;
use App\Models\Domain\DomainInfo;
use App\Models\Manage\Manage;
use App\Models\PackDir\SitePackTask;
use App\Models\Project\Project;
class PackDirController extends BaseController
{
/**
* 获取打包静态页面任务列表
* @author Akun
* @date 2024/10/08 16:12
*/
public function getTaskLists()
{
$autoModule = new SitePackTask();
$lists = $autoModule->lists($this->map, $this->page, $this->row);
if (!empty($lists)) {
$projectModel = new Project();
$manageModel = new Manage();
$serverModel = new Servers();
$domainModel = new DomainInfo();
foreach ($lists['list'] as $k => $v) {
$lists['list'][$k]['operator_name'] = $manageModel->getName($v['user_id']);
$lists['list'][$k]['project_name'] = $projectModel->getProjectName($v['project_id']);
$download_url = '';
if ($v['status'] == 2) {
$server_info = $serverModel->read(['id' => $v['server_id']], ['init_domain']);
$domain_info = $domainModel->read(['project_id' => $v['project_id']], ['domain']);
if ($server_info && $domain_info) {
$download_url = 'https://' . $server_info['init_domain'] . '/pack_sites/' . $domain_info['domain'] . '.zip';
}
}
$lists['list'][$k]['download_url'] = $download_url;
}
}
$this->response('success', Code::SUCCESS, $lists);
}
/**
* 添加静态页面打包任务
* @throws \App\Exceptions\AsideGlobalException
* @author Akun
* @date 2024/10/08 16:39
*/
public function saveTask()
{
$this->request->validate([
'project_id' => 'required',
], [
'project_id.required' => '项目不能为空'
]);
$domainModel = new DomainInfo();
$domain_info = $domainModel->read(['project_id' => $this->param['project_id']], ['domain']);
if (!$domain_info) {
$this->fail('项目未上线,无法打包静态页面');
}
$projectModel = new Project();
$project_info = $projectModel->read(['id' => $this->param['project_id']], ['serve_id']);
if (!$project_info) {
$this->fail('未查询到项目所属服务器信息');
}
$serverIpModel = new ServersIp();
$server_ip_info = $serverIpModel->read(['id' => $project_info['serve_id']], ['servers_id']);
if (!$server_ip_info) {
$this->fail('未查询到项目所属服务器信息');
}
$data = [
'user_id' => $this->uid,
'project_id' => $this->param['project_id'],
'server_id' => $server_ip_info['servers_id']
];
$model = new SitePackTask();
$pack_info = $model->read(array_merge($data, ['status' => ['in', [SitePackTask::STATUS_UN, SitePackTask::STATUS_ING]]]));
if ($pack_info) {
$this->fail('当前项目已有打包任务进行中,请勿重复提交');
}
$model->add($data);
$this->response('success');
}
}
... ...
... ... @@ -285,7 +285,7 @@ class ProjectController extends BaseController
if($this->map['domain'] == 0){
$query = $query->where('gl_project_deploy_optimize.domain',null);
}else{
$query = $query->where('gl_project_deploy_optimize.domain',null);
$query = $query->where('gl_project_deploy_optimize.domain','!=',null);
}
}
return $query;
... ... @@ -608,9 +608,6 @@ class ProjectController extends BaseController
*/
public function getManagerList(){
$hrManagerModel = new ManageHr();
if(!isset($this->param['name']) || empty($this->param['name'])){
$this->map['status'] = $hrManagerModel::STATUS_ONE;
}
if(isset($this->map['entry_position']) && !empty($this->map['entry_position'])){
$this->map['entry_position'] = ['in',$this->map['entry_position']];
}
... ...
... ... @@ -12,6 +12,8 @@ namespace App\Http\Controllers\Bside\BCom;
use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Models\Log\OperationHeartbeat;
use App\Models\Manage\Manage;
use App\Models\User\User;
class OperationHeartbeatController extends BaseController
{
... ... @@ -36,6 +38,7 @@ class OperationHeartbeatController extends BaseController
'is_custom.required' => '是否为扩展模版',
'is_template.required' => '详情页/可视化',
]);
$condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'],
'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
$operationHeartbeatModel = new OperationHeartbeat();
... ... @@ -44,9 +47,11 @@ class OperationHeartbeatController extends BaseController
if($info === false){
$condition['operator_id'] = $this->user['id'];
$condition['project_id'] = $this->user['project_id'];
$condition['ip'] = $this->request->ip();
$condition['manager_id'] = $this->user['manager_id'] ?? 0;
$operationHeartbeatModel->addReturnId($condition);
}else{
$operationHeartbeatModel->edit(['status'=>$condition['status'] ?? 0],['id'=>$info['id']]);
$operationHeartbeatModel->edit(['status'=>$condition['status'] ?? 0,'ip'=>$this->request->ip(),'manager_id'=> $this->user['manager_id'] ?? 0],['id'=>$info['id']]);
}
$this->response('success');
}
... ... @@ -75,15 +80,33 @@ class OperationHeartbeatController extends BaseController
$condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'],
'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
$operationHeartbeatModel = new OperationHeartbeat();
$info = $operationHeartbeatModel->read($condition,['id','status','updated_at']);
$info = $operationHeartbeatModel->read($condition,['id','status','manager_id','ip','operator_id','updated_at']);
if($info === false){
$info = [];
}else{
$date_time = strtotime($info['updated_at']) + 7200;
$date_time = strtotime($info['updated_at']) + 120;
if($date_time < time()){
$operationHeartbeatModel->edit(['status'=>0],$condition);
$operationHeartbeatModel->edit(['status'=>0,'ip'=>'127.0.0.1'],$condition);
$info['status'] = 0;
}
if($info['status'] == 1){
//当前登录为切入登录
if(isset($this->user['manager_id']) && !empty($this->user['manager_id'])){
//上一次验证也是切入登录
if($info['manager_id'] != 0){
$managerModel = new Manage();
$managerInfo = $managerModel->read(['id'=>$info['manager_id']],['name']);
$info['message'] = '此页面数据已有人在编辑,请勿重复操作!操作人ip:'.$info['ip'].'操作的管理员为:'.$managerInfo['name'];
}else{
//账号密码登录
$userModel = new User();
$userInfo = $userModel->read(['id'=>$info['operator_id']],['name']);
$info['message'] = '此页面数据已有人在编辑,请勿重复操作!'.$userInfo['name'].'用户登录在操作。';
}
}else{
$info['message'] = '此页面数据已有人在编辑,请勿重复操作!';
}
}
}
$this->response('success',Code::SUCCESS,$info);
}
... ...
... ... @@ -173,16 +173,15 @@ class FileManageController extends BaseController
public function delete(Request $request){
$request->validate([
'id'=>'required',
'id'=>'required | array',
],[
'id.required' => 'ID不能为空',
]);
$fileManage = FileManage::find($this->param['id']);
if(!$fileManage){
$this->response('数据不存在或者已经删除');
if(!is_array($this->param['id'])){
$this->param['id'] = [$this->param['id']];
}
$fileManage->delete();
$fileManage = new FileManage();
$fileManage->del(['id'=>['in',$this->param['id']]]);
$this->response('success');
}
}
... ...
... ... @@ -297,8 +297,7 @@ class LoginController extends BaseController
];
}
}
$info = $logic->autologin($data);
$info = $logic->autologin($data,User::LOGIN_OTHER_SOURCE);
$this->response('success',Code::SUCCESS,['info'=>$info]);
}
... ...
... ... @@ -788,7 +788,7 @@ class ProductController extends BaseController
'keyword_id'=>'required|array',
],[
'id.required' => '产品ID不能为空',
'category_id.required' => '关键词ID不能为空',
'keyword_id.required' => '关键词ID不能为空',
]);
$logic->batchSetKeyword();
$this->response('success');
... ...
... ... @@ -69,7 +69,7 @@ class ReplaceHtmlLogic extends BaseLogic
*/
public function getCustomTemplateId($typeInfo,$template_id){
$customModuleModel = new CustomModule();
$moduleInfo = $customModuleModel->read(['id'=>$typeInfo['type']],['list_customized','detail_customized']);
$moduleInfo = $customModuleModel->read(['id'=>$typeInfo['source']],['list_customized','detail_customized']);
if($moduleInfo === false){
$this->fail('当前扩展模块不存在或已被删除');
}
... ...
... ... @@ -186,9 +186,9 @@ class InquiryLogic extends BaseLogic
public function sendMobileVerifyData($phone){
$phoneDataModel = new PhoneData();
$num_phone = preg_replace('/\D/', '',$phone) ?? ''; // \D 匹配所有非数字字符
$info = $phoneDataModel->read(['phone'=>$num_phone]);
if($info === false){
$url = 'https://fob.ai.cc/api/mobile_verify_data/'.$phone;
$data = $phoneDataModel->read(['num_phone'=>$num_phone]);
if($data === false){
$url = 'https://fob.ai.cc/api/mobile_verify_data/'.$num_phone;
$data = http_get($url);
if(!empty($data)){
$param = [
... ...
... ... @@ -350,6 +350,8 @@ class ProductLogic extends BaseLogic
DB::connection('custom_mysql')->beginTransaction();
try {
$cateRelate = new CategoryRelated();
//删除扩展字段
$extendInfoModel = new ExtendInfo();
foreach ($this->param['ids'] as $id) {
$info = $this->model->read(['id'=>$id],['id','status']);
if($info['status'] == Product::STATUS_RECYCLE){
... ... @@ -359,6 +361,7 @@ class ProductLogic extends BaseLogic
$this->model->del(['id'=>$id]);
//删除关联表
$cateRelate->del(['product_id'=>$id]);
$extendInfoModel->del(['product_id'=>$id]);
}else{
//回收站
$this->model->edit(['status'=>Product::STATUS_RECYCLE],['id'=>$id]);
... ...
... ... @@ -107,7 +107,7 @@ class UserLoginLogic
* @method :post
* @time :2023/9/18 11:00
*/
public function autologin($data)
public function autologin($data,$login_source = User::LOGIN_AUTO_SOURCE)
{
//项目自动登录
if(isset($data['project_id']) && !empty($data['project_id'])){
... ... @@ -120,7 +120,7 @@ class UserLoginLogic
if ($has_user === false) {
$this->fail('该项目未找到注册账号');
}
$info = $this->autoAssembleParam($has_user);
$info = $this->autoAssembleParam($has_user,$login_source);
//生成新token
$token = md5(uniqid().$info['id']);
//存储缓存
... ... @@ -160,7 +160,7 @@ class UserLoginLogic
* @method :post
* @time :2023/6/12 15:34
*/
public function autoAssembleParam($info){
public function autoAssembleParam($info,$login_source = User::LOGIN_AUTO_SOURCE){
$project = $this->getProjectInfo($info['project_id']);
if($project['site_status'] != 0){//关闭站点
$this->fail('当前网站已过期,请联系管理员及时续费。');
... ... @@ -206,7 +206,7 @@ class UserLoginLogic
$is_amp = $amp_info ? $amp_info['amp_status'] : 0;
}
$info['is_amp'] = $is_amp;
$info['login_source'] = $login_source;
//保存项目缓存
Cache::put('user-'.$info['project_id'],$project,12 * 3600);
return $this->success($info);
... ... @@ -316,6 +316,7 @@ class UserLoginLogic
$is_amp = $amp_info ? $amp_info['amp_status'] : 0;
}
$info['is_amp'] = $is_amp;
$info['login_source'] = User::LOGIN_PASSWORD_SOURCE;//账号密码登录返回
//保存项目缓存
Cache::put('user-'.$info['project_id'],$project,12 * 3600);
return $this->success($info);
... ... @@ -363,7 +364,7 @@ class UserLoginLogic
];
}else {
//获取项目详情
$info = $this->autoAssembleParam($info);
$info = $this->autoAssembleParam($info,User::LOGIN_PASSWORD_SOURCE);
if(isset($info['token']) && !empty($info['token'])){
//清除上一次用户缓存
Cache::pull($info['token']);
... ...
... ... @@ -13,7 +13,7 @@ class AutoPullNotify extends Base
return [
1 => '硅谷云服务器',
9 => '硅谷IDC服务器01(6.0美服1)',
3 => '硅谷IDC服务器02(6.0美服2)',
14 => '硅谷IDC服务器02(6.0美服2)',
2 => '俄罗斯服务器',
4 => '阿里云深圳服务器',
5 => '日本服务器',
... ...
... ... @@ -116,6 +116,17 @@ class Base extends Model
}
/**
* @remark :统计数量
* @name :count
* @author :lyh
* @method :post
* @time :2024/9/26 10:52
*/
public function counts($condition){
$condition = $this->filterRequestData($condition);
return $this->formatQuery($condition)->count();
}
/**
* @remark :编辑
* @name :edit
* @author :lyh
... ...
<?php
namespace App\Models\PackDir;
use App\Models\Base;
class SitePackTask extends Base
{
protected $table = 'gl_site_pack_task';
const STATUS_UN = 0;
const STATUS_ING = 1;
const STATUS_SUC = 2;
const STATUS_FAL = 3;
const STATUS_EXP = 4;
}
... ...
... ... @@ -17,6 +17,9 @@ class User extends Base
//自动维护create_at创建时间 updated_at修改时间
public $timestamps = true;
const LOGIN_AUTO_SOURCE = 1;//自动登录
const LOGIN_PASSWORD_SOURCE = 2;//账号密码登录
const LOGIN_OTHER_SOURCE = 3;//其他平台切入
/**
* The attributes that should be cast.
*
... ...
<?php
namespace App\Services;
use AlibabaCloud\SDK\Alidns\V20150109\Alidns;
use AlibabaCloud\SDK\Alidns\V20150109\Models\AddDomainRecordRequest;
use AlibabaCloud\SDK\Alidns\V20150109\Models\DescribeDomainRecordsRequest;
use AlibabaCloud\SDK\Alidns\V20150109\Models\UpdateDomainRecordRemarkRequest;
use AlibabaCloud\SDK\Alidns\V20150109\Models\UpdateDomainRecordRequest;
use AlibabaCloud\Tea\Utils\Utils;
use Darabonba\OpenApi\Models\Config;
class AlibabaCloudService
{
/**
* 创建客户端
* @return Alidns
* @author Akun
* @date 2024/09/21 16:16
*/
public static function createClient()
{
$config = new Config([
'accessKeyId' => env('ALIBABA_CLOUD_KEY'),
'accessKeySecret' => env('ALIBABA_CLOUD_SECRET'),
]);
return new Alidns($config);
}
/**
* 获取域名解析记录列表
* @param $domain
* @param $keyword
* @param $status
* @return array
* @author Akun
* @date 2024/09/21 17:19
*/
public static function describeDomainRecords($domain, $keyword, $status = 'Enable')
{
$client = self::createClient();
$request = new DescribeDomainRecordsRequest([
'domainName' => $domain,
'RRKeyWord' => $keyword,
'status' => $status,
]);
$response = $client->DescribeDomainRecords($request);
return Utils::toArray($response);
}
/**
* 添加解析记录
* @param $domain
* @param $rr
* @param $type
* @param $value
* @return array
* @author Akun
* @date 2024/09/21 17:33
*/
public static function addDomainRecord($domain, $rr, $type, $value)
{
$client = self::createClient();
$request = new AddDomainRecordRequest([
'domainName' => $domain,
'RR' => $rr,
'type' => $type,
'value' => $value
]);
$response = $client->AddDomainRecord($request);
return Utils::toArray($response);
}
/**
* 修改解析记录备注
* @param $record_id
* @param $remark
* @return array
* @author Akun
* @date 2024/09/21 17:38
*/
public static function updateDomainRecordRemark($record_id, $remark)
{
$client = self::createClient();
$request = new UpdateDomainRecordRemarkRequest([
'recordId' => $record_id,
'remark' => $remark,
]);
$response = $client->UpdateDomainRecordRemark($request);
return Utils::toArray($response);
}
/**
* 修改解析记录详情
* @param $record_id
* @param $rr
* @param $type
* @param $value
* @return array
* @author Akun
* @date 2024/09/23 10:55
*/
public static function updateDomainRecord($record_id, $rr, $type, $value)
{
$client = self::createClient();
$request = new UpdateDomainRecordRequest([
'recordId' => $record_id,
'RR' => $rr,
'type' => $type,
'value' => $value,
]);
$response = $client->UpdateDomainRecord($request);
return Utils::toArray($response);
}
}
... ...
... ... @@ -5,6 +5,8 @@
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"alibabacloud/alidns-20150109": "*",
"alibabacloud/darabonba-openapi": "^0.2.12",
"barryvdh/laravel-dompdf": "^2.0",
"bensampo/laravel-enum": "^4.2",
"beyondcode/laravel-websockets": "^1.14",
... ...
... ... @@ -53,4 +53,7 @@ Route::post('selfSiteApi', [\App\Http\Controllers\Api\SelfSiteController::class,
Route::post('selfSiteNotify', [\App\Http\Controllers\Api\SelfSiteController::class, 'selfSiteNotify']);
Route::post('selfSiteVerify', [\App\Http\Controllers\Api\SelfSiteController::class, 'selfSiteVerify']);
//创建301跳转任务
Route::any('/addRedirect',[\App\Http\Controllers\Api\NoticeController::class,'addRedirect']);
... ...
... ... @@ -473,6 +473,13 @@ Route::middleware(['aloginauth'])->group(function () {
Route::any('/saveTask', [Aside\AutoPull\AutoPullController::class, 'saveTask'])->name('admin.auto_pull_saveTask');
Route::any('/taskMap', [Aside\AutoPull\AutoPullController::class, 'taskMap'])->name('admin.auto_pull_taskMap');
});
/**
* 打包静态页面模块
*/
Route::prefix('pack_dir')->group(function () {
Route::any('/', [Aside\PackDir\PackDirController::class, 'getTaskLists'])->name('admin.pack_dir_getTaskLists');
Route::any('/saveTask', [Aside\PackDir\PackDirController::class, 'saveTask'])->name('admin.pack_dir_saveTask');
});
});
//无需登录验证的路由组
... ...