带阿里标识的版本

This commit is contained in:
robin
2026-02-28 18:55:33 +08:00
parent 150799f41d
commit 5d0b7c7e91
477 changed files with 10813 additions and 4044 deletions

View File

@@ -0,0 +1,28 @@
{$layout "layout_popup"}
<h3 v-if="!isUpdating">添加端口绑定</h3>
<h3 v-if="isUpdating">修改端口绑定</h3>
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="supportRange" :value="supportRange ? 1 : 0"/>
<table class="ui table definition selectable">
<tr>
<td>网络协议</td>
<td>
<select class="ui dropdown auto-width" name="protocol" v-model="protocol" @change="changeProtocol">
<option v-for="p in protocols" :value="p.code">{{p.name}}</option>
</select>
</td>
</tr>
<tr>
<td class="title">端口 *</td>
<td>
<input type="text" name="address" ref="focus" v-model="address"/>
<p class="comment">可以是一个数字端口通常不超过65535也可以是"地址:端口"的方式。<span v-if="supportRange">支持端口范围,形式为<code-label>port1-port2</code-label></span>
<span v-if="from.length == 0 && protocol == 'http'">HTTP常用端口为<a href="" title="点击添加" @click.prevent="addPort('80')">80</a></span>
<span v-if="from.length == 0 && protocol == 'https'">HTTPS常用端口为<a href="" title="点击添加" @click.prevent="addPort('443')">443</a></span>
</p>
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,47 @@
Tea.context(function () {
this.success = NotifyPopup;
this.isUpdating = false
this.address = ""
this.protocol = this.protocols[0].code
// 初始化
// from 用来标记是否为特殊的节点
if (this.from.length == 0) {
if (this.protocol == "http") {
this.address = "80"
} else if (this.protocol == "https") {
this.address = "443"
}
}
if (window.parent.UPDATING_ADDR != null) {
this.isUpdating = true
let addr = window.parent.UPDATING_ADDR
this.protocol = addr.protocol
if (addr.host.length == 0) {
this.address = addr.portRange
} else {
this.address = addr.host.quoteIP() + ":" + addr.portRange
}
}
this.changeProtocol = function () {
if (this.from.length > 0) {
return
}
switch (this.protocol) {
case "http":
this.address = "80"
break
case "https":
this.address = "443"
break
}
}
this.addPort = function (port) {
this.address = port
}
});

View File

