DomainInfoLogic.php 15.1 KB
<?php

namespace App\Http\Logic\Aside\Domain;

use App\Http\Logic\Aside\BaseLogic;
use App\Models\Devops\ServerConfig;
use App\Models\Devops\ServersIp;
use App\Models\Domain\DomainCreateTask;
use App\Models\Domain\DomainInfo;
use App\Models\Domain\DomainRedirectTask;
use App\Models\Project\CountryCustom;
use App\Models\Project\DeployBuild;
use App\Models\Project\Project;

class DomainInfoLogic extends BaseLogic
{

    public function __construct()
    {
        parent::__construct();
        $this->model = new DomainInfo();
        $this->param = $this->requestAll;

    }

    /**
     * @remark :保存域名
     * @name   :createDomain
     * @author :lyh
     * @method :post
     * @time   :2023/8/1 14:52
     */
    public function saveDomain()
    {
        $domain = parse_url($this->param['domain'], PHP_URL_HOST);
        if(!empty($domain)){
            $this->param['domain'] = trim($domain['host']);
        }
        //验证域名
        $this->verifyDomain($this->param['domain'],$this->param['id'] ?? '');
        if(isset($this->param['id']) && !empty($this->param['id'])){
            $rs = $this->model->edit($this->param,['id'=>$this->param['id']]);
        }else{
            //查看域名是否以WWW开头
            if (strpos($this->param['domain'], 'www.') === 0) {
                $this->param['other_domain'] = json_encode([str_replace('www', '*', $this->param['domain']),str_replace('www.', '', $this->param['domain'])]);
            }
            $rs = $this->model->add($this->param);
        }
        if($rs === false){
            $this->fail('error');
        }
        return $this->success();
    }


    /**
     * @remark :验证域名是否存在
     * @name   :verifyDomain
     * @author :lyh
     * @method :post
     * @time   :2023/8/1 14:59
     */
    public function verifyDomain($domain,$id = ''){
        if(!empty($id)){
            $info = $this->model->read(['domain'=>$domain,'id'=>['!=',$id]]);
            if ($info !== false) {
                $this->fail('当前域名已存在');
            }
        }else{
            $info = $this->model->read(['domain'=>$domain]);
            if ($info !== false) {
                $this->fail('当前域名已存在');
            }
        }
        return $this->success();
    }

    /**
     * @remark :修改当前域名状态
     * @name   :editStatus
     * @author :lyh
     * @method :post
     * @time   :2023/8/1 15:43
     */
    public function editDomainStatus(){
        //查看当前域名是否有项目在使用
        if($this->param['status'] != $this->model::STATUS_ONE){
            $info = $this->model->read(['id'=>$this->param['id']]);
            if($info === false){
                $this->fail('当前域名有项目正在使用中');
            }
        }
        $rs = $this->model->edit(['status'=>$this->param['status']],['id'=>$this->param['id']]);
        if($rs === false){
            $this->fail('error');
        }
        return $this->success();
    }

    /**
     * @remark :获取所有项目列表
     * @name   :getProjectList
     * @author :lyh
     * @method :post
     * @time   :2023/8/1 16:10
     */
    public function getProjectList($map){
        $projectModel = new Project();
        $lists = $projectModel->list($map,'id',['id','title']);
        return $this->success($lists);
    }

    /**
     * 删除域名
     */
    public function delDomain(){
        $ids = $this->param['id'];
        // 初始化数据
        if (FALSE == is_array($ids))
            $ids = [$ids];
        foreach ($ids as $k => $v){
            $domain = DomainInfo::where(['id' => $v])->first();
            if (empty($domain))
                continue;
            if (FALSE == empty($domain['project_id']))
                $this->fail($domain->domain . '域名正在使用中, 删除失败!');
            $domain->delete();
        }
        return $this->success();
    }


    public function infoDomain(){
        $info = $this->model->read(['id'=>$this->param['id']]);
        if($info === false){
            $this->fail('当前数据不存在或者已被删除');
        }
        if(!empty($info['project_id'])){
            $info['company'] = (new Project())->read(['id'=>$info['project_id']],['title'])['title'];
        }
        return $this->success($info);
    }

