mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-07 15:20:25 +08:00
优化界面显示
This commit is contained in:
@@ -30,9 +30,10 @@ func (this *SelectPopupAction) RunGet(params struct {
|
|||||||
// TODO 列出常用和最新的证书供用户选择
|
// TODO 列出常用和最新的证书供用户选择
|
||||||
|
|
||||||
this.Data["keyword"] = params.Keyword
|
this.Data["keyword"] = params.Keyword
|
||||||
|
this.Data["selectedCertIds"] = params.SelectedCertIds
|
||||||
|
|
||||||
// 已经选择的证书
|
// 已经选择的证书
|
||||||
selectedCertIds := []string{}
|
var selectedCertIds = []string{}
|
||||||
if len(params.SelectedCertIds) > 0 {
|
if len(params.SelectedCertIds) > 0 {
|
||||||
selectedCertIds = strings.Split(params.SelectedCertIds, ",")
|
selectedCertIds = strings.Split(params.SelectedCertIds, ",")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1321,7 +1321,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
|||||||
|
|
||||||
<!-- HSTS -->
|
<!-- HSTS -->
|
||||||
<tr v-show="vProtocol == 'https'">
|
<tr v-show="vProtocol == 'https'">
|
||||||
<td :class="{'color-border':hsts.isOn}">是否开启HSTS</td>
|
<td :class="{'color-border':hsts.isOn}">开启HSTS</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<input type="checkbox" name="hstsOn" v-model="hsts.isOn" value="1"/>
|
<input type="checkbox" name="hstsOn" v-model="hsts.isOn" value="1"/>
|
||||||
@@ -2158,7 +2158,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
|||||||
<button class="ui button tiny" @click.prevent="addRef(false)" type="button">+添加缓存条件</button> <a href="" @click.prevent="addRef(true)">+添加不缓存条件</a>
|
<button class="ui button tiny" @click.prevent="addRef(false)" type="button">+添加缓存条件</button> <a href="" @click.prevent="addRef(true)">+添加不缓存条件</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="margin"></div>
|
<div class="margin"></div>
|
||||||
</div>`}),Vue.component("origin-list-box",{props:["v-primary-origins","v-backup-origins","v-server-type","v-params"],data:function(){return{primaryOrigins:this.vPrimaryOrigins,backupOrigins:this.vBackupOrigins}},methods:{createPrimaryOrigin:function(){teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&"+this.vParams,{height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},createBackupOrigin:function(){teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&"+this.vParams,{height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},updateOrigin:function(e,t){teaweb.popup("/servers/server/settings/origins/updatePopup?originType="+t+"&"+this.vParams+"&originId="+e,{height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},deleteOrigin:function(e,t){let i=this;teaweb.confirm("确定要删除此源站吗?",function(){Tea.action("/servers/server/settings/origins/delete?"+i.vParams+"&originId="+e+"&originType="+t).post().success(function(){teaweb.success("删除成功",function(){window.location.reload()})})})}},template:`<div>
|
</div>`}),Vue.component("origin-list-box",{props:["v-primary-origins","v-backup-origins","v-server-type","v-params"],data:function(){return{primaryOrigins:this.vPrimaryOrigins,backupOrigins:this.vBackupOrigins}},methods:{createPrimaryOrigin:function(){teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&"+this.vParams,{width:"45em",height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},createBackupOrigin:function(){teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&"+this.vParams,{width:"45em",height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},updateOrigin:function(e,t){teaweb.popup("/servers/server/settings/origins/updatePopup?originType="+t+"&"+this.vParams+"&originId="+e,{width:"45em",height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},deleteOrigin:function(e,t){let i=this;teaweb.confirm("确定要删除此源站吗?",function(){Tea.action("/servers/server/settings/origins/delete?"+i.vParams+"&originId="+e+"&originType="+t).post().success(function(){teaweb.success("删除成功",function(){window.location.reload()})})})}},template:`<div>
|
||||||
<h3>主要源站 <a href="" @click.prevent="createPrimaryOrigin()">[添加主要源站]</a> </h3>
|
<h3>主要源站 <a href="" @click.prevent="createPrimaryOrigin()">[添加主要源站]</a> </h3>
|
||||||
<p class="comment" v-if="primaryOrigins.length == 0">暂时还没有主要源站。</p>
|
<p class="comment" v-if="primaryOrigins.length == 0">暂时还没有主要源站。</p>
|
||||||
<origin-list-table v-if="primaryOrigins.length > 0" :v-origins="vPrimaryOrigins" :v-origin-type="'primary'" @deleteOrigin="deleteOrigin" @updateOrigin="updateOrigin"></origin-list-table>
|
<origin-list-table v-if="primaryOrigins.length > 0" :v-origins="vPrimaryOrigins" :v-origin-type="'primary'" @deleteOrigin="deleteOrigin" @updateOrigin="updateOrigin"></origin-list-table>
|
||||||
@@ -2385,29 +2385,50 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
|||||||
已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时间:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
|
已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时间:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
|
||||||
</span>
|
</span>
|
||||||
<span v-else>未启用</span>
|
<span v-else>未启用</span>
|
||||||
</div>`}),Vue.component("domains-box",{props:["v-domains","name"],data:function(){let e=this.vDomains,t=(null==e&&(e=[]),"domainsJSON");return null!=this.name&&"string"==typeof this.name&&(t=this.name),{domains:e,isAdding:!1,addingDomain:"",realName:t}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.addingDomain.focus()},100)},confirm:function(){let t=this;if(this.addingDomain=this.addingDomain.replace(/\s/g,""),0==this.addingDomain.length)teaweb.warn("请输入要添加的域名",function(){t.$refs.addingDomain.focus()});else{if("~"==this.addingDomain[0]){var e=this.addingDomain.substring(1);try{new RegExp(e)}catch(e){return void teaweb.warn("正则表达式错误:"+e.message,function(){t.$refs.addingDomain.focus()})}}this.domains.push(this.addingDomain),this.cancel()}},remove:function(e){this.domains.$remove(e)},cancel:function(){this.isAdding=!1,this.addingDomain=""}},template:`<div>
|
</div>`}),Vue.component("domains-box",{props:["v-domains","name","v-support-wildcard"],data:function(){let e=this.vDomains,t=(null==e&&(e=[]),"domainsJSON"),i=(null!=this.name&&"string"==typeof this.name&&(t=this.name),!0);return"boolean"==typeof this.vSupportWildcard&&(i=this.vSupportWildcard),{domains:e,mode:"single",batchDomains:"",isAdding:!1,addingDomain:"",isEditing:!1,editingIndex:-1,realName:t,supportWildcard:i}},watch:{vSupportWildcard:function(e){"boolean"==typeof e&&(this.supportWildcard=e)},mode:function(e){let t=this;setTimeout(function(){"single"==e?null!=t.$refs.addingDomain&&t.$refs.addingDomain.focus():"batch"==e&&null!=t.$refs.batchDomains&&t.$refs.batchDomains.focus()},100)}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.addingDomain.focus()},100)},confirm:function(){if("batch"==this.mode)this.confirmBatch();else{let t=this;if(this.addingDomain=this.addingDomain.replace(/\s/g,""),0==this.addingDomain.length)teaweb.warn("请输入要添加的域名",function(){t.$refs.addingDomain.focus()});else{if(this.supportWildcard){if("~"==this.addingDomain[0]){var e=this.addingDomain.substring(1);try{new RegExp(e)}catch(e){return void teaweb.warn("正则表达式错误:"+e.message,function(){t.$refs.addingDomain.focus()})}}}else if(/[*~^]/.test(this.addingDomain))return void teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号",function(){t.$refs.addingDomain.focus()});this.isEditing&&0<=this.editingIndex?this.domains[this.editingIndex]=this.addingDomain:this.domains.push(this.addingDomain),this.cancel(),this.change()}}},confirmBatch:function(){let e=this.batchDomains.split("\n"),i=[],s=this,n=!1;e.forEach(function(e){if(!n&&0!=e.length){if(s.supportWildcard){if("~"==e){var t=e.substring(1);try{new RegExp(t)}catch(e){return n=!0,void teaweb.warn("正则表达式错误:"+e.message,function(){s.$refs.batchDomains.focus()})}}}else if(/[*~^]/.test(e))return n=!0,void teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号",function(){s.$refs.batchDomains.focus()});i.push(e)}}),n||(0==i.length?teaweb.warn("请输入要添加的域名",function(){s.$refs.batchDomains.focus()}):(i.forEach(function(e){s.domains.push(e)}),this.cancel(),this.change()))},edit:function(e){this.addingDomain=this.domains[e],this.isEditing=!0,this.editingIndex=e;let t=this;setTimeout(function(){t.$refs.addingDomain.focus()},50)},remove:function(e){this.domains.$remove(e),this.change()},cancel:function(){this.isAdding=!1,this.mode="single",this.batchDomains="",this.isEditing=!1,this.editingIndex=-1,this.addingDomain=""},change:function(){this.$emit("change",this.domains)}},template:`<div>
|
||||||
<input type="hidden" :name="realName" :value="JSON.stringify(domains)"/>
|
<input type="hidden" :name="realName" :value="JSON.stringify(domains)"/>
|
||||||
<div v-if="domains.length > 0">
|
<div v-if="domains.length > 0">
|
||||||
<span class="ui label small basic" v-for="(domain, index) in domains">
|
<span class="ui label small basic" v-for="(domain, index) in domains" :class="{blue: index == editingIndex}">
|
||||||
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
||||||
<span v-if="domain.length > 0 && domain[0] == '.'" class="grey" style="font-style: normal">[后缀]</span>
|
<span v-if="domain.length > 0 && domain[0] == '.'" class="grey" style="font-style: normal">[后缀]</span>
|
||||||
<span v-if="domain.length > 0 && domain[0] == '*'" class="grey" style="font-style: normal">[泛域名]</span>
|
<span v-if="domain.length > 0 && domain[0] == '*'" class="grey" style="font-style: normal">[泛域名]</span>
|
||||||
{{domain}}
|
{{domain}}
|
||||||
|
<span v-if="!isAdding && !isEditing">
|
||||||
|
<a href="" title="修改" @click.prevent="edit(index)"><i class="icon pencil small"></i></a>
|
||||||
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon remove small"></i></a>
|
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon remove small"></i></a>
|
||||||
</span>
|
</span>
|
||||||
|
<span v-if="isAdding || isEditing">
|
||||||
|
<a class="disabled"><i class="icon pencil small"></i></a>
|
||||||
|
<a class="disabled"><i class="icon remove small"></i></a>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isAdding">
|
<div v-if="isAdding || isEditing">
|
||||||
<div class="ui fields">
|
<div class="ui fields">
|
||||||
|
<div class="ui field" v-if="isAdding">
|
||||||
|
<select class="ui dropdown" v-model="mode">
|
||||||
|
<option value="single">单个</option>
|
||||||
|
<option value="batch">批量</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<input type="text" v-model="addingDomain" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="addingDomain" placeholder="*.xxx.com" size="30"/>
|
<div v-show="mode == 'single'">
|
||||||
|
<input type="text" v-model="addingDomain" @keyup.enter="confirm()" @keypress.enter.prevent="1" @keydown.esc="cancel()" ref="addingDomain" :placeholder="supportWildcard ? 'example.com、*.example.com' : 'example.com、www.example.com'" size="30" maxlength="100"/>
|
||||||
|
</div>
|
||||||
|
<div v-show="mode == 'batch'">
|
||||||
|
<textarea cols="30" v-model="batchDomains" placeholder="example1.com
|
||||||
|
example2.com
|
||||||
|
每行一个域名" ref="batchDomains"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
|
<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
|
||||||
<a href="" title="取消" @click.prevent="cancel"><i class="icon remove small"></i></a>
|
<a href="" title="取消" @click.prevent="cancel"><i class="icon remove small"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="comment">支持普通域名(<code-label>example.com</code-label>)、泛域名(<code-label>*.example.com</code-label>)、域名后缀(以点号开头,如<code-label>.example.com</code-label>)和正则表达式(以波浪号开头,如<code-label>~.*.example.com</code-label>)。</p>
|
<p class="comment" v-if="supportWildcard">支持普通域名(<code-label>example.com</code-label>)、泛域名(<code-label>*.example.com</code-label>)、域名后缀(以点号开头,如<code-label>.example.com</code-label>)和正则表达式(以波浪号开头,如<code-label>~.*.example.com</code-label>)。</p>
|
||||||
|
<p class="comment" v-if="!supportWildcard">只支持普通域名(<code-label>example.com</code-label>、<code-label>www.example.com</code-label>)。</p>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 0.5em" v-if="!isAdding">
|
<div style="margin-top: 0.5em" v-if="!isAdding">
|
||||||
@@ -3371,7 +3392,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
|||||||
<span v-if="accessLog.requestTime != null"> - 耗时:{{formatCost(accessLog.requestTime)}} ms </span><span v-if="accessLog.humanTime != null && accessLog.humanTime.length > 0" class="grey small"> ({{accessLog.humanTime}})</span>
|
<span v-if="accessLog.requestTime != null"> - 耗时:{{formatCost(accessLog.requestTime)}} ms </span><span v-if="accessLog.humanTime != null && accessLog.humanTime.length > 0" class="grey small"> ({{accessLog.humanTime}})</span>
|
||||||
<a href="" @click.prevent="showLog" title="查看详情"><i class="icon expand"></i></a>
|
<a href="" @click.prevent="showLog" title="查看详情"><i class="icon expand"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>`});var punycode=new function(){this.utf16={decode:function(e){for(var t,i,s=[],n=0,o=e.length;n<o;){if(55296==(63488&(t=e.charCodeAt(n++)))){if(i=e.charCodeAt(n++),55296!=(64512&t)||56320!=(64512&i))throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");t=((1023&t)<<10)+(1023&i)+65536}s.push(t)}return s},encode:function(e){for(var t,i=[],s=0,n=e.length;s<n;){if(55296==(63488&(t=e[s++])))throw new RangeError("UTF-16(encode): Illegal UTF-16 value");65535<t&&(t-=65536,i.push(String.fromCharCode(t>>>10&1023|55296)),t=56320|1023&t),i.push(String.fromCharCode(t))}return i.join("")}};var b=2147483647;function y(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function x(e,t,i){var s;for(e=i?Math.floor(e/700):e>>1,e+=Math.floor(e/t),s=0;455<e;s+=36)e=Math.floor(e/35);return Math.floor(s+36*e/(e+38))}this.decode=function(e,t){var i,s,n,o,a,l,c,r,d=[],p=[],u=e.length,h=128,v=0,m=72,f=e.lastIndexOf("-");for(f<0&&(f=0),s=0;s<f;++s){if(t&&(p[d.length]=e.charCodeAt(s)-65<26),128<=e.charCodeAt(s))throw new RangeError("Illegal input >= 0x80");d.push(e.charCodeAt(s))}for(n=0<f?f+1:0;n<u;){for(o=v,a=1,l=36;;l+=36){if(u<=n)throw RangeError("punycode_bad_input(1)");if(36<=(r=(r=e.charCodeAt(n++))-48<10?r-22:r-65<26?r-65:r-97<26?r-97:36))throw RangeError("punycode_bad_input(2)");if(r>Math.floor((b-v)/a))throw RangeError("punycode_overflow(1)");if(v+=r*a,r<(r=l<=m?1:m+26<=l?26:l-m))break;if(a>Math.floor(b/(36-r)))throw RangeError("punycode_overflow(2)");a*=36-r}if(m=x(v-o,i=d.length+1,0===o),Math.floor(v/i)>b-h)throw RangeError("punycode_overflow(3)");h+=Math.floor(v/i),v%=i,t&&p.splice(v,0,e.charCodeAt(n-1)-65<26),d.splice(v,0,h),v++}if(t)for(v=0,c=d.length;v<c;v++)p[v]&&(d[v]=String.fromCharCode(d[v]).toUpperCase().charCodeAt(0));return this.utf16.encode(d)},this.encode=function(e,t){t&&(r=this.utf16.decode(e));var i,s,n,o,a,l,c,r,d=(e=this.utf16.decode(e.toLowerCase())).length;if(t)for(g=0;g<d;g++)r[g]=e[g]!=r[g];for(var p,u,h=[],v=128,m=0,f=72,g=0;g<d;++g)e[g]<128&&h.push(String.fromCharCode(r?(p=e[g],u=r[g],(p-=(p-97<26)<<5)+((!u&&p-65<26)<<5)):e[g]));for(i=s=h.length,0<s&&h.push("-");i<d;){for(n=b,g=0;g<d;++g)v<=(c=e[g])&&c<n&&(n=c);if(n-v>Math.floor((b-m)/(i+1)))throw RangeError("punycode_overflow (1)");for(m+=(n-v)*(i+1),v=n,g=0;g<d;++g){if((c=e[g])<v&&++m>b)return Error("punycode_overflow(2)");if(c==v){for(o=m,a=36;!(o<(l=a<=f?1:f+26<=a?26:a-f));a+=36)h.push(String.fromCharCode(y(l+(o-l)%(36-l),0))),o=Math.floor((o-l)/(36-l));h.push(String.fromCharCode(y(o,t&&r[g]?1:0))),f=x(m,i+1,i==s),m=0,++i}}++m,++v}return h.join("")},this.ToASCII=function(e){for(var t=e.split("."),i=[],s=0;s<t.length;++s){var n=t[s];i.push(n.match(/[^A-Za-z0-9-]/)?"xn--"+punycode.encode(n):n)}return i.join(".")},this.ToUnicode=function(e){for(var t=e.split("."),i=[],s=0;s<t.length;++s){var n=t[s];i.push(n.match(/^xn--/)?punycode.decode(n.slice(4)):n)}return i.join(".")}};function sortTable(n){let e=document.createElement("script");e.setAttribute("src","/js/sortable.min.js"),e.addEventListener("load",function(){let s=document.querySelector("#sortable-table");null!=s&&Sortable.create(s,{draggable:"tbody",handle:".icon.handle",onStart:function(){},onUpdate:function(e){let t=s.querySelectorAll("tbody"),i=[];t.forEach(function(e){i.push(parseInt(e.getAttribute("v-id")))}),n(i)}})}),document.head.appendChild(e)}function sortLoad(e){let t=document.createElement("script");t.setAttribute("src","/js/sortable.min.js"),t.addEventListener("load",function(){"function"==typeof e&&e()}),document.head.appendChild(t)}function emitClick(e,arguments){let t=["click"];for(let e=0;e<arguments.length;e++)t.push(arguments[e]);e.$emit.apply(e,t)}Vue.component("http-firewall-block-options-viewer",{props:["v-block-options"],data:function(){return{options:this.vBlockOptions}},template:`<div>
|
</div>`});var punycode=new function(){this.utf16={decode:function(e){for(var t,i,s=[],n=0,o=e.length;n<o;){if(55296==(63488&(t=e.charCodeAt(n++)))){if(i=e.charCodeAt(n++),55296!=(64512&t)||56320!=(64512&i))throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");t=((1023&t)<<10)+(1023&i)+65536}s.push(t)}return s},encode:function(e){for(var t,i=[],s=0,n=e.length;s<n;){if(55296==(63488&(t=e[s++])))throw new RangeError("UTF-16(encode): Illegal UTF-16 value");65535<t&&(t-=65536,i.push(String.fromCharCode(t>>>10&1023|55296)),t=56320|1023&t),i.push(String.fromCharCode(t))}return i.join("")}};var b=2147483647;function y(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function x(e,t,i){var s;for(e=i?Math.floor(e/700):e>>1,e+=Math.floor(e/t),s=0;455<e;s+=36)e=Math.floor(e/35);return Math.floor(s+36*e/(e+38))}this.decode=function(e,t){var i,s,n,o,a,l,c,r,d=[],p=[],u=e.length,h=128,m=0,v=72,f=e.lastIndexOf("-");for(f<0&&(f=0),s=0;s<f;++s){if(t&&(p[d.length]=e.charCodeAt(s)-65<26),128<=e.charCodeAt(s))throw new RangeError("Illegal input >= 0x80");d.push(e.charCodeAt(s))}for(n=0<f?f+1:0;n<u;){for(o=m,a=1,l=36;;l+=36){if(u<=n)throw RangeError("punycode_bad_input(1)");if(36<=(r=(r=e.charCodeAt(n++))-48<10?r-22:r-65<26?r-65:r-97<26?r-97:36))throw RangeError("punycode_bad_input(2)");if(r>Math.floor((b-m)/a))throw RangeError("punycode_overflow(1)");if(m+=r*a,r<(r=l<=v?1:v+26<=l?26:l-v))break;if(a>Math.floor(b/(36-r)))throw RangeError("punycode_overflow(2)");a*=36-r}if(v=x(m-o,i=d.length+1,0===o),Math.floor(m/i)>b-h)throw RangeError("punycode_overflow(3)");h+=Math.floor(m/i),m%=i,t&&p.splice(m,0,e.charCodeAt(n-1)-65<26),d.splice(m,0,h),m++}if(t)for(m=0,c=d.length;m<c;m++)p[m]&&(d[m]=String.fromCharCode(d[m]).toUpperCase().charCodeAt(0));return this.utf16.encode(d)},this.encode=function(e,t){t&&(r=this.utf16.decode(e));var i,s,n,o,a,l,c,r,d=(e=this.utf16.decode(e.toLowerCase())).length;if(t)for(g=0;g<d;g++)r[g]=e[g]!=r[g];for(var p,u,h=[],m=128,v=0,f=72,g=0;g<d;++g)e[g]<128&&h.push(String.fromCharCode(r?(p=e[g],u=r[g],(p-=(p-97<26)<<5)+((!u&&p-65<26)<<5)):e[g]));for(i=s=h.length,0<s&&h.push("-");i<d;){for(n=b,g=0;g<d;++g)m<=(c=e[g])&&c<n&&(n=c);if(n-m>Math.floor((b-v)/(i+1)))throw RangeError("punycode_overflow (1)");for(v+=(n-m)*(i+1),m=n,g=0;g<d;++g){if((c=e[g])<m&&++v>b)return Error("punycode_overflow(2)");if(c==m){for(o=v,a=36;!(o<(l=a<=f?1:f+26<=a?26:a-f));a+=36)h.push(String.fromCharCode(y(l+(o-l)%(36-l),0))),o=Math.floor((o-l)/(36-l));h.push(String.fromCharCode(y(o,t&&r[g]?1:0))),f=x(v,i+1,i==s),v=0,++i}}++v,++m}return h.join("")},this.ToASCII=function(e){for(var t=e.split("."),i=[],s=0;s<t.length;++s){var n=t[s];i.push(n.match(/[^A-Za-z0-9-]/)?"xn--"+punycode.encode(n):n)}return i.join(".")},this.ToUnicode=function(e){for(var t=e.split("."),i=[],s=0;s<t.length;++s){var n=t[s];i.push(n.match(/^xn--/)?punycode.decode(n.slice(4)):n)}return i.join(".")}};function sortTable(n){let e=document.createElement("script");e.setAttribute("src","/js/sortable.min.js"),e.addEventListener("load",function(){let s=document.querySelector("#sortable-table");null!=s&&Sortable.create(s,{draggable:"tbody",handle:".icon.handle",onStart:function(){},onUpdate:function(e){let t=s.querySelectorAll("tbody"),i=[];t.forEach(function(e){i.push(parseInt(e.getAttribute("v-id")))}),n(i)}})}),document.head.appendChild(e)}function sortLoad(e){let t=document.createElement("script");t.setAttribute("src","/js/sortable.min.js"),t.addEventListener("load",function(){"function"==typeof e&&e()}),document.head.appendChild(t)}function emitClick(e,arguments){let t=["click"];for(let e=0;e<arguments.length;e++)t.push(arguments[e]);e.$emit.apply(e,t)}Vue.component("http-firewall-block-options-viewer",{props:["v-block-options"],data:function(){return{options:this.vBlockOptions}},template:`<div>
|
||||||
<span v-if="options == null">默认设置</span>
|
<span v-if="options == null">默认设置</span>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
状态码:{{options.statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span> / 超时时间:{{options.timeout}}秒
|
状态码:{{options.statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span> / 超时时间:{{options.timeout}}秒
|
||||||
@@ -4826,7 +4847,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
|||||||
<input type="hidden" :name="vName" :value="JSON.stringify(addrs)"/>
|
<input type="hidden" :name="vName" :value="JSON.stringify(addrs)"/>
|
||||||
<div v-if="addrs.length > 0">
|
<div v-if="addrs.length > 0">
|
||||||
<div>
|
<div>
|
||||||
<div v-for="(addr, index) in addrs" class="ui label small">
|
<div v-for="(addr, index) in addrs" class="ui label small basic">
|
||||||
{{addr.protocol}}://{{addr.host.quoteIP()}}:{{addr.portRange}}</span>
|
{{addr.protocol}}://{{addr.host.quoteIP()}}:{{addr.portRange}}</span>
|
||||||
<a href="" title="修改" @click.prevent="updateAddr(index, addr)"><i class="icon pencil small"></i></a>
|
<a href="" title="修改" @click.prevent="updateAddr(index, addr)"><i class="icon pencil small"></i></a>
|
||||||
<a href="" title="删除" @click.prevent="removeAddr(index)"><i class="icon remove"></i></a>
|
<a href="" title="删除" @click.prevent="removeAddr(index)"><i class="icon remove"></i></a>
|
||||||
|
|||||||
@@ -3980,7 +3980,7 @@ Vue.component("ssl-config-box", {
|
|||||||
|
|
||||||
<!-- HSTS -->
|
<!-- HSTS -->
|
||||||
<tr v-show="vProtocol == 'https'">
|
<tr v-show="vProtocol == 'https'">
|
||||||
<td :class="{'color-border':hsts.isOn}">是否开启HSTS</td>
|
<td :class="{'color-border':hsts.isOn}">开启HSTS</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<input type="checkbox" name="hstsOn" v-model="hsts.isOn" value="1"/>
|
<input type="checkbox" name="hstsOn" v-model="hsts.isOn" value="1"/>
|
||||||
@@ -6446,6 +6446,7 @@ Vue.component("origin-list-box", {
|
|||||||
methods: {
|
methods: {
|
||||||
createPrimaryOrigin: function () {
|
createPrimaryOrigin: function () {
|
||||||
teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&" + this.vParams, {
|
teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&" + this.vParams, {
|
||||||
|
width: "45em",
|
||||||
height: "27em",
|
height: "27em",
|
||||||
callback: function (resp) {
|
callback: function (resp) {
|
||||||
teaweb.success("保存成功", function () {
|
teaweb.success("保存成功", function () {
|
||||||
@@ -6456,6 +6457,7 @@ Vue.component("origin-list-box", {
|
|||||||
},
|
},
|
||||||
createBackupOrigin: function () {
|
createBackupOrigin: function () {
|
||||||
teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&" + this.vParams, {
|
teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&" + this.vParams, {
|
||||||
|
width: "45em",
|
||||||
height: "27em",
|
height: "27em",
|
||||||
callback: function (resp) {
|
callback: function (resp) {
|
||||||
teaweb.success("保存成功", function () {
|
teaweb.success("保存成功", function () {
|
||||||
@@ -6466,6 +6468,7 @@ Vue.component("origin-list-box", {
|
|||||||
},
|
},
|
||||||
updateOrigin: function (originId, originType) {
|
updateOrigin: function (originId, originType) {
|
||||||
teaweb.popup("/servers/server/settings/origins/updatePopup?originType=" + originType + "&" + this.vParams + "&originId=" + originId, {
|
teaweb.popup("/servers/server/settings/origins/updatePopup?originType=" + originType + "&" + this.vParams + "&originId=" + originId, {
|
||||||
|
width: "45em",
|
||||||
height: "27em",
|
height: "27em",
|
||||||
callback: function (resp) {
|
callback: function (resp) {
|
||||||
teaweb.success("保存成功", function () {
|
teaweb.success("保存成功", function () {
|
||||||
@@ -7045,7 +7048,7 @@ Vue.component("firewall-syn-flood-config-viewer", {
|
|||||||
|
|
||||||
// 域名列表
|
// 域名列表
|
||||||
Vue.component("domains-box", {
|
Vue.component("domains-box", {
|
||||||
props: ["v-domains", "name"],
|
props: ["v-domains", "name", "v-support-wildcard"],
|
||||||
data: function () {
|
data: function () {
|
||||||
let domains = this.vDomains
|
let domains = this.vDomains
|
||||||
if (domains == null) {
|
if (domains == null) {
|
||||||
@@ -7056,11 +7059,47 @@ Vue.component("domains-box", {
|
|||||||
if (this.name != null && typeof this.name == "string") {
|
if (this.name != null && typeof this.name == "string") {
|
||||||
realName = this.name
|
realName = this.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let supportWildcard = true
|
||||||
|
if (typeof this.vSupportWildcard == "boolean") {
|
||||||
|
supportWildcard = this.vSupportWildcard
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains: domains,
|
domains: domains,
|
||||||
|
|
||||||
|
mode: "single", // single | batch
|
||||||
|
batchDomains: "",
|
||||||
|
|
||||||
isAdding: false,
|
isAdding: false,
|
||||||
addingDomain: "",
|
addingDomain: "",
|
||||||
realName: realName
|
|
||||||
|
isEditing: false,
|
||||||
|
editingIndex: -1,
|
||||||
|
|
||||||
|
realName: realName,
|
||||||
|
supportWildcard: supportWildcard
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
vSupportWildcard: function (v) {
|
||||||
|
if (typeof v == "boolean") {
|
||||||
|
this.supportWildcard = v
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mode: function (mode) {
|
||||||
|
let that = this
|
||||||
|
setTimeout(function () {
|
||||||
|
if (mode == "single") {
|
||||||
|
if (that.$refs.addingDomain != null) {
|
||||||
|
that.$refs.addingDomain.focus()
|
||||||
|
}
|
||||||
|
} else if (mode == "batch") {
|
||||||
|
if (that.$refs.batchDomains != null) {
|
||||||
|
that.$refs.batchDomains.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -7072,6 +7111,11 @@ Vue.component("domains-box", {
|
|||||||
}, 100)
|
}, 100)
|
||||||
},
|
},
|
||||||
confirm: function () {
|
confirm: function () {
|
||||||
|
if (this.mode == "batch") {
|
||||||
|
this.confirmBatch()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let that = this
|
let that = this
|
||||||
|
|
||||||
// 删除其中的空格
|
// 删除其中的空格
|
||||||
@@ -7084,8 +7128,8 @@ Vue.component("domains-box", {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 基本校验
|
// 基本校验
|
||||||
|
if (this.supportWildcard) {
|
||||||
if (this.addingDomain[0] == "~") {
|
if (this.addingDomain[0] == "~") {
|
||||||
let expr = this.addingDomain.substring(1)
|
let expr = this.addingDomain.substring(1)
|
||||||
try {
|
try {
|
||||||
@@ -7097,41 +7141,142 @@ Vue.component("domains-box", {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (/[*~^]/.test(this.addingDomain)) {
|
||||||
|
teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号", function () {
|
||||||
|
that.$refs.addingDomain.focus()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isEditing && this.editingIndex >= 0) {
|
||||||
|
this.domains[this.editingIndex] = this.addingDomain
|
||||||
|
} else {
|
||||||
this.domains.push(this.addingDomain)
|
this.domains.push(this.addingDomain)
|
||||||
|
}
|
||||||
this.cancel()
|
this.cancel()
|
||||||
|
this.change()
|
||||||
|
},
|
||||||
|
confirmBatch: function () {
|
||||||
|
let domains = this.batchDomains.split("\n")
|
||||||
|
let realDomains = []
|
||||||
|
let that = this
|
||||||
|
let hasProblems = false
|
||||||
|
domains.forEach(function (domain) {
|
||||||
|
if (hasProblems) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (domain.length == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (that.supportWildcard) {
|
||||||
|
if (domain == "~") {
|
||||||
|
let expr = domain.substring(1)
|
||||||
|
try {
|
||||||
|
new RegExp(expr)
|
||||||
|
} catch (e) {
|
||||||
|
hasProblems = true
|
||||||
|
teaweb.warn("正则表达式错误:" + e.message, function () {
|
||||||
|
that.$refs.batchDomains.focus()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (/[*~^]/.test(domain)) {
|
||||||
|
hasProblems = true
|
||||||
|
teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号", function () {
|
||||||
|
that.$refs.batchDomains.focus()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
realDomains.push(domain)
|
||||||
|
})
|
||||||
|
if (hasProblems) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (realDomains.length == 0) {
|
||||||
|
teaweb.warn("请输入要添加的域名", function () {
|
||||||
|
that.$refs.batchDomains.focus()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
realDomains.forEach(function (domain) {
|
||||||
|
that.domains.push(domain)
|
||||||
|
})
|
||||||
|
this.cancel()
|
||||||
|
this.change()
|
||||||
|
},
|
||||||
|
edit: function (index) {
|
||||||
|
this.addingDomain = this.domains[index]
|
||||||
|
this.isEditing = true
|
||||||
|
this.editingIndex = index
|
||||||
|
let that = this
|
||||||
|
setTimeout(function () {
|
||||||
|
that.$refs.addingDomain.focus()
|
||||||
|
}, 50)
|
||||||
},
|
},
|
||||||
remove: function (index) {
|
remove: function (index) {
|
||||||
this.domains.$remove(index)
|
this.domains.$remove(index)
|
||||||
|
this.change()
|
||||||
},
|
},
|
||||||
cancel: function () {
|
cancel: function () {
|
||||||
this.isAdding = false
|
this.isAdding = false
|
||||||
|
this.mode = "single"
|
||||||
|
this.batchDomains = ""
|
||||||
|
this.isEditing = false
|
||||||
|
this.editingIndex = -1
|
||||||
this.addingDomain = ""
|
this.addingDomain = ""
|
||||||
|
},
|
||||||
|
change: function () {
|
||||||
|
this.$emit("change", this.domains)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: `<div>
|
template: `<div>
|
||||||
<input type="hidden" :name="realName" :value="JSON.stringify(domains)"/>
|
<input type="hidden" :name="realName" :value="JSON.stringify(domains)"/>
|
||||||
<div v-if="domains.length > 0">
|
<div v-if="domains.length > 0">
|
||||||
<span class="ui label small basic" v-for="(domain, index) in domains">
|
<span class="ui label small basic" v-for="(domain, index) in domains" :class="{blue: index == editingIndex}">
|
||||||
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
||||||
<span v-if="domain.length > 0 && domain[0] == '.'" class="grey" style="font-style: normal">[后缀]</span>
|
<span v-if="domain.length > 0 && domain[0] == '.'" class="grey" style="font-style: normal">[后缀]</span>
|
||||||
<span v-if="domain.length > 0 && domain[0] == '*'" class="grey" style="font-style: normal">[泛域名]</span>
|
<span v-if="domain.length > 0 && domain[0] == '*'" class="grey" style="font-style: normal">[泛域名]</span>
|
||||||
{{domain}}
|
{{domain}}
|
||||||
|
<span v-if="!isAdding && !isEditing">
|
||||||
|
<a href="" title="修改" @click.prevent="edit(index)"><i class="icon pencil small"></i></a>
|
||||||
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon remove small"></i></a>
|
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon remove small"></i></a>
|
||||||
</span>
|
</span>
|
||||||
|
<span v-if="isAdding || isEditing">
|
||||||
|
<a class="disabled"><i class="icon pencil small"></i></a>
|
||||||
|
<a class="disabled"><i class="icon remove small"></i></a>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isAdding">
|
<div v-if="isAdding || isEditing">
|
||||||
<div class="ui fields">
|
<div class="ui fields">
|
||||||
|
<div class="ui field" v-if="isAdding">
|
||||||
|
<select class="ui dropdown" v-model="mode">
|
||||||
|
<option value="single">单个</option>
|
||||||
|
<option value="batch">批量</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<input type="text" v-model="addingDomain" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="addingDomain" placeholder="*.xxx.com" size="30"/>
|
<div v-show="mode == 'single'">
|
||||||
|
<input type="text" v-model="addingDomain" @keyup.enter="confirm()" @keypress.enter.prevent="1" @keydown.esc="cancel()" ref="addingDomain" :placeholder="supportWildcard ? 'example.com、*.example.com' : 'example.com、www.example.com'" size="30" maxlength="100"/>
|
||||||
|
</div>
|
||||||
|
<div v-show="mode == 'batch'">
|
||||||
|
<textarea cols="30" v-model="batchDomains" placeholder="example1.com\nexample2.com\n每行一个域名" ref="batchDomains"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
|
<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
|
||||||
<a href="" title="取消" @click.prevent="cancel"><i class="icon remove small"></i></a>
|
<a href="" title="取消" @click.prevent="cancel"><i class="icon remove small"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="comment">支持普通域名(<code-label>example.com</code-label>)、泛域名(<code-label>*.example.com</code-label>)、域名后缀(以点号开头,如<code-label>.example.com</code-label>)和正则表达式(以波浪号开头,如<code-label>~.*.example.com</code-label>)。</p>
|
<p class="comment" v-if="supportWildcard">支持普通域名(<code-label>example.com</code-label>)、泛域名(<code-label>*.example.com</code-label>)、域名后缀(以点号开头,如<code-label>.example.com</code-label>)和正则表达式(以波浪号开头,如<code-label>~.*.example.com</code-label>)。</p>
|
||||||
|
<p class="comment" v-if="!supportWildcard">只支持普通域名(<code-label>example.com</code-label>、<code-label>www.example.com</code-label>)。</p>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 0.5em" v-if="!isAdding">
|
<div style="margin-top: 0.5em" v-if="!isAdding">
|
||||||
@@ -13798,7 +13943,7 @@ Vue.component("api-node-addresses-box", {
|
|||||||
<input type="hidden" :name="vName" :value="JSON.stringify(addrs)"/>
|
<input type="hidden" :name="vName" :value="JSON.stringify(addrs)"/>
|
||||||
<div v-if="addrs.length > 0">
|
<div v-if="addrs.length > 0">
|
||||||
<div>
|
<div>
|
||||||
<div v-for="(addr, index) in addrs" class="ui label small">
|
<div v-for="(addr, index) in addrs" class="ui label small basic">
|
||||||
{{addr.protocol}}://{{addr.host.quoteIP()}}:{{addr.portRange}}</span>
|
{{addr.protocol}}://{{addr.host.quoteIP()}}:{{addr.portRange}}</span>
|
||||||
<a href="" title="修改" @click.prevent="updateAddr(index, addr)"><i class="icon pencil small"></i></a>
|
<a href="" title="修改" @click.prevent="updateAddr(index, addr)"><i class="icon pencil small"></i></a>
|
||||||
<a href="" title="删除" @click.prevent="removeAddr(index)"><i class="icon remove"></i></a>
|
<a href="" title="删除" @click.prevent="removeAddr(index)"><i class="icon remove"></i></a>
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ Vue.component("ssl-config-box", {
|
|||||||
|
|
||||||
<!-- HSTS -->
|
<!-- HSTS -->
|
||||||
<tr v-show="vProtocol == 'https'">
|
<tr v-show="vProtocol == 'https'">
|
||||||
<td :class="{'color-border':hsts.isOn}">是否开启HSTS</td>
|
<td :class="{'color-border':hsts.isOn}">开启HSTS</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<input type="checkbox" name="hstsOn" v-model="hsts.isOn" value="1"/>
|
<input type="checkbox" name="hstsOn" v-model="hsts.isOn" value="1"/>
|
||||||
|
|||||||
@@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<form class="ui form" action="/servers/certs/selectPopup">
|
<form class="ui form" action="/servers/certs/selectPopup">
|
||||||
|
<input type="hidden" name="selectedCertIds" :value="selectedCertIds"/>
|
||||||
<div class="ui fields inline">
|
<div class="ui fields inline">
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<input type="text" name="keyword" v-model="keyword" placeholder="域名、说明文字等"/>
|
<input type="text" name="keyword" v-model="keyword" placeholder="域名、说明文字等"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<button class="ui button" type="submit">搜索</button>
|
<button class="ui button" type="submit">搜索</button>
|
||||||
|
<a :href="'/servers/certs/selectPopup?selectedCertIds=' + selectedCertIds" v-if="keyword.length > 0">[清除条件]</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -42,7 +44,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div v-for="dnsName in cert.dnsNames" style="margin-bottom:0.4em">
|
<div v-for="dnsName in cert.dnsNames" style="margin-bottom:0.4em">
|
||||||
<span class="ui label tiny"><keyword :v-word="keyword">{{dnsName}}</keyword></span>
|
<span class="ui label tiny basic"><keyword :v-word="keyword">{{dnsName}}</keyword></span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{certInfos[index].endDay}}</td>
|
<td>{{certInfos[index].endDay}}</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user