This commit is contained in:
TomyJan 2026-01-30 23:13:20 +08:00 committed by GitHub
commit 4ef89595db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 111 additions and 15 deletions

View File

@ -85,8 +85,11 @@ class Optimizeip extends BaseController
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 ($task['recordnum'] < 1) {
return json(['code' => -1, 'msg' => '解析数量不能少于1个']);
}
if ($task['recordnum'] > 50) {
return json(['code' => -1, 'msg' => '解析数量不能超过50个']);
}
if (Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->find()) {
return json(['code' => -1, 'msg' => '当前域名的优选IP任务已存在']);
@ -109,8 +112,11 @@ class Optimizeip extends BaseController
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 ($task['recordnum'] < 1) {
return json(['code' => -1, 'msg' => '解析数量不能少于1个']);
}
if ($task['recordnum'] > 50) {
return json(['code' => -1, 'msg' => '解析数量不能超过50个']);
}
if (Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->where('id', '<>', $id)->find()) {
return json(['code' => -1, 'msg' => '当前域名的优选IP任务已存在']);

View File

@ -19,7 +19,7 @@ class OptimizeService
public static function get_license($api, $key)
{
if ($api == 2) {
throw new Exception('当前接口暂不支持');
throw new Exception('xingpingcn.top 接口免费使用,无需密钥,无积分限制');
} elseif ($api == 1) {
$url = 'https://api.hostmonit.com/get_license?license='.$key;
} else {
@ -39,7 +39,9 @@ class OptimizeService
public function get_ip_address($cdn_type = 1, $ip_type = 'v4')
{
$api = config_get('optimize_ip_api', 0);
if ($api == 1) {
if ($api == 2) {
return $this->get_ip_address_xingpingcn($ip_type);
} elseif ($api == 1) {
$url = 'https://api.hostmonit.com/get_optimization_ip';
} else {
$url = 'https://www.wetest.vip/api/cf2dns/';
@ -70,6 +72,59 @@ class OptimizeService
}
}
/**
* xingpingcn.top 获取优选IP数据
* @param string $ip_type IP类型 v4/v6
* @return array
* @throws Exception
*/
private function get_ip_address_xingpingcn($ip_type = 'v4')
{
if ($ip_type == 'v6') {
throw new Exception('xingpingcn.top 接口暂不支持IPv6');
}
$proxy = config_get('optimize_ip_proxy', '');
if (!empty($proxy)) {
$proxy = trim($proxy);
if (filter_var($proxy, FILTER_VALIDATE_URL) === false) {
throw new Exception('无效的代理地址配置URL 格式错误');
}
$scheme = parse_url($proxy, PHP_URL_SCHEME);
if (!in_array($scheme, ['http', 'https'], true)) {
throw new Exception('无效的代理地址配置:仅支持 http 和 https 协议');
}
$url = rtrim($proxy, '/') . '/xingpingcn/enhanced-FaaS-in-China/refs/heads/main/Cf.json';
} else {
$url = 'https://raw.githubusercontent.com/xingpingcn/enhanced-FaaS-in-China/refs/heads/main/Cf.json';
}
$response = get_curl($url);
if ($response === '') {
throw new Exception('获取优选IP数据失败网络请求失败请检查网络连接或代理地址');
}
$arr = json_decode($response, true);
if (isset($arr['Cf']['result'])) {
$result = $arr['Cf']['result'];
$info = [];
// 转换格式dianxin->CT, liantong->CU, yidong->CM, default->DEF
if (isset($result['dianxin']) && is_array($result['dianxin'])) {
$info['CT'] = array_map(function($ip) { return ['ip' => $ip]; }, $result['dianxin']);
}
if (isset($result['liantong']) && is_array($result['liantong'])) {
$info['CU'] = array_map(function($ip) { return ['ip' => $ip]; }, $result['liantong']);
}
if (isset($result['yidong']) && is_array($result['yidong'])) {
$info['CM'] = array_map(function($ip) { return ['ip' => $ip]; }, $result['yidong']);
}
// 不使用他的默认线路数据, 因为这真的是默认. 由后续逻辑自己决定是否把CT线路当DEF来用
// if (isset($result['default']) && is_array($result['default'])) {
// $info['DEF'] = array_map(function($ip) { return ['ip' => $ip]; }, $result['default']);
// }
return $info;
} else {
throw new Exception('获取优选IP数据失败接口返回数据格式错误');
}
}
public function get_ip_address2($cdn_type = 1, $ip_type = 'v4')
{
$key = $cdn_type.'_'.$ip_type;

View File

@ -54,14 +54,14 @@
<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}}
<input type="checkbox" name="ip_type" :value="option.value" v-model="set.ip_type_select" :disabled="option.value=='v6' && isXingpingcn" required> {{option.label}}<span v-if="option.value=='v6' && isXingpingcn" class="text-muted">(xingpingcn.top不支持)</span>
</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>
<input type="text" name="recordnum" v-model="set.recordnum" placeholder="填写每线路解析数量" class="form-control" data-bv-integer="true" min="1" max="50" required>
</div>
</div>
<div class="form-group">
@ -110,6 +110,7 @@ new Vue({
el: '#app',
data: {
action: '{$action}',
optimize_ip_api: '{:config_get("optimize_ip_api", 0)}',
set: {
id: '',
remark: '',
@ -132,8 +133,18 @@ new Vue({
4:'EdgeOne'
},
},
computed: {
isXingpingcn: function() {
return this.optimize_ip_api == '2';
}
},
watch: {
'set.ip_type_select': function(val){
// 如果使用xingpingcn.top接口自动移除v6
if(this.isXingpingcn && val.includes('v6')){
this.set.ip_type_select = val.filter(v => v !== 'v6');
return;
}
this.set.ip_type = val.join(',');
}
},
@ -185,4 +196,4 @@ new Vue({
},
});
</script>
{/block}
{/block}

View File

@ -14,8 +14,9 @@
<div class="panel-heading"><h3 class="panel-title">使用说明</h3></div>
<div class="panel-body">
<p><li>不支持对CloudFlare里的域名添加优选必须使用其他DNS服务商。需开通Cloudflare for SaaS且域名使用CNAME的方式解析到CloudFlare。</li></p>
<p><li>数据接口:<a href="https://www.wetest.vip/" target="_blank" rel="noreferrer">wetest.vip</a> 数据接口支持CloudFlare、CloudFront、EdgeOne<a href="https://stock.hostmonit.com/" target="_blank" rel="noreferrer">HostMonit</a> 只支持CloudFlare。</li></p>
<p><li>数据接口:<a href="https://www.wetest.vip/" target="_blank" rel="noreferrer">wetest.vip</a> 数据接口支持CloudFlare、CloudFront、EdgeOne<a href="https://stock.hostmonit.com/" target="_blank" rel="noreferrer">HostMonit</a> 只支持CloudFlare<a href="https://github.com/xingpingcn/enhanced-FaaS-in-China" target="_blank" rel="noreferrer">xingpingcn.top</a> 只支持CloudFlare免费、无需密钥</li></p>
<p><li>接口密钥默认o1zrmHAF为免费KEY可永久免费使用。</li></p>
<p><li>代理地址:如 https://ghfast.top/https://raw.githubusercontent.com/ ,留空则直接访问 https://raw.githubusercontent.com/。</li></p>
<p><li>自动更新:可查看<a href="/system/cronset">计划任务设置</a></p>
</div>
</div>
@ -24,19 +25,23 @@
<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">
<form onsubmit="return saveSetting(this)" method="post" class="form-horizontal" role="form" id="apiSettingForm">
<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 class="col-sm-9"><select class="form-control" name="optimize_ip_api" id="optimize_ip_api" default="{:config_get('optimize_ip_api')}"><option value="0">wetest.vip</option><option value="1">HostMonit</option><option value="2">xingpingcn.top</option></select></div>
</div>
<div class="form-group">
<div class="form-group" id="keyGroup">
<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" id="proxyGroup" style="display:none;">
<label class="col-sm-3 control-label">代理地址</label>
<div class="col-sm-9"><input type="text" name="optimize_ip_proxy" value="{:config_get('optimize_ip_proxy', '')}" class="form-control" placeholder="留空则直接访问GitHub"/></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>
<a href="javascript:queryapi()" class="btn btn-default btn-block" id="queryBtn">查询积分</a>
</div>
</div>
</form>
@ -69,6 +74,25 @@ var items = $("select[default]");
for (i = 0; i < items.length; i++) {
$(items[i]).val($(items[i]).attr("default")||0);
}
// 切换接口时显示/隐藏对应设置项
function toggleApiSettings(){
var api = $("#optimize_ip_api").val();
if(api == '2'){
$("#keyGroup").hide();
$("#proxyGroup").show();
$("#queryBtn").hide();
}else{
$("#keyGroup").show();
$("#proxyGroup").hide();
$("#queryBtn").show();
}
}
$("#optimize_ip_api").change(function(){
toggleApiSettings();
});
// 页面加载时初始化
toggleApiSettings();
$('[data-toggle="tooltip"]').tooltip();
function saveSetting(obj){
var ii = layer.load(2, {shade:[0.1,'#fff']});
$.ajax({
@ -118,4 +142,4 @@ function queryapi(){
});
}
</script>
{/block}
{/block}