@@ -67,8 +67,24 @@
<table class="ui table selectable definition" v-show="activeSection == 'basic'">
<tr>
<td class="title">App ID</td>
<td><code>{{settings.appId}}</code></td>
<td class="title">主集群</td>
<td>
<select class="ui dropdown auto-width" name="primaryClusterId" v-model="settings.primaryClusterId">
<option :value="0">[不设置]</option>
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
</select>
<p class="comment httpdns-note">未设置时,按默认主集群处理(当前默认主集群:{{settings.defaultPrimaryClusterName || '-' }})。</p>
</td>
</tr>
<tr>
<td class="title">备集群</td>
<td>
<select class="ui dropdown auto-width" name="backupClusterId" v-model="settings.backupClusterId">
<option :value="0">[不设置]</option>
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
</select>
<p class="comment httpdns-note">未设置时,按默认备用集群处理(当前默认备用集群:{{settings.defaultBackupClusterName || '-' }})。</p>
</td>
</tr>
<tr>
<td class="title">应用启用</td>
@@ -86,14 +102,34 @@
</table>
<table class="ui table selectable definition httpdns-auth-table" v-show="activeSection == 'auth'">
<tr>
<td class="title">App ID</td>
<td>
<code>{{settings.appId}}</code>
<a href="" class="httpdns-mini-icon" title="复制 App ID" @click.prevent="copySecret(settings.appId, 'App ID')"><i class="copy outline icon"></i></a>
</td>
</tr>
<tr>
<td class="title">主服务域名</td>
<td>
<code v-if="settings.primaryServiceDomain && settings.primaryServiceDomain.length > 0">{{settings.primaryServiceDomain}}</code>
<span class="grey" v-else>未配置</span>
<a v-if="settings.primaryServiceDomain && settings.primaryServiceDomain.length > 0" href="" class="httpdns-mini-icon" title="复制主服务域名" @click.prevent="copySecret(settings.primaryServiceDomain, '主服务域名')"><i class="copy outline icon"></i></a>
</td>
</tr>
<tr>
<td class="title">备用服务域名</td>
<td>
<code v-if="settings.backupServiceDomain && settings.backupServiceDomain.length > 0">{{settings.backupServiceDomain}}</code>
<span class="grey" v-else>未配置</span>
<a v-if="settings.backupServiceDomain && settings.backupServiceDomain.length > 0" href="" class="httpdns-mini-icon" title="复制备用服务域名" @click.prevent="copySecret(settings.backupServiceDomain, '备用服务域名')"><i class="copy outline icon"></i></a>
</td>
</tr>
<tr>
<td class="title">请求验签</td>
<td>
<span
:class="settings.signEnabled ? 'httpdns-state-on' : 'httpdns-state-off'">{{settings.signEnabled
? "已开启" : "已关闭"}}</span>
<a href="" class="ui mini button basic" style="margin-left: .8em;"
@click.prevent="toggleSignEnabled">{{settings.signEnabled ? "关闭请求验签" : "开启请求验签"}}</a>
<span :class="settings.signEnabled ? 'httpdns-state-on' : 'httpdns-state-off'">{{settings.signEnabled ? "已开启" : "已关闭"}}</span>
<a href="" class="ui mini button basic" style="margin-left: .8em;" @click.prevent="toggleSignEnabled">{{settings.signEnabled ? "关闭请求验签" : "开启请求验签"}}</a>
<p class="comment httpdns-note">打开后,服务端会对请求进行签名校验。</p>
</td>
</tr>
@@ -102,14 +138,9 @@
<td>
<div class="httpdns-secret-line">
<code>{{signSecretVisible ? settings.signSecretPlain : settings.signSecretMasked}}</code>
<a href="" class="httpdns-mini-icon" @click.prevent="signSecretVisible = !signSecretVisible"
:title="signSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon"
:class="signSecretVisible ? 'eye slash' : 'eye'"></i></a>
<a href="" class="httpdns-mini-icon" title="复制加签 Secret"
@click.prevent="copySecret(settings.signSecretPlain, '加签 Secret')"><i
class="copy outline icon"></i></a>
<a href="" class="httpdns-mini-icon" title="重置加签 Secret" @click.prevent="resetSignSecret"><i
class="redo icon"></i></a>
<a href="" class="httpdns-mini-icon" @click.prevent="signSecretVisible = !signSecretVisible" :title="signSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon" :class="signSecretVisible ? 'eye slash' : 'eye'"></i></a>
<a href="" class="httpdns-mini-icon" title="复制加签 Secret" @click.prevent="copySecret(settings.signSecretPlain, '加签 Secret')"><i class="copy outline icon"></i></a>
<a href="" class="httpdns-mini-icon" title="重置加签 Secret" @click.prevent="resetSignSecret"><i class="redo icon"></i></a>
</div>
<p class="comment httpdns-note">最近更新:{{settings.signSecretUpdatedAt}}</p>
<p class="comment httpdns-note" v-if="!settings.signEnabled">请求验签已关闭,当前不使用加签 Secret。</p>

View File

@@ -34,10 +34,13 @@
<tr>
<td>所属用户</td>
<td>
<user-selector></user-selector>
<select class="ui dropdown auto-width" name="userId">
<option value="0">[不设置]</option>
<option v-for="user in users" :value="user.id">{{user.fullname}} ({{user.username}})</option>
</select>
<p class="comment">可以选择当前应用所属的平台用户。</p>
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>
</form>

View File

