Cloudflare增强添加DCV 委派+优化,添加快速解析功能,已有解析记录和智能批量添加 (#442)

* Update RewriteRule in .htaccess for cleaner routing

修复Apache环境下路由重写规则
废弃旧版 index.php/$1 写法,改用兼容新版PHP的PATH_INFO传参方式
解决访问时报错 No input file specified. 问题

* Add files via upload

1.添加DCV 委派一键添加CNAME
2.添加证书验证方法和最低 TLS 版本
3.添加批量添加 修改 删除
4.修复华为云一键txt解析失败(我没其他dns, 其他的需关注)
5.Cloudflare增强改Cloudflare自定义主机名

* 1.添加快速解析 2.Cloudflare自定义主机名添加搜索功能

* Add files via upload

1.Cloudflare自定义主机名自动获取默认线路(支持所有dns,华为云退回之前)
2.优化手机上显示问题
3.一键添加 DCV 委派支持选择要写入的解析域名

* 优化手机显示

* 添加1. 批量 DCV 委派 2. 批量主机名 TXT 验证 3. 批量证书 TXT 验证 4. 批量刷新验证

1. 批量 DCV 委派
2. 批量主机名 TXT 验证
3. 批量证书 TXT 验证
4. 批量刷新验证

* 快速解析改名智能解析,添加已有解析记录和智能批量添加

* 快速解析改名智能解析,添加已有解析记录和智能批量添加

* 由于之前复制保存的,代码有些差异

* 修复已有解析记录的备注功能

* 备注按dns显示

* 修复记录值过长无法复制,优化显示

* 优化显示
This commit is contained in:
wmwlwmwl
2026-04-23 23:15:28 +08:00
committed by GitHub
parent 75a8aa97b8
commit 668e2b4ceb
9 changed files with 4584 additions and 121 deletions

View File

@@ -43,15 +43,23 @@ class Cloudflare extends BaseController
$context = $this->getCloudflareDomainContext(input('param.id/d')); $context = $this->getCloudflareDomainContext(input('param.id/d'));
$hostname = trim(input('post.hostname', '', 'trim')); $hostname = trim(input('post.hostname', '', 'trim'));
$origin = trim(input('post.custom_origin_server', '', 'trim')); $origin = trim(input('post.custom_origin_server', '', 'trim'));
$sslMethod = trim(input('post.ssl_method', 'txt', 'trim'));
$minTlsVersion = trim(input('post.min_tls_version', '1.0', 'trim'));
if (empty($hostname) || !checkDomain($hostname)) { if (empty($hostname) || !checkDomain($hostname)) {
throw new Exception('主机名格式不正确'); throw new Exception('主机名格式不正确');
} }
if (!in_array($sslMethod, ['txt', 'http'])) {
throw new Exception('证书验证方法无效');
}
if (!in_array($minTlsVersion, ['1.0', '1.1', '1.2', '1.3'])) {
throw new Exception('最低 TLS 版本无效');
}
if ($origin !== '') { if ($origin !== '') {
$this->validateCustomOrigin($origin); $this->validateCustomOrigin($origin);
} }
$result = $context['service']->createCustomHostname($context['domain']['thirdid'], $hostname, $origin !== '' ? $origin : null); $result = $context['service']->createCustomHostname($context['domain']['thirdid'], $hostname, $origin !== '' ? $origin : null, $sslMethod, $minTlsVersion);
$this->add_log($context['domain']['name'], '创建自定义主机名', $hostname . ($origin !== '' ? ' -> ' . $origin : '')); $this->add_log($context['domain']['name'], '创建自定义主机名', $hostname . ($origin !== '' ? ' -> ' . $origin : '') . ' (验证: ' . $sslMethod . ', TLS: ' . $minTlsVersion . ')');
return json(['code' => 0, 'msg' => '创建自定义主机名成功', 'data' => $this->formatCustomHostnameRow($result)]); return json(['code' => 0, 'msg' => '创建自定义主机名成功', 'data' => $this->formatCustomHostnameRow($result)]);
} catch (Exception $e) { } catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]); return json(['code' => -1, 'msg' => $e->getMessage()]);
@@ -70,6 +78,14 @@ class Cloudflare extends BaseController
$current = $context['service']->getCustomHostname($context['domain']['thirdid'], $hostnameId); $current = $context['service']->getCustomHostname($context['domain']['thirdid'], $hostnameId);
$hostname = trim((string)($current['hostname'] ?? '')); $hostname = trim((string)($current['hostname'] ?? ''));
$origin = trim(input('post.custom_origin_server', '', 'trim')); $origin = trim(input('post.custom_origin_server', '', 'trim'));
$sslMethod = trim(input('post.ssl_method', 'txt', 'trim'));
$minTlsVersion = trim(input('post.min_tls_version', '1.0', 'trim'));
if (!in_array($sslMethod, ['txt', 'http'])) {
throw new Exception('证书验证方法无效');
}
if (!in_array($minTlsVersion, ['1.0', '1.1', '1.2', '1.3'])) {
throw new Exception('最低 TLS 版本无效');
}
if ($origin !== '') { if ($origin !== '') {
$this->validateCustomOrigin($origin); $this->validateCustomOrigin($origin);
} }
@@ -79,10 +95,10 @@ class Cloudflare extends BaseController
$hostnameId, $hostnameId,
[ [
'custom_origin_server' => $origin !== '' ? $origin : null, 'custom_origin_server' => $origin !== '' ? $origin : null,
'ssl' => $this->extractCustomHostnameSslPayload($current), 'ssl' => $this->extractCustomHostnameSslPayload($current, $sslMethod, $minTlsVersion),
] ]
); );
$this->add_log($context['domain']['name'], '编辑自定义主机名', $hostname . ' -> ' . ($origin !== '' ? $origin : '清空源站')); $this->add_log($context['domain']['name'], '编辑自定义主机名', $hostname . ' -> ' . ($origin !== '' ? $origin : '清空源站') . ' (验证: ' . $sslMethod . ', TLS: ' . $minTlsVersion . ')');
return json(['code' => 0, 'msg' => '更新自定义主机名成功', 'data' => $this->formatCustomHostnameRow($result)]); return json(['code' => 0, 'msg' => '更新自定义主机名成功', 'data' => $this->formatCustomHostnameRow($result)]);
} catch (Exception $e) { } catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]); return json(['code' => -1, 'msg' => $e->getMessage()]);
@@ -109,8 +125,8 @@ class Cloudflare extends BaseController
'ssl' => $this->extractCustomHostnameSslPayload($current), 'ssl' => $this->extractCustomHostnameSslPayload($current),
] ]
); );
$this->add_log($context['domain']['name'], '刷新自定义主机名验', $hostname); $this->add_log($context['domain']['name'], '刷新自定义主机名验', $hostname);
return json(['code' => 0, 'msg' => '已向 Cloudflare 重新发起验', 'data' => $this->formatCustomHostnameRow($result)]); return json(['code' => 0, 'msg' => '已向 Cloudflare 重新发起验', 'data' => $this->formatCustomHostnameRow($result)]);
} catch (Exception $e) { } catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]); return json(['code' => -1, 'msg' => $e->getMessage()]);
} }
@@ -125,15 +141,170 @@ class Cloudflare extends BaseController
if ($hostnameId === '') { if ($hostnameId === '') {
throw new Exception('缺少 hostname_id'); throw new Exception('缺少 hostname_id');
} }
$context['service']->deleteCustomHostname($context['domain']['thirdid'], $hostnameId); $context['service']->deleteCustomHostname($context['domain']['thirdid'], $hostnameId);
$this->add_log($context['domain']['name'], '删除自定义主机名', $hostname !== '' ? $hostname : $hostnameId); $this->add_log($context['domain']['name'], '删除自定义主机名', $hostname);
return json(['code' => 0, 'msg' => '删除自定义主机名成功']); return json(['code' => 0, 'msg' => '删除自定义主机名成功']);
} catch (Exception $e) { } catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]); return json(['code' => -1, 'msg' => $e->getMessage()]);
} }
} }
public function hostnames_batch_delete()
{
try {
$context = $this->getCloudflareDomainContext(input('param.id/d'));
$hostnameIds = input('post.hostname_ids/a', []);
if (empty($hostnameIds)) {
throw new Exception('缺少 hostname_ids');
}
$deletedCount = 0;
foreach ($hostnameIds as $hostnameId) {
if (trim((string)$hostnameId) !== '') {
try {
// 获取主机名信息用于日志
$hostnameInfo = $context['service']->getCustomHostname($context['domain']['thirdid'], trim((string)$hostnameId));
$hostname = trim((string)($hostnameInfo['hostname'] ?? ''));
$context['service']->deleteCustomHostname($context['domain']['thirdid'], trim((string)$hostnameId));
$deletedCount++;
// 为每个成功删除的主机名记录单独的日志
$this->add_log($context['domain']['name'], '批量删除自定义主机名', $hostname);
} catch (Exception $e) {
// 忽略删除失败的情况,继续处理其他主机名
}
}
}
return json(['code' => 0, 'msg' => '批量删除成功,共删除 ' . $deletedCount . ' 个自定义主机名']);
} catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]);
}
}
public function hostnames_batch_update()
{
try {
$context = $this->getCloudflareDomainContext(input('param.id/d'));
$hostnameIds = input('post.hostname_ids/s', '');
$hostnameIdArray = array_filter(array_map('trim', explode(',', $hostnameIds)));
if (empty($hostnameIdArray)) {
throw new Exception('缺少 hostname_ids');
}
$origin = trim(input('post.custom_origin_server', '', 'trim'));
$sslMethod = trim(input('post.ssl_method', '', 'trim'));
$minTlsVersion = trim(input('post.min_tls_version', '', 'trim'));
if (!empty($sslMethod) && !in_array($sslMethod, ['txt', 'http'])) {
throw new Exception('证书验证方法无效');
}
if (!empty($minTlsVersion) && !in_array($minTlsVersion, ['1.0', '1.1', '1.2', '1.3'])) {
throw new Exception('最低 TLS 版本无效');
}
if ($origin !== '') {
$this->validateCustomOrigin($origin);
}
$updatedCount = 0;
foreach ($hostnameIdArray as $hostnameId) {
if (trim((string)$hostnameId) !== '') {
try {
$current = $context['service']->getCustomHostname($context['domain']['thirdid'], $hostnameId);
$hostname = trim((string)($current['hostname'] ?? ''));
$payload = [];
// 总是设置 custom_origin_server留空时设置为 null 表示清空
$payload['custom_origin_server'] = $origin !== '' ? $origin : null;
if (!empty($sslMethod) || !empty($minTlsVersion)) {
$payload['ssl'] = $this->extractCustomHostnameSslPayload($current, $sslMethod, $minTlsVersion);
}
if (!empty($payload)) {
$context['service']->updateCustomHostname($context['domain']['thirdid'], $hostnameId, $payload);
$updatedCount++;
// 为每个成功修改的主机名记录单独的日志
$logMessage = $hostname . ' -> ' . ($origin !== '' ? $origin : '清空源站') . ' (验证: ' . ($sslMethod ?: '保持不变') . ', TLS: ' . ($minTlsVersion ?: '保持不变') . ')';
$this->add_log($context['domain']['name'], '批量修改自定义主机名', $logMessage);
}
} catch (Exception $e) {
// 忽略修改失败的情况,继续处理其他主机名
}
}
}
return json(['code' => 0, 'msg' => '批量修改成功,共修改 ' . $updatedCount . ' 个自定义主机名']);
} catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]);
}
}
public function hostnames_batch_add()
{
try {
$context = $this->getCloudflareDomainContext(input('param.id/d'));
$hostnamesText = trim(input('post.hostnames', '', 'trim'));
$origin = trim(input('post.custom_origin_server', '', 'trim'));
$sslMethod = trim(input('post.ssl_method', 'txt', 'trim'));
$minTlsVersion = trim(input('post.min_tls_version', '1.0', 'trim'));
if (empty($hostnamesText)) {
throw new Exception('缺少主机名列表');
}
if (!in_array($sslMethod, ['txt', 'http'])) {
throw new Exception('证书验证方法无效');
}
if (!in_array($minTlsVersion, ['1.0', '1.1', '1.2', '1.3'])) {
throw new Exception('最低 TLS 版本无效');
}
if ($origin !== '') {
$this->validateCustomOrigin($origin);
}
$hostnames = array_filter(array_map('trim', explode("\n", $hostnamesText)));
if (empty($hostnames)) {
throw new Exception('主机名列表为空');
}
$addedCount = 0;
$failedHostnames = [];
foreach ($hostnames as $hostname) {
if (empty($hostname)) {
continue;
}
if (!checkDomain($hostname)) {
$failedHostnames[] = $hostname . '(格式不正确)';
continue;
}
try {
$context['service']->createCustomHostname(
$context['domain']['thirdid'],
$hostname,
$origin !== '' ? $origin : null,
$sslMethod,
$minTlsVersion
);
$addedCount++;
// 为每个成功添加的主机名记录单独的日志
$logMessage = $hostname . ($origin !== '' ? ' -> ' . $origin : '') . ' (验证: ' . $sslMethod . ', TLS: ' . $minTlsVersion . ')';
$this->add_log($context['domain']['name'], '批量添加自定义主机名', $logMessage);
} catch (Exception $e) {
$failedHostnames[] = $hostname . '' . $e->getMessage() . '';
}
}
$message = '批量添加成功,共添加 ' . $addedCount . ' 个自定义主机名';
if (!empty($failedHostnames)) {
$message .= ',失败 ' . count($failedHostnames) . ' 个:' . implode('; ', $failedHostnames);
}
return json(['code' => 0, 'msg' => $message]);
} catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]);
}
}
public function hostnames_txt_targets() public function hostnames_txt_targets()
{ {
try { try {
@@ -196,6 +367,77 @@ class Cloudflare extends BaseController
} }
} }
public function dcv_delegation_uuid()
{
try {
$context = $this->getCloudflareDomainContext(input('param.id/d'));
$uuid = $context['service']->getDcvDelegationUuid($context['domain']['thirdid']);
return json(['code' => 0, 'data' => ['uuid' => $uuid]]);
} catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]);
}
}
public function get_domain_default_line()
{
try {
$domainId = input('param.domain_id/d');
if (empty($domainId)) {
throw new Exception('缺少 domain_id 参数');
}
// 查询域名信息
$domainRow = Db::name('domain')->alias('A')
->join('account B', 'A.aid = B.id')
->where('A.id', $domainId)
->field('A.*, B.type, B.config account_config')
->find();
if (!$domainRow) {
throw new Exception('域名不存在');
}
// 获取该域名的默认线路
$recordLine = cache('record_line_' . $domainId);
if (empty($recordLine)) {
// 缓存中没有,需要从 DNS 提供商获取
$config = json_decode($domainRow['account_config'] ?? '', true);
if (!is_array($config)) {
$config = [];
}
$dnsModel = \app\lib\DnsHelper::getModel(
intval($domainRow['aid']),
$domainRow['name'],
$domainRow['thirdid'],
$domainRow['type'],
$config
);
if ($dnsModel && method_exists($dnsModel, 'getRecordLine')) {
$recordLine = $dnsModel->getRecordLine();
if ($recordLine && is_array($recordLine)) {
cache('record_line_' . $domainId, $recordLine, 604800); // 缓存7天
}
}
}
if (empty($recordLine) || !is_array($recordLine)) {
throw new Exception('无法获取该域名的解析线路列表');
}
$firstKey = array_key_first($recordLine);
if ($firstKey === null) {
throw new Exception('解析线路列表为空');
}
return json(['code' => 0, 'data' => ['default_line' => strval($firstKey)]]);
} catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]);
}
}
public function tunnels() public function tunnels()
{ {
try { try {
@@ -650,11 +892,11 @@ class Cloudflare extends BaseController
} }
} }
private function extractCustomHostnameSslPayload(array $row): array private function extractCustomHostnameSslPayload(array $row, string $sslMethod = '', string $minTlsVersion = ''): array
{ {
$ssl = isset($row['ssl']) && is_array($row['ssl']) ? $row['ssl'] : []; $ssl = isset($row['ssl']) && is_array($row['ssl']) ? $row['ssl'] : [];
$payload = [ $payload = [
'method' => trim((string)($ssl['method'] ?? 'http')), 'method' => $sslMethod !== '' ? $sslMethod : trim((string)($ssl['method'] ?? 'http')),
'type' => trim((string)($ssl['type'] ?? 'dv')), 'type' => trim((string)($ssl['type'] ?? 'dv')),
]; ];
if ($payload['method'] === '') { if ($payload['method'] === '') {
@@ -663,6 +905,16 @@ class Cloudflare extends BaseController
if ($payload['type'] === '') { if ($payload['type'] === '') {
$payload['type'] = 'dv'; $payload['type'] = 'dv';
} }
// 添加 TLS 版本设置
if ($minTlsVersion !== '') {
$payload['settings'] = [
'min_tls_version' => $minTlsVersion
];
} elseif (isset($ssl['settings']) && is_array($ssl['settings'])) {
$payload['settings'] = $ssl['settings'];
}
return $payload; return $payload;
} }
@@ -755,8 +1007,10 @@ class Cloudflare extends BaseController
'hostname' => trim((string)($row['hostname'] ?? '')), 'hostname' => trim((string)($row['hostname'] ?? '')),
'custom_origin_server' => trim((string)($row['custom_origin_server'] ?? '')), 'custom_origin_server' => trim((string)($row['custom_origin_server'] ?? '')),
'status' => trim((string)($row['status'] ?? '')), 'status' => trim((string)($row['status'] ?? '')),
'ssl' => $ssl,
'ssl_status' => trim((string)($ssl['status'] ?? '')), 'ssl_status' => trim((string)($ssl['status'] ?? '')),
'ssl_method' => trim((string)($ssl['method'] ?? '')), 'ssl_method' => trim((string)($ssl['method'] ?? '')),
'ssl_min_tls_version' => trim((string)($ssl['settings']['min_tls_version'] ?? '')),
'ssl_type' => trim((string)($ssl['type'] ?? '')), 'ssl_type' => trim((string)($ssl['type'] ?? '')),
'ssl_validation_status' => $sslValidationStatus, 'ssl_validation_status' => $sslValidationStatus,
'verification_status' => $verificationStatus !== '' ? $verificationStatus : '-', 'verification_status' => $verificationStatus !== '' ? $verificationStatus : '-',

View File

@@ -1005,6 +1005,68 @@ class Domain extends BaseController
return view('log'); return view('log');
} }
public function smartparse()
{
if (request()->user['type'] == 'domain') {
return redirect('/record/' . request()->user['id']);
}
$list = Db::name('domain')->alias('A')->join('account B', 'A.aid = B.id')
->field('A.id, A.name, A.aid, B.type')
->order('A.name', 'asc')
->select();
$domainList = [];
foreach ($list as $row) {
if (request()->user['level'] == 1 && !in_array($row['name'], request()->user['permission'])) {
continue;
}
$dnsTypeName = isset(DnsHelper::$dns_config[$row['type']]) ? DnsHelper::$dns_config[$row['type']]['name'] : $row['type'];
$domainList[] = [
'id' => $row['id'],
'name' => $row['name'],
'dnsType' => $dnsTypeName
];
}
View::assign('domainList', $domainList);
return view();
}
public function quickinfo()
{
$id = input('param.id/d');
$drow = Db::name('domain')->where('id', $id)->find();
if (!$drow) {
return json(['code' => -1, 'msg' => '域名不存在']);
}
if (!checkPermission(0, $drow['name'])) return json(['code' => -1, 'msg' => '无权限']);
try {
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']];
}
$dnstype = Db::name('account')->where('id', $drow['aid'])->value('type');
$dnsconfig = DnsHelper::$dns_config[$dnstype];
return json([
'code' => 0,
'data' => [
'recordLine' => $recordLineArr,
'minTTL' => $minTTL ? $minTTL : 1,
'weight' => $dnsconfig['weight'] ?? false,
'remark' => $dnsconfig['remark'] ?? 0
]
]);
} catch (Exception $e) {
return json(['code' => -1, 'msg' => $e->getMessage()]);
}
}
private function add_log($domain, $action, $data) private function add_log($domain, $action, $data)
{ {
if (strlen($data) > 500) $data = substr($data, 0, 500); if (strlen($data) > 500) $data = substr($data, 0, 500);

View File

@@ -91,14 +91,17 @@ class CloudflareEnhanceService
} }
} }
public function createCustomHostname(string $zoneId, string $hostname, ?string $customOriginServer = null): array public function createCustomHostname(string $zoneId, string $hostname, ?string $customOriginServer = null, string $sslMethod = 'http', string $minTlsVersion = '1.0'): array
{ {
$hostname = $this->normalizeHostname($hostname); $hostname = $this->normalizeHostname($hostname);
$payload = [ $payload = [
'hostname' => $hostname, 'hostname' => $hostname,
'ssl' => [ 'ssl' => [
'method' => 'http', 'method' => $sslMethod === 'txt' ? 'txt' : 'http',
'type' => 'dv', 'type' => 'dv',
'settings' => [
'min_tls_version' => $minTlsVersion
]
], ],
]; ];
$origin = trim((string)$customOriginServer); $origin = trim((string)$customOriginServer);
@@ -180,6 +183,19 @@ class CloudflareEnhanceService
} }
} }
public function getDcvDelegationUuid(string $zoneId): string
{
try {
$result = $this->requestResult('GET', '/zones/' . $zoneId . '/dcv_delegation/uuid', [], null, true);
if ($result === null) {
return '';
}
return trim((string)($result['uuid'] ?? ''));
} catch (Exception $e) {
$this->throwActionError('获取 DCV 委派 UUID', $e, 'SSL and Certificates:Read');
}
}
public function listTunnels(string $accountId): array public function listTunnels(string $accountId): array
{ {
$this->assertTunnelSupported(); $this->assertTunnelSupported();

File diff suppressed because it is too large Load Diff

View File

@@ -106,9 +106,12 @@
{if request()->user['type'] eq 'user'}<li class="{:checkIfActive('index')}"> {if request()->user['type'] eq 'user'}<li class="{:checkIfActive('index')}">
<a href="/"><i class="fa fa-home fa-fw"></i> <span>后台首页</span></a> <a href="/"><i class="fa fa-home fa-fw"></i> <span>后台首页</span></a>
</li>{/if} </li>{/if}
<li class="{:checkIfActive('domain,record,record_log,record_batch_add,domain_add,weight,record_batch_add2,record_batch_edit2,expire_notice')}"> <li class="{:checkIfActive('domain,record,record_log,record_batch_add,domain_add,weight,record_batch_add2,record_batch_edit2,expire_notice,smartparse')}">
<a href="/domain"><i class="fa fa-list-ul fa-fw"></i> <span>域名管理</span></a> <a href="/domain"><i class="fa fa-list-ul fa-fw"></i> <span>域名管理</span></a>
</li> </li>
<li class="{:checkIfActive('smartparse')}">
<a href="/record/smartparse"><i class="fa fa-magic fa-fw"></i> <span>智能解析</span></a>
</li>
{if request()->user['level'] eq 2} {if request()->user['level'] eq 2}
<li class="{:checkIfActive('account,account_add')}"> <li class="{:checkIfActive('account,account_add')}">
<a href="/account"><i class="fa fa-lock fa-fw"></i> <span>域名账户</span></a> <a href="/account"><i class="fa fa-lock fa-fw"></i> <span>域名账户</span></a>

View File

@@ -183,7 +183,7 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button> <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:searchClear()" class="btn btn-default" title="刷新解析记录列表"><i class="fa fa-refresh"></i> 刷新</a>
<a href="javascript:addframe()" class="btn btn-success"><i class="fa fa-plus"></i> 添加记录</a> <a href="javascript:addframe()" class="btn btn-success"><i class="fa fa-plus"></i> 添加记录</a>
{if $dnsconfig.type=='cloudflare' && $user['level'] eq 2}<a href="/cloudflare/hostnames/{$domainId}" class="btn btn-default">Cloudflare增强</a>{/if} {if $dnsconfig.type=='cloudflare' && $user['level'] eq 2}<a href="/cloudflare/hostnames/{$domainId}" class="btn btn-default">Cloudflare自定义主机名</a>{/if}
{if $dnsconfig.type=='aliyun'}<a href="/record/weight/{$domainId}" class="btn btn-default">权重配置</a>{/if} {if $dnsconfig.type=='aliyun'}<a href="/record/weight/{$domainId}" class="btn btn-default">权重配置</a>{/if}
{if $dnsconfig.type=='dnspod'}<a href="/record/alias/{$domainId}" class="btn btn-default">域名别名</a>{/if} {if $dnsconfig.type=='dnspod'}<a href="/record/alias/{$domainId}" class="btn btn-default">域名别名</a>{/if}
<div class="btn-group" role="group"> <div class="btn-group" role="group">

File diff suppressed because it is too large Load Diff

View File

@@ -4,5 +4,5 @@
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:/$1]
</IfModule> </IfModule>

View File

@@ -55,12 +55,17 @@ Route::group(function () {
Route::post('/cloudflare/hostnames/data/:id', 'cloudflare/hostnames_data'); Route::post('/cloudflare/hostnames/data/:id', 'cloudflare/hostnames_data');
Route::post('/cloudflare/hostnames/add/:id', 'cloudflare/hostnames_add'); Route::post('/cloudflare/hostnames/add/:id', 'cloudflare/hostnames_add');
Route::post('/cloudflare/hostnames/update/:id', 'cloudflare/hostnames_update'); Route::post('/cloudflare/hostnames/update/:id', 'cloudflare/hostnames_update');
Route::post('/cloudflare/hostnames/refresh/:id', 'cloudflare/hostnames_refresh');
Route::post('/cloudflare/hostnames/delete/:id', 'cloudflare/hostnames_delete'); Route::post('/cloudflare/hostnames/delete/:id', 'cloudflare/hostnames_delete');
Route::post('/cloudflare/hostnames/refresh/:id', 'cloudflare/hostnames_refresh');
Route::post('/cloudflare/hostnames/txttargets/:id', 'cloudflare/hostnames_txt_targets'); Route::post('/cloudflare/hostnames/txttargets/:id', 'cloudflare/hostnames_txt_targets');
Route::post('/cloudflare/hostnames/batch_add/:id', 'cloudflare/hostnames_batch_add');
Route::post('/cloudflare/hostnames/batch_delete/:id', 'cloudflare/hostnames_batch_delete');
Route::post('/cloudflare/hostnames/batch_update/:id', 'cloudflare/hostnames_batch_update');
Route::post('/cloudflare/fallback/get/:id', 'cloudflare/fallback_get'); Route::post('/cloudflare/fallback/get/:id', 'cloudflare/fallback_get');
Route::post('/cloudflare/fallback/set/:id', 'cloudflare/fallback_set'); Route::post('/cloudflare/fallback/set/:id', 'cloudflare/fallback_set');
Route::post('/cloudflare/fallback/delete/:id', 'cloudflare/fallback_delete'); Route::post('/cloudflare/fallback/delete/:id', 'cloudflare/fallback_delete');
Route::post('/cloudflare/dcv_delegation_uuid/:id', 'cloudflare/dcv_delegation_uuid');
Route::post('/cloudflare/get_domain_default_line', 'cloudflare/get_domain_default_line');
Route::get('/cloudflare/tunnels/:id', 'cloudflare/tunnels'); Route::get('/cloudflare/tunnels/:id', 'cloudflare/tunnels');
Route::post('/cloudflare/tunnels/data/:id', 'cloudflare/tunnels_data'); Route::post('/cloudflare/tunnels/data/:id', 'cloudflare/tunnels_data');
Route::post('/cloudflare/tunnels/add/:id', 'cloudflare/tunnels_add'); Route::post('/cloudflare/tunnels/add/:id', 'cloudflare/tunnels_add');
@@ -101,6 +106,8 @@ Route::group(function () {
Route::any('/record/weight/:id', 'domain/weight'); Route::any('/record/weight/:id', 'domain/weight');
Route::any('/record/alias/:id', 'domain/alias'); Route::any('/record/alias/:id', 'domain/alias');
Route::get('/record/:id', 'domain/record'); Route::get('/record/:id', 'domain/record');
Route::get('/record/smartparse', 'domain/smartparse');
Route::post('/record/quickinfo/:id', 'domain/quickinfo');
Route::get('/dmonitor/overview', 'dmonitor/overview'); Route::get('/dmonitor/overview', 'dmonitor/overview');
Route::post('/dmonitor/task/data', 'dmonitor/task_data'); Route::post('/dmonitor/task/data', 'dmonitor/task_data');