前端页面
This commit is contained in:
@@ -1,116 +1,141 @@
|
||||
{$layout}
|
||||
{$template "menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<style>
|
||||
.httpdns-settings-grid {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
.httpdns-settings-grid .left-nav-column {
|
||||
max-width: 220px;
|
||||
}
|
||||
.httpdns-settings-grid .right-form-column {
|
||||
padding-left: .3em !important;
|
||||
}
|
||||
.httpdns-side-menu .item {
|
||||
padding-top: .8em !important;
|
||||
padding-bottom: .8em !important;
|
||||
}
|
||||
.httpdns-mini-action {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
margin-left: .55em;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.httpdns-mini-action:hover {
|
||||
color: #1e70bf;
|
||||
}
|
||||
.httpdns-mini-action .icon {
|
||||
margin-right: 0 !important;
|
||||
font-size: .92em !important;
|
||||
}
|
||||
.httpdns-note.comment {
|
||||
color: #8f9aa6 !important;
|
||||
font-size: 12px;
|
||||
margin-top: .45em !important;
|
||||
}
|
||||
.httpdns-mini-action {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
margin-left: .55em;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.httpdns-mini-action:hover {
|
||||
color: #1e70bf;
|
||||
}
|
||||
|
||||
.httpdns-mini-action .icon {
|
||||
margin-right: 0 !important;
|
||||
font-size: .92em !important;
|
||||
}
|
||||
|
||||
.httpdns-note.comment {
|
||||
color: #8f9aa6 !important;
|
||||
font-size: 12px;
|
||||
margin-top: .45em !important;
|
||||
}
|
||||
|
||||
.httpdns-auth-table td.title {
|
||||
width: 260px !important;
|
||||
min-width: 260px !important;
|
||||
white-space: nowrap;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.httpdns-secret-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .35em;
|
||||
}
|
||||
|
||||
.httpdns-mini-icon {
|
||||
color: #8c96a3 !important;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.httpdns-mini-icon:hover {
|
||||
color: #5e6c7b !important;
|
||||
}
|
||||
|
||||
.httpdns-state-on {
|
||||
color: #21ba45;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.httpdns-state-off {
|
||||
color: #8f9aa6;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<div class="ui menu text blue">
|
||||
<div class="item"><strong>{{app.name}}</strong> (<code>{{settings.appId}}</code>)</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="appId" :value="app.id" />
|
||||
|
||||
<div class="ui stackable grid httpdns-settings-grid">
|
||||
<div class="three wide computer four wide tablet sixteen wide mobile column left-nav-column">
|
||||
<div class="ui fluid vertical pointing menu httpdns-side-menu">
|
||||
<a href="" class="item" :class="{active: activeSection == 'basic'}" @click.prevent="activeSection='basic'">基础配置</a>
|
||||
<a href="" class="item" :class="{active: activeSection == 'auth'}" @click.prevent="activeSection='auth'">认证与密钥</a>
|
||||
</div>
|
||||
</div>
|
||||
<table class="ui table selectable definition" v-show="activeSection == 'basic'">
|
||||
<tr>
|
||||
<td class="title">App ID</td>
|
||||
<td><code>{{settings.appId}}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">应用启用</td>
|
||||
<td>
|
||||
<checkbox name="appStatus" value="1" v-model="settings.appStatus"></checkbox>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">SNI 防护配置</td>
|
||||
<td>
|
||||
<span class="green">隐匿 SNI</span>
|
||||
<p class="comment httpdns-note">当前默认采用隐匿 SNI 策略,避免在 TLS 握手阶段暴露业务域名。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="thirteen wide computer twelve wide tablet sixteen wide mobile column right-form-column">
|
||||
<table class="ui table selectable definition" v-show="activeSection == 'basic'">
|
||||
<tr>
|
||||
<td class="title">App ID</td>
|
||||
<td><code>{{settings.appId}}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">应用启用</td>
|
||||
<td><checkbox name="appStatus" value="1" v-model="settings.appStatus"></checkbox></td>
|
||||
</tr>
|
||||
<table class="ui table selectable definition httpdns-auth-table" v-show="activeSection == 'auth'">
|
||||
<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>
|
||||
<p class="comment httpdns-note">打开后,服务端会对请求进行签名校验。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">加签 Secret</td>
|
||||
<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>
|
||||
</div>
|
||||
<p class="comment httpdns-note">最近更新:{{settings.signSecretUpdatedAt}}</p>
|
||||
<p class="comment httpdns-note" v-if="!settings.signEnabled">请求验签已关闭,当前不使用加签 Secret。</p>
|
||||
<p class="comment httpdns-note">用于生成鉴权接口的安全密钥。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">数据加密 Secret</td>
|
||||
<td>
|
||||
<div class="httpdns-secret-line">
|
||||
<code>{{aesSecretVisible ? settings.aesSecretPlain : settings.aesSecretMasked}}</code>
|
||||
<a href="" class="httpdns-mini-icon" @click.prevent="aesSecretVisible = !aesSecretVisible"
|
||||
:title="aesSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon"
|
||||
:class="aesSecretVisible ? 'eye slash' : 'eye'"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="复制数据加密 Secret"
|
||||
@click.prevent="copySecret(settings.aesSecretPlain, 'AES Secret')"><i
|
||||
class="copy outline icon"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="重置数据加密 Secret" @click.prevent="resetAESSecret"><i
|
||||
class="redo icon"></i></a>
|
||||
</div>
|
||||
<p class="comment httpdns-note">最近更新:{{settings.aesSecretUpdatedAt}}</p>
|
||||
<p class="comment httpdns-note">用于解析接口数据加密的密钥。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<tr>
|
||||
<td class="title">SNI 防护配置</td>
|
||||
<td>
|
||||
<span class="green">隐匿 SNI</span>
|
||||
<p class="comment httpdns-note">当前默认采用隐匿 SNI 策略,避免在 TLS 握手阶段暴露业务域名。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="ui table selectable definition" v-show="activeSection == 'auth'">
|
||||
<tr>
|
||||
<td class="title">请求验签</td>
|
||||
<td>
|
||||
<span class="ui label tiny green" v-if="settings.signEnabled">已开启</span>
|
||||
<span class="ui label tiny basic" v-else>已关闭</span>
|
||||
<a href="" class="ui mini button" :class="settings.signEnabled ? 'basic' : 'primary'" style="margin-left: .8em;" @click.prevent="toggleSignEnabled">{{settings.signEnabled ? "关闭请求验签" : "开启请求验签"}}</a>
|
||||
<p class="comment httpdns-note">打开后,服务端会对请求进行签名校验。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">加签 Secret</td>
|
||||
<td>
|
||||
<code>{{signSecretVisible ? settings.signSecretPlain : settings.signSecretMasked}}</code>
|
||||
<a href="" class="httpdns-mini-action" @click.prevent="signSecretVisible = !signSecretVisible" :title="signSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon" :class="signSecretVisible ? 'eye slash' : 'eye'"></i></a>
|
||||
<a href="" class="httpdns-mini-action" title="复制加签 Secret" @click.prevent="copySecret(settings.signSecretPlain, '加签 Secret')"><i class="copy outline icon"></i></a>
|
||||
<a href="" class="httpdns-mini-action" @click.prevent="resetSignSecret">[重置]</a>
|
||||
<p class="comment httpdns-note">最近更新:{{settings.signSecretUpdatedAt}}</p>
|
||||
<p class="comment httpdns-note" v-if="!settings.signEnabled">请求验签已关闭,当前不使用加签 Secret。</p>
|
||||
<p class="comment httpdns-note">用于生成鉴权接口的安全密钥。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">AES 数据加密 Secret</td>
|
||||
<td>
|
||||
<code>{{aesSecretVisible ? settings.aesSecretPlain : settings.aesSecretMasked}}</code>
|
||||
<a href="" class="httpdns-mini-action" @click.prevent="aesSecretVisible = !aesSecretVisible" :title="aesSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon" :class="aesSecretVisible ? 'eye slash' : 'eye'"></i></a>
|
||||
<a href="" class="httpdns-mini-action" title="复制 AES 数据加密 Secret" @click.prevent="copySecret(settings.aesSecretPlain, 'AES Secret')"><i class="copy outline icon"></i></a>
|
||||
<a href="" class="httpdns-mini-action" @click.prevent="resetAESSecret">[重置]</a>
|
||||
<p class="comment httpdns-note">最近更新:{{settings.aesSecretUpdatedAt}}</p>
|
||||
<p class="comment httpdns-note">用于解析接口数据加密的密钥。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</div>
|
||||
</div>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
Tea.context(function () {
|
||||
this.activeSection = "basic";
|
||||
this.activeSection = this.activeSection || "basic";
|
||||
this.success = NotifyReloadSuccess("保存成功");
|
||||
this.signSecretVisible = false;
|
||||
this.aesSecretVisible = false;
|
||||
@@ -9,7 +9,7 @@ Tea.context(function () {
|
||||
let targetIsOn = !this.settings.signEnabled;
|
||||
|
||||
if (targetIsOn) {
|
||||
teaweb.confirm("html:开启后,服务端将会对解析请求进行验签鉴权,<span class='red'>未签名、签名无效或过期的请求都解析失败</span>,确认开启吗?", function () {
|
||||
teaweb.confirm("html:开启后,服务端会对解析请求进行签名鉴权,<span class='red'>未签名、签名无效或过期的请求都解析失败</span>,确认开启吗?", function () {
|
||||
that.$post("/httpdns/apps/app/settings/toggleSignEnabled")
|
||||
.params({
|
||||
appId: that.app.id,
|
||||
@@ -23,7 +23,7 @@ Tea.context(function () {
|
||||
return;
|
||||
}
|
||||
|
||||
teaweb.confirm("html:关闭后,服务端将不会对解析请求进行验签鉴权,可能<span class='red'>存在被刷风险</span>,确认关闭吗?", function () {
|
||||
teaweb.confirm("html:关闭后,服务端不会对解析请求进行签名鉴权,可能<span class='red'>存在被刷风险</span>,确认关闭吗?", function () {
|
||||
that.$post("/httpdns/apps/app/settings/toggleSignEnabled")
|
||||
.params({
|
||||
appId: that.app.id,
|
||||
@@ -109,3 +109,4 @@ Tea.context(function () {
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -13,13 +13,23 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>所属集群 *</td>
|
||||
<td>主集群 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown" name="clusterId" v-model="defaultClusterId">
|
||||
<select class="ui dropdown" name="primaryClusterId" v-model="defaultPrimaryClusterId">
|
||||
<option value="">[请选择集群]</option>
|
||||
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
|
||||
</select>
|
||||
<p class="comment">应用的解析请求将由所选集群下的网关节点处理。默认值来自“HTTPDNS 用户设置”。</p>
|
||||
<p class="comment">主集群用于优先处理应用解析请求。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>备集群</td>
|
||||
<td>
|
||||
<select class="ui dropdown" name="backupClusterId" v-model="defaultBackupClusterId">
|
||||
<option :value="0">[不设置]</option>
|
||||
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
|
||||
</select>
|
||||
<p class="comment">当主集群不可用时,可切换到备集群。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1,66 +1,55 @@
|
||||
{$layout}
|
||||
{$template "menu"}
|
||||
{$layout}
|
||||
|
||||
<style>
|
||||
.httpdns-col-ttl {
|
||||
width: 72px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.httpdns-col-actions {
|
||||
width: 130px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<div class="ui menu text blue">
|
||||
<div class="item"><strong>{{app.name}}</strong> (<code>{{app.appId}}</code>)</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<second-menu>
|
||||
<a class="item" :href="'/httpdns/apps/domains?appId=' + app.id">{{app.name}}</a>
|
||||
<span class="item disabled" style="padding-left: 0; padding-right: 0">»</span>
|
||||
<a class="item" :href="'/httpdns/apps/domains?appId=' + app.id">域名列表</a>
|
||||
<span class="item disabled" style="padding-left: 0; padding-right: 0">»</span>
|
||||
<div class="item"><strong>{{domain.name}}</strong></div>
|
||||
<a href="" class="item" @click.prevent="createRecord" :class="{disabled: !domain || !domain.id}">创建规则</a>
|
||||
</second-menu>
|
||||
|
||||
<div class="ui small message">
|
||||
当前域名:<strong>{{domain.name}}</strong>
|
||||
</div>
|
||||
<table class="ui table selectable celled" v-if="records.length > 0" style="margin-top: .8em;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>线路</th>
|
||||
<th>规则名称</th>
|
||||
<th>解析记录</th>
|
||||
<th class="httpdns-col-ttl">TTL</th>
|
||||
<th class="width10">状态</th>
|
||||
<th class="httpdns-col-actions">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="record in records">
|
||||
<td>{{record.lineText}}</td>
|
||||
<td>{{record.ruleName}}</td>
|
||||
<td>{{record.recordValueText}}</td>
|
||||
<td class="httpdns-col-ttl">{{record.ttl}}s</td>
|
||||
<td>
|
||||
<span class="green" v-if="record.isOn">已启用</span>
|
||||
<span class="grey" v-else>已停用</span>
|
||||
</td>
|
||||
<td class="httpdns-col-actions">
|
||||
<a href="" @click.prevent="editRecord(record.id)">编辑</a> |
|
||||
<a href="" @click.prevent="toggleRecord(record)">{{record.isOn ? "停用" : "启用"}}</a> |
|
||||
<a href="" @click.prevent="deleteRecord(record.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="" @click.prevent="createRecord" class="ui button primary small" :class="{disabled: !domain || !domain.id}">
|
||||
<i class="icon plus"></i> 新增自定义解析规则
|
||||
</a>
|
||||
<a :href="'/httpdns/apps/domains?appId=' + app.id" class="ui button small">返回域名管理</a>
|
||||
|
||||
<table class="ui table selectable celled" v-if="records.length > 0" style="margin-top: 1em;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>线路</th>
|
||||
<th>规则名称</th>
|
||||
<th>SDNS 参数</th>
|
||||
<th>解析记录</th>
|
||||
<th class="httpdns-col-ttl">TTL</th>
|
||||
<th class="width10">状态</th>
|
||||
<th class="httpdns-col-actions">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="record in records">
|
||||
<td>{{record.lineText}}</td>
|
||||
<td>{{record.ruleName}}</td>
|
||||
<td>{{record.paramsText}}</td>
|
||||
<td>
|
||||
{{record.recordValueText}}
|
||||
</td>
|
||||
<td class="httpdns-col-ttl">{{record.ttl}}s</td>
|
||||
<td>
|
||||
<span class="green" v-if="record.isOn">已启用</span>
|
||||
<span class="grey" v-else>已停用</span>
|
||||
</td>
|
||||
<td class="httpdns-col-actions">
|
||||
<a href="" @click.prevent="editRecord(record.id)">编辑</a> |
|
||||
<a href="" @click.prevent="toggleRecord(record)">{{record.isOn ? "停用" : "启用"}}</a> |
|
||||
<a href="" @click.prevent="deleteRecord(record.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="ui warning message" v-if="!domain || !domain.id">当前应用暂无可用域名,请先到域名管理中添加域名。</p>
|
||||
<p class="ui message" v-else-if="records.length == 0">当前域名还没有自定义解析规则。</p>
|
||||
</div>
|
||||
<not-found-box v-if="!domain || !domain.id">当前应用暂无可用域名,请先到域名管理中添加域名。</not-found-box>
|
||||
<not-found-box v-else-if="records.length == 0">当前域名还没有自定义解析规则。</not-found-box>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Tea.context(function () {
|
||||
Tea.context(function () {
|
||||
if (typeof this.records == "undefined") {
|
||||
this.records = [];
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
<input type="hidden" name="domainId" :value="domain.id" />
|
||||
<input type="hidden" name="domain" :value="record.domain" />
|
||||
<input type="hidden" name="recordId" :value="record.id" />
|
||||
<input type="hidden" name="sdnsParamsJSON" :value="JSON.stringify(sdnsParams)" />
|
||||
<input type="hidden" name="recordItemsJSON" :value="JSON.stringify(recordItems)" />
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
@@ -81,26 +80,6 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">SDNS 参数配置</td>
|
||||
<td>
|
||||
<div class="httpdns-row" v-for="(param, index) in sdnsParams">
|
||||
<div class="field flex">
|
||||
<input type="text" maxlength="64" placeholder="参数名称" v-model="param.name" />
|
||||
</div>
|
||||
<div class="field flex">
|
||||
<input type="text" maxlength="64" placeholder="参数值" v-model="param.value" />
|
||||
</div>
|
||||
<a href="" @click.prevent="removeSDNSParam(index)" title="删除"><i class="icon trash alternate outline"></i></a>
|
||||
</div>
|
||||
<div class="httpdns-inline-actions">
|
||||
<a href="" @click.prevent="addSDNSParam" :class="{disabled: sdnsParams.length >= 10}">
|
||||
<i class="icon plus circle"></i>添加参数
|
||||
</a>
|
||||
<span class="count">{{sdnsParams.length}}/10</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">解析记录值 *</td>
|
||||
<td>
|
||||
|
||||
@@ -75,11 +75,6 @@ Tea.context(function () {
|
||||
vm.record.weightEnabled = vm.normalizeBoolean(vm.record.weightEnabled, false);
|
||||
vm.record.isOn = vm.normalizeBoolean(vm.record.isOn, true);
|
||||
|
||||
vm.sdnsParams = vm.parseJSONList(vm.record.sdnsParamsJson);
|
||||
if (vm.sdnsParams.length == 0) {
|
||||
vm.sdnsParams.push({name: "", value: ""});
|
||||
}
|
||||
|
||||
vm.recordItems = vm.parseJSONList(vm.record.recordItemsJson);
|
||||
if (vm.recordItems.length == 0) {
|
||||
vm.recordItems.push({type: "A", value: "", weight: 100});
|
||||
@@ -139,23 +134,6 @@ Tea.context(function () {
|
||||
}
|
||||
};
|
||||
|
||||
vm.addSDNSParam = function () {
|
||||
if (vm.sdnsParams.length >= 10) {
|
||||
return;
|
||||
}
|
||||
vm.sdnsParams.push({name: "", value: ""});
|
||||
};
|
||||
|
||||
vm.removeSDNSParam = function (index) {
|
||||
if (index < 0 || index >= vm.sdnsParams.length) {
|
||||
return;
|
||||
}
|
||||
vm.sdnsParams.splice(index, 1);
|
||||
if (vm.sdnsParams.length == 0) {
|
||||
vm.sdnsParams.push({name: "", value: ""});
|
||||
}
|
||||
};
|
||||
|
||||
vm.addRecordItem = function () {
|
||||
if (vm.recordItems.length >= 10) {
|
||||
return;
|
||||
|
||||
12
EdgeAdmin/web/views/@default/httpdns/apps/delete.html
Normal file
12
EdgeAdmin/web/views/@default/httpdns/apps/delete.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{$layout}
|
||||
|
||||
<second-menu>
|
||||
<a class="item" :href="'/httpdns/apps/domains?appId=' + app.id">{{app.name}}</a>
|
||||
<span class="item disabled" style="padding-left: 0; padding-right: 0">»</span>
|
||||
<div class="item"><strong>删除应用</strong></div>
|
||||
</second-menu>
|
||||
|
||||
<div class="buttons-box">
|
||||
<button class="ui button red" type="button" @click.prevent="deleteApp(app.id)">删除当前应用</button>
|
||||
<p class="comment" style="margin-top: .8em;">包含{{domainCount}}域名</p>
|
||||
</div>
|
||||
16
EdgeAdmin/web/views/@default/httpdns/apps/delete.js
Normal file
16
EdgeAdmin/web/views/@default/httpdns/apps/delete.js
Normal file
@@ -0,0 +1,16 @@
|
||||
Tea.context(function () {
|
||||
this.deleteApp = function (appId) {
|
||||
let that = this;
|
||||
teaweb.confirm("确定要删除此应用吗?", function () {
|
||||
that.$post("/httpdns/apps/delete")
|
||||
.params({
|
||||
appId: appId
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.success("删除成功", function () {
|
||||
window.location = "/httpdns/apps";
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -1,35 +1,62 @@
|
||||
{$layout}
|
||||
{$template "menu"}
|
||||
{$layout}
|
||||
|
||||
<div>
|
||||
<div class="ui menu text blue">
|
||||
<div class="item"><strong>{{app.name}}</strong> (<code>{{app.appId}}</code>)</div>
|
||||
<div class="margin"></div>
|
||||
|
||||
<style>
|
||||
.httpdns-domains-table .httpdns-domains-op {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
<second-menu>
|
||||
<a class="item" :href="'/httpdns/apps/domains?appId=' + app.id">{{app.name}}</a>
|
||||
<span class="item disabled" style="padding-left: 0; padding-right: 0">»</span>
|
||||
<div class="item"><strong>域名列表</strong></div>
|
||||
<a href="" class="item" @click.prevent="bindDomain">创建域名</a>
|
||||
</second-menu>
|
||||
|
||||
<form class="ui form small" @submit.prevent="doSearch">
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" v-model.trim="keywordInput" placeholder="按域名筛选..." />
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<button type="submit" class="ui button small">搜索</button>
|
||||
|
||||
<a href="" v-if="keyword.length > 0" @click.prevent="clearSearch">[清除条件]</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
</form>
|
||||
|
||||
<a href="" @click.prevent="bindDomain" class="ui button primary small"><i class="icon plus"></i>添加域名</a>
|
||||
<table class="ui table selectable celled httpdns-domains-table" v-if="filteredDomains().length > 0">
|
||||
<colgroup>
|
||||
<col style="width:60%;" />
|
||||
<col style="width:20%;" />
|
||||
<col style="width:20%;" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>服务域名</th>
|
||||
<th class="width10">规则策略</th>
|
||||
<th class="httpdns-domains-op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="domain in filteredDomains()">
|
||||
<td>
|
||||
<div><strong>{{domain.name}}</strong></div>
|
||||
</td>
|
||||
<td>
|
||||
<a
|
||||
:href="'/httpdns/apps/customRecords?appId=' + app.id + '&domainId=' + domain.id">{{domain.customRecordCount}}</a>
|
||||
</td>
|
||||
<td class="httpdns-domains-op">
|
||||
<a :href="'/httpdns/apps/customRecords?appId=' + app.id + '&domainId=' + domain.id">自定义解析</a>
|
||||
|
|
||||
<a href="" @click.prevent="deleteDomain(domain.id)">解绑</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="ui table selectable celled" v-if="domains.length > 0" style="margin-top: 1em;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>域名列表</th>
|
||||
<th class="two wide">规则策略</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="domain in domains">
|
||||
<td><strong>{{domain.name}}</strong></td>
|
||||
<td>
|
||||
<a :href="'/httpdns/apps/customRecords?appId=' + app.id + '&domainId=' + domain.id">{{domain.customRecordCount}}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a :href="'/httpdns/apps/customRecords?appId=' + app.id + '&domainId=' + domain.id">自定义解析</a> |
|
||||
<a href="" @click.prevent="deleteDomain(domain.id)">解绑</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="ui message" v-if="domains.length == 0">该应用尚未绑定域名。</p>
|
||||
</div>
|
||||
<not-found-box v-if="domains.length == 0">当前应用尚未绑定域名。</not-found-box>
|
||||
<not-found-box v-if="domains.length > 0 && filteredDomains().length == 0">没有匹配的域名。</not-found-box>
|
||||
@@ -1,8 +1,37 @@
|
||||
Tea.context(function () {
|
||||
Tea.context(function () {
|
||||
if (typeof this.keywordInput == "undefined") {
|
||||
this.keywordInput = "";
|
||||
}
|
||||
if (typeof this.keyword == "undefined") {
|
||||
this.keyword = "";
|
||||
}
|
||||
|
||||
if (typeof this.domains == "undefined") {
|
||||
this.domains = [];
|
||||
}
|
||||
|
||||
this.keywordInput = this.keyword;
|
||||
|
||||
this.doSearch = function () {
|
||||
this.keyword = this.keywordInput.trim();
|
||||
};
|
||||
|
||||
this.clearSearch = function () {
|
||||
this.keywordInput = "";
|
||||
this.keyword = "";
|
||||
};
|
||||
|
||||
this.filteredDomains = function () {
|
||||
let keyword = this.keyword.trim().toLowerCase();
|
||||
if (keyword.length == 0) {
|
||||
return this.domains;
|
||||
}
|
||||
return this.domains.filter(function (domain) {
|
||||
let name = (domain.name || "").toLowerCase();
|
||||
return name.indexOf(keyword) >= 0;
|
||||
});
|
||||
};
|
||||
|
||||
this.bindDomain = function () {
|
||||
teaweb.popup("/httpdns/apps/domains/createPopup?appId=" + this.app.id, {
|
||||
height: "24em",
|
||||
@@ -11,6 +40,19 @@ Tea.context(function () {
|
||||
});
|
||||
};
|
||||
|
||||
this.deleteApp = function () {
|
||||
let that = this;
|
||||
teaweb.confirm("确定要删除当前应用吗?", function () {
|
||||
that.$post("/httpdns/apps/delete")
|
||||
.params({
|
||||
appId: that.app.id
|
||||
})
|
||||
.success(function () {
|
||||
window.location = "/httpdns/apps";
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.deleteDomain = function (domainId) {
|
||||
let that = this;
|
||||
teaweb.confirm("确定要解绑这个域名吗?", function () {
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
{$layout}
|
||||
{$template "menu"}
|
||||
|
||||
<div class="ui margin"></div>
|
||||
|
||||
<style>
|
||||
.httpdns-apps-table .httpdns-apps-op {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<form method="get" class="ui form" action="/httpdns/apps">
|
||||
<div class="ui fields inline">
|
||||
@@ -16,21 +24,30 @@
|
||||
|
||||
<p class="ui message" v-if="apps.length == 0">暂时没有符合条件的 HTTPDNS 应用。</p>
|
||||
|
||||
<table class="ui table selectable celled" v-if="apps.length > 0">
|
||||
<table class="ui table selectable celled httpdns-apps-table" v-if="apps.length > 0">
|
||||
<colgroup>
|
||||
<col style="width:34%;" />
|
||||
<col style="width:28%;" />
|
||||
<col style="width:12%;" />
|
||||
<col style="width:10%;" />
|
||||
<col style="width:16%;" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>应用名称</th>
|
||||
<th>AppID</th>
|
||||
<th>绑定域名数</th>
|
||||
<th class="one wide center">状态</th>
|
||||
<th class="tz op">操作</th>
|
||||
<th class="center">绑定域名数</th>
|
||||
<th class="center">状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="app in apps">
|
||||
<td>
|
||||
<a :href="'/httpdns/apps/app?appId=' + app.id">
|
||||
<strong><keyword :v-word="keyword">{{app.name}}</keyword></strong>
|
||||
<strong>
|
||||
<keyword :v-word="keyword">{{app.name}}</keyword>
|
||||
</strong>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
@@ -41,13 +58,14 @@
|
||||
<td class="center">
|
||||
<label-on :v-is-on="app.isOn"></label-on>
|
||||
</td>
|
||||
<td>
|
||||
<td class="httpdns-apps-op">
|
||||
<a :href="'/httpdns/apps/app?appId=' + app.id">域名管理</a> |
|
||||
<a :href="'/httpdns/apps/app/settings?appId=' + app.id">应用设置</a>
|
||||
<a :href="'/httpdns/apps/app/settings?appId=' + app.id">应用设置</a> |
|
||||
<a :href="'/httpdns/apps/sdk?appId=' + app.id">SDK集成</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="page" v-html="page"></div>
|
||||
</div>
|
||||
</div>
|
||||
79
EdgeAdmin/web/views/@default/httpdns/apps/sdk.html
Normal file
79
EdgeAdmin/web/views/@default/httpdns/apps/sdk.html
Normal file
@@ -0,0 +1,79 @@
|
||||
{$layout}
|
||||
|
||||
<style>
|
||||
.httpdns-sdk-cards {
|
||||
margin-top: 1em;
|
||||
}
|
||||
.httpdns-sdk-cards > .card {
|
||||
min-height: 168px;
|
||||
}
|
||||
.httpdns-sdk-desc {
|
||||
margin-top: .6em;
|
||||
color: #5e6c7b;
|
||||
}
|
||||
.httpdns-sdk-meta {
|
||||
margin-top: .35em;
|
||||
color: #9aa6b2;
|
||||
font-size: 12px;
|
||||
}
|
||||
.httpdns-sdk-actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .6em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.httpdns-sdk-actions .button {
|
||||
padding-left: .8em !important;
|
||||
padding-right: .8em !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<second-menu>
|
||||
<a class="item" :href="'/httpdns/apps/domains?appId=' + app.id">{{app.name}}</a>
|
||||
<span class="item disabled" style="padding-left: 0; padding-right: 0">»</span>
|
||||
<div class="item"><strong>SDK 集成</strong></div>
|
||||
</second-menu>
|
||||
|
||||
<div class="ui three stackable cards httpdns-sdk-cards">
|
||||
<div class="card">
|
||||
<div class="content">
|
||||
<div class="header"><i class="icon android green"></i> Android SDK</div>
|
||||
<div class="httpdns-sdk-meta">Java / Kotlin</div>
|
||||
<div class="description httpdns-sdk-desc">适用于 Android 客户端接入。</div>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<div class="httpdns-sdk-actions">
|
||||
<a class="ui button compact mini basic" href="javascript:;"><i class="icon download"></i> 下载 SDK</a>
|
||||
<a class="ui button compact mini basic" href="javascript:;"><i class="icon book"></i> 集成文档</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="content">
|
||||
<div class="header"><i class="icon apple grey"></i> iOS SDK</div>
|
||||
<div class="httpdns-sdk-meta">Objective-C / Swift</div>
|
||||
<div class="description httpdns-sdk-desc">适用于 iOS 客户端接入。</div>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<div class="httpdns-sdk-actions">
|
||||
<a class="ui button compact mini basic" href="javascript:;"><i class="icon download"></i> 下载 SDK</a>
|
||||
<a class="ui button compact mini basic" href="javascript:;"><i class="icon book"></i> 集成文档</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="content">
|
||||
<div class="header"><i class="icon mobile alternate blue"></i> Flutter SDK</div>
|
||||
<div class="httpdns-sdk-meta">Dart / Plugin</div>
|
||||
<div class="description httpdns-sdk-desc">适用于 Flutter 跨平台接入。</div>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<div class="httpdns-sdk-actions">
|
||||
<a class="ui button compact mini basic" href="javascript:;"><i class="icon download"></i> 下载 SDK</a>
|
||||
<a class="ui button compact mini basic" href="javascript:;"><i class="icon book"></i> 集成文档</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user