    /**
     * @remark :保存证书相关配置
     * @name   :sslSave
     * @author :lyh
     * @method :post
     * @time   :2023/11/6 10:50
     */
    public function sslSave(){
        $info = $this->model->read(['id'=>$this->param['id']]);
        if($info === false || empty($info['domain'])){
            $this->fail('当前数据不存在或者已被删除');
        }
        //获取项目数据
        $project_model = new Project();
        $project_info = $project_model->read(['id'=>$info['project_id']],['serve_id','type','project_type']);
        if($project_info === false){
            $this->fail('获取项目数据失败');
        }
        if($project_info['type'] == Project::TYPE_CLOSE){
            $this->fail('项目已关闭,无法执行此操作');
        }
        if($project_info['project_type'] == Project::PROJECT_TYPE_SEO){
            $this->fail('白帽SEO项目,无法执行此操作');
        }
        $serverIpModel = new ServersIp();
        $serversIpInfo = $serverIpModel->read(['id'=>$project_info['serve_id']],['servers_id','ip','domain']);
        if($serversIpInfo === false){
            $this->fail('获取服务器数据失败');
        }
        if($serversIpInfo['servers_id'] == ServerConfig::SELF_TEST_ID){
            $this->fail('请切换服务器,生成站点不能使用测试服务器');
        }
        if($serversIpInfo['servers_id'] == ServerConfig::SELF_SITE_ID){
            $this->model->edit(['amp_status' => $this->param['amp_status'] ?? 0],['id'=>$this->param['id']]);
            $this->fail('自建站服务器无需生成站点');
        }
        //域名是否都已经解析
        if(!check_domain_record($info['domain'], $serversIpInfo)){
            $this->fail('域名' . $info['domain'] . '未解析至目标服务器');
        }
        $domain_301 = '';
        foreach ($this->param['other_domain']??[] as $other_domain){
            if($other_domain && substr($other_domain,0,2) != '*.'){
                if(check_domain_record($other_domain,['domain'=>'','ip'=>DomainInfo::SERVER_IP_301])){
                    $domain_301 = $other_domain;
                }else{
                    if(!check_domain_record($other_domain, $serversIpInfo)){
                        $this->fail('域名' . $other_domain . '未解析至目标服务器');
                    }
                }
            }
        }

        //如果要开通amp站点,判断m域名是否已经解析
        if(isset($this->param['amp_status']) && $this->param['amp_status'] == 1){
            $domain_array = parse_url($info['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);
            if(!check_domain_record($amp_domain, $serversIpInfo)){
                $this->fail('AMP站点域名' . $amp_domain . '未解析至目标服务器');
            }

            $is_redirect = $this->param['is_redirect'] ?? 0;
        }else{
            //未开通amp站,主站和m站相互跳转也自动取消
            $is_redirect = 0;
        }

        $not_allow_ip = array_filter($this->param['not_allow_ip'] ?? []);
        if($not_allow_ip){
            //判断禁止访问IP是否填写正确
            foreach ($not_allow_ip as $vn){
                $vn_count = count(explode('.',$vn));
                if($vn_count != 4){
                    $this->fail('禁止访问IP填写有误');
                }
            }
        }

        $extend_config = [];
        $unique_extend = [];
        if(isset($this->param['extend_config']) && $this->param['extend_config']){
            foreach ($this->param['extend_config'] as $k=>$v){
                if($v['origin'] && (!in_array($v['origin'],$unique_extend))){
                    $unique_extend[] = $v['origin'];
                    $extend_config[] = $v;
                }
            }
        }

        $amp_extend_config = [];
        $amp_unique_extend = [];
        if(isset($this->param['amp_extend_config']) && $this->param['amp_extend_config']){
            foreach ($this->param['amp_extend_config'] as $ka=>$va){
                if($va['origin'] && (!in_array($va['origin'],$amp_unique_extend))){
                    $amp_unique_extend[] = $va['origin'];
                    $amp_extend_config[] = $va;
                }
            }
        }

        //小语种为二级目录的站点,强制跳转https
        $is_https = 0;
        $buildModel = new DeployBuild();
        $build_info = $buildModel->read(['project_id' => $info['project_id']], ['linking_format']);
        if ($build_info && $build_info['linking_format'] == 1) {
            $is_https = 1;
        }

        //保存301跳转数据+其他域名
        $data = [
            'other_domain'=>json_encode(array_filter($this->param['other_domain'] ?? [])),
            'extend_config'=>json_encode($extend_config),
            'type'=>$this->param['type'],
            'private_key' => $this->param['key'] ?? '',
            'private_cert' => $this->param['cert'] ?? '',
            'is_https' => $is_https,
            'amp_status' => $this->param['amp_status'] ?? 0,
            'amp_type' => $this->param['amp_type'] ?? 0,
            'amp_extend_config'=>json_encode($amp_extend_config),
            'amp_private_key' => $this->param['amp_key'] ?? '',
            'amp_private_cert' => $this->param['amp_cert'] ?? '',
            'not_allow_country'=>json_encode(array_filter($this->param['not_allow_country'] ?? [])),
            'not_allow_ip'=>json_encode($not_allow_ip),
            'is_redirect' => $is_redirect,
        ];
        $this->model->edit($data,['id'=>$this->param['id']]);

        //新增建站任务
        $task_model = new DomainCreateTask();
        $task_info = $task_model->read(['type'=>DomainCreateTask::TYPE_MAIN,'domain_id'=>$this->param['id'],'status'=>['<',DomainCreateTask::STATUS_SUC]]);
        if(!$task_info){
            $task_model->add([
                'server_id' => $serversIpInfo['servers_id'],
                'project_id' => $info['project_id'],
                'domain_id' => $this->param['id'],
                'type' => DomainCreateTask::TYPE_MAIN
            ]);
        }else{
            if($task_info['status'] == DomainCreateTask::STATUS_UN){
                $task_model->edit(['sort'=>0],['id'=>$task_info['id']]);
            }
        }
        if($data['amp_status']){
            $task_amp_info = $task_model->read(['type'=>DomainCreateTask::TYPE_AMP,'domain_id'=>$this->param['id'],'status'=>['<',DomainCreateTask::STATUS_SUC]]);
            if(!$task_amp_info){
                $task_model->add([
                    'server_id' => $serversIpInfo['servers_id'],
                    'project_id' => $info['project_id'],
                    'domain_id' => $this->param['id'],
                    'type' => DomainCreateTask::TYPE_AMP
                ]);
            }
        }

        //新增重定向任务
        $redirect_model = new DomainRedirectTask();
        if($domain_301){
            $task_redirect_info = $redirect_model->read(['origin_domain'=>$domain_301]);
            if(!$task_redirect_info){
                $redirect_model->add([
                    'origin_domain'=> $domain_301,
                    'other_domain' => json_encode([]),
                    'target_domain' => $info['domain']
                ]);
            }
        }

        return $this->success();
    }

    /**
     * 设置语种自定义跳转链接
     * @param $project_id
     * @return array
     * @author Akun
     * @date 2024/03/05 9:48
     */
    public function country_custom($project_id){
        $project_model = new Project();
        $project_info = $project_model->read(['id'=>$project_id],'serve_id');
        if($project_info === false){
            $this->fail('获取项目数据失败');
        }

        $custom_model = new CountryCustom();
        if($this->param['is_create']){
            //需要创建站点
            $serverIpModel = new ServersIp();
            $serversIpInfo = $serverIpModel->read(['id'=>$project_info['serve_id']],['servers_id','ip','domain']);
            if($serversIpInfo === false){
                $this->fail('获取服务器数据失败');
            }
            if($serversIpInfo['servers_id'] == ServerConfig::SELF_TEST_ID){
                $this->fail('请切换服务器,生成站点不能使用测试服务器');
            }
            if($serversIpInfo['servers_id'] == ServerConfig::SELF_SITE_ID){
                $this->fail('自建站服务器无法生成站点');
            }
            //域名是否都已经解析
            if(strpos($this->param['custom_domain'],'//') === false){
                $this->param['custom_domain'] = '//'.$this->param['custom_domain'];
            }
            $domain_arr = parse_url($this->param['custom_domain']);
            if(!isset($domain_arr['host'])){
                $this->fail('自定义域名填写错误');
            }
            $this->param['custom_domain'] = $domain_arr['host'];
            //判断域名是否已经被使用
            $has_info = $custom_model->read(['custom_domain'=>$this->param['custom_domain']]);
            if($has_info && ($has_info['project_id'] != $project_id || $has_info['language_id'] != $this->param['language_id'])){
                $this->fail('自定义域名已被使用');
            }
            if(!check_domain_record($this->param['custom_domain'], $serversIpInfo)){
                $this->fail('域名' . $this->param['custom_domain'] . '未解析至目标服务器');
            }
        }else{
            $this->param['custom_domain'] = str_replace('https://','',$this->param['custom_domain']);
            $this->param['custom_domain'] = str_replace('http://','',$this->param['custom_domain']);
            $this->param['custom_domain'] = str_replace('//','',$this->param['custom_domain']);
        }

        $info = $custom_model->read(['project_id'=>$project_id,'language_id'=>$this->param['language_id']]);
        if($info === false){
            $this->param['project_id'] = $project_id;
            $id = $custom_model->addReturnId($this->param);
        }else{
            $custom_model->edit($this->param,['id'=>$info['id']]);
            $id = $info['id'];
        }

        if($this->param['is_create']){
            $task_model = new DomainCreateTask();
            $task_amp_info = $task_model->read(['type'=>DomainCreateTask::TYPE_CUSTOM,'domain_id'=>$id,'status'=>['<',DomainCreateTask::STATUS_SUC]]);
            if(!$task_amp_info){
                $task_model->add([
                    'server_id' => $serversIpInfo['servers_id'],
                    'project_id' => $project_id,
                    'domain_id' => $id,
                    'type' => DomainCreateTask::TYPE_CUSTOM
                ]);
            }
        }

        return $this->success();
    }
}