@@ -1,4 +1,4 @@
{$layout}
{$layout}
{$template "menu"}
<div class="ui margin"></div>
@@ -26,16 +26,22 @@
<table class="ui table selectable celled httpdns-apps-table" v-if="apps.length > 0">
<colgroup>
<col style="width:32%;" />
<col style="width:26%;" />
<col style="width:20%;" />
<col style="width:12%;" />
<col style="width:10%;" />
<col style="width:11%;" />
<col style="width:11%;" />
<col style="width:12%;" />
<col style="width:8%;" />
<col style="width:6%;" />
<col style="width:20%;" />
</colgroup>
<thead>
<tr>
<th>应用名称</th>
<th>AppID</th>
<th>主集群</th>
<th>备用集群</th>
<th>用户</th>
<th class="center">绑定域名数</th>
<th class="center">状态</th>
<th>操作</th>
@@ -54,6 +60,26 @@
<code>{{app.appId}}</code>
<copy-icon :text="app.appId"></copy-icon>
</td>
<td>
<span v-if="app.primaryCluster != null && app.primaryCluster.id > 0">
{{app.primaryCluster.name || ('#' + app.primaryCluster.id)}}
<link-icon :href="'/httpdns/clusters/cluster?clusterId=' + app.primaryCluster.id"></link-icon>
</span>
<span v-else class="disabled">-</span>
</td>
<td>
<span v-if="app.backupCluster != null && app.backupCluster.id > 0">
{{app.backupCluster.name || ('#' + app.backupCluster.id)}}
<link-icon :href="'/httpdns/clusters/cluster?clusterId=' + app.backupCluster.id"></link-icon>
</span>
<span v-else class="disabled">-</span>
</td>
<td>
<span v-if="app.user != null && app.user.id > 0">
{{app.user.fullname}} ({{app.user.username}})
</span>
<span v-else class="disabled">-</span>
</td>
<td class="center"><a :href="'/httpdns/apps/domains?appId=' + app.id">{{app.domainCount}}</a></td>
<td class="center">
<label-on :v-is-on="app.isOn"></label-on>
@@ -68,4 +94,4 @@
</table>
<div class="page" v-html="page"></div>
</div>
</div>

View File

@@ -49,8 +49,8 @@
</div>
<div class="extra content">
<div class="httpdns-sdk-actions">
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/download?platform=android"><i class="icon download"></i> 下载 SDK</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/doc?platform=android"><i class="icon book"></i> 下载文档</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/download?platform=android" @click="downloadSDK('android', $event)"><i class="icon download"></i> 下载 SDK</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/doc?platform=android" @click="downloadDoc('android', $event)"><i class="icon book"></i> 下载文档</a>
</div>
</div>
</div>
@@ -63,8 +63,8 @@
</div>
<div class="extra content">
<div class="httpdns-sdk-actions">
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/download?platform=ios"><i class="icon download"></i> 下载 SDK</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/doc?platform=ios"><i class="icon book"></i> 下载文档</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/download?platform=ios" @click="downloadSDK('ios', $event)"><i class="icon download"></i> 下载 SDK</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/doc?platform=ios" @click="downloadDoc('ios', $event)"><i class="icon book"></i> 下载文档</a>
</div>
</div>
</div>
@@ -77,8 +77,8 @@
</div>
<div class="extra content">
<div class="httpdns-sdk-actions">
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/download?platform=flutter"><i class="icon download"></i> 下载 SDK</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/doc?platform=flutter"><i class="icon book"></i> 下载文档</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/download?platform=flutter" @click="downloadSDK('flutter', $event)"><i class="icon download"></i> 下载 SDK</a>
<a class="ui button compact mini basic" href="/httpdns/apps/sdk/doc?platform=flutter" @click="downloadDoc('flutter', $event)"><i class="icon book"></i> 下载文档</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,123 @@
Tea.context(function () {
this.downloadSDK = function (platform, event) {
this.checkAndDownload(platform, "sdk", event)
}
this.downloadDoc = function (platform, event) {
this.checkAndDownload(platform, "doc", event)
}
this.checkAndDownload = function (platform, type, event) {
if (event != null && typeof event.preventDefault == "function") {
event.preventDefault()
}
this.$get("/httpdns/apps/sdk/check")
.params({
platform: platform,
type: type
})
.success(function (resp) {
let data = (resp != null && resp.data != null) ? resp.data : {}
if (!data.exists) {
teaweb.warn(data.message || "当前暂无可下载文件")
return
}
if (typeof data.url == "string" && data.url.length > 0) {
this.downloadByBlob(data.url, platform, type)
return
}
teaweb.warn("下载地址生成失败,请稍后重试")
}.bind(this))
}
this.downloadByBlob = function (url, platform, type) {
let defaultFileName = "httpdns-sdk-" + platform + (type == "doc" ? ".md" : ".zip")
let xhr = new XMLHttpRequest()
xhr.open("GET", url, true)
xhr.responseType = "blob"
xhr.onload = function () {
if (xhr.status < 200 || xhr.status >= 300) {
teaweb.warn("下载失败HTTP " + xhr.status + "")
return
}
if (xhr.status == 204) {
teaweb.warn("下载被浏览器扩展或下载工具拦截,请暂时关闭相关扩展后重试")
return
}
let contentType = (xhr.getResponseHeader("Content-Type") || "").toLowerCase()
if (contentType.indexOf("application/json") >= 0) {
let reader = new FileReader()
reader.onload = function () {
try {
let json = JSON.parse(reader.result)
teaweb.warn((json && json.message) ? json.message : "下载失败,请稍后重试")
} catch (_e) {
teaweb.warn("下载失败,请稍后重试")
}
}
reader.readAsText(xhr.response)
return
}
let disposition = xhr.getResponseHeader("Content-Disposition") || ""
let fileName = xhr.getResponseHeader("X-SDK-Filename") || this.parseFileName(disposition) || defaultFileName
if (xhr.response == null || xhr.response.size <= 0) {
teaweb.warn("下载文件为空,请检查已上传 SDK 包是否完整")
return
}
this.saveBlob(xhr.response, fileName)
}.bind(this)
xhr.onerror = function () {
teaweb.warn("下载失败,请检查网络后重试")
}
xhr.send()
}
this.parseFileName = function (disposition) {
if (typeof disposition != "string" || disposition.length == 0) {
return ""
}
let utf8Match = disposition.match(/filename\*=UTF-8''([^;]+)/i)
if (utf8Match != null && utf8Match.length > 1) {
try {
return decodeURIComponent(utf8Match[1])
} catch (_e) {
}
}
let plainMatch = disposition.match(/filename="?([^";]+)"?/i)
if (plainMatch != null && plainMatch.length > 1) {
return plainMatch[1]
}
return ""
}
this.saveBlob = function (blob, fileName) {
if (window.navigator != null && typeof window.navigator.msSaveOrOpenBlob == "function") {
window.navigator.msSaveOrOpenBlob(blob, fileName)
return
}
let objectURL = window.URL.createObjectURL(blob)
let a = document.createElement("a")
a.style.display = "none"
a.href = objectURL
a.download = fileName
document.body.appendChild(a)
a.click()
setTimeout(function () {
window.URL.revokeObjectURL(objectURL)
if (a.parentNode != null) {
a.parentNode.removeChild(a)
}
}, 30000)
}
})

