mirror of
https://github.com/netcccyun/dnsmgr.git
synced 2026-05-09 15:06:28 +02:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ed93cd295 | ||
|
|
2bcd590ce9 | ||
|
|
a3b26085a6 | ||
|
|
410a33e870 | ||
|
|
f85ac7f724 | ||
|
|
86adfd018a | ||
|
|
3b93ee1203 | ||
|
|
a5145accd6 | ||
|
|
30427a9704 | ||
|
|
4145e282f9 | ||
|
|
53ec0e12df | ||
|
|
b8addd6d27 | ||
|
|
0d1d7d3c67 | ||
|
|
8bdf58651c | ||
|
|
350a0bd306 | ||
|
|
ab074da839 | ||
|
|
57a237f898 | ||
|
|
bf6a091c8d | ||
|
|
14700052b8 | ||
|
|
f43f2b196d | ||
|
|
949b52722a | ||
|
|
1c504f3b04 | ||
|
|
8e4fd32f8c | ||
|
|
5cd6b108f0 | ||
|
|
424d2c8132 | ||
|
|
86bffab357 | ||
|
|
c1edf905f3 | ||
|
|
b252816711 | ||
|
|
7a58292fb9 | ||
|
|
d4b7bcfbf6 | ||
|
|
f20b132d97 | ||
|
|
ad85fa7c22 |
@@ -2,7 +2,6 @@ APP_DEBUG = false
|
||||
|
||||
[APP]
|
||||
DEFAULT_TIMEZONE = Asia/Shanghai
|
||||
SYS_KEY = {syskey}
|
||||
|
||||
[DATABASE]
|
||||
TYPE = mysql
|
||||
|
||||
86
README.md
86
README.md
@@ -9,7 +9,12 @@
|
||||
- DNSLA
|
||||
- CloudFlare
|
||||
|
||||
本系统支持多用户,每个用户可分配不同的域名解析权限;支持API接口,支持获取域名独立DNS控制面板登录链接,方便各种IDC系统对接。
|
||||
### 功能特性
|
||||
|
||||
- 多用户管理,可为每个用户可分配不同的域名解析权限
|
||||
- 提供API接口,可获取域名单独的登录链接,方便各种IDC系统对接
|
||||
- 容灾切换功能,支持ping、tcp、http(s)检测协议并自动暂停/修改域名解析,并支持邮件、微信公众号通知
|
||||
- CF优选IP功能,支持获取最新的Cloudflare优选IP,并自动更新到解析记录
|
||||
|
||||
### 演示截图
|
||||
|
||||
@@ -29,6 +34,10 @@
|
||||
|
||||

|
||||
|
||||
CF优选IP功能,添加优选IP任务
|
||||
|
||||

|
||||
|
||||
### 部署方法
|
||||
|
||||
* 从[Release](https://github.com/netcccyun/dnsmgr/releases)页面下载安装包
|
||||
@@ -74,6 +83,81 @@ location / {
|
||||
</IfModule>
|
||||
```
|
||||
|
||||
### Docker部署方法
|
||||
|
||||
首先需要安装Docker,然后执行以下命令拉取镜像并启动(启动后监听8081端口):
|
||||
|
||||
```
|
||||
docker run --name dnsmgr -dit -p 8081:80 -v /var/dnsmgr:/app/www netcccyun/dnsmgr
|
||||
```
|
||||
|
||||
访问并安装好后如果容灾切换未自动启动,重启容器即可:
|
||||
|
||||
```
|
||||
docker restart dnsmgr
|
||||
```
|
||||
|
||||
### docker-compose部署方法
|
||||
|
||||
```
|
||||
version: '3'
|
||||
services:
|
||||
dnsmgr-web:
|
||||
container_name: dnsmgr-web
|
||||
stdin_open: true
|
||||
tty: true
|
||||
ports:
|
||||
- 8081:80
|
||||
volumes:
|
||||
- /volume1/docker/dnsmgr/web:/app/www
|
||||
image: netcccyun/dnsmgr
|
||||
depends_on:
|
||||
- dnsmgr-mysql
|
||||
networks:
|
||||
- dnsmgr-network
|
||||
|
||||
dnsmgr-mysql:
|
||||
container_name: dnsmgr-mysql
|
||||
restart: always
|
||||
ports:
|
||||
- 3306:3306
|
||||
volumes:
|
||||
- ./mysql/conf/my.cnf:/etc/mysql/my.cnf
|
||||
- ./mysql/logs:/logs
|
||||
- ./mysql/data:/var/lib/mysql
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=123456
|
||||
- TZ=Asia/Shanghai
|
||||
image: mysql:5.7
|
||||
networks:
|
||||
- dnsmgr-network
|
||||
|
||||
networks:
|
||||
dnsmgr-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
在运行之前请创建好目录
|
||||
```
|
||||
mkdir -p ./web
|
||||
mkdir -p ./mysql/conf
|
||||
mkdir -p ./mysql/logs
|
||||
mkdir -p ./mysql/data
|
||||
|
||||
vim mysql/conf/my.cnf
|
||||
[mysqld]
|
||||
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
|
||||
```
|
||||
|
||||
登陆mysql容器创建数据库
|
||||
```
|
||||
docker exec -it dnsmgr-mysql /bin/bash
|
||||
mysql -uroot -p123456
|
||||
create database dnsmgr;
|
||||
```
|
||||
|
||||
在install界面链接IP填写dnsmgr-mysql
|
||||
|
||||
### 版权信息
|
||||
|
||||
版权所有Copyright © 2023~2024 by 消失的彩虹海(https://blog.cccyun.cn)
|
||||
|
||||
@@ -102,15 +102,17 @@ abstract class BaseController
|
||||
if ($url) {
|
||||
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : (string)$this->app->route->buildUrl($url);
|
||||
}
|
||||
if(empty($msg)) $msg = '未知错误';
|
||||
if (empty($msg)) {
|
||||
$msg = '未知错误';
|
||||
}
|
||||
|
||||
if (request()->isApi) {
|
||||
return json(['code'=>$code=='success'?0:-1, 'msg'=>$msg]);
|
||||
if ($this->request->isApi) {
|
||||
return json(['code' => $code == 'success' ? 0 : -1, 'msg' => $msg]);
|
||||
}
|
||||
if (request()->isAjax()) {
|
||||
return json(['code'=>$code=='success'?0:-1, 'msg'=>$msg, 'url'=>$url]);
|
||||
if ($this->request->isAjax()) {
|
||||
return json(['code' => $code == 'success' ? 0 : -1, 'msg' => $msg, 'url' => $url]);
|
||||
}
|
||||
|
||||
|
||||
View::assign([
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
@@ -10,6 +11,7 @@ use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use app\lib\TaskRunner;
|
||||
|
||||
class Dmtask extends Command
|
||||
@@ -23,42 +25,46 @@ class Dmtask extends Command
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$res = Db::name('config')->cache('configs', 0)->column('value', 'key');
|
||||
Config::set($res, 'sys');
|
||||
|
||||
config_set('run_error', '');
|
||||
if(!extension_loaded('swoole')){
|
||||
if (!extension_loaded('swoole')) {
|
||||
$output->writeln('[Error] 未安装Swoole扩展');
|
||||
config_set('run_error', '未安装Swoole扩展');
|
||||
return;
|
||||
}
|
||||
try{
|
||||
try {
|
||||
$output->writeln('进程启动成功.');
|
||||
$this->runtask();
|
||||
}catch(Exception $e){
|
||||
$output->writeln('[Error] '.$e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
$output->writeln('[Error] ' . $e->getMessage());
|
||||
config_set('run_error', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function runtask(){
|
||||
\Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
|
||||
\Co\run(function() {
|
||||
private function runtask()
|
||||
{
|
||||
\Co::set(['hook_flags' => SWOOLE_HOOK_ALL]);
|
||||
\Co\run(function () {
|
||||
$date = date("Ymd");
|
||||
$count = config_get('run_count', null, true) ?? 0;
|
||||
while(true){
|
||||
while (true) {
|
||||
sleep(1);
|
||||
if($date != date("Ymd")){
|
||||
if ($date != date("Ymd")) {
|
||||
$count = 0;
|
||||
$date = date("Ymd");
|
||||
}
|
||||
|
||||
$rows = Db::name('dmtask')->where('checknexttime', '<=', time())->where('active', 1)->order('id', 'ASC')->select();
|
||||
foreach($rows as $row){
|
||||
\go(function () use($row) {
|
||||
try{
|
||||
foreach ($rows as $row) {
|
||||
\go(function () use ($row) {
|
||||
try {
|
||||
(new TaskRunner())->execute($row);
|
||||
} catch (\Swoole\ExitException $e) {
|
||||
echo $e->getStatus()."\n";
|
||||
echo $e->getStatus() . "\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->__toString()."\n";
|
||||
echo $e->__toString() . "\n";
|
||||
}
|
||||
});
|
||||
Db::name('dmtask')->where('id', $row['id'])->update([
|
||||
|
||||
33
app/command/Opiptask.php
Normal file
33
app/command/Opiptask.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use Exception;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use app\lib\OptimizeService;
|
||||
|
||||
class Opiptask extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
// 指令配置
|
||||
$this->setName('opiptask')
|
||||
->setDescription('CF优选IP任务');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$res = Db::name('config')->cache('configs', 0)->column('value', 'key');
|
||||
Config::set($res, 'sys');
|
||||
|
||||
(new OptimizeService())->execute();
|
||||
}
|
||||
}
|
||||
558
app/common.php
558
app/common.php
@@ -1,228 +1,254 @@
|
||||
<?php
|
||||
// 应用公共文件
|
||||
use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
|
||||
function get_curl($url, $post=0, $referer=0, $cookie=0, $header=0, $ua=0, $nobody=0, $addheader=0)
|
||||
function get_curl($url, $post = 0, $referer = 0, $cookie = 0, $header = 0, $ua = 0, $nobody = 0, $addheader = 0)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$httpheader[] = "Accept: */*";
|
||||
$httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
|
||||
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
|
||||
$httpheader[] = "Connection: close";
|
||||
if($addheader){
|
||||
$httpheader = array_merge($httpheader, $addheader);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
|
||||
if ($post) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
}
|
||||
if ($header) {
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
}
|
||||
if ($cookie) {
|
||||
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
|
||||
}
|
||||
if($referer){
|
||||
curl_setopt($ch, CURLOPT_REFERER, $referer);
|
||||
}
|
||||
if ($ua) {
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
|
||||
}
|
||||
else {
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.0.4; es-mx; HTC_One_X Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0");
|
||||
}
|
||||
if ($nobody) {
|
||||
curl_setopt($ch, CURLOPT_NOBODY, 1);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$ret = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $ret;
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$httpheader[] = "Accept: */*";
|
||||
$httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
|
||||
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
|
||||
$httpheader[] = "Connection: close";
|
||||
if ($addheader) {
|
||||
$httpheader = array_merge($httpheader, $addheader);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
|
||||
if ($post) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
}
|
||||
if ($header) {
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
}
|
||||
if ($cookie) {
|
||||
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
|
||||
}
|
||||
if ($referer) {
|
||||
curl_setopt($ch, CURLOPT_REFERER, $referer);
|
||||
}
|
||||
if ($ua) {
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.0.4; es-mx; HTC_One_X Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0");
|
||||
}
|
||||
if ($nobody) {
|
||||
curl_setopt($ch, CURLOPT_NOBODY, 1);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$ret = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function real_ip($type=0){
|
||||
function real_ip($type = 0)
|
||||
{
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
if($type<=0 && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
|
||||
foreach ($matches[0] AS $xip) {
|
||||
if ($type <= 0 && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
|
||||
foreach ($matches[0] as $xip) {
|
||||
if (filter_var($xip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
$ip = $xip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif ($type<=0 && isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
} elseif ($type <= 0 && isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif ($type<=1 && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
} elseif ($type <= 1 && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
} elseif ($type<=1 && isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
} elseif ($type <= 1 && isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
$ip = $_SERVER['HTTP_X_REAL_IP'];
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
|
||||
function strexists($string, $find) {
|
||||
return !(strpos($string, $find) === FALSE);
|
||||
function strexists($string, $find)
|
||||
{
|
||||
return !(strpos($string, $find) === FALSE);
|
||||
}
|
||||
|
||||
function dstrpos($string, $arr) {
|
||||
if(empty($string)) return false;
|
||||
foreach((array)$arr as $v) {
|
||||
if(strpos($string, $v) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
function dstrpos($string, $arr)
|
||||
{
|
||||
if (empty($string)) return false;
|
||||
foreach ((array)$arr as $v) {
|
||||
if (strpos($string, $v) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkmobile() {
|
||||
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
$ualist = array('android', 'midp', 'nokia', 'mobile', 'iphone', 'ipod', 'blackberry', 'windows phone');
|
||||
if((dstrpos($useragent, $ualist) || strexists($_SERVER['HTTP_ACCEPT'], "VND.WAP") || strexists($_SERVER['HTTP_VIA'],"wap")))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
function checkmobile()
|
||||
{
|
||||
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
$ualist = array('android', 'midp', 'nokia', 'mobile', 'iphone', 'ipod', 'blackberry', 'windows phone');
|
||||
if ((dstrpos($useragent, $ualist) || strexists($_SERVER['HTTP_ACCEPT'], "VND.WAP") || strexists($_SERVER['HTTP_VIA'], "wap"))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
|
||||
$ckey_length = 4;
|
||||
$key = md5($key);
|
||||
$keya = md5(substr($key, 0, 16));
|
||||
$keyb = md5(substr($key, 16, 16));
|
||||
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
|
||||
$cryptkey = $keya.md5($keya.$keyc);
|
||||
$key_length = strlen($cryptkey);
|
||||
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
|
||||
$string_length = strlen($string);
|
||||
$result = '';
|
||||
$box = range(0, 255);
|
||||
$rndkey = array();
|
||||
for($i = 0; $i <= 255; $i++) {
|
||||
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
|
||||
}
|
||||
for($j = $i = 0; $i < 256; $i++) {
|
||||
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
|
||||
$tmp = $box[$i];
|
||||
$box[$i] = $box[$j];
|
||||
$box[$j] = $tmp;
|
||||
}
|
||||
for($a = $j = $i = 0; $i < $string_length; $i++) {
|
||||
$a = ($a + 1) % 256;
|
||||
$j = ($j + $box[$a]) % 256;
|
||||
$tmp = $box[$a];
|
||||
$box[$a] = $box[$j];
|
||||
$box[$j] = $tmp;
|
||||
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
|
||||
}
|
||||
if($operation == 'DECODE') {
|
||||
if(((int)substr($result, 0, 10) == 0 || (int)substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
|
||||
return substr($result, 26);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return $keyc.base64_encode($result);
|
||||
}
|
||||
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
|
||||
{
|
||||
$ckey_length = 4;
|
||||
$key = md5($key);
|
||||
$keya = md5(substr($key, 0, 16));
|
||||
$keyb = md5(substr($key, 16, 16));
|
||||
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
|
||||
$cryptkey = $keya.md5($keya.$keyc);
|
||||
$key_length = strlen($cryptkey);
|
||||
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
|
||||
$string_length = strlen($string);
|
||||
$result = '';
|
||||
$box = range(0, 255);
|
||||
$rndkey = array();
|
||||
for ($i = 0; $i <= 255; $i++) {
|
||||
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
|
||||
}
|
||||
for ($j = $i = 0; $i < 256; $i++) {
|
||||
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
|
||||
$tmp = $box[$i];
|
||||
$box[$i] = $box[$j];
|
||||
$box[$j] = $tmp;
|
||||
}
|
||||
for ($a = $j = $i = 0; $i < $string_length; $i++) {
|
||||
$a = ($a + 1) % 256;
|
||||
$j = ($j + $box[$a]) % 256;
|
||||
$tmp = $box[$a];
|
||||
$box[$a] = $box[$j];
|
||||
$box[$j] = $tmp;
|
||||
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
|
||||
}
|
||||
if ($operation == 'DECODE') {
|
||||
if (((int)substr($result, 0, 10) == 0 || (int)substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
|
||||
return substr($result, 26);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return $keyc.base64_encode($result);
|
||||
}
|
||||
}
|
||||
|
||||
function random($length, $numeric = 0) {
|
||||
$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
|
||||
$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
|
||||
$hash = '';
|
||||
$max = strlen($seed) - 1;
|
||||
for($i = 0; $i < $length; $i++) {
|
||||
$hash .= $seed[mt_rand(0, $max)];
|
||||
}
|
||||
return $hash;
|
||||
function random($length, $numeric = 0)
|
||||
{
|
||||
$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
|
||||
$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
|
||||
$hash = '';
|
||||
$max = strlen($seed) - 1;
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$hash .= $seed[mt_rand(0, $max)];
|
||||
}
|
||||
return $hash;
|
||||
}
|
||||
|
||||
function checkDomain($domain){
|
||||
if(empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0 ,1) == '.' || substr($domain, 0 ,1) == '*' && substr($domain, 1 ,1) != '.' || substr_count($domain, '*')>1 || strpos($domain, '*')>0 || strlen($domain)<4) return false;
|
||||
return true;
|
||||
function checkDomain($domain)
|
||||
{
|
||||
if (empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0, 1) == '.' || substr($domain, 0, 1) == '*' && substr($domain, 1, 1) != '.' || substr_count($domain, '*') > 1 || strpos($domain, '*') > 0 || strlen($domain) < 4) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function getSubstr($str, $leftStr, $rightStr)
|
||||
{
|
||||
$left = strpos($str, $leftStr);
|
||||
$start = $left+strlen($leftStr);
|
||||
$right = strpos($str, $rightStr, $start);
|
||||
if($left < 0) return '';
|
||||
if($right>0){
|
||||
return substr($str, $start, $right-$start);
|
||||
}else{
|
||||
return substr($str, $start);
|
||||
}
|
||||
$left = strpos($str, $leftStr);
|
||||
$start = $left + strlen($leftStr);
|
||||
$right = strpos($str, $rightStr, $start);
|
||||
if ($left < 0) return '';
|
||||
if ($right > 0) {
|
||||
return substr($str, $start, $right - $start);
|
||||
} else {
|
||||
return substr($str, $start);
|
||||
}
|
||||
}
|
||||
|
||||
function checkRefererHost(){
|
||||
if(!request()->header('referer'))return false;
|
||||
$url_arr = parse_url(request()->header('referer'));
|
||||
$http_host = request()->header('host');
|
||||
if(strpos($http_host,':'))$http_host = substr($http_host, 0, strpos($http_host, ':'));
|
||||
function checkRefererHost()
|
||||
{
|
||||
if (!Request::header('referer')) {
|
||||
return false;
|
||||
}
|
||||
$url_arr = parse_url(Request::header('referer'));
|
||||
$http_host = Request::header('host');
|
||||
if (strpos($http_host, ':')) {
|
||||
$http_host = substr($http_host, 0, strpos($http_host, ':'));
|
||||
}
|
||||
return $url_arr['host'] === $http_host;
|
||||
}
|
||||
|
||||
function checkIfActive($string) {
|
||||
$array=explode(',',$string);
|
||||
$action = request()->action();
|
||||
if (in_array($action,$array)){
|
||||
return 'active';
|
||||
}else
|
||||
return null;
|
||||
function checkIfActive($string)
|
||||
{
|
||||
$array = explode(',', $string);
|
||||
$action = Request::action();
|
||||
if (in_array($action, $array)) {
|
||||
return 'active';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getSid() {
|
||||
function getSid()
|
||||
{
|
||||
return md5(uniqid(mt_rand(), true) . microtime());
|
||||
}
|
||||
function getMd5Pwd($pwd, $salt=null) {
|
||||
function getMd5Pwd($pwd, $salt = null)
|
||||
{
|
||||
return md5(md5($pwd) . md5('1277180438'.$salt));
|
||||
}
|
||||
|
||||
function isNullOrEmpty($str){
|
||||
return $str === null || $str === '';
|
||||
function isNullOrEmpty($str)
|
||||
{
|
||||
return $str === null || $str === '';
|
||||
}
|
||||
|
||||
function checkPermission($type, $domain = null){
|
||||
$user = request()->user;
|
||||
if(empty($user)) return false;
|
||||
if($user['level'] == 2) return true;
|
||||
if($type == 1 && $user['level'] == 1 || $type == 0 && $user['level'] >= 0){
|
||||
if($domain == null) return true;
|
||||
if(in_array($domain, $user['permission'])){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
function checkPermission($type, $domain = null)
|
||||
{
|
||||
$user = Request()->user;
|
||||
if (empty($user)) {
|
||||
return false;
|
||||
}
|
||||
if ($user['level'] == 2) {
|
||||
return true;
|
||||
}
|
||||
if ($type == 1 && $user['level'] == 1 || $type == 0 && $user['level'] >= 0) {
|
||||
if ($domain == null) {
|
||||
return true;
|
||||
}
|
||||
if (in_array($domain, $user['permission'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getAdminSkin(){
|
||||
$skin = cookie('admin_skin');
|
||||
if(empty($skin)){
|
||||
$skin = config_get('admin_skin');
|
||||
}
|
||||
if(empty($skin)){
|
||||
$skin = 'skin-black-blue';
|
||||
}
|
||||
return $skin;
|
||||
function getAdminSkin()
|
||||
{
|
||||
$skin = cookie('admin_skin');
|
||||
if (empty($skin)) {
|
||||
$skin = config_get('admin_skin');
|
||||
}
|
||||
if (empty($skin)) {
|
||||
$skin = 'skin-black-blue';
|
||||
}
|
||||
return $skin;
|
||||
}
|
||||
|
||||
function config_get($key, $default = null, $force = false)
|
||||
{
|
||||
if ($force) {
|
||||
$value = Db::name('config')->where('key', $key)->value('value');
|
||||
} else {
|
||||
$value = config('sys.'.$key);
|
||||
}
|
||||
if ($force) {
|
||||
$value = Db::name('config')->where('key', $key)->value('value');
|
||||
} else {
|
||||
$value = config('sys.' . $key);
|
||||
}
|
||||
return $value ?: $default;
|
||||
}
|
||||
|
||||
function config_set($key, $value)
|
||||
{
|
||||
$res = Db::name('config')->replace()->insert(['key'=>$key, 'value'=>$value]);
|
||||
return $res!==false;
|
||||
$res = Db::name('config')->replace()->insert(['key' => $key, 'value' => $value]);
|
||||
return $res !== false;
|
||||
}
|
||||
|
||||
function getMillisecond()
|
||||
@@ -231,23 +257,189 @@ function getMillisecond()
|
||||
return (int)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
|
||||
}
|
||||
|
||||
function getDnsType($value){
|
||||
if(filter_var($value, FILTER_VALIDATE_IP))return 'A';
|
||||
else return 'CNAME';
|
||||
function getDnsType($value)
|
||||
{
|
||||
if (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
return 'A';
|
||||
} elseif (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
return 'AAAA';
|
||||
} else {
|
||||
return 'CNAME';
|
||||
}
|
||||
}
|
||||
|
||||
function convert_second($s){
|
||||
$m = floor($s/60);
|
||||
if($m == 0){
|
||||
return $s.'秒';
|
||||
}else{
|
||||
$s = $s%60;
|
||||
$h = floor($m/60);
|
||||
if($h == 0){
|
||||
return $m.'分钟'.$s.'秒';
|
||||
}else{
|
||||
$m = $m%60;
|
||||
return $h.'小时'.$m.'分钟'.$s.'秒';
|
||||
}
|
||||
}
|
||||
function convert_second($s)
|
||||
{
|
||||
$m = floor($s / 60);
|
||||
if ($m == 0) {
|
||||
return $s.'秒';
|
||||
} else {
|
||||
$s = $s % 60;
|
||||
$h = floor($m / 60);
|
||||
if ($h == 0) {
|
||||
return $m.'分钟'.$s.'秒';
|
||||
} else {
|
||||
$m = $m % 60;
|
||||
return $h.'小时'.$m.'分钟'.$s.'秒';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMainDomain($host)
|
||||
{
|
||||
if (filter_var($host, FILTER_VALIDATE_IP)) return $host;
|
||||
$domain_root = file_get_contents(app()->getBasePath() . 'data' . DIRECTORY_SEPARATOR . 'domain_root.txt');
|
||||
$domain_root = explode("\r\n", $domain_root);
|
||||
$data = explode('.', $host);
|
||||
$co_ta = count($data);
|
||||
if ($co_ta <= 2) return $host;
|
||||
$domain_name = $data[$co_ta - 2] . '.' . $data[$co_ta - 1];
|
||||
if (in_array($domain_name, $domain_root) && $co_ta > 2) {
|
||||
$domain_name = $data[$co_ta - 3] . '.' . $domain_name;
|
||||
}
|
||||
return $domain_name;
|
||||
}
|
||||
|
||||
function check_proxy($url, $proxy_server, $proxy_port, $type, $proxy_user, $proxy_pwd)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
if ($type == 'https') {
|
||||
$proxy_type = CURLPROXY_HTTPS;
|
||||
} elseif ($type == 'sock4') {
|
||||
$proxy_type = CURLPROXY_SOCKS4;
|
||||
} elseif ($type == 'sock5') {
|
||||
$proxy_type = CURLPROXY_SOCKS5;
|
||||
} else {
|
||||
$proxy_type = CURLPROXY_HTTP;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
|
||||
curl_setopt($ch, CURLOPT_PROXYPORT, intval($proxy_port));
|
||||
if (!empty($proxy_user) && !empty($proxy_pwd)) {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_user . ':' . $proxy_pwd);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
|
||||
$httpheader[] = "Accept: */*";
|
||||
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
|
||||
$httpheader[] = "Connection: close";
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36');
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
|
||||
curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$errmsg = curl_error($ch);
|
||||
curl_close($ch);
|
||||
throw new Exception($errmsg);
|
||||
}
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($httpCode >= 200 && $httpCode < 400) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Exception('HTTP状态码异常:' . $httpCode);
|
||||
}
|
||||
}
|
||||
|
||||
function clearDirectory($dir): bool
|
||||
{
|
||||
// 确保路径是目录
|
||||
if (!is_dir($dir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 打开目录
|
||||
$items = scandir($dir);
|
||||
foreach ($items as $item) {
|
||||
// 跳过 '.' 和 '..'
|
||||
if ($item == '.' || $item == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 完整路径
|
||||
$path = $dir . DIRECTORY_SEPARATOR . $item;
|
||||
|
||||
// 如果是目录,递归删除其内容
|
||||
if (is_dir($path)) {
|
||||
clearDirectory($path);
|
||||
// 删除空目录
|
||||
rmdir($path);
|
||||
} else {
|
||||
// 删除文件
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function curl_client($url, $data = null, $referer = null, $cookie = null, $headers = null, $proxy = false, $method = null, $timeout = 5)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$httpheader[] = "Accept: */*";
|
||||
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
|
||||
$httpheader[] = "Connection: close";
|
||||
if ($headers) {
|
||||
$httpheader = array_merge($httpheader, $headers);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36");
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
if ($data) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
if ($cookie) {
|
||||
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
|
||||
}
|
||||
if ($referer) {
|
||||
curl_setopt($ch, CURLOPT_REFERER, $referer);
|
||||
}
|
||||
if ($method) {
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
}
|
||||
|
||||
if ($proxy) {
|
||||
$proxy_server = config_get('proxy_server');
|
||||
$proxy_port = intval(config_get('proxy_port'));
|
||||
$proxy_userpwd = config_get('proxy_user') . ':' . config_get('proxy_pwd');
|
||||
$proxy_type = config_get('proxy_type');
|
||||
if ($proxy_type == 'https') {
|
||||
$proxy_type = CURLPROXY_HTTPS;
|
||||
} elseif ($proxy_type == 'sock4') {
|
||||
$proxy_type = CURLPROXY_SOCKS4;
|
||||
} elseif ($proxy_type == 'sock5') {
|
||||
$proxy_type = CURLPROXY_SOCKS5;
|
||||
} else {
|
||||
$proxy_type = CURLPROXY_HTTP;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
|
||||
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
|
||||
if ($proxy_userpwd != ':') {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_userpwd);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
|
||||
}
|
||||
|
||||
$ret = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
curl_close($ch);
|
||||
throw new Exception('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$redirect_url = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
|
||||
curl_close($ch);
|
||||
$header = substr($ret, 0, $headerSize);
|
||||
$body = substr($ret, $headerSize);
|
||||
return ['code' => $httpCode, 'redirect_url' => $redirect_url, 'header' => $header, 'body' => $body];
|
||||
}
|
||||
@@ -1,58 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\BaseController;
|
||||
use Exception;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
use app\lib\DnsHelper;
|
||||
|
||||
class Auth extends BaseController
|
||||
{
|
||||
|
||||
public function verifycode()
|
||||
public function login()
|
||||
{
|
||||
return captcha();
|
||||
}
|
||||
$login_limit_count = 5; //登录失败次数
|
||||
$login_limit_file = app()->getRuntimePath() . '@login.lock';
|
||||
|
||||
public function login(){
|
||||
$login_limit_count = 5;//登录失败次数
|
||||
$login_limit_file = app()->getRuntimePath().'@login.lock';
|
||||
|
||||
if(request()->islogin){
|
||||
if ($this->request->islogin) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
if(request()->isAjax()){
|
||||
$username = input('post.username',null,'trim');
|
||||
$password = input('post.password',null,'trim');
|
||||
$code = input('post.code',null,'trim');
|
||||
|
||||
if(empty($username) || empty($password)){
|
||||
return json(['code'=>-1, 'msg'=>'用户名或密码不能为空']);
|
||||
if ($this->request->isAjax()) {
|
||||
$username = input('post.username', null, 'trim');
|
||||
$password = input('post.password', null, 'trim');
|
||||
$code = input('post.code', null, 'trim');
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
return json(['code' => -1, 'msg' => '用户名或密码不能为空']);
|
||||
}
|
||||
if(!captcha_check($code)){
|
||||
return json(['code'=>-1, 'msg'=>'验证码错误', 'vcode'=>1]);
|
||||
if (!captcha_check($code)) {
|
||||
return json(['code' => -1, 'msg' => '验证码错误', 'vcode' => 1]);
|
||||
}
|
||||
if (file_exists($login_limit_file)) {
|
||||
$login_limit = unserialize(file_get_contents($login_limit_file));
|
||||
if ($login_limit['count'] >= $login_limit_count && $login_limit['time'] > time() - 86400) {
|
||||
exit(json_encode(['code' => -1, 'msg' => '多次登录失败,暂时禁止登录。可删除/runtime/@login.lock文件解除限制', 'vcode'=>1]));
|
||||
if ($login_limit['count'] >= $login_limit_count && $login_limit['time'] > time() - 7200) {
|
||||
return json(['code' => -1, 'msg' => '多次登录失败,暂时禁止登录。可删除/runtime/@login.lock文件解除限制', 'vcode' => 1]);
|
||||
}
|
||||
}
|
||||
$user = Db::name('user')->where('username', $username)->find();
|
||||
if($user && password_verify($password, $user['password'])){
|
||||
if($user['status'] == 0) return json(['code'=>-1, 'msg'=>'此用户已被封禁', 'vcode'=>1]);
|
||||
Db::name('log')->insert(['uid' => $user['id'], 'action' => '登录后台', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
if ($user['status'] == 0) return json(['code' => -1, 'msg' => '此用户已被封禁', 'vcode' => 1]);
|
||||
Db::name('log')->insert(['uid' => $user['id'], 'action' => '登录后台', 'data' => 'IP:' . $this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
|
||||
DB::name('user')->where('id', $user['id'])->update(['lasttime' => date("Y-m-d H:i:s")]);
|
||||
$session = md5($user['id'].$user['password']);
|
||||
$expiretime = time()+2562000;
|
||||
$token = authcode("user\t{$user['id']}\t{$session}\t{$expiretime}", 'ENCODE', env('app.sys_key'));
|
||||
$session = md5($user['id'] . $user['password']);
|
||||
$expiretime = time() + 2562000;
|
||||
$token = authcode("user\t{$user['id']}\t{$session}\t{$expiretime}", 'ENCODE', config_get('sys_key'));
|
||||
cookie('user_token', $token, ['expire' => $expiretime, 'httponly' => true]);
|
||||
return json(['code'=>0]);
|
||||
}else{
|
||||
if($user){
|
||||
Db::name('log')->insert(['uid' => $user['id'], 'action' => '登录失败', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
|
||||
if (file_exists($login_limit_file)) {
|
||||
unlink($login_limit_file);
|
||||
}
|
||||
return json(['code' => 0]);
|
||||
} else {
|
||||
if ($user) {
|
||||
Db::name('log')->insert(['uid' => $user['id'], 'action' => '登录失败', 'data' => 'IP:' . $this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
|
||||
}
|
||||
if (!file_exists($login_limit_file)) {
|
||||
$login_limit = ['count' => 0, 'time' => 0];
|
||||
@@ -80,36 +77,41 @@ class Auth extends BaseController
|
||||
|
||||
public function quicklogin()
|
||||
{
|
||||
$domain = input('get.domain',null,'trim');
|
||||
$timestamp = input('get.timestamp',null,'trim');
|
||||
$token = input('get.token',null,'trim');
|
||||
$sign = input('get.sign',null,'trim');
|
||||
if(empty($domain) || empty($timestamp) || empty($token) || empty($sign)){
|
||||
$domain = input('get.domain', null, 'trim');
|
||||
$timestamp = input('get.timestamp', null, 'trim');
|
||||
$token = input('get.token', null, 'trim');
|
||||
$sign = input('get.sign', null, 'trim');
|
||||
if (empty($domain) || empty($timestamp) || empty($token) || empty($sign)) {
|
||||
return $this->alert('error', '参数错误');
|
||||
}
|
||||
if($timestamp < time()-300 || $timestamp > time()+300){
|
||||
if ($timestamp < time() - 300 || $timestamp > time() + 300) {
|
||||
return $this->alert('error', '时间戳无效');
|
||||
}
|
||||
if(md5(env('app.sys_key').$domain.$timestamp.$token.env('app.sys_key')) !== $sign){
|
||||
if (md5(config_get('sys_key') . $domain . $timestamp . $token . config_get('sys_key')) !== $sign) {
|
||||
return $this->alert('error', '签名错误');
|
||||
}
|
||||
if($token != cache('quicklogin_'.$domain)){
|
||||
if ($token != cache('quicklogin_' . $domain)) {
|
||||
return $this->alert('error', 'Token无效');
|
||||
}
|
||||
$row = Db::name('domain')->where('name', $domain)->find();
|
||||
if(!$row){
|
||||
if (!$row) {
|
||||
return $this->alert('error', '该域名不存在');
|
||||
}
|
||||
if(!$row['is_sso']){
|
||||
if (!$row['is_sso']) {
|
||||
return $this->alert('error', '该域名不支持快捷登录');
|
||||
}
|
||||
|
||||
Db::name('log')->insert(['uid' => 0, 'action' => '域名快捷登录', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s"), 'domain' => $domain]);
|
||||
Db::name('log')->insert(['uid' => 0, 'action' => '域名快捷登录', 'data' => 'IP:' . $this->clientip, 'addtime' => date("Y-m-d H:i:s"), 'domain' => $domain]);
|
||||
|
||||
$session = md5($row['id'].$row['name']);
|
||||
$expiretime = time()+2562000;
|
||||
$token = authcode("domain\t{$row['id']}\t{$session}\t{$expiretime}", 'ENCODE', env('app.sys_key'));
|
||||
$session = md5($row['id'] . $row['name']);
|
||||
$expiretime = time() + 2562000;
|
||||
$token = authcode("domain\t{$row['id']}\t{$session}\t{$expiretime}", 'ENCODE', config_get('sys_key'));
|
||||
cookie('user_token', $token, ['expire' => $expiretime, 'httponly' => true]);
|
||||
return redirect('/record/'.$row['id']);
|
||||
return redirect('/record/' . $row['id']);
|
||||
}
|
||||
|
||||
public function verifycode()
|
||||
{
|
||||
return captcha();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\BaseController;
|
||||
@@ -6,18 +7,17 @@ use Exception;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
use think\facade\Cache;
|
||||
use app\lib\DnsHelper;
|
||||
|
||||
class Dmonitor extends BaseController
|
||||
{
|
||||
public function overview()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$switch_count = Db::name('dmlog')->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->count();
|
||||
$fail_count = Db::name('dmlog')->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->where('action', 1)->count();
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$switch_count = Db::name('dmlog')->where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->count();
|
||||
$fail_count = Db::name('dmlog')->where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->where('action', 1)->count();
|
||||
|
||||
$run_time = config_get('run_time', null, true);
|
||||
$run_state = $run_time ? (time()-strtotime($run_time) > 10 ? 0 : 1) : 0;
|
||||
$run_state = $run_time ? (time() - strtotime($run_time) > 10 ? 0 : 1) : 0;
|
||||
View::assign('info', [
|
||||
'run_count' => config_get('run_count', null, true) ?? 0,
|
||||
'run_time' => $run_time ?? '无',
|
||||
@@ -32,47 +32,48 @@ class Dmonitor extends BaseController
|
||||
|
||||
public function task()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function task_data(){
|
||||
if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
|
||||
public function task_data()
|
||||
{
|
||||
if (!checkPermission(2)) return json(['total' => 0, 'rows' => []]);
|
||||
$type = input('post.type/d', 1);
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
|
||||
$select = Db::name('dmtask')->alias('A')->join('domain B','A.did = B.id');
|
||||
if(!empty($kw)){
|
||||
if($type == 1){
|
||||
$select->whereLike('rr|B.name', '%'.$kw.'%');
|
||||
}elseif($type == 2){
|
||||
$select = Db::name('dmtask')->alias('A')->join('domain B', 'A.did = B.id');
|
||||
if (!empty($kw)) {
|
||||
if ($type == 1) {
|
||||
$select->whereLike('rr|B.name', '%' . $kw . '%');
|
||||
} elseif ($type == 2) {
|
||||
$select->where('recordid', $kw);
|
||||
}elseif($type == 3){
|
||||
} elseif ($type == 3) {
|
||||
$select->where('main_value', $kw);
|
||||
}elseif($type == 4){
|
||||
} elseif ($type == 4) {
|
||||
$select->where('backup_value', $kw);
|
||||
}elseif($type == 5){
|
||||
$select->whereLike('remark', '%'.$kw.'%');
|
||||
} elseif ($type == 5) {
|
||||
$select->whereLike('remark', '%' . $kw . '%');
|
||||
}
|
||||
}
|
||||
$total = $select->count();
|
||||
$list = $select->order('A.id','desc')->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
|
||||
$list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
|
||||
|
||||
foreach($list as &$row){
|
||||
foreach ($list as &$row) {
|
||||
$row['checktimestr'] = date('Y-m-d H:i:s', $row['checktime']);
|
||||
}
|
||||
|
||||
return json(['total'=>$total, 'rows'=>$list]);
|
||||
return json(['total' => $total, 'rows' => $list]);
|
||||
}
|
||||
|
||||
public function taskform()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$action = input('param.action');
|
||||
if(request()->isPost()){
|
||||
if($action == 'add'){
|
||||
if ($this->request->isPost()) {
|
||||
if ($action == 'add') {
|
||||
$task = [
|
||||
'did' => input('post.did/d'),
|
||||
'rr' => input('post.rr', null, 'trim'),
|
||||
@@ -86,27 +87,28 @@ class Dmonitor extends BaseController
|
||||
'frequency' => input('post.frequency/d'),
|
||||
'cycle' => input('post.cycle/d'),
|
||||
'timeout' => input('post.timeout/d'),
|
||||
'proxy' => input('post.proxy/d'),
|
||||
'remark' => input('post.remark', null, 'trim'),
|
||||
'recordinfo' => input('post.recordinfo', null, 'trim'),
|
||||
'addtime' => time(),
|
||||
'active' => 1
|
||||
];
|
||||
|
||||
if(empty($task['did']) || empty($task['rr']) || empty($task['recordid']) || empty($task['main_value']) || empty($task['frequency']) || empty($task['cycle'])){
|
||||
return json(['code'=>-1, 'msg'=>'必填项不能为空']);
|
||||
|
||||
if (empty($task['did']) || empty($task['rr']) || empty($task['recordid']) || empty($task['main_value']) || empty($task['frequency']) || empty($task['cycle'])) {
|
||||
return json(['code' => -1, 'msg' => '必填项不能为空']);
|
||||
}
|
||||
if($task['checktype'] > 0 && $task['timeout'] > $task['frequency']){
|
||||
return json(['code'=>-1, 'msg'=>'为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
|
||||
if ($task['checktype'] > 0 && $task['timeout'] > $task['frequency']) {
|
||||
return json(['code' => -1, 'msg' => '为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
|
||||
}
|
||||
if($task['type'] == 2 && $task['backup_value'] == $task['main_value']){
|
||||
return json(['code'=>-1, 'msg'=>'主备地址不能相同']);
|
||||
if ($task['type'] == 2 && $task['backup_value'] == $task['main_value']) {
|
||||
return json(['code' => -1, 'msg' => '主备地址不能相同']);
|
||||
}
|
||||
if(Db::name('dmtask')->where('recordid', $task['recordid'])->find()){
|
||||
return json(['code'=>-1, 'msg'=>'当前容灾切换策略已存在']);
|
||||
if (Db::name('dmtask')->where('recordid', $task['recordid'])->find()) {
|
||||
return json(['code' => -1, 'msg' => '当前容灾切换策略已存在']);
|
||||
}
|
||||
Db::name('dmtask')->insert($task);
|
||||
return json(['code'=>0, 'msg'=>'添加成功']);
|
||||
}elseif($action == 'edit'){
|
||||
return json(['code' => 0, 'msg' => '添加成功']);
|
||||
} elseif ($action == 'edit') {
|
||||
$id = input('post.id/d');
|
||||
$task = [
|
||||
'did' => input('post.did/d'),
|
||||
@@ -121,145 +123,201 @@ class Dmonitor extends BaseController
|
||||
'frequency' => input('post.frequency/d'),
|
||||
'cycle' => input('post.cycle/d'),
|
||||
'timeout' => input('post.timeout/d'),
|
||||
'proxy' => input('post.proxy/d'),
|
||||
'remark' => input('post.remark', null, 'trim'),
|
||||
'recordinfo' => input('post.recordinfo', null, 'trim'),
|
||||
];
|
||||
|
||||
if(empty($task['did']) || empty($task['rr']) || empty($task['recordid']) || empty($task['main_value']) || empty($task['frequency']) || empty($task['cycle'])){
|
||||
return json(['code'=>-1, 'msg'=>'必填项不能为空']);
|
||||
|
||||
if (empty($task['did']) || empty($task['rr']) || empty($task['recordid']) || empty($task['main_value']) || empty($task['frequency']) || empty($task['cycle'])) {
|
||||
return json(['code' => -1, 'msg' => '必填项不能为空']);
|
||||
}
|
||||
if($task['checktype'] > 0 && $task['timeout'] > $task['frequency']){
|
||||
return json(['code'=>-1, 'msg'=>'为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
|
||||
if ($task['checktype'] > 0 && $task['timeout'] > $task['frequency']) {
|
||||
return json(['code' => -1, 'msg' => '为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
|
||||
}
|
||||
if($task['type'] == 2 && $task['backup_value'] == $task['main_value']){
|
||||
return json(['code'=>-1, 'msg'=>'主备地址不能相同']);
|
||||
if ($task['type'] == 2 && $task['backup_value'] == $task['main_value']) {
|
||||
return json(['code' => -1, 'msg' => '主备地址不能相同']);
|
||||
}
|
||||
if(Db::name('dmtask')->where('recordid', $task['recordid'])->where('id', '<>', $id)->find()){
|
||||
return json(['code'=>-1, 'msg'=>'当前容灾切换策略已存在']);
|
||||
if (Db::name('dmtask')->where('recordid', $task['recordid'])->where('id', '<>', $id)->find()) {
|
||||
return json(['code' => -1, 'msg' => '当前容灾切换策略已存在']);
|
||||
}
|
||||
Db::name('dmtask')->where('id', $id)->update($task);
|
||||
return json(['code'=>0, 'msg'=>'修改成功']);
|
||||
}elseif($action == 'setactive'){
|
||||
return json(['code' => 0, 'msg' => '修改成功']);
|
||||
} elseif ($action == 'setactive') {
|
||||
$id = input('post.id/d');
|
||||
$active = input('post.active/d');
|
||||
Db::name('dmtask')->where('id', $id)->update(['active'=>$active]);
|
||||
return json(['code'=>0, 'msg'=>'设置成功']);
|
||||
}elseif($action == 'del'){
|
||||
Db::name('dmtask')->where('id', $id)->update(['active' => $active]);
|
||||
return json(['code' => 0, 'msg' => '设置成功']);
|
||||
} elseif ($action == 'del') {
|
||||
$id = input('post.id/d');
|
||||
Db::name('dmtask')->where('id', $id)->delete();
|
||||
Db::name('dmlog')->where('taskid', $id)->delete();
|
||||
return json(['code'=>0, 'msg'=>'删除成功']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'参数错误']);
|
||||
return json(['code' => 0, 'msg' => '删除成功']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '参数错误']);
|
||||
}
|
||||
}
|
||||
$task = null;
|
||||
if($action == 'edit'){
|
||||
if ($action == 'edit') {
|
||||
$id = input('get.id/d');
|
||||
$task = Db::name('dmtask')->where('id', $id)->find();
|
||||
if(empty($task)) return $this->alert('error', '任务不存在');
|
||||
if (empty($task)) return $this->alert('error', '切换策略不存在');
|
||||
}
|
||||
|
||||
$domains = [];
|
||||
foreach(Db::name('domain')->select() as $row){
|
||||
foreach (Db::name('domain')->select() as $row) {
|
||||
$domains[$row['id']] = $row['name'];
|
||||
}
|
||||
View::assign('domains', $domains);
|
||||
|
||||
View::assign('info', $task);
|
||||
View::assign('action', $action);
|
||||
View::assign('support_ping', function_exists('exec')?'1':'0');
|
||||
return View::fetch('taskform');
|
||||
View::assign('support_ping', function_exists('exec') ? '1' : '0');
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function taskinfo()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$id = input('param.id/d');
|
||||
$task = Db::name('dmtask')->where('id', $id)->find();
|
||||
if(empty($task)) return $this->alert('error', '任务不存在');
|
||||
if (empty($task)) return $this->alert('error', '切换策略不存在');
|
||||
|
||||
$switch_count = Db::name('dmlog')->where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->count();
|
||||
$fail_count = Db::name('dmlog')->where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->where('action', 1)->count();
|
||||
$switch_count = Db::name('dmlog')->where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->count();
|
||||
$fail_count = Db::name('dmlog')->where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->where('action', 1)->count();
|
||||
|
||||
$task['switch_count'] = $switch_count;
|
||||
$task['fail_count'] = $fail_count;
|
||||
if($task['type'] == 2){
|
||||
if ($task['type'] == 3) {
|
||||
$task['action_name'] = ['未知', '<font color="red">开启解析</font>', '<font color="green">暂停解析</font>'];
|
||||
} elseif ($task['type'] == 2) {
|
||||
$task['action_name'] = ['未知', '<font color="red">切换备用解析记录</font>', '<font color="green">恢复主解析记录</font>'];
|
||||
}else{
|
||||
} else {
|
||||
$task['action_name'] = ['未知', '<font color="red">暂停解析</font>', '<font color="green">启用解析</font>'];
|
||||
}
|
||||
View::assign('info', $task);
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function tasklog_data(){
|
||||
if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
|
||||
public function tasklog_data()
|
||||
{
|
||||
if (!checkPermission(2)) return json(['total' => 0, 'rows' => []]);
|
||||
$taskid = input('param.id/d');
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
$action = input('post.action/d', 0);
|
||||
|
||||
$select = Db::name('dmlog')->where('taskid', $taskid);
|
||||
if($action > 0){
|
||||
if ($action > 0) {
|
||||
$select->where('action', $action);
|
||||
}
|
||||
$total = $select->count();
|
||||
$list = $select->order('id','desc')->limit($offset, $limit)->select();
|
||||
$list = $select->order('id', 'desc')->limit($offset, $limit)->select();
|
||||
|
||||
return json(['total'=>$total, 'rows'=>$list]);
|
||||
return json(['total' => $total, 'rows' => $list]);
|
||||
}
|
||||
|
||||
public function noticeset()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if(request()->isPost()){
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if ($this->request->isPost()) {
|
||||
$params = input('post.');
|
||||
if(isset($params['mail_type']) && isset($params['mail_name2']) && $params['mail_type'] > 0){
|
||||
if (isset($params['mail_type']) && isset($params['mail_name2']) && $params['mail_type'] > 0) {
|
||||
$params['mail_name'] = $params['mail_name2'];
|
||||
unset($params['mail_name2']);
|
||||
}
|
||||
foreach ($params as $key=>$value){
|
||||
foreach ($params as $key => $value) {
|
||||
if (empty($key)) {
|
||||
continue;
|
||||
}
|
||||
config_set($key, $value);
|
||||
Cache::delete('configs');
|
||||
Cache::delete('configs');
|
||||
}
|
||||
return json(['code'=>0, 'msg'=>'succ']);
|
||||
return json(['code' => 0, 'msg' => 'succ']);
|
||||
}
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function proxyset()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if ($this->request->isPost()) {
|
||||
$params = input('post.');
|
||||
foreach ($params as $key => $value) {
|
||||
if (empty($key)) {
|
||||
continue;
|
||||
}
|
||||
config_set($key, $value);
|
||||
Cache::delete('configs');
|
||||
}
|
||||
return json(['code' => 0, 'msg' => 'succ']);
|
||||
}
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function mailtest()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$mail_name = config_get('mail_recv')?config_get('mail_recv'):config_get('mail_name');
|
||||
if(empty($mail_name)) return json(['code'=>-1, 'msg'=>'您还未设置邮箱!']);
|
||||
$result = \app\lib\MsgNotice::send_mail($mail_name,'邮件发送测试。','这是一封测试邮件!<br/><br/>来自:'.request()->root(true));
|
||||
if($result === true){
|
||||
return json(['code'=>0, 'msg'=>'邮件发送成功!']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'邮件发送失败!'.$result]);
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$mail_name = config_get('mail_recv') ? config_get('mail_recv') : config_get('mail_name');
|
||||
if (empty($mail_name)) return json(['code' => -1, 'msg' => '您还未设置邮箱!']);
|
||||
$result = \app\lib\MsgNotice::send_mail($mail_name, '邮件发送测试。', '这是一封测试邮件!<br/><br/>来自:' . $this->request->root(true));
|
||||
if ($result === true) {
|
||||
return json(['code' => 0, 'msg' => '邮件发送成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '邮件发送失败!' . $result]);
|
||||
}
|
||||
}
|
||||
|
||||
public function tgbottest()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$tgbot_token = config_get('tgbot_token');
|
||||
$tgbot_chatid = config_get('tgbot_chatid');
|
||||
if (empty($tgbot_token) || empty($tgbot_chatid)) return json(['code' => -1, 'msg' => '请先保存设置']);
|
||||
$content = "<strong>消息发送测试</strong>\n\n这是一封测试消息!\n\n来自:" . $this->request->root(true);
|
||||
$result = \app\lib\MsgNotice::send_telegram_bot($content);
|
||||
if ($result === true) {
|
||||
return json(['code' => 0, 'msg' => '消息发送成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '消息发送失败!' . $result]);
|
||||
}
|
||||
}
|
||||
|
||||
public function proxytest()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$proxy_server = trim($_POST['proxy_server']);
|
||||
$proxy_port = $_POST['proxy_port'];
|
||||
$proxy_user = trim($_POST['proxy_user']);
|
||||
$proxy_pwd = trim($_POST['proxy_pwd']);
|
||||
$proxy_type = $_POST['proxy_type'];
|
||||
try {
|
||||
check_proxy('https://dl.amh.sh/ip.htm', $proxy_server, $proxy_port, $proxy_type, $proxy_user, $proxy_pwd);
|
||||
} catch (Exception $e) {
|
||||
try {
|
||||
check_proxy('https://myip.ipip.net/', $proxy_server, $proxy_port, $proxy_type, $proxy_user, $proxy_pwd);
|
||||
} catch (Exception $e) {
|
||||
return json(['code' => -1, 'msg' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
return json(['code' => 0]);
|
||||
}
|
||||
|
||||
public function clean()
|
||||
{
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if(request()->isPost()){
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if ($this->request->isPost()) {
|
||||
$days = input('post.days/d');
|
||||
if(!$days || $days < 0) return json(['code'=>-1, 'msg'=>'参数错误']);
|
||||
Db::execute("DELETE FROM `".config('database.connections.mysql.prefix')."dmlog` WHERE `date`<'".date("Y-m-d H:i:s",strtotime("-".$days." days"))."'");
|
||||
Db::execute("OPTIMIZE TABLE `".config('database.connections.mysql.prefix')."dmlog`");
|
||||
return json(['code'=>0, 'msg'=>'清理成功']);
|
||||
if (!$days || $days < 0) return json(['code' => -1, 'msg' => '参数错误']);
|
||||
Db::execute("DELETE FROM `" . config('database.connections.mysql.prefix') . "dmlog` WHERE `date`<'" . date("Y-m-d H:i:s", strtotime("-" . $days . " days")) . "'");
|
||||
Db::execute("OPTIMIZE TABLE `" . config('database.connections.mysql.prefix') . "dmlog`");
|
||||
return json(['code' => 0, 'msg' => '清理成功']);
|
||||
}
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
$run_time = config_get('run_time', null, true);
|
||||
$run_state = $run_time ? (time()-strtotime($run_time) > 10 ? 0 : 1) : 0;
|
||||
$run_state = $run_time ? (time() - strtotime($run_time) > 10 ? 0 : 1) : 0;
|
||||
return $run_state == 1 ? 'ok' : 'error';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,55 +7,59 @@ use think\facade\Db;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use app\lib\DnsHelper;
|
||||
use Exception;
|
||||
|
||||
class Domain extends BaseController
|
||||
{
|
||||
|
||||
public function account(){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
|
||||
public function account()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
View::assign('dnsconfig', DnsHelper::$dns_config);
|
||||
return view();
|
||||
}
|
||||
|
||||
public function account_data(){
|
||||
if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
public function account_data()
|
||||
{
|
||||
if (!checkPermission(2)) return json(['total' => 0, 'rows' => []]);
|
||||
$kw = $this->request->post('kw', null, 'trim');
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
|
||||
$select = Db::name('account');
|
||||
if(!empty($kw)){
|
||||
$select->whereLike('ak|remark', '%'.$kw.'%');
|
||||
if (!empty($kw)) {
|
||||
$select->whereLike('ak|remark', '%' . $kw . '%');
|
||||
}
|
||||
$total = $select->count();
|
||||
$rows = $select->order('id','desc')->limit($offset, $limit)->select();
|
||||
$rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
|
||||
|
||||
$list = [];
|
||||
foreach($rows as $row){
|
||||
foreach ($rows as $row) {
|
||||
$row['typename'] = DnsHelper::$dns_config[$row['type']]['name'];
|
||||
$list[] = $row;
|
||||
}
|
||||
|
||||
return json(['total'=>$total, 'rows'=>$list]);
|
||||
return json(['total' => $total, 'rows' => $list]);
|
||||
}
|
||||
|
||||
public function account_op(){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
public function account_op()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$act = input('param.act');
|
||||
if($act == 'get'){
|
||||
if ($act == 'get') {
|
||||
$id = input('post.id/d');
|
||||
$row = Db::name('account')->where('id', $id)->find();
|
||||
if(!$row) return json(['code'=>-1, 'msg'=>'域名账户不存在']);
|
||||
return json(['code'=>0, 'data'=>$row]);
|
||||
}elseif($act == 'add'){
|
||||
if (!$row) return json(['code' => -1, 'msg' => '域名账户不存在']);
|
||||
return json(['code' => 0, 'data' => $row]);
|
||||
} elseif ($act == 'add') {
|
||||
$type = input('post.type');
|
||||
$ak = input('post.ak', null, 'trim');
|
||||
$sk = input('post.sk', null, 'trim');
|
||||
$ext = input('post.ext', null, 'trim');
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
if(empty($ak) || empty($sk)) return json(['code'=>-1, 'msg'=>'AccessKey和SecretKey不能为空']);
|
||||
if(Db::name('account')->where('type', $type)->where('ak', $ak)->find()){
|
||||
return json(['code'=>-1, 'msg'=>'域名账户已存在']);
|
||||
if (empty($ak) || empty($sk)) return json(['code' => -1, 'msg' => 'AccessKey和SecretKey不能为空']);
|
||||
if (Db::name('account')->where('type', $type)->where('ak', $ak)->find()) {
|
||||
return json(['code' => -1, 'msg' => '域名账户已存在']);
|
||||
}
|
||||
Db::startTrans();
|
||||
$id = Db::name('account')->insertGetId([
|
||||
@@ -67,31 +71,30 @@ class Domain extends BaseController
|
||||
'addtime' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
$dns = DnsHelper::getModel($id);
|
||||
if($dns){
|
||||
if($dns->check()){
|
||||
if ($dns) {
|
||||
if ($dns->check()) {
|
||||
Db::commit();
|
||||
return json(['code'=>0, 'msg'=>'添加域名账户成功!']);
|
||||
}else{
|
||||
return json(['code' => 0, 'msg' => '添加域名账户成功!']);
|
||||
} else {
|
||||
Db::rollback();
|
||||
return json(['code'=>-1, 'msg'=>'验证域名账户失败,'.$dns->getError()]);
|
||||
return json(['code' => -1, 'msg' => '验证域名账户失败,' . $dns->getError()]);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
Db::rollback();
|
||||
return json(['code'=>-1, 'msg'=>'DNS模块('.$type.')不存在']);
|
||||
return json(['code' => -1, 'msg' => 'DNS模块(' . $type . ')不存在']);
|
||||
}
|
||||
|
||||
}elseif($act == 'edit'){
|
||||
} elseif ($act == 'edit') {
|
||||
$id = input('post.id/d');
|
||||
$row = Db::name('account')->where('id', $id)->find();
|
||||
if(!$row) return json(['code'=>-1, 'msg'=>'域名账户不存在']);
|
||||
if (!$row) return json(['code' => -1, 'msg' => '域名账户不存在']);
|
||||
$type = input('post.type');
|
||||
$ak = input('post.ak', null, 'trim');
|
||||
$sk = input('post.sk', null, 'trim');
|
||||
$ext = input('post.ext', null, 'trim');
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
if(empty($ak) || empty($sk)) return json(['code'=>-1, 'msg'=>'AccessKey和SecretKey不能为空']);
|
||||
if(Db::name('account')->where('type', $type)->where('ak', $ak)->where('id', '<>', $id)->find()){
|
||||
return json(['code'=>-1, 'msg'=>'域名账户已存在']);
|
||||
if (empty($ak) || empty($sk)) return json(['code' => -1, 'msg' => 'AccessKey和SecretKey不能为空']);
|
||||
if (Db::name('account')->where('type', $type)->where('ak', $ak)->where('id', '<>', $id)->find()) {
|
||||
return json(['code' => -1, 'msg' => '域名账户已存在']);
|
||||
}
|
||||
Db::startTrans();
|
||||
Db::name('account')->where('id', $id)->update([
|
||||
@@ -102,43 +105,44 @@ class Domain extends BaseController
|
||||
'remark' => $remark,
|
||||
]);
|
||||
$dns = DnsHelper::getModel($id);
|
||||
if($dns){
|
||||
if($dns->check()){
|
||||
if ($dns) {
|
||||
if ($dns->check()) {
|
||||
Db::commit();
|
||||
return json(['code'=>0, 'msg'=>'修改域名账户成功!']);
|
||||
}else{
|
||||
return json(['code' => 0, 'msg' => '修改域名账户成功!']);
|
||||
} else {
|
||||
Db::rollback();
|
||||
return json(['code'=>-1, 'msg'=>'验证域名账户失败,'.$dns->getError()]);
|
||||
return json(['code' => -1, 'msg' => '验证域名账户失败,' . $dns->getError()]);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
Db::rollback();
|
||||
return json(['code'=>-1, 'msg'=>'DNS模块('.$type.')不存在']);
|
||||
return json(['code' => -1, 'msg' => 'DNS模块(' . $type . ')不存在']);
|
||||
}
|
||||
}elseif($act == 'del'){
|
||||
} elseif ($act == 'del') {
|
||||
$id = input('post.id/d');
|
||||
$dcount = DB::name('domain')->where('aid', $id)->count();
|
||||
if($dcount > 0) return json(['code'=>-1, 'msg'=>'该域名账户下存在域名,无法删除']);
|
||||
if ($dcount > 0) return json(['code' => -1, 'msg' => '该域名账户下存在域名,无法删除']);
|
||||
Db::name('account')->where('id', $id)->delete();
|
||||
return json(['code'=>0]);
|
||||
return json(['code' => 0]);
|
||||
}
|
||||
return json(['code'=>-3]);
|
||||
return json(['code' => -3]);
|
||||
}
|
||||
|
||||
|
||||
public function domain(){
|
||||
if(request()->user['type'] == 'domain'){
|
||||
return redirect('/record/'.request()->user['id']);
|
||||
public function domain()
|
||||
{
|
||||
if (request()->user['type'] == 'domain') {
|
||||
return redirect('/record/' . request()->user['id']);
|
||||
}
|
||||
$list = Db::name('account')->select();
|
||||
$accounts = [];
|
||||
$types = [];
|
||||
foreach($list as $row){
|
||||
$accounts[$row['id']] = $row['id'].'_'.DnsHelper::$dns_config[$row['type']]['name'];
|
||||
if(!array_key_exists($row['type'], $types)){
|
||||
foreach ($list as $row) {
|
||||
$accounts[$row['id']] = $row['id'] . '_' . DnsHelper::$dns_config[$row['type']]['name'];
|
||||
if (!array_key_exists($row['type'], $types)) {
|
||||
$types[$row['type']] = DnsHelper::$dns_config[$row['type']]['name'];
|
||||
}
|
||||
if(!empty($row['remark'])){
|
||||
$accounts[$row['id']] .= '('.$row['remark'].')';
|
||||
if (!empty($row['remark'])) {
|
||||
$accounts[$row['id']] .= '(' . $row['remark'] . ')';
|
||||
}
|
||||
}
|
||||
View::assign('accounts', $accounts);
|
||||
@@ -146,52 +150,54 @@ class Domain extends BaseController
|
||||
return view();
|
||||
}
|
||||
|
||||
public function domain_data(){
|
||||
if(!checkPermission(1)) return json(['total'=>0, 'rows'=>[]]);
|
||||
public function domain_data()
|
||||
{
|
||||
if (!checkPermission(1)) return json(['total' => 0, 'rows' => []]);
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
$type = input('post.type', null, 'trim');
|
||||
$offset = input('post.offset/d', 0);
|
||||
$limit = input('post.limit/d', 10);
|
||||
|
||||
$select = Db::name('domain')->alias('A')->join('account B','A.aid = B.id');
|
||||
if(!empty($kw)){
|
||||
$select->whereLike('name', '%'.$kw.'%');
|
||||
$select = Db::name('domain')->alias('A')->join('account B', 'A.aid = B.id');
|
||||
if (!empty($kw)) {
|
||||
$select->whereLike('name|A.remark', '%' . $kw . '%');
|
||||
}
|
||||
if(!empty($type)){
|
||||
if (!empty($type)) {
|
||||
$select->whereLike('B.type', $type);
|
||||
}
|
||||
if(request()->user['level'] == 1){
|
||||
if (request()->user['level'] == 1) {
|
||||
$select->where('is_hide', 0)->where('A.name', 'in', request()->user['permission']);
|
||||
}
|
||||
$total = $select->count();
|
||||
$rows = $select->fieldRaw('A.*,B.type,B.remark')->order('A.id','desc')->limit($offset, $limit)->select();
|
||||
$rows = $select->fieldRaw('A.*,B.type,B.remark aremark')->order('A.id', 'desc')->limit($offset, $limit)->select();
|
||||
|
||||
$list = [];
|
||||
foreach($rows as $row){
|
||||
foreach ($rows as $row) {
|
||||
$row['typename'] = DnsHelper::$dns_config[$row['type']]['name'];
|
||||
$list[] = $row;
|
||||
}
|
||||
|
||||
return json(['total'=>$total, 'rows'=>$list]);
|
||||
return json(['total' => $total, 'rows' => $list]);
|
||||
}
|
||||
|
||||
public function domain_op(){
|
||||
if(!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
public function domain_op()
|
||||
{
|
||||
if (!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
$act = input('param.act');
|
||||
if($act == 'get'){
|
||||
if ($act == 'get') {
|
||||
$id = input('post.id/d');
|
||||
$row = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$row) return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
return json(['code'=>0, 'data'=>$row]);
|
||||
}elseif($act == 'add'){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if (!$row) return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
return json(['code' => 0, 'data' => $row]);
|
||||
} elseif ($act == 'add') {
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$aid = input('post.aid/d');
|
||||
$name = input('post.name', null, 'trim');
|
||||
$thirdid = input('post.thirdid', null, 'trim');
|
||||
$recordcount = input('post.recordcount/d', 0);
|
||||
if(empty($name) || empty($thirdid)) return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if(Db::name('domain')->where('aid', $aid)->where('name', $name)->find()){
|
||||
return json(['code'=>-1, 'msg'=>'域名已存在']);
|
||||
if (empty($name) || empty($thirdid)) return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
if (Db::name('domain')->where('aid', $aid)->where('name', $name)->find()) {
|
||||
return json(['code' => -1, 'msg' => '域名已存在']);
|
||||
}
|
||||
Db::name('domain')->insert([
|
||||
'aid' => $aid,
|
||||
@@ -202,73 +208,86 @@ class Domain extends BaseController
|
||||
'is_sso' => 1,
|
||||
'recordcount' => $recordcount,
|
||||
]);
|
||||
return json(['code'=>0, 'msg'=>'添加域名成功!']);
|
||||
}elseif($act == 'edit'){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
return json(['code' => 0, 'msg' => '添加域名成功!']);
|
||||
} elseif ($act == 'edit') {
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$id = input('post.id/d');
|
||||
$row = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$row) return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$row) return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
$is_hide = input('post.is_hide/d');
|
||||
$is_sso = input('post.is_sso/d');
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
Db::name('domain')->where('id', $id)->update([
|
||||
'is_hide' => $is_hide,
|
||||
'is_sso' => $is_sso,
|
||||
'remark' => $remark,
|
||||
]);
|
||||
return json(['code'=>0, 'msg'=>'修改域名配置成功!']);
|
||||
}elseif($act == 'del'){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
return json(['code' => 0, 'msg' => '修改域名配置成功!']);
|
||||
} elseif ($act == 'del') {
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$id = input('post.id/d');
|
||||
Db::name('domain')->where('id', $id)->delete();
|
||||
Db::name('dmtask')->where('did', $id)->delete();
|
||||
return json(['code'=>0]);
|
||||
Db::name('optimizeip')->where('did', $id)->delete();
|
||||
return json(['code' => 0]);
|
||||
}
|
||||
return json(['code'=>-3]);
|
||||
return json(['code' => -3]);
|
||||
}
|
||||
|
||||
public function domain_list(){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
public function domain_list()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$aid = input('post.aid/d');
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
$page = input('?post.page') ? input('post.page/d') : 1;
|
||||
$pagesize = input('?post.pagesize') ? input('post.pagesize/d') : 10;
|
||||
$dns = DnsHelper::getModel($aid);
|
||||
$list = $dns->getDomainList($kw, $page, $pagesize);
|
||||
if(!$list) return json(['code'=>-1, 'msg'=>'获取域名列表失败,'.$dns->getError()]);
|
||||
return json(['code'=>0, 'data'=>$list]);
|
||||
$result = $dns->getDomainList($kw, $page, $pagesize);
|
||||
if (!$result) return json(['code' => -1, 'msg' => '获取域名列表失败,' . $dns->getError()]);
|
||||
|
||||
$newlist = [];
|
||||
foreach ($result['list'] as $row) {
|
||||
if (!Db::name('domain')->where('aid', $aid)->where('name', $row['Domain'])->find()) {
|
||||
$newlist[] = $row;
|
||||
}
|
||||
}
|
||||
return json(['code' => 0, 'data' => ['total' => $result['total'], 'list' => $newlist]]);
|
||||
}
|
||||
|
||||
//获取解析线路和最小TTL
|
||||
private function get_line_and_ttl($drow){
|
||||
$recordLine = cache('record_line_'.$drow['id']);
|
||||
$minTTL = cache('min_ttl_'.$drow['id']);
|
||||
if(empty($recordLine)){
|
||||
private function get_line_and_ttl($drow)
|
||||
{
|
||||
$recordLine = cache('record_line_' . $drow['id']);
|
||||
$minTTL = cache('min_ttl_' . $drow['id']);
|
||||
if (empty($recordLine)) {
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
if(!$dns) return $this->alert('error', 'DNS模块不存在');
|
||||
$recordLine = $dns->getRecordLine($drow['name']);
|
||||
if(!$recordLine) return $this->alert('error', '获取解析线路列表失败,'.$dns->getError());
|
||||
cache('record_line_'.$drow['id'], $recordLine, 604800);
|
||||
$minTTL = $dns->getMinTTL($drow['name']);
|
||||
if($minTTL){
|
||||
cache('min_ttl_'.$drow['id'], $minTTL, 604800);
|
||||
if (!$dns) throw new Exception('DNS模块不存在');
|
||||
$recordLine = $dns->getRecordLine();
|
||||
if (!$recordLine) throw new Exception('获取解析线路列表失败,' . $dns->getError());
|
||||
cache('record_line_' . $drow['id'], $recordLine, 604800);
|
||||
$minTTL = $dns->getMinTTL();
|
||||
if ($minTTL) {
|
||||
cache('min_ttl_' . $drow['id'], $minTTL, 604800);
|
||||
}
|
||||
}
|
||||
return [$recordLine, $minTTL];
|
||||
}
|
||||
|
||||
public function domain_info(){
|
||||
public function domain_info()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
if (!$drow) {
|
||||
return $this->alert('error', '域名不存在');
|
||||
}
|
||||
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
list($recordLine, $minTTL) = $this->get_line_and_ttl($drow);
|
||||
|
||||
$recordLineArr = [];
|
||||
foreach($recordLine as $key=>$item){
|
||||
$recordLineArr[] = ['id'=>strval($key), 'name'=>$item['name'], 'parent'=>$item['parent']];
|
||||
foreach ($recordLine as $key => $item) {
|
||||
$recordLineArr[] = ['id' => strval($key), 'name' => $item['name'], 'parent' => $item['parent']];
|
||||
}
|
||||
|
||||
$dnsconfig = DnsHelper::$dns_config[$dnstype];
|
||||
@@ -276,32 +295,33 @@ class Domain extends BaseController
|
||||
|
||||
$drow['config'] = $dnsconfig;
|
||||
$drow['recordLine'] = $recordLineArr;
|
||||
$drow['minTTL'] = $minTTL?$minTTL:1;
|
||||
if(input('?post.loginurl') && input('post.loginurl') == '1'){
|
||||
$drow['minTTL'] = $minTTL ? $minTTL : 1;
|
||||
if (input('?post.loginurl') && input('post.loginurl') == '1') {
|
||||
$token = getSid();
|
||||
cache('quicklogin_'.$drow['name'], $token, 3600);
|
||||
cache('quicklogin_' . $drow['name'], $token, 3600);
|
||||
$timestamp = time();
|
||||
$sign = md5(env('app.sys_key').$drow['name'].$timestamp.$token.env('app.sys_key'));
|
||||
$drow['loginurl'] = request()->root(true).'/quicklogin?domain='.$drow['name'].'×tamp='.$timestamp.'&token='.$token.'&sign='.$sign;
|
||||
$sign = md5(config_get('sys_key') . $drow['name'] . $timestamp . $token . config_get('sys_key'));
|
||||
$drow['loginurl'] = request()->root(true) . '/quicklogin?domain=' . $drow['name'] . '×tamp=' . $timestamp . '&token=' . $token . '&sign=' . $sign;
|
||||
}
|
||||
|
||||
return json(['code'=>0, 'data'=>$drow]);
|
||||
return json(['code' => 0, 'data' => $drow]);
|
||||
}
|
||||
|
||||
public function record(){
|
||||
public function record()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
if (!$drow) {
|
||||
return $this->alert('error', '域名不存在');
|
||||
}
|
||||
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
list($recordLine, $minTTL) = $this->get_line_and_ttl($drow);
|
||||
|
||||
$recordLineArr = [];
|
||||
foreach($recordLine as $key=>$item){
|
||||
$recordLineArr[] = ['id'=>strval($key), 'name'=>$item['name'], 'parent'=>$item['parent']];
|
||||
foreach ($recordLine as $key => $item) {
|
||||
$recordLineArr[] = ['id' => strval($key), 'name' => $item['name'], 'parent' => $item['parent']];
|
||||
}
|
||||
|
||||
$dnsconfig = DnsHelper::$dns_config[$dnstype];
|
||||
@@ -310,110 +330,121 @@ class Domain extends BaseController
|
||||
View::assign('domainId', $id);
|
||||
View::assign('domainName', $drow['name']);
|
||||
View::assign('recordLine', $recordLineArr);
|
||||
View::assign('minTTL', $minTTL?$minTTL:1);
|
||||
View::assign('minTTL', $minTTL ? $minTTL : 1);
|
||||
View::assign('dnsconfig', $dnsconfig);
|
||||
return view();
|
||||
}
|
||||
|
||||
public function record_data(){
|
||||
public function record_data()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$keyword = input('post.keyword', null, 'trim');
|
||||
$subdomain = input('post.subdomain', null, 'trim');
|
||||
$value = input('post.value', null, 'trim');
|
||||
$type = input('post.type', null, 'trim');
|
||||
$line = input('post.line', null, 'trim');
|
||||
$status = input('post.status', null, 'trim');
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
if($limit == 0){
|
||||
if ($limit == 0) {
|
||||
$page = 1;
|
||||
}else{
|
||||
$page = $offset/$limit + 1;
|
||||
} else {
|
||||
$page = $offset / $limit + 1;
|
||||
}
|
||||
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['total'=>0, 'rows'=>[]]);
|
||||
if (!$drow) {
|
||||
return json(['total' => 0, 'rows' => []]);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return json(['total'=>0, 'rows'=>[]]);
|
||||
if (!checkPermission(0, $drow['name'])) return json(['total' => 0, 'rows' => []]);
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
$domainRecords = $dns->getDomainRecords($page, $limit, $keyword, $subdomain, $type, $line, $status);
|
||||
if(!$domainRecords) return json(['total'=>0, 'rows'=>[]]);
|
||||
$domainRecords = $dns->getDomainRecords($page, $limit, $keyword, $subdomain, $value, $type, $line, $status);
|
||||
if (!$domainRecords) return json(['total' => 0, 'rows' => []]);
|
||||
|
||||
if($domainRecords['total'] != $drow['recordcount']){
|
||||
Db::name('domain')->where('id', $id)->update(['recordcount'=>$domainRecords['total']]);
|
||||
if (empty($keyword) && empty($subdomain) && empty($type) && isNullOrEmpty($line) && empty($status) && empty($value) && $domainRecords['total'] != $drow['recordcount']) {
|
||||
Db::name('domain')->where('id', $id)->update(['recordcount' => $domainRecords['total']]);
|
||||
}
|
||||
|
||||
$recordLine = cache('record_line_'.$id);
|
||||
$recordLine = cache('record_line_' . $id);
|
||||
|
||||
foreach($domainRecords['list'] as &$row){
|
||||
foreach ($domainRecords['list'] as &$row) {
|
||||
$row['LineName'] = isset($recordLine[$row['Line']]) ? $recordLine[$row['Line']]['name'] : $row['Line'];
|
||||
}
|
||||
|
||||
return json(['total'=>$domainRecords['total'], 'rows'=>$domainRecords['list']]);
|
||||
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
|
||||
if ($dnstype == 'baidu' || $dnstype == 'namesilo') {
|
||||
return json($domainRecords['list']);
|
||||
}
|
||||
|
||||
return json(['total' => $domainRecords['total'], 'rows' => $domainRecords['list']]);
|
||||
}
|
||||
|
||||
public function record_list(){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
public function record_list()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$id = input('post.id/d');
|
||||
$rr = input('post.rr', null, 'trim');
|
||||
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return json(['code'=>-1, 'msg'=>'无权限']);
|
||||
if (!checkPermission(0, $drow['name'])) return json(['code' => -1, 'msg' => '无权限']);
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
$domainRecords = $dns->getSubDomainRecords($rr, 1, 100);
|
||||
if(!$domainRecords) return json(['code'=>-1, 'msg'=>'获取记录列表失败,'.$dns->getError()]);
|
||||
if (!$domainRecords) return json(['code' => -1, 'msg' => '获取记录列表失败,' . $dns->getError()]);
|
||||
|
||||
list($recordLine, $minTTL) = $this->get_line_and_ttl($drow);
|
||||
|
||||
foreach($domainRecords['list'] as &$row){
|
||||
foreach ($domainRecords['list'] as &$row) {
|
||||
$row['LineName'] = isset($recordLine[$row['Line']]) ? $recordLine[$row['Line']]['name'] : $row['Line'];
|
||||
}
|
||||
|
||||
return json(['code'=>0, 'data'=>$domainRecords['list']]);
|
||||
return json(['code' => 0, 'data' => $domainRecords['list']]);
|
||||
}
|
||||
|
||||
public function record_add(){
|
||||
public function record_add()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$name = input('post.name', null, 'trim');
|
||||
$type = input('post.type', null, 'trim');
|
||||
$value = input('post.value', null, 'trim');
|
||||
$line = input('post.line', null, 'trim');
|
||||
$ttl = input('post.ttl/d', 600);
|
||||
$weight = input('post.weight/d', 0);
|
||||
$mx = input('post.mx/d', 1);
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
|
||||
if(empty($name) || empty($type) || empty($value)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if (empty($name) || empty($type) || empty($value)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
$recordid = $dns->addDomainRecord($name, $type, $value, $line, $ttl, $mx, $remark);
|
||||
if($recordid){
|
||||
$this->add_log($drow['name'], '添加解析', $type.'记录 '.$name.' '.$value.' (线路:'.$line.' TTL:'.$ttl.')');
|
||||
return json(['code'=>0, 'msg'=>'添加解析记录成功!']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'添加解析记录失败,'.$dns->getError()]);
|
||||
$recordid = $dns->addDomainRecord($name, $type, $value, $line, $ttl, $mx, $weight, $remark);
|
||||
if ($recordid) {
|
||||
$this->add_log($drow['name'], '添加解析', $type . '记录 ' . $name . ' ' . $value . ' (线路:' . $line . ' TTL:' . $ttl . ')');
|
||||
return json(['code' => 0, 'msg' => '添加解析记录成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '添加解析记录失败,' . $dns->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function record_update(){
|
||||
public function record_update()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$recordid = input('post.recordid', null, 'trim');
|
||||
$name = input('post.name', null, 'trim');
|
||||
@@ -421,156 +452,293 @@ class Domain extends BaseController
|
||||
$value = input('post.value', null, 'trim');
|
||||
$line = input('post.line', null, 'trim');
|
||||
$ttl = input('post.ttl/d', 600);
|
||||
$weight = input('post.weight/d', 0);
|
||||
$mx = input('post.mx/d', 1);
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
|
||||
if(empty($recordid) || empty($name) || empty($type) || empty($value)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if (empty($recordid) || empty($name) || empty($type) || empty($value)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
$recordid = $dns->updateDomainRecord($recordid, $name, $type, $value, $line, $ttl, $mx, $remark);
|
||||
if($recordid){
|
||||
$this->add_log($drow['name'], '修改解析', $type.'记录 '.$name.' '.$value.' (线路:'.$line.' TTL:'.$ttl.')');
|
||||
return json(['code'=>0, 'msg'=>'修改解析记录成功!']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'修改解析记录失败,'.$dns->getError()]);
|
||||
$recordid = $dns->updateDomainRecord($recordid, $name, $type, $value, $line, $ttl, $mx, $weight, $remark);
|
||||
if ($recordid) {
|
||||
$this->add_log($drow['name'], '修改解析', $type . '记录 ' . $name . ' ' . $value . ' (线路:' . $line . ' TTL:' . $ttl . ')');
|
||||
return json(['code' => 0, 'msg' => '修改解析记录成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '修改解析记录失败,' . $dns->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function record_delete(){
|
||||
public function record_delete()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$recordid = input('post.recordid', null, 'trim');
|
||||
|
||||
if(empty($recordid)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if (empty($recordid)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
if($dns->deleteDomainRecord($recordid)){
|
||||
$this->add_log($drow['name'], '删除解析', '记录ID:'.$recordid);
|
||||
return json(['code'=>0, 'msg'=>'删除解析记录成功!']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'删除解析记录失败,'.$dns->getError()]);
|
||||
if ($dns->deleteDomainRecord($recordid)) {
|
||||
$this->add_log($drow['name'], '删除解析', '记录ID:' . $recordid);
|
||||
return json(['code' => 0, 'msg' => '删除解析记录成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '删除解析记录失败,' . $dns->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function record_status(){
|
||||
public function record_status()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$recordid = input('post.recordid', null, 'trim');
|
||||
$status = input('post.status', null, 'trim');
|
||||
|
||||
if(empty($recordid)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if (empty($recordid)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
if($dns->setDomainRecordStatus($recordid, $status)){
|
||||
if ($dns->setDomainRecordStatus($recordid, $status)) {
|
||||
$action = $status == '1' ? '启用解析' : '暂停解析';
|
||||
$this->add_log($drow['name'], $action, '记录ID:'.$recordid);
|
||||
return json(['code'=>0, 'msg'=>'操作成功!']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'操作失败,'.$dns->getError()]);
|
||||
$this->add_log($drow['name'], $action, '记录ID:' . $recordid);
|
||||
return json(['code' => 0, 'msg' => '操作成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '操作失败,' . $dns->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function record_remark(){
|
||||
public function record_remark()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$recordid = input('post.recordid', null, 'trim');
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
|
||||
if(empty($recordid)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if (empty($recordid)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
if(empty($remark)) $remark = null;
|
||||
if (empty($remark)) $remark = null;
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
if($dns->updateDomainRecordRemark($recordid, $remark)){
|
||||
return json(['code'=>0, 'msg'=>'操作成功!']);
|
||||
}else{
|
||||
return json(['code'=>-1, 'msg'=>'操作失败,'.$dns->getError()]);
|
||||
if ($dns->updateDomainRecordRemark($recordid, $remark)) {
|
||||
return json(['code' => 0, 'msg' => '操作成功!']);
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '操作失败,' . $dns->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function record_batch(){
|
||||
public function record_batch()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
return json(['code'=>-1, 'msg'=>'域名不存在']);
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$recordids = input('post.recordids', null, 'trim');
|
||||
$action = input('post.action', null, 'trim');
|
||||
|
||||
if(empty($recordids) || empty($action)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
if (empty($recordids) || empty($action)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
if($action == 'open'){
|
||||
foreach($recordids as $recordid){
|
||||
if($dns->setDomainRecordStatus($recordid, '1')){
|
||||
$this->add_log($drow['name'], '启用解析', '记录ID:'.$recordid);
|
||||
if ($action == 'open') {
|
||||
foreach ($recordids as $recordid) {
|
||||
if ($dns->setDomainRecordStatus($recordid, '1')) {
|
||||
$this->add_log($drow['name'], '启用解析', '记录ID:' . $recordid);
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
$msg = '成功启用'.$success.'条解析记录';
|
||||
}else if($action == 'pause'){
|
||||
foreach($recordids as $recordid){
|
||||
if($dns->setDomainRecordStatus($recordid, '0')){
|
||||
$this->add_log($drow['name'], '暂停解析', '记录ID:'.$recordid);
|
||||
$msg = '成功启用' . $success . '条解析记录';
|
||||
} else if ($action == 'pause') {
|
||||
foreach ($recordids as $recordid) {
|
||||
if ($dns->setDomainRecordStatus($recordid, '0')) {
|
||||
$this->add_log($drow['name'], '暂停解析', '记录ID:' . $recordid);
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
$msg = '成功暂停'.$success.'条解析记录';
|
||||
}else if($action == 'delete'){
|
||||
foreach($recordids as $recordid){
|
||||
if($dns->deleteDomainRecord($recordid)){
|
||||
$this->add_log($drow['name'], '删除解析', '记录ID:'.$recordid);
|
||||
$msg = '成功暂停' . $success . '条解析记录';
|
||||
} else if ($action == 'delete') {
|
||||
foreach ($recordids as $recordid) {
|
||||
if ($dns->deleteDomainRecord($recordid)) {
|
||||
$this->add_log($drow['name'], '删除解析', '记录ID:' . $recordid);
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
$msg = '成功删除'.$success.'条解析记录';
|
||||
$msg = '成功删除' . $success . '条解析记录';
|
||||
} else if ($action == 'remark') {
|
||||
$remark = input('post.remark', null, 'trim');
|
||||
if (empty($remark)) $remark = null;
|
||||
foreach ($recordids as $recordid) {
|
||||
if ($dns->updateDomainRecordRemark($recordid, $remark)) {
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
$msg = '批量修改备注,成功' . $success . '条,失败' . $fail . '条';
|
||||
}
|
||||
return json(['code'=>0, 'msg'=>$msg]);
|
||||
return json(['code' => 0, 'msg' => $msg]);
|
||||
}
|
||||
|
||||
public function record_log(){
|
||||
public function record_batch_edit()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if(!$drow){
|
||||
if (!$drow) {
|
||||
return json(['code' => -1, 'msg' => '域名不存在']);
|
||||
}
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
$action = input('post.action', null, 'trim');
|
||||
$recordinfo = input('post.recordinfo', null, 'trim');
|
||||
$recordinfo = json_decode($recordinfo, true);
|
||||
|
||||
if ($action == 'value') {
|
||||
$type = input('post.type', null, 'trim');
|
||||
$value = input('post.value', null, 'trim');
|
||||
|
||||
if (empty($recordinfo) || empty($type) || empty($value)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
foreach ($recordinfo as $record) {
|
||||
$recordid = $dns->updateDomainRecord($record['recordid'], $record['name'], $type, $value, $record['line'], $record['ttl'], $record['mx'], $record['weight'], $record['remark']);
|
||||
if ($recordid) {
|
||||
$this->add_log($drow['name'], '修改解析', $type . '记录 ' . $record['name'] . ' ' . $value . ' (线路:' . $record['line'] . ' TTL:' . $record['ttl'] . ')');
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
return json(['code' => 0, 'msg' => '批量修改解析记录,成功' . $success . '条,失败' . $fail . '条']);
|
||||
} else if ($action == 'line') {
|
||||
$line = input('post.line', null, 'trim');
|
||||
|
||||
if (empty($recordinfo) || isNullOrEmpty($line)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
foreach ($recordinfo as $record) {
|
||||
$recordid = $dns->updateDomainRecord($record['recordid'], $record['name'], $record['type'], $record['value'], $line, $record['ttl'], $record['mx'], $record['weight'], $record['remark']);
|
||||
if ($recordid) {
|
||||
$this->add_log($drow['name'], '修改解析', $record['type'] . '记录 ' . $record['name'] . ' ' . $record['value'] . ' (线路:' . $line . ' TTL:' . $record['ttl'] . ')');
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
return json(['code' => 0, 'msg' => '批量修改解析线路,成功' . $success . '条,失败' . $fail . '条']);
|
||||
}
|
||||
}
|
||||
|
||||
public function record_batch_add()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if (!$drow) {
|
||||
return $this->alert('error', '域名不存在');
|
||||
}
|
||||
if(!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
if(request()->isPost()){
|
||||
if (request()->isAjax()) {
|
||||
$record = input('post.record', null, 'trim');
|
||||
$type = input('post.type', null, 'trim');
|
||||
$line = input('post.line', null, 'trim');
|
||||
$ttl = input('post.ttl/d', 600);
|
||||
$mx = input('post.mx/d', 1);
|
||||
$recordlist = explode("\n", $record);
|
||||
|
||||
if (empty($record) || empty($recordlist)) {
|
||||
return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
}
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
foreach ($recordlist as $record) {
|
||||
$record = trim($record);
|
||||
$arr = explode(' ', $record);
|
||||
if (empty($record) || empty($arr[0]) || empty($arr[1])) continue;
|
||||
$thistype = empty($type) ? getDnsType($arr[1]) : $type;
|
||||
$recordid = $dns->addDomainRecord($arr[0], $thistype, $arr[1], $line, $ttl, $mx);
|
||||
if ($recordid) {
|
||||
$this->add_log($drow['name'], '添加解析', $thistype . '记录 ' . $arr[0] . ' ' . $arr[1] . ' (线路:' . $line . ' TTL:' . $ttl . ')');
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
return json(['code' => 0, 'msg' => '批量添加解析,成功' . $success . '条,失败' . $fail . '条']);
|
||||
}
|
||||
|
||||
list($recordLine, $minTTL) = $this->get_line_and_ttl($drow);
|
||||
|
||||
$recordLineArr = [];
|
||||
foreach ($recordLine as $key => $item) {
|
||||
$recordLineArr[] = ['id' => strval($key), 'name' => $item['name'], 'parent' => $item['parent']];
|
||||
}
|
||||
|
||||
$dnsconfig = DnsHelper::$dns_config[$dnstype];
|
||||
$dnsconfig['type'] = $dnstype;
|
||||
|
||||
View::assign('domainId', $id);
|
||||
View::assign('domainName', $drow['name']);
|
||||
View::assign('recordLine', $recordLineArr);
|
||||
View::assign('minTTL', $minTTL ? $minTTL : 1);
|
||||
View::assign('dnsconfig', $dnsconfig);
|
||||
return view('batchadd');
|
||||
}
|
||||
|
||||
public function record_log()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
$drow = Db::name('domain')->where('id', $id)->find();
|
||||
if (!$drow) {
|
||||
return $this->alert('error', '域名不存在');
|
||||
}
|
||||
if (!checkPermission(0, $drow['name'])) return $this->alert('error', '无权限');
|
||||
|
||||
if (request()->isPost()) {
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
$page = $offset/$limit + 1;
|
||||
$page = $offset / $limit + 1;
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
$domainRecords = $dns->getDomainRecordLog($page, $limit);
|
||||
if(!$domainRecords) return json(['total'=>0, 'rows'=>[]]);
|
||||
return json(['total'=>$domainRecords['total'], 'rows'=>$domainRecords['list']]);
|
||||
if (!$domainRecords) return json(['total' => 0, 'rows' => []]);
|
||||
return json(['total' => $domainRecords['total'], 'rows' => $domainRecords['list']]);
|
||||
}
|
||||
|
||||
View::assign('domainId', $id);
|
||||
@@ -578,7 +746,8 @@ class Domain extends BaseController
|
||||
return view('log');
|
||||
}
|
||||
|
||||
private function add_log($domain, $action, $data){
|
||||
private function add_log($domain, $action, $data)
|
||||
{
|
||||
Db::name('log')->insert(['uid' => request()->user['id'], 'domain' => $domain, 'action' => $action, 'data' => $data, 'addtime' => date("Y-m-d H:i:s")]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\BaseController;
|
||||
@@ -12,27 +13,27 @@ class Index extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if(request()->user['type'] == 'domain'){
|
||||
return redirect('/record/'.request()->user['id']);
|
||||
if ($this->request->user['type'] == 'domain') {
|
||||
return redirect('/record/' . $this->request->user['id']);
|
||||
}
|
||||
if(request()->isAjax()){
|
||||
if(input('post.do') == 'stat'){
|
||||
$stat = ['domains'=>0, 'users'=>0, 'records'=>0, 'types'=>count(DnsHelper::$dns_config)];
|
||||
if(request()->user['level'] == 2){
|
||||
if ($this->request->isAjax()) {
|
||||
if (input('post.do') == 'stat') {
|
||||
$stat = ['domains' => 0, 'users' => 0, 'records' => 0, 'types' => count(DnsHelper::$dns_config)];
|
||||
if ($this->request->user['level'] == 2) {
|
||||
$stat['domains'] = Db::name('domain')->count();
|
||||
$stat['users'] = Db::name('user')->count();
|
||||
$stat['records'] = Db::name('domain')->sum('recordcount');
|
||||
}else{
|
||||
$stat['domains'] = Db::name('domain')->where('name', 'in', request()->user['permission'])->count();
|
||||
} else {
|
||||
$stat['domains'] = Db::name('domain')->where('name', 'in', $this->request->user['permission'])->count();
|
||||
$stat['users'] = 1;
|
||||
$stat['records'] = Db::name('domain')->where('name', 'in', request()->user['permission'])->sum('recordcount');
|
||||
$stat['records'] = Db::name('domain')->where('name', 'in', $this->request->user['permission'])->sum('recordcount');
|
||||
}
|
||||
return json($stat);
|
||||
}
|
||||
return json(['code'=>-3]);
|
||||
return json(['code' => -3]);
|
||||
}
|
||||
|
||||
if(config('app.dbversion') && config_get('version') != config('app.dbversion')){
|
||||
if (config('app.dbversion') && config_get('version') != config('app.dbversion')) {
|
||||
$this->db_update();
|
||||
config_set('version', config('app.dbversion'));
|
||||
Cache::clear();
|
||||
@@ -49,67 +50,86 @@ class Index extends BaseController
|
||||
'date' => date("Y-m-d H:i:s"),
|
||||
];
|
||||
View::assign('info', $info);
|
||||
View::assign('checkupdate', '//auth.cccyun.cc/app/dnsmgr.php?ver='.config('app.version'));
|
||||
View::assign('checkupdate', '//auth.cccyun.cc/app/dnsmgr.php?ver=' . config('app.version'));
|
||||
return view();
|
||||
}
|
||||
|
||||
private function db_update(){
|
||||
$sqls=file_get_contents(app()->getAppPath().'sql/update.sql');
|
||||
private function db_update()
|
||||
{
|
||||
$sqls = file_get_contents(app()->getAppPath() . 'sql/update.sql');
|
||||
$mysql_prefix = env('database.prefix', 'dnsmgr_');
|
||||
$sqls=explode(';', $sqls);
|
||||
$sqls = explode(';', $sqls);
|
||||
foreach ($sqls as $value) {
|
||||
$value=trim($value);
|
||||
if(empty($value))continue;
|
||||
$value = str_replace('dnsmgr_',$mysql_prefix,$value);
|
||||
Db::execute($value);
|
||||
$value = trim($value);
|
||||
if (empty($value)) continue;
|
||||
$value = str_replace('dnsmgr_', $mysql_prefix, $value);
|
||||
try {
|
||||
Db::execute($value);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function changeskin(){
|
||||
public function changeskin()
|
||||
{
|
||||
$skin = input('post.skin');
|
||||
if(request()->user['level'] == 2){
|
||||
if(cookie('admin_skin')){
|
||||
if ($this->request->user['level'] == 2) {
|
||||
if (cookie('admin_skin')) {
|
||||
cookie('admin_skin', null);
|
||||
}
|
||||
config_set('admin_skin', $skin);
|
||||
Cache::delete('configs');
|
||||
}else{
|
||||
Cache::delete('configs');
|
||||
} else {
|
||||
cookie('admin_skin', $skin);
|
||||
}
|
||||
return json(['code'=>0,'msg'=>'succ']);
|
||||
return json(['code' => 0, 'msg' => 'succ']);
|
||||
}
|
||||
|
||||
public function cleancache(){
|
||||
if(!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
public function cleancache()
|
||||
{
|
||||
if (!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
Cache::clear();
|
||||
return json(['code'=>0,'msg'=>'succ']);
|
||||
clearDirectory(app()->getRuntimePath().'cache/');
|
||||
clearDirectory(app()->getRuntimePath().'temp/');
|
||||
return json(['code' => 0, 'msg' => 'succ']);
|
||||
}
|
||||
|
||||
public function doc(){
|
||||
if(!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
View::assign('siteurl', request()->root(true));
|
||||
public function doc()
|
||||
{
|
||||
if (!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
View::assign('siteurl', $this->request->root(true));
|
||||
return view();
|
||||
}
|
||||
|
||||
public function setpwd(){
|
||||
if(!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
if(request()->isPost()){
|
||||
public function setpwd()
|
||||
{
|
||||
if (!checkPermission(1)) return $this->alert('error', '无权限');
|
||||
if ($this->request->isPost()) {
|
||||
$oldpwd = input('post.oldpwd');
|
||||
$newpwd = input('post.newpwd');
|
||||
$newpwd2 = input('post.newpwd2');
|
||||
if(empty($oldpwd) || empty($newpwd) || empty($newpwd2)){
|
||||
return json(['code'=>-1, 'msg'=>'密码不能为空']);
|
||||
if (empty($oldpwd) || empty($newpwd) || empty($newpwd2)) {
|
||||
return json(['code' => -1, 'msg' => '密码不能为空']);
|
||||
}
|
||||
if($newpwd != $newpwd2){
|
||||
return json(['code'=>-1, 'msg'=>'两次输入的密码不一致']);
|
||||
if ($newpwd != $newpwd2) {
|
||||
return json(['code' => -1, 'msg' => '两次输入的密码不一致']);
|
||||
}
|
||||
if(!password_verify($oldpwd, request()->user['password'])){
|
||||
return json(['code'=>-1, 'msg'=>'原密码错误']);
|
||||
if (!password_verify($oldpwd, $this->request->user['password'])) {
|
||||
return json(['code' => -1, 'msg' => '原密码错误']);
|
||||
}
|
||||
Db::name('user')->where('id', request()->user['id'])->update(['password'=>password_hash($newpwd, PASSWORD_DEFAULT)]);
|
||||
return json(['code'=>0, 'msg'=>'succ']);
|
||||
Db::name('user')->where('id', $this->request->user['id'])->update(['password' => password_hash($newpwd, PASSWORD_DEFAULT)]);
|
||||
return json(['code' => 0, 'msg' => 'succ']);
|
||||
}
|
||||
return view();
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
//$a = \app\lib\DnsQueryUtils::query_dns_doh('www.cccyun.cc', 'A');
|
||||
//print_r($a);
|
||||
$dnsList = json_decode('{"cccyun.net":[{"name":"@","type":"CAA","value":"0 issue \"letsencrypt.org\""},{"name":"verify","type":"TXT","value":"TXTTEST1"},{"name":"verify","type":"TXT","value":"TXTTEST2"}],"yuncname.com":[{"name":"@","type":"CAA","value":"0 issue \"letsencrypt.org\""},{"name":"verify.testhost1","type":"CNAME","value":"i.trust.com"},{"name":"verify.testhost2","type":"CNAME","value":"i.trust.com"}]}', true);
|
||||
\app\lib\CertDnsUtils::addDns($dnsList, function ($txt) {
|
||||
echo $txt . PHP_EOL;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use app\BaseController;
|
||||
use think\facade\View;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Request;
|
||||
|
||||
class Install extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (file_exists(app()->getRootPath().'.env')){
|
||||
if (file_exists(app()->getRootPath() . '.env')) {
|
||||
return '当前已经安装成功,如果需要重新安装,请手动删除根目录.env文件';
|
||||
}
|
||||
if(request()->isPost()){
|
||||
if (Request::isPost()) {
|
||||
$mysql_host = input('post.mysql_host', null, 'trim');
|
||||
$mysql_port = intval(input('post.mysql_port', '3306'));
|
||||
$mysql_user = input('post.mysql_user', null, 'trim');
|
||||
@@ -24,61 +25,64 @@ class Install extends BaseController
|
||||
$admin_username = input('post.admin_username', null, 'trim');
|
||||
$admin_password = input('post.admin_password', null, 'trim');
|
||||
|
||||
if(!$mysql_host || !$mysql_user || !$mysql_pwd || !$mysql_name || !$admin_username || !$admin_password){
|
||||
return json(['code'=>0, 'msg'=>'必填项不能为空']);
|
||||
if (!$mysql_host || !$mysql_user || !$mysql_pwd || !$mysql_name || !$admin_username || !$admin_password) {
|
||||
return json(['code' => 0, 'msg' => '必填项不能为空']);
|
||||
}
|
||||
|
||||
$configdata = file_get_contents(app()->getRootPath().'.example.env');
|
||||
$configdata = str_replace(['{syskey}','{dbhost}','{dbname}','{dbuser}','{dbpwd}','{dbport}','{dbprefix}'], [random(16), $mysql_host, $mysql_name, $mysql_user, $mysql_pwd, $mysql_port, $mysql_prefix], $configdata);
|
||||
$configData = file_get_contents(app()->getRootPath() . '.example.env');
|
||||
$configData = str_replace(['{dbhost}', '{dbname}', '{dbuser}', '{dbpwd}', '{dbport}', '{dbprefix}'], [$mysql_host, $mysql_name, $mysql_user, $mysql_pwd, $mysql_port, $mysql_prefix], $configData);
|
||||
|
||||
try{
|
||||
$DB=new PDO("mysql:host=".$mysql_host.";dbname=".$mysql_name.";port=".$mysql_port,$mysql_user,$mysql_pwd);
|
||||
}catch(Exception $e){
|
||||
if($e->getCode() == 2002){
|
||||
$errorMsg='连接数据库失败:数据库地址填写错误!';
|
||||
}elseif($e->getCode() == 1045){
|
||||
$errorMsg='连接数据库失败:数据库用户名或密码填写错误!';
|
||||
}elseif($e->getCode() == 1049){
|
||||
$errorMsg='连接数据库失败:数据库名不存在!';
|
||||
}else{
|
||||
$errorMsg='连接数据库失败:'.$e->getMessage();
|
||||
try {
|
||||
$DB = new PDO("mysql:host=" . $mysql_host . ";dbname=" . $mysql_name . ";port=" . $mysql_port, $mysql_user, $mysql_pwd);
|
||||
} catch (Exception $e) {
|
||||
if ($e->getCode() == 2002) {
|
||||
$errorMsg = '连接数据库失败:数据库地址填写错误!';
|
||||
} elseif ($e->getCode() == 1045) {
|
||||
$errorMsg = '连接数据库失败:数据库用户名或密码填写错误!';
|
||||
} elseif ($e->getCode() == 1049) {
|
||||
$errorMsg = '连接数据库失败:数据库名不存在!';
|
||||
} else {
|
||||
$errorMsg = '连接数据库失败:' . $e->getMessage();
|
||||
}
|
||||
return json(['code'=>0, 'msg'=>$errorMsg]);
|
||||
return json(['code' => 0, 'msg' => $errorMsg]);
|
||||
}
|
||||
$DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
$DB->exec("set sql_mode = ''");
|
||||
$DB->exec("set names utf8");
|
||||
|
||||
$sqls=file_get_contents(app()->getAppPath().'sql/install.sql');
|
||||
$sqls=explode(';', $sqls);
|
||||
$sqls = file_get_contents(app()->getAppPath() . 'sql/install.sql');
|
||||
$sqls = explode(';', $sqls);
|
||||
|
||||
$password = password_hash($admin_password, PASSWORD_DEFAULT);
|
||||
$sqls[]="INSERT INTO `".$mysql_prefix."user` (`username`,`password`,`level`,`regtime`,`lasttime`,`status`) VALUES ('".addslashes($admin_username)."', '$password', 2, NOW(), NOW(), 1)";
|
||||
$sqls[] = "REPLACE INTO `" . $mysql_prefix . "config` VALUES ('sys_key', '" . random(16) . "')";
|
||||
$sqls[] = "INSERT INTO `" . $mysql_prefix . "user` (`username`,`password`,`level`,`regtime`,`lasttime`,`status`) VALUES ('" . addslashes($admin_username) . "', '$password', 2, NOW(), NOW(), 1)";
|
||||
|
||||
$success=0;$error=0;$errorMsg=null;
|
||||
$success = 0;
|
||||
$error = 0;
|
||||
$errorMsg = null;
|
||||
foreach ($sqls as $value) {
|
||||
$value=trim($value);
|
||||
if(empty($value))continue;
|
||||
$value = str_replace('dnsmgr_',$mysql_prefix,$value);
|
||||
if($DB->exec($value)===false){
|
||||
$value = trim($value);
|
||||
if (empty($value)) continue;
|
||||
$value = str_replace('dnsmgr_', $mysql_prefix, $value);
|
||||
if ($DB->exec($value) === false) {
|
||||
$error++;
|
||||
$dberror=$DB->errorInfo();
|
||||
$errorMsg.=$dberror[2]."\n";
|
||||
}else{
|
||||
$dberror = $DB->errorInfo();
|
||||
$errorMsg .= $dberror[2] . "\n";
|
||||
} else {
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
if(empty($errorMsg)){
|
||||
if(!file_put_contents(app()->getRootPath().'.env', $configdata)){
|
||||
return json(['code'=>0, 'msg'=>'保存失败,请确保网站根目录有写入权限']);
|
||||
if (empty($errorMsg)) {
|
||||
if (!file_put_contents(app()->getRootPath() . '.env', $configData)) {
|
||||
return json(['code' => 0, 'msg' => '保存失败,请确保网站根目录有写入权限']);
|
||||
}
|
||||
Cache::clear();
|
||||
return json(['code'=>1, 'msg'=>'安装完成!成功执行SQL语句'.$success.'条']);
|
||||
}else{
|
||||
return json(['code'=>0, 'msg'=>$errorMsg]);
|
||||
return json(['code' => 1, 'msg' => '安装完成!成功执行SQL语句' . $success . '条']);
|
||||
} else {
|
||||
return json(['code' => 0, 'msg' => $errorMsg]);
|
||||
}
|
||||
}
|
||||
return view();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
176
app/controller/Optimizeip.php
Normal file
176
app/controller/Optimizeip.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\BaseController;
|
||||
use Exception;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
use think\facade\Cache;
|
||||
use app\lib\OptimizeService;
|
||||
|
||||
class Optimizeip extends BaseController
|
||||
{
|
||||
public function opipset()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
if ($this->request->isPost()) {
|
||||
$params = input('post.');
|
||||
foreach ($params as $key => $value) {
|
||||
if (empty($key)) {
|
||||
continue;
|
||||
}
|
||||
config_set($key, $value);
|
||||
Cache::delete('configs');
|
||||
}
|
||||
return json(['code' => 0, 'msg' => 'succ']);
|
||||
}
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function opiplist()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function opiplist_data()
|
||||
{
|
||||
if (!checkPermission(2)) return json(['total' => 0, 'rows' => []]);
|
||||
$type = input('post.type/d', 1);
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
|
||||
$select = Db::name('optimizeip')->alias('A')->join('domain B', 'A.did = B.id');
|
||||
if (!empty($kw)) {
|
||||
if ($type == 1) {
|
||||
$select->whereLike('rr|B.name', '%' . $kw . '%');
|
||||
} elseif ($type == 2) {
|
||||
$select->whereLike('remark', '%' . $kw . '%');
|
||||
}
|
||||
}
|
||||
$total = $select->count();
|
||||
$list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select();
|
||||
|
||||
return json(['total' => $total, 'rows' => $list]);
|
||||
}
|
||||
|
||||
public function opipform()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$action = input('param.action');
|
||||
if ($this->request->isPost()) {
|
||||
if ($action == 'add') {
|
||||
$task = [
|
||||
'did' => input('post.did/d'),
|
||||
'rr' => input('post.rr', null, 'trim'),
|
||||
'type' => input('post.type/d'),
|
||||
'ip_type' => input('post.ip_type', null, 'trim'),
|
||||
'cdn_type' => input('post.cdn_type/d'),
|
||||
'recordnum' => input('post.recordnum/d'),
|
||||
'ttl' => input('post.ttl/d'),
|
||||
'remark' => input('post.remark', null, 'trim'),
|
||||
'addtime' => date('Y-m-d H:i:s'),
|
||||
'active' => 1
|
||||
];
|
||||
|
||||
if (empty($task['did']) || empty($task['rr']) || empty($task['ip_type']) || empty($task['recordnum']) || empty($task['ttl'])) {
|
||||
return json(['code' => -1, 'msg' => '必填项不能为空']);
|
||||
}
|
||||
if ($task['recordnum'] > 5) {
|
||||
return json(['code' => -1, 'msg' => '解析数量不能超过5个']);
|
||||
}
|
||||
if (Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->find()) {
|
||||
return json(['code' => -1, 'msg' => '当前域名的优选IP任务已存在']);
|
||||
}
|
||||
Db::name('optimizeip')->insert($task);
|
||||
return json(['code' => 0, 'msg' => '添加成功']);
|
||||
} elseif ($action == 'edit') {
|
||||
$id = input('post.id/d');
|
||||
$task = [
|
||||
'did' => input('post.did/d'),
|
||||
'rr' => input('post.rr', null, 'trim'),
|
||||
'type' => input('post.type/d'),
|
||||
'ip_type' => input('post.ip_type', null, 'trim'),
|
||||
'cdn_type' => input('post.cdn_type/d'),
|
||||
'recordnum' => input('post.recordnum/d'),
|
||||
'ttl' => input('post.ttl/d'),
|
||||
'remark' => input('post.remark', null, 'trim'),
|
||||
];
|
||||
|
||||
if (empty($task['did']) || empty($task['rr']) || empty($task['ip_type']) || empty($task['recordnum']) || empty($task['ttl'])) {
|
||||
return json(['code' => -1, 'msg' => '必填项不能为空']);
|
||||
}
|
||||
if ($task['recordnum'] > 5) {
|
||||
return json(['code' => -1, 'msg' => '解析数量不能超过5个']);
|
||||
}
|
||||
if (Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->where('id', '<>', $id)->find()) {
|
||||
return json(['code' => -1, 'msg' => '当前域名的优选IP任务已存在']);
|
||||
}
|
||||
Db::name('optimizeip')->where('id', $id)->update($task);
|
||||
return json(['code' => 0, 'msg' => '修改成功']);
|
||||
} elseif ($action == 'setactive') {
|
||||
$id = input('post.id/d');
|
||||
$active = input('post.active/d');
|
||||
Db::name('optimizeip')->where('id', $id)->update(['active' => $active]);
|
||||
return json(['code' => 0, 'msg' => '设置成功']);
|
||||
} elseif ($action == 'del') {
|
||||
$id = input('post.id/d');
|
||||
Db::name('optimizeip')->where('id', $id)->delete();
|
||||
return json(['code' => 0, 'msg' => '删除成功']);
|
||||
} elseif ($action == 'run') {
|
||||
$id = input('post.id/d');
|
||||
$task = Db::name('optimizeip')->where('id', $id)->find();
|
||||
if (empty($task)) return json(['code' => -1, 'msg' => '任务不存在']);
|
||||
try {
|
||||
$result = (new OptimizeService())->execute_one($task);
|
||||
Db::name('optimizeip')->where('id', $id)->update(['status' => 1, 'errmsg' => null, 'updatetime' => date('Y-m-d H:i:s')]);
|
||||
return json(['code' => 0, 'msg' => '优选任务执行成功:' . $result]);
|
||||
} catch (Exception $e) {
|
||||
Db::name('optimizeip')->where('id', $id)->update(['status' => 2, 'errmsg' => $e->getMessage(), 'updatetime' => date('Y-m-d H:i:s')]);
|
||||
return json(['code' => -1, 'msg' => '优选任务执行失败:' . $e->getMessage(), 'stack' => $e->__toString()]);
|
||||
}
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => '参数错误']);
|
||||
}
|
||||
}
|
||||
$task = null;
|
||||
if ($action == 'edit') {
|
||||
$id = input('get.id/d');
|
||||
$task = Db::name('optimizeip')->where('id', $id)->find();
|
||||
if (empty($task)) return $this->alert('error', '任务不存在');
|
||||
}
|
||||
|
||||
$domains = [];
|
||||
foreach (Db::name('domain')->alias('A')->join('account B', 'A.aid = B.id')->field('A.*')->where('B.type', '<>', 'cloudflare')->select() as $row) {
|
||||
$domains[$row['id']] = $row['name'];
|
||||
}
|
||||
View::assign('domains', $domains);
|
||||
|
||||
View::assign('info', $task);
|
||||
View::assign('action', $action);
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function queryapi()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$optimize_ip_api = input('post.optimize_ip_api/d');
|
||||
$optimize_ip_key = input('post.optimize_ip_key', null, 'trim');
|
||||
if (empty($optimize_ip_key)) return json(['code' => -1, 'msg' => '参数不能为空']);
|
||||
try {
|
||||
$result = (new OptimizeService())->get_license($optimize_ip_api, $optimize_ip_key);
|
||||
return json(['code' => 0, 'msg' => '当前积分余额:' . $result]);
|
||||
} catch (Exception $e) {
|
||||
return json(['code' => -1, 'msg' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
$run_time = Db::name('optimizeip')->where('active', 1)->order('updatetime', 'desc')->value('updatetime');
|
||||
$run_state = $run_time ? (time() - strtotime($run_time) > 3600 ? 0 : 1) : 0;
|
||||
return $run_state == 1 ? 'ok' : 'error';
|
||||
}
|
||||
}
|
||||
@@ -9,53 +9,62 @@ use think\facade\Request;
|
||||
|
||||
class User extends BaseController
|
||||
{
|
||||
|
||||
public function user(){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
|
||||
public function user()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$list = Db::name('domain')->select();
|
||||
$domains = [];
|
||||
foreach($list as $row){
|
||||
foreach ($list as $row) {
|
||||
$domains[] = $row['name'];
|
||||
}
|
||||
View::assign('domains', $domains);
|
||||
return view();
|
||||
}
|
||||
|
||||
public function user_data(){
|
||||
if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
|
||||
public function user_data()
|
||||
{
|
||||
if (!checkPermission(2)) return json(['total' => 0, 'rows' => []]);
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
$offset = input('post.offset/d');
|
||||
$limit = input('post.limit/d');
|
||||
|
||||
$select = Db::name('user');
|
||||
if(!empty($kw)){
|
||||
if (!empty($kw)) {
|
||||
$select->whereLike('id|username', $kw);
|
||||
}
|
||||
$total = $select->count();
|
||||
$rows = $select->order('id','desc')->limit($offset, $limit)->select();
|
||||
$rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
|
||||
|
||||
return json(['total'=>$total, 'rows'=>$rows]);
|
||||
return json(['total' => $total, 'rows' => $rows]);
|
||||
}
|
||||
|
||||
public function user_op(){
|
||||
if(!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
public function user_op()
|
||||
{
|
||||
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||
$act = input('param.act');
|
||||
if($act == 'get'){
|
||||
if ($act == 'get') {
|
||||
$id = input('post.id/d');
|
||||
$row = Db::name('user')->where('id', $id)->find();
|
||||
if(!$row) return json(['code'=>-1, 'msg'=>'用户不存在']);
|
||||
if (!$row) {
|
||||
return json(['code' => -1, 'msg' => '用户不存在']);
|
||||
}
|
||||
$row['permission'] = Db::name('permission')->where('uid', $id)->column('domain');
|
||||
return json(['code'=>0, 'data'=>$row]);
|
||||
}elseif($act == 'add'){
|
||||
return json(['code' => 0, 'data' => $row]);
|
||||
} elseif ($act == 'add') {
|
||||
$username = input('post.username', null, 'trim');
|
||||
$password = input('post.password', null, 'trim');
|
||||
$is_api = input('post.is_api/d');
|
||||
$apikey = input('post.apikey', null, 'trim');
|
||||
$level = input('post.level/d');
|
||||
if(empty($username) || empty($password)) return json(['code'=>-1, 'msg'=>'用户名或密码不能为空']);
|
||||
if($is_api ==1 && empty($apikey)) return json(['code'=>-1, 'msg'=>'API密钥不能为空']);
|
||||
if(Db::name('user')->where('username', $username)->find()){
|
||||
return json(['code'=>-1, 'msg'=>'用户名已存在']);
|
||||
if (empty($username) || empty($password)) {
|
||||
return json(['code' => -1, 'msg' => '用户名或密码不能为空']);
|
||||
}
|
||||
if ($is_api == 1 && empty($apikey)) {
|
||||
return json(['code' => -1, 'msg' => 'API密钥不能为空']);
|
||||
}
|
||||
if (Db::name('user')->where('username', $username)->find()) {
|
||||
return json(['code' => -1, 'msg' => '用户名已存在']);
|
||||
}
|
||||
$uid = Db::name('user')->insertGetId([
|
||||
'username' => $username,
|
||||
@@ -66,75 +75,91 @@ class User extends BaseController
|
||||
'regtime' => date('Y-m-d H:i:s'),
|
||||
'status' => 1,
|
||||
]);
|
||||
if($level == 1){
|
||||
if ($level == 1) {
|
||||
$permission = input('post.permission/a');
|
||||
if(!empty($permission)){
|
||||
if (!empty($permission)) {
|
||||
$data = [];
|
||||
foreach($permission as $domain){
|
||||
$data[] = ['uid'=>$uid, 'domain'=>$domain];
|
||||
foreach ($permission as $domain) {
|
||||
$data[] = ['uid' => $uid, 'domain' => $domain];
|
||||
}
|
||||
Db::name('permission')->insertAll($data);
|
||||
}
|
||||
}
|
||||
return json(['code'=>0, 'msg'=>'添加用户成功!']);
|
||||
}elseif($act == 'edit'){
|
||||
return json(['code' => 0, 'msg' => '添加用户成功!']);
|
||||
} elseif ($act == 'edit') {
|
||||
$id = input('post.id/d');
|
||||
$row = Db::name('user')->where('id', $id)->find();
|
||||
if(!$row) return json(['code'=>-1, 'msg'=>'用户不存在']);
|
||||
if (!$row) return json(['code' => -1, 'msg' => '用户不存在']);
|
||||
$username = input('post.username', null, 'trim');
|
||||
$is_api = input('post.is_api/d');
|
||||
$apikey = input('post.apikey', null, 'trim');
|
||||
$level = input('post.level/d');
|
||||
$repwd = input('post.repwd', null, 'trim');
|
||||
if(empty($username)) return json(['code'=>-1, 'msg'=>'用户名不能为空']);
|
||||
if($is_api ==1 && empty($apikey)) return json(['code'=>-1, 'msg'=>'API密钥不能为空']);
|
||||
if(Db::name('user')->where('username', $username)->where('id', '<>', $id)->find()){
|
||||
return json(['code'=>-1, 'msg'=>'用户名已存在']);
|
||||
if (empty($username)) {
|
||||
return json(['code' => -1, 'msg' => '用户名不能为空']);
|
||||
}
|
||||
if ($is_api == 1 && empty($apikey)) {
|
||||
return json(['code' => -1, 'msg' => 'API密钥不能为空']);
|
||||
}
|
||||
if (Db::name('user')->where('username', $username)->where('id', '<>', $id)->find()) {
|
||||
return json(['code' => -1, 'msg' => '用户名已存在']);
|
||||
}
|
||||
if ($level == 1 && ($id == 1000 || $id == $this->request->user['id'])) {
|
||||
$level = 2;
|
||||
}
|
||||
if($level == 1 && ($id == 1000 || $id == request()->user['id'])) $level = 2;
|
||||
Db::name('user')->where('id', $id)->update([
|
||||
'username' => $username,
|
||||
'is_api' => $is_api,
|
||||
'apikey' => $apikey,
|
||||
'level' => $level,
|
||||
]);
|
||||
Db::name('permission')->where(['uid'=>$id])->delete();
|
||||
if($level == 1){
|
||||
Db::name('permission')->where(['uid' => $id])->delete();
|
||||
if ($level == 1) {
|
||||
$permission = input('post.permission/a');
|
||||
if(!empty($permission)){
|
||||
if (!empty($permission)) {
|
||||
$data = [];
|
||||
foreach($permission as $domain){
|
||||
$data[] = ['uid'=>$id, 'domain'=>$domain];
|
||||
foreach ($permission as $domain) {
|
||||
$data[] = ['uid' => $id, 'domain' => $domain];
|
||||
}
|
||||
Db::name('permission')->insertAll($data);
|
||||
}
|
||||
}
|
||||
if(!empty($repwd)){
|
||||
Db::name('user')->where('id', $id)->update(['password'=>password_hash($repwd, PASSWORD_DEFAULT)]);
|
||||
if (!empty($repwd)) {
|
||||
Db::name('user')->where('id', $id)->update(['password' => password_hash($repwd, PASSWORD_DEFAULT)]);
|
||||
}
|
||||
return json(['code'=>0, 'msg'=>'修改用户成功!']);
|
||||
}elseif($act == 'set'){
|
||||
return json(['code' => 0, 'msg' => '修改用户成功!']);
|
||||
} elseif ($act == 'set') {
|
||||
$id = input('post.id/d');
|
||||
$status = input('post.status/d');
|
||||
if($id == 1000) return json(['code'=>-1, 'msg'=>'此用户无法修改状态']);
|
||||
if($id == request()->user['id']) return json(['code'=>-1, 'msg'=>'当前登录用户无法修改状态']);
|
||||
Db::name('user')->where('id', $id)->update(['status'=>$status]);
|
||||
return json(['code'=>0]);
|
||||
}elseif($act == 'del'){
|
||||
if ($id == 1000) {
|
||||
return json(['code' => -1, 'msg' => '此用户无法修改状态']);
|
||||
}
|
||||
if ($id == $this->request->user['id']) {
|
||||
return json(['code' => -1, 'msg' => '当前登录用户无法修改状态']);
|
||||
}
|
||||
Db::name('user')->where('id', $id)->update(['status' => $status]);
|
||||
return json(['code' => 0]);
|
||||
} elseif ($act == 'del') {
|
||||
$id = input('post.id/d');
|
||||
if($id == 1000) return json(['code'=>-1, 'msg'=>'此用户无法删除']);
|
||||
if($id == request()->user['id']) return json(['code'=>-1, 'msg'=>'当前登录用户无法删除']);
|
||||
if ($id == 1000) {
|
||||
return json(['code' => -1, 'msg' => '此用户无法删除']);
|
||||
}
|
||||
if ($id == $this->request->user['id']) {
|
||||
return json(['code' => -1, 'msg' => '当前登录用户无法删除']);
|
||||
}
|
||||
Db::name('user')->where('id', $id)->delete();
|
||||
return json(['code'=>0]);
|
||||
return json(['code' => 0]);
|
||||
}
|
||||
return json(['code'=>-3]);
|
||||
return json(['code' => -3]);
|
||||
}
|
||||
|
||||
public function log(){
|
||||
public function log()
|
||||
{
|
||||
return view();
|
||||
}
|
||||
|
||||
public function log_data(){
|
||||
public function log_data()
|
||||
{
|
||||
$uid = input('post.uid', null, 'trim');
|
||||
$kw = input('post.kw', null, 'trim');
|
||||
$domain = input('post.domain', null, 'trim');
|
||||
@@ -142,23 +167,22 @@ class User extends BaseController
|
||||
$limit = input('post.limit/d');
|
||||
|
||||
$select = Db::name('log');
|
||||
if(request()->user['type'] == 'domain'){
|
||||
$select->where('domain', request()->user['name']);
|
||||
}elseif(request()->user['level'] == 1){
|
||||
$select->where('uid', request()->user['id']);
|
||||
}elseif(!empty($uid)){
|
||||
if ($this->request->user['type'] == 'domain') {
|
||||
$select->where('domain', $this->request->user['name']);
|
||||
} elseif ($this->request->user['level'] == 1) {
|
||||
$select->where('uid', $this->request->user['id']);
|
||||
} elseif (!empty($uid)) {
|
||||
$select->where('uid', $uid);
|
||||
}
|
||||
if(!empty($kw)){
|
||||
$select->whereLike('action|data', '%'.$kw.'%');
|
||||
if (!empty($kw)) {
|
||||
$select->whereLike('action|data', '%' . $kw . '%');
|
||||
}
|
||||
if(!empty($domain)){
|
||||
if (!empty($domain)) {
|
||||
$select->where('domain', $domain);
|
||||
}
|
||||
$total = $select->count();
|
||||
$rows = $select->order('id','desc')->limit($offset, $limit)->select();
|
||||
$rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
|
||||
|
||||
return json(['total'=>$total, 'rows'=>$rows]);
|
||||
return json(['total' => $total, 'rows' => $rows]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace app\lib;
|
||||
|
||||
class CheckUtils
|
||||
{
|
||||
public static function curl($url, $timeout, $ip = null)
|
||||
public static function curl($url, $timeout, $ip = null, $proxy = false)
|
||||
{
|
||||
$status = true;
|
||||
$errmsg = null;
|
||||
@@ -19,6 +19,28 @@ class CheckUtils
|
||||
}
|
||||
}
|
||||
$ch = curl_init();
|
||||
if ($proxy) {
|
||||
$proxy_server = config_get('proxy_server');
|
||||
$proxy_port = intval(config_get('proxy_port'));
|
||||
$proxy_userpwd = config_get('proxy_user').':'.config_get('proxy_pwd');
|
||||
$proxy_type = config_get('proxy_type');
|
||||
if ($proxy_type == 'https') {
|
||||
$proxy_type = CURLPROXY_HTTPS;
|
||||
} elseif ($proxy_type == 'sock4') {
|
||||
$proxy_type = CURLPROXY_SOCKS4;
|
||||
} elseif ($proxy_type == 'sock5') {
|
||||
$proxy_type = CURLPROXY_SOCKS5;
|
||||
} else {
|
||||
$proxy_type = CURLPROXY_HTTP;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
|
||||
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
|
||||
if ($proxy_userpwd != ':') {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_userpwd);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
@@ -30,7 +52,7 @@ class CheckUtils
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
if(!empty($resolve)){
|
||||
if (!empty($resolve)) {
|
||||
curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
|
||||
curl_setopt($ch, CURLOPT_RESOLVE, [$resolve]);
|
||||
}
|
||||
@@ -41,19 +63,20 @@ class CheckUtils
|
||||
$errmsg = curl_error($ch);
|
||||
}
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if($status && ($httpcode < 200 || $httpcode >= 400)){
|
||||
if ($status && ($httpcode < 200 || $httpcode >= 400)) {
|
||||
$status = false;
|
||||
$errmsg = 'http_code='.$httpcode;
|
||||
}
|
||||
$usetime = round(curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000);
|
||||
curl_close($ch);
|
||||
return ['status'=>$status, 'errmsg'=>$errmsg, 'usetime'=>$usetime];
|
||||
return ['status' => $status, 'errmsg' => $errmsg, 'usetime' => $usetime];
|
||||
}
|
||||
|
||||
public static function tcp($target, $port, $timeout){
|
||||
if(!filter_var($target,FILTER_VALIDATE_IP) && checkDomain($target)){
|
||||
public static function tcp($target, $port, $timeout)
|
||||
{
|
||||
if (!filter_var($target, FILTER_VALIDATE_IP) && checkDomain($target)) {
|
||||
$target = gethostbyname($target);
|
||||
if(!$target)return ['status'=>false, 'error'=>'DNS resolve failed', 'usetime'=>0];
|
||||
if (!$target) return ['status' => false, 'error' => 'DNS resolve failed', 'usetime' => 0];
|
||||
}
|
||||
$starttime = getMillisecond();
|
||||
$fp = @fsockopen($target, $port, $errCode, $errStr, $timeout);
|
||||
@@ -64,27 +87,28 @@ class CheckUtils
|
||||
$status = false;
|
||||
}
|
||||
$endtime = getMillisecond();
|
||||
$usetime = $endtime-$starttime;
|
||||
return ['status'=>$status, 'errmsg'=>$errStr, 'usetime'=>$usetime];
|
||||
$usetime = $endtime - $starttime;
|
||||
return ['status' => $status, 'errmsg' => $errStr, 'usetime' => $usetime];
|
||||
}
|
||||
|
||||
public static function ping($target){
|
||||
if(!function_exists('exec'))return ['status'=>false, 'error'=>'exec函数不可用', 'usetime'=>0];
|
||||
if(!filter_var($target,FILTER_VALIDATE_IP) && checkDomain($target)){
|
||||
public static function ping($target)
|
||||
{
|
||||
if (!function_exists('exec')) return ['status' => false, 'error' => 'exec函数不可用', 'usetime' => 0];
|
||||
if (!filter_var($target, FILTER_VALIDATE_IP) && checkDomain($target)) {
|
||||
$target = gethostbyname($target);
|
||||
if(!$target)return ['status'=>false, 'error'=>'DNS resolve failed', 'usetime'=>0];
|
||||
if (!$target) return ['status' => false, 'error' => 'DNS resolve failed', 'usetime' => 0];
|
||||
}
|
||||
if(!filter_var($target,FILTER_VALIDATE_IP)){
|
||||
return ['status'=>false, 'error'=>'Invalid IP address', 'usetime'=>0];
|
||||
if (!filter_var($target, FILTER_VALIDATE_IP)) {
|
||||
return ['status' => false, 'error' => 'Invalid IP address', 'usetime' => 0];
|
||||
}
|
||||
$timeout = 1;
|
||||
exec('ping -c 1 -w '.$timeout.' '.$target.'', $output, $return_var);
|
||||
$usetime = !empty($output[1]) ? round(getSubstr($output[1], 'time=', ' ms')) : 0;
|
||||
$errmsg = null;
|
||||
if($return_var !== 0){
|
||||
$usetime = $usetime == 0 ? $timeout*1000 : $usetime;
|
||||
if ($return_var !== 0) {
|
||||
$usetime = $usetime == 0 ? $timeout * 1000 : $usetime;
|
||||
$errmsg = 'ping timeout';
|
||||
}
|
||||
return ['status'=>$return_var===0, 'errmsg'=>$errmsg, 'usetime'=>$usetime];
|
||||
return ['status' => $return_var === 0, 'errmsg' => $errmsg, 'usetime' => $usetime];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use think\facade\Db;
|
||||
|
||||
class DnsHelper
|
||||
@@ -10,68 +11,121 @@ class DnsHelper
|
||||
'name' => '阿里云',
|
||||
'config' => [
|
||||
'ak' => 'AccessKeyId',
|
||||
'sk' => 'AccessKeySecret'
|
||||
'sk' => 'AccessKeySecret',
|
||||
],
|
||||
'remark' => 1, //是否支持备注,1单独设置备注,2和记录一起设置
|
||||
'status' => true, //是否支持启用暂停
|
||||
'redirect' => true, //是否支持域名转发
|
||||
'log' => true, //是否支持查看日志
|
||||
'weight' => false, //是否支持权重
|
||||
],
|
||||
'dnspod' => [
|
||||
'name' => '腾讯云',
|
||||
'config' => [
|
||||
'ak' => 'SecretId',
|
||||
'sk' => 'SecretKey'
|
||||
'sk' => 'SecretKey',
|
||||
],
|
||||
'remark' => 1,
|
||||
'status' => true,
|
||||
'redirect' => true,
|
||||
'log' => true,
|
||||
'weight' => true,
|
||||
],
|
||||
'huawei' => [
|
||||
'name' => '华为云',
|
||||
'config' => [
|
||||
'ak' => 'AccessKeyId',
|
||||
'sk' => 'SecretAccessKey'
|
||||
'sk' => 'SecretAccessKey',
|
||||
],
|
||||
'remark' => 2,
|
||||
'status' => true,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
'weight' => true,
|
||||
],
|
||||
'west' => [
|
||||
'name' => '西部数码',
|
||||
'baidu' => [
|
||||
'name' => '百度云',
|
||||
'config' => [
|
||||
'ak' => '用户名',
|
||||
'sk' => 'API密码'
|
||||
],
|
||||
'remark' => 0,
|
||||
'status' => true,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
],
|
||||
'dnsla' => [
|
||||
'name' => 'DNSLA',
|
||||
'config' => [
|
||||
'ak' => 'APIID',
|
||||
'sk' => 'API密钥'
|
||||
],
|
||||
'remark' => 0,
|
||||
'status' => true,
|
||||
'redirect' => true,
|
||||
'log' => false,
|
||||
],
|
||||
'cloudflare' => [
|
||||
'name' => 'Cloudflare',
|
||||
'config' => [
|
||||
'ak' => '邮箱地址',
|
||||
'sk' => 'API密钥'
|
||||
'ak' => 'AccessKey',
|
||||
'sk' => 'SecretKey',
|
||||
],
|
||||
'remark' => 2,
|
||||
'status' => false,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
'weight' => false,
|
||||
],
|
||||
'west' => [
|
||||
'name' => '西部数码',
|
||||
'config' => [
|
||||
'ak' => '用户名',
|
||||
'sk' => 'API密码',
|
||||
],
|
||||
'remark' => 0,
|
||||
'status' => true,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
'weight' => false,
|
||||
],
|
||||
'huoshan' => [
|
||||
'name' => '火山引擎',
|
||||
'config' => [
|
||||
'ak' => 'AccessKeyId',
|
||||
'sk' => 'SecretAccessKey',
|
||||
],
|
||||
'remark' => 2,
|
||||
'status' => true,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
'weight' => true,
|
||||
],
|
||||
'dnsla' => [
|
||||
'name' => 'DNSLA',
|
||||
'config' => [
|
||||
'ak' => 'APIID',
|
||||
'sk' => 'API密钥',
|
||||
],
|
||||
'remark' => 0,
|
||||
'status' => true,
|
||||
'redirect' => true,
|
||||
'log' => false,
|
||||
'weight' => true,
|
||||
],
|
||||
'cloudflare' => [
|
||||
'name' => 'Cloudflare',
|
||||
'config' => [
|
||||
'ak' => '邮箱地址',
|
||||
'sk' => 'API密钥/令牌',
|
||||
],
|
||||
'remark' => 2,
|
||||
'status' => false,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
'weight' => false,
|
||||
],
|
||||
'namesilo' => [
|
||||
'name' => 'NameSilo',
|
||||
'config' => [
|
||||
'ak' => '账户名',
|
||||
'sk' => 'API Key',
|
||||
],
|
||||
'remark' => 0,
|
||||
'status' => false,
|
||||
'redirect' => false,
|
||||
'log' => false,
|
||||
'weight' => false,
|
||||
],
|
||||
];
|
||||
|
||||
public static $line_name = [
|
||||
'aliyun' => ['DEF' => 'default', 'CT' => 'telecom', 'CU' => 'unicom', 'CM' => 'mobile', 'AB' => 'oversea'],
|
||||
'dnspod' => ['DEF' => '0', 'CT' => '10=0', 'CU' => '10=1', 'CM' => '10=3', 'AB' => '3=0'],
|
||||
'huawei' => ['DEF' => 'default_view', 'CT' => 'Dianxin', 'CU' => 'Liantong', 'CM' => 'Yidong', 'AB' => 'Abroad'],
|
||||
'west' => ['DEF' => '', 'CT' => 'LTEL', 'CU' => 'LCNC', 'CM' => 'LMOB', 'AB' => 'LFOR'],
|
||||
'dnsla' => ['DEF' => '', 'CT' => '84613316902921216', 'CU' => '84613316923892736', 'CM' => '84613316953252864', 'AB' => ''],
|
||||
'huoshan' => ['DEF' => 'default', 'CT' => 'telecom', 'CU' => 'unicom', 'CM' => 'mobile', 'AB' => 'oversea'],
|
||||
'baidu' => ['DEF' => 'default', 'CT' => 'ct', 'CU' => 'cnc', 'CM' => 'cmnet', 'AB' => ''],
|
||||
'cloudflare' => ['DEF' => '0'],
|
||||
];
|
||||
|
||||
public static function getList()
|
||||
@@ -79,19 +133,23 @@ class DnsHelper
|
||||
return self::$dns_config;
|
||||
}
|
||||
|
||||
private static function getConfig($aid){
|
||||
private static function getConfig($aid)
|
||||
{
|
||||
$account = Db::name('account')->where('id', $aid)->find();
|
||||
if(!$account) return false;
|
||||
if (!$account) return false;
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DnsInterface|bool
|
||||
*/
|
||||
public static function getModel($aid, $domain = null, $domainid = null)
|
||||
{
|
||||
$config = self::getConfig($aid);
|
||||
if(!$config) return false;
|
||||
if (!$config) return false;
|
||||
$dnstype = $config['type'];
|
||||
$class = "\\app\\lib\\dns\\{$dnstype}";
|
||||
if(class_exists($class)){
|
||||
if (class_exists($class)) {
|
||||
$config['domain'] = $domain;
|
||||
$config['domainid'] = $domainid;
|
||||
$model = new $class($config);
|
||||
@@ -100,11 +158,14 @@ class DnsHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DnsInterface|bool
|
||||
*/
|
||||
public static function getModel2($config)
|
||||
{
|
||||
$dnstype = $config['type'];
|
||||
$class = "\\app\\lib\\dns\\{$dnstype}";
|
||||
if(class_exists($class)){
|
||||
if (class_exists($class)) {
|
||||
$config['domain'] = $config['name'];
|
||||
$config['domainid'] = $config['thirdid'];
|
||||
$model = new $class($config);
|
||||
@@ -112,4 +173,4 @@ class DnsHelper
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,17 +8,17 @@ interface DnsInterface
|
||||
|
||||
function check();
|
||||
|
||||
function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20);
|
||||
function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20);
|
||||
|
||||
function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null);
|
||||
function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null);
|
||||
|
||||
function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null);
|
||||
function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null);
|
||||
|
||||
function getDomainRecordInfo($RecordId);
|
||||
|
||||
function addDomainRecord($Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = 1, $Remark = null);
|
||||
function addDomainRecord($Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = 1, $Weight = null, $Remark = null);
|
||||
|
||||
function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = 1, $Remark = null);
|
||||
function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = 1, $Weight = null, $Remark = null);
|
||||
|
||||
function updateDomainRecordRemark($RecordId, $Remark);
|
||||
|
||||
@@ -31,5 +31,4 @@ interface DnsInterface
|
||||
function getRecordLine();
|
||||
|
||||
function getMinTTL();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,60 +8,70 @@ class MsgNotice
|
||||
|
||||
public static function send($action, $task, $result)
|
||||
{
|
||||
if($action == 1){
|
||||
if ($action == 1) {
|
||||
$mail_title = 'DNS容灾切换-发生告警通知';
|
||||
$mail_content = '尊敬的系统管理员,您好:<br/>您的域名 <b>'.$task['domain'].'</b> 的 <b>'.$task['main_value'].'</b> 记录发生了异常';
|
||||
if($task['type'] == 2){
|
||||
if ($task['type'] == 2) {
|
||||
$mail_content .= ',已自动切换为备用解析记录 '.$task['backup_value'].' ';
|
||||
}elseif($task['type'] == 1){
|
||||
} elseif ($task['type'] == 1) {
|
||||
$mail_content .= ',已自动暂停解析';
|
||||
}else{
|
||||
} else {
|
||||
$mail_content .= ',请及时处理';
|
||||
}
|
||||
if(!empty($result['errmsg'])){
|
||||
if (!empty($result['errmsg'])) {
|
||||
$mail_content .= '。<br/>异常信息:'.$result['errmsg'];
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
$mail_title = 'DNS容灾切换-恢复正常通知';
|
||||
$mail_content = '尊敬的系统管理员,您好:<br/>您的域名 <b>'.$task['domain'].'</b> 的 <b>'.$task['main_value'].'</b> 记录已恢复正常';
|
||||
if($task['type'] == 2){
|
||||
if ($task['type'] == 2) {
|
||||
$mail_content .= ',已自动切换回当前解析记录';
|
||||
}elseif($task['type'] == 1){
|
||||
} elseif ($task['type'] == 1) {
|
||||
$mail_content .= ',已自动开启解析';
|
||||
}
|
||||
$lasttime = convert_second(time() - $task['switchtime']);
|
||||
$mail_content .= '。<br/>异常持续时间:'.$lasttime;
|
||||
}
|
||||
if(!empty($task['remark'])) $mail_title .= '('.$task['remark'].')';
|
||||
if(!empty($task['remark'])) $mail_content .= '<br/>备注:'.$task['remark'];
|
||||
if (!empty($task['remark'])) {
|
||||
$mail_title .= '('.$task['remark'].')';
|
||||
}
|
||||
if (!empty($task['remark'])) {
|
||||
$mail_content .= '<br/>备注:'.$task['remark'];
|
||||
}
|
||||
$mail_content .= '<br/>'.self::$sitename.'<br/>'.date('Y-m-d H:i:s');
|
||||
|
||||
if(config_get('notice_mail') == 1){
|
||||
$mail_name = config_get('mail_recv')?config_get('mail_recv'):config_get('mail_name');
|
||||
if (config_get('notice_mail') == 1) {
|
||||
$mail_name = config_get('mail_recv') ? config_get('mail_recv') : config_get('mail_name');
|
||||
self::send_mail($mail_name, $mail_title, $mail_content);
|
||||
}
|
||||
if(config_get('notice_wxtpl') == 1){
|
||||
$mail_content = str_replace(['<br/>', '<b>', '</b>'], ["\n\n", '**', '**'], $mail_content);
|
||||
self::send_wechat_tplmsg($mail_title, $mail_content);
|
||||
if (config_get('notice_wxtpl') == 1) {
|
||||
$content = str_replace(['<br/>', '<b>', '</b>'], ["\n\n", '**', '**'], $mail_content);
|
||||
self::send_wechat_tplmsg($mail_title, $content);
|
||||
}
|
||||
if (config_get('notice_tgbot') == 1) {
|
||||
$content = str_replace('<br/>', "\n", $mail_content);
|
||||
$content = "<strong>".$mail_title."</strong>\n".$content;
|
||||
self::send_telegram_bot($content);
|
||||
}
|
||||
}
|
||||
|
||||
public static function send_mail($to, $sub, $msg){
|
||||
|
||||
public static function send_mail($to, $sub, $msg)
|
||||
{
|
||||
$mail_type = config_get('mail_type');
|
||||
if($mail_type == 1){
|
||||
if ($mail_type == 1) {
|
||||
$mail = new \app\lib\mail\Sendcloud(config_get('mail_apiuser'), config_get('mail_apikey'));
|
||||
return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
|
||||
}elseif($mail_type == 2){
|
||||
return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
|
||||
} elseif ($mail_type == 2) {
|
||||
$mail = new \app\lib\mail\Aliyun(config_get('mail_apiuser'), config_get('mail_apikey'));
|
||||
return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
|
||||
}else{
|
||||
} else {
|
||||
$mail_name = config_get('mail_name');
|
||||
$mail_port = intval(config_get('mail_port'));
|
||||
$mail_smtp = config_get('mail_smtp');
|
||||
$mail_pwd = config_get('mail_pwd');
|
||||
if(!$mail_name || !$mail_port || !$mail_smtp || !$mail_pwd)return false;
|
||||
if (!$mail_name || !$mail_port || !$mail_smtp || !$mail_pwd) return false;
|
||||
$mail = new \app\lib\mail\PHPMailer\PHPMailer(true);
|
||||
try{
|
||||
try {
|
||||
$mail->SMTPDebug = 0;
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->Timeout = 5;
|
||||
@@ -70,8 +80,8 @@ class MsgNotice
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $mail_name;
|
||||
$mail->Password = $mail_pwd;
|
||||
if($mail_port == 587) $mail->SMTPSecure = 'tls';
|
||||
else if($mail_port >= 465) $mail->SMTPSecure = 'ssl';
|
||||
if ($mail_port == 587) $mail->SMTPSecure = 'tls';
|
||||
else if ($mail_port >= 465) $mail->SMTPSecure = 'ssl';
|
||||
else $mail->SMTPAutoTLS = false;
|
||||
$mail->Port = $mail_port;
|
||||
$mail->setFrom($mail_name, self::$sitename);
|
||||
@@ -88,18 +98,78 @@ class MsgNotice
|
||||
}
|
||||
}
|
||||
|
||||
public static function send_wechat_tplmsg($title, $content){
|
||||
public static function send_wechat_tplmsg($title, $content)
|
||||
{
|
||||
$wechat_apptoken = config_get('wechat_apptoken');
|
||||
$wechat_appuid = config_get('wechat_appuid');
|
||||
if(!$wechat_apptoken||!$wechat_appuid)return false;
|
||||
$url = 'https://wxpusher.zjiecode.com/api/send/message';
|
||||
$post = ['appToken'=>$wechat_apptoken, 'content'=>$content, 'summary'=>$title, 'contentType'=>3, 'uids'=>[$wechat_appuid]];
|
||||
$result = get_curl($url, json_encode($post),0,0,0,0,0,['Content-Type: application/json; charset=UTF-8']);
|
||||
$arr = json_decode($result, true);
|
||||
if(isset($arr['success']) && $arr['success']==true){
|
||||
return true;
|
||||
}else{
|
||||
return $arr['msg'];
|
||||
}
|
||||
if (!$wechat_apptoken || !$wechat_appuid) return false;
|
||||
$url = 'https://wxpusher.zjiecode.com/api/send/message';
|
||||
$post = ['appToken' => $wechat_apptoken, 'content' => $content, 'summary' => $title, 'contentType' => 3, 'uids' => [$wechat_appuid]];
|
||||
$result = get_curl($url, json_encode($post), 0, 0, 0, 0, 0, ['Content-Type: application/json; charset=UTF-8']);
|
||||
$arr = json_decode($result, true);
|
||||
if (isset($arr['success']) && $arr['success'] == true) {
|
||||
return true;
|
||||
} else {
|
||||
return $arr['msg'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function send_telegram_bot($content)
|
||||
{
|
||||
$tgbot_token = config_get('tgbot_token');
|
||||
$tgbot_chatid = config_get('tgbot_chatid');
|
||||
if (!$tgbot_token || !$tgbot_chatid) return false;
|
||||
$url = 'https://api.telegram.org/bot'.$tgbot_token.'/sendMessage';
|
||||
$post = ['chat_id' => $tgbot_chatid, 'text' => $content, 'parse_mode' => 'HTML'];
|
||||
$result = self::telegram_curl($url, http_build_query($post));
|
||||
$arr = json_decode($result, true);
|
||||
if (isset($arr['ok']) && $arr['ok'] == true) {
|
||||
return true;
|
||||
} else {
|
||||
return $arr['description'];
|
||||
}
|
||||
}
|
||||
|
||||
private static function telegram_curl($url, $post)
|
||||
{
|
||||
$ch = curl_init();
|
||||
if (config_get('tgbot_proxy') == 1) {
|
||||
$proxy_server = config_get('proxy_server');
|
||||
$proxy_port = intval(config_get('proxy_port'));
|
||||
$proxy_userpwd = config_get('proxy_user').':'.config_get('proxy_pwd');
|
||||
$proxy_type = config_get('proxy_type');
|
||||
if ($proxy_type == 'https') {
|
||||
$proxy_type = CURLPROXY_HTTPS;
|
||||
} elseif ($proxy_type == 'sock4') {
|
||||
$proxy_type = CURLPROXY_SOCKS4;
|
||||
} elseif ($proxy_type == 'sock5') {
|
||||
$proxy_type = CURLPROXY_SOCKS5;
|
||||
} else {
|
||||
$proxy_type = CURLPROXY_HTTP;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
|
||||
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
|
||||
if ($proxy_userpwd != ':') {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_userpwd);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$httpheader[] = "Accept: */*";
|
||||
$httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
|
||||
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
|
||||
$httpheader[] = "Connection: close";
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.0.4; es-mx; HTC_One_X Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0");
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$ret = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
232
app/lib/OptimizeService.php
Normal file
232
app/lib/OptimizeService.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use Exception;
|
||||
use think\facade\Db;
|
||||
|
||||
class OptimizeService
|
||||
{
|
||||
private $ip_address = [];
|
||||
private $add_num = 0;
|
||||
private $change_num = 0;
|
||||
private $del_num = 0;
|
||||
|
||||
public static function get_license($api, $key)
|
||||
{
|
||||
if ($api == 2) {
|
||||
throw new Exception('当前接口暂不支持');
|
||||
} elseif ($api == 1) {
|
||||
$url = 'https://api.hostmonit.com/get_license?license='.$key;
|
||||
} else {
|
||||
$url = 'https://www.wetest.vip/api/cf2dns/get_license?license='.$key;
|
||||
}
|
||||
$response = get_curl($url);
|
||||
$arr = json_decode($response, true);
|
||||
if (isset($arr['code']) && $arr['code'] == 200 && isset($arr['count'])) {
|
||||
return $arr['count'];
|
||||
} elseif (isset($arr['info'])) {
|
||||
throw new Exception('获取剩余请求次数失败,'.$arr['info']);
|
||||
} else {
|
||||
throw new Exception('获取剩余请求次数失败');
|
||||
}
|
||||
}
|
||||
|
||||
public function get_ip_address($cdn_type = 1, $ip_type = 'v4')
|
||||
{
|
||||
$api = config_get('optimize_ip_api', 0);
|
||||
if ($api == 2) {
|
||||
$url = 'https://api.345673.xyz/get_data';
|
||||
} elseif ($api == 1) {
|
||||
$url = 'https://api.hostmonit.com/get_optimization_ip';
|
||||
} else {
|
||||
$url = 'https://www.wetest.vip/api/cf2dns/';
|
||||
if ($cdn_type == 1) {
|
||||
$url .= 'get_cloudflare_ip';
|
||||
} elseif ($cdn_type == 2) {
|
||||
$url .= 'get_cloudfront_ip';
|
||||
} elseif ($cdn_type == 3) {
|
||||
$url .= 'get_gcore_ip';
|
||||
}
|
||||
}
|
||||
$params = [
|
||||
'key' => config_get('optimize_ip_key', 'o1zrmHAF'),
|
||||
'type' => $ip_type,
|
||||
];
|
||||
$response = get_curl($url, json_encode($params), 0, 0, 0, 0, 0, ['Content-Type: application/json; charset=UTF-8']);
|
||||
$arr = json_decode($response, true);
|
||||
if (isset($arr['code']) && $arr['code'] == 200) {
|
||||
return $arr['info'];
|
||||
} elseif (isset($arr['info'])) {
|
||||
throw new Exception('获取优选IP数据失败,'.$arr['info']);
|
||||
} elseif (isset($arr['msg'])) {
|
||||
throw new Exception('获取优选IP数据失败,'.$arr['msg']);
|
||||
} else {
|
||||
throw new Exception('获取优选IP数据失败,原因未知');
|
||||
}
|
||||
}
|
||||
|
||||
public function get_ip_address2($cdn_type = 1, $ip_type = 'v4')
|
||||
{
|
||||
$key = $cdn_type.'_'.$ip_type;
|
||||
if (!isset($this->ip_address[$key])) {
|
||||
$info = $this->get_ip_address($cdn_type, $ip_type);
|
||||
$res = [];
|
||||
if (isset($info['DEF'])) {
|
||||
$res['DEF'] = $info['DEF'];
|
||||
}
|
||||
if (isset($info['CT'])) {
|
||||
$res['CT'] = $info['CT'];
|
||||
}
|
||||
if (isset($info['CU'])) {
|
||||
$res['CU'] = $info['CU'];
|
||||
}
|
||||
if (isset($info['CM'])) {
|
||||
$res['CM'] = $info['CM'];
|
||||
}
|
||||
$this->ip_address[$key] = $res;
|
||||
}
|
||||
return $this->ip_address[$key];
|
||||
}
|
||||
|
||||
//批量执行优选任务
|
||||
public function execute()
|
||||
{
|
||||
$list = Db::name('optimizeip')->where('active', 1)->select();
|
||||
echo '开始执行IP优选任务,共获取到'.count($list).'个待执行任务'."\n";
|
||||
foreach ($list as $row) {
|
||||
try {
|
||||
$result = $this->execute_one($row);
|
||||
Db::name('optimizeip')->where('id', $row['id'])->update(['status' => 1, 'errmsg' => null, 'updatetime' => date('Y-m-d H:i:s')]);
|
||||
echo '优选任务'.$row['id'].'执行成功:'.$result."\n";
|
||||
} catch (Exception $e) {
|
||||
Db::name('optimizeip')->where('id', $row['id'])->update(['status' => 2, 'errmsg' => $e->getMessage(), 'updatetime' => date('Y-m-d H:i:s')]);
|
||||
echo '优选任务'.$row['id'].'执行失败:'.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//执行单个优选任务
|
||||
public function execute_one($row)
|
||||
{
|
||||
$this->add_num = 0;
|
||||
$this->change_num = 0;
|
||||
$this->del_num = 0;
|
||||
$ip_types = explode(',', $row['ip_type']);
|
||||
foreach ($ip_types as $ip_type) {
|
||||
if (empty($ip_type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$drow = Db::name('domain')->alias('A')->join('account B', 'A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
|
||||
if (!$drow) {
|
||||
throw new Exception('域名不存在(ID:'.$row['did'].')');
|
||||
}
|
||||
if (!isset(DnsHelper::$line_name[$drow['type']])) {
|
||||
throw new Exception('不支持的DNS服务商');
|
||||
}
|
||||
|
||||
$info = $this->get_ip_address2($row['cdn_type'], $ip_type);
|
||||
|
||||
$dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
|
||||
$domainRecords = $dns->getSubDomainRecords($row['rr'], 1, 100);
|
||||
if (!$domainRecords) {
|
||||
throw new Exception('获取记录列表失败,'.$dns->getError());
|
||||
}
|
||||
|
||||
if ($row['type'] == 1 && isset($info['DEF']) && !empty($info['DEF'])) {
|
||||
$row['type'] = 0;
|
||||
}
|
||||
|
||||
foreach ($info as $line => $iplist) {
|
||||
if (empty($iplist)) {
|
||||
continue;
|
||||
}
|
||||
$get_ips = array_column($iplist, 'ip');
|
||||
if ($drow['type'] == 'huawei') {
|
||||
sort($get_ips);
|
||||
$get_ips = [implode(',', $get_ips)];
|
||||
$row['recordnum'] = 1;
|
||||
}
|
||||
if ($row['type'] == 1 && $line == 'CT') {
|
||||
$line = 'DEF';
|
||||
}
|
||||
$line_name = DnsHelper::$line_name[$drow['type']][$line];
|
||||
$this->process_dns_line($dns, $row, $domainRecords['list'], $get_ips, $line_name, $ip_type);
|
||||
}
|
||||
}
|
||||
|
||||
return '成功添加'.$this->add_num.'条记录,修改'.$this->change_num.'条记录,删除'.$this->del_num.'条记录';
|
||||
}
|
||||
|
||||
//处理单个线路的解析记录
|
||||
private function process_dns_line($dns, $row, $record_list, $get_ips, $line_name, $ip_type)
|
||||
{
|
||||
$record_num = $row['recordnum'];
|
||||
$records = array_filter($record_list, function ($v) use ($line_name) {
|
||||
return $v['Line'] == $line_name;
|
||||
});
|
||||
|
||||
//删除CNAME记录
|
||||
$cname_records = array_filter($records, function ($v) {
|
||||
return $v['Type'] == 'CNAME';
|
||||
});
|
||||
if (!empty($cname_records)) {
|
||||
foreach ($cname_records as $record) {
|
||||
$dns->deleteDomainRecord($record['RecordId']);
|
||||
}
|
||||
}
|
||||
|
||||
//处理A/AAAA记录
|
||||
$ip_records = array_filter($records, function ($v) use ($ip_type) {
|
||||
return $v['Type'] == ($ip_type == 'v6' ? 'AAAA' : 'A');
|
||||
});
|
||||
|
||||
if (!empty($ip_records) && is_array($ip_records[array_key_first($ip_records)]['Value'])) { //处理华为云记录
|
||||
foreach ($ip_records as &$ip_record) {
|
||||
sort($ip_record['Value']);
|
||||
$ip_record['Value'] = implode(',', $ip_record['Value']);
|
||||
}
|
||||
}
|
||||
|
||||
$exist_ips = array_column($ip_records, 'Value');
|
||||
$add_ips = array_diff($get_ips, $exist_ips);
|
||||
$del_ips = array_diff($exist_ips, $get_ips);
|
||||
$correct_ips = array_diff($exist_ips, $del_ips);
|
||||
$correct_count = count($correct_ips);
|
||||
if (!empty($del_ips)) {
|
||||
foreach ($ip_records as $record) {
|
||||
if (in_array($record['Value'], $del_ips)) {
|
||||
$add_ip = array_pop($add_ips);
|
||||
if ($add_ip) {
|
||||
$res = $dns->updateDomainRecord($record['RecordId'], $row['rr'], $ip_type == 'v6' ? 'AAAA' : 'A', $add_ip, $line_name, $row['ttl']);
|
||||
if (!$res) {
|
||||
throw new Exception('修改解析失败,'.$dns->getError());
|
||||
}
|
||||
$this->change_num++;
|
||||
$correct_count++;
|
||||
} else {
|
||||
$res = $dns->deleteDomainRecord($record['RecordId']);
|
||||
if (!$res) {
|
||||
throw new Exception('删除解析失败,'.$dns->getError());
|
||||
}
|
||||
$this->del_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($correct_count < $record_num && !empty($add_ips)) {
|
||||
foreach ($add_ips as $add_ip) {
|
||||
$res = $dns->addDomainRecord($row['rr'], $ip_type == 'v6' ? 'AAAA' : 'A', $add_ip, $line_name, $row['ttl']);
|
||||
if (!$res) {
|
||||
throw new Exception('添加解析失败,'.$dns->getError());
|
||||
}
|
||||
$this->add_num++;
|
||||
$correct_count++;
|
||||
if ($correct_count >= $record_num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use app\lib\NewDb;
|
||||
@@ -12,7 +13,7 @@ class TaskRunner
|
||||
|
||||
private function db()
|
||||
{
|
||||
if(!$this->conn){
|
||||
if (!$this->conn) {
|
||||
$this->conn = NewDb::connect();
|
||||
}
|
||||
return $this->conn;
|
||||
@@ -20,80 +21,92 @@ class TaskRunner
|
||||
|
||||
private function closeDb()
|
||||
{
|
||||
if($this->conn){
|
||||
if ($this->conn) {
|
||||
$this->conn->close();
|
||||
}
|
||||
}
|
||||
|
||||
public function execute($row)
|
||||
{
|
||||
if($row['checktype'] == 2){
|
||||
$result = CheckUtils::curl($row['checkurl'], $row['timeout'], $row['main_value']);
|
||||
}else if($row['checktype'] == 1){
|
||||
$result = CheckUtils::tcp($row['main_value'], $row['tcpport'], $row['timeout']);
|
||||
}else{
|
||||
$result = CheckUtils::ping($row['main_value']);
|
||||
}
|
||||
|
||||
$action = 0;
|
||||
if($result['status'] && $row['status']==1){
|
||||
if($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']){
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['status'=>0, 'errcount'=>0, 'switchtime'=>time()]);
|
||||
if ($row['type'] == 3) { //条件开启解析
|
||||
$action = 0;
|
||||
$remain = $this->db()->name('dmtask')->where(['did' => $row['did'], 'rr' => $row['rr'], 'type' => 1, 'status' => 0])->count();
|
||||
if ($remain <= $row['cycle'] && $row['status'] == 0) {
|
||||
$action = 2;
|
||||
}else{
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
|
||||
}
|
||||
}elseif(!$result['status'] && $row['status']==0){
|
||||
if($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']){
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['status'=>1, 'errcount'=>0, 'switchtime'=>time()]);
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 1, 'errcount' => 0, 'switchtime' => time()]);
|
||||
} elseif ($remain > $row['cycle'] && $row['status'] == 1) {
|
||||
$action = 1;
|
||||
}else{
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 0, 'errcount' => 0, 'switchtime' => time()]);
|
||||
}
|
||||
} else {
|
||||
if ($row['checktype'] == 2) {
|
||||
$result = CheckUtils::curl($row['checkurl'], $row['timeout'], $row['main_value'], $row['proxy'] == 1);
|
||||
} elseif ($row['checktype'] == 1) {
|
||||
$result = CheckUtils::tcp($row['main_value'], $row['tcpport'], $row['timeout']);
|
||||
} else {
|
||||
$result = CheckUtils::ping($row['main_value']);
|
||||
}
|
||||
|
||||
$action = 0;
|
||||
if ($result['status'] && $row['status'] == 1) {
|
||||
if ($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']) {
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 0, 'errcount' => 0, 'switchtime' => time()]);
|
||||
$action = 2;
|
||||
} else {
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
|
||||
}
|
||||
} elseif (!$result['status'] && $row['status'] == 0) {
|
||||
if ($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']) {
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 1, 'errcount' => 0, 'switchtime' => time()]);
|
||||
$action = 1;
|
||||
} else {
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
|
||||
}
|
||||
} elseif ($row['errcount'] > 0) {
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['errcount' => 0]);
|
||||
}
|
||||
}elseif($row['errcount'] > 0){
|
||||
$this->db()->name('dmtask')->where('id', $row['id'])->update(['errcount'=>0]);
|
||||
}
|
||||
|
||||
if($action > 0){
|
||||
$drow = $this->db()->name('domain')->alias('A')->join('account B','A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
|
||||
if(!$drow){
|
||||
if ($action > 0) {
|
||||
$drow = $this->db()->name('domain')->alias('A')->join('account B', 'A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
|
||||
if (!$drow) {
|
||||
echo '域名不存在(ID:'.$row['did'].')'."\n";
|
||||
$this->closeDb();
|
||||
return;
|
||||
}
|
||||
$row['domain'] = $row['rr'] . '.' . $drow['name'];
|
||||
}
|
||||
if($action == 1){
|
||||
if($row['type'] == 2){
|
||||
if ($action == 1) {
|
||||
if ($row['type'] == 2) {
|
||||
$dns = DnsHelper::getModel2($drow);
|
||||
$recordinfo = json_decode($row['recordinfo'], true);
|
||||
$res = $dns->updateDomainRecord($row['recordid'], $row['rr'], getDnsType($row['backup_value']), $row['backup_value'], $recordinfo['Line'], $recordinfo['TTL']);
|
||||
if(!$res){
|
||||
if (!$res) {
|
||||
$this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '修改解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
|
||||
}
|
||||
}elseif($row['type'] == 1){
|
||||
} elseif ($row['type'] == 1 || $row['type'] == 3) {
|
||||
$dns = DnsHelper::getModel2($drow);
|
||||
$res = $dns->setDomainRecordStatus($row['recordid'], '0');
|
||||
if(!$res){
|
||||
if (!$res) {
|
||||
$this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '暂停解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
|
||||
}
|
||||
}
|
||||
}elseif($action == 2){
|
||||
if($row['type'] == 2){
|
||||
} elseif ($action == 2) {
|
||||
if ($row['type'] == 2) {
|
||||
$dns = DnsHelper::getModel2($drow);
|
||||
$recordinfo = json_decode($row['recordinfo'], true);
|
||||
$res = $dns->updateDomainRecord($row['recordid'], $row['rr'], getDnsType($row['main_value']), $row['main_value'], $recordinfo['Line'], $recordinfo['TTL']);
|
||||
if(!$res){
|
||||
if (!$res) {
|
||||
$this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '修改解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
|
||||
}
|
||||
}elseif($row['type'] == 1){
|
||||
} elseif ($row['type'] == 1 || $row['type'] == 3) {
|
||||
$dns = DnsHelper::getModel2($drow);
|
||||
$res = $dns->setDomainRecordStatus($row['recordid'], '1');
|
||||
if(!$res){
|
||||
if (!$res) {
|
||||
$this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '启用解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
$this->closeDb();
|
||||
return;
|
||||
}
|
||||
@@ -101,11 +114,13 @@ class TaskRunner
|
||||
$this->db()->name('dmlog')->insert([
|
||||
'taskid' => $row['id'],
|
||||
'action' => $action,
|
||||
'errmsg' => $result['status'] ? null : $result['errmsg'],
|
||||
'errmsg' => isset($result) ? ($result['status'] ? null : $result['errmsg']) : null,
|
||||
'date' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
$this->closeDb();
|
||||
|
||||
MsgNotice::send($action, $row, $result);
|
||||
if ($row['type'] != 3) {
|
||||
MsgNotice::send($action, $row, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,314 +1,338 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class aliyun implements DnsInterface {
|
||||
private $AccessKeyId;
|
||||
private $AccessKeySecret;
|
||||
private $Endpoint = 'alidns.aliyuncs.com'; //API接入域名
|
||||
private $Version = '2015-01-09'; //API版本号
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
private $domainInfo;
|
||||
class aliyun implements DnsInterface
|
||||
{
|
||||
private $AccessKeyId;
|
||||
private $AccessKeySecret;
|
||||
private $Endpoint = 'alidns.aliyuncs.com'; //API接入域名
|
||||
private $Version = '2015-01-09'; //API版本号
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
private $domainInfo;
|
||||
|
||||
function __construct($config){
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->AccessKeySecret = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->AccessKeySecret = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getDomainList() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$param = ['Action' => 'DescribeDomains', 'KeyWord' => $KeyWord, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['Domains']['Domain'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['DomainId'],
|
||||
'Domain' => $row['DomainName'],
|
||||
'RecordCount' => $row['RecordCount'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$param = ['Action' => 'DescribeDomains', 'KeyWord' => $KeyWord, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['Domains']['Domain'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['DomainId'],
|
||||
'Domain' => $row['DomainName'],
|
||||
'RecordCount' => $row['RecordCount'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$param = ['Action' => 'DescribeDomainRecords', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
|
||||
if(!empty($SubDomain) || !empty($Type) || !empty($Line)){
|
||||
$param += ['SearchMode' => 'ADVANCED', 'RRKeyWord' => $SubDomain, 'ValueKeyWord' => $KeyWord, 'Type' => $Type, 'Line' => $Line, 'ValueKeyWord' => $KeyWord];
|
||||
}elseif(!empty($KeyWord)){
|
||||
$param += ['KeyWord' => $KeyWord];
|
||||
}
|
||||
if(!isNullOrEmpty($Status)){
|
||||
$Status = $Status == '1' ? 'Enable' : 'Disable';
|
||||
$param += ['Status' => $Status];
|
||||
}
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['DomainRecords']['Record'] as $row){
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordId'],
|
||||
'Domain' => $row['DomainName'],
|
||||
'Name' => $row['RR'],
|
||||
'Type' => $row['Type'],
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['Line'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => isset($row['Priority']) ? $row['Priority'] : null,
|
||||
'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
|
||||
'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
|
||||
'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $row['UpdateTimestamp']/1000) : null,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$param = ['Action' => 'DescribeDomainRecords', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
|
||||
if (!empty($SubDomain) || !empty($Type) || !empty($Line) || !empty($Value)) {
|
||||
$param += ['SearchMode' => 'ADVANCED', 'RRKeyWord' => $SubDomain, 'ValueKeyWord' => $Value, 'Type' => $Type, 'Line' => $Line];
|
||||
} elseif (!empty($KeyWord)) {
|
||||
$param += ['KeyWord' => $KeyWord];
|
||||
}
|
||||
if (!isNullOrEmpty($Status)) {
|
||||
$Status = $Status == '1' ? 'Enable' : 'Disable';
|
||||
$param += ['Status' => $Status];
|
||||
}
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['DomainRecords']['Record'] as $row) {
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordId'],
|
||||
'Domain' => $row['DomainName'],
|
||||
'Name' => $row['RR'],
|
||||
'Type' => $row['Type'],
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['Line'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => isset($row['Priority']) ? $row['Priority'] : null,
|
||||
'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
|
||||
'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
|
||||
'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', intval($row['UpdateTimestamp'] / 1000)) : null,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
$param = ['Action' => 'DescribeSubDomainRecords', 'SubDomain' => $SubDomain . '.' . $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Type' => $Type, 'Line' => $Line];
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['DomainRecords']['Record'] as $row){
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordId'],
|
||||
'Domain' => $row['DomainName'],
|
||||
'Name' => $row['RR'],
|
||||
'Type' => $row['Type'],
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['Line'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => isset($row['Priority']) ? $row['Priority'] : null,
|
||||
'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
|
||||
'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
|
||||
'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $row['UpdateTimestamp']/1000) : null,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
$param = ['Action' => 'DescribeSubDomainRecords', 'SubDomain' => $SubDomain . '.' . $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Type' => $Type, 'Line' => $Line];
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['DomainRecords']['Record'] as $row) {
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordId'],
|
||||
'Domain' => $row['DomainName'],
|
||||
'Name' => $row['RR'],
|
||||
'Type' => $row['Type'],
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['Line'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => isset($row['Priority']) ? $row['Priority'] : null,
|
||||
'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
|
||||
'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
|
||||
'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', intval($row['UpdateTimestamp'] / 1000)) : null,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
$param = ['Action' => 'DescribeDomainRecordInfo', 'RecordId' => $RecordId];
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
return [
|
||||
'RecordId' => $data['RecordId'],
|
||||
'Domain' => $data['DomainName'],
|
||||
'Name' => $data['RR'],
|
||||
'Type' => $data['Type'],
|
||||
'Value' => $data['Value'],
|
||||
'Line' => $data['Line'],
|
||||
'TTL' => $data['TTL'],
|
||||
'MX' => isset($data['Priority']) ? $data['Priority'] : null,
|
||||
'Status' => $data['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => isset($data['Weight']) ? $data['Weight'] : null,
|
||||
'Remark' => isset($data['Remark']) ? $data['Remark'] : null,
|
||||
'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $data['UpdateTimestamp']/1000) : null,
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
$param = ['Action' => 'DescribeDomainRecordInfo', 'RecordId' => $RecordId];
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
return [
|
||||
'RecordId' => $data['RecordId'],
|
||||
'Domain' => $data['DomainName'],
|
||||
'Name' => $data['RR'],
|
||||
'Type' => $data['Type'],
|
||||
'Value' => $data['Value'],
|
||||
'Line' => $data['Line'],
|
||||
'TTL' => $data['TTL'],
|
||||
'MX' => isset($data['Priority']) ? $data['Priority'] : null,
|
||||
'Status' => $data['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => isset($data['Weight']) ? $data['Weight'] : null,
|
||||
'Remark' => isset($data['Remark']) ? $data['Remark'] : null,
|
||||
'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', intval($data['UpdateTimestamp'] / 1000)) : null,
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Remark = null){
|
||||
$param = ['Action' => 'AddDomainRecord', 'DomainName' => $this->domain, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
|
||||
if($MX){
|
||||
$params['Priority'] = intval($MX);
|
||||
}
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
return $data['RecordId'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['Action' => 'AddDomainRecord', 'DomainName' => $this->domain, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
|
||||
if ($MX) {
|
||||
$param['Priority'] = intval($MX);
|
||||
}
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
return $data['RecordId'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Remark = null){
|
||||
$param = ['Action' => 'UpdateDomainRecord', 'RecordId' => $RecordId, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
|
||||
if($MX){
|
||||
$params['Priority'] = intval($MX);
|
||||
}
|
||||
return $this->request($param);
|
||||
}
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['Action' => 'UpdateDomainRecord', 'RecordId' => $RecordId, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
|
||||
if ($MX) {
|
||||
$param['Priority'] = intval($MX);
|
||||
}
|
||||
return $this->request($param);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
$param = ['Action' => 'UpdateDomainRecordRemark', 'RecordId' => $RecordId, 'Remark' => $Remark];
|
||||
return $this->request($param);
|
||||
}
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
$param = ['Action' => 'UpdateDomainRecordRemark', 'RecordId' => $RecordId, 'Remark' => $Remark];
|
||||
return $this->request($param);
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$param = ['Action' => 'DeleteDomainRecord', 'RecordId' => $RecordId];
|
||||
return $this->request($param);
|
||||
}
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$param = ['Action' => 'DeleteDomainRecord', 'RecordId' => $RecordId];
|
||||
return $this->request($param);
|
||||
}
|
||||
|
||||
//删除子域名的解析记录
|
||||
public function deleteSubDomainRecords($SubDomain){
|
||||
$param = ['Action' => 'DeleteSubDomainRecords', 'DomainName' => $this->domain, 'RR' => $SubDomain];
|
||||
return $this->request($param);
|
||||
}
|
||||
//删除子域名的解析记录
|
||||
public function deleteSubDomainRecords($SubDomain)
|
||||
{
|
||||
$param = ['Action' => 'DeleteSubDomainRecords', 'DomainName' => $this->domain, 'RR' => $SubDomain];
|
||||
return $this->request($param);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
$Status = $Status == '1' ? 'Enable' : 'Disable';
|
||||
$param = ['Action' => 'SetDomainRecordStatus', 'RecordId' => $RecordId, 'Status' => $Status];
|
||||
return $this->request($param);
|
||||
}
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$Status = $Status == '1' ? 'Enable' : 'Disable';
|
||||
$param = ['Action' => 'SetDomainRecordStatus', 'RecordId' => $RecordId, 'Status' => $Status];
|
||||
return $this->request($param);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
$param = ['Action' => 'DescribeRecordLogs', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'KeyWord' => $KeyWord, 'StartDate' => $StartDate, 'endDate' => $endDate, 'Lang' => 'zh'];
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['RecordLogs']['RecordLog'] as $row){
|
||||
$list[] = ['time'=>date('Y-m-d H:i:s', intval($row['ActionTimestamp']/1000)), 'data'=>$row['Message']];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
$param = ['Action' => 'DescribeRecordLogs', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'KeyWord' => $KeyWord, 'StartDate' => $StartDate, 'endDate' => $endDate, 'Lang' => 'zh'];
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['RecordLogs']['RecordLog'] as $row) {
|
||||
$list[] = ['time' => date('Y-m-d H:i:s', intval($row['ActionTimestamp'] / 1000)), 'data' => $row['Message']];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
$data = $this->getDomainInfo();
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['RecordLines']['RecordLine'] as $row){
|
||||
$list[$row['LineCode']] = ['name'=>$row['LineDisplayName'], 'parent'=>isset($row['FatherCode']) ? $row['FatherCode'] : null];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
$data = $this->getDomainInfo();
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['RecordLines']['RecordLine'] as $row) {
|
||||
$list[$row['LineCode']] = ['name' => $row['LineDisplayName'], 'parent' => isset($row['FatherCode']) ? $row['FatherCode'] : null];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名信息
|
||||
public function getDomainInfo(){
|
||||
if(!empty($this->domainInfo)) return $this->domainInfo;
|
||||
$param = ['Action' => 'DescribeDomainInfo', 'DomainName' => $this->domain, 'NeedDetailAttributes' => 'true'];
|
||||
$data = $this->request($param, true);
|
||||
if($data){
|
||||
$this->domainInfo = $data;
|
||||
return $data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
if (!empty($this->domainInfo)) return $this->domainInfo;
|
||||
$param = ['Action' => 'DescribeDomainInfo', 'DomainName' => $this->domain, 'NeedDetailAttributes' => 'true'];
|
||||
$data = $this->request($param, true);
|
||||
if ($data) {
|
||||
$this->domainInfo = $data;
|
||||
return $data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
$data = $this->getDomainInfo();
|
||||
if($data){
|
||||
return $data['MinTtl'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
$data = $this->getDomainInfo();
|
||||
if ($data) {
|
||||
return $data['MinTtl'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertLineCode($line){
|
||||
$convert_dict = ['0'=>'default', '10=1'=>'unicom', '10=0'=>'telecom', '10=3'=>'mobile', '10=2'=>'edu', '3=0'=>'oversea', '10=22'=>'btvn', '80=0'=>'search', '7=0'=>'internal'];
|
||||
if(array_key_exists($line, $convert_dict)){
|
||||
return $convert_dict[$line];
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
private function convertLineCode($line)
|
||||
{
|
||||
$convert_dict = ['0' => 'default', '10=1' => 'unicom', '10=0' => 'telecom', '10=3' => 'mobile', '10=2' => 'edu', '3=0' => 'oversea', '10=22' => 'btvn', '80=0' => 'search', '7=0' => 'internal'];
|
||||
if (array_key_exists($line, $convert_dict)) {
|
||||
return $convert_dict[$line];
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
|
||||
private function aliyunSignature($parameters, $accessKeySecret, $method)
|
||||
{
|
||||
ksort($parameters);
|
||||
$canonicalizedQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
if($value === null) continue;
|
||||
$canonicalizedQueryString .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value);
|
||||
}
|
||||
$stringToSign = $method . '&%2F&' . $this->percentEncode(substr($canonicalizedQueryString, 1));
|
||||
$signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret."&", true));
|
||||
private function aliyunSignature($parameters, $accessKeySecret, $method)
|
||||
{
|
||||
ksort($parameters);
|
||||
$canonicalizedQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
if ($value === null) continue;
|
||||
$canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
|
||||
}
|
||||
$stringToSign = $method . '&%2F&' . $this->percentEncode(substr($canonicalizedQueryString, 1));
|
||||
$signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&", true));
|
||||
|
||||
return $signature;
|
||||
}
|
||||
private function percentEncode($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
private function request($param, $returnData=false){
|
||||
if(empty($this->AccessKeyId)||empty($this->AccessKeySecret))return false;
|
||||
$result = $this->request_do($param, $returnData);
|
||||
if(!$returnData && $result!==true){
|
||||
usleep(50000);
|
||||
$result = $this->request_do($param, $returnData);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
private function request_do($param, $returnData=false){
|
||||
if(empty($this->AccessKeyId)||empty($this->AccessKeySecret))return false;
|
||||
$url='https://'.$this->Endpoint.'/';
|
||||
$data=array(
|
||||
'Format' => 'JSON',
|
||||
'Version' => $this->Version,
|
||||
'AccessKeyId' => $this->AccessKeyId,
|
||||
'SignatureMethod' => 'HMAC-SHA1',
|
||||
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
|
||||
'SignatureVersion' => '1.0',
|
||||
'SignatureNonce' => random(8));
|
||||
$data=array_merge($data, $param);
|
||||
$data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
return $signature;
|
||||
}
|
||||
private function percentEncode($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
private function request($param, $returnData = false)
|
||||
{
|
||||
if (empty($this->AccessKeyId) || empty($this->AccessKeySecret)) return false;
|
||||
$result = $this->request_do($param, $returnData);
|
||||
if (!$returnData && $result !== true) {
|
||||
usleep(50000);
|
||||
$result = $this->request_do($param, $returnData);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
private function request_do($param, $returnData = false)
|
||||
{
|
||||
if (empty($this->AccessKeyId) || empty($this->AccessKeySecret)) return false;
|
||||
$url = 'https://' . $this->Endpoint . '/';
|
||||
$data = array(
|
||||
'Format' => 'JSON',
|
||||
'Version' => $this->Version,
|
||||
'AccessKeyId' => $this->AccessKeyId,
|
||||
'SignatureMethod' => 'HMAC-SHA1',
|
||||
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
|
||||
'SignatureVersion' => '1.0',
|
||||
'SignatureNonce' => random(8)
|
||||
);
|
||||
$data = array_merge($data, $param);
|
||||
$data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
|
||||
$arr = json_decode($response,true);
|
||||
if($httpCode==200){
|
||||
return $returnData ? $arr : true;
|
||||
}elseif($arr){
|
||||
$this->setError($arr['Message']);
|
||||
return false;
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$arr = json_decode($response, true);
|
||||
if ($httpCode == 200) {
|
||||
return $returnData ? $arr : true;
|
||||
} elseif ($arr) {
|
||||
$this->setError($arr['Message']);
|
||||
return false;
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,325 +1,350 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class baidu implements DnsInterface {
|
||||
private $AccessKeyId;
|
||||
private $SecretAccessKey;
|
||||
private $endpoint = "dns.baidubce.com";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
class baidu implements DnsInterface
|
||||
{
|
||||
private $AccessKeyId;
|
||||
private $SecretAccessKey;
|
||||
private $endpoint = "dns.baidubce.com";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
|
||||
function __construct($config){
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->SecretAccessKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getDomainList() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$query = ['name' => $KeyWord];
|
||||
$data = $this->send_reuqest('GET', '/v1/dns/zone', $query);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['zones'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => rtrim($row['name'], '.'),
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => count($list), 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$marker = cookie('baidu_record_marker');
|
||||
$query = ['rr' => $KeyWord];
|
||||
if(!isNullOrEmpty(($SubDomain))){
|
||||
$param['rr'] = $SubDomain;
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['records'] as $row){
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['rr'],
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['value'],
|
||||
'Line' => $row['line'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => $row['priority'],
|
||||
'Status' => $row['status'] == 'running' ? '1' : '0',
|
||||
'Weight' => null,
|
||||
'Remark' => $row['description'],
|
||||
'UpdateTime' => null,
|
||||
];
|
||||
}
|
||||
return ['total' => count($list), 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
if($SubDomain == '')$SubDomain='@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
$data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
|
||||
if($data){
|
||||
return [
|
||||
'RecordId' => $data['id'],
|
||||
'Domain' => rtrim($data['zone_name'], '.'),
|
||||
'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
|
||||
'Type' => $data['type'],
|
||||
'Value' => $data['records'],
|
||||
'Line' => $data['line'],
|
||||
'TTL' => $data['ttl'],
|
||||
'MX' => $data['weight'],
|
||||
'Status' => $data['status'] == 'ACTIVE' ? '1' : '0',
|
||||
'Weight' => $data['weight'],
|
||||
'Remark' => $data['description'],
|
||||
'UpdateTime' => $data['updated_at'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if($Type == 'MX')$param['priority'] = intval($MX);
|
||||
$query = ['clientToken' => getSid()];
|
||||
return $this->send_reuqest('POST', '/v1/dns/zone/'.$this->domain.'/record', $query, $params);
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if($Type == 'MX')$param['priority'] = intval($MX);
|
||||
$query = ['clientToken' => getSid()];
|
||||
return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query, $params);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$query = ['clientToken' => getSid()];
|
||||
return $this->send_reuqest('DELETE', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
$Status = $Status == '1' ? 'enable' : 'disable';
|
||||
$query = [$Status => '', 'clientToken' => getSid()];
|
||||
return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
return [
|
||||
'default'=>['name'=>'默认', 'parent'=>null],
|
||||
'ct'=>['name'=>'电信', 'parent'=>null],
|
||||
'cnc'=>['name'=>'联通', 'parent'=>null],
|
||||
'cmnet'=>['name'=>'移动', 'parent'=>null],
|
||||
'edu'=>['name'=>'教育网', 'parent'=>null],
|
||||
'search'=>['name'=>'搜索引擎(百度)', 'parent'=>null],
|
||||
];
|
||||
}
|
||||
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo(){
|
||||
$res = $this->getDomainList($this->domain);
|
||||
if($res && !empty($res['list'])){
|
||||
return $res['list'][0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type){
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function send_reuqest($method, $path, $query = null, $params = null){
|
||||
if(!empty($query)){
|
||||
$query = array_filter($query, function($a){ return $a!==null;});
|
||||
}
|
||||
if(!empty($params)){
|
||||
$params = array_filter($params, function($a){ return $a!==null;});
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$date = gmdate("Y-m-d\TH:i:s\Z", $time);
|
||||
$body = !empty($params) ? json_encode($params) : '';
|
||||
$headers = [
|
||||
'Host' => $this->endpoint,
|
||||
'x-bce-date' => $date,
|
||||
];
|
||||
if($body){
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
$authorization = $this->generateSign($method, $path, $query, $headers, $time);
|
||||
$headers['Authorization'] = $authorization;
|
||||
|
||||
$url = 'https://'.$this->endpoint.$path;
|
||||
if(!empty($query)){
|
||||
$url .= '?'.http_build_query($query);
|
||||
}
|
||||
$header = [];
|
||||
foreach($headers as $key => $value){
|
||||
$header[] = $key.': '.$value;
|
||||
}
|
||||
return $this->curl($method, $url, $body, $header);
|
||||
}
|
||||
|
||||
private function generateSign($method, $path, $query, $headers, $time){
|
||||
$algorithm = "bce-auth-v1";
|
||||
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = $method;
|
||||
$canonicalUri = $this->getCanonicalUri($path);
|
||||
$canonicalQueryString = $this->getCanonicalQueryString($query);
|
||||
[$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders;
|
||||
|
||||
// step 2: calculate signing key
|
||||
$date = gmdate("Y-m-d\TH:i:s\Z", $time);
|
||||
$expirationInSeconds = 1800;
|
||||
$authString = $algorithm . '/' . $this->AccessKeyId . '/' . $date . '/' . $expirationInSeconds;
|
||||
$signingKey = hash_hmac('sha256', $authString, $this->SecretAccessKey);
|
||||
|
||||
// step 3: sign string
|
||||
$signature = hash_hmac("sha256", $canonicalRequest, $signingKey);
|
||||
|
||||
// step 4: build authorization
|
||||
$authorization = $authString . '/' . $signedHeaders . "/" . $signature;
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
private function escape($str)
|
||||
public function __construct($config)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->SecretAccessKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
private function getCanonicalUri($path)
|
||||
{
|
||||
if(empty($path)) return '/';
|
||||
$uri = str_replace('%2F', '/', $this->escape($path));
|
||||
if(substr($uri, 0, 1) !== '/') $uri = '/'.$uri;
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function getCanonicalQueryString($parameters)
|
||||
public function getError()
|
||||
{
|
||||
if(empty($parameters)) return '';
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$query = ['name' => $KeyWord];
|
||||
$data = $this->send_reuqest('GET', '/v1/dns/zone', $query);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['zones'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => rtrim($row['name'], '.'),
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => count($list), 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$query = ['rr' => $KeyWord];
|
||||
if (!isNullOrEmpty($SubDomain)) {
|
||||
$query['rr'] = $SubDomain;
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['records'] as $row) {
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['rr'],
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['value'],
|
||||
'Line' => $row['line'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => $row['priority'],
|
||||
'Status' => $row['status'] == 'running' ? '1' : '0',
|
||||
'Weight' => null,
|
||||
'Remark' => $row['description'],
|
||||
'UpdateTime' => null,
|
||||
];
|
||||
}
|
||||
return ['total' => count($list), 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
if ($SubDomain == '') $SubDomain = '@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
$query = ['id' => $RecordId];
|
||||
$data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
|
||||
if ($data && !empty($data['records'])) {
|
||||
$data = $data['records'][0];
|
||||
return [
|
||||
'RecordId' => $data['id'],
|
||||
'Domain' => rtrim($data['zone_name'], '.'),
|
||||
'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
|
||||
'Type' => $data['type'],
|
||||
'Value' => $data['value'],
|
||||
'Line' => $data['line'],
|
||||
'TTL' => $data['ttl'],
|
||||
'MX' => $data['priority'],
|
||||
'Status' => $data['status'] == 'running' ? '1' : '0',
|
||||
'Weight' => null,
|
||||
'Remark' => $data['description'],
|
||||
'UpdateTime' => null,
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if ($Type == 'MX') $params['priority'] = intval($MX);
|
||||
$query = ['clientToken' => getSid()];
|
||||
return $this->send_reuqest('POST', '/v1/dns/zone/'.$this->domain.'/record', $query, $params);
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if ($Type == 'MX') $params['priority'] = intval($MX);
|
||||
$query = ['clientToken' => getSid()];
|
||||
return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query, $params);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$query = ['clientToken' => getSid()];
|
||||
return $this->send_reuqest('DELETE', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$Status = $Status == '1' ? 'enable' : 'disable';
|
||||
$query = [$Status => '', 'clientToken' => getSid()];
|
||||
return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
return [
|
||||
'default' => ['name' => '默认', 'parent' => null],
|
||||
'ct' => ['name' => '电信', 'parent' => null],
|
||||
'cnc' => ['name' => '联通', 'parent' => null],
|
||||
'cmnet' => ['name' => '移动', 'parent' => null],
|
||||
'edu' => ['name' => '教育网', 'parent' => null],
|
||||
'search' => ['name' => '搜索引擎(百度)', 'parent' => null],
|
||||
];
|
||||
}
|
||||
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
$res = $this->getDomainList($this->domain);
|
||||
if ($res && !empty($res['list'])) {
|
||||
return $res['list'][0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type)
|
||||
{
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function send_reuqest($method, $path, $query = null, $params = null)
|
||||
{
|
||||
if (!empty($query)) {
|
||||
$query = array_filter($query, function ($a) { return $a !== null;});
|
||||
}
|
||||
if (!empty($params)) {
|
||||
$params = array_filter($params, function ($a) { return $a !== null;});
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$date = gmdate("Y-m-d\TH:i:s\Z", $time);
|
||||
$body = !empty($params) ? json_encode($params) : '';
|
||||
$headers = [
|
||||
'Host' => $this->endpoint,
|
||||
'x-bce-date' => $date,
|
||||
];
|
||||
if ($body) {
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
$authorization = $this->generateSign($method, $path, $query, $headers, $time);
|
||||
$headers['Authorization'] = $authorization;
|
||||
|
||||
$url = 'https://'.$this->endpoint.$path;
|
||||
if (!empty($query)) {
|
||||
$url .= '?'.http_build_query($query);
|
||||
}
|
||||
$header = [];
|
||||
foreach ($headers as $key => $value) {
|
||||
$header[] = $key.': '.$value;
|
||||
}
|
||||
return $this->curl($method, $url, $body, $header);
|
||||
}
|
||||
|
||||
private function generateSign($method, $path, $query, $headers, $time)
|
||||
{
|
||||
$algorithm = "bce-auth-v1";
|
||||
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = $method;
|
||||
$canonicalUri = $this->getCanonicalUri($path);
|
||||
$canonicalQueryString = $this->getCanonicalQueryString($query);
|
||||
[$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders;
|
||||
|
||||
// step 2: calculate signing key
|
||||
$date = gmdate("Y-m-d\TH:i:s\Z", $time);
|
||||
$expirationInSeconds = 1800;
|
||||
$authString = $algorithm . '/' . $this->AccessKeyId . '/' . $date . '/' . $expirationInSeconds;
|
||||
$signingKey = hash_hmac('sha256', $authString, $this->SecretAccessKey);
|
||||
|
||||
// step 3: sign string
|
||||
$signature = hash_hmac("sha256", $canonicalRequest, $signingKey);
|
||||
|
||||
// step 4: build authorization
|
||||
$authorization = $authString . '/' . $signedHeaders . "/" . $signature;
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
private function escape($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
|
||||
private function getCanonicalUri($path)
|
||||
{
|
||||
if (empty($path)) return '/';
|
||||
$uri = str_replace('%2F', '/', $this->escape($path));
|
||||
if (substr($uri, 0, 1) !== '/') $uri = '/' . $uri;
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function getCanonicalQueryString($parameters)
|
||||
{
|
||||
if (empty($parameters)) return '';
|
||||
ksort($parameters);
|
||||
$canonicalQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
if($key == 'authorization') continue;
|
||||
$canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
|
||||
}
|
||||
$canonicalQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
if ($key == 'authorization') continue;
|
||||
$canonicalQueryString .= '&' . $this->escape($key) . '=' . $this->escape($value);
|
||||
}
|
||||
return substr($canonicalQueryString, 1);
|
||||
}
|
||||
|
||||
private function getCanonicalHeaders($oldheaders){
|
||||
$headers = array();
|
||||
private function getCanonicalHeaders($oldheaders)
|
||||
{
|
||||
$headers = array();
|
||||
foreach ($oldheaders as $key => $value) {
|
||||
$headers[strtolower($key)] = trim($value);
|
||||
}
|
||||
ksort($headers);
|
||||
ksort($headers);
|
||||
|
||||
$canonicalHeaders = '';
|
||||
$signedHeaders = '';
|
||||
foreach ($headers as $key => $value) {
|
||||
$canonicalHeaders .= $this->escape($key) . ':' . $this->escape($value) . "\n";
|
||||
$signedHeaders .= $key . ';';
|
||||
}
|
||||
$canonicalHeaders = substr($canonicalHeaders, 0, -1);
|
||||
$signedHeaders = substr($signedHeaders, 0, -1);
|
||||
return [$canonicalHeaders, $signedHeaders];
|
||||
}
|
||||
$canonicalHeaders = '';
|
||||
$signedHeaders = '';
|
||||
foreach ($headers as $key => $value) {
|
||||
$canonicalHeaders .= $this->escape($key) . ':' . $this->escape($value) . "\n";
|
||||
$signedHeaders .= $key . ';';
|
||||
}
|
||||
$canonicalHeaders = substr($canonicalHeaders, 0, -1);
|
||||
$signedHeaders = substr($signedHeaders, 0, -1);
|
||||
return [$canonicalHeaders, $signedHeaders];
|
||||
}
|
||||
|
||||
private function curl($method, $url, $body, $header){
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if(!empty($body)){
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
private function curl($method, $url, $body, $header)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if (!empty($body)) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
|
||||
if(empty($response) && $httpCode == 200){
|
||||
return true;
|
||||
}
|
||||
$arr=json_decode($response,true);
|
||||
if($arr){
|
||||
if(isset($arr['code']) && isset($arr['message'])){
|
||||
$this->setError($arr['message']);
|
||||
return false;
|
||||
}else{
|
||||
return $arr;
|
||||
}
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (empty($response) && $httpCode == 200) {
|
||||
return true;
|
||||
}
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if (isset($arr['code']) && isset($arr['message'])) {
|
||||
$this->setError($arr['message']);
|
||||
return false;
|
||||
} else {
|
||||
return $arr;
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,202 +1,271 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class cloudflare implements DnsInterface {
|
||||
private $Email;
|
||||
private $ApiKey;
|
||||
private $baseUrl = 'https://api.cloudflare.com/client/v4';
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
class cloudflare implements DnsInterface
|
||||
{
|
||||
private $Email;
|
||||
private $ApiKey;
|
||||
private $baseUrl = 'https://api.cloudflare.com/client/v4';
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
|
||||
function __construct($config){
|
||||
$this->Email = $config['ak'];
|
||||
$this->ApiKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
function __construct($config)
|
||||
{
|
||||
$this->Email = $config['ak'];
|
||||
$this->ApiKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getDomainList() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$param = ['page' => $PageNumber, 'per_page' => $PageSize, 'name' => $KeyWord];
|
||||
$data = $this->send_reuqest('GET', '/zones', $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['result'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => $row['name'],
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['result_info']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$param = ['page' => $PageNumber, 'per_page' => $PageSize];
|
||||
if (!empty($KeyWord)) {
|
||||
$param['name'] = $KeyWord;
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/zones', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['result'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => $row['name'],
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['result_info']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$param = ['name' => $SubDomain, 'type' => $Type, 'search' => $KeyWord, 'page' => $PageNumber, 'per_page' => $PageSize];
|
||||
if(!isNullOrEmpty($Line)){
|
||||
$param['proxied'] = $Line == '1' ? 'true' : 'false';
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/zones/'.$this->domainid.'/dns_records', $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['result'] as $row){
|
||||
$name = $row['zone_name'] == $row['name'] ? '@' : str_replace('.'.$row['zone_name'], '', $row['name']);
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $row['zone_name'],
|
||||
'Name' => $name,
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['content'],
|
||||
'Line' => $row['proxied'] ? '1' : '0',
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => isset($row['priority']) ? $row['priority'] : null,
|
||||
'Status' => $row['locked'] ? '0' : '1',
|
||||
'Weight' => null,
|
||||
'Remark' => $row['comment'],
|
||||
'UpdateTime' => $row['modified_on'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['result_info']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
if (!isNullOrEmpty($SubDomain)) {
|
||||
if ($SubDomain == '@') $SubDomain = $this->domain;
|
||||
else $SubDomain .= '.' . $this->domain;
|
||||
}
|
||||
if (!isNullOrEmpty($Value)) $KeyWord = $Value;
|
||||
$param = ['name' => $SubDomain, 'type' => $Type, 'search' => $KeyWord, 'page' => $PageNumber, 'per_page' => $PageSize];
|
||||
if (!isNullOrEmpty($Line)) {
|
||||
$param['proxied'] = $Line == '1' ? 'true' : 'false';
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/zones/'.$this->domainid.'/dns_records', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['result'] as $row) {
|
||||
$name = $row['zone_name'] == $row['name'] ? '@' : str_replace('.'.$row['zone_name'], '', $row['name']);
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $row['zone_name'],
|
||||
'Name' => $name,
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['content'],
|
||||
'Line' => $row['proxied'] ? '1' : '0',
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => isset($row['priority']) ? $row['priority'] : null,
|
||||
'Status' => '1',
|
||||
'Weight' => null,
|
||||
'Remark' => $row['comment'],
|
||||
'UpdateTime' => $row['modified_on'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['result_info']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
if($SubDomain == '@')$SubDomain=$this->domain;
|
||||
else $SubDomain .= '.'.$this->domain;
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, $Type, $Line);
|
||||
}
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
$data = $this->send_reuqest('GET', '/zones/'.$this->domainid.'/dns_records/'.$RecordId);
|
||||
if($data){
|
||||
$name = $data['result']['zone_name'] == $data['result']['name'] ? '@' : str_replace('.'.$data['result']['zone_name'], '', $data['result']['name']);
|
||||
return [
|
||||
'RecordId' => $data['result']['id'],
|
||||
'Domain' => $data['result']['zone_name'],
|
||||
'Name' => str_replace('.'.$data['result']['zone_name'], '', $data['result']['name']),
|
||||
'Type' => $data['result']['type'],
|
||||
'Value' => $data['result']['content'],
|
||||
'Line' => $data['result']['proxied'] ? '1' : '0',
|
||||
'TTL' => $data['result']['ttl'],
|
||||
'MX' => isset($data['result']['priority']) ? $data['result']['priority'] : null,
|
||||
'Status' => $data['result']['locked'] ? '0' : '1',
|
||||
'Weight' => null,
|
||||
'Remark' => $data['result']['comment'],
|
||||
'UpdateTime' => $data['result']['modified_on'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
$data = $this->send_reuqest('GET', '/zones/'.$this->domainid.'/dns_records/'.$RecordId);
|
||||
if ($data) {
|
||||
$name = $data['result']['zone_name'] == $data['result']['name'] ? '@' : str_replace('.' . $data['result']['zone_name'], '', $data['result']['name']);
|
||||
return [
|
||||
'RecordId' => $data['result']['id'],
|
||||
'Domain' => $data['result']['zone_name'],
|
||||
'Name' => str_replace('.'.$data['result']['zone_name'], '', $data['result']['name']),
|
||||
'Type' => $data['result']['type'],
|
||||
'Value' => $data['result']['content'],
|
||||
'Line' => $data['result']['proxied'] ? '1' : '0',
|
||||
'TTL' => $data['result']['ttl'],
|
||||
'MX' => isset($data['result']['priority']) ? $data['result']['priority'] : null,
|
||||
'Status' => '1',
|
||||
'Weight' => null,
|
||||
'Remark' => $data['result']['comment'],
|
||||
'UpdateTime' => $data['result']['modified_on'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$param = ['name' => $Name, 'type' => $this->convertType($Type), 'content' => $Value, 'proxied' => $Line=='1', 'ttl' => intval($TTL), 'comment' => $Remark];
|
||||
if($Type == 'MX')$param['priority'] = intval($MX);
|
||||
$data = $this->send_reuqest('POST', '/zones/'.$this->domainid.'/dns_records', $param);
|
||||
return is_array($data) ? $data['result']['id'] : false;
|
||||
}
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['name' => $Name, 'type' => $this->convertType($Type), 'content' => $Value, 'proxied' => $Line == '1', 'ttl' => intval($TTL), 'comment' => $Remark];
|
||||
if ($Type == 'MX') $param['priority'] = intval($MX);
|
||||
if ($Type == 'CAA' || $Type == 'SRV') {
|
||||
unset($param['content']);
|
||||
$param['data'] = $this->convertValue($Value, $Type);
|
||||
}
|
||||
$data = $this->send_reuqest('POST', '/zones/'.$this->domainid.'/dns_records', $param);
|
||||
return is_array($data) ? $data['result']['id'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$param = ['name' => $Name, 'type' => $this->convertType($Type), 'content' => $Value, 'proxied' => $Line=='1', 'ttl' => intval($TTL), 'comment' => $Remark];
|
||||
if($Type == 'MX')$param['priority'] = intval($MX);
|
||||
$data = $this->send_reuqest('PATCH', '/zones/'.$this->domainid.'/dns_records/'.$RecordId, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['name' => $Name, 'type' => $this->convertType($Type), 'content' => $Value, 'proxied' => $Line == '1', 'ttl' => intval($TTL), 'comment' => $Remark];
|
||||
if ($Type == 'MX') $param['priority'] = intval($MX);
|
||||
if ($Type == 'CAA' || $Type == 'SRV') {
|
||||
unset($param['content']);
|
||||
$param['data'] = $this->convertValue($Value, $Type);
|
||||
}
|
||||
$data = $this->send_reuqest('PATCH', '/zones/'.$this->domainid.'/dns_records/'.$RecordId, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
return false;
|
||||
}
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$data = $this->send_reuqest('DELETE', '/zones/'.$this->domainid.'/dns_records/'.$RecordId);
|
||||
return is_array($data);
|
||||
}
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$data = $this->send_reuqest('DELETE', '/zones/'.$this->domainid.'/dns_records/'.$RecordId);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
return false;
|
||||
}
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
return false;
|
||||
}
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
return ['0'=>['name'=>'仅DNS', 'parent'=>null], '1'=>['name'=>'已代理', 'parent'=>null]];
|
||||
}
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
return ['0' => ['name' => '仅DNS', 'parent' => null], '1' => ['name' => '已代理', 'parent' => null]];
|
||||
}
|
||||
|
||||
//获取域名信息
|
||||
public function getDomainInfo(){
|
||||
$data = $this->send_reuqest('GET', '/zones/'.$this->domainid);
|
||||
if($data){
|
||||
return $data['result'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
$data = $this->send_reuqest('GET', '/zones/'.$this->domainid);
|
||||
if ($data) {
|
||||
return $data['result'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
return false;
|
||||
}
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type){
|
||||
$convert_dict = ['REDIRECT_URL'=>'URI', 'FORWARD_URL'=>'URI'];
|
||||
if(array_key_exists($type, $convert_dict)){
|
||||
return $convert_dict[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
private function convertType($type)
|
||||
{
|
||||
$convert_dict = ['REDIRECT_URL' => 'URI', 'FORWARD_URL' => 'URI'];
|
||||
if (array_key_exists($type, $convert_dict)) {
|
||||
return $convert_dict[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function send_reuqest($method, $path, $params = null){
|
||||
$url = $this->baseUrl . $path;
|
||||
|
||||
$headers = [
|
||||
'X-Auth-Email: '.$this->Email,
|
||||
'X-Auth-Key: '.$this->ApiKey,
|
||||
];
|
||||
private function convertValue($value, $type)
|
||||
{
|
||||
if ($type == 'SRV') {
|
||||
$arr = explode(' ', $value);
|
||||
if (count($arr) > 3) {
|
||||
$data = [
|
||||
'priority' => intval($arr[0]),
|
||||
'weight' => intval($arr[1]),
|
||||
'port' => intval($arr[2]),
|
||||
'target' => $arr[3],
|
||||
];
|
||||
} else {
|
||||
$data = [
|
||||
'weight' => intval($arr[0]),
|
||||
'port' => intval($arr[1]),
|
||||
'target' => $arr[2],
|
||||
];
|
||||
}
|
||||
} elseif ($type == 'CAA') {
|
||||
$arr = explode(' ', $value);
|
||||
$data = [
|
||||
'flags' => intval($arr[0]),
|
||||
'tag' => $arr[1],
|
||||
'value' => trim($arr[2], '"'),
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
$body = '';
|
||||
private function send_reuqest($method, $path, $params = null)
|
||||
{
|
||||
$url = $this->baseUrl . $path;
|
||||
|
||||
if (preg_match('/^[0-9a-z]+$/i', $this->ApiKey)) {
|
||||
$headers = [
|
||||
'X-Auth-Email: ' . $this->Email,
|
||||
'X-Auth-Key: ' . $this->ApiKey,
|
||||
];
|
||||
} else {
|
||||
$headers = [
|
||||
'Authorization: Bearer ' . $this->ApiKey,
|
||||
];
|
||||
}
|
||||
|
||||
$body = '';
|
||||
if ($method == 'GET' || $method == 'DELETE') {
|
||||
if ($params) {
|
||||
$url .= '?' . http_build_query($params);
|
||||
}
|
||||
} else {
|
||||
$body = json_encode($params);
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
}
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
if ($method == 'POST') {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
if ($method == 'POST') {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
} elseif ($method == 'PUT') {
|
||||
@@ -208,30 +277,31 @@ class cloudflare implements DnsInterface {
|
||||
} elseif ($method == 'DELETE') {
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
|
||||
$arr=json_decode($response,true);
|
||||
if($arr){
|
||||
if($arr['success']){
|
||||
return $arr;
|
||||
}else{
|
||||
$this->setError(isset($arr['errors'][0])?$arr['errors'][0]['message']:'未知错误');
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if ($arr['success']) {
|
||||
return $arr;
|
||||
} else {
|
||||
$this->setError(isset($arr['errors'][0]) ? $arr['errors'][0]['message'] : '未知错误');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,248 +1,289 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class dnsla implements DnsInterface {
|
||||
private $apiid;
|
||||
private $apisecret;
|
||||
private $baseUrl = 'https://api.dns.la';
|
||||
private $typeList = [1 => 'A', 2 => 'NS', 5 => 'CNAME', 15 => 'MX', 16 => 'TXT', 28 => 'AAAA', 33 => 'SRV', 257 => 'CAA', 256 => 'URL转发'];
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
class dnsla implements DnsInterface
|
||||
{
|
||||
private $apiid;
|
||||
private $apisecret;
|
||||
private $baseUrl = 'https://api.dns.la';
|
||||
private $typeList = [1 => 'A', 2 => 'NS', 5 => 'CNAME', 15 => 'MX', 16 => 'TXT', 28 => 'AAAA', 33 => 'SRV', 257 => 'CAA', 256 => 'URL转发'];
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
|
||||
function __construct($config){
|
||||
$this->apiid = $config['ak'];
|
||||
$this->apisecret = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->apiid = $config['ak'];
|
||||
$this->apisecret = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getDomainList() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$param = ['pageIndex' => $PageNumber, 'pageSize' => $PageSize];
|
||||
$data = $this->execute('GET', '/api/domainList', $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['results'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => rtrim($row['displayDomain'], '.'),
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$param = ['pageIndex' => $PageNumber, 'pageSize' => $PageSize];
|
||||
$data = $this->execute('GET', '/api/domainList', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['results'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => rtrim($row['displayDomain'], '.'),
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$param = ['domainId' => $this->domainid, 'pageIndex' => $PageNumber, 'pageSize' => $PageSize];
|
||||
if(!isNullOrEmpty(($KeyWord))){
|
||||
$param['host'] = $KeyWord;
|
||||
}
|
||||
if(!isNullOrEmpty(($Type))){
|
||||
$param['type'] = $this->convertType($Type);
|
||||
}
|
||||
if(!isNullOrEmpty(($Line))){
|
||||
$param['lineId'] = $Line;
|
||||
}
|
||||
if(!isNullOrEmpty(($SubDomain))){
|
||||
$param['host'] = $SubDomain;
|
||||
}
|
||||
$data = $this->execute('GET', '/api/recordList', $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['results'] as $row){
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['host'],
|
||||
'Type' => $this->convertTypeId($row['type'], isset($row['domaint']) ? $row['domaint'] : false),
|
||||
'Value' => $row['data'],
|
||||
'Line' => $row['lineId'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => isset($row['preference']) ? $row['preference'] : null,
|
||||
'Status' => $row['disable'] ? '0' : '1',
|
||||
'Weight' => isset($row['weight']) ? $row['weight'] : null,
|
||||
'Remark' => null,
|
||||
'UpdateTime' => date('Y-m-d H:i:s', $row['updatedAt']),
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$param = ['domainId' => $this->domainid, 'pageIndex' => $PageNumber, 'pageSize' => $PageSize];
|
||||
if (!isNullOrEmpty(($KeyWord))) {
|
||||
$param['host'] = $KeyWord;
|
||||
}
|
||||
if (!isNullOrEmpty(($Type))) {
|
||||
$param['type'] = $this->convertType($Type);
|
||||
}
|
||||
if (!isNullOrEmpty(($Line))) {
|
||||
$param['lineId'] = $Line;
|
||||
}
|
||||
if (!isNullOrEmpty(($SubDomain))) {
|
||||
$param['host'] = $SubDomain;
|
||||
}
|
||||
if (!isNullOrEmpty(($Value))) {
|
||||
$param['data'] = $Value;
|
||||
}
|
||||
$data = $this->execute('GET', '/api/recordList', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['results'] as $row) {
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['host'],
|
||||
'Type' => $this->convertTypeId($row['type'], isset($row['domaint']) ? $row['domaint'] : false),
|
||||
'Value' => $row['data'],
|
||||
'Line' => $row['lineId'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => isset($row['preference']) ? $row['preference'] : null,
|
||||
'Status' => $row['disable'] ? '0' : '1',
|
||||
'Weight' => isset($row['weight']) ? $row['weight'] : null,
|
||||
'Remark' => null,
|
||||
'UpdateTime' => date('Y-m-d H:i:s', $row['updatedAt']),
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
if($SubDomain == '')$SubDomain='@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, $Type, $Line);
|
||||
}
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
if ($SubDomain == '') $SubDomain = '@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
return false;
|
||||
}
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$param = ['domainId' => $this->domainid, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
|
||||
if($Type == 'MX')$param['preference'] = intval($MX);
|
||||
if($Type == 'REDIRECT_URL'){$param['type'] = 256;$param['dominant'] = true;}
|
||||
elseif($Type == 'FORWARD_URL'){$param['type'] = 256;$param['dominant'] = false;}
|
||||
$data = $this->execute('POST', '/api/record', $param);
|
||||
return is_array($data) ? $data['id'] : false;
|
||||
}
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['domainId' => $this->domainid, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
|
||||
if ($Type == 'MX') $param['preference'] = intval($MX);
|
||||
if ($Type == 'REDIRECT_URL') {
|
||||
$param['type'] = 256;
|
||||
$param['dominant'] = true;
|
||||
} elseif ($Type == 'FORWARD_URL') {
|
||||
$param['type'] = 256;
|
||||
$param['dominant'] = false;
|
||||
}
|
||||
if ($Weight > 0) $param['weight'] = $Weight;
|
||||
$data = $this->execute('POST', '/api/record', $param);
|
||||
return is_array($data) ? $data['id'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$param = ['id' => $RecordId, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
|
||||
if($Type == 'MX')$param['preference'] = intval($MX);
|
||||
if($Type == 'REDIRECT_URL'){$param['type'] = 256;$param['dominant'] = true;}
|
||||
elseif($Type == 'FORWARD_URL'){$param['type'] = 256;$param['dominant'] = false;}
|
||||
$data = $this->execute('PUT', '/api/record', $param);
|
||||
return $data!==false;
|
||||
}
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['id' => $RecordId, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
|
||||
if ($Type == 'MX') $param['preference'] = intval($MX);
|
||||
if ($Type == 'REDIRECT_URL') {
|
||||
$param['type'] = 256;
|
||||
$param['dominant'] = true;
|
||||
} elseif ($Type == 'FORWARD_URL') {
|
||||
$param['type'] = 256;
|
||||
$param['dominant'] = false;
|
||||
}
|
||||
if ($Weight > 0) $param['weight'] = $Weight;
|
||||
$data = $this->execute('PUT', '/api/record', $param);
|
||||
return $data !== false;
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
return false;
|
||||
}
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$param = ['id' => $RecordId];
|
||||
$data = $this->execute('DELETE', '/api/record', $param);
|
||||
return $data!==false;
|
||||
}
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$param = ['id' => $RecordId];
|
||||
$data = $this->execute('DELETE', '/api/record', $param);
|
||||
return $data !== false;
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
$param = ['id' => $RecordId, 'disable' => $Status == '0' ? true : false];
|
||||
$data = $this->execute('PUT', '/api/recordDisable', $param);
|
||||
return $data!==false;
|
||||
}
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$param = ['id' => $RecordId, 'disable' => $Status == '0' ? true : false];
|
||||
$data = $this->execute('PUT', '/api/recordDisable', $param);
|
||||
return $data !== false;
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
return false;
|
||||
}
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
$param = ['domain' => $this->domain];
|
||||
$data = $this->execute('GET', '/api/availableLine', $param);
|
||||
if($data){
|
||||
array_multisort(array_column($data, 'order'), SORT_ASC, $data);
|
||||
$list = [];
|
||||
foreach($data as $row){
|
||||
if($row['id'] == '0') $row['id'] = '';
|
||||
$list[$row['id']] = ['name'=>$row['value'], 'parent'=>!empty($row['pid']) ? $row['pid'] : null];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名信息
|
||||
public function getDomainInfo(){
|
||||
$param = ['id' => $this->domainid];
|
||||
$data = $this->execute('GET', '/api/domain', $param);
|
||||
return $data;
|
||||
}
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
$param = ['domain' => $this->domain];
|
||||
$data = $this->execute('GET', '/api/availableLine', $param);
|
||||
if ($data) {
|
||||
array_multisort(array_column($data, 'order'), SORT_ASC, $data);
|
||||
$list = [];
|
||||
foreach ($data as $row) {
|
||||
if ($row['id'] == '0') $row['id'] = '';
|
||||
$list[$row['id']] = ['name' => $row['value'], 'parent' => !empty($row['pid']) ? $row['pid'] : null];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
$param = ['id' => $this->domainid];
|
||||
$data = $this->execute('GET', '/api/dnsMeasures', $param);
|
||||
if($data && isset($data['minTTL'])){
|
||||
return $data['minTTL'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
$param = ['id' => $this->domainid];
|
||||
$data = $this->execute('GET', '/api/domain', $param);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function convertType($type){
|
||||
$typeList = array_flip($this->typeList);
|
||||
return $typeList[$type];
|
||||
}
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
$param = ['id' => $this->domainid];
|
||||
$data = $this->execute('GET', '/api/dnsMeasures', $param);
|
||||
if ($data && isset($data['minTTL'])) {
|
||||
return $data['minTTL'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertTypeId($typeId, $domaint){
|
||||
if($typeId == 256) return $domaint ? 'REDIRECT_URL' : 'FORWARD_URL';
|
||||
return $this->typeList[$typeId];
|
||||
}
|
||||
private function convertType($type)
|
||||
{
|
||||
$typeList = array_flip($this->typeList);
|
||||
return $typeList[$type];
|
||||
}
|
||||
|
||||
private function execute($method, $path, $params = null){
|
||||
$token = base64_encode($this->apiid.':'.$this->apisecret);
|
||||
$header = ['Authorization: Basic '.$token, 'Content-Type: application/json; charset=utf-8'];
|
||||
if($method == 'POST' || $method == 'PUT'){
|
||||
$response = $this->curl($method, $path, $header, json_encode($params));
|
||||
}else{
|
||||
if($params){
|
||||
$path .= '?'.http_build_query($params);
|
||||
}
|
||||
$response = $this->curl($method, $path, $header);
|
||||
}
|
||||
$arr=json_decode($response,true);
|
||||
if($arr){
|
||||
if($arr['code'] == 200){
|
||||
return $arr['data'];
|
||||
}else{
|
||||
$this->setError($arr['msg']);
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private function convertTypeId($typeId, $domaint)
|
||||
{
|
||||
if ($typeId == 256) return $domaint ? 'REDIRECT_URL' : 'FORWARD_URL';
|
||||
return $this->typeList[$typeId];
|
||||
}
|
||||
|
||||
private function curl($method, $path, $header, $body = null, $isPut = false){
|
||||
$url = $this->baseUrl . $path;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if ($body) {
|
||||
private function execute($method, $path, $params = null)
|
||||
{
|
||||
$token = base64_encode($this->apiid.':'.$this->apisecret);
|
||||
$header = ['Authorization: Basic '.$token, 'Content-Type: application/json; charset=utf-8'];
|
||||
if ($method == 'POST' || $method == 'PUT') {
|
||||
$response = $this->curl($method, $path, $header, json_encode($params));
|
||||
} else {
|
||||
if ($params) {
|
||||
$path .= '?'.http_build_query($params);
|
||||
}
|
||||
$response = $this->curl($method, $path, $header);
|
||||
}
|
||||
if (!$response) {
|
||||
return false;
|
||||
}
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if ($arr['code'] == 200) {
|
||||
return $arr['data'];
|
||||
} else {
|
||||
$this->setError($arr['msg']);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function curl($method, $path, $header, $body = null, $isPut = false)
|
||||
{
|
||||
$url = $this->baseUrl . $path;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if ($body) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
if($httpCode==200){
|
||||
return $response;
|
||||
}elseif($httpCode==401){
|
||||
$this->setError('认证失败');
|
||||
return false;
|
||||
}else{
|
||||
$this->setError('http code: '.$httpCode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
if ($httpCode == 200) {
|
||||
return $response;
|
||||
} elseif ($httpCode == 401) {
|
||||
$this->setError('认证失败');
|
||||
return false;
|
||||
} else {
|
||||
$this->setError('http code: '.$httpCode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,367 +1,436 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class dnspod implements DnsInterface {
|
||||
private $SecretId;
|
||||
private $SecretKey;
|
||||
private $endpoint = "dnspod.tencentcloudapi.com";
|
||||
private $service = "dnspod";
|
||||
private $version = "2021-03-23";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
class dnspod implements DnsInterface
|
||||
{
|
||||
private $SecretId;
|
||||
private $SecretKey;
|
||||
private $endpoint = "dnspod.tencentcloudapi.com";
|
||||
private $service = "dnspod";
|
||||
private $version = "2021-03-23";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
private $domainInfo;
|
||||
|
||||
function __construct($config){
|
||||
$this->SecretId = $config['ak'];
|
||||
$this->SecretKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->SecretId = $config['ak'];
|
||||
$this->SecretKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getAccountInfo() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$action = 'DescribeDomainList';
|
||||
$offset = ($PageNumber-1)*$PageSize;
|
||||
$param = ['Offset' => $offset, 'Limit' => $PageSize, 'Keyword' => $KeyWord];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['DomainList'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['DomainId'],
|
||||
'Domain' => $row['Name'],
|
||||
'RecordCount' => $row['RecordCount'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['DomainCountInfo']['DomainTotal'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$action = 'DescribeDomainList';
|
||||
$offset = ($PageNumber - 1) * $PageSize;
|
||||
$param = ['Offset' => $offset, 'Limit' => $PageSize, 'Keyword' => $KeyWord];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['DomainList'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['DomainId'],
|
||||
'Domain' => $row['Name'],
|
||||
'RecordCount' => $row['RecordCount'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['DomainCountInfo']['DomainTotal'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$offset = ($PageNumber-1)*$PageSize;
|
||||
if(!isNullOrEmpty($Status)){
|
||||
$action = 'DescribeRecordFilterList';
|
||||
$Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
|
||||
$param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize, 'RecordStatus' => [$Status]];
|
||||
if(!isNullOrEmpty($Type)) $param['RecordType'] = [$this->convertType($Type)];
|
||||
if(!isNullOrEmpty($Line)) $param['RecordLine'] = [$Line];
|
||||
}else{
|
||||
$action = 'DescribeRecordList';
|
||||
$param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $this->convertType($Type), 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize];
|
||||
}
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['RecordList'] as $row){
|
||||
//if($row['Name'] == '@' && $row['Type'] == 'NS') continue;
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordId'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['Name'],
|
||||
'Type' => $this->convertTypeId($row['Type']),
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['LineId'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => $row['MX'],
|
||||
'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => $row['Weight'],
|
||||
'Remark' => $row['Remark'],
|
||||
'UpdateTime' => $row['UpdatedOn'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['RecordCountInfo']['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$offset = ($PageNumber - 1) * $PageSize;
|
||||
if (!isNullOrEmpty($Status) || !isNullOrEmpty($Value)) {
|
||||
$action = 'DescribeRecordFilterList';
|
||||
$param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize, 'RecordValue' => $Value];
|
||||
if (!isNullOrEmpty($SubDomain)) $param['SubDomain'] = $SubDomain;
|
||||
if (!isNullOrEmpty($KeyWord)) $param['Keyword'] = $KeyWord;
|
||||
if (!isNullOrEmpty($Value)) $param['RecordValue'] = $Value;
|
||||
if (!isNullOrEmpty($Status)) {
|
||||
$Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
|
||||
$param['RecordStatus'] = [$Status];
|
||||
}
|
||||
if (!isNullOrEmpty($Type)) $param['RecordType'] = [$this->convertType($Type)];
|
||||
if (!isNullOrEmpty($Line)) $param['RecordLine'] = [$Line];
|
||||
} else {
|
||||
$action = 'DescribeRecordList';
|
||||
$param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $this->convertType($Type), 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize];
|
||||
}
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['RecordList'] as $row) {
|
||||
//if($row['Name'] == '@' && $row['Type'] == 'NS') continue;
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordId'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['Name'],
|
||||
'Type' => $this->convertTypeId($row['Type']),
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['LineId'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => $row['MX'],
|
||||
'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
|
||||
'Weight' => $row['Weight'],
|
||||
'Remark' => $row['Remark'],
|
||||
'UpdateTime' => $row['UpdatedOn'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['RecordCountInfo']['TotalCount'], 'list' => $list];
|
||||
} elseif ($this->error == '记录列表为空。' || $this->error == 'No records on the list.') {
|
||||
return ['total' => 0, 'list' => []];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
if($SubDomain == '')$SubDomain='@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, $Type, $Line);
|
||||
}
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
if ($SubDomain == '') $SubDomain = '@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
$action = 'DescribeRecord';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
return [
|
||||
'RecordId' => $data['RecordInfo']['Id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $data['RecordInfo']['SubDomain'],
|
||||
'Type' => $this->convertTypeId($data['RecordInfo']['RecordType']),
|
||||
'Value' => $data['RecordInfo']['Value'],
|
||||
'Line' => $data['RecordInfo']['RecordLineId'],
|
||||
'TTL' => $data['RecordInfo']['TTL'],
|
||||
'MX' => $data['RecordInfo']['MX'],
|
||||
'Status' => $data['RecordInfo']['Enabled'] == 1 ? '1' : '0',
|
||||
'Weight' => $data['RecordInfo']['Weight'],
|
||||
'Remark' => $data['RecordInfo']['Remark'],
|
||||
'UpdateTime' => $data['RecordInfo']['UpdatedOn'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
$action = 'DescribeRecord';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
return [
|
||||
'RecordId' => $data['RecordInfo']['Id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $data['RecordInfo']['SubDomain'],
|
||||
'Type' => $this->convertTypeId($data['RecordInfo']['RecordType']),
|
||||
'Value' => $data['RecordInfo']['Value'],
|
||||
'Line' => $data['RecordInfo']['RecordLineId'],
|
||||
'TTL' => $data['RecordInfo']['TTL'],
|
||||
'MX' => $data['RecordInfo']['MX'],
|
||||
'Status' => $data['RecordInfo']['Enabled'] == 1 ? '1' : '0',
|
||||
'Weight' => $data['RecordInfo']['Weight'],
|
||||
'Remark' => $data['RecordInfo']['Remark'],
|
||||
'UpdateTime' => $data['RecordInfo']['UpdatedOn'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$action = 'CreateRecord';
|
||||
$param = ['Domain' => $this->domain, 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine'=>$Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
|
||||
if($Type == 'MX')$param['MX'] = intval($MX);
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data) ? $data['RecordId'] : false;
|
||||
}
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$action = 'CreateRecord';
|
||||
$param = ['Domain' => $this->domain, 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine' => $Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL), 'Weight' => $Weight];
|
||||
if ($Type == 'MX') $param['MX'] = intval($MX);
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data) ? $data['RecordId'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$action = 'ModifyRecord';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine'=>$Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
|
||||
if($Type == 'MX')$param['MX'] = intval($MX);
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$action = 'ModifyRecord';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine' => $Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL), 'Weight' => $Weight];
|
||||
if ($Type == 'MX') $param['MX'] = intval($MX);
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
$action = 'ModifyRecordRemark';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Remark' => $Remark];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
$action = 'ModifyRecordRemark';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Remark' => $Remark];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$action = 'DeleteRecord';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
$Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
|
||||
$action = 'ModifyRecordStatus';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Status' => $Status];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$action = 'DeleteRecord';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
$action = 'DescribeDomainLogList';
|
||||
$offset = ($PageNumber-1)*$PageSize;
|
||||
$param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['LogList'] as $row){
|
||||
$list[] = ['time'=>substr($row, 0, strpos($row,'(')), 'ip'=>substr($row, strpos($row,'(')+1, strpos($row,')')-strpos($row,'(')-1), 'data'=>substr($row, strpos($row,')')+1, strpos($row,' Uin:')-strpos($row,')')-1)];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
|
||||
$action = 'ModifyRecordStatus';
|
||||
$param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Status' => $Status];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
$action = 'DescribeRecordLineCategoryList';
|
||||
$param = ['Domain' => $this->domain];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
$this->processLineList($list, $data['LineList'], null);
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
$action = 'DescribeDomainLogList';
|
||||
$offset = ($PageNumber - 1) * $PageSize;
|
||||
$param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['LogList'] as $row) {
|
||||
$list[] = ['time' => substr($row, 0, strpos($row, '(')), 'ip' => substr($row, strpos($row, '(') + 1, strpos($row, ')') - strpos($row, '(') - 1), 'data' => substr($row, strpos($row, ')') + 1, strpos($row, ' Uin:') - strpos($row, ')') - 1)];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function processLineList(&$list, $line_list, $parent){
|
||||
foreach($line_list as $row){
|
||||
if(!isNullOrEmpty($row['LineId']) && $row['Useful'] && !isset($list[$row['LineId']])){
|
||||
$list[$row['LineId']] = ['name'=>$row['LineName'], 'parent'=>$parent];
|
||||
if($row['SubGroup']){
|
||||
$this->processLineList($list, $row['SubGroup'], $row['LineId']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
$action = 'DescribeRecordLineCategoryList';
|
||||
$param = ['Domain' => $this->domain];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
$this->processLineList($list, $data['LineList'], null);
|
||||
return $list;
|
||||
} else {
|
||||
$data = $this->getRecordLineByGrade();
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data as $row) {
|
||||
$list[$row['LineId']] = ['name' => $row['Name'], 'parent' => null];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo(){
|
||||
$action = 'DescribeDomainPreview';
|
||||
$param = ['Domain' => $this->domain];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
return $data['Domain'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private function processLineList(&$list, $line_list, $parent)
|
||||
{
|
||||
foreach ($line_list as $row) {
|
||||
if (isNullOrEmpty($row['LineId'])) $row['LineId'] = 'N.' . $row['LineName'];
|
||||
if ($row['Useful'] && !isset($list[$row['LineId']])) {
|
||||
$list[$row['LineId']] = ['name' => $row['LineName'], 'parent' => $parent];
|
||||
if ($row['SubGroup']) {
|
||||
$this->processLineList($list, $row['SubGroup'], $row['LineId']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取域名权限
|
||||
public function getDomainPurview(){
|
||||
$action = 'DescribeDomainPurview';
|
||||
$param = ['Domain' => $this->domain];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
return $data['PurviewList'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
$action = 'DescribeDomain';
|
||||
$param = ['Domain' => $this->domain];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
$this->domainInfo = $data['DomainInfo'];
|
||||
return $data['DomainInfo'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
$PurviewList = $this->getDomainPurview();
|
||||
if($PurviewList){
|
||||
foreach($PurviewList as $row){
|
||||
if($row['Name'] == '记录 TTL 最低'){
|
||||
return intval($row['Value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名权限
|
||||
public function getDomainPurview()
|
||||
{
|
||||
$action = 'DescribeDomainPurview';
|
||||
$param = ['Domain' => $this->domain];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
return $data['PurviewList'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
public function getAccountInfo(){
|
||||
$action = 'DescribeUserDetail';
|
||||
$param = [];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if($data){
|
||||
return $data['UserInfo'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
if ($this->domainInfo) {
|
||||
return $this->domainInfo['TTL'];
|
||||
}
|
||||
$PurviewList = $this->getDomainPurview();
|
||||
if ($PurviewList) {
|
||||
foreach ($PurviewList as $row) {
|
||||
if ($row['Name'] == '记录 TTL 最低' || $row['Name'] == 'Min TTL value') {
|
||||
return intval($row['Value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertLineCode($line){
|
||||
$convert_dict = ['default'=>'0', 'unicom'=>'10=1', 'telecom'=>'10=0', 'mobile'=>'10=3', 'edu'=>'10=2', 'oversea'=>'3=0', 'btvn'=>'10=22', 'search'=>'80=0', 'internal'=>'7=0'];
|
||||
if(array_key_exists($line, $convert_dict)){
|
||||
return $convert_dict[$line];
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
//获取等级允许的线路
|
||||
public function getRecordLineByGrade()
|
||||
{
|
||||
$action = 'DescribeRecordLineList';
|
||||
$param = ['Domain' => $this->domain, 'DomainGrade' => ''];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
$line_list = $data['LineList'];
|
||||
if (!empty($data['LineGroupList'])) {
|
||||
foreach ($data['LineGroupList'] as $row) {
|
||||
$line_list[] = ['Name' => $row['Name'], 'LineId' => $row['LineId']];
|
||||
}
|
||||
}
|
||||
return $line_list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type){
|
||||
$convert_dict = ['REDIRECT_URL'=>'显性URL', 'FORWARD_URL'=>'隐性URL'];
|
||||
if(array_key_exists($type, $convert_dict)){
|
||||
return $convert_dict[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
//获取用户信息
|
||||
public function getAccountInfo()
|
||||
{
|
||||
$action = 'DescribeUserDetail';
|
||||
$param = [];
|
||||
$data = $this->send_reuqest($action, $param);
|
||||
if ($data) {
|
||||
return $data['UserInfo'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertTypeId($type){
|
||||
$convert_dict = ['显性URL'=>'REDIRECT_URL', '隐性URL'=>'FORWARD_URL'];
|
||||
if(array_key_exists($type, $convert_dict)){
|
||||
return $convert_dict[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
private function convertLineCode($line)
|
||||
{
|
||||
$convert_dict = ['default' => '0', 'unicom' => '10=1', 'telecom' => '10=0', 'mobile' => '10=3', 'edu' => '10=2', 'oversea' => '3=0', 'btvn' => '10=22', 'search' => '80=0', 'internal' => '7=0'];
|
||||
if (array_key_exists($line, $convert_dict)) {
|
||||
return $convert_dict[$line];
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
private function convertType($type)
|
||||
{
|
||||
$convert_dict = ['REDIRECT_URL' => '显性URL', 'FORWARD_URL' => '隐性URL'];
|
||||
if (array_key_exists($type, $convert_dict)) {
|
||||
return $convert_dict[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function convertTypeId($type)
|
||||
{
|
||||
$convert_dict = ['显性URL' => 'REDIRECT_URL', '隐性URL' => 'FORWARD_URL'];
|
||||
if (array_key_exists($type, $convert_dict)) {
|
||||
return $convert_dict[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
private function send_reuqest($action, $param){
|
||||
$param = array_filter($param, function($a){ return $a!==null;});
|
||||
if(!$param) $param = (object)[];
|
||||
$payload = json_encode($param);
|
||||
$time = time();
|
||||
$authorization = $this->generateSign($payload, $time);
|
||||
$header = [
|
||||
'Authorization: '.$authorization,
|
||||
'Content-Type: application/json; charset=utf-8',
|
||||
'X-TC-Action: '.$action,
|
||||
'X-TC-Timestamp: '.$time,
|
||||
'X-TC-Version: '.$this->version,
|
||||
];
|
||||
return $this->curl_post($payload, $header);
|
||||
}
|
||||
private function send_reuqest($action, $param)
|
||||
{
|
||||
$param = array_filter($param, function ($a) { return $a !== null;});
|
||||
if (!$param) $param = (object)[];
|
||||
$payload = json_encode($param);
|
||||
$time = time();
|
||||
$authorization = $this->generateSign($payload, $time);
|
||||
$header = [
|
||||
'Authorization: '.$authorization,
|
||||
'Content-Type: application/json; charset=utf-8',
|
||||
'X-TC-Action: '.$action,
|
||||
'X-TC-Timestamp: '.$time,
|
||||
'X-TC-Version: '.$this->version,
|
||||
];
|
||||
return $this->curl_post($payload, $header);
|
||||
}
|
||||
|
||||
private function generateSign($payload, $time){
|
||||
$algorithm = "TC3-HMAC-SHA256";
|
||||
private function generateSign($payload, $time)
|
||||
{
|
||||
$algorithm = "TC3-HMAC-SHA256";
|
||||
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = "POST";
|
||||
$canonicalUri = "/";
|
||||
$canonicalQueryString = "";
|
||||
$canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$this->endpoint."\n";
|
||||
$signedHeaders = "content-type;host";
|
||||
$hashedRequestPayload = hash("SHA256", $payload);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders."\n"
|
||||
.$signedHeaders."\n"
|
||||
.$hashedRequestPayload;
|
||||
|
||||
// step 2: build string to sign
|
||||
$date = gmdate("Y-m-d", $time);
|
||||
$credentialScope = $date."/".$this->service."/tc3_request";
|
||||
$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
|
||||
$stringToSign = $algorithm."\n"
|
||||
.$time."\n"
|
||||
.$credentialScope."\n"
|
||||
.$hashedCanonicalRequest;
|
||||
|
||||
// step 3: sign string
|
||||
$secretDate = hash_hmac("SHA256", $date, "TC3".$this->SecretKey, true);
|
||||
$secretService = hash_hmac("SHA256", $this->service, $secretDate, true);
|
||||
$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
|
||||
$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = "POST";
|
||||
$canonicalUri = "/";
|
||||
$canonicalQueryString = "";
|
||||
$canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$this->endpoint."\n";
|
||||
$signedHeaders = "content-type;host";
|
||||
$hashedRequestPayload = hash("SHA256", $payload);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders."\n"
|
||||
.$signedHeaders."\n"
|
||||
.$hashedRequestPayload;
|
||||
|
||||
// step 4: build authorization
|
||||
$authorization = $algorithm
|
||||
." Credential=".$this->SecretId."/".$credentialScope
|
||||
.", SignedHeaders=content-type;host, Signature=".$signature;
|
||||
// step 2: build string to sign
|
||||
$date = gmdate("Y-m-d", $time);
|
||||
$credentialScope = $date."/".$this->service."/tc3_request";
|
||||
$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
|
||||
$stringToSign = $algorithm."\n"
|
||||
.$time."\n"
|
||||
.$credentialScope."\n"
|
||||
.$hashedCanonicalRequest;
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
// step 3: sign string
|
||||
$secretDate = hash_hmac("SHA256", $date, "TC3".$this->SecretKey, true);
|
||||
$secretService = hash_hmac("SHA256", $this->service, $secretDate, true);
|
||||
$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
|
||||
$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
|
||||
|
||||
private function curl_post($payload, $header){
|
||||
$url = 'https://'.$this->endpoint.'/';
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
// step 4: build authorization
|
||||
$authorization = $algorithm
|
||||
." Credential=".$this->SecretId."/".$credentialScope
|
||||
.", SignedHeaders=content-type;host, Signature=".$signature;
|
||||
|
||||
$arr=json_decode($response,true);
|
||||
if($arr){
|
||||
if(isset($arr['Response']['Error'])){
|
||||
$this->setError($arr['Response']['Error']['Message']);
|
||||
return false;
|
||||
}else{
|
||||
return $arr['Response'];
|
||||
}
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
private function curl_post($payload, $header)
|
||||
{
|
||||
$url = 'https://'.$this->endpoint.'/';
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if (isset($arr['Response']['Error'])) {
|
||||
$this->setError($arr['Response']['Error']['Message']);
|
||||
return false;
|
||||
} else {
|
||||
return $arr['Response'];
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,349 +1,386 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class huawei implements DnsInterface {
|
||||
private $AccessKeyId;
|
||||
private $SecretAccessKey;
|
||||
private $endpoint = "dns.myhuaweicloud.com";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
class huawei implements DnsInterface
|
||||
{
|
||||
private $AccessKeyId;
|
||||
private $SecretAccessKey;
|
||||
private $endpoint = "dns.myhuaweicloud.com";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
|
||||
function __construct($config){
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->SecretAccessKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getDomainList() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$offset = ($PageNumber-1)*$PageSize;
|
||||
$query = ['offset' => $offset, 'limit' => $PageSize, 'name' => $KeyWord];
|
||||
$data = $this->send_reuqest('GET', '/v2/zones', $query);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['zones'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => rtrim($row['name'], '.'),
|
||||
'RecordCount' => $row['record_num'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['metadata']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$offset = ($PageNumber-1)*$PageSize;
|
||||
$query = ['type' => $Type, 'line_id' => $Line, 'name' => $KeyWord, 'status' => $Status, 'offset' => $offset, 'limit' => $PageSize];
|
||||
if(!isNullOrEmpty(($SubDomain))){
|
||||
$query['name'] = $SubDomain;
|
||||
$query['search_mode'] = 'equal';
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets', $query);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['recordsets'] as $row){
|
||||
if($row['name'] == $row['zone_name']) $row['name'] = '@';
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => rtrim($row['zone_name'], '.'),
|
||||
'Name' => str_replace('.'.$row['zone_name'], '', $row['name']),
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['records'],
|
||||
'Line' => $row['line'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => $row['weight'],
|
||||
'Status' => $row['status'] == 'ACTIVE' ? '1' : '0',
|
||||
'Weight' => $row['weight'],
|
||||
'Remark' => $row['description'],
|
||||
'UpdateTime' => $row['updated_at'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['metadata']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
$SubDomain = $this->getHost($SubDomain);
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
$data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
|
||||
if($data){
|
||||
return [
|
||||
'RecordId' => $data['id'],
|
||||
'Domain' => rtrim($data['zone_name'], '.'),
|
||||
'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
|
||||
'Type' => $data['type'],
|
||||
'Value' => $data['records'],
|
||||
'Line' => $data['line'],
|
||||
'TTL' => $data['ttl'],
|
||||
'MX' => $data['weight'],
|
||||
'Status' => $data['status'] == 'ACTIVE' ? '1' : '0',
|
||||
'Weight' => $data['weight'],
|
||||
'Remark' => $data['description'],
|
||||
'UpdateTime' => $data['updated_at'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$Name = $this->getHost($Name);
|
||||
$records = explode(',', $Value);
|
||||
$params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if($Type == 'MX')$param['weight'] = intval($MX);
|
||||
$data = $this->send_reuqest('POST', '/v2.1/zones/'.$this->domainid.'/recordsets', null, $params);
|
||||
return is_array($data) ? $data['id'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$Name = $this->getHost($Name);
|
||||
$records = explode(',', $Value);
|
||||
$params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if($Type == 'MX')$param['weight'] = intval($MX);
|
||||
$data = $this->send_reuqest('PUT', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId, null, $params);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$data = $this->send_reuqest('DELETE', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
$Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
|
||||
$params = ['status' => $Status];
|
||||
$data = $this->send_reuqest('PUT', '/v2.1/recordsets/'.$RecordId.'/statuses/set', null, $params);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
$file_path = app()->getBasePath().'data'.DIRECTORY_SEPARATOR.'huawei_line.json';
|
||||
$content = file_get_contents($file_path);
|
||||
$data = json_decode($content, true);
|
||||
if($data){
|
||||
return $data;
|
||||
$list = [$data['DEFAULT']['id'] => ['name'=>$data['DEFAULT']['zh'], 'parent'=>null]];
|
||||
$this->processLineList($list, $data['ISP'], null, 1, 1);
|
||||
$this->processLineList($list, $data['REGION'], null, null, 1);
|
||||
//file_put_contents($file_path, json_encode($list, JSON_UNESCAPED_UNICODE));
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function processLineList(&$list, $line_list, $parent, $rootId = null, $rootName = null){
|
||||
foreach($line_list as $row){
|
||||
if($rootId && $rootId!==1){
|
||||
$row['id'] = $rootId.'_'.$row['id'];
|
||||
}
|
||||
if($rootName && $rootName!==1){
|
||||
$row['zh'] = $rootName.'_'.$row['zh'];
|
||||
}
|
||||
$list[$row['id']] = ['name'=>$row['zh'], 'parent'=>$parent];
|
||||
if(isset($row['children']) && !empty($row['children'])){
|
||||
$this->processLineList($list, $row['children'], $row['id'], $rootId === 1 ? $row['id'] : $rootId, $rootName === 1 ? $row['zh'] : $rootName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo(){
|
||||
return $this->send_reuqest('GET', '/v2/zones/'.$this->domainid);
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type){
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function getHost($Name){
|
||||
if($Name == '@') $Name = '';
|
||||
else $Name .= '.';
|
||||
$Name .= $this->domain . '.';
|
||||
return $Name;
|
||||
}
|
||||
|
||||
private function send_reuqest($method, $path, $query = null, $params = null){
|
||||
if(!empty($query)){
|
||||
$query = array_filter($query, function($a){ return $a!==null;});
|
||||
}
|
||||
if(!empty($params)){
|
||||
$params = array_filter($params, function($a){ return $a!==null;});
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$date = gmdate("Ymd\THis\Z", $time);
|
||||
$body = !empty($params) ? json_encode($params) : '';
|
||||
$headers = [
|
||||
'Host' => $this->endpoint,
|
||||
'X-Sdk-Date' => $date,
|
||||
];
|
||||
if($body){
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
$authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
|
||||
$headers['Authorization'] = $authorization;
|
||||
|
||||
$url = 'https://'.$this->endpoint.$path;
|
||||
if(!empty($query)){
|
||||
$url .= '?'.http_build_query($query);
|
||||
}
|
||||
$header = [];
|
||||
foreach($headers as $key => $value){
|
||||
$header[] = $key.': '.$value;
|
||||
}
|
||||
return $this->curl($method, $url, $body, $header);
|
||||
}
|
||||
|
||||
private function generateSign($method, $path, $query, $headers, $body, $time){
|
||||
$algorithm = "SDK-HMAC-SHA256";
|
||||
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = $method;
|
||||
$canonicalUri = $path;
|
||||
if(substr($canonicalUri, -1) != "/") $canonicalUri .= "/";
|
||||
$canonicalQueryString = $this->getCanonicalQueryString($query);
|
||||
[$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
|
||||
$hashedRequestPayload = hash("sha256", $body);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders."\n"
|
||||
.$signedHeaders."\n"
|
||||
.$hashedRequestPayload;
|
||||
|
||||
// step 2: build string to sign
|
||||
$date = gmdate("Ymd\THis\Z", $time);
|
||||
$hashedCanonicalRequest = hash("sha256", $canonicalRequest);
|
||||
$stringToSign = $algorithm."\n"
|
||||
.$date."\n"
|
||||
.$hashedCanonicalRequest;
|
||||
|
||||
// step 3: sign string
|
||||
$signature = hash_hmac("sha256", $stringToSign, $this->SecretAccessKey);
|
||||
|
||||
// step 4: build authorization
|
||||
$authorization = $algorithm . ' Access=' . $this->AccessKeyId . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
private function escape($str)
|
||||
public function __construct($config)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->SecretAccessKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
private function getCanonicalQueryString($parameters)
|
||||
public function getError()
|
||||
{
|
||||
if(empty($parameters)) return '';
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$offset = ($PageNumber - 1) * $PageSize;
|
||||
$query = ['offset' => $offset, 'limit' => $PageSize, 'name' => $KeyWord];
|
||||
$data = $this->send_reuqest('GET', '/v2/zones', $query);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['zones'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['id'],
|
||||
'Domain' => rtrim($row['name'], '.'),
|
||||
'RecordCount' => $row['record_num'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['metadata']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$offset = ($PageNumber - 1) * $PageSize;
|
||||
$query = ['type' => $Type, 'line_id' => $Line, 'name' => $KeyWord, 'offset' => $offset, 'limit' => $PageSize];
|
||||
if (!isNullOrEmpty($Status)) {
|
||||
$Status = $Status == '1' ? 'ACTIVE' : 'DISABLE';
|
||||
$query['status'] = $Status;
|
||||
}
|
||||
if (!isNullOrEmpty($SubDomain)) {
|
||||
$SubDomain = $this->getHost($SubDomain);
|
||||
$query['name'] = $SubDomain;
|
||||
$query['search_mode'] = 'equal';
|
||||
}
|
||||
$data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets', $query);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['recordsets'] as $row) {
|
||||
if ($row['name'] == $row['zone_name']) $row['name'] = '@';
|
||||
if ($row['type'] == 'MX') list($row['mx'], $row['records']) = explode(' ', $row['records'][0]);
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => rtrim($row['zone_name'], '.'),
|
||||
'Name' => str_replace('.'.$row['zone_name'], '', $row['name']),
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['records'],
|
||||
'Line' => $row['line'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => isset($row['mx']) ? $row['mx'] : null,
|
||||
'Status' => $row['status'] == 'ACTIVE' ? '1' : '0',
|
||||
'Weight' => $row['weight'],
|
||||
'Remark' => $row['description'],
|
||||
'UpdateTime' => $row['updated_at'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['metadata']['total_count'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
$data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
|
||||
if ($data) {
|
||||
if ($data['name'] == $data['zone_name']) $data['name'] = '@';
|
||||
if ($data['type'] == 'MX') list($data['mx'], $data['records']) = explode(' ', $data['records'][0]);
|
||||
return [
|
||||
'RecordId' => $data['id'],
|
||||
'Domain' => rtrim($data['zone_name'], '.'),
|
||||
'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
|
||||
'Type' => $data['type'],
|
||||
'Value' => $data['records'],
|
||||
'Line' => $data['line'],
|
||||
'TTL' => $data['ttl'],
|
||||
'MX' => isset($data['mx']) ? $data['mx'] : null,
|
||||
'Status' => $data['status'] == 'ACTIVE' ? '1' : '0',
|
||||
'Weight' => $data['weight'],
|
||||
'Remark' => $data['description'],
|
||||
'UpdateTime' => $data['updated_at'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$Name = $this->getHost($Name);
|
||||
if ($Type == 'TXT' && substr($Value, 0, 1) != '"') $Value = '"' . $Value . '"';
|
||||
$records = explode(',', $Value);
|
||||
$params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if ($Type == 'MX') $params['records'][0] = intval($MX) . ' ' . $Value;
|
||||
if ($Weight > 0) $params['weight'] = intval($Weight);
|
||||
$data = $this->send_reuqest('POST', '/v2.1/zones/'.$this->domainid.'/recordsets', null, $params);
|
||||
return is_array($data) ? $data['id'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$Name = $this->getHost($Name);
|
||||
if ($Type == 'TXT' && substr($Value, 0, 1) != '"') $Value = '"' . $Value . '"';
|
||||
$records = explode(',', $Value);
|
||||
$params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
|
||||
if ($Type == 'MX') $params['records'][0] = intval($MX) . ' ' . $Value;
|
||||
if ($Weight > 0) $params['weight'] = intval($Weight);
|
||||
$data = $this->send_reuqest('PUT', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId, null, $params);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$data = $this->send_reuqest('DELETE', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
|
||||
$params = ['status' => $Status];
|
||||
$data = $this->send_reuqest('PUT', '/v2.1/recordsets/'.$RecordId.'/statuses/set', null, $params);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
$file_path = app()->getBasePath().'data'.DIRECTORY_SEPARATOR.'huawei_line.json';
|
||||
$content = file_get_contents($file_path);
|
||||
$data = json_decode($content, true);
|
||||
if ($data) {
|
||||
return $data;
|
||||
$list = [$data['DEFAULT']['id'] => ['name' => $data['DEFAULT']['zh'], 'parent' => null]];
|
||||
$this->processLineList($list, $data['ISP'], null, 1, 1);
|
||||
$this->processLineList($list, $data['REGION'], null, null, 1);
|
||||
//file_put_contents($file_path, json_encode($list, JSON_UNESCAPED_UNICODE));
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function processLineList(&$list, $line_list, $parent, $rootId = null, $rootName = null)
|
||||
{
|
||||
foreach ($line_list as $row) {
|
||||
if ($rootId && $rootId !== 1) {
|
||||
$row['id'] = $rootId.'_'.$row['id'];
|
||||
}
|
||||
if ($rootName && $rootName !== 1) {
|
||||
$row['zh'] = $rootName.'_'.$row['zh'];
|
||||
}
|
||||
$list[$row['id']] = ['name' => $row['zh'], 'parent' => $parent];
|
||||
if (isset($row['children']) && !empty($row['children'])) {
|
||||
$this->processLineList($list, $row['children'], $row['id'], $rootId === 1 ? $row['id'] : $rootId, $rootName === 1 ? $row['zh'] : $rootName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
return $this->send_reuqest('GET', '/v2/zones/'.$this->domainid);
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type)
|
||||
{
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function getHost($Name)
|
||||
{
|
||||
if ($Name == '@') $Name = '';
|
||||
else $Name .= '.';
|
||||
$Name .= $this->domain . '.';
|
||||
return $Name;
|
||||
}
|
||||
|
||||
private function send_reuqest($method, $path, $query = null, $params = null)
|
||||
{
|
||||
if (!empty($query)) {
|
||||
$query = array_filter($query, function ($a) { return $a !== null;});
|
||||
}
|
||||
if (!empty($params)) {
|
||||
$params = array_filter($params, function ($a) { return $a !== null;});
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$date = gmdate("Ymd\THis\Z", $time);
|
||||
$body = !empty($params) ? json_encode($params) : '';
|
||||
$headers = [
|
||||
'Host' => $this->endpoint,
|
||||
'X-Sdk-Date' => $date,
|
||||
];
|
||||
if ($body) {
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
$authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
|
||||
$headers['Authorization'] = $authorization;
|
||||
|
||||
$url = 'https://'.$this->endpoint.$path;
|
||||
if (!empty($query)) {
|
||||
$url .= '?'.http_build_query($query);
|
||||
}
|
||||
$header = [];
|
||||
foreach ($headers as $key => $value) {
|
||||
$header[] = $key.': '.$value;
|
||||
}
|
||||
return $this->curl($method, $url, $body, $header);
|
||||
}
|
||||
|
||||
private function generateSign($method, $path, $query, $headers, $body, $time)
|
||||
{
|
||||
$algorithm = "SDK-HMAC-SHA256";
|
||||
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = $method;
|
||||
$canonicalUri = $path;
|
||||
if (substr($canonicalUri, -1) != "/") $canonicalUri .= "/";
|
||||
$canonicalQueryString = $this->getCanonicalQueryString($query);
|
||||
[$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
|
||||
$hashedRequestPayload = hash("sha256", $body);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders."\n"
|
||||
.$signedHeaders."\n"
|
||||
.$hashedRequestPayload;
|
||||
|
||||
// step 2: build string to sign
|
||||
$date = gmdate("Ymd\THis\Z", $time);
|
||||
$hashedCanonicalRequest = hash("sha256", $canonicalRequest);
|
||||
$stringToSign = $algorithm."\n"
|
||||
.$date."\n"
|
||||
.$hashedCanonicalRequest;
|
||||
|
||||
// step 3: sign string
|
||||
$signature = hash_hmac("sha256", $stringToSign, $this->SecretAccessKey);
|
||||
|
||||
// step 4: build authorization
|
||||
$authorization = $algorithm . ' Access=' . $this->AccessKeyId . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
private function escape($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
|
||||
private function getCanonicalQueryString($parameters)
|
||||
{
|
||||
if (empty($parameters)) return '';
|
||||
ksort($parameters);
|
||||
$canonicalQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
$canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
|
||||
}
|
||||
$canonicalQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
$canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
|
||||
}
|
||||
return substr($canonicalQueryString, 1);
|
||||
}
|
||||
|
||||
private function getCanonicalHeaders($oldheaders){
|
||||
$headers = array();
|
||||
private function getCanonicalHeaders($oldheaders)
|
||||
{
|
||||
$headers = array();
|
||||
foreach ($oldheaders as $key => $value) {
|
||||
$headers[strtolower($key)] = trim($value);
|
||||
}
|
||||
ksort($headers);
|
||||
ksort($headers);
|
||||
|
||||
$canonicalHeaders = '';
|
||||
$signedHeaders = '';
|
||||
foreach ($headers as $key => $value) {
|
||||
$canonicalHeaders .= $key . ':' . $value . "\n";
|
||||
$signedHeaders .= $key . ';';
|
||||
}
|
||||
$signedHeaders = substr($signedHeaders, 0, -1);
|
||||
return [$canonicalHeaders, $signedHeaders];
|
||||
}
|
||||
$canonicalHeaders = '';
|
||||
$signedHeaders = '';
|
||||
foreach ($headers as $key => $value) {
|
||||
$canonicalHeaders .= $key . ':' . $value . "\n";
|
||||
$signedHeaders .= $key . ';';
|
||||
}
|
||||
$signedHeaders = substr($signedHeaders, 0, -1);
|
||||
return [$canonicalHeaders, $signedHeaders];
|
||||
}
|
||||
|
||||
private function curl($method, $url, $body, $header){
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if(!empty($body)){
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
private function curl($method, $url, $body, $header)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if (!empty($body)) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
|
||||
$arr=json_decode($response,true);
|
||||
if($arr){
|
||||
if(isset($arr['error_msg'])){
|
||||
$this->setError($arr['error_msg']);
|
||||
return false;
|
||||
}elseif(isset($arr['message'])){
|
||||
$this->setError($arr['message']);
|
||||
return false;
|
||||
}else{
|
||||
return $arr;
|
||||
}
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if (isset($arr['error_msg'])) {
|
||||
$this->setError($arr['error_msg']);
|
||||
return false;
|
||||
} elseif (isset($arr['message'])) {
|
||||
$this->setError($arr['message']);
|
||||
return false;
|
||||
} else {
|
||||
return $arr;
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
412
app/lib/dns/huoshan.php
Normal file
412
app/lib/dns/huoshan.php
Normal file
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
|
||||
class huoshan implements DnsInterface
|
||||
{
|
||||
private $AccessKeyId;
|
||||
private $SecretAccessKey;
|
||||
private $endpoint = "open.volcengineapi.com";
|
||||
private $service = "DNS";
|
||||
private $version = "2018-08-01";
|
||||
private $region = "cn-north-1";
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
private $domainInfo;
|
||||
|
||||
private static $trade_code_list = [
|
||||
'free_inner' => ['level' => 1, 'name' => '免费版', 'ttl' => 600],
|
||||
'professional_inner' => ['level' => 2, 'name' => '专业版', 'ttl' => 300],
|
||||
'enterprise_inner' => ['level' => 3, 'name' => '企业版', 'ttl' => 60],
|
||||
'ultimate_inner' => ['level' => 4, 'name' => '旗舰版', 'ttl' => 1],
|
||||
'ultimate_exclusive_inner' => ['level' => 5, 'name' => '尊享版', 'ttl' => 1],
|
||||
];
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->AccessKeyId = $config['ak'];
|
||||
$this->SecretAccessKey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
$this->domainid = $config['domainid'];
|
||||
}
|
||||
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$query = ['PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Key' => $KeyWord];
|
||||
$data = $this->send_reuqest('GET', 'ListZones', $query);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
if (!empty($data['Zones'])) {
|
||||
foreach ($data['Zones'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['ZID'],
|
||||
'Domain' => $row['ZoneName'],
|
||||
'RecordCount' => $row['RecordCount'],
|
||||
];
|
||||
}
|
||||
}
|
||||
return ['total' => $data['Total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$query = ['ZID' => intval($this->domainid), 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'SearchOrder' => 'desc'];
|
||||
if (!empty($SubDomain) || !empty($Type) || !empty($Line) || !empty($Value)) {
|
||||
$query += ['Host' => $SubDomain, 'Value' => $Value, 'Type' => $Type, 'Line' => $Line];
|
||||
} elseif (!empty($KeyWord)) {
|
||||
$query += ['Host' => $KeyWord];
|
||||
}
|
||||
$data = $this->send_reuqest('GET', 'ListRecords', $query);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['Records'] as $row) {
|
||||
if ($row['Type'] == 'MX') list($row['MX'], $row['Value']) = explode(' ', $row['Value']);
|
||||
$list[] = [
|
||||
'RecordId' => $row['RecordID'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['Host'],
|
||||
'Type' => $row['Type'],
|
||||
'Value' => $row['Value'],
|
||||
'Line' => $row['Line'],
|
||||
'TTL' => $row['TTL'],
|
||||
'MX' => isset($row['MX']) ? $row['MX'] : null,
|
||||
'Status' => $row['Enable'] ? '1' : '0',
|
||||
'Weight' => $row['Weight'],
|
||||
'Remark' => $row['Remark'],
|
||||
'UpdateTime' => $row['UpdatedAt'],
|
||||
];
|
||||
}
|
||||
return ['total' => $data['TotalCount'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
$data = $this->send_reuqest('GET', 'QueryRecord', ['RecordID' => $RecordId]);
|
||||
if ($data) {
|
||||
if ($data['name'] == $data['zone_name']) $data['name'] = '@';
|
||||
if ($data['Type'] == 'MX') list($data['MX'], $data['Value']) = explode(' ', $data['Value']);
|
||||
return [
|
||||
'RecordId' => $data['RecordID'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $data['Host'],
|
||||
'Type' => $data['Type'],
|
||||
'Value' => $data['Value'],
|
||||
'Line' => $data['Line'],
|
||||
'TTL' => $data['TTL'],
|
||||
'MX' => isset($data['MX']) ? $data['MX'] : null,
|
||||
'Status' => $data['Enable'] ? '1' : '0',
|
||||
'Weight' => $data['Weight'],
|
||||
'Remark' => $data['Remark'],
|
||||
'UpdateTime' => $data['UpdatedAt'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$params = ['ZID' => intval($this->domainid), 'Host' => $Name, 'Type' => $this->convertType($Type), 'Value' => $Value, 'Line' => $Line, 'TTL' => intval($TTL), 'Remark' => $Remark];
|
||||
if ($Type == 'MX') $params['Value'] = intval($MX) . ' ' . $Value;
|
||||
if ($Weight > 0) $params['Weight'] = $Weight;
|
||||
$data = $this->send_reuqest('POST', 'CreateRecord', $params);
|
||||
return is_array($data) ? $data['RecordID'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$params = ['RecordID' => $RecordId, 'Host' => $Name, 'Type' => $this->convertType($Type), 'Value' => $Value, 'Line' => $Line, 'TTL' => intval($TTL), 'Remark' => $Remark];
|
||||
if ($Type == 'MX') $params['Value'] = intval($MX) . ' ' . $Value;
|
||||
if ($Weight > 0) $params['Weight'] = $Weight;
|
||||
$data = $this->send_reuqest('POST', 'UpdateRecord', $params);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$data = $this->send_reuqest('POST', 'DeleteRecord', ['RecordID' => $RecordId]);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$params = ['RecordID' => $RecordId, 'Enable' => $Status == '1'];
|
||||
$data = $this->send_reuqest('POST', 'UpdateRecordStatus', $params);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
$domainInfo = $this->getDomainInfo();
|
||||
if (!$domainInfo) return false;
|
||||
$level = $this->getTradeInfo($domainInfo['TradeCode'])['level'];
|
||||
$data = $this->send_reuqest('GET', 'ListLines', []);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
$list['default'] = ['name' => '默认', 'parent' => null];
|
||||
foreach ($data['Lines'] as $row) {
|
||||
if ($row['Value'] == 'default') continue;
|
||||
if ($row['Level'] > $level) continue;
|
||||
$list[$row['Value']] = ['name' => $row['Name'], 'parent' => isset($row['FatherValue']) ? $row['FatherValue'] : null];
|
||||
}
|
||||
|
||||
$data = $this->send_reuqest('GET', 'ListCustomLines', []);
|
||||
if ($data && $data['TotalCount'] > 0) {
|
||||
$list['N.customer_lines'] = ['name' => '自定义线路', 'parent' => null];
|
||||
foreach ($data['CustomerLines'] as $row) {
|
||||
$list[$row['Line']] = ['name' => $row['NameCN'], 'parent' => 'N.customer_lines'];
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名概览信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
if (!empty($this->domainInfo)) return $this->domainInfo;
|
||||
$query = ['ZID' => intval($this->domainid)];
|
||||
$data = $this->send_reuqest('GET', 'QueryZone', $query);
|
||||
if ($data) {
|
||||
$this->domainInfo = $data;
|
||||
return $data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
$domainInfo = $this->getDomainInfo();
|
||||
if ($domainInfo) {
|
||||
$ttl = $this->getTradeInfo($domainInfo['TradeCode'])['ttl'];
|
||||
return $ttl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type)
|
||||
{
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function getTradeInfo($trade_code)
|
||||
{
|
||||
if (array_key_exists($trade_code, self::$trade_code_list)) {
|
||||
$trade_code = $trade_code;
|
||||
} else {
|
||||
$trade_code = 'free_inner';
|
||||
}
|
||||
return self::$trade_code_list[$trade_code];
|
||||
}
|
||||
|
||||
private function send_reuqest($method, $action, $params = [])
|
||||
{
|
||||
if (!empty($params)) {
|
||||
$params = array_filter($params, function ($a) { return $a !== null;});
|
||||
}
|
||||
|
||||
$query = [
|
||||
'Action' => $action,
|
||||
'Version' => $this->version,
|
||||
];
|
||||
|
||||
$body = '';
|
||||
if ($method == 'GET') {
|
||||
$query = array_merge($query, $params);
|
||||
} else {
|
||||
$body = !empty($params) ? json_encode($params) : '';
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$headers = [
|
||||
'Host' => $this->endpoint,
|
||||
'X-Date' => gmdate("Ymd\THis\Z", $time),
|
||||
//'X-Content-Sha256' => hash("sha256", $body),
|
||||
];
|
||||
if ($body) {
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
$path = '/';
|
||||
|
||||
$authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
|
||||
$headers['Authorization'] = $authorization;
|
||||
|
||||
$url = 'https://'.$this->endpoint.$path.'?'.http_build_query($query);
|
||||
$header = [];
|
||||
foreach ($headers as $key => $value) {
|
||||
$header[] = $key.': '.$value;
|
||||
}
|
||||
return $this->curl($method, $url, $body, $header);
|
||||
}
|
||||
|
||||
private function generateSign($method, $path, $query, $headers, $body, $time)
|
||||
{
|
||||
$algorithm = "HMAC-SHA256";
|
||||
|
||||
// step 1: build canonical request string
|
||||
$httpRequestMethod = $method;
|
||||
$canonicalUri = $path;
|
||||
if (substr($canonicalUri, -1) != "/") $canonicalUri .= "/";
|
||||
$canonicalQueryString = $this->getCanonicalQueryString($query);
|
||||
[$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
|
||||
$hashedRequestPayload = hash("sha256", $body);
|
||||
$canonicalRequest = $httpRequestMethod."\n"
|
||||
.$canonicalUri."\n"
|
||||
.$canonicalQueryString."\n"
|
||||
.$canonicalHeaders."\n"
|
||||
.$signedHeaders."\n"
|
||||
.$hashedRequestPayload;
|
||||
|
||||
// step 2: build string to sign
|
||||
$date = gmdate("Ymd\THis\Z", $time);
|
||||
$shortDate = substr($date, 0, 8);
|
||||
$credentialScope = $shortDate . '/' .$this->region . '/' . $this->service . '/request';
|
||||
$hashedCanonicalRequest = hash("sha256", $canonicalRequest);
|
||||
$stringToSign = $algorithm."\n"
|
||||
.$date."\n"
|
||||
.$credentialScope."\n"
|
||||
.$hashedCanonicalRequest;
|
||||
|
||||
// step 3: sign string
|
||||
$kDate = hash_hmac("sha256", $shortDate, $this->SecretAccessKey, true);
|
||||
$kRegion = hash_hmac("sha256", $this->region, $kDate, true);
|
||||
$kService = hash_hmac("sha256", $this->service, $kRegion, true);
|
||||
$kSigning = hash_hmac("sha256", "request", $kService, true);
|
||||
$signature = hash_hmac("sha256", $stringToSign, $kSigning);
|
||||
|
||||
// step 4: build authorization
|
||||
$credential = $this->AccessKeyId . '/' . $shortDate . '/' . $this->region . '/' . $this->service . '/request';
|
||||
$authorization = $algorithm . ' Credential=' . $credential . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
private function escape($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
|
||||
private function getCanonicalQueryString($parameters)
|
||||
{
|
||||
if (empty($parameters)) return '';
|
||||
ksort($parameters);
|
||||
$canonicalQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
$canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
|
||||
}
|
||||
return substr($canonicalQueryString, 1);
|
||||
}
|
||||
|
||||
private function getCanonicalHeaders($oldheaders)
|
||||
{
|
||||
$headers = array();
|
||||
foreach ($oldheaders as $key => $value) {
|
||||
$headers[strtolower($key)] = trim($value);
|
||||
}
|
||||
ksort($headers);
|
||||
|
||||
$canonicalHeaders = '';
|
||||
$signedHeaders = '';
|
||||
foreach ($headers as $key => $value) {
|
||||
$canonicalHeaders .= $key . ':' . $value . "\n";
|
||||
$signedHeaders .= $key . ';';
|
||||
}
|
||||
$signedHeaders = substr($signedHeaders, 0, -1);
|
||||
return [$canonicalHeaders, $signedHeaders];
|
||||
}
|
||||
|
||||
private function curl($method, $url, $body, $header)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if (!empty($body)) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if (isset($arr['ResponseMetadata']['Error']['MessageCN'])) {
|
||||
$this->setError($arr['ResponseMetadata']['Error']['MessageCN']);
|
||||
return false;
|
||||
} elseif (isset($arr['ResponseMetadata']['Error']['Message'])) {
|
||||
$this->setError($arr['ResponseMetadata']['Error']['Message']);
|
||||
return false;
|
||||
} elseif (isset($arr['Result'])) {
|
||||
return $arr['Result'];
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
221
app/lib/dns/namesilo.php
Normal file
221
app/lib/dns/namesilo.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
use Exception;
|
||||
|
||||
class namesilo implements DnsInterface
|
||||
{
|
||||
private $apikey;
|
||||
private $baseUrl = 'https://www.namesilo.com/api/';
|
||||
private $version = '1';
|
||||
private $error;
|
||||
private $domain;
|
||||
|
||||
function __construct($config)
|
||||
{
|
||||
$this->apikey = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$param = ['page' => $PageNumber, 'pageSize' => $PageSize];
|
||||
$data = $this->send_reuqest('listDomains', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
if($data['domains']){
|
||||
foreach ($data['domains'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['domain'],
|
||||
'Domain' => $row['domain'],
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
return ['total' => $data['pager']['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$param = ['domain' => $this->domain];
|
||||
$data = $this->send_reuqest('dnsListRecords', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['resource_record'] as $row) {
|
||||
$name = $row['host'] == $this->domain ? '@' : str_replace('.'.$this->domain, '', $row['host']);
|
||||
$list[] = [
|
||||
'RecordId' => $row['record_id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $name,
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['value'],
|
||||
'Line' => 'default',
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => isset($row['distance']) ? $row['distance'] : null,
|
||||
'Status' => '1',
|
||||
'Weight' => null,
|
||||
'Remark' => null,
|
||||
'UpdateTime' => null,
|
||||
];
|
||||
}
|
||||
if(!empty($SubDomain)){
|
||||
$list = array_values(array_filter($list, function($v) use ($SubDomain){
|
||||
return $v['Name'] == $SubDomain;
|
||||
}));
|
||||
}else{
|
||||
if(!empty($KeyWord)){
|
||||
$list = array_values(array_filter($list, function($v) use ($KeyWord){
|
||||
return strpos($v['Name'], $KeyWord) !== false || strpos($v['Value'], $KeyWord) !== false;
|
||||
}));
|
||||
}
|
||||
if(!empty($Value)){
|
||||
$list = array_values(array_filter($list, function($v) use ($Value){
|
||||
return $v['Value'] == $Value;
|
||||
}));
|
||||
}
|
||||
if(!empty($Type)){
|
||||
$list = array_values(array_filter($list, function($v) use ($Type){
|
||||
return $v['Type'] == $Type;
|
||||
}));
|
||||
}
|
||||
}
|
||||
return ['total' => count($data['resource_record']), 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['domain' => $this->domain, 'rrtype' => $Type, 'rrhost' => $Name, 'rrvalue' => $Value, 'rrttl' => $TTL];
|
||||
if ($Type == 'MX') $param['rrdistance'] = intval($MX);
|
||||
$data = $this->send_reuqest('dnsAddRecord', $param);
|
||||
return is_array($data) ? $data['record_id'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['domain' => $this->domain, 'rrid' => $RecordId, 'rrtype' => $Type, 'rrhost' => $Name, 'rrvalue' => $Value, 'rrttl' => $TTL];
|
||||
if ($Type == 'MX') $param['rrdistance'] = intval($MX);
|
||||
$data = $this->send_reuqest('dnsUpdateRecord', $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$param = ['domain' => $this->domain, 'rrid' => $RecordId];
|
||||
$data = $this->send_reuqest('dnsDeleteRecord', $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
return ['default' => ['name' => '默认', 'parent' => null]];
|
||||
}
|
||||
|
||||
//获取域名信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function send_reuqest($operation, $param = null)
|
||||
{
|
||||
$url = $this->baseUrl . $operation;
|
||||
|
||||
$params = [
|
||||
'version' => $this->version,
|
||||
'type' => 'json',
|
||||
'key' => $this->apikey,
|
||||
];
|
||||
if($param){
|
||||
$params = array_merge($params, $param);
|
||||
}
|
||||
|
||||
$url .= '?' . http_build_query($params);
|
||||
|
||||
try{
|
||||
$response = curl_client($url);
|
||||
}catch(Exception $e){
|
||||
$this->setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
$arr = json_decode($response['body'], true);
|
||||
if (isset($arr['reply']['code'])) {
|
||||
if ($arr['reply']['code'] == 300) {
|
||||
return $arr['reply'];
|
||||
} else {
|
||||
$this->setError(isset($arr['reply']['detail']) ? $arr['reply']['detail'] : '未知错误');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->setError($response['body']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\dns;
|
||||
|
||||
use app\lib\DnsInterface;
|
||||
@@ -6,204 +7,225 @@ use app\lib\DnsInterface;
|
||||
/**
|
||||
* @see http://apipost.west.cn/
|
||||
*/
|
||||
class west implements DnsInterface {
|
||||
private $username;
|
||||
private $api_password;
|
||||
private $baseUrl = 'https://api.west.cn/api/v2';
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
class west implements DnsInterface
|
||||
{
|
||||
private $username;
|
||||
private $api_password;
|
||||
private $baseUrl = 'https://api.west.cn/api/v2';
|
||||
private $error;
|
||||
private $domain;
|
||||
private $domainid;
|
||||
|
||||
function __construct($config){
|
||||
$this->username = $config['ak'];
|
||||
$this->api_password = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->username = $config['ak'];
|
||||
$this->api_password = $config['sk'];
|
||||
$this->domain = $config['domain'];
|
||||
}
|
||||
|
||||
public function getError(){
|
||||
return $this->error;
|
||||
}
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function check(){
|
||||
if($this->getDomainList() != false){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function check()
|
||||
{
|
||||
if ($this->getDomainList() != false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
|
||||
$param = ['act' => 'getdomains', 'page' => $PageNumber, 'limit' => $PageSize, 'domain' => $KeyWord];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['items'] as $row){
|
||||
$list[] = [
|
||||
'DomainId' => $row['domain'],
|
||||
'Domain' => $row['domain'],
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取域名列表
|
||||
public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
|
||||
{
|
||||
$param = ['act' => 'getdomains', 'page' => $PageNumber, 'limit' => $PageSize, 'domain' => $KeyWord];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['items'] as $row) {
|
||||
$list[] = [
|
||||
'DomainId' => $row['domain'],
|
||||
'Domain' => $row['domain'],
|
||||
'RecordCount' => 0,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){
|
||||
$param = ['act' => 'getdnsrecord', 'domain' => $this->domain, 'type' => $Type, 'line' => $Line, 'host' => $KeyWord, 'pageno' => $PageNumber, 'limit' => $PageSize];
|
||||
if(!isNullOrEmpty(($SubDomain))){
|
||||
$param['host'] = $SubDomain;
|
||||
}
|
||||
$data = $this->execute('/domain/', $param);
|
||||
if($data){
|
||||
$list = [];
|
||||
foreach($data['items'] as $row){
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['item'],
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['value'],
|
||||
'Line' => $row['line'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => $row['level'],
|
||||
'Status' => $row['pause'] == 1 ? '0' : '1',
|
||||
'Weight' => null,
|
||||
'Remark' => null,
|
||||
'UpdateTime' => null,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//获取解析记录列表
|
||||
public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
|
||||
{
|
||||
$param = ['act' => 'getdnsrecord', 'domain' => $this->domain, 'type' => $Type, 'line' => $Line, 'host' => $KeyWord, 'value' => $Value, 'pageno' => $PageNumber, 'limit' => $PageSize];
|
||||
if (!isNullOrEmpty(($SubDomain))) {
|
||||
$param['host'] = $SubDomain;
|
||||
}
|
||||
$data = $this->execute('/domain/', $param);
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data['items'] as $row) {
|
||||
$list[] = [
|
||||
'RecordId' => $row['id'],
|
||||
'Domain' => $this->domain,
|
||||
'Name' => $row['item'],
|
||||
'Type' => $row['type'],
|
||||
'Value' => $row['value'],
|
||||
'Line' => $row['line'],
|
||||
'TTL' => $row['ttl'],
|
||||
'MX' => $row['level'],
|
||||
'Status' => $row['pause'] == 1 ? '0' : '1',
|
||||
'Weight' => null,
|
||||
'Remark' => null,
|
||||
'UpdateTime' => null,
|
||||
];
|
||||
}
|
||||
return ['total' => $data['total'], 'list' => $list];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
|
||||
if($SubDomain == '')$SubDomain='@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, $Type, $Line);
|
||||
}
|
||||
//获取子域名解析记录列表
|
||||
public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
|
||||
{
|
||||
if ($SubDomain == '') $SubDomain = '@';
|
||||
return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
|
||||
}
|
||||
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId){
|
||||
return false;
|
||||
}
|
||||
//获取解析记录详细信息
|
||||
public function getDomainRecordInfo($RecordId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$param = ['act' => 'adddnsrecord', 'domain' => $this->domain, 'host' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return is_array($data) ? $data['id'] : false;
|
||||
}
|
||||
//添加解析记录
|
||||
public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['act' => 'adddnsrecord', 'domain' => $this->domain, 'host' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return is_array($data) ? $data['id'] : false;
|
||||
}
|
||||
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){
|
||||
$param = ['act' => 'moddnsrecord', 'domain' => $this->domain, 'id' => $RecordId, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return is_array($data);
|
||||
}
|
||||
//修改解析记录
|
||||
public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
|
||||
{
|
||||
$param = ['act' => 'moddnsrecord', 'domain' => $this->domain, 'id' => $RecordId, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark){
|
||||
return false;
|
||||
}
|
||||
//修改解析记录备注
|
||||
public function updateDomainRecordRemark($RecordId, $Remark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId){
|
||||
$param = ['act' => 'deldnsrecord', 'domain' => $this->domain, 'id' => $RecordId];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return is_array($data);
|
||||
}
|
||||
//删除解析记录
|
||||
public function deleteDomainRecord($RecordId)
|
||||
{
|
||||
$param = ['act' => 'deldnsrecord', 'domain' => $this->domain, 'id' => $RecordId];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return is_array($data);
|
||||
}
|
||||
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status){
|
||||
$param = ['act' => 'pause', 'domain' => $this->domain, 'id' => $RecordId, 'val' => $Status == '1' ? '0' : '1'];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return $data !== false;
|
||||
}
|
||||
//设置解析记录状态
|
||||
public function setDomainRecordStatus($RecordId, $Status)
|
||||
{
|
||||
$param = ['act' => 'pause', 'domain' => $this->domain, 'id' => $RecordId, 'val' => $Status == '1' ? '0' : '1'];
|
||||
$data = $this->execute('/domain/', $param);
|
||||
return $data !== false;
|
||||
}
|
||||
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
|
||||
return false;
|
||||
}
|
||||
//获取解析记录操作日志
|
||||
public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取解析线路列表
|
||||
public function getRecordLine(){
|
||||
return [
|
||||
''=>['name'=>'默认', 'parent'=>null],
|
||||
'LTEL'=>['name'=>'电信', 'parent'=>null],
|
||||
'LCNC'=>['name'=>'联通', 'parent'=>null],
|
||||
'LMOB'=>['name'=>'移动', 'parent'=>null],
|
||||
'LEDU'=>['name'=>'教育网', 'parent'=>null],
|
||||
'LSEO'=>['name'=>'搜索引擎', 'parent'=>null],
|
||||
'LFOR'=>['name'=>'境外', 'parent'=>null],
|
||||
];
|
||||
}
|
||||
//获取解析线路列表
|
||||
public function getRecordLine()
|
||||
{
|
||||
return [
|
||||
'' => ['name' => '默认', 'parent' => null],
|
||||
'LTEL' => ['name' => '电信', 'parent' => null],
|
||||
'LCNC' => ['name' => '联通', 'parent' => null],
|
||||
'LMOB' => ['name' => '移动', 'parent' => null],
|
||||
'LEDU' => ['name' => '教育网', 'parent' => null],
|
||||
'LSEO' => ['name' => '搜索引擎', 'parent' => null],
|
||||
'LFOR' => ['name' => '境外', 'parent' => null],
|
||||
];
|
||||
}
|
||||
|
||||
//获取域名信息
|
||||
public function getDomainInfo(){
|
||||
return false;
|
||||
}
|
||||
//获取域名信息
|
||||
public function getDomainInfo()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL(){
|
||||
return false;
|
||||
}
|
||||
//获取域名最低TTL
|
||||
public function getMinTTL()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertType($type){
|
||||
return $type;
|
||||
}
|
||||
private function convertType($type)
|
||||
{
|
||||
return $type;
|
||||
}
|
||||
|
||||
private function execute($path, $params){
|
||||
$params['username'] = $this->username;
|
||||
$params['time'] = $this->getMillisecond();
|
||||
$params['token'] = md5($this->username.$this->api_password.$params['time']);
|
||||
$response = $this->curl($path, $params);
|
||||
$response = mb_convert_encoding($response, 'UTF-8', 'GBK');
|
||||
$arr=json_decode($response,true);
|
||||
if($arr){
|
||||
if($arr['result'] == 200){
|
||||
return isset($arr['data']) ? $arr['data'] : [];
|
||||
}else{
|
||||
$this->setError($arr['msg']);
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private function execute($path, $params)
|
||||
{
|
||||
$params['username'] = $this->username;
|
||||
$params['time'] = $this->getMillisecond();
|
||||
$params['token'] = md5($this->username.$this->api_password.$params['time']);
|
||||
$response = $this->curl($path, $params);
|
||||
$response = mb_convert_encoding($response, 'UTF-8', 'GBK');
|
||||
$arr = json_decode($response, true);
|
||||
if ($arr) {
|
||||
if ($arr['result'] == 200) {
|
||||
return isset($arr['data']) ? $arr['data'] : [];
|
||||
} else {
|
||||
$this->setError($arr['msg']);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->setError('返回数据解析失败');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function curl($path, $params = null){
|
||||
$url = $this->baseUrl . $path;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
if ($params) {
|
||||
private function curl($path, $params = null)
|
||||
{
|
||||
$url = $this->baseUrl . $path;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
if ($params) {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
return $response;
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
if ($errno) {
|
||||
$this->setError('Curl error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if ($errno) return false;
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function getMillisecond()
|
||||
private function getMillisecond()
|
||||
{
|
||||
list($s1, $s2) = explode(' ', microtime());
|
||||
return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
|
||||
}
|
||||
|
||||
private function setError($message){
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
private function setError($message)
|
||||
{
|
||||
$this->error = $message;
|
||||
//file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\mail;
|
||||
|
||||
class Aliyun
|
||||
{
|
||||
private $AccessKeyId;
|
||||
private $AccessKeySecret;
|
||||
private $AccessKeyId;
|
||||
private $AccessKeySecret;
|
||||
|
||||
function __construct($AccessKeyId, $AccessKeySecret)
|
||||
{
|
||||
$this->AccessKeyId = $AccessKeyId;
|
||||
$this->AccessKeySecret = $AccessKeySecret;
|
||||
}
|
||||
private function aliyunSignature($parameters, $accessKeySecret, $method)
|
||||
{
|
||||
ksort($parameters);
|
||||
$canonicalizedQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
if($value === null) continue;
|
||||
$canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
|
||||
}
|
||||
$stringToSign = $method . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
|
||||
$signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&", true));
|
||||
public function __construct($AccessKeyId, $AccessKeySecret)
|
||||
{
|
||||
$this->AccessKeyId = $AccessKeyId;
|
||||
$this->AccessKeySecret = $AccessKeySecret;
|
||||
}
|
||||
private function aliyunSignature($parameters, $accessKeySecret, $method)
|
||||
{
|
||||
ksort($parameters);
|
||||
$canonicalizedQueryString = '';
|
||||
foreach ($parameters as $key => $value) {
|
||||
if ($value === null) continue;
|
||||
$canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
|
||||
}
|
||||
$stringToSign = $method . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
|
||||
$signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&", true));
|
||||
|
||||
return $signature;
|
||||
}
|
||||
private function percentEncode($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
public function send($to, $sub, $msg, $from, $from_name)
|
||||
{
|
||||
if (empty($this->AccessKeyId) || empty($this->AccessKeySecret)) return false;
|
||||
$url = 'https://dm.aliyuncs.com/';
|
||||
$data = array(
|
||||
'Action' => 'SingleSendMail',
|
||||
'AccountName' => $from,
|
||||
'ReplyToAddress' => 'false',
|
||||
'AddressType' => 1,
|
||||
'ToAddress' => $to,
|
||||
'FromAlias' => $from_name,
|
||||
'Subject' => $sub,
|
||||
'HtmlBody' => $msg,
|
||||
'Format' => 'JSON',
|
||||
'Version' => '2015-11-23',
|
||||
'AccessKeyId' => $this->AccessKeyId,
|
||||
'SignatureMethod' => 'HMAC-SHA1',
|
||||
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
|
||||
'SignatureVersion' => '1.0',
|
||||
'SignatureNonce' => random(8)
|
||||
);
|
||||
$data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
$json = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
$arr = json_decode($json, true);
|
||||
if ($httpCode == 200) {
|
||||
return true;
|
||||
} else {
|
||||
return $arr['Message'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $signature;
|
||||
}
|
||||
private function percentEncode($str)
|
||||
{
|
||||
$search = ['+', '*', '%7E'];
|
||||
$replace = ['%20', '%2A', '~'];
|
||||
return str_replace($search, $replace, urlencode($str));
|
||||
}
|
||||
public function send($to, $sub, $msg, $from, $from_name)
|
||||
{
|
||||
if (empty($this->AccessKeyId) || empty($this->AccessKeySecret)) return false;
|
||||
$url = 'https://dm.aliyuncs.com/';
|
||||
$data = array(
|
||||
'Action' => 'SingleSendMail',
|
||||
'AccountName' => $from,
|
||||
'ReplyToAddress' => 'false',
|
||||
'AddressType' => 1,
|
||||
'ToAddress' => $to,
|
||||
'FromAlias' => $from_name,
|
||||
'Subject' => $sub,
|
||||
'HtmlBody' => $msg,
|
||||
'Format' => 'JSON',
|
||||
'Version' => '2015-11-23',
|
||||
'AccessKeyId' => $this->AccessKeyId,
|
||||
'SignatureMethod' => 'HMAC-SHA1',
|
||||
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
|
||||
'SignatureVersion' => '1.0',
|
||||
'SignatureNonce' => random(8)
|
||||
);
|
||||
$data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
$json = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
$arr = json_decode($json, true);
|
||||
if ($httpCode == 200) {
|
||||
return true;
|
||||
} else {
|
||||
return $arr['Message'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\mail;
|
||||
|
||||
class Sendcloud {
|
||||
private $apiUser;
|
||||
private $apiKey;
|
||||
class Sendcloud
|
||||
{
|
||||
private $apiUser;
|
||||
private $apiKey;
|
||||
|
||||
function __construct($apiUser, $apiKey){
|
||||
public function __construct($apiUser, $apiKey)
|
||||
{
|
||||
$this->apiUser = $apiUser;
|
||||
$this->apiKey = $apiKey;
|
||||
}
|
||||
public function send($to, $sub, $msg, $from, $from_name){
|
||||
if(empty($this->apiUser)||empty($this->apiKey))return false;
|
||||
$url='http://api.sendcloud.net/apiv2/mail/send';
|
||||
$data=array(
|
||||
'apiUser' => $this->apiUser,
|
||||
'apiKey' => $this->apiKey,
|
||||
'from' => $from,
|
||||
'fromName' => $from_name,
|
||||
'to' => $to,
|
||||
'subject' => $sub,
|
||||
'html' => $msg);
|
||||
$ch=curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$json=curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$arr=json_decode($json,true);
|
||||
if($arr['statusCode']==200){
|
||||
return true;
|
||||
}else{
|
||||
return implode("\n",$arr['message']);
|
||||
}
|
||||
}
|
||||
public function send($to, $sub, $msg, $from, $from_name)
|
||||
{
|
||||
if (empty($this->apiUser) || empty($this->apiKey)) return false;
|
||||
$url = 'http://api.sendcloud.net/apiv2/mail/send';
|
||||
$data = array(
|
||||
'apiUser' => $this->apiUser,
|
||||
'apiKey' => $this->apiKey,
|
||||
'from' => $from,
|
||||
'fromName' => $from_name,
|
||||
'to' => $to,
|
||||
'subject' => $sub,
|
||||
'html' => $msg
|
||||
);
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$json = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$arr = json_decode($json, true);
|
||||
if ($arr['statusCode'] == 200) {
|
||||
return true;
|
||||
} else {
|
||||
return implode("\n", $arr['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
@@ -12,23 +13,29 @@ class AuthApi
|
||||
$uid = input('post.uid/d');
|
||||
$timestamp = input('post.timestamp');
|
||||
$sign = input('post.sign');
|
||||
if(!$uid || empty($timestamp) || empty($sign)){
|
||||
return json(['code'=>-1, 'msg'=>'认证参数不能为空'])->code(403);
|
||||
if (!$uid || empty($timestamp) || empty($sign)) {
|
||||
return json(['code' => -1, 'msg' => '认证参数不能为空'])->code(403);
|
||||
}
|
||||
if($timestamp < time()-300 || $timestamp > time()+300){
|
||||
return json(['code'=>-1, 'msg'=>'时间戳不合法'])->code(403);
|
||||
if ($timestamp < time() - 300 || $timestamp > time() + 300) {
|
||||
return json(['code' => -1, 'msg' => '时间戳不合法'])->code(403);
|
||||
}
|
||||
$user = Db::name('user')->where('id', $uid)->find();
|
||||
if(!$user) return json(['code'=>-1, 'msg'=>'用户不存在'])->code(403);
|
||||
if($user['status'] == 0) return json(['code'=>-1, 'msg'=>'该用户已被封禁'])->code(403);
|
||||
if($user['is_api'] == 0) return json(['code'=>-1, 'msg'=>'该用户未开启API权限'])->code(403);
|
||||
if(md5($uid.$timestamp.$user['apikey']) !== $sign){
|
||||
return json(['code'=>-1, 'msg'=>'签名错误'])->code(403);
|
||||
if (!$user) {
|
||||
return json(['code' => -1, 'msg' => '用户不存在'])->code(403);
|
||||
}
|
||||
if ($user['status'] == 0) {
|
||||
return json(['code' => -1, 'msg' => '该用户已被封禁'])->code(403);
|
||||
}
|
||||
if ($user['is_api'] == 0) {
|
||||
return json(['code' => -1, 'msg' => '该用户未开启API权限'])->code(403);
|
||||
}
|
||||
if (md5($uid.$timestamp.$user['apikey']) !== $sign) {
|
||||
return json(['code' => -1, 'msg' => '签名错误'])->code(403);
|
||||
}
|
||||
|
||||
$user['type'] = 'user';
|
||||
$user['permission'] = [];
|
||||
if($user['level'] == 1){
|
||||
if ($user['level'] == 1) {
|
||||
$user['permission'] = Db::name('permission')->where('uid', $uid)->column('domain');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
@@ -12,28 +13,28 @@ class AuthUser
|
||||
$islogin = false;
|
||||
$cookie = cookie('user_token');
|
||||
$user = null;
|
||||
if($cookie){
|
||||
$token=authcode($cookie, 'DECODE', env('app.sys_key'));
|
||||
if($token){
|
||||
if ($cookie && config_get('sys_key')) {
|
||||
$token = authcode($cookie, 'DECODE', config_get('sys_key'));
|
||||
if ($token) {
|
||||
list($type, $uid, $sid, $expiretime) = explode("\t", $token);
|
||||
if($type == 'user'){
|
||||
if ($type == 'user') {
|
||||
$user = Db::name('user')->where('id', $uid)->find();
|
||||
if($user && $user['status']==1){
|
||||
$session=md5($user['id'].$user['password']);
|
||||
if($session==$sid && $expiretime>time()) {
|
||||
if ($user && $user['status'] == 1) {
|
||||
$session = md5($user['id'].$user['password']);
|
||||
if ($session == $sid && $expiretime > time()) {
|
||||
$islogin = true;
|
||||
}
|
||||
$user['type'] = 'user';
|
||||
$user['permission'] = [];
|
||||
if($user['level'] == 1){
|
||||
if ($user['level'] == 1) {
|
||||
$user['permission'] = Db::name('permission')->where('uid', $uid)->column('domain');
|
||||
}
|
||||
}
|
||||
}elseif($type == 'domain'){
|
||||
} elseif ($type == 'domain') {
|
||||
$user = Db::name('domain')->where('id', $uid)->find();
|
||||
if($user && $user['is_sso']==1){
|
||||
$session=md5($user['id'].$user['name']);
|
||||
if($session==$sid && $expiretime>time()) {
|
||||
if ($user && $user['is_sso'] == 1) {
|
||||
$session = md5($user['id'].$user['name']);
|
||||
if ($session == $sid && $expiretime > time()) {
|
||||
$islogin = true;
|
||||
}
|
||||
$user['username'] = $user['name'];
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
|
||||
class CheckLogin
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if (!request()->islogin) {
|
||||
if (!$request->islogin) {
|
||||
if ($request->isAjax() || !$request->isGet()) {
|
||||
return json(['code'=>-1, 'msg'=>'未登录'])->code(401);
|
||||
return json(['code' => -1, 'msg' => '未登录'])->code(401);
|
||||
}
|
||||
return redirect((string)url('/login'));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use Exception;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use think\facade\Cache;
|
||||
|
||||
class LoadConfig
|
||||
{
|
||||
@@ -18,22 +20,27 @@ class LoadConfig
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if (!file_exists(app()->getRootPath().'.env')){
|
||||
if(strpos(request()->url(),'/install')===false){
|
||||
if (!file_exists(app()->getRootPath().'.env')) {
|
||||
if (strpos($this->request->url(), '/install') === false) {
|
||||
return redirect((string)url('/install'))->header([
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate',
|
||||
'Pragma' => 'no-cache',
|
||||
]);
|
||||
}else{
|
||||
} else {
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
$res = Db::name('config')->cache('configs',0)->column('value','key');
|
||||
|
||||
try {
|
||||
$res = Db::name('config')->cache('configs', 0)->column('value', 'key');
|
||||
if (empty($res['sys_key']) && !empty(env('app.sys_key'))) {
|
||||
config_set('sys_key', env('app.sys_key'));
|
||||
Cache::delete('configs');
|
||||
$res['sys_key'] = env('app.sys_key');
|
||||
}
|
||||
Config::set($res, 'sys');
|
||||
}catch(Exception $e){
|
||||
if(!strpos($e->getMessage(), 'doesn\'t exist')){
|
||||
} catch (Exception $e) {
|
||||
if (!strpos($e->getMessage(), 'doesn\'t exist')) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
@@ -16,7 +17,7 @@ class RefererCheck
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if(!checkRefererHost()){
|
||||
if (!checkRefererHost()) {
|
||||
return response('Access Denied', 403);
|
||||
}
|
||||
return $next($request);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
@@ -18,7 +19,7 @@ class ViewOutput
|
||||
{
|
||||
View::assign('islogin', $request->islogin);
|
||||
View::assign('user', $request->user);
|
||||
View::assign('cdnpublic', '//lib.baomitu.com/');
|
||||
View::assign('cdnpublic', 'https://s4.zstatic.net/ajax/libs/');
|
||||
View::assign('skin', getAdminSkin());
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ CREATE TABLE `dnsmgr_config` (
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
INSERT INTO `dnsmgr_config` VALUES ('version', '1003');
|
||||
INSERT INTO `dnsmgr_config` VALUES ('version', '1011');
|
||||
INSERT INTO `dnsmgr_config` VALUES ('notice_mail', '0');
|
||||
INSERT INTO `dnsmgr_config` VALUES ('notice_wxtpl', '0');
|
||||
INSERT INTO `dnsmgr_config` VALUES ('mail_smtp', 'smtp.qq.com');
|
||||
@@ -33,6 +33,7 @@ CREATE TABLE `dnsmgr_domain` (
|
||||
`is_hide` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`is_sso` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`recordcount` int(1) NOT NULL DEFAULT '0',
|
||||
`remark` varchar(100) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -64,7 +65,7 @@ CREATE TABLE `dnsmgr_permission` (
|
||||
|
||||
DROP TABLE IF EXISTS `dnsmgr_log`;
|
||||
CREATE TABLE `dnsmgr_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uid` int(11) unsigned NOT NULL,
|
||||
`action` varchar(40) NOT NULL,
|
||||
`domain` varchar(128) NOT NULL DEFAULT '',
|
||||
@@ -77,7 +78,7 @@ CREATE TABLE `dnsmgr_log` (
|
||||
|
||||
DROP TABLE IF EXISTS `dnsmgr_dmtask`;
|
||||
CREATE TABLE `dnsmgr_dmtask` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`did` int(11) unsigned NOT NULL,
|
||||
`rr` varchar(128) NOT NULL,
|
||||
`recordid` varchar(60) NOT NULL,
|
||||
@@ -91,6 +92,7 @@ CREATE TABLE `dnsmgr_dmtask` (
|
||||
`cycle` tinyint(5) NOT NULL DEFAULT 3,
|
||||
`timeout` tinyint(5) NOT NULL DEFAULT 2,
|
||||
`remark` varchar(100) DEFAULT NULL,
|
||||
`proxy` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`addtime` int(11) NOT NULL DEFAULT 0,
|
||||
`checktime` int(11) NOT NULL DEFAULT 0,
|
||||
`checknexttime` int(11) NOT NULL DEFAULT 0,
|
||||
@@ -105,7 +107,7 @@ CREATE TABLE `dnsmgr_dmtask` (
|
||||
|
||||
DROP TABLE IF EXISTS `dnsmgr_dmlog`;
|
||||
CREATE TABLE `dnsmgr_dmlog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`taskid` int(11) unsigned NOT NULL,
|
||||
`action` tinyint(4) NOT NULL DEFAULT 0,
|
||||
`errmsg` varchar(100) DEFAULT NULL,
|
||||
@@ -113,4 +115,24 @@ CREATE TABLE `dnsmgr_dmlog` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `taskid` (`taskid`),
|
||||
KEY `date` (`date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
DROP TABLE IF EXISTS `dnsmgr_optimizeip`;
|
||||
CREATE TABLE `dnsmgr_optimizeip` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`did` int(11) unsigned NOT NULL,
|
||||
`rr` varchar(128) NOT NULL,
|
||||
`type` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`ip_type` varchar(10) NOT NULL,
|
||||
`cdn_type` tinyint(5) NOT NULL DEFAULT 1,
|
||||
`recordnum` tinyint(5) NOT NULL DEFAULT 2,
|
||||
`ttl` int(5) NOT NULL DEFAULT 600,
|
||||
`remark` varchar(100) DEFAULT NULL,
|
||||
`addtime` datetime NOT NULL,
|
||||
`updatetime` datetime DEFAULT NULL,
|
||||
`status` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`errmsg` varchar(100) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `did` (`did`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS `dnsmgr_config` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `dnsmgr_dmtask` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`did` int(11) unsigned NOT NULL,
|
||||
`rr` varchar(128) NOT NULL,
|
||||
`recordid` varchar(60) NOT NULL,
|
||||
@@ -32,7 +32,7 @@ CREATE TABLE IF NOT EXISTS `dnsmgr_dmtask` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `dnsmgr_dmlog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`taskid` int(11) unsigned NOT NULL,
|
||||
`action` tinyint(4) NOT NULL DEFAULT 0,
|
||||
`errmsg` varchar(100) DEFAULT NULL,
|
||||
@@ -40,4 +40,29 @@ CREATE TABLE IF NOT EXISTS `dnsmgr_dmlog` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `taskid` (`taskid`),
|
||||
KEY `date` (`date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `dnsmgr_optimizeip` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`did` int(11) unsigned NOT NULL,
|
||||
`rr` varchar(128) NOT NULL,
|
||||
`type` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`ip_type` varchar(10) NOT NULL,
|
||||
`cdn_type` tinyint(5) NOT NULL DEFAULT 1,
|
||||
`recordnum` tinyint(5) NOT NULL DEFAULT 2,
|
||||
`ttl` int(5) NOT NULL DEFAULT 600,
|
||||
`remark` varchar(100) DEFAULT NULL,
|
||||
`addtime` datetime NOT NULL,
|
||||
`updatetime` datetime DEFAULT NULL,
|
||||
`status` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`errmsg` varchar(100) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `did` (`did`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
ALTER TABLE `dnsmgr_domain`
|
||||
ADD COLUMN `remark` varchar(100) DEFAULT NULL;
|
||||
|
||||
ALTER TABLE `dnsmgr_dmtask`
|
||||
ADD COLUMN `proxy` tinyint(1) NOT NULL DEFAULT 0;
|
||||
@@ -56,7 +56,7 @@ a{color:#444}
|
||||
<div class="input-group-addon"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span></div>
|
||||
<input type="text" class="form-control input-lg" placeholder="验证码" name="code" autocomplete="off" required="required"/>
|
||||
<span class="input-group-addon" style="padding: 0">
|
||||
<img id="verifycode" src="/verifycode" height="45" onclick="this.src='/verifycode?r='+Math.random();" title="点击更换验证码">
|
||||
<img id="verifycode" src="{:captcha_src()}" height="45" onclick="this.src='{:captcha_src()}?r='+Math.random();" title="点击更换验证码">
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -103,11 +103,11 @@
|
||||
{if request()->user['type'] eq 'user'}<li class="{:checkIfActive('index')}">
|
||||
<a href="/"><i class="fa fa-home fa-fw"></i> <span>后台首页</span></a>
|
||||
</li>{/if}
|
||||
<li class="{:checkIfActive('domain,record,record_log')}">
|
||||
<li class="{:checkIfActive('domain,record,record_log,record_batch_add')}">
|
||||
<a href="/domain"><i class="fa fa-list-ul fa-fw"></i> <span>域名管理</span></a>
|
||||
</li>
|
||||
{if request()->user['level'] eq 2}
|
||||
<li class="treeview {:checkIfActive('overview,task,noticeset,taskinfo,taskform')}">
|
||||
<li class="treeview {:checkIfActive('overview,task,noticeset,taskinfo,taskform,proxyset')}">
|
||||
<a href="javascript:;">
|
||||
<i class="fa fa-heartbeat fa-fw"></i>
|
||||
<span>容灾切换</span>
|
||||
@@ -119,6 +119,20 @@
|
||||
<li><a href="/dmonitor/overview"><i class="fa fa-circle-o"></i> 运行概览</a></li>
|
||||
<li><a href="/dmonitor/task"><i class="fa fa-circle-o"></i> 切换策略</a></li>
|
||||
<li><a href="/dmonitor/noticeset"><i class="fa fa-circle-o"></i> 通知设置</a></li>
|
||||
<li><a href="/dmonitor/proxyset"><i class="fa fa-circle-o"></i> 代理设置</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="treeview {:checkIfActive('opipset,opiplist,opipform')}">
|
||||
<a href="javascript:;">
|
||||
<i class="fa fa-globe fa-fw"></i>
|
||||
<span>CF优选IP</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li><a href="/optimizeip/opipset"><i class="fa fa-circle-o"></i> 优选设置</a></li>
|
||||
<li><a href="/optimizeip/opiplist"><i class="fa fa-circle-o"></i> 任务管理</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="{:checkIfActive('account')}">
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
<label class="col-sm-3 control-label">微信公众号通知</label>
|
||||
<div class="col-sm-9"><select class="form-control" name="notice_wxtpl" default="{:config_get('notice_wxtpl')}"><option value="0">关闭</option><option value="1">开启</option></select></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Telegram机器人通知</label>
|
||||
<div class="col-sm-9"><select class="form-control" name="notice_tgbot" default="{:config_get('notice_tgbot')}"><option value="0">关闭</option><option value="1">开启</option></select></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-9"><input type="submit" name="submit" value="保存" class="btn btn-primary btn-block"/></div>
|
||||
</div>
|
||||
@@ -99,6 +103,34 @@
|
||||
<b>WxPusher:</b><a href="https://wxpusher.zjiecode.com/admin/" target="_blank" rel="noopener noreferrer">点此进入</a> ,注册并且创建应用 -> 将appToken填写到上方输入框 -> 扫码关注应用 -> 在用户列表查看自己的UID填写到上方输入框<br/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading"><h3 class="panel-title">Telegram机器人接口设置</h3></div>
|
||||
<div class="panel-body">
|
||||
<form onsubmit="return saveSetting(this)" method="post" class="form-horizontal" role="form">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Token</label>
|
||||
<div class="col-sm-9"><input type="text" name="tgbot_token" value="{:config_get('tgbot_token')}" class="form-control"/></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Chat Id</label>
|
||||
<div class="col-sm-9"><input type="text" name="tgbot_chatid" value="{:config_get('tgbot_chatid')}" class="form-control"/></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">使用代理服务器</label>
|
||||
<div class="col-sm-9"><select class="form-control" name="tgbot_proxy" default="{:config_get('tgbot_proxy')}"><option value="0">否</option><option value="1">是</option></select></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-9">
|
||||
<input type="submit" name="submit" value="保存" class="btn btn-primary btn-block"/>
|
||||
<a href="javascript:tgbottest()" class="btn btn-default btn-block">发送测试消息</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
与<a href="https://t.me/BotFather" target="_blank" rel="noopener noreferrer">@BotFather</a>对话,使用/newbot命令创建一个新的机器人,根据提示输入机器人的名称和用户名,可得到Token,或使用/mybots命令查看已创建的机器人;与<a href="https://t.me/getmyid_bot" target="_blank" rel="noopener noreferrer">@getmyid_bot</a>对话,可得到Chat Id<br/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
@@ -129,7 +161,7 @@ function saveSetting(obj){
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert('设置保存成功!', {
|
||||
layer.alert('设置保存成功!<br/>重启检测进程或容器后生效', {
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
@@ -166,5 +198,25 @@ function mailtest(){
|
||||
}
|
||||
});
|
||||
}
|
||||
function tgbottest(){
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'GET',
|
||||
url : '/dmonitor/tgbottest',
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
110
app/view/dmonitor/proxyset.html
Normal file
110
app/view/dmonitor/proxyset.html
Normal file
@@ -0,0 +1,110 @@
|
||||
{extend name="common/layout" /}
|
||||
{block name="title"}容灾切换代理设置{/block}
|
||||
{block name="main"}
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-8 col-lg-6 center-block" style="float: none;">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading"><h3 class="panel-title">代理服务器设置</h3></div>
|
||||
<div class="panel-body">
|
||||
<form onsubmit="return saveSetting(this)" method="post" class="form-horizontal" role="form">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">代理IP</label>
|
||||
<div class="col-sm-9"><input type="text" name="proxy_server" value="{:config_get('proxy_server')}" class="form-control"/></div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">代理端口</label>
|
||||
<div class="col-sm-9"><input type="text" name="proxy_port" value="{:config_get('proxy_port')}" class="form-control"/></div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">代理账号</label>
|
||||
<div class="col-sm-9"><input type="text" name="proxy_user" value="{:config_get('proxy_user')}" class="form-control" placeholder="没有请留空"/></div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">代理密码</label>
|
||||
<div class="col-sm-9"><input type="text" name="proxy_pwd" value="{:config_get('proxy_pwd')}" class="form-control" placeholder="没有请留空"/></div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">代理协议</label>
|
||||
<div class="col-sm-9"><select class="form-control" name="proxy_type" default="{:config_get('proxy_type')}">
|
||||
<option value="http">HTTP</option>
|
||||
<option value="https">HTTPS</option>
|
||||
<option value="sock4">SOCK4</option>
|
||||
<option value="sock5">SOCK5</option>
|
||||
</select></div>
|
||||
</div><br/>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-9"><input type="submit" name="submit" value="保存" class="btn btn-primary btn-block"/><br/>
|
||||
<a href="javascript:proxytest()" class="btn btn-default btn-block">测试连通性</a></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script>
|
||||
var items = $("select[default]");
|
||||
for (i = 0; i < items.length; i++) {
|
||||
$(items[i]).val($(items[i]).attr("default")||0);
|
||||
}
|
||||
function saveSetting(obj){
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '',
|
||||
data : $(obj).serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert('设置保存成功!', {
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
window.location.reload()
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
function proxytest(){
|
||||
var proxy_server = $("input[name='proxy_server']").val();
|
||||
var proxy_port = $("input[name='proxy_port']").val();
|
||||
var proxy_user = $("input[name='proxy_user']").val();
|
||||
var proxy_pwd = $("input[name='proxy_pwd']").val();
|
||||
var proxy_type = $("select[name='proxy_type']").val();
|
||||
if(proxy_server=='' || proxy_port==''){
|
||||
layer.alert('代理服务器和端口不能为空!');
|
||||
return false;
|
||||
}
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/dmonitor/proxytest',
|
||||
data : {proxy_server:proxy_server, proxy_port:proxy_port, proxy_user:proxy_user, proxy_pwd:proxy_pwd, proxy_type:proxy_type},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert('连通性测试成功!', {icon: 1})
|
||||
}else{
|
||||
layer.alert('连通性测试失败:'+data.msg, {icon: 2})
|
||||
}
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -33,8 +33,8 @@ tbody tr>td:nth-child(2){overflow: hidden;text-overflow: ellipsis;white-space: n
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
@@ -75,6 +75,8 @@ $(document).ready(function(){
|
||||
return '暂停解析';
|
||||
} else if(value == 2) {
|
||||
return '<span title="" data-toggle="tooltip" data-placement="bottom" data-original-title="备用:'+row.backup_value+'" class="tips">切换备用</span>';
|
||||
} else if(value == 3) {
|
||||
return '<span title="" data-toggle="tooltip" data-placement="bottom" data-original-title="同域名正常数量<='+row.cycle+'" class="tips">条件开启</span>';
|
||||
} else {
|
||||
return '无操作';
|
||||
}
|
||||
@@ -84,11 +86,15 @@ $(document).ready(function(){
|
||||
field: 'frequency',
|
||||
title: '检测间隔',
|
||||
formatter: function(value, row, index) {
|
||||
var checktype = 'PING';
|
||||
if(row.checktype == 2){
|
||||
checktype = row.checkurl;
|
||||
}else if(row.checktype == 1){
|
||||
checktype = 'TCP('+row.tcpport+'端口)';
|
||||
if(row.type <= 2){
|
||||
var checktype = 'PING';
|
||||
if(row.checktype == 2){
|
||||
checktype = row.checkurl;
|
||||
}else if(row.checktype == 1){
|
||||
checktype = 'TCP('+row.tcpport+'端口)';
|
||||
}
|
||||
}else{
|
||||
var checktype = '';
|
||||
}
|
||||
return '<span title="" data-toggle="tooltip" data-placement="bottom" data-original-title="'+checktype+'" class="tips">' + value + '秒</span>';
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
.tips{color: #f6a838; padding-left: 5px;}
|
||||
</style>
|
||||
<div class="row" id="app">
|
||||
<div class="col-xs-12 center-block" style="float: none;">
|
||||
@@ -49,7 +50,7 @@
|
||||
<input type="text" name="backup_value" v-model="set.backup_value" placeholder="支持填写IPv4或CNAME地址" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" v-show="set.type<=2">
|
||||
<label class="col-sm-3 control-label no-padding-right">检测协议</label>
|
||||
<div class="col-sm-6">
|
||||
<label class="radio-inline" v-for="option in checktypeList">
|
||||
@@ -57,19 +58,30 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.checktype==1">
|
||||
<div class="form-group" v-show="set.type<=2&&set.checktype==1">
|
||||
<label class="col-sm-3 control-label no-padding-right">TCP检测端口</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="tcpport" v-model="set.tcpport" placeholder="填写TCP端口号" class="form-control" data-bv-integer="true" min="1" max="65535" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.checktype==2">
|
||||
<div class="form-group" v-show="set.type<=2&&set.checktype==2">
|
||||
<label class="col-sm-3 control-label no-padding-right">检测URL地址</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="checkurl" v-model="set.checkurl" placeholder="填写以http(s)://开头的完整地址,http状态码须为2xx/3xx" class="form-control" data-bv-uri="true" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.checktype>0">
|
||||
<div class="form-group" v-show="set.type<=2&&set.checktype==2">
|
||||
<label class="col-sm-3 control-label no-padding-right">使用代理请求</label>
|
||||
<div class="col-sm-6">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="proxy" value="0" v-model="set.proxy"> 否
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="proxy" value="1" v-model="set.proxy"> 是
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.type<=2&&set.checktype>0">
|
||||
<label class="col-sm-3 control-label no-padding-right">最大超时时间</label>
|
||||
<div class="col-sm-3">
|
||||
<div class="input-group">
|
||||
@@ -78,6 +90,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.type==3">
|
||||
<label class="col-sm-3 control-label no-padding-right">同域名正常数量<span class="tips" title="" data-toggle="tooltip" data-placement="bottom" data-original-title="与暂停解析配合使用,当同域名正常记录数量<=几条时开启解析"><i class="fa fa-question-circle"></i></span></label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" name="cycle" v-model="set.cycle" placeholder="同域名正常记录数量<=几条时开启解析" class="form-control" data-bv-integer="true" min="0" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">检测间隔</label>
|
||||
<div class="col-sm-3">
|
||||
@@ -87,7 +105,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" v-show="set.type<=2">
|
||||
<label class="col-sm-3 control-label no-padding-right">确认次数</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" name="cycle" v-model="set.cycle" placeholder="连续失败几次后进行切换" class="form-control" data-bv-integer="true" min="1" required>
|
||||
@@ -128,18 +146,20 @@ new Vue({
|
||||
main_value: '',
|
||||
type: 1,
|
||||
backup_value: '',
|
||||
checktype: 2,
|
||||
checktype: 1,
|
||||
tcpport: 80,
|
||||
checkurl: '',
|
||||
frequency: 5,
|
||||
timeout: 2,
|
||||
cycle: 3,
|
||||
proxy: 0,
|
||||
},
|
||||
recordList: [],
|
||||
typeList: [
|
||||
{value:0, label:'无操作'},
|
||||
{value:1, label:'暂停解析'},
|
||||
{value:2, label:'切换备用解析'},
|
||||
{value:3, label:'条件开启解析'},
|
||||
],
|
||||
checktypeList: [
|
||||
{value:0, label:'PING', disabled: support_ping=='0'},
|
||||
@@ -169,6 +189,7 @@ new Vue({
|
||||
$("#taskform").bootstrapValidator({
|
||||
live: 'submitted',
|
||||
});
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
},
|
||||
methods: {
|
||||
getRecordList(){
|
||||
|
||||
@@ -30,8 +30,8 @@ tbody tr>td:nth-child(4){overflow: hidden;text-overflow: ellipsis;white-space: n
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
var action_name = {$info.action_name|json_encode|raw};
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
var dnsconfig = {$dnsconfig|json_encode|raw};
|
||||
@@ -198,7 +198,7 @@ function save(){
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store").modal('hide');
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
@@ -220,7 +220,7 @@ function delItem(id) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
|
||||
139
app/view/domain/batchadd.html
Normal file
139
app/view/domain/batchadd.html
Normal file
@@ -0,0 +1,139 @@
|
||||
{extend name="common/layout" /}
|
||||
{block name="title"}批量添加解析 - {$domainName}{/block}
|
||||
{block name="main"}
|
||||
<div class="row" id="app">
|
||||
<div class="col-xs-12 center-block" style="float: none;">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title"><a href="/record/{$domainId}" class="btn btn-sm btn-default pull-right" style="margin-top:-6px"><i class="fa fa-reply fa-fw"></i> 返回</a>批量添加解析 - {$domainName}</h3></div>
|
||||
<div class="panel-body">
|
||||
<form onsubmit="return false" method="post" class="form-horizontal" role="form" id="form-store">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-xs-12 control-label no-padding-right">主机记录&记录值</label>
|
||||
<div class="col-sm-6">
|
||||
<textarea name="record" placeholder="主机记录和记录值用空格隔开,一行一个" class="form-control" rows="8" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">记录类型</label>
|
||||
<div class="col-sm-6">
|
||||
<select name="type" class="form-control">
|
||||
<option value="">A / CNAME / AAAA 自动识别</option>
|
||||
<option value="A">A</option>
|
||||
<option value="CNAME">CNAME</option>
|
||||
<option value="AAAA">AAAA</option>
|
||||
<option value="NS">NS</option>
|
||||
<option value="MX">MX</option>
|
||||
<option value="SRV">SRV</option>
|
||||
<option value="TXT">TXT</option>
|
||||
<option value="CAA">CAA</option>
|
||||
{if $dnsconfig.redirect}<option value="REDIRECT_URL">显性URL</option>
|
||||
<option value="FORWARD_URL">隐性URL</option>{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">线路类型</label>
|
||||
<div class="col-sm-6" id="line_list">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="display:none" id="mx_type">
|
||||
<label class="col-sm-3 control-label no-padding-right">MX优先级</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" name="mx" value="10">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">TTL</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" name="ttl" value="600" placeholder="指解析结果在DNS服务器中的缓存时间" required min="{$minTTL}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-6"><button type="button" class="btn btn-primary" onclick="save()">保存</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="/static/js/bootstrapValidator.min.js"></script>
|
||||
<script>
|
||||
var recordLine = {$recordLine|json_encode|raw};
|
||||
var dnsconfig = {$dnsconfig|json_encode|raw};
|
||||
var defaultLine = recordLine[0].id;
|
||||
$(document).ready(function(){
|
||||
$("select[name=type]").change(function(){
|
||||
if($(this).val() == 'MX'){
|
||||
$("#mx_type").show();
|
||||
}else{
|
||||
$("#mx_type").hide();
|
||||
}
|
||||
});
|
||||
|
||||
$("#form-store").bootstrapValidator();
|
||||
initLine();
|
||||
});
|
||||
|
||||
function initLine(option, elem){
|
||||
option = option || '';
|
||||
elem = elem || 'line_list';
|
||||
$("#"+elem).empty();
|
||||
$.each(recordLine, function(index, item){
|
||||
if(item.parent == null){
|
||||
option += '<option value="'+item.id+'">'+item.name+'</option>';
|
||||
}
|
||||
})
|
||||
$("#"+elem).append('<select name="line" class="form-control" onchange="changeLine(this, \''+elem+'\')">'+option+'</select>');
|
||||
}
|
||||
function changeLine(obj, elem){
|
||||
var line = $(obj).val();
|
||||
var flag = false;
|
||||
$("#"+elem).children().each(function(index, elem){
|
||||
if(flag) $(elem).remove()
|
||||
if(obj == elem){
|
||||
flag = true;
|
||||
}
|
||||
})
|
||||
if($(obj).find("option:selected").text() == '子集线路(非必填)') return;
|
||||
var tempLine = recordLine.filter((x) => x.parent == line)
|
||||
if(tempLine.length > 0){
|
||||
var option = '<option value="'+line+'">子集线路(非必填)</option>';
|
||||
$.each(tempLine, function(index, item){
|
||||
option += '<option value="'+item.id+'">'+item.name+'</option>';
|
||||
})
|
||||
$("#"+elem).append('<select name="line" class="form-control" onchange="changeLine(this, \''+elem+'\')">'+option+'</select>');
|
||||
}
|
||||
}
|
||||
function save(){
|
||||
$("#form-store").data("bootstrapValidator").validate();
|
||||
if(!$("#form-store").data("bootstrapValidator").isValid()){
|
||||
return;
|
||||
}
|
||||
var act = $("#form-store input[name=action]").val();
|
||||
var ii = layer.load(2);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/record/batchadd/{$domainId}',
|
||||
data : $("#form-store").serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert(data.msg,{
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
if(document.referrer.indexOf('/record?') > 0)
|
||||
window.location.href = document.referrer;
|
||||
else
|
||||
window.location.href = '/record/{$domainId}';
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -74,6 +74,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">备注</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="remark" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@@ -91,7 +97,7 @@
|
||||
<form onsubmit="return searchSubmit()" method="GET" class="form-inline" id="searchToolbar">
|
||||
<div class="form-group">
|
||||
<label>搜索</label>
|
||||
<input type="text" class="form-control" name="kw" placeholder="域名">
|
||||
<input type="text" class="form-control" name="kw" placeholder="域名或备注">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="type" class="form-control"><option value="">所有平台</option>{foreach $types as $k=>$v}
|
||||
@@ -112,8 +118,8 @@
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}select2/4.0.13/js/select2.min.js"></script>
|
||||
<script src="{$cdnpublic}select2/4.0.13/js/i18n/zh-CN.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
@@ -139,7 +145,7 @@ $(document).ready(function(){
|
||||
field: 'typename',
|
||||
title: '平台账户',
|
||||
formatter: function(value, row, index) {
|
||||
return '<span title="'+row.remark+'" data-toggle="tooltip" data-placement="right" title="Tooltip on right"><img src="/static/images/'+row.type+'.ico" class="type-logo"></img>'+value+'('+row.aid+')</span>';
|
||||
return '<img src="/static/images/'+row.type+'.ico" class="type-logo"></img>'+(row.aremark?row.aremark:value+'('+row.aid+')');
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -157,6 +163,10 @@ $(document).ready(function(){
|
||||
field: 'addtime',
|
||||
title: '添加时间'
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
title: '备注'
|
||||
},
|
||||
{
|
||||
field: 'is_hide',
|
||||
title: '是否隐藏',
|
||||
@@ -183,10 +193,7 @@ $(document).ready(function(){
|
||||
return html;
|
||||
}
|
||||
},
|
||||
],
|
||||
onLoadSuccess: function(data) {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
$("#form-store select[name=aid]").change(function(){
|
||||
@@ -234,7 +241,7 @@ function saveAdd(){
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store").modal('hide');
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
@@ -256,6 +263,7 @@ function editframe(id){
|
||||
$("#form-store2 input[name=id]").val(data.data.id);
|
||||
$("#form-store2 select[name=is_hide]").val(data.data.is_hide);
|
||||
$("#form-store2 select[name=is_sso]").val(data.data.is_sso);
|
||||
$("#form-store2 input[name=remark]").val(data.data.remark);
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
@@ -278,7 +286,7 @@ function saveEdit(){
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store2").modal('hide');
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
@@ -300,7 +308,7 @@ function delItem(id) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
@@ -357,5 +365,10 @@ function getDomainList(){
|
||||
function loading(){
|
||||
layer.load(2);
|
||||
}
|
||||
document.addEventListener("visibilitychange", function() {
|
||||
if (document.visibilityState === "visible") {
|
||||
layer.closeAll();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
@@ -16,8 +16,8 @@
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
@@ -63,6 +63,12 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
<input type="text" class="form-control" name="ttl" value="600" placeholder="指解析结果在DNS服务器中的缓存时间" required min="{$minTTL}">
|
||||
</div>
|
||||
</div>
|
||||
{if $dnsconfig.weight}<div class="form-group" style="display:none" id="weight">
|
||||
<label class="col-sm-3 control-label no-padding-right">权重</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="weight" value="" placeholder="留空则不使用权重">
|
||||
</div>
|
||||
</div>{/if}
|
||||
{if $dnsconfig.remark == 2}<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">备注</label>
|
||||
<div class="col-sm-9">
|
||||
@@ -78,6 +84,78 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal" id="modal-store2" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content animated flipInX">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span
|
||||
aria-hidden="true">×</span><span
|
||||
class="sr-only">Close</span></button>
|
||||
<h4 class="modal-title" id="modal-title">批量修改解析记录</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-horizontal" id="form-store2">
|
||||
<input type="hidden" name="action" value="value"/>
|
||||
<input type="hidden" name="recordinfo"/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">记录类型</label>
|
||||
<div class="col-sm-9">
|
||||
<select name="type" class="form-control">
|
||||
<option value="A">A</option>
|
||||
<option value="CNAME">CNAME</option>
|
||||
<option value="AAAA">AAAA</option>
|
||||
<option value="NS">NS</option>
|
||||
<option value="MX">MX</option>
|
||||
<option value="SRV">SRV</option>
|
||||
<option value="TXT">TXT</option>
|
||||
<option value="CAA">CAA</option>
|
||||
{if $dnsconfig.redirect}<option value="REDIRECT_URL">显性URL</option>
|
||||
<option value="FORWARD_URL">隐性URL</option>{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">记录值</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="value" placeholder="输入记录值" required>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-white" data-dismiss="modal">关闭</button>
|
||||
<button type="button" class="btn btn-primary" id="store" onclick="batch_save()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal" id="modal-store3" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content animated flipInX">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span
|
||||
aria-hidden="true">×</span><span
|
||||
class="sr-only">Close</span></button>
|
||||
<h4 class="modal-title" id="modal-title">批量修改解析线路</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-horizontal" id="form-store3">
|
||||
<input type="hidden" name="action" value="line"/>
|
||||
<input type="hidden" name="recordinfo"/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">线路类型</label>
|
||||
<div class="col-sm-9" id="line_list3">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-white" data-dismiss="modal">关闭</button>
|
||||
<button type="button" class="btn btn-primary" id="store" onclick="batch_save_line()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 center-block" style="float: none;">
|
||||
<div class="panel panel-default panel-default">
|
||||
@@ -87,6 +165,7 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
<div class="panel-body">
|
||||
|
||||
<form onsubmit="return searchSubmit()" method="GET" class="form-inline" id="searchToolbar">
|
||||
<div id="searchbox1">
|
||||
<div class="form-group">
|
||||
<label>搜索</label>
|
||||
<input type="text" class="form-control" name="keyword" placeholder="输入关键字">
|
||||
@@ -99,12 +178,45 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
<a href="javascript:addframe()" class="btn btn-success"><i class="fa fa-plus"></i> 添加记录</a>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">批量操作 <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu"><li><a href="javascript:operation('open')">启用</a></li><li><a href="javascript:operation('pause')">暂停</a></li><li><a href="javascript:operation('delete')">删除</a></li></ul>
|
||||
<ul class="dropdown-menu"><li><a href="/record/batchadd/{$domainId}">添加</a></li><li><a href="javascript:operation('open')">启用</a></li><li><a href="javascript:operation('pause')">暂停</a></li><li><a href="javascript:operation('edit')">修改记录</a></li><li><a href="javascript:operation('editline')">修改线路</a></li>{if $dnsconfig.remark == 1}<li><a href="javascript:operation('editremark')">修改备注</a></li>{/if}<li><a href="javascript:operation('delete')">删除</a></li></ul>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">日志 <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu"><li><a href="/log?domain={$domainName}">本站日志</a></li>{if $dnsconfig.log}<li><a href="/record/log/{$domainId}">域名日志</a></li>{/if}</ul>
|
||||
</div>
|
||||
<a href="javascript:advanceSearch()" class="btn"><i class="fa fa-angle-down"></i> 高级搜索</a>
|
||||
</div>
|
||||
<div id="searchbox2" style="display:none">
|
||||
<div class="form-group">
|
||||
<select name="type" class="form-control"><option value="">全部类型</option>
|
||||
<option value="A">A</option>
|
||||
<option value="CNAME">CNAME</option>
|
||||
<option value="AAAA">AAAA</option>
|
||||
<option value="NS">NS</option>
|
||||
<option value="MX">MX</option>
|
||||
<option value="SRV">SRV</option>
|
||||
<option value="TXT">TXT</option>
|
||||
<option value="CAA">CAA</option>
|
||||
{if $dnsconfig.redirect}<option value="REDIRECT_URL">显性URL</option>
|
||||
<option value="FORWARD_URL">隐性URL</option>{/if}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="subdomain" placeholder="输入主机记录">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="line" class="form-control"><option value="">全部线路</option></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="value" placeholder="输入记录值">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="status" class="form-control"><option value="">所有状态</option><option value="1">启用</option><option value="0">暂停</option></select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
|
||||
<a href="javascript:searchClear()" class="btn btn-default" title="刷新解析记录列表"><i class="fa fa-refresh"></i> 刷新</a>
|
||||
<a href="javascript:advanceSearch()" class="btn"><i class="fa fa-angle-up"></i> 收起</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table id="listTable">
|
||||
@@ -116,17 +228,19 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/bootstrapValidator.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script src="/static/js/custom.js?v=1003"></script>
|
||||
<script>
|
||||
var recordLine = {$recordLine|json_encode|raw};
|
||||
var dnsconfig = {$dnsconfig|json_encode|raw};
|
||||
var defaultLine = recordLine[0].id;
|
||||
var sidePagination = dnsconfig.type == 'baidu' || dnsconfig.type == 'namesilo' ? 'client' : 'server';
|
||||
var showWeight = dnsconfig.weight;
|
||||
$(document).ready(function(){
|
||||
updateToolbar();
|
||||
const defaultPageSize = 15;
|
||||
let defaultPageSize = getCookie('record_pagesize') ? getCookie('record_pagesize') : 15;
|
||||
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
|
||||
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
|
||||
|
||||
@@ -136,7 +250,7 @@ $(document).ready(function(){
|
||||
pageSize: pageSize,
|
||||
classes: 'table table-striped table-hover table-bordered',
|
||||
uniqueId: 'RecordId',
|
||||
sidePagination: "{if $dnsconfig.type=='baidu'}client{else}server{/if}",
|
||||
sidePagination: sidePagination,
|
||||
columns: [
|
||||
{
|
||||
field: '',
|
||||
@@ -176,6 +290,11 @@ $(document).ready(function(){
|
||||
field: 'TTL',
|
||||
title: 'TTL'
|
||||
},
|
||||
{
|
||||
field: 'Weight',
|
||||
visible: showWeight,
|
||||
title: '权重'
|
||||
},
|
||||
{
|
||||
field: 'Remark',
|
||||
visible: dnsconfig.remark > 0,
|
||||
@@ -218,32 +337,56 @@ $(document).ready(function(){
|
||||
}
|
||||
},
|
||||
],
|
||||
onPageChange: function(number, size){
|
||||
if(size != defaultPageSize){
|
||||
defaultPageSize = size;
|
||||
setCookie('record_pagesize', size);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
$("select[name=type]").change(function(){
|
||||
var typeChange = function(){
|
||||
if($(this).val() == 'MX'){
|
||||
$("#mx_type").show();
|
||||
}else{
|
||||
$("#mx_type").hide();
|
||||
}
|
||||
});
|
||||
if(showWeight){
|
||||
if($(this).val() == 'A' || $(this).val() == 'CNAME' || $(this).val() == 'AAAA'){
|
||||
$("#weight").show();
|
||||
}else{
|
||||
$("#weight").hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$("#form-store select[name=type]").change(typeChange);
|
||||
$("#form-store2 select[name=type]").change(typeChange);
|
||||
|
||||
$("#form-store").bootstrapValidator();
|
||||
$("#form-store2").bootstrapValidator();
|
||||
|
||||
$.each(recordLine, function(index, item){
|
||||
if(item.parent == null){
|
||||
$("#searchToolbar select[name='line']").append('<option value="'+item.id+'">'+item.name+'</option>');
|
||||
}
|
||||
})
|
||||
})
|
||||
function initLine(option){
|
||||
function initLine(option, elem){
|
||||
option = option || '';
|
||||
$("#line_list").empty();
|
||||
elem = elem || 'line_list';
|
||||
$("#"+elem).empty();
|
||||
$.each(recordLine, function(index, item){
|
||||
if(item.parent == null){
|
||||
option += '<option value="'+item.id+'">'+item.name+'</option>';
|
||||
}
|
||||
})
|
||||
$("#line_list").append('<select name="line" class="form-control" onchange="changeLine(this)">'+option+'</select>');
|
||||
$("#"+elem).append('<select name="line" class="form-control" onchange="changeLine(this, \''+elem+'\')">'+option+'</select>');
|
||||
}
|
||||
function changeLine(obj){
|
||||
function changeLine(obj, elem){
|
||||
var line = $(obj).val();
|
||||
var flag = false;
|
||||
$("#line_list").children().each(function(index, elem){
|
||||
$("#"+elem).children().each(function(index, elem){
|
||||
if(flag) $(elem).remove()
|
||||
if(obj == elem){
|
||||
flag = true;
|
||||
@@ -252,11 +395,11 @@ function changeLine(obj){
|
||||
if($(obj).find("option:selected").text() == '子集线路(非必填)') return;
|
||||
var tempLine = recordLine.filter((x) => x.parent == line)
|
||||
if(tempLine.length > 0){
|
||||
var option = '<option value="'+line+'">子集线路(非必填)</option>';
|
||||
var option = line.substr(0,2) == 'N.' ? '' : '<option value="'+line+'">子集线路(非必填)</option>';
|
||||
$.each(tempLine, function(index, item){
|
||||
option += '<option value="'+item.id+'">'+item.name+'</option>';
|
||||
})
|
||||
$("#line_list").append('<select name="line" class="form-control" onchange="changeLine(this)">'+option+'</select>');
|
||||
$("#"+elem).append('<select name="line" class="form-control" onchange="changeLine(this, \''+elem+'\')">'+option+'</select>');
|
||||
}
|
||||
}
|
||||
function addframe(){
|
||||
@@ -266,10 +409,11 @@ function addframe(){
|
||||
$("#form-store input[name=recordid]").val('');
|
||||
$("#form-store input[name=name]").val('');
|
||||
$("#form-store select[name=type]").val('A');
|
||||
$("select[name=type]").change();
|
||||
$("#form-store select[name=type]").change();
|
||||
initLine();
|
||||
$("#form-store input[name=value]").val('');
|
||||
$("#form-store input[name=ttl]").val('600');
|
||||
$("#form-store input[name=weight]").val('');
|
||||
$("#form-store input[name=remark]").val('');
|
||||
$("#form-store").data("bootstrapValidator").resetForm();
|
||||
}
|
||||
@@ -281,7 +425,7 @@ function editframe(recordid){
|
||||
$("#form-store input[name=recordid]").val(recordid);
|
||||
$("#form-store input[name=name]").val(row.Name);
|
||||
$("#form-store select[name=type]").val(row.Type);
|
||||
$("select[name=type]").change();
|
||||
$("#form-store select[name=type]").change();
|
||||
initLine();
|
||||
if($('#form-store select[name=line] option[value="'+row.Line+'"]').length > 0){
|
||||
$("#form-store select[name=line]").val(row.Line);
|
||||
@@ -292,6 +436,7 @@ function editframe(recordid){
|
||||
$("#form-store input[name=value]").val(row.Value);
|
||||
$("#form-store input[name=mx]").val(row.MX);
|
||||
$("#form-store input[name=ttl]").val(row.TTL);
|
||||
$("#form-store input[name=weight]").val(row.Weight);
|
||||
$("#form-store input[name=remark]").val(row.Remark);
|
||||
$("#form-store").data("bootstrapValidator").resetForm();
|
||||
}
|
||||
@@ -316,7 +461,7 @@ function save(){
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store").modal('hide');
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
@@ -336,7 +481,7 @@ function setStatus(recordid, status){
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
layer.msg(status=='1'?'开启成功':'暂停成功', {icon: 1, time:500});
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
@@ -358,7 +503,7 @@ function delItem(recordid) {
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
layer.msg('删除成功', {icon: 1, time:800});
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
@@ -390,7 +535,7 @@ function setRemark(recordid) {
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
layer.msg('保存成功', {icon: 1, time:800});
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon:2});
|
||||
}
|
||||
@@ -409,6 +554,29 @@ function operation(action){
|
||||
layer.msg('请选择要操作的记录');
|
||||
return;
|
||||
}
|
||||
if(action == 'edit'){
|
||||
var records = [];
|
||||
$.each(rows, function(index, item){
|
||||
records.push({recordid:item.RecordId, name:item.Name, line:item.Line, mx:item.MX, ttl:item.TTL, weight:item.Weight, remark:item.Remark});
|
||||
})
|
||||
batch_edit(records)
|
||||
return;
|
||||
}else if(action == 'editline'){
|
||||
var records = [];
|
||||
$.each(rows, function(index, item){
|
||||
records.push({recordid:item.RecordId, name:item.Name, type:item.Type, value:item.Value, mx:item.MX, ttl:item.TTL, weight:item.Weight, remark:item.Remark});
|
||||
})
|
||||
batch_edit_line(records)
|
||||
return;
|
||||
}else if(action == 'editremark'){
|
||||
var ids = [];
|
||||
$.each(rows, function(index, item){
|
||||
ids.push(item.RecordId);
|
||||
})
|
||||
batch_edit_remark(ids)
|
||||
return;
|
||||
}
|
||||
|
||||
var ids = [];
|
||||
$.each(rows, function(index, item){
|
||||
ids.push(item.RecordId);
|
||||
@@ -427,7 +595,7 @@ function operation(action){
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
layer.alert(data.msg, {icon: 1});
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
@@ -437,5 +605,124 @@ function operation(action){
|
||||
layer.close(confirmobj);
|
||||
});
|
||||
}
|
||||
function batch_edit(records){
|
||||
var row = $("#listTable").bootstrapTable('getSelections')[0];
|
||||
$("#batch_num").text(records.length);
|
||||
$("#modal-store2").modal('show');
|
||||
$("#form-store2 input[name=recordinfo]").val(JSON.stringify(records));
|
||||
$("#form-store2 input[name=recordid]").val(row.RecordId);
|
||||
$("#form-store2 input[name=name]").val(row.Name);
|
||||
$("#form-store2 select[name=type]").val(row.Type);
|
||||
$("#form-store2 select[name=type]").change();
|
||||
$("#form-store2 input[name=value]").val(row.Value);
|
||||
$("#form-store2").data("bootstrapValidator").resetForm();
|
||||
}
|
||||
function batch_save(){
|
||||
$("#form-store2").data("bootstrapValidator").validate();
|
||||
if(!$("#form-store2").data("bootstrapValidator").isValid()){
|
||||
return;
|
||||
}
|
||||
var ii = layer.load(2);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/record/batchedit/{$domainId}',
|
||||
data : $("#form-store2").serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert(data.msg,{
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store2").modal('hide');
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function batch_edit_line(records){
|
||||
$("#batch_num").text(records.length);
|
||||
$("#modal-store3").modal('show');
|
||||
$("#form-store3 input[name=recordinfo]").val(JSON.stringify(records));
|
||||
initLine('', 'line_list3');
|
||||
}
|
||||
function batch_save_line(){
|
||||
var ii = layer.load(2);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/record/batchedit/{$domainId}',
|
||||
data : $("#form-store3").serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert(data.msg,{
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store3").modal('hide');
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function batch_edit_remark(recordids) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: ['350px'],
|
||||
closeBtn: 2,
|
||||
title: '批量修改备注',
|
||||
content: '<div style="padding:15px"><div class="form-group"><input class="form-control" type="text" name="remark" value="" autocomplete="off" placeholder="备注信息"></div></div>',
|
||||
btn: ['确认', '取消'],
|
||||
yes: function(){
|
||||
var remark = $("input[name='remark']").val();
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/record/batch/{$domainId}',
|
||||
data : {action:'remark', recordids:recordids, remark:remark},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
layer.alert(data.msg,{
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
searchRefresh();
|
||||
});
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function advanceSearch(){
|
||||
$('#searchToolbar').find('input[name]').each(function() {
|
||||
$(this).val('');
|
||||
});
|
||||
$('#searchToolbar').find('select[name]').each(function() {
|
||||
$(this).find('option:first').prop("selected", 'selected');
|
||||
});
|
||||
if($("#searchbox1").is(":visible")){
|
||||
$("#searchbox1").slideUp();
|
||||
$("#searchbox2").slideDown();
|
||||
}else{
|
||||
$("#searchbox2").slideUp();
|
||||
$("#searchbox1").slideDown();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
502
app/view/exception.tpl
Normal file
502
app/view/exception.tpl
Normal file
@@ -0,0 +1,502 @@
|
||||
<?php
|
||||
/** @var array $traces */
|
||||
if (!function_exists('parse_padding')) {
|
||||
function parse_padding($source)
|
||||
{
|
||||
$length = strlen(strval(count($source['source']) + $source['first']));
|
||||
return 40 + ($length - 1) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('parse_class')) {
|
||||
function parse_class($name)
|
||||
{
|
||||
$names = explode('\\', $name);
|
||||
return '<abbr title="'.$name.'">'.end($names).'</abbr>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('parse_file')) {
|
||||
function parse_file($file, $line)
|
||||
{
|
||||
return '<a class="toggle" title="'."{$file} line {$line}".'">'.basename($file)." line {$line}".'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('parse_args')) {
|
||||
function parse_args($args)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($args as $key => $item) {
|
||||
switch (true) {
|
||||
case is_object($item):
|
||||
$value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));
|
||||
break;
|
||||
case is_array($item):
|
||||
if (count($item) > 3) {
|
||||
$value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));
|
||||
} else {
|
||||
$value = sprintf('[%s]', parse_args($item));
|
||||
}
|
||||
break;
|
||||
case is_string($item):
|
||||
if (strlen($item) > 20) {
|
||||
$value = sprintf(
|
||||
'\'<a class="toggle" title="%s">%s...</a>\'',
|
||||
htmlentities($item),
|
||||
htmlentities(substr($item, 0, 20))
|
||||
);
|
||||
} else {
|
||||
$value = sprintf("'%s'", htmlentities($item));
|
||||
}
|
||||
break;
|
||||
case is_int($item):
|
||||
case is_float($item):
|
||||
$value = $item;
|
||||
break;
|
||||
case is_null($item):
|
||||
$value = '<em>null</em>';
|
||||
break;
|
||||
case is_bool($item):
|
||||
$value = '<em>' . ($item ? 'true' : 'false') . '</em>';
|
||||
break;
|
||||
case is_resource($item):
|
||||
$value = '<em>resource</em>';
|
||||
break;
|
||||
default:
|
||||
$value = htmlentities(str_replace("\n", '', var_export(strval($item), true)));
|
||||
break;
|
||||
}
|
||||
|
||||
$result[] = is_int($key) ? $value : sprintf('\'%s\' => %s', htmlentities($key), $value);
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
}
|
||||
}
|
||||
if (!function_exists('echo_value')) {
|
||||
function echo_value($val)
|
||||
{
|
||||
if (is_array($val) || is_object($val)) {
|
||||
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
|
||||
} elseif (is_bool($val)) {
|
||||
echo $val ? 'true' : 'false';
|
||||
} elseif (is_scalar($val)) {
|
||||
echo htmlentities($val);
|
||||
} else {
|
||||
echo 'Resource';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>系统发生错误</title>
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
<style>
|
||||
/* Base */
|
||||
body {
|
||||
color: #333;
|
||||
font: 16px Verdana, "Helvetica Neue", helvetica, Arial, 'Microsoft YaHei', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0 20px 20px;
|
||||
}
|
||||
h1{
|
||||
margin: 10px 0 0;
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
}
|
||||
h2{
|
||||
color: #4288ce;
|
||||
font-weight: 400;
|
||||
padding: 6px 0;
|
||||
margin: 6px 0 0;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
h3{
|
||||
margin: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
abbr{
|
||||
cursor: help;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dotted;
|
||||
}
|
||||
a{
|
||||
color: #868686;
|
||||
cursor: pointer;
|
||||
}
|
||||
a:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
.line-error{
|
||||
background: #f8cbcb;
|
||||
}
|
||||
.echo table {
|
||||
width: 100%;
|
||||
}
|
||||
.echo pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f7f7f7;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
}
|
||||
.echo pre > pre {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
/* Exception Info */
|
||||
.exception {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.exception .message{
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-bottom: 0 none;
|
||||
line-height: 18px;
|
||||
font-size:16px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑",serif;
|
||||
}
|
||||
.exception .code{
|
||||
float: left;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
margin-right: 12px;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
background: #999;
|
||||
}
|
||||
.exception .source-code{
|
||||
padding: 6px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
background: #f9f9f9;
|
||||
overflow-x: auto;
|
||||
|
||||
}
|
||||
.exception .source-code pre{
|
||||
margin: 0;
|
||||
}
|
||||
.exception .source-code pre ol{
|
||||
margin: 0;
|
||||
color: #4288ce;
|
||||
display: inline-block;
|
||||
min-width: 100%;
|
||||
box-sizing: border-box;
|
||||
font-size:14px;
|
||||
font-family: "Century Gothic",Consolas,"Liberation Mono",Courier,Verdana,serif;
|
||||
padding-left: <?php echo (isset($source) && !empty($source)) ? parse_padding($source) : 40; ?>px;
|
||||
}
|
||||
.exception .source-code pre li{
|
||||
border-left: 1px solid #ddd;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.exception .source-code pre code{
|
||||
color: #333;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
border-left: 1px solid #fff;
|
||||
font-size:14px;
|
||||
font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑",serif;
|
||||
}
|
||||
.exception .trace{
|
||||
padding: 6px;
|
||||
border: 1px solid #ddd;
|
||||
border-top: 0 none;
|
||||
line-height: 16px;
|
||||
font-size:14px;
|
||||
font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑",serif;
|
||||
}
|
||||
.exception .trace h2:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
.exception .trace ol{
|
||||
margin: 12px;
|
||||
}
|
||||
.exception .trace ol li{
|
||||
padding: 2px 4px;
|
||||
}
|
||||
.exception div:last-child{
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
/* Exception Variables */
|
||||
.exception-var table{
|
||||
width: 100%;
|
||||
margin: 12px 0;
|
||||
box-sizing: border-box;
|
||||
table-layout:fixed;
|
||||
word-wrap:break-word;
|
||||
}
|
||||
.exception-var table caption{
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
padding: 6px 0;
|
||||
}
|
||||
.exception-var table caption small{
|
||||
font-weight: 300;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
color: #ccc;
|
||||
}
|
||||
.exception-var table tbody{
|
||||
font-size: 13px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, "微软雅黑",serif;
|
||||
}
|
||||
.exception-var table td{
|
||||
padding: 0 6px;
|
||||
vertical-align: top;
|
||||
word-break: break-all;
|
||||
}
|
||||
.exception-var table td:first-child{
|
||||
width: 28%;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.exception-var table td pre{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Copyright Info */
|
||||
.copyright{
|
||||
margin-top: 24px;
|
||||
padding: 12px 0;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
pre.prettyprint .pln { color: #000 } /* plain text */
|
||||
pre.prettyprint .str { color: #080 } /* string content */
|
||||
pre.prettyprint .kwd { color: #008 } /* a keyword */
|
||||
pre.prettyprint .com { color: #800 } /* a comment */
|
||||
pre.prettyprint .typ { color: #606 } /* a type name */
|
||||
pre.prettyprint .lit { color: #066 } /* a literal value */
|
||||
/* punctuation, lisp open bracket, lisp close bracket */
|
||||
pre.prettyprint .pun, pre.prettyprint .opn, pre.prettyprint .clo { color: #660 }
|
||||
pre.prettyprint .tag { color: #008 } /* a markup tag name */
|
||||
pre.prettyprint .atn { color: #606 } /* a markup attribute name */
|
||||
pre.prettyprint .atv { color: #080 } /* a markup attribute value */
|
||||
pre.prettyprint .dec, pre.prettyprint .var { color: #606 } /* a declaration; a variable name */
|
||||
pre.prettyprint .fun { color: red } /* a function name */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (\think\facade\App::isDebug()) { ?>
|
||||
<?php foreach ($traces as $index => $trace) { ?>
|
||||
<div class="exception">
|
||||
<div class="message">
|
||||
<div class="info">
|
||||
<div>
|
||||
<h2><?php echo "#{$index} [{$trace['code']}]" . sprintf('%s in %s', parse_class($trace['name']), parse_file($trace['file'], $trace['line'])); ?></h2>
|
||||
</div>
|
||||
<div><h1><?php echo nl2br(htmlentities($trace['message'])); ?></h1></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (!empty($trace['source'])) { ?>
|
||||
<div class="source-code">
|
||||
<pre class="prettyprint lang-php"><ol start="<?php echo $trace['source']['first']; ?>"><?php foreach ((array) $trace['source']['source'] as $key => $value) { ?><li class="line-<?php echo "{$index}-"; echo $key + $trace['source']['first']; echo $trace['line'] === $key + $trace['source']['first'] ? ' line-error' : ''; ?>"><code><?php echo htmlentities($value); ?></code></li><?php } ?></ol></pre>
|
||||
</div>
|
||||
<?php }?>
|
||||
<div class="trace">
|
||||
<h2 data-expand="<?php echo 0 === $index ? '1' : '0'; ?>">Call Stack</h2>
|
||||
<ol>
|
||||
<li><?php echo sprintf('in %s', parse_file($trace['file'], $trace['line'])); ?></li>
|
||||
<?php foreach ((array) $trace['trace'] as $value) { ?>
|
||||
<li>
|
||||
<?php
|
||||
// Show Function
|
||||
if ($value['function']) {
|
||||
echo sprintf(
|
||||
'at %s%s%s(%s)',
|
||||
isset($value['class']) ? parse_class($value['class']) : '',
|
||||
isset($value['type']) ? $value['type'] : '',
|
||||
$value['function'],
|
||||
isset($value['args'])?parse_args($value['args']):''
|
||||
);
|
||||
}
|
||||
|
||||
// Show line
|
||||
if (isset($value['file']) && isset($value['line'])) {
|
||||
echo sprintf(' in %s', parse_file($value['file'], $value['line']));
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php } else { ?>
|
||||
<div class="exception">
|
||||
<div class="info"><h1><?php echo htmlentities($message); ?></h1></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (!empty($datas)) { ?>
|
||||
<div class="exception-var">
|
||||
<h2>Exception Datas</h2>
|
||||
<?php foreach ((array) $datas as $label => $value) { ?>
|
||||
<table>
|
||||
<?php if (empty($value)) { ?>
|
||||
<caption><?php echo $label; ?><small>empty</small></caption>
|
||||
<?php } else { ?>
|
||||
<caption><?php echo $label; ?></caption>
|
||||
<tbody>
|
||||
<?php foreach ((array) $value as $key => $val) { ?>
|
||||
<tr>
|
||||
<td><?php echo htmlentities($key); ?></td>
|
||||
<td><?php echo_value($val); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (!empty($tables)) { ?>
|
||||
<div class="exception-var">
|
||||
<h2>Environment Variables</h2>
|
||||
<?php foreach ((array) $tables as $label => $value) { ?>
|
||||
<table>
|
||||
<?php if (empty($value)) { ?>
|
||||
<caption><?php echo $label; ?><small>empty</small></caption>
|
||||
<?php } else { ?>
|
||||
<caption><?php echo $label; ?></caption>
|
||||
<tbody>
|
||||
<?php foreach ((array) $value as $key => $val) { ?>
|
||||
<tr>
|
||||
<td><?php echo htmlentities($key); ?></td>
|
||||
<td><?php echo_value($val); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (\think\facade\App::isDebug()) { ?>
|
||||
<div class="copyright">
|
||||
<a title="官方网站" href="http://www.thinkphp.cn">ThinkPHP</a>
|
||||
<span>V<?php echo \think\facade\App::version(); ?></span>
|
||||
<span>{ 十年磨一剑-为API开发设计的高性能框架 }</span>
|
||||
<span>- <a title="官方手册" href="https://www.kancloud.cn/manual/thinkphp6_0/content">官方手册</a></span>
|
||||
</div>
|
||||
<script>
|
||||
function $(selector, node){
|
||||
var elements;
|
||||
|
||||
node = node || document;
|
||||
if(document.querySelectorAll){
|
||||
elements = node.querySelectorAll(selector);
|
||||
} else {
|
||||
switch(selector.substr(0, 1)){
|
||||
case '#':
|
||||
elements = [node.getElementById(selector.substr(1))];
|
||||
break;
|
||||
case '.':
|
||||
if(document.getElementsByClassName){
|
||||
elements = node.getElementsByClassName(selector.substr(1));
|
||||
} else {
|
||||
elements = get_elements_by_class(selector.substr(1), node);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elements = node.getElementsByTagName();
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
|
||||
function get_elements_by_class(search_class, node, tag) {
|
||||
var elements = [], eles,
|
||||
pattern = new RegExp('(^|\\s)' + search_class + '(\\s|$)');
|
||||
|
||||
node = node || document;
|
||||
tag = tag || '*';
|
||||
|
||||
eles = node.getElementsByTagName(tag);
|
||||
for(var i = 0; i < eles.length; i++) {
|
||||
if(pattern.test(eles[i].className)) {
|
||||
elements.push(eles[i])
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
$.getScript = function(src, func){
|
||||
var script = document.createElement('script');
|
||||
|
||||
script.async = 'async';
|
||||
script.src = src;
|
||||
script.onload = func || function(){};
|
||||
|
||||
$('head')[0].appendChild(script);
|
||||
}
|
||||
|
||||
;(function(){
|
||||
var files = $('.toggle');
|
||||
var ol = $('ol', $('.prettyprint')[0]);
|
||||
var li = $('li', ol[0]);
|
||||
|
||||
// 短路径和长路径变换
|
||||
for(var i = 0; i < files.length; i++){
|
||||
files[i].ondblclick = function(){
|
||||
var title = this.title;
|
||||
|
||||
this.title = this.innerHTML;
|
||||
this.innerHTML = title;
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var expand = function (dom, expand) {
|
||||
var ol = $('ol', dom.parentNode)[0];
|
||||
expand = undefined === expand ? dom.attributes['data-expand'].value === '0' : undefined;
|
||||
if (expand) {
|
||||
dom.attributes['data-expand'].value = '1';
|
||||
ol.style.display = 'none';
|
||||
dom.innerText = 'Call Stack (展开)';
|
||||
} else {
|
||||
dom.attributes['data-expand'].value = '0';
|
||||
ol.style.display = 'block';
|
||||
dom.innerText = 'Call Stack (折叠)';
|
||||
}
|
||||
};
|
||||
var traces = $('.trace');
|
||||
for (var i = 0; i < traces.length; i ++) {
|
||||
var h2 = $('h2', traces[i])[0];
|
||||
expand(h2);
|
||||
h2.onclick = function () {
|
||||
expand(this);
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
$.getScript('//cdn.bootcdn.net/ajax/libs/prettify/r298/prettify.min.js', function(){
|
||||
prettyPrint();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<?php } ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<title>抱歉,出错了</title>
|
||||
<link href="//res.wx.qq.com/open/libs/weui/0.4.3/weui.css" rel="stylesheet">
|
||||
<style>.page{position:absolute;top:0;right:0;bottom:0;left:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="weui_msg">
|
||||
<div class="weui_icon_area"><i class="weui_icon_info weui_icon_msg"></i></div>
|
||||
<div class="weui_text_area">
|
||||
<h4 class="weui_msg_title">{$errmsg}</h4>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.body.addEventListener('touchmove', function (event) {
|
||||
event.preventDefault();
|
||||
},{ passive: false });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -59,7 +59,7 @@
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h3 id="count4">0</h3>
|
||||
<p>平台数量</p>
|
||||
<p>DNS平台数量</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-connectdevelop"></i>
|
||||
@@ -169,6 +169,10 @@ function speedModeNotice(){
|
||||
var html = "<div class=\"panel panel-default\"><div class=\"panel-body\">当前浏览器是兼容模式,为确保后台功能正常使用,请切换到<b style='color:#51b72f'>极速模式</b>!<br>操作方法:点击浏览器地址栏右侧的IE符号<b style='color:#51b72f;'><i class='fa fa-internet-explorer fa-fw'></i></b>→选择“<b style='color:#51b72f;'><i class='fa fa-flash fa-fw'></i></b><b style='color:#51b72f;'>极速模式</b>”</div></div>";
|
||||
$("#browser-notice").html(html)
|
||||
}
|
||||
else if(window.location.protocol.indexOf("https")==-1){
|
||||
var html = "<div class=\"panel panel-default\"><div class=\"panel-body\"><b style='color:#CC3022;'><i class='fa fa-info-circle fa-fw'></i></b>当前正在使用HTTP访问,可能存在被窃取敏感信息风险,请使用HTTPS访问!</div></div>";
|
||||
$("#browser-notice").html(html)
|
||||
}
|
||||
}
|
||||
speedModeNotice();
|
||||
</script>
|
||||
|
||||
181
app/view/optimizeip/opipform.html
Normal file
181
app/view/optimizeip/opipform.html
Normal file
@@ -0,0 +1,181 @@
|
||||
{extend name="common/layout" /}
|
||||
{block name="title"}优选IP任务{/block}
|
||||
{block name="main"}
|
||||
<style>
|
||||
.dselect::before{
|
||||
content: '.';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
.tips{color: #f6a838; padding-left: 5px;}
|
||||
</style>
|
||||
<div class="row" id="app">
|
||||
<div class="col-xs-12 center-block" style="float: none;">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title"><a href="/optimizeip/opiplist" class="btn btn-sm btn-default pull-right" style="margin-top:-6px"><i class="fa fa-reply fa-fw"></i> 返回</a>{if $action=='edit'}编辑{else}添加{/if}优选IP任务</h3></div>
|
||||
<div class="panel-body">
|
||||
<form onsubmit="return false" method="post" class="form-horizontal" role="form" id="taskform">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-xs-12 control-label no-padding-right">域名选择</label>
|
||||
<div class="col-sm-3 col-xs-5"><input type="text" name="rr" v-model="set.rr" placeholder="主机记录" class="form-control" required></div>
|
||||
<div class="col-sm-3 col-xs-7 dselect"><select name="did" v-model="set.did" class="form-control" required>
|
||||
<option value="">--主域名--</option>
|
||||
{foreach $domains as $k=>$v}
|
||||
<option value="{$k}">{$v}</option>
|
||||
{/foreach}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">CDN服务商</label>
|
||||
<div class="col-sm-6">
|
||||
<label class="radio-inline" v-for="(value,key) in cdntypeList">
|
||||
<input type="radio" name="cdntype" :value="key" v-model="set.cdn_type"> {{value}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">解析线路类型</label>
|
||||
<div class="col-sm-6">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="type" value="0" v-model="set.type"> 电信/联通/移动线路<span class="tips" title="用于已在CF添加,需优化三网访问速度的域名" data-toggle="tooltip" data-placement="bottom" data-original-title=""><i class="fa fa-question-circle"></i></span>
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="type" value="1" v-model="set.type"> 默认/联通/移动线路<span class="tips" title="将电信优选IP解析到默认线路,用于给其他域名提供CNAME服务" data-toggle="tooltip" data-placement="bottom" data-original-title=""><i class="fa fa-question-circle"></i></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">解析IP类型<span class="tips" title="" data-toggle="tooltip" data-placement="bottom" data-original-title="同时开启IPv6&IPv4将会请求2次接口消耗双倍积分"><i class="fa fa-question-circle"></i></span></label>
|
||||
<div class="col-sm-6">
|
||||
<label class="checkbox-inline" v-for="option in iptypeList">
|
||||
<input type="checkbox" name="ip_type" :value="option.value" v-model="set.ip_type_select" required> {{option.label}}
|
||||
</label><br/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">每线路解析数量<span class="tips" title="" data-toggle="tooltip" data-placement="bottom" data-original-title="数量不要超过当前域名套餐允许的最大数量,否则会添加解析失败"><i class="fa fa-question-circle"></i></span></label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="recordnum" v-model="set.recordnum" placeholder="填写每线路解析数量" class="form-control" data-bv-integer="true" min="1" max="5" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">TTL<span class="tips" title="" data-toggle="tooltip" data-placement="bottom" data-original-title="TTL不要低于当前域名套餐允许的最小值,否则会添加解析失败"><i class="fa fa-question-circle"></i></span></label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="ttl" v-model="set.ttl" placeholder="填写TTL" class="form-control" data-bv-integer="true" min="1" max="3600" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label no-padding-right">备注</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="remark" v-model="set.remark" placeholder="可留空" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.type==0">
|
||||
<div class="col-sm-offset-3 col-sm-6">
|
||||
<div class="alert alert-dismissible alert-info">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<strong>提示:</strong>所选域名需保留一个默认线路的解析记录,指向{{cdntypeList[set.cdn_type]}}提供的CNAME地址,其他线路的解析记录需要删除,添加任务后将自动为当前域名添加电信/联通/移动线路的解析记录。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" v-show="set.type==1">
|
||||
<div class="col-sm-offset-3 col-sm-6">
|
||||
<div class="alert alert-dismissible alert-info">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<strong>提示:</strong>所选域名需删除全部解析记录,添加任务后将自动为当前域名添加解析记录。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-6"><button type="button" class="btn btn-primary" @click="submit">提交</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}vue/2.6.14/vue.min.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="/static/js/bootstrapValidator.min.js"></script>
|
||||
<script>
|
||||
var action = '{$action}';
|
||||
var info = {$info|json_encode|raw};
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
action: '{$action}',
|
||||
set: {
|
||||
id: '',
|
||||
remark: '',
|
||||
rr: '',
|
||||
did: '',
|
||||
type: 0,
|
||||
cdn_type: 1,
|
||||
ip_type_select: ['v4'],
|
||||
ip_type: 'v4',
|
||||
recordnum: 2,
|
||||
ttl: 600,
|
||||
},
|
||||
iptypeList: [
|
||||
{value:'v4', label:'IPv4(A记录)'},
|
||||
{value:'v6', label:'IPv6(AAAA记录)'},
|
||||
],
|
||||
cdntypeList: {
|
||||
1:'CloudFlare',
|
||||
2:"CloudFront",
|
||||
3:'Gcore'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'set.ip_type_select': function(val){
|
||||
this.set.ip_type = val.join(',');
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if(this.action == 'edit'){
|
||||
Object.keys(info).forEach((key) => {
|
||||
this.$set(this.set, key, info[key])
|
||||
})
|
||||
this.set.ip_type_select = this.set.ip_type.split(',')
|
||||
}
|
||||
$("#taskform").bootstrapValidator({
|
||||
live: 'submitted',
|
||||
});
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
},
|
||||
methods: {
|
||||
submit(){
|
||||
var that=this;
|
||||
$("#taskform").data("bootstrapValidator").validate();
|
||||
if(!$("#taskform").data("bootstrapValidator").isValid()){
|
||||
return false;
|
||||
}
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "",
|
||||
data: this.set,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert(data.msg, {icon: 1}, function(){
|
||||
if(document.referrer.indexOf('/opiplist?') > 0)
|
||||
window.location.href = document.referrer;
|
||||
else
|
||||
window.location.href = '/optimizeip/opiplist';
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
},
|
||||
error: function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
184
app/view/optimizeip/opiplist.html
Normal file
184
app/view/optimizeip/opiplist.html
Normal file
@@ -0,0 +1,184 @@
|
||||
{extend name="common/layout" /}
|
||||
{block name="title"}CF优选IP任务管理{/block}
|
||||
{block name="main"}
|
||||
<style>
|
||||
tbody tr>td:nth-child(2){overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:180px;}
|
||||
</style>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 center-block" style="float: none;">
|
||||
<div class="panel panel-default panel-intro">
|
||||
<div class="panel-body">
|
||||
|
||||
<form onsubmit="return searchSubmit()" method="GET" class="form-inline" id="searchToolbar">
|
||||
<div class="form-group">
|
||||
<label>搜索</label>
|
||||
<div class="form-group">
|
||||
<select name="type" class="form-control"><option value="1">域名</option><option value="2">备注</option></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="kw" placeholder="">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
|
||||
<a href="javascript:searchClear()" class="btn btn-default" title="刷新域名账户列表"><i class="fa fa-refresh"></i> 刷新</a>
|
||||
<a href="/optimizeip/opipform/add" class="btn btn-success"><i class="fa fa-plus"></i> 添加</a>
|
||||
</form>
|
||||
|
||||
<table id="listTable">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
updateToolbar();
|
||||
const defaultPageSize = 15;
|
||||
const pageNumber = typeof window.$_GET['pageNumber'] != 'undefined' ? parseInt(window.$_GET['pageNumber']) : 1;
|
||||
const pageSize = typeof window.$_GET['pageSize'] != 'undefined' ? parseInt(window.$_GET['pageSize']) : defaultPageSize;
|
||||
|
||||
$("#listTable").bootstrapTable({
|
||||
url: '/optimizeip/opiplist/data',
|
||||
pageNumber: pageNumber,
|
||||
pageSize: pageSize,
|
||||
classes: 'table table-striped table-hover table-bordered',
|
||||
columns: [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID'
|
||||
},
|
||||
{
|
||||
field: 'rr',
|
||||
title: '域名',
|
||||
formatter: function(value, row, index) {
|
||||
return '<span title="'+row.remark+'" data-toggle="tooltip" data-placement="right" title="Tooltip on right">' + value + '.' + row.domain + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'cdn_type',
|
||||
title: 'CDN运营商',
|
||||
formatter: function(value, row, index) {
|
||||
if(value == 1){
|
||||
return 'CloudFlare';
|
||||
}else if(value == 2){
|
||||
return 'CloudFront';
|
||||
}else if(value == 3){
|
||||
return 'Gcore';
|
||||
}else{
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'recordnum',
|
||||
title: '解析数量',
|
||||
formatter: function(value, row, index) {
|
||||
return '<span title="" data-toggle="tooltip" data-placement="bottom" data-original-title="TTL:'+row.ttl+'" class="tips">'+value+'</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'ip_type',
|
||||
title: '解析IP类型',
|
||||
formatter: function(value, row, index) {
|
||||
var value = value.split(',')
|
||||
value.forEach((element, index) => {
|
||||
if(element == 'v4') value[index] = 'IPv4'
|
||||
else if(element == 'v6') value[index] = 'IPv6'
|
||||
});
|
||||
return value.join(',');
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'active',
|
||||
title: '任务开关',
|
||||
formatter: function(value, row, index) {
|
||||
var html = '';
|
||||
if(value == 1) {
|
||||
html += '<span class="btn btn-success btn-xs" onclick="setActive('+row.id+', 0)">开启</span>';
|
||||
} else {
|
||||
html += '<span class="btn btn-warning btn-xs" onclick="setActive('+row.id+', 1)">关闭</span>';
|
||||
}
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'updatetime',
|
||||
title: '上次更新时间',
|
||||
formatter: function(value, row, index) {
|
||||
return value ? value : '无';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: '上次更新结果',
|
||||
formatter: function(value, row, index) {
|
||||
if(value == 1) {
|
||||
return '<span class="label label-success">成功</span>';
|
||||
} else if(value == 2) {
|
||||
return '<span class="label label-danger">失败</span> <span title="" data-toggle="tooltip" data-placement="bottom" data-original-title="'+row.errmsg+'" class="tips"><i class="fa fa-info-circle"></i></span>';
|
||||
} else {
|
||||
return '<span class="label label-warning">未运行</span>';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: '',
|
||||
title: '操作',
|
||||
formatter: function(value, row, index) {
|
||||
var html = '<a href="javascript:runTask(\''+row.id+'\')" class="btn btn-success btn-xs">手动更新</a> ';
|
||||
html += '<a href="/optimizeip/opipform/edit?id='+row.id+'" class="btn btn-primary btn-xs">修改</a> ';
|
||||
html += '<a href="/record/'+row.did+'?keyword='+row.rr+'" class="btn btn-default btn-xs" target="_blank">解析</a> ';
|
||||
html += '<a href="javascript:delItem(\''+row.id+'\')" class="btn btn-danger btn-xs">删除</a> ';
|
||||
return html;
|
||||
}
|
||||
},
|
||||
],
|
||||
onLoadSuccess: function(data) {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
}
|
||||
})
|
||||
})
|
||||
function setActive(id, active){
|
||||
$.post('/optimizeip/opipform/setactive', {id: id, active: active}, function(data){
|
||||
if(data.code == 0) {
|
||||
layer.msg('修改成功', {icon: 1, time:800});
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
} else {
|
||||
layer.msg(data.msg, {icon: 2});
|
||||
}
|
||||
}, 'json');
|
||||
}
|
||||
function delItem(id){
|
||||
layer.confirm('确定要删除此任务吗?', {
|
||||
btn: ['确定','取消']
|
||||
}, function(){
|
||||
$.post('/optimizeip/opipform/del', {id: id}, function(data){
|
||||
if(data.code == 0) {
|
||||
layer.msg('删除成功', {icon: 1, time:800});
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
} else {
|
||||
layer.msg(data.msg, {icon: 2});
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
}
|
||||
function runTask(id){
|
||||
var ii = layer.msg('正在更新中...', {icon: 16,shade: 0.1,time: 0});
|
||||
$.post('/optimizeip/opipform/run', {id: id}, function(data){
|
||||
layer.close(ii);
|
||||
if(data.code == 0) {
|
||||
layer.alert(data.msg, {icon: 1});
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
} else {
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
}, 'json');
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
105
app/view/optimizeip/opipset.html
Normal file
105
app/view/optimizeip/opipset.html
Normal file
@@ -0,0 +1,105 @@
|
||||
{extend name="common/layout" /}
|
||||
{block name="title"}CF优选IP设置{/block}
|
||||
{block name="main"}
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<div class="panel panel-success">
|
||||
<div class="panel-heading"><h3 class="panel-title">功能简介</h3></div>
|
||||
<div class="panel-body">
|
||||
<p>由于CloudFlare官方IP是泛播路由,同一个IP在不同地区不同运营商所链接的机房是不同的,速度或延迟也会有区别。目前网上也有很多CF优选CNAME服务,然而公共的CNAME可能无法满足稳定性和安全性的需要。</p>
|
||||
<p>本功能可以获取CloudFlare最新的优选IP地址(分为电信/联通/移动线路),并自动更新到域名解析记录。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading"><h3 class="panel-title">使用说明</h3></div>
|
||||
<div class="panel-body">
|
||||
<p><li>数据接口:<a href="https://www.wetest.vip/" target="_blank" rel="noreferrer">wetest.vip</a> 数据接口支持CloudFlare、CloudFront、Gcore;<a href="https://stock.hostmonit.com/" target="_blank" rel="noreferrer">HostMonit</a> 只支持CloudFlare。</li></p>
|
||||
<p><li>接口密钥:默认o1zrmHAF为免费KEY可永久免费使用。</li></p>
|
||||
<p><li>计划任务:将以下命令添加到计划任务,周期设置为15分钟以上</li></p>
|
||||
<p><code>cd {:app()->getRootPath()} && php think opiptask</code></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading"><h3 class="panel-title">数据接口设置</h3></div>
|
||||
<div class="panel-body">
|
||||
<form onsubmit="return saveSetting(this)" method="post" class="form-horizontal" role="form">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">数据接口</label>
|
||||
<div class="col-sm-9"><select class="form-control" name="optimize_ip_api" default="{:config_get('optimize_ip_api')}"><option value="0">wetest.vip</option><option value="1">HostMonit</option></select></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">接口密钥</label>
|
||||
<div class="col-sm-9"><input type="text" name="optimize_ip_key" value="{:config_get('optimize_ip_key', 'o1zrmHAF')}" class="form-control"/></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-9">
|
||||
<input type="submit" name="submit" value="保存" class="btn btn-primary btn-block"/>
|
||||
<a href="javascript:queryapi()" class="btn btn-default btn-block">查询积分</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script>
|
||||
var items = $("select[default]");
|
||||
for (i = 0; i < items.length; i++) {
|
||||
$(items[i]).val($(items[i]).attr("default")||0);
|
||||
}
|
||||
function saveSetting(obj){
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '',
|
||||
data : $(obj).serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert('设置保存成功!', {
|
||||
icon: 1,
|
||||
closeBtn: false
|
||||
}, function(){
|
||||
window.location.reload()
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
function queryapi(){
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/optimizeip/queryapi',
|
||||
data : $("form").serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.alert(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -27,8 +27,8 @@
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
@@ -109,8 +109,8 @@
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.20.2/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.21.4/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}select2/4.0.13/js/select2.min.js"></script>
|
||||
<script src="{$cdnpublic}select2/4.0.13/js/i18n/zh-CN.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
@@ -253,7 +253,7 @@ function save(){
|
||||
}, function(){
|
||||
layer.closeAll();
|
||||
$("#modal-store").modal('hide');
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
@@ -271,7 +271,7 @@ function setStatus(id,status) {
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.msg(data.msg, {icon:2, time:1500});
|
||||
}
|
||||
@@ -292,7 +292,7 @@ function delItem(id) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
layer.closeAll();
|
||||
searchSubmit();
|
||||
searchRefresh();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2});
|
||||
}
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
{
|
||||
"name": "topthink/think",
|
||||
"description": "the new thinkphp framework",
|
||||
"name": "netcccyun/dnsmgr",
|
||||
"description": "聚合DNS管理系统",
|
||||
"type": "project",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"thinkphp",
|
||||
"ORM"
|
||||
"dns",
|
||||
"dnsmanager",
|
||||
"cccyun"
|
||||
],
|
||||
"homepage": "https://www.thinkphp.cn/",
|
||||
"homepage": "https://blog.cccyun.cn/post-526.html",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "liu21st",
|
||||
"email": "liu21st@gmail.com"
|
||||
"email": "liu21st@gmail.com",
|
||||
"role": "Framework Developer"
|
||||
},
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
"email": "448901948@qq.com",
|
||||
"role": "Framework Developer"
|
||||
},
|
||||
{
|
||||
"name": "netcccyun",
|
||||
"homepage": "https://blog.cccyun.cn",
|
||||
"role": "Project Owner"
|
||||
},
|
||||
{
|
||||
"name": "coolxitech",
|
||||
"email": "admin@kuxi.tech",
|
||||
"homepage": "https://www.kuxi.tech",
|
||||
"role": "Project Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"php": ">=7.4.0",
|
||||
"ext-pdo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-curl": "*",
|
||||
"topthink/framework": "^6.0.0",
|
||||
"topthink/think-orm": "^2.0",
|
||||
"topthink/think-view": "^1.0",
|
||||
|
||||
@@ -28,9 +28,10 @@ return [
|
||||
// 错误显示信息,非调试模式有效
|
||||
'error_message' => '页面错误!请稍后再试~',
|
||||
// 显示错误信息
|
||||
'show_error_msg' => false,
|
||||
'show_error_msg' => true,
|
||||
'exception_tmpl' => \think\facade\App::getAppPath() . 'view/exception.tpl',
|
||||
|
||||
'version' => '1004',
|
||||
'version' => '1018',
|
||||
|
||||
'dbversion' => '1003'
|
||||
'dbversion' => '1011'
|
||||
];
|
||||
|
||||
@@ -30,7 +30,8 @@ return [
|
||||
'imageH' => 0,
|
||||
// 验证码图片宽度
|
||||
'imageW' => 0,
|
||||
|
||||
// 验证成功后是否重置
|
||||
'reset' => true,
|
||||
// 添加额外的验证码设置
|
||||
// verify => [
|
||||
// 'length'=>4,
|
||||
|
||||
@@ -6,5 +6,6 @@ return [
|
||||
// 指令定义
|
||||
'commands' => [
|
||||
'dmtask' => 'app\command\Dmtask',
|
||||
'opiptask' => 'app\command\Opiptask',
|
||||
],
|
||||
];
|
||||
|
||||
BIN
public/static/images/huoshan.ico
Normal file
BIN
public/static/images/huoshan.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
BIN
public/static/images/namesilo.ico
Normal file
BIN
public/static/images/namesilo.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
@@ -14,10 +14,18 @@ if (parameter_str !== undefined) {
|
||||
window.$_GET = [];
|
||||
}
|
||||
|
||||
function searchSubmit(){
|
||||
function searchRefresh(){
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
return false;
|
||||
}
|
||||
function searchSubmit(){
|
||||
if(typeof sidePagination != 'undefined' && sidePagination == 'client'){
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
}else{
|
||||
$('#listTable').bootstrapTable('selectPage', 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function searchClear(){
|
||||
$('#searchToolbar').find('input[name]').each(function() {
|
||||
$(this).val('');
|
||||
@@ -25,7 +33,11 @@ function searchClear(){
|
||||
$('#searchToolbar').find('select[name]').each(function() {
|
||||
$(this).find('option:first').prop("selected", 'selected');
|
||||
});
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
if(typeof sidePagination != 'undefined' && sidePagination == 'client'){
|
||||
$('#listTable').bootstrapTable('refresh');
|
||||
}else{
|
||||
$('#listTable').bootstrapTable('selectPage', 1);
|
||||
}
|
||||
}
|
||||
function updateToolbar(){
|
||||
$('#searchToolbar').find(':input[name]').each(function() {
|
||||
@@ -67,6 +79,7 @@ if (typeof $.fn.bootstrapTable !== "undefined") {
|
||||
queryParamsType: '',
|
||||
queryParams: function(params) {
|
||||
$('#searchToolbar').find(':input[name]').each(function() {
|
||||
if(!$(this).is(":visible")) return;
|
||||
params[$(this).attr('name')] = $(this).val()
|
||||
})
|
||||
updateQueryStr(params);
|
||||
@@ -130,4 +143,32 @@ var isMobile = function(){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function setCookie(name,value,expire = null)
|
||||
{
|
||||
var cookie = name + "=" + escape(value);
|
||||
if(expire){
|
||||
var exp = new Date();
|
||||
exp.setTime(exp.getTime() + expire*1000);
|
||||
cookie += ";expires=" + exp.toGMTString();
|
||||
}
|
||||
document.cookie = cookie;
|
||||
}
|
||||
function getCookie(name)
|
||||
{
|
||||
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
|
||||
if(arr=document.cookie.match(reg))
|
||||
return unescape(arr[2]);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
function delCookie(name)
|
||||
{
|
||||
var exp = new Date();
|
||||
exp.setTime(exp.getTime() - 1);
|
||||
var cval=getCookie(name);
|
||||
if(cval!=null){
|
||||
document.cookie= name + "="+cval+";expires="+exp.toGMTString();
|
||||
}
|
||||
}
|
||||
@@ -8,28 +8,34 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
use app\middleware\AuthApi;
|
||||
use app\middleware\CheckLogin;
|
||||
use app\middleware\ViewOutput;
|
||||
use think\facade\Route;
|
||||
use think\middleware\SessionInit;
|
||||
|
||||
Route::pattern([
|
||||
'id' => '\d+',
|
||||
]);
|
||||
|
||||
Route::any('/install', 'install/index')
|
||||
->middleware(\app\middleware\ViewOutput::class);
|
||||
->middleware(ViewOutput::class);
|
||||
|
||||
Route::get('/verifycode', 'auth/verifycode')->middleware(\think\middleware\SessionInit::class)
|
||||
->middleware(\app\middleware\ViewOutput::class);
|
||||
Route::any('/login', 'auth/login')->middleware(\think\middleware\SessionInit::class)
|
||||
->middleware(\app\middleware\ViewOutput::class);
|
||||
Route::get('/verifycode', 'auth/verifycode')->middleware(SessionInit::class)
|
||||
->middleware(ViewOutput::class);
|
||||
Route::any('/login', 'auth/login')->middleware(SessionInit::class)
|
||||
->middleware(ViewOutput::class);
|
||||
Route::get('/logout', 'auth/logout');
|
||||
Route::any('/quicklogin', 'auth/quicklogin');
|
||||
Route::any('/dmtask/status', 'dmonitor/status');
|
||||
Route::any('/optimizeip/status', 'optimizeip/status');
|
||||
|
||||
Route::group(function () {
|
||||
Route::any('/', 'index/index');
|
||||
Route::post('/changeskin', 'index/changeskin');
|
||||
Route::get('/cleancache', 'index/cleancache');
|
||||
Route::any('/setpwd', 'index/setpwd');
|
||||
Route::get('/test', 'index/test');
|
||||
|
||||
Route::post('/user/data', 'user/user_data');
|
||||
Route::post('/user/op', 'user/user_op');
|
||||
@@ -54,6 +60,8 @@ Route::group(function () {
|
||||
Route::post('/record/status/:id', 'domain/record_status');
|
||||
Route::post('/record/remark/:id', 'domain/record_remark');
|
||||
Route::post('/record/batch/:id', 'domain/record_batch');
|
||||
Route::post('/record/batchedit/:id', 'domain/record_batch_edit');
|
||||
Route::any('/record/batchadd/:id', 'domain/record_batch_add');
|
||||
Route::any('/record/log/:id', 'domain/record_log');
|
||||
Route::post('/record/list', 'domain/record_list');
|
||||
Route::get('/record/:id', 'domain/record');
|
||||
@@ -65,11 +73,20 @@ Route::group(function () {
|
||||
Route::any('/dmonitor/task/:action', 'dmonitor/taskform');
|
||||
Route::get('/dmonitor/task', 'dmonitor/task');
|
||||
Route::any('/dmonitor/noticeset', 'dmonitor/noticeset');
|
||||
Route::any('/dmonitor/proxyset', 'dmonitor/proxyset');
|
||||
Route::get('/dmonitor/mailtest', 'dmonitor/mailtest');
|
||||
Route::get('/dmonitor/tgbottest', 'dmonitor/tgbottest');
|
||||
Route::post('/dmonitor/proxytest', 'dmonitor/proxytest');
|
||||
Route::post('/dmonitor/clean', 'dmonitor/clean');
|
||||
|
||||
})->middleware(\app\middleware\CheckLogin::class)
|
||||
->middleware(\app\middleware\ViewOutput::class);
|
||||
Route::any('/optimizeip/opipset', 'optimizeip/opipset');
|
||||
Route::post('/optimizeip/queryapi', 'optimizeip/queryapi');
|
||||
Route::post('/optimizeip/opiplist/data', 'optimizeip/opiplist_data');
|
||||
Route::get('/optimizeip/opiplist', 'optimizeip/opiplist');
|
||||
Route::any('/optimizeip/opipform/:action', 'optimizeip/opipform');
|
||||
|
||||
})->middleware(CheckLogin::class)
|
||||
->middleware(ViewOutput::class);
|
||||
|
||||
Route::group('api', function () {
|
||||
Route::post('/domain/:id', 'domain/domain_info');
|
||||
@@ -83,7 +100,7 @@ Route::group('api', function () {
|
||||
Route::post('/record/remark/:id', 'domain/record_remark');
|
||||
Route::post('/record/batch/:id', 'domain/record_batch');
|
||||
|
||||
})->middleware(\app\middleware\AuthApi::class);
|
||||
})->middleware(AuthApi::class);
|
||||
|
||||
Route::miss(function() {
|
||||
return response('404 Not Found')->code(404);
|
||||
|
||||
Reference in New Issue
Block a user