DomainInfoLogic.php 11.6 KB
<?php

namespace App\Http\Logic\Aside\Domain;


use App\Enums\Common\Code;
use App\Exceptions\AsideGlobalException;
use App\Exceptions\BsideGlobalException;
use App\Http\Logic\Aside\BaseLogic;
use App\Http\Logic\Aside\Devops\ServerInformationLogic;
use App\Models\Aside\Domain\DomainInfo;
use App\Models\Aside\Domain\DomainInfoLog;
use App\Models\Devops\ServerInformation;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class DomainInfoLogic extends BaseLogic
{
    /**
     * @var array
     */
    private $param;

    public function __construct()
    {
        parent::__construct();

        $this->model = new ServerInformation();

        $this->param = $this->requestAll;

    }

    /**
     * 添加数据
     * @return array
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function create()
    {
        $request = $this->param ?? [];
        if ($this->checkDomain($request['domain'])) {
            return $this->fail('域名已存在!');
        }
        $domain = new DomainInfo();
        $this->extracted($request, $domain);
        DB::beginTransaction();
        if ($domain->save()) {
            $original = $domain->getOriginal();
            $original['belong_to'] = $request['belong_to'];
            $original['status'] = $request['status'];
            // 添加日志
            $this->domain_action_log(DomainInfoLog::ACTION_ADD, $original, $original, '添加域名信息成功 - ID : ' . $domain->id);
            DB::commit();
            return $this->success();
        }
        DB::rollBack();
        return $this->fail('域名信息添加失败');

    }

    /**
     * 修改数据
     * @return array
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function update()
    {
        $domain = $this->getDomain();
        $original = $domain->getOriginal();
        $original['belong_to'] = $domain->BelongToStr($original['belong_to']);
        $original['status'] = $domain->StatusToStr($original['status']);
        $request = $this->param;
        $this->extracted($request, $domain, $original);
        // 检查ip是否存在
        if ($domain->domain != $request['domain']) {
            if ($this->checkDomain($request['domain'])) {
                $this->fail('域名信息修改失败,域名已存在', Code::USER_ERROR);
            }
        }
        DB::beginTransaction();
        if ($domain->save()) {
            $fields_array = $domain->FieldsArray();
            $revised = $domain->getAttributes();
            $diff = array_diff_assoc($original, $revised);
            unset($diff['created_at']);
            unset($diff['updated_at']);
            unset($diff['deleted']);
            $remarks = '';
            if ($diff) {
                $remarks .= '修改ID为 ' . $domain->id . ' 的服务器信息,修改内容为:';
                foreach ($diff as $key => $value) {
                    $remarks .= $fields_array[$key] . ' 由 ' . $value . ' 修改为 ' . $revised[$key] . '; ';
                }
            } else {
                $remarks .= '修改ID为 ' . $domain->id . ' 的域名信息,无修改';
            }
            // 添加日志
            $this->domain_action_log(DomainInfoLog::ACTION_UPDATE, $original, $revised, $remarks);
            DB::commit();
            return $this->success();
        }
        DB::rollBack();
        return $this->fail('域名信息修改失败');
    }

    /**
     * 根据ID获取数据
     * @return array
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function getDomain(int $deleted = DomainInfo::DELETED_NORMAL)
    {
        $id = $this->param['id'] ?? 0;
        if (!$id) {
            return $this->fail('ID不能为空');
        }
        $data = DomainInfo::query()->where('deleted', $deleted)->find($id);
        if (!$data) {
            return $this->fail('数据不存在!');
        }
        return $data;
    }

    /**
     * 检查域名是否存在
     * @param $domain
     * @return bool
     */
    public function checkDomain($domain)
    {
        $usIp = DomainInfo::query()->where('domain', $domain)->first();
        if ($usIp) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 详情
     * @param int $deleted
     * @return array|Builder|Collection|Model
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function domainInfo(int $deleted = DomainInfo::DELETED_NORMAL)
    {
        $id = $this->param['id'] ?? 0;
        if (!$id) {
            return $this->fail('ID不能为空');
        }
        $data = DomainInfo::query()->where('deleted', $deleted)->find($id, ['domain', 'belong_to', 'status', 'domain_start_time', 'domain_end_time', 'certificate_start_time', 'certificate_end_time', 'created_at', 'updated_at']);
        if (!$data) {
            return $this->fail('数据不存在!');
        }
        return $data;
    }

    /**
     * 服务器操作日志
     * @param int $action 1:添加 2:修改 3:删除 4:搜索 5:详情 6:列表
     * @param array $original 原始数据
     * @param array $revised 修改后数据
     */
    public function domain_action_log(int $action = DomainInfoLog::ACTION_ADD, array $original = [], array $revised = [], $remarks = '')
    {
        $log = new DomainInfoLog();
        $this->log($log, $action, $original, $revised, $remarks);
    }

    /**
     * @param array $request
     * @param $domain
     * @param array $original
     * @return void
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function extracted( array $request, $domain, array $original = [])
    {
        $domain->domain = trim($request['domain']) ?? $original['domain'];
        if (!$this->validateDomain($domain->domain)) {
            $this->fail('域名格式错误');
        }
        $domain->belong_to = trim($request['belong_to']) ?? $original['belong_to'];                                                                  // 域名归属 1 - 公司 2 - 客户
        $domain->status = trim($request['status']) ?? $original['status'];                                                                        // 域名状态 0 - 正常 1 - 关闭
        $domain->domain_start_time = trim($request['domain_start_time']) ?? $original['domain_start_time'];                                                  // 域名开始时间
        $domain->domain_end_time = trim($request['domain_end_time']) ?? $original['domain_end_time'];
        $domain->certificate_start_time = trim($request['certificate_start_time']) ?? $original['certificate_start_time'];                                        // 证书开始时间
        $domain->certificate_end_time = trim($request['certificate_end_time']) ?? $original['certificate_end_time'];                                            // 证书结束时间
    }

    /**
     * 批量获取数据删除
     * @return array
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function get_batch_update($action = DomainInfoLog::ACTION_DELETE, $deleted = DomainInfo::DELETED_NORMAL)
    {
        $ids = (new ServerInformationLogic())->getIds();
        $data = DomainInfo::query()->whereIn('id', $ids)->where('deleted', $deleted)->get();
        $restore_ids = $data->pluck('id')->toArray();
        $actionArr = DomainInfoLog::actionArr();
        $actionStr = $actionArr[$action];
        if (empty($restore_ids)) {
            $this->fail($actionStr . '域名信息不存在!', Code::USER_ERROR);
        }
        $original = $data->toArray();
        DB::beginTransaction();
        try {
            $update = $deleted == DomainInfo::DELETED_NORMAL ? DomainInfo::DELETED_DELETE : DomainInfo::DELETED_NORMAL;
            DomainInfo::query()->whereIn('id', $restore_ids)->update(['deleted' => $update]);
            $this->domain_action_log($action, $original, $original, $actionStr . '域名信息 - ID : ' . implode(', ', $restore_ids));
            DB::commit();
            return $this->success();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->fail('域名信息' . $actionStr . '失败', Code::USER_ERROR);
        }
    }

    /**
     * 证书到期时间
     * @return array
     */
    public function getDomainCertificateTime($domain)
    {
        $domain = trim($domain);
        $data = [];
        $context = stream_context_create(['ssl' => ['capture_peer_cert' => true]]); // Notice: only 7.0.7+ supports this
        $stream = stream_socket_client("ssl://$domain:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
        if ($stream) {
            $params = stream_context_get_params($stream);
            $peerCertificate = openssl_x509_parse($params['options']['ssl']['peer_certificate']);
            if ($peerCertificate) {
                $validFrom = date_create_from_format('U', $peerCertificate['validFrom_time_t']);    // 有效期开始时间
                $validTo = date_create_from_format('U', $peerCertificate['validTo_time_t']);        // 有效期结束时间
                $data['validFrom'] = $validFrom->format('Y-m-d H:i:s');
                $data['validTo'] = $validTo->format('Y-m-d H:i:s');
            }
        }
        return $data;
    }

    /**
     * 获取所有正常域名信息
     * @return Builder[]|Collection
     */
    public function getAllDomain()
    {
        return DomainInfo::query()->where('status', 1)
            ->where('deleted', DomainInfo::DELETED_NORMAL)
            ->orderBy('updated_at', 'desc')
            ->get();
    }

    /**
     * 域名到期时间
     * @return array
     */
    public function getDomainTime($domain)
    {
        $conJson = file_get_contents("http://openai.waimaoq.com/v1/whois_api?domain={$domain}");
        $conArr = json_decode($conJson, true);
        $data = [];
        if ($conArr['code'] == 200) {
            $con = $conArr['text'];
            $data['domain'] = $domain;
            $data['validFrom'] = $con['creation_date'];
            $data['validTo'] = $con['expiration_date'];
        }
        return $data;
    }

    /**
     * 验证给定的值是否是有效的域名。
     *
     * @param mixed $value
     * @return bool
     */
    public function validateDomain($value)
    {
        // 从域中删除任何空间或路径。
        $domain = preg_replace('/\s|\/.*$/', '', $value);
        // 验证域是否至少包含一个句点。
        if (strpos($domain, '.') === false) {
            return false;
        }
        // 验证域是否以句点开始或结束。
        if (strpos($domain, '.') === 0 || strrpos($domain, '.') === strlen($domain) - 1) {
            return false;
        }
        // 验证域是否不包含无效字符。
        if (!preg_match('/^[a-zA-Z0-9\-\.]+$/', $domain)) {
            return false;
        }
        // 验证域是否具有有效的顶级域。
        $tld = substr($domain, strrpos($domain, '.') + 1);
        if (!in_array($tld, ['com', 'net', 'org'])) { // 如有必要,添加更多TLD。
            return false;
        }
        return true;
    }

    /**
     * 根据域名更新证书到期时间
     * @param $id
     * @param $updata
     * @return array
     * @throws AsideGlobalException
     * @throws BsideGlobalException
     */
    public function updateDomain($id, $updata)
    {
        $isRes = DomainInfo::query()->where('id', $id)->where('deleted', DomainInfo::DELETED_NORMAL)->update($updata);
        if ($isRes) {
            return $this->success();
        } else {
            return $this->fail('更新域名到期时间失败');
        }
    }
}