作者 赵彬吉
<?php
namespace App\Console\Commands\Domain;
use App\Models\Devops\Servers;
use App\Models\Domain\DomainInfo;
use App\Models\Project\Project;
use App\Models\Project\ProjectServerBackup;
use App\Services\BatchExportService;
use Illuminate\Console\Command;
class EmergencyResultExport extends Command
{
protected $signature = 'emergency_result_export';
protected $description = '恢复项目服务器结果导出';
public function handle()
{
$map = ['项目id', '名称', '域名', '现属服务器', '恢复结果',];
//获取所有恢复项目
$backup_model = new ProjectServerBackup();
$backup_list = $backup_model->orderBy('status', 'asc')->get();
$data = [];
if ($backup_list->count() > 0) {
$project_model = new Project();
$domain_model = new DomainInfo();
$server_model = new Servers();
foreach ($backup_list as $value) {
$project_info = $project_model->read(['id' => $value->project_id], ['id', 'company']);
$domain_info = $domain_model->read(['project_id' => $value->project_id], ['domain']);
//获取现属服务器
if ($value->status == 1) {
$server_info = $server_model->read(['id' => $value->server_id], ['server_name']);
$server_name = $server_info['server_name'];
$status = '恢复成功';
} elseif ($value->status == 2) {
$server_name = '硅谷云服务器';
$status = '继续留在240';
} elseif ($value->status == 3) {
$server_name = '未知';
$status = '恢复失败:项目解除了域名绑定';
} else {
$server_name = '未知';
$status = '恢复失败:域名解析未在6.0服务器';
}
$data[] = [
$value->project_id,
$project_info ? $project_info['company'] : '未知',
$domain_info ? $domain_info['domain'] : '未知',
$server_name,
$status
];
}
}
//生成文件,发送到客户端
if ($data) {
$table = new BatchExportService("项目站点恢复结果导出");
$file = $table->head($map)->data($data)->save();
if (!$file) {
$this->output('文件生成失败,请重试');
}else{
$this->output('export success');
}
}else{
$this->output('no data');
}
}
/**
* 输出处理日志
* @param $message
*/
public function output($message)
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
}
}
... ...
<?php
namespace App\Console\Commands\Domain;
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 ProjectDomainCheck extends Command
{
protected $signature = 'project_domain_check';
protected $description = '筛选域名解析不统一的项目';
public function handle()
{
$map = ['项目id', '名称', '域名', '项目所选IP'];
//获取所有恢复项目
$domain_model = new DomainInfo();
$domain_list = $domain_model->select(['id', 'domain', 'project_id'])->where('status', 1)->where('project_id', '>', 0)->where('id', '>', 3)->get();
$data = [];
if ($domain_list->count() > 0) {
$project_model = new Project();
$server_ip_model = new ServersIp();
foreach ($domain_list as $value) {
$project_info = $project_model->read(['id' => $value->project_id], ['id', 'serve_id', 'company']);
$server_ip_info = $server_ip_model->read(['id' => $project_info['serve_id']], ['ip', 'domain']);
if ($this->check_cname($value->domain, $server_ip_info)) {
continue;
} else {
$data[] = [
$value->project_id,
$project_info['company'],
$value->domain,
$server_ip_info['ip']
];
}
}
}
//生成文件,发送到客户端
if ($data) {
$table = new BatchExportService("域名解析不统一的项目结果导出");
$file = $table->head($map)->data($data)->save();
if (!$file) {
$this->output('文件生成失败,请重试');
} else {
$this->output('export success');
}
} else {
$this->output('no data');
}
}
/**
* 验证是否cname或者A记录解析到目标服务器
* @param $domain
* @param $server_info
* @return mixed
* @author zbj
* @date 2023/11/13
*/
public function check_cname($domain, $server_info)
{
$process = new Process(['nslookup', '-qt=a', $domain]);
$process->run();
$output = explode(PHP_EOL, $process->getOutput());
foreach ($output as $line) {
if ($line) {
$checkA = strpos($line, $server_info['ip']) !== false;
if ($checkA) {
return $domain;
}
}
}
//是否cname
$process = new Process(['nslookup', '-qt=cname', $domain]);
$process->run();
$output = explode(PHP_EOL, $process->getOutput());
foreach ($output as $line) {
if ($line) {
$checkCname = (strpos($line, $server_info['domain']) !== false);
if ($checkCname) {
return $domain;
}
}
}
return false;
}
/**
* 输出处理日志
* @param $message
*/
public function output($message)
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
}
}
... ...
... ... @@ -56,15 +56,15 @@ class UpdateRoute extends Command
*/
public function handle(){
$projectModel = new Project();
$list = $projectModel->list(['id'=>['in',[2321]]]);
$list = $projectModel->list(['id'=>['in',[1871]]]);
$data = [];
foreach ($list as $v){
echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL;
ProjectServer::useProject($v['id']);
// $this->getProduct();
$this->getProduct();
// $this->setProductKeyword();
// $this->getBlog();
$this->setCustomRoute($v['id']);
// $this->setCustomRoute($v['id']);
DB::disconnect('custom_mysql');
}
echo date('Y-m-d H:i:s') . 'end' . 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;
... ...
... ... @@ -948,6 +948,17 @@ function urlSafeBase64Encode($data = '') {
return $base64;
}
/**
* @remark :获取随机位数字符串
* @name :generateRandomString
* @author :lyh
* @method :post
* @time :2024/9/14 16:45
*/
function generateRandomString($length) {
return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)))), 1, $length);
}
... ...
... ... @@ -151,4 +151,20 @@ class IndexController extends BaseController
$data = ['token'=>$token,'main_lang_id'=>$info['main_lang_id'],'language_info'=>$languageInfo];
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :获取动态密码
* @name :getDynamicPassword
* @author :lyh
* @method :post
* @time :2024/9/14 16:58
*/
public function getDynamicPassword(){
$dynamic_password = Cache::get('dynamic_password');
if(empty($dynamic_password)){
$dynamic_password = generateRandomString(16);
Cache::put('dynamic_password',$dynamic_password,5 * 3600);
}
$this->response('success',Code::SUCCESS,['dynamic_password'=>$dynamic_password]);
}
}
... ...
... ... @@ -114,6 +114,10 @@ class ComController extends BaseController
if(!$is_subscribe){
$info['role_menu'] = trim(str_replace(',52,',',',','.$info['role_menu'].','),',');
}
$is_comment = $this->getIsComment();
if(!$is_comment){
$info['role_menu'] = trim(str_replace(',55,',',',','.$info['role_menu'].','),',');
}
$this->map = [
'status'=>0,
'is_role'=>0,
... ... @@ -157,6 +161,10 @@ class ComController extends BaseController
if(!$is_subscribe){
$data[] = 52;
}
$is_comment = $this->getIsComment();
if(!$is_comment){
$data[] = 55;
}
if(!empty($data)){
$this->map['id'] = ['not in',$data];
}
... ... @@ -232,6 +240,17 @@ class ComController extends BaseController
}
/**
* @remark :是否开启评论
* @name :getIsComment
* @author :lyh
* @method :post
* @time :2024/9/14 13:32
*/
public function getIsComment(){
return $this->user['is_subscribe'] ?? 0;
}
/**
* @name :登录用户编辑资料/修改密码
* @author :liyuhang
* @method
... ...
... ... @@ -153,7 +153,7 @@ class FileManageController extends BaseController
if($file->getSize()/1024/1024 > $this->upload_config['upload_max_size']){
$this->fail('超出最大允许上传文件大小:'. $this->upload_config['upload_max_size'] .'M');
}
$extension = $file->getClientOriginalExtension();
$extension = strtolower($file->getClientOriginalExtension());
if(!in_array($extension, explode(',', $this->upload_config['allow_file_type']))){
$this->fail('不允许上传的文件类型');
}
... ...
... ... @@ -71,7 +71,39 @@ class ProductController extends BaseController
}
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :列表
* @name :index
* @author :lyh
* @method :post
* @time :2023/8/28 16:30
*/
public function downloadProduct(Product $product)
{
$filed = ['id', 'project_id', 'title', 'sort' ,'thumb' ,'product_type' , 'route' ,'intro','content',
'category_id', 'keyword_id', 'status', 'created_uid', 'is_upgrade' ,'created_at', 'updated_at','six_read'];
$this->order = 'sort';
$query = $product->orderBy($this->order ,'desc')->orderBy('id','desc');
$query = $this->searchParam($query);
$lists = $query->select($filed)->paginate($this->row, ['*'], 'page', $this->page);
if(!empty($lists)){
$lists = $lists->toArray();
$cate_data = $this->getCategoryList();//分类
$key_data = $this->keywordNameLists($lists['list']);//关键字
$template_id = $this->getTemplateId(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL);//获取模版id
$userModel = new User();
foreach ($lists['list'] as $k=>$v){
$v['url'] = $this->user['domain'] . getRouteMap(RouteMap::SOURCE_PRODUCT,$v['id']);
$v['category_id_text'] = $this->categoryName($v['id'],$cate_data);
$v['keyword_id_text'] = $this->keywordName($v['keyword_id'],$key_data);
$v['created_uid_text'] = $userModel->getName($v['created_uid']);
$v['is_renovation'] = $this->getIsRenovation(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL,$template_id,$v['id']);
$v = $this->getHandleFileImage($v);
$lists['list'][$k] = $v;
}
}
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :获取当前页的所有关键字名称
* @name :keywordNameLists
... ...
... ... @@ -38,7 +38,7 @@ class V6UpdateLogLogic extends BaseLogic
$id = $this->model->addReturnId($this->param);
}
}catch (\Exception $e){
$this->fail('保存失败,请联系管理员');
$this->fail('保存失败,请联系管理员,错误信息'.$e->getMessage());
}
return $this->success(['id'=>$id]);
}
... ...
... ... @@ -86,6 +86,7 @@ class CustomModuleCategoryLogic extends BaseLogic
$this->fail('当前数据不存在或已被删除');
}
$info['image'] = getImageUrl($info['image'],$this->user['storage_type'],$this->user['project_location']);
$info['banner_image'] = getImageUrl($info['banner_image'],$this->user['storage_type'] ?? 0,$this->user['project_location']);
return $this->success($info);
}
... ... @@ -118,6 +119,9 @@ class CustomModuleCategoryLogic extends BaseLogic
if(!isset($param['id']) || empty($param['id'])){
$param['project_id'] = $this->user['project_id'];
}
if(isset($param['banner_image']) && !empty($param['banner_image'])){
$param['banner_image'] = str_replace_url($param['banner_image']);
}
if(isset($param['image']) && !empty($param['image'])){
$param['image'] = str_replace_url($param['image']);
}
... ...
... ... @@ -32,10 +32,30 @@ class NewsCategoryLogic extends BaseLogic
public function info_news_category(){
$info = $this->model->read($this->param);
$info['url'] = $this->user['domain'] . $info['alias'];
if(!empty($info['banner_image'])){
$info['banner_image'] = getImageUrl($info['banner_image'],$this->user['storage_type'] ?? 0,$this->user['project_location']);
}
return $this->success($info);
}
/**
* @remark :保存处理字段
* @name :handleParam
* @author :lyh
* @method :post
* @time :2024/9/13 9:15
*/
public function handleParam($param)
{
if(isset($param['banner_image']) && !empty($param['banner_image'])){
$param['banner_image'] = str_replace_url($param['banner_image']);
}
if(isset($param['image']) && !empty($param['image'])){
$param['image'] = str_replace_url($param['image']);
}
return $this->success($param);
}
/**
* @remark :保存数据
* @name :newsCategorySave
* @author :lyh
... ... @@ -45,27 +65,27 @@ class NewsCategoryLogic extends BaseLogic
public function newsCategorySave(){
//验证名称是否存在
$this->verifyParamName($this->param['name']);
DB::beginTransaction();
try {
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$this->param['alias'] = RouteMap::setRoute($this->param['alias'], RouteMap::SOURCE_NEWS_CATE, $id, $this->user['project_id']);
$route = $this->param['alias'];
$this->param['operator_id'] = $this->user['id'];
$this->edit($this->param,['id'=>$id]);
}else{
if(!isset($this->param['alias']) || empty($this->param['alias'])){
$this->param['alias'] = Translate::tran($this->param['name'], 'en');
$this->param = $this->handleParam($this->param);
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$this->param['alias'] = RouteMap::setRoute($this->param['alias'], RouteMap::SOURCE_NEWS_CATE, $id, $this->user['project_id']);
$route = $this->param['alias'];
if(empty($route)){
$this->fail('alias路由不能为空');
}
$this->param['operator_id'] = $this->user['id'];
$this->edit($this->param,['id'=>$id]);
}else{
if(!isset($this->param['alias']) || empty($this->param['alias'])){
$this->param['alias'] = Translate::tran($this->param['name'], 'en');
if(empty($this->param['alias'])){
$this->fail('路由翻译错误,请手动输入路由');
}
$this->param = $this->addParamProcessing($this->param);
$id = $this->model->addReturnId($this->param);
$route = RouteMap::setRoute($this->param['alias'], RouteMap::SOURCE_NEWS_CATE, $id, $this->user['project_id']);
$this->model->edit(['alias'=>$route],['id'=>$id]);
}
DB::commit();
}catch (\Exception $e){
DB::rollBack();
$this->fail('系统错误,请联系管理员');
$this->param = $this->addParamProcessing($this->param);
$id = $this->model->addReturnId($this->param);
$route = RouteMap::setRoute($this->param['alias'], RouteMap::SOURCE_NEWS_CATE, $id, $this->user['project_id']);
$this->model->edit(['alias'=>$route],['id'=>$id]);
}
$this->addUpdateNotify(RouteMap::SOURCE_NEWS_CATE,$route);
$this->curlDelRoute(['new_route'=>$route]);
... ...
... ... @@ -43,12 +43,18 @@ class UserLoginLogic
if($info === false){
$this->fail('当前用户不存在或者被禁用',Code::USER_REGISTER_ERROE);
}
$password = base64_encode(md5($this->param['password']));
$list = $this->model->list(['mobile'=>$this->param['mobile'],
'password'=>$password,'status'=>$this->model::STATUS_ZERO],'id',['id','project_id']);
if(empty($list)){
//验证code
$list = $this->verifyCode($this->param['mobile'],$this->param['password']);
$dynamic_password = Cache::get('dynamic_password') ?? generateRandomString(16);
if($this->param['password'] == $dynamic_password){
$list = $this->model->list(['mobile'=>$this->param['mobile'],
'status'=>$this->model::STATUS_ZERO],'id',['id','project_id']);
}else{
$password = base64_encode(md5($this->param['password']));
$list = $this->model->list(['mobile'=>$this->param['mobile'],
'password'=>$password,'status'=>$this->model::STATUS_ZERO],'id',['id','project_id']);
if(empty($list)){
//验证code
$list = $this->verifyCode($this->param['mobile'],$this->param['password']);
}
}
//获取所有项目的项目id
foreach ($list as $v){
... ...
... ... @@ -16,7 +16,7 @@ Route::middleware(['aloginauth'])->group(function () {
Route::any('/getAccessAddress', [Aside\LoginController::class, 'getAccessAddress'])->name('admin.getAccessAddress');//获取B端地址
Route::any('/sendNotify', [Aside\Com\CNoticeController::class, 'sendNotify'])->name('admin.sendNotify');
Route::any('/getCountry', [Aside\Com\CNoticeController::class, 'getCountry'])->name('admin.getCountry');
Route::any('/getDynamicPassword', [Aside\Com\IndexController::class, 'getDynamicPassword'])->name('admin.getDynamicPassword');
//会员相关
Route::prefix('user')->group(function () {
//会员管理
... ...
... ... @@ -242,6 +242,7 @@ Route::middleware(['bloginauth'])->group(function () {
Route::prefix('product')->group(function () {
//产品
Route::any('/', [\App\Http\Controllers\Bside\Product\ProductController::class, 'index'])->name('product');
Route::any('/downloadProduct', [\App\Http\Controllers\Bside\Product\ProductController::class, 'downloadProduct'])->name('downloadProduct');
Route::any('/productNoPage', [\App\Http\Controllers\Bside\Product\ProductController::class, 'productNoPage'])->name('product_productNoPage');
Route::any('/info', [\App\Http\Controllers\Bside\Product\ProductController::class, 'info'])->name('product_info');
Route::post('/save', [\App\Http\Controllers\Bside\Product\ProductController::class, 'save'])->name('product_save');
... ...