DomainInfoLogic.php 15.0 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');
        if ($project_info === false) {
            $this->fail('获取项目数据失败');
        }
        $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 = $this->param['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
            ]);
        }
        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();
    }
}