mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-03 12:20:28 +08:00
提交components.js
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -2840,6 +2840,42 @@ Vue.component("plan-user-selector", {
|
||||
</div>`
|
||||
})
|
||||
|
||||
// 显示流量限制说明
|
||||
Vue.component("plan-limit-view", {
|
||||
props: ["value", "v-single-mode"],
|
||||
data: function () {
|
||||
let config = this.value
|
||||
|
||||
let hasLimit = false
|
||||
if (!this.vSingleMode) {
|
||||
if (config.trafficLimit != null && config.trafficLimit.isOn && ((config.trafficLimit.dailySize != null && config.trafficLimit.dailySize.count > 0) || (config.trafficLimit.monthlySize != null && config.trafficLimit.monthlySize.count > 0))) {
|
||||
hasLimit = true
|
||||
} else if (config.dailyRequests > 0 || config.monthlyRequests > 0) {
|
||||
hasLimit = true
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
config: config,
|
||||
hasLimit: hasLimit
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatNumber: function (n) {
|
||||
return teaweb.formatNumber(n)
|
||||
}
|
||||
},
|
||||
template: `<div style="font-size: 0.8em; color: grey">
|
||||
<div class="ui divider" v-if="hasLimit"></div>
|
||||
<div v-if="config.trafficLimit != null && config.trafficLimit.isOn">
|
||||
<span v-if="config.trafficLimit.dailySize != null && config.trafficLimit.dailySize.count > 0">日流量限制:{{config.trafficLimit.dailySize.count}}{{config.trafficLimit.dailySize.unit.toUpperCase()}}<br/></span>
|
||||
<span v-if="config.trafficLimit.monthlySize != null && config.trafficLimit.monthlySize.count > 0">月流量限制:{{config.trafficLimit.monthlySize.count}}{{config.trafficLimit.monthlySize.unit.toUpperCase()}}<br/></span>
|
||||
</div>
|
||||
<div v-if="config.dailyRequests > 0">单日请求数限制:{{formatNumber(config.dailyRequests)}}</div>
|
||||
<div v-if="config.monthlyRequests > 0">单月请求数限制:{{formatNumber(config.monthlyRequests)}}</div>
|
||||
</div>`
|
||||
})
|
||||
|
||||
Vue.component("plan-price-view", {
|
||||
props: ["v-plan"],
|
||||
data: function () {
|
||||
@@ -3033,6 +3069,7 @@ Vue.component("plan-price-config-box", {
|
||||
<input type="text" style="width: 7em" maxlength="10" v-model="monthlyPrice"/>
|
||||
<span class="ui label">元</span>
|
||||
</div>
|
||||
<p class="comment">如果为0表示免费。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -3042,6 +3079,7 @@ Vue.component("plan-price-config-box", {
|
||||
<input type="text" style="width: 7em" maxlength="10" v-model="seasonallyPrice"/>
|
||||
<span class="ui label">元</span>
|
||||
</div>
|
||||
<p class="comment">如果为0表示免费。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -3051,6 +3089,7 @@ Vue.component("plan-price-config-box", {
|
||||
<input type="text" style="width: 7em" maxlength="10" v-model="yearlyPrice"/>
|
||||
<span class="ui label">元</span>
|
||||
</div>
|
||||
<p class="comment">如果为0表示免费。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -4505,44 +4544,6 @@ Vue.component("http-firewall-actions-view", {
|
||||
</div>`
|
||||
})
|
||||
|
||||
Vue.component("http-request-scripts-config-box", {
|
||||
props: ["vRequestScriptsConfig", "v-is-location"],
|
||||
data: function () {
|
||||
let config = this.vRequestScriptsConfig
|
||||
if (config == null) {
|
||||
config = {}
|
||||
}
|
||||
return {
|
||||
config: config
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeInitGroup: function (group) {
|
||||
this.config.initGroup = group
|
||||
this.$forceUpdate()
|
||||
},
|
||||
changeRequestGroup: function (group) {
|
||||
this.config.requestGroup = group
|
||||
this.$forceUpdate()
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="requestScriptsJSON" :value="JSON.stringify(config)"/>
|
||||
<div class="margin"></div>
|
||||
<h4 style="margin-bottom: 0">请求初始化</h4>
|
||||
<p class="comment">在请求刚初始化时调用,此时自定义Header等尚未生效。</p>
|
||||
<div>
|
||||
<script-group-config-box :v-group="config.initGroup" @change="changeInitGroup" :v-is-location="vIsLocation"></script-group-config-box>
|
||||
</div>
|
||||
<h4 style="margin-bottom: 0">准备发送请求</h4>
|
||||
<p class="comment">在准备执行请求或者转发请求之前调用,此时自定义Header、源站等已准备好。</p>
|
||||
<div>
|
||||
<script-group-config-box :v-group="config.requestGroup" @change="changeRequestGroup" :v-is-location="vIsLocation"></script-group-config-box>
|
||||
</div>
|
||||
<div class="margin"></div>
|
||||
</div>`
|
||||
})
|
||||
|
||||
// 显示WAF规则的标签
|
||||
Vue.component("http-firewall-rule-label", {
|
||||
props: ["v-rule"],
|
||||
@@ -5333,7 +5334,7 @@ Vue.component("http-cache-ref-box", {
|
||||
<input type="checkbox" value="1" v-model="ref.skipSetCookie"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后,当响应的Header中有Set-Cookie时不缓存响应内容。</p>
|
||||
<p class="comment">选中后,当响应的报头中有Set-Cookie时不缓存响应内容,防止动态内容被缓存。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="moreOptionsVisible && !vIsReverse">
|
||||
@@ -5343,7 +5344,7 @@ Vue.component("http-cache-ref-box", {
|
||||
<input type="checkbox" name="enableRequestCachePragma" value="1" v-model="ref.enableRequestCachePragma"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后,当请求的Header中含有Pragma: no-cache或Cache-Control: no-cache时,会跳过缓存直接读取源内容。</p>
|
||||
<p class="comment">选中后,当请求的报头中含有Pragma: no-cache或Cache-Control: no-cache时,会跳过缓存直接读取源内容,一般仅用于调试。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="moreOptionsVisible && !vIsReverse">
|
||||
@@ -8614,11 +8615,15 @@ Vue.component("http-firewall-actions-box", {
|
||||
}
|
||||
|
||||
var defaultPageBody = `<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<title>403 Forbidden</title>
|
||||
\t<style>
|
||||
\t\taddress { line-height: 1.8; }
|
||||
\t</style>
|
||||
<body>
|
||||
<h1>403 Forbidden</h1>
|
||||
<address>Request ID: \${requestId}.</address>
|
||||
<address>Connection: \${remoteAddr} (Client) -> \${serverAddr} (Server)</address>
|
||||
<address>Request ID: \${requestId}</address>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
@@ -10178,17 +10183,21 @@ Vue.component("http-pages-and-shutdown-box", {
|
||||
},
|
||||
addShutdownHTMLTemplate: function () {
|
||||
this.shutdownConfig.body = `<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
\t<title>升级中</title>
|
||||
\t<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
\t<style>
|
||||
\t\taddress { line-height: 1.8; }
|
||||
\t</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>网站升级中</h1>
|
||||
<p>为了给您提供更好的服务,我们正在升级网站,请稍后重新访问。</p>
|
||||
|
||||
<address>Request ID: \${requestId}.</address>
|
||||
<address>Connection: \${remoteAddr} (Client) -> \${serverAddr} (Server)</address>
|
||||
<address>Request ID: \${requestId}</address>
|
||||
|
||||
</body>
|
||||
</html>`
|
||||
@@ -11560,23 +11569,6 @@ Vue.component("http-access-log-config-box", {
|
||||
</div>`
|
||||
})
|
||||
|
||||
// 显示流量限制说明
|
||||
Vue.component("traffic-limit-view", {
|
||||
props: ["v-traffic-limit"],
|
||||
data: function () {
|
||||
return {
|
||||
config: this.vTrafficLimit
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<div v-if="config.isOn">
|
||||
<span v-if="config.dailySize != null && config.dailySize.count > 0">日流量限制:{{config.dailySize.count}}{{config.dailySize.unit.toUpperCase()}}<br/></span>
|
||||
<span v-if="config.monthlySize != null && config.monthlySize.count > 0">月流量限制:{{config.monthlySize.count}}{{config.monthlySize.unit.toUpperCase()}}<br/></span>
|
||||
</div>
|
||||
<span v-else class="disabled">没有限制。</span>
|
||||
</div>`
|
||||
})
|
||||
|
||||
// 基本认证用户配置
|
||||
Vue.component("http-auth-basic-auth-user-box", {
|
||||
props: ["v-users"],
|
||||
@@ -12041,7 +12033,8 @@ Vue.component("reverse-proxy-box", {
|
||||
idleTimeout: {count: 0, unit: "second"},
|
||||
maxConns: 0,
|
||||
maxIdleConns: 0,
|
||||
followRedirects: false
|
||||
followRedirects: false,
|
||||
retry50X: true
|
||||
}
|
||||
}
|
||||
if (reverseProxyConfig.addHeaders == null) {
|
||||
@@ -12181,6 +12174,7 @@ Vue.component("reverse-proxy-box", {
|
||||
<input type="checkbox" v-model="reverseProxyRef.isOn"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后,所有源站设置才会生效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="family == null || family == 'http'">
|
||||
@@ -12192,7 +12186,7 @@ Vue.component("reverse-proxy-box", {
|
||||
<div v-show="reverseProxyConfig.requestHostType == 2" style="margin-top: 0.8em">
|
||||
<input type="text" placeholder="比如example.com" v-model="reverseProxyConfig.requestHost"/>
|
||||
</div>
|
||||
<p class="comment">请求源站时的Host,用于修改源站接收到的域名
|
||||
<p class="comment">请求源站时的主机名(Host),用于修改源站接收到的域名
|
||||
<span v-if="reverseProxyConfig.requestHostType == 0">,"跟随CDN域名"是指源站接收到的域名和当前CDN访问域名保持一致</span>
|
||||
<span v-if="reverseProxyConfig.requestHostType == 1">,"跟随源站"是指源站接收到的域名仍然是填写的源站地址中的信息,不随代理服务域名改变而改变</span>
|
||||
<span v-if="reverseProxyConfig.requestHostType == 2">,自定义Host内容中支持请求变量</span>。</p>
|
||||
@@ -12215,7 +12209,7 @@ Vue.component("reverse-proxy-box", {
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="family == null || family == 'http'">
|
||||
<td>自动添加的Header</td>
|
||||
<td>自动添加报头</td>
|
||||
<td>
|
||||
<div>
|
||||
<div style="width: 14em; float: left; margin-bottom: 1em" v-for="header in forwardHeaders" :key="header.name">
|
||||
@@ -12223,7 +12217,7 @@ Vue.component("reverse-proxy-box", {
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<p class="comment">选中后,会自动向源站请求添加这些Header。</p>
|
||||
<p class="comment">选中后,会自动向源站请求添加这些报头,以便于源站获取客户端信息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="family == null || family == 'http'">
|
||||
@@ -12314,6 +12308,13 @@ Vue.component("reverse-proxy-box", {
|
||||
<p class="comment">源站保持等待的空闲超时时间,0表示使用默认时间。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="family == null || family == 'http'">
|
||||
<td>自动重试50X</td>
|
||||
<td>
|
||||
<checkbox v-model="reverseProxyConfig.retry50X"></checkbox>
|
||||
<p class="comment">选中后,表示当源站返回状态码为50X(比如502、504)时,自动重试。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="family != 'unix'">
|
||||
<td>PROXY Protocol</td>
|
||||
<td>
|
||||
@@ -12428,13 +12429,35 @@ Vue.component("http-remote-addr-config-box", {
|
||||
isPrior: false,
|
||||
isOn: false,
|
||||
value: "${rawRemoteAddr}",
|
||||
isCustomized: false
|
||||
type: "default",
|
||||
|
||||
requestHeaderName: ""
|
||||
}
|
||||
}
|
||||
|
||||
let optionValue = ""
|
||||
if (!config.isCustomized && (config.value == "${remoteAddr}" || config.value == "${rawRemoteAddr}")) {
|
||||
optionValue = config.value
|
||||
// type
|
||||
if (config.type == null || config.type.length == 0) {
|
||||
config.type = "default"
|
||||
switch (config.value) {
|
||||
case "${rawRemoteAddr}":
|
||||
config.type = "default"
|
||||
break
|
||||
case "${remoteAddrValue}":
|
||||
config.type = "default"
|
||||
break
|
||||
case "${remoteAddr}":
|
||||
config.type = "proxy"
|
||||
break
|
||||
default:
|
||||
if (config.value != null && config.value.length > 0) {
|
||||
config.type = "variable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// value
|
||||
if (config.value == null || config.value.length == 0) {
|
||||
config.value = "${rawRemoteAddr}"
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -12442,33 +12465,70 @@ Vue.component("http-remote-addr-config-box", {
|
||||
options: [
|
||||
{
|
||||
name: "直接获取",
|
||||
description: "用户直接访问边缘节点,即 \"用户 --> 边缘节点\" 模式,这时候可以直接从连接中读取到真实的IP地址。",
|
||||
value: "${rawRemoteAddr}"
|
||||
description: "用户直接访问边缘节点,即 \"用户 --> 边缘节点\" 模式,这时候系统会试图从直接的连接中读取到客户端IP地址。",
|
||||
value: "${rawRemoteAddr}",
|
||||
type: "default"
|
||||
},
|
||||
{
|
||||
name: "从上级代理中获取",
|
||||
description: "用户和边缘节点之间有别的代理服务转发,即 \"用户 --> [第三方代理服务] --> 边缘节点\",这时候只能从上级代理中获取传递的IP地址。",
|
||||
value: "${remoteAddr}"
|
||||
description: "用户和边缘节点之间有别的代理服务转发,即 \"用户 --> [第三方代理服务] --> 边缘节点\",这时候只能从上级代理中获取传递的IP地址;上级代理传递的请求报头中必须包含 X-Forwarded-For 或 X-Real-IP 信息。",
|
||||
value: "${remoteAddr}",
|
||||
type: "proxy"
|
||||
},
|
||||
{
|
||||
name: "[自定义]",
|
||||
name: "从请求报头中读取",
|
||||
description: "从自定义请求报头读取客户端IP。",
|
||||
value: "",
|
||||
type: "requestHeader"
|
||||
},
|
||||
{
|
||||
name: "[自定义变量]",
|
||||
description: "通过自定义变量来获取客户端真实的IP地址。",
|
||||
value: ""
|
||||
value: "",
|
||||
type: "variable"
|
||||
}
|
||||
],
|
||||
optionValue: optionValue
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"config.requestHeaderName": function (value) {
|
||||
if (this.config.type == "requestHeader"){
|
||||
this.config.value = "${header." + value.trim() + "}"
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isOn: function () {
|
||||
return ((!this.vIsLocation && !this.vIsGroup) || this.config.isPrior) && this.config.isOn
|
||||
},
|
||||
changeOptionValue: function () {
|
||||
if (this.optionValue.length > 0) {
|
||||
this.config.value = this.optionValue
|
||||
this.config.isCustomized = false
|
||||
} else {
|
||||
this.config.isCustomized = true
|
||||
changeOptionType: function () {
|
||||
let that = this
|
||||
|
||||
switch(this.config.type) {
|
||||
case "default":
|
||||
this.config.value = "${rawRemoteAddr}"
|
||||
break
|
||||
case "proxy":
|
||||
this.config.value = "${remoteAddr}"
|
||||
break
|
||||
case "requestHeader":
|
||||
this.config.value = ""
|
||||
if (this.requestHeaderName != null && this.requestHeaderName.length > 0) {
|
||||
this.config.value = "${header." + this.requestHeaderName + "}"
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
that.$refs.requestHeaderInput.focus()
|
||||
})
|
||||
break
|
||||
case "variable":
|
||||
this.config.value = "${rawRemoteAddr}"
|
||||
|
||||
setTimeout(function () {
|
||||
that.$refs.variableInput.focus()
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -12484,7 +12544,7 @@ Vue.component("http-remote-addr-config-box", {
|
||||
<input type="checkbox" value="1" v-model="config.isOn"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后表示使用自定义的请求变量获取客户端IP。</p>
|
||||
<p class="comment">选中后,表示使用自定义的请求变量获取客户端IP。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -12492,20 +12552,28 @@ Vue.component("http-remote-addr-config-box", {
|
||||
<tr>
|
||||
<td>获取IP方式 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="optionValue" @change="changeOptionValue">
|
||||
<option v-for="option in options" :value="option.value">{{option.name}}</option>
|
||||
<select class="ui dropdown auto-width" v-model="config.type" @change="changeOptionType">
|
||||
<option v-for="option in options" :value="option.type">{{option.name}}</option>
|
||||
</select>
|
||||
<p class="comment" v-for="option in options" v-if="option.value == optionValue && option.description.length > 0">{{option.description}}</p>
|
||||
<p class="comment" v-for="option in options" v-if="option.type == config.type && option.description.length > 0">{{option.description}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="optionValue.length == 0">
|
||||
|
||||
<!-- read from request header -->
|
||||
<tr v-show="config.type == 'requestHeader'">
|
||||
<td>请求报头 *</td>
|
||||
<td>
|
||||
<input type="text" name="requestHeaderName" v-model="config.requestHeaderName" maxlength="100" ref="requestHeaderInput"/>
|
||||
<p class="comment">请输入包含有客户端IP的请求报头,需要注意大小写,常见的有<code-label>X-Forwarded-For</code-label>、<code-label>X-Real-IP</code-label>、<code-label>X-Client-IP</code-label>等。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- read from variable -->
|
||||
<tr v-show="config.type == 'variable'">
|
||||
<td>读取IP变量值 *</td>
|
||||
<td>
|
||||
<input type="hidden" v-model="config.value" maxlength="100"/>
|
||||
<div v-if="optionValue == ''" style="margin-top: 1em">
|
||||
<input type="text" v-model="config.value" maxlength="100"/>
|
||||
<p class="comment">通过此变量获取用户的IP地址。具体可用的请求变量列表可参考官方网站文档。</p>
|
||||
</div>
|
||||
<input type="text" name="value" v-model="config.value" maxlength="100" ref="variableInput"/>
|
||||
<p class="comment">通过此变量获取用户的IP地址。具体可用的请求变量列表可参考官方网站文档;比如通过报头传递IP的情形,可以使用<code-label>\${header.你的自定义报头}</code-label>(类似于<code-label>\${header.X-Forwarded-For}</code-label>,需要注意大小写规范)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -12996,7 +13064,7 @@ Vue.component("http-webp-config-box", {
|
||||
quality: 50,
|
||||
minLength: {count: 0, "unit": "kb"},
|
||||
maxLength: {count: 0, "unit": "kb"},
|
||||
mimeTypes: ["image/png", "image/jpeg", "image/bmp", "image/x-ico", "image/gif"],
|
||||
mimeTypes: ["image/png", "image/jpeg", "image/bmp", "image/x-ico"],
|
||||
extensions: [".png", ".jpeg", ".jpg", ".bmp", ".ico"],
|
||||
conds: null
|
||||
}
|
||||
@@ -13062,7 +13130,7 @@ Vue.component("http-webp-config-box", {
|
||||
<input type="checkbox" value="1" v-model="config.isOn"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后表示开启自动WebP压缩<span v-if="vRequireCache">;只有满足缓存条件的图片内容才会被转换</span>。</p>
|
||||
<p class="comment">选中后表示开启自动WebP压缩;图片的宽和高均不能超过16383像素<span v-if="vRequireCache">;只有满足缓存条件的图片内容才会被转换</span>。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -13296,6 +13364,44 @@ Vue.component("http-oss-bucket-params", {
|
||||
</tbody>`
|
||||
})
|
||||
|
||||
Vue.component("http-request-scripts-config-box", {
|
||||
props: ["vRequestScriptsConfig", "v-is-location"],
|
||||
data: function () {
|
||||
let config = this.vRequestScriptsConfig
|
||||
if (config == null) {
|
||||
config = {}
|
||||
}
|
||||
return {
|
||||
config: config
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeInitGroup: function (group) {
|
||||
this.config.initGroup = group
|
||||
this.$forceUpdate()
|
||||
},
|
||||
changeRequestGroup: function (group) {
|
||||
this.config.requestGroup = group
|
||||
this.$forceUpdate()
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="requestScriptsJSON" :value="JSON.stringify(config)"/>
|
||||
<div class="margin"></div>
|
||||
<h4 style="margin-bottom: 0">请求初始化</h4>
|
||||
<p class="comment">在请求刚初始化时调用,此时自定义报头等尚未生效。</p>
|
||||
<div>
|
||||
<script-group-config-box :v-group="config.initGroup" @change="changeInitGroup" :v-is-location="vIsLocation"></script-group-config-box>
|
||||
</div>
|
||||
<h4 style="margin-bottom: 0">准备发送请求</h4>
|
||||
<p class="comment">在准备执行请求或者转发请求之前调用,此时自定义报头、源站等已准备好。</p>
|
||||
<div>
|
||||
<script-group-config-box :v-group="config.requestGroup" @change="changeRequestGroup" :v-is-location="vIsLocation"></script-group-config-box>
|
||||
</div>
|
||||
<div class="margin"></div>
|
||||
</div>`
|
||||
})
|
||||
|
||||
Vue.component("http-request-cond-view", {
|
||||
props: ["v-cond"],
|
||||
data: function () {
|
||||
@@ -14923,7 +15029,8 @@ Vue.component("http-firewall-captcha-options", {
|
||||
return {
|
||||
options: options,
|
||||
isEditing: false,
|
||||
summary: ""
|
||||
summary: "",
|
||||
uiBodyWarning: ""
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -14967,6 +15074,13 @@ Vue.component("http-firewall-captcha-options", {
|
||||
},
|
||||
"options.uiIsOn": function (v) {
|
||||
this.updateSummary()
|
||||
},
|
||||
"options.uiBody": function (v) {
|
||||
if (/<form(>|\s).+\$\{body}.*<\/form>/s.test(v)) {
|
||||
this.uiBodyWarning = "页面模板中不能使用<form></form>标签包裹\${body}变量,否则将导致验证码表单无法提交。"
|
||||
} else {
|
||||
this.uiBodyWarning = ""
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -15101,7 +15215,7 @@ Vue.component("http-firewall-captcha-options", {
|
||||
<td class="color-border">页面模板</td>
|
||||
<td>
|
||||
<textarea spellcheck="false" rows="2" v-model="options.uiBody"></textarea>
|
||||
<p class="comment"><span v-if="options.uiBody.length > 0 && options.uiBody.indexOf('\${body}') < 0 " class="red">模板中必须包含\${body}表示验证码表单!</span>整个页面的模板,支持HTML,其中必须使用<code-label>\${body}</code-label>变量代表验证码表单,否则将无法正常显示验证码。</p>
|
||||
<p class="comment"><span v-if="uiBodyWarning.length > 0" class="red">警告:{{uiBodyWarning}}</span><span v-if="options.uiBody.length > 0 && options.uiBody.indexOf('\${body}') < 0 " class="red">模板中必须包含\${body}表示验证码表单!</span>整个页面的模板,支持HTML,其中必须使用<code-label>\${body}</code-label>变量代表验证码表单,否则将无法正常显示验证码。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -15677,10 +15791,13 @@ Vue.component("ip-list-table", {
|
||||
<keyword :v-word="keyword">{{item.ipFrom}}</keyword> <span> <span class="small red" v-if="item.isRead != null && !item.isRead"> New </span> <a :href="'/servers/iplists?ip=' + item.ipFrom" v-if="vShowSearchButton" title="搜索此IP"><span><i class="icon search small" style="color: #ccc"></i></span></a></span>
|
||||
<span v-if="item.ipTo.length > 0"> - <keyword :v-word="keyword">{{item.ipTo}}</keyword></span></span>
|
||||
<span v-else class="disabled">*</span>
|
||||
|
||||
<div v-if="item.region != null && item.region.length > 0">
|
||||
<span class="grey small">{{item.region}}</span>
|
||||
<span v-if="item.isp != null && item.isp.length > 0 && item.isp != '内网IP'" class="grey small"><span class="disabled">|</span> {{item.isp}}</span>
|
||||
</div>
|
||||
<div v-else-if="item.isp != null && item.isp.length > 0 && item.isp != '内网IP'"><span class="grey small">{{item.isp}}</span></div>
|
||||
|
||||
<div v-if="item.createdTime != null">
|
||||
<span class="small grey">添加于 {{item.createdTime}}
|
||||
<span v-if="item.list != null && item.list.id > 0">
|
||||
@@ -18209,7 +18326,7 @@ Vue.component("digit-input", {
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `<input type="text" v-model="realValue" :maxlength="realMaxLength" :size="realSize" :class="{error: !this.isValid}" :placeholder="placeholder"/>`
|
||||
template: `<input type="text" v-model="realValue" :maxlength="realMaxLength" :size="realSize" :class="{error: !this.isValid}" :placeholder="placeholder" autocomplete="off"/>`
|
||||
})
|
||||
|
||||
Vue.component("keyword", {
|
||||
@@ -20534,6 +20651,9 @@ Vue.component("dns-route-selector", {
|
||||
this.routes.$removeIf(function (k, v) {
|
||||
return v.code + "@" + v.domainId == route.code + "@" + route.domainId
|
||||
})
|
||||
},
|
||||
clearKeyword: function () {
|
||||
this.keyword = ""
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -20567,16 +20687,22 @@ Vue.component("dns-route-selector", {
|
||||
<tr>
|
||||
<td class="title">所有线路</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="routeCode">
|
||||
<option value="" v-if="keyword.length == 0">[请选择]</option>
|
||||
<option v-for="route in searchingRoutes" :value="route.code + '@' + route.domainId">{{route.name}}({{route.code}}/{{route.domainName}})</option>
|
||||
</select>
|
||||
<span v-if="keyword.length > 0 && searchingRoutes.length == 0">没有和关键词“{{keyword}}”匹配的线路</span>
|
||||
<span v-show="keyword.length == 0 || searchingRoutes.length > 0">
|
||||
<select class="ui dropdown" v-model="routeCode">
|
||||
<option value="" v-if="keyword.length == 0">[请选择]</option>
|
||||
<option v-for="route in searchingRoutes" :value="route.code + '@' + route.domainId">{{route.name}}({{route.code}}/{{route.domainName}})</option>
|
||||
</select>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>搜索</td>
|
||||
<td>搜索线路</td>
|
||||
<td>
|
||||
<input type="text" placeholder="搜索..." size="10" style="width: 10em" v-model="keyword" ref="keywordRef" @keyup.enter="confirm" @keypress.enter.prevent="1"/>
|
||||
<div class="ui input" :class="{'right labeled':keyword.length > 0}">
|
||||
<input type="text" placeholder="线路名称或代号..." size="10" style="width: 10em" v-model="keyword" ref="keywordRef" @keyup.enter="confirm" @keypress.enter.prevent="1"/>
|
||||
<a class="ui label" v-if="keyword.length > 0" @click.prevent="clearKeyword" href=""><i class="icon remove small blue"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user