View File

@@ -1,4 +1,4 @@
{$layout}
{$layout}
<second-menu>
<a class="item" :href="'/httpdns/apps/domains?appId=' + app.id">{{app.name}}</a>
@@ -34,7 +34,7 @@
<td class="title">版本号 *</td>
<td>
<input type="text" name="version" v-model="version" maxlength="32"/>
<p class="comment">默认 `1.0.0`。同平台上传会覆盖“最新版本”下载内容</p>
<p class="comment">默认 `1.0.0`。同平台+同版本再次上传会覆盖该版本文件</p>
</td>
</tr>
<tr>
@@ -90,4 +90,3 @@
<div class="ui message" v-else>
暂无上传记录。
</div>

View File

@@ -1,4 +1,4 @@
Tea.context(function () {
Tea.context(function () {
this.platform = "android";
this.version = this.defaultVersion || "1.0.0";
this.isUploading = false;

View File

@@ -11,7 +11,6 @@
<div class="item"><strong>集群设置</strong></div>
</second-menu>
{$template "/left_menu_with_menu"}
<div class="right-box with-menu">
@@ -39,50 +38,65 @@
<td>节点安装根目录</td>
<td>
<input type="text" name="installDir" maxlength="100" v-model="settings.installDir" />
<p class="comment">边缘节点安装 HTTPDNS 服务的默认所在目录,此目录将被用于下发配置。通常保持默认即可。</p>
<p class="comment">边缘节点安装 HTTPDNS 服务的默认目录,通常保持默认即可。</p>
</td>
</tr>
<tr>
<td>默认解析 TTL</td>
<td>
<div class="ui input right labeled">
<input type="text" name="cacheTtl" maxlength="5" v-model="settings.cacheTtl"
style="width: 6em" />
<input type="text" name="cacheTtl" maxlength="5" v-model="settings.cacheTtl" style="width: 6em" />
<span class="ui label"></span>
</div>
<p class="comment">SDK HTTPDNS 请求域名解析时,返回的默认缓存有效期 (TTL)。SDK 超时后将重新发起请求</p>
<p class="comment">SDK 通过 HTTPDNS 解析域名时返回的默认 TTL</p>
</td>
</tr>
<tr>
<td>降级超时容忍度</td>
<td>
<div class="ui input right labeled">
<input type="text" name="fallbackTimeout" maxlength="5" v-model="settings.fallbackTimeout"
style="width: 6em" />
<input type="text" name="fallbackTimeout" maxlength="5" v-model="settings.fallbackTimeout" style="width: 6em" />
<span class="ui label">毫秒</span>
</div>
<p class="comment">HTTPDNS 节点回源查询其它 DNS 时的最大等待时间。超出此时间将触发服务降级逻辑(返回上一有效缓存或错误)。</p>
<p class="comment">节点回源查询上游 DNS 时的最大等待时间。</p>
</td>
</tr>
<tr>
<td>启用当前集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isOn" value="1" v-model="settings.isOn"
@change="syncDefaultCluster" />
<input type="checkbox" name="isOn" value="1" v-model="settings.isOn" @change="syncDefaultCluster" />
<label></label>
</div>
<p class="comment">如果取消启用,整个集群的 HTTPDNS 解析服务将停止</p>
<p class="comment">取消启用后,该集群不会参与 HTTPDNS 服务</p>
</td>
</tr>
<tr>
<td>默认集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isDefaultCluster" value="1" v-model="settings.isDefaultCluster" />
<label>为默认部署集群</label>
<input type="checkbox" value="1" v-model="settings.defaultClusterEnabled" @change="syncDefaultClusterSelection" />
<label>设为默认集群</label>
</div>
<p class="comment">全局设置。如果应用未单独指定集群,将默认分配和部署到该集群中。</p>
<div class="ui form" style="margin-top: .8em;" v-if="settings.defaultClusterEnabled">
<div class="grouped fields" style="margin:0;">
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="settings.defaultClusterRole" value="primary" @change="syncDefaultClusterSelection" />
<label>主集群</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="settings.defaultClusterRole" value="backup" @change="syncDefaultClusterSelection" />
<label>备用集群</label>
</div>
</div>
</div>
</div>
<input type="hidden" name="isDefaultCluster" value="1" v-if="settings.defaultClusterEnabled && settings.defaultClusterRole == 'primary'" />
<input type="hidden" name="isDefaultBackupCluster" value="1" v-if="settings.defaultClusterEnabled && settings.defaultClusterRole == 'backup'" />
<p class="comment">同一时刻最多 1 个默认集群角色,新设置会自动取消旧设置。</p>
</td>
</tr>
</table>
@@ -91,15 +105,12 @@
<tr>
<td class="title">绑定端口 *</td>
<td>
<network-addresses-box :v-url="'/httpdns/addPortPopup'" :v-addresses="tlsConfig.listen"
:v-protocol="'tls'" :v-support-range="true"></network-addresses-box>
<network-addresses-box :v-url="'/httpdns/addPortPopup'" :v-addresses="tlsConfig.listen" :v-protocol="'tls'" :v-support-range="true"></network-addresses-box>
</td>
</tr>
</table>
<!-- SSL配置 -->
<ssl-config-box v-show="activeSection == 'tls'" :v-ssl-policy="tlsConfig.sslPolicy"
:v-protocol="'tls'"></ssl-config-box>
<ssl-config-box v-show="activeSection == 'tls'" :v-ssl-policy="tlsConfig.sslPolicy" :v-protocol="'tls'"></ssl-config-box>
<submit-btn></submit-btn>
</form>

View File

@@ -1,4 +1,4 @@
Tea.context(function () {
Tea.context(function () {
this.success = NotifyReloadSuccess("保存成功")
this.activeSection = this.activeSection || "basic"
@@ -8,9 +8,38 @@ Tea.context(function () {
this.settings = {}
}
// 兼容旧字段,转换成统一“默认集群 + 角色”表现
let isDefaultPrimary = !!this.settings.isDefaultCluster
let isDefaultBackup = !!this.settings.isDefaultBackupCluster
this.settings.defaultClusterEnabled = isDefaultPrimary || isDefaultBackup
this.settings.defaultClusterRole = isDefaultBackup ? "backup" : "primary"
this.syncDefaultCluster = function () {
if (!this.settings.isOn) {
this.settings.defaultClusterEnabled = false
this.settings.defaultClusterRole = "primary"
this.settings.isDefaultCluster = false
this.settings.isDefaultBackupCluster = false
return
}
this.syncDefaultClusterSelection()
}
this.syncDefaultClusterSelection = function () {
if (!this.settings.defaultClusterEnabled) {
this.settings.isDefaultCluster = false
this.settings.isDefaultBackupCluster = false
return
}
if (this.settings.defaultClusterRole === "backup") {
this.settings.isDefaultCluster = false
this.settings.isDefaultBackupCluster = true
} else {
this.settings.defaultClusterRole = "primary"
this.settings.isDefaultCluster = true
this.settings.isDefaultBackupCluster = false
}
}
})

View File

@@ -1,4 +1,4 @@
{$layout}
{$layout}
{$template "menu"}
<div class="ui margin"></div>
@@ -27,7 +27,7 @@
<input type="text" name="cacheTtl" maxlength="5" value="30" style="width: 6em" />
<span class="ui label"></span>
</div>
<p class="comment">SDK HTTPDNS 请求域名解析时,返回的默认缓存有效期 (TTL)。SDK 超时后将重新发起请求</p>
<p class="comment">SDK 通过 HTTPDNS 解析域名时返回的默认 TTL</p>
</td>
</tr>
<tr>
@@ -37,36 +37,52 @@
<input type="text" name="fallbackTimeout" maxlength="5" value="300" style="width: 6em" />
<span class="ui label">毫秒</span>
</div>
<p class="comment">HTTPDNS 节点回源查询其它 DNS 时的最大等待时间。超出此时间将触发服务降级逻辑(返回上一有效缓存或错误)。</p>
<p class="comment">节点回源查询上游 DNS 时的最大等待时间。</p>
</td>
</tr>
<tr>
<td>节点安装根目录</td>
<td>
<input type="text" name="installDir" maxlength="255" value="/opt/edge-httpdns" />
<p class="comment">边缘节点安装 HTTPDNS 服务的默认所在目录,此目录将被用于下发配置。通常保持默认即可</p>
<p class="comment">边缘节点安装 HTTPDNS 服务的默认目录</p>
</td>
</tr>
<tr>
<td>启用当前集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isOn" value="1" checked />
<input type="checkbox" name="isOn" value="1" v-model="isOn" @change="syncDefaultClusterEnabled" checked />
<label></label>
</div>
<p class="comment">如果取消启用,整个集群的 HTTPDNS 解析服务将不被系统分配。</p>
</td>
</tr>
<tr>
<td>默认集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isDefault" value="1" />
<label>为默认部署集群</label>
<input type="checkbox" value="1" v-model="defaultClusterEnabled" @change="syncDefaultClusterEnabled" />
<label>设为默认集群</label>
</div>
<p class="comment">全局设置。如果应用未单独指定集群,将默认分配和部署到该集群中。</p>
<div class="ui form" style="margin-top: .8em;" v-if="defaultClusterEnabled">
<div class="grouped fields" style="margin:0;">
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="defaultClusterRole" value="primary" />
<label>主集群</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="defaultClusterRole" value="backup" />
<label>备用集群</label>
</div>
</div>
</div>
</div>
<input type="hidden" name="isDefaultPrimary" value="1" v-if="defaultClusterEnabled && defaultClusterRole == 'primary'" />
<input type="hidden" name="isDefaultBackup" value="1" v-if="defaultClusterEnabled && defaultClusterRole == 'backup'" />
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>
</form>

View File

@@ -1,4 +1,15 @@
Tea.context(function () {
Tea.context(function () {
this.isOn = true
this.defaultClusterEnabled = false
this.defaultClusterRole = "primary"
this.syncDefaultClusterEnabled = function () {
if (!this.isOn) {
this.defaultClusterEnabled = false
this.defaultClusterRole = "primary"
}
}
this.success = function (resp) {
let clusterId = 0
if (resp != null && resp.data != null && typeof resp.data.clusterId != "undefined") {

View File

@@ -256,5 +256,17 @@
<div class="margin"></div>
</div>
<div class="margin"></div>
<h4>HTTPDNS服务</h4>
<table class="ui table definition selectable">
<tr>
<td class="title">开通HTTPDNS服务</td>
<td><checkbox name="httpdnsIsOn" v-model="config.httpdnsIsOn"></checkbox>
<p class="comment">选中表示自动为用户开通HTTPDNS服务。</p>
</td>
</tr>
</table>
<div class="margin"></div>
<submit-btn></submit-btn>
</form>
</form>

View File

@@ -7,7 +7,8 @@ Tea.context(function () {
this.mobileVerificationMoreOptions = false
this.mobileResetPasswordMoreOptions = false
this.featureOp = "overwrite"
// 默认不影响已有用户功能,避免保存注册设置时误改用户功能绑定
this.featureOp = "keep"
this.featuresVisible = false
this.showFeatures = function () {
@@ -27,4 +28,4 @@ Tea.context(function () {
})
return names.join(" / ")
}
})
})