mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-15 13:00:25 +08:00
WAF规则中国家/地区、省份、城市、ISP增加候选项检索和选择
This commit is contained in:
@@ -4258,10 +4258,10 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
||||
<div class="margin"></div>
|
||||
</div>`}),Vue.component("request-variables-describer",{data:function(){return{vars:[]}},methods:{update:function(e){this.vars=[];let i=this;e.replace(/\${.+?}/g,function(e){var t=i.findVar(e);if(null==t)return e;i.vars.push(t)})},findVar:function(t){let i=null;return window.REQUEST_VARIABLES.forEach(function(e){e.code==t&&(i=e)}),i}},template:`<span>
|
||||
<span v-for="(v, index) in vars"><code-label :title="v.description">{{v.code}}</code-label> - {{v.name}}<span v-if="index < vars.length-1">;</span></span>
|
||||
</span>`}),Vue.component("combo-box",{props:["name","title","placeholder","size","v-items","v-value"],data:function(){let e=this.vItems,i=((e=null!=e&&e instanceof Array?e:[]).forEach(function(e){null==e.value&&(e.value=e.id)}),null);if(null!=this.vValue){let t=this;e.forEach(function(e){e.value==t.vValue&&(i=e)})}return{allItems:e,items:e.$copy(),selectedItem:i,keyword:"",visible:!1,hideTimer:null,hoverIndex:0}},methods:{reset:function(){this.selectedItem=null,this.change(),this.hoverIndex=0;let e=this;setTimeout(function(){e.$refs.searchBox&&e.$refs.searchBox.focus()})},changeKeyword:function(){this.hoverIndex=0;let t=this.keyword;0==t.length?this.items=this.allItems.$copy():this.items=this.allItems.$copy().filter(function(e){return teaweb.match(e.name,t)})},selectItem:function(e){this.selectedItem=e,this.change(),this.hoverIndex=0,this.keyword="",this.changeKeyword()},confirm:function(){this.items.length>this.hoverIndex&&this.selectItem(this.items[this.hoverIndex])},show:function(){this.visible=!0},hide:function(){let e=this;this.hideTimer=setTimeout(function(){e.visible=!1},500)},downItem:function(){this.hoverIndex++,this.hoverIndex>this.items.length-1&&(this.hoverIndex=0),this.focusItem()},upItem:function(){this.hoverIndex--,this.hoverIndex<0&&(this.hoverIndex=0),this.focusItem()},focusItem:function(){if(this.hoverIndex<this.items.length){this.$refs.itemRef[this.hoverIndex].focus();let e=this;setTimeout(function(){e.$refs.searchBox.focus(),null!=e.hideTimer&&(clearTimeout(e.hideTimer),e.hideTimer=null)})}},change:function(){this.$emit("change",this.selectedItem);let e=this;setTimeout(function(){null!=e.$refs.selectedLabel&&e.$refs.selectedLabel.focus()})},submitForm:function(e){if("A"==e.target.tagName){let e=this.$refs.selectedLabel.parentNode;for(;;){if(null==(e=e.parentNode)||"BODY"==e.tagName)return;if("FORM"==e.tagName){e.submit();break}}}}},template:`<div style="display: inline; z-index: 10; background: white">
|
||||
</span>`}),Vue.component("combo-box",{props:["name","title","placeholder","size","v-items","v-value","data-url","data-key","width"],mounted:function(){var e=this.dataUrl;let i=this.dataKey,s=this;null!=e&&0<e.length&&null!=i&&Tea.action(e).post().success(function(t){if(null!=t.data&&"object"==typeof t.data[i]){let e=s.formatItems(t.data[i]);s.allItems=e,s.items=e.$copy(),null!=s.vValue&&e.forEach(function(e){e.value==s.vValue&&(s.selectedItem=e)})}});e=this.$refs.searchBox.offsetWidth;null!=e&&0<e?this.$refs.menu.style.width=e+"px":0<this.styleWidth.length&&(this.$refs.menu.style.width=this.styleWidth)},data:function(){let e=this.vItems,i=(null!=e&&e instanceof Array||(e=[]),e=this.formatItems(e),null);if(null!=this.vValue){let t=this;e.forEach(function(e){e.value==t.vValue&&(i=e)})}let t=this.width;return null==t||0==t.length?t="11em":/\d+$/.test(t)&&(t+="em"),{allItems:e,items:e.$copy(),selectedItem:i,keyword:"",visible:!1,hideTimer:null,hoverIndex:0,styleWidth:t}},methods:{formatItems:function(e){return e.forEach(function(e){null==e.value&&(e.value=e.id)}),e},reset:function(){this.selectedItem=null,this.change(),this.hoverIndex=0;let e=this;setTimeout(function(){e.$refs.searchBox&&e.$refs.searchBox.focus()})},clear:function(){this.selectedItem=null,this.change(),this.hoverIndex=0},changeKeyword:function(){this.hoverIndex=0;let t=this.keyword;0==t.length?this.items=this.allItems.$copy():this.items=this.allItems.$copy().filter(function(e){return!!(null!=e.fullname&&0<e.fullname.length&&teaweb.match(e.fullname,t))||teaweb.match(e.name,t)})},selectItem:function(e){this.selectedItem=e,this.change(),this.hoverIndex=0,this.keyword="",this.changeKeyword()},confirm:function(){this.items.length>this.hoverIndex&&this.selectItem(this.items[this.hoverIndex])},show:function(){this.visible=!0},hide:function(){let e=this;this.hideTimer=setTimeout(function(){e.visible=!1},500)},downItem:function(){this.hoverIndex++,this.hoverIndex>this.items.length-1&&(this.hoverIndex=0),this.focusItem()},upItem:function(){this.hoverIndex--,this.hoverIndex<0&&(this.hoverIndex=0),this.focusItem()},focusItem:function(){if(this.hoverIndex<this.items.length){this.$refs.itemRef[this.hoverIndex].focus();let e=this;setTimeout(function(){e.$refs.searchBox.focus(),null!=e.hideTimer&&(clearTimeout(e.hideTimer),e.hideTimer=null)})}},change:function(){this.$emit("change",this.selectedItem);let e=this;setTimeout(function(){null!=e.$refs.selectedLabel&&e.$refs.selectedLabel.focus()})},submitForm:function(e){if("A"==e.target.tagName){let e=this.$refs.selectedLabel.parentNode;for(;;){if(null==(e=e.parentNode)||"BODY"==e.tagName)return;if("FORM"==e.tagName){e.submit();break}}}}},template:`<div style="display: inline; z-index: 10; background: white" class="combo-box">
|
||||
<!-- 搜索框 -->
|
||||
<div v-if="selectedItem == null">
|
||||
<input type="text" v-model="keyword" :placeholder="placeholder" :size="size" style="width: 11em" @input="changeKeyword" @focus="show" @blur="hide" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="searchBox" @keyup.down="downItem" @keyup.up="upItem"/>
|
||||
<input type="text" v-model="keyword" :placeholder="placeholder" :size="size" :style="{'width': styleWidth}" @input="changeKeyword" @focus="show" @blur="hide" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="searchBox" @keyup.down="downItem" @keyup.up="upItem"/>
|
||||
</div>
|
||||
|
||||
<!-- 当前选中 -->
|
||||
@@ -4273,9 +4273,12 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
|
||||
</div>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<div v-if="selectedItem == null && items.length > 0 && visible">
|
||||
<div class="ui menu vertical small narrow-scrollbar" style="width: 11em; max-height: 17em; overflow-y: auto; position: absolute; border: rgba(129, 177, 210, 0.81) 1px solid; border-top: 0; z-index: 100">
|
||||
<a href="" v-for="(item, index) in items" ref="itemRef" class="item" :class="{active: index == hoverIndex, blue: index == hoverIndex}" @click.prevent="selectItem(item)" style="line-height: 1.4">{{item.name}}</a>
|
||||
<div v-show="selectedItem == null && items.length > 0 && visible">
|
||||
<div class="ui menu vertical small narrow-scrollbar" ref="menu">
|
||||
<a href="" v-for="(item, index) in items" ref="itemRef" class="item" :class="{active: index == hoverIndex, blue: index == hoverIndex}" @click.prevent="selectItem(item)" style="line-height: 1.4">
|
||||
<span v-if="item.fullname != null && item.fullname.length > 0">{{item.fullname}}</span>
|
||||
<span v-else>{{item.name}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`}),Vue.component("time-duration-box",{props:["v-name","v-value","v-count","v-unit"],mounted:function(){this.change()},data:function(){let e=this.vValue;return"number"!=typeof(e=null==e?{count:this.vCount,unit:this.vUnit}:e).count&&(e.count=-1),{duration:e,countString:0<=e.count?e.count.toString():""}},watch:{countString:function(e){var e=e.trim();0==e.length?this.duration.count=-1:(e=parseInt(e),isNaN(e)||(this.duration.count=e),this.change())}},methods:{change:function(){this.$emit("change",this.duration)}},template:`<div class="ui fields inline" style="padding-bottom: 0; margin-bottom: 0">
|
||||
|
||||
@@ -12802,19 +12802,49 @@ Vue.component("request-variables-describer", {
|
||||
|
||||
|
||||
Vue.component("combo-box", {
|
||||
props: ["name", "title", "placeholder", "size", "v-items", "v-value"],
|
||||
// data-url 和 data-key 成对出现
|
||||
props: ["name", "title", "placeholder", "size", "v-items", "v-value", "data-url", "data-key", "width"],
|
||||
mounted: function () {
|
||||
// 从URL中获取选项数据
|
||||
let dataUrl = this.dataUrl
|
||||
let dataKey = this.dataKey
|
||||
let that = this
|
||||
if (dataUrl != null && dataUrl.length > 0 && dataKey != null) {
|
||||
Tea.action(dataUrl)
|
||||
.post()
|
||||
.success(function (resp) {
|
||||
if (resp.data != null) {
|
||||
if (typeof (resp.data[dataKey]) == "object") {
|
||||
let items = that.formatItems(resp.data[dataKey])
|
||||
that.allItems = items
|
||||
that.items = items.$copy()
|
||||
|
||||
if (that.vValue != null) {
|
||||
items.forEach(function (v) {
|
||||
if (v.value == that.vValue) {
|
||||
that.selectedItem = v
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 设定菜单宽度
|
||||
let inputWidth = this.$refs.searchBox.offsetWidth
|
||||
if (inputWidth != null && inputWidth > 0) {
|
||||
this.$refs.menu.style.width = inputWidth + "px"
|
||||
} else if (this.styleWidth.length > 0) {
|
||||
this.$refs.menu.style.width = this.styleWidth
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
let items = this.vItems
|
||||
if (items == null || !(items instanceof Array)) {
|
||||
items = []
|
||||
}
|
||||
|
||||
// 自动使用ID作为值
|
||||
items.forEach(function (v) {
|
||||
if (v.value == null) {
|
||||
v.value = v.id
|
||||
}
|
||||
})
|
||||
items = this.formatItems(items)
|
||||
|
||||
// 当前选中项
|
||||
let selectedItem = null
|
||||
@@ -12827,17 +12857,35 @@ Vue.component("combo-box", {
|
||||
})
|
||||
}
|
||||
|
||||
let width = this.width
|
||||
if (width == null || width.length == 0) {
|
||||
width = "11em"
|
||||
} else {
|
||||
if (/\d+$/.test(width)) {
|
||||
width += "em"
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
allItems: items,
|
||||
items: items.$copy(),
|
||||
selectedItem: selectedItem,
|
||||
allItems: items, // 原始的所有的items
|
||||
items: items.$copy(), // 候选的items
|
||||
selectedItem: selectedItem, // 选中的item
|
||||
keyword: "",
|
||||
visible: false,
|
||||
hideTimer: null,
|
||||
hoverIndex: 0
|
||||
hoverIndex: 0,
|
||||
styleWidth: width
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatItems: function (items) {
|
||||
items.forEach(function (v) {
|
||||
if (v.value == null) {
|
||||
v.value = v.id
|
||||
}
|
||||
})
|
||||
return items
|
||||
},
|
||||
reset: function () {
|
||||
this.selectedItem = null
|
||||
this.change()
|
||||
@@ -12850,6 +12898,11 @@ Vue.component("combo-box", {
|
||||
}
|
||||
})
|
||||
},
|
||||
clear: function () {
|
||||
this.selectedItem = null
|
||||
this.change()
|
||||
this.hoverIndex = 0
|
||||
},
|
||||
changeKeyword: function () {
|
||||
this.hoverIndex = 0
|
||||
let keyword = this.keyword
|
||||
@@ -12858,6 +12911,9 @@ Vue.component("combo-box", {
|
||||
return
|
||||
}
|
||||
this.items = this.allItems.$copy().filter(function (v) {
|
||||
if (v.fullname != null && v.fullname.length > 0 && teaweb.match(v.fullname, keyword)) {
|
||||
return true
|
||||
}
|
||||
return teaweb.match(v.name, keyword)
|
||||
})
|
||||
},
|
||||
@@ -12938,10 +12994,10 @@ Vue.component("combo-box", {
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `<div style="display: inline; z-index: 10; background: white">
|
||||
template: `<div style="display: inline; z-index: 10; background: white" class="combo-box">
|
||||
<!-- 搜索框 -->
|
||||
<div v-if="selectedItem == null">
|
||||
<input type="text" v-model="keyword" :placeholder="placeholder" :size="size" style="width: 11em" @input="changeKeyword" @focus="show" @blur="hide" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="searchBox" @keyup.down="downItem" @keyup.up="upItem"/>
|
||||
<input type="text" v-model="keyword" :placeholder="placeholder" :size="size" :style="{'width': styleWidth}" @input="changeKeyword" @focus="show" @blur="hide" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="searchBox" @keyup.down="downItem" @keyup.up="upItem"/>
|
||||
</div>
|
||||
|
||||
<!-- 当前选中 -->
|
||||
@@ -12953,9 +13009,12 @@ Vue.component("combo-box", {
|
||||
</div>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<div v-if="selectedItem == null && items.length > 0 && visible">
|
||||
<div class="ui menu vertical small narrow-scrollbar" style="width: 11em; max-height: 17em; overflow-y: auto; position: absolute; border: rgba(129, 177, 210, 0.81) 1px solid; border-top: 0; z-index: 100">
|
||||
<a href="" v-for="(item, index) in items" ref="itemRef" class="item" :class="{active: index == hoverIndex, blue: index == hoverIndex}" @click.prevent="selectItem(item)" style="line-height: 1.4">{{item.name}}</a>
|
||||
<div v-show="selectedItem == null && items.length > 0 && visible">
|
||||
<div class="ui menu vertical small narrow-scrollbar" ref="menu">
|
||||
<a href="" v-for="(item, index) in items" ref="itemRef" class="item" :class="{active: index == hoverIndex, blue: index == hoverIndex}" @click.prevent="selectItem(item)" style="line-height: 1.4">
|
||||
<span v-if="item.fullname != null && item.fullname.length > 0">{{item.fullname}}</span>
|
||||
<span v-else>{{item.name}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
@@ -1,17 +1,47 @@
|
||||
Vue.component("combo-box", {
|
||||
props: ["name", "title", "placeholder", "size", "v-items", "v-value"],
|
||||
// data-url 和 data-key 成对出现
|
||||
props: ["name", "title", "placeholder", "size", "v-items", "v-value", "data-url", "data-key", "width"],
|
||||
mounted: function () {
|
||||
// 从URL中获取选项数据
|
||||
let dataUrl = this.dataUrl
|
||||
let dataKey = this.dataKey
|
||||
let that = this
|
||||
if (dataUrl != null && dataUrl.length > 0 && dataKey != null) {
|
||||
Tea.action(dataUrl)
|
||||
.post()
|
||||
.success(function (resp) {
|
||||
if (resp.data != null) {
|
||||
if (typeof (resp.data[dataKey]) == "object") {
|
||||
let items = that.formatItems(resp.data[dataKey])
|
||||
that.allItems = items
|
||||
that.items = items.$copy()
|
||||
|
||||
if (that.vValue != null) {
|
||||
items.forEach(function (v) {
|
||||
if (v.value == that.vValue) {
|
||||
that.selectedItem = v
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 设定菜单宽度
|
||||
let inputWidth = this.$refs.searchBox.offsetWidth
|
||||
if (inputWidth != null && inputWidth > 0) {
|
||||
this.$refs.menu.style.width = inputWidth + "px"
|
||||
} else if (this.styleWidth.length > 0) {
|
||||
this.$refs.menu.style.width = this.styleWidth
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
let items = this.vItems
|
||||
if (items == null || !(items instanceof Array)) {
|
||||
items = []
|
||||
}
|
||||
|
||||
// 自动使用ID作为值
|
||||
items.forEach(function (v) {
|
||||
if (v.value == null) {
|
||||
v.value = v.id
|
||||
}
|
||||
})
|
||||
items = this.formatItems(items)
|
||||
|
||||
// 当前选中项
|
||||
let selectedItem = null
|
||||
@@ -24,17 +54,35 @@ Vue.component("combo-box", {
|
||||
})
|
||||
}
|
||||
|
||||
let width = this.width
|
||||
if (width == null || width.length == 0) {
|
||||
width = "11em"
|
||||
} else {
|
||||
if (/\d+$/.test(width)) {
|
||||
width += "em"
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
allItems: items,
|
||||
items: items.$copy(),
|
||||
selectedItem: selectedItem,
|
||||
allItems: items, // 原始的所有的items
|
||||
items: items.$copy(), // 候选的items
|
||||
selectedItem: selectedItem, // 选中的item
|
||||
keyword: "",
|
||||
visible: false,
|
||||
hideTimer: null,
|
||||
hoverIndex: 0
|
||||
hoverIndex: 0,
|
||||
styleWidth: width
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatItems: function (items) {
|
||||
items.forEach(function (v) {
|
||||
if (v.value == null) {
|
||||
v.value = v.id
|
||||
}
|
||||
})
|
||||
return items
|
||||
},
|
||||
reset: function () {
|
||||
this.selectedItem = null
|
||||
this.change()
|
||||
@@ -47,6 +95,11 @@ Vue.component("combo-box", {
|
||||
}
|
||||
})
|
||||
},
|
||||
clear: function () {
|
||||
this.selectedItem = null
|
||||
this.change()
|
||||
this.hoverIndex = 0
|
||||
},
|
||||
changeKeyword: function () {
|
||||
this.hoverIndex = 0
|
||||
let keyword = this.keyword
|
||||
@@ -55,6 +108,9 @@ Vue.component("combo-box", {
|
||||
return
|
||||
}
|
||||
this.items = this.allItems.$copy().filter(function (v) {
|
||||
if (v.fullname != null && v.fullname.length > 0 && teaweb.match(v.fullname, keyword)) {
|
||||
return true
|
||||
}
|
||||
return teaweb.match(v.name, keyword)
|
||||
})
|
||||
},
|
||||
@@ -135,10 +191,10 @@ Vue.component("combo-box", {
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `<div style="display: inline; z-index: 10; background: white">
|
||||
template: `<div style="display: inline; z-index: 10; background: white" class="combo-box">
|
||||
<!-- 搜索框 -->
|
||||
<div v-if="selectedItem == null">
|
||||
<input type="text" v-model="keyword" :placeholder="placeholder" :size="size" style="width: 11em" @input="changeKeyword" @focus="show" @blur="hide" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="searchBox" @keyup.down="downItem" @keyup.up="upItem"/>
|
||||
<input type="text" v-model="keyword" :placeholder="placeholder" :size="size" :style="{'width': styleWidth}" @input="changeKeyword" @focus="show" @blur="hide" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="searchBox" @keyup.down="downItem" @keyup.up="upItem"/>
|
||||
</div>
|
||||
|
||||
<!-- 当前选中 -->
|
||||
@@ -150,9 +206,12 @@ Vue.component("combo-box", {
|
||||
</div>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<div v-if="selectedItem == null && items.length > 0 && visible">
|
||||
<div class="ui menu vertical small narrow-scrollbar" style="width: 11em; max-height: 17em; overflow-y: auto; position: absolute; border: rgba(129, 177, 210, 0.81) 1px solid; border-top: 0; z-index: 100">
|
||||
<a href="" v-for="(item, index) in items" ref="itemRef" class="item" :class="{active: index == hoverIndex, blue: index == hoverIndex}" @click.prevent="selectItem(item)" style="line-height: 1.4">{{item.name}}</a>
|
||||
<div v-show="selectedItem == null && items.length > 0 && visible">
|
||||
<div class="ui menu vertical small narrow-scrollbar" ref="menu">
|
||||
<a href="" v-for="(item, index) in items" ref="itemRef" class="item" :class="{active: index == hoverIndex, blue: index == hoverIndex}" @click.prevent="selectItem(item)" style="line-height: 1.4">
|
||||
<span v-if="item.fullname != null && item.fullname.length > 0">{{item.fullname}}</span>
|
||||
<span v-else>{{item.name}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
Reference in New Issue
Block a user