feat(cloudflare): 添加快速添加TXT记录功能

- 在主机名验证对话框中增加快速添加TXT记录按钮
- 实现convertFullHostnameToRecordName函数用于转换完整主机名为记录名
- 添加quickAddTxtRecord函数处理TXT记录的快速添加逻辑
- 在前端页面中集成快速添加功能,支持一键添加证书验证所需的TXT记录
- 移除SSL配置中的bundle_method和certificate_authority字段

```
This commit is contained in:
luo-bo
2026-03-24 03:45:22 +08:00
parent 7d02f15fde
commit c64a385ffc
3 changed files with 156 additions and 6 deletions

View File

@@ -1,4 +1,5 @@
var currentVerificationHostnameId = '';
var currentDomainName = '6byj.cn';
$(document).ready(function(){
$("#form-store").bootstrapValidator();
@@ -191,6 +192,7 @@ function renderVerificationDialog(row){
renderCopyInput('记录类型', ownership.type || 'txt', false)
+ renderCopyInput('TXT 名称', ownership.name || '', true)
+ renderCopyTextarea('TXT 值', ownership.value || '', true, 3)
+ renderQuickAddTxtButton(ownership.name || '', ownership.value || '', '快速添加所有权 TXT')
);
}
@@ -213,6 +215,7 @@ function renderVerificationDialog(row){
recordsHtml += '<div class="panel-body">';
recordsHtml += renderCopyInput('TXT 名称', item.txt_name || '', true);
recordsHtml += renderCopyTextarea('TXT 值', item.txt_value || '', true, 3);
recordsHtml += renderQuickAddTxtButton(item.txt_name || '', item.txt_value || '', '快速添加 TXT');
recordsHtml += renderCopyInput('CNAME 名称', item.cname_name || '', true);
recordsHtml += renderCopyTextarea('CNAME 目标', item.cname_target || '', true, 2);
recordsHtml += renderCopyTextarea('HTTP URL', item.http_url || '', true, 2);
@@ -274,6 +277,15 @@ function renderCopyTextarea(label, value, copyable, rows){
return html;
}
function renderQuickAddTxtButton(name, value, label){
var txtName = String(name || '').trim();
var txtValue = String(value || '').trim();
if(!txtName || !txtValue){
return '';
}
return '<div class="text-right" style="margin-top:8px;margin-bottom:12px;"><button type="button" class="btn btn-success btn-xs" data-name="' + encodeURIComponent(txtName) + '" data-value="' + encodeURIComponent(txtValue) + '" onclick="quickAddTxtRecord(this)">' + htmlEscape(label || '快速添加 TXT') + '</button></div>';
}
function formatStatusText(value){
var text = value || '-';
if(text === '-'){
@@ -316,6 +328,72 @@ function fallbackCopyText(text){
$temp.remove();
}
function quickAddTxtRecord(btn){
var fullName = decodeURIComponent($(btn).attr('data-name') || '');
var value = decodeURIComponent($(btn).attr('data-value') || '');
var rr = convertFullHostnameToRecordName(fullName);
if(rr === null){
layer.alert('TXT 记录名称与当前域名不匹配,无法自动添加,请手动到解析页添加', {icon: 2});
return;
}
layer.confirm('确定要快速添加 TXT 记录吗?<br><code>' + htmlEscape(fullName) + '</code>', {title: '提示', icon: 0}, function(){
var ii = layer.load(2);
$.ajax({
type: 'POST',
url: '/record/add/1',
data: {
name: rr,
type: 'TXT',
value: value,
line: '0',
ttl: 600,
mx: 1,
weight: 0,
remark: 'Cloudflare证书校验'
},
dataType: 'json',
success: function(res){
layer.close(ii);
if(res.code === 0){
layer.closeAll();
$("#modal-verification").modal('show');
layer.msg('TXT 记录添加成功', {icon: 1, time: 1200});
}else{
layer.alert(res.msg, {icon: 2});
}
},
error: function(){
layer.close(ii);
layer.alert('服务器错误', {icon: 2});
}
});
});
}
function convertFullHostnameToRecordName(fullName){
var name = String(fullName || '').trim().replace(/\.$/, '');
var domain = String(currentDomainName || '').trim().replace(/\.$/, '');
if(!name || !domain){
return null;
}
var lowerName = name.toLowerCase();
var lowerDomain = domain.toLowerCase();
if(lowerName === lowerDomain){
return '@';
}
if(lowerName.endsWith('.' + lowerDomain)){
return name.slice(0, name.length - domain.length - 1);
}
if(name === '@'){
return '@';
}
if(name.indexOf('.') === -1){
return name;
}
return null;
}
function deleteHostname(id, hostname){
layer.confirm('确定要删除自定义主机名 ' + hostname + ' 吗?', {title: '提示', icon: 0}, function(){
var ii = layer.load(2);

View File

@@ -641,12 +641,6 @@ class Cloudflare extends BaseController
if ($payload['type'] === '') {
$payload['type'] = 'dv';
}
if (!empty($ssl['bundle_method'])) {
$payload['bundle_method'] = trim((string)$ssl['bundle_method']);
}
if (!empty($ssl['certificate_authority'])) {
$payload['certificate_authority'] = trim((string)$ssl['certificate_authority']);
}
return $payload;
}

View File

@@ -100,6 +100,7 @@
<script src="/static/js/custom.js"></script>
<script>
var currentVerificationHostnameId = '';
var currentDomainName = '{$domainName}';
$(document).ready(function(){
$("#form-store").bootstrapValidator();
@@ -292,6 +293,7 @@ function renderVerificationDialog(row){
renderCopyInput('记录类型', ownership.type || 'txt', false)
+ renderCopyInput('TXT 名称', ownership.name || '', true)
+ renderCopyTextarea('TXT 值', ownership.value || '', true, 3)
+ renderQuickAddTxtButton(ownership.name || '', ownership.value || '', '快速添加所有权 TXT')
);
}
@@ -314,6 +316,7 @@ function renderVerificationDialog(row){
recordsHtml += '<div class="panel-body">';
recordsHtml += renderCopyInput('TXT 名称', item.txt_name || '', true);
recordsHtml += renderCopyTextarea('TXT 值', item.txt_value || '', true, 3);
recordsHtml += renderQuickAddTxtButton(item.txt_name || '', item.txt_value || '', '快速添加 TXT');
recordsHtml += renderCopyInput('CNAME 名称', item.cname_name || '', true);
recordsHtml += renderCopyTextarea('CNAME 目标', item.cname_target || '', true, 2);
recordsHtml += renderCopyTextarea('HTTP URL', item.http_url || '', true, 2);
@@ -375,6 +378,15 @@ function renderCopyTextarea(label, value, copyable, rows){
return html;
}
function renderQuickAddTxtButton(name, value, label){
var txtName = String(name || '').trim();
var txtValue = String(value || '').trim();
if(!txtName || !txtValue){
return '';
}
return '<div class="text-right" style="margin-top:8px;margin-bottom:12px;"><button type="button" class="btn btn-success btn-xs" data-name="' + encodeURIComponent(txtName) + '" data-value="' + encodeURIComponent(txtValue) + '" onclick="quickAddTxtRecord(this)">' + htmlEscape(label || '快速添加 TXT') + '</button></div>';
}
function formatStatusText(value){
var text = value || '-';
if(text === '-'){
@@ -417,6 +429,72 @@ function fallbackCopyText(text){
$temp.remove();
}
function quickAddTxtRecord(btn){
var fullName = decodeURIComponent($(btn).attr('data-name') || '');
var value = decodeURIComponent($(btn).attr('data-value') || '');
var rr = convertFullHostnameToRecordName(fullName);
if(rr === null){
layer.alert('TXT 记录名称与当前域名不匹配,无法自动添加,请手动到解析页添加', {icon: 2});
return;
}
layer.confirm('确定要快速添加 TXT 记录吗?<br><code>' + htmlEscape(fullName) + '</code>', {title: '提示', icon: 0}, function(){
var ii = layer.load(2);
$.ajax({
type: 'POST',
url: '/record/add/{$domainId}',
data: {
name: rr,
type: 'TXT',
value: value,
line: '0',
ttl: 600,
mx: 1,
weight: 0,
remark: 'Cloudflare证书校验'
},
dataType: 'json',
success: function(res){
layer.close(ii);
if(res.code === 0){
layer.closeAll();
$("#modal-verification").modal('show');
layer.msg('TXT 记录添加成功', {icon: 1, time: 1200});
}else{
layer.alert(res.msg, {icon: 2});
}
},
error: function(){
layer.close(ii);
layer.alert('服务器错误', {icon: 2});
}
});
});
}
function convertFullHostnameToRecordName(fullName){
var name = String(fullName || '').trim().replace(/\.$/, '');
var domain = String(currentDomainName || '').trim().replace(/\.$/, '');
if(!name || !domain){
return null;
}
var lowerName = name.toLowerCase();
var lowerDomain = domain.toLowerCase();
if(lowerName === lowerDomain){
return '@';
}
if(lowerName.endsWith('.' + lowerDomain)){
return name.slice(0, name.length - domain.length - 1);
}
if(name === '@'){
return '@';
}
if(name.indexOf('.') === -1){
return name;
}
return null;
}
function deleteHostname(id, hostname){
layer.confirm('确定要删除自定义主机名 ' + hostname + ' 吗?', {title: '提示', icon: 0}, function(){
var ii = layer.load(2);