优化WAF区域/省份封禁:增加仅允许、增加中国香港澳台、内地等特殊区域

This commit is contained in:
GoEdgeLab
2023-07-07 09:53:00 +08:00
parent 3b8a483933
commit e27c0280ff
30 changed files with 751 additions and 237 deletions

View File

@@ -1,17 +0,0 @@
.region-letter-group .item {
padding-left: 1em !important;
padding-right: 1em !important;
}
.country-group {
padding-bottom: 1em;
}
.country-group .country-list .item {
float: left;
width: 12em;
margin-bottom: 0.5em;
}
.country-group .country-list .item .checkbox label {
font-size: 12px !important;
cursor: pointer !important;
}
/*# sourceMappingURL=countries.css.map */

View File

@@ -1 +0,0 @@
{"version":3,"sources":["countries.less"],"names":[],"mappings":"AAAA,oBACC;EACC,4BAAA;EACA,6BAAA;;AAIF;EAcC,mBAAA;;AAdD,cACC,cACC;EACC,WAAA;EACA,WAAA;EACA,oBAAA;;AALH,cACC,cACC,MAKC,UAAU;EACT,0BAAA;EACA,0BAAA","file":"countries.css"}

View File

@@ -15,54 +15,32 @@
<input type="hidden" name="exceptURLPatternsJSON" :value="JSON.stringify(exceptURLPatterns)"/>
<input type="hidden" name="onlyURLPatternsJSON" :value="JSON.stringify(onlyURLPatterns)"/>
<table class="ui table selectable definition">
<tr>
<td class="title">已封禁</td>
<td>
<span v-if="countSelectedCountries == 0" class="disabled">暂时没有选择封禁区域。</span>
<div class="ui label tiny basic" v-for="country in countries" v-if="country.isChecked" style="margin-bottom: 0.5em">
<input type="hidden" name="countryIds" :value="country.id"/>
({{country.letter}}){{country.name}} <a href="" @click.prevent="deselectCountry(country)" title="取消封禁"><i class="icon remove"></i></a>
</div>
</td>
</tr>
<tr>
<td>选择封禁区域 *</td>
<td>
<more-options-indicator><span v-if="!moreOptionsVisible">选择区域</span><span v-else>完成选择</span></more-options-indicator>
<div class="ui menu tabular tiny region-letter-group" v-show="moreOptionsVisible">
<a href="" v-for="group in letterGroups" class="item" :class="{active: group == selectedGroup}" @click.prevent="selectGroup(group)">{{group}}</a>
<div class="item right">
<div class="ui checkbox" @click.prevent="checkAll">
<input type="checkbox" v-model="isCheckingAll"/>
<label>全选</label>
</div>
</div>
</div>
<div v-for="group in letterGroups" v-show="moreOptionsVisible">
<div v-for="letter in group" v-if="letterCountries[letter] != null && group == selectedGroup" class="country-group">
<h4>{{letter}}</h4>
<div class="country-list">
<div class="item" v-for="country in letterCountries[letter]">
<div class="ui checkbox" @click.prevent="selectCountry(country)">
<input type="checkbox" v-model="country.isChecked"/>
<label>{{country.name}}</label>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
</td>
</tr>
<tr>
<td>例外URL &nbsp;<tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
<td class="title">仅允许的区域</td>
<td>
<http-firewall-region-selector :v-countries="allowedCountries" :v-type="'allow'" @change="changeAllowedCountries"></http-firewall-region-selector>
</td>
</tr>
<tr>
<td>限制URL &nbsp;<tip-icon content="只对这些URL做限制。"></tip-icon></td>
<td><url-patterns-box v-model="onlyURLPatterns"></url-patterns-box></td>
<td class="title">仅封禁的区域</td>
<td>
<p class="comment" v-if="allowedCountries.length > 0">由于你已设置"仅允许的区域",所以不需要再设置封禁区域。</p>
<http-firewall-region-selector :v-countries="deniedCountries" :v-type="'deny'" v-show="allowedCountries.length == 0"></http-firewall-region-selector>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>例外URL &nbsp;<tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
</tr>
<tr>
<td>限制URL &nbsp;<tip-icon content="只对这些URL做限制。"></tip-icon></td>
<td><url-patterns-box v-model="onlyURLPatterns"></url-patterns-box></td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -1,54 +1,11 @@
Tea.context(function () {
this.letterGroups = [
"ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZ"
];
this.selectedGroup = "ABC"
this.letterCountries = {}
let that = this
this.countSelectedCountries = this.countries.$count(function (k, country) {
return country.isChecked
})
this.countries.forEach(function (country) {
if (typeof (that.letterCountries[country.letter]) == "undefined") {
that.letterCountries[country.letter] = []
}
that.letterCountries[country.letter].push(country)
})
this.isCheckingAll = false
this.selectGroup = function (group) {
this.selectedGroup = group
}
this.selectCountry = function (country) {
country.isChecked = !country.isChecked
this.change()
}
this.deselectCountry = function (country) {
country.isChecked = false
this.change()
}
this.checkAll = function () {
this.isCheckingAll = !this.isCheckingAll
this.countries.forEach(function (country) {
country.isChecked = that.isCheckingAll
})
this.change()
}
this.success = function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
this.change = function () {
this.countSelectedCountries = this.countries.$count(function (k, country) {
return country.isChecked
})
this.changeAllowedCountries = function (event) {
this.allowedCountries = event.countries
}
})

View File

@@ -1,23 +0,0 @@
.region-letter-group {
.item {
padding-left: 1em !important;
padding-right: 1em !important;
}
}
.country-group {
.country-list {
.item {
float: left;
width: 12em;
margin-bottom: 0.5em;
.checkbox label {
font-size: 12px !important;
cursor: pointer !important;
}
}
}
padding-bottom: 1em;
}

View File

@@ -1 +0,0 @@
{"version":3,"sources":["provinces.less"],"names":[],"mappings":"AAAA,cACC;EACC,WAAA;EACA,WAAA;EACA,oBAAA;;AAJF,cACC,MAKC,UAAU;EACT,0BAAA;EACA,0BAAA","file":"provinces.css"}

View File

@@ -15,49 +15,32 @@
<input type="hidden" name="exceptURLPatternsJSON" :value="JSON.stringify(exceptURLPatterns)"/>
<input type="hidden" name="onlyURLPatternsJSON" :value="JSON.stringify(onlyURLPatterns)"/>
<table class="ui table selectable definition">
<tr>
<td class="title">已封禁</td>
<td>
<span v-if="countSelectedProvinces == 0" class="disabled">暂时没有选择封禁省份。</span>
<div class="ui label tiny basic" v-for="province in provinces" v-if="province.isChecked" style="margin-bottom: 0.5em">
<input type="hidden" name="provinceIds" :value="province.id"/>
{{province.name}} <a href="" @click.prevent="deselectProvince(province)" title="取消封禁"><i class="icon remove"></i></a>
</div>
</td>
</tr>
<tr>
<td>选择封禁区域</td>
<td>
<first-menu>
<menu-item><more-options-indicator><span v-if="!moreOptionsVisible">选择省份/自治区</span><span v-else>完成选择</span></more-options-indicator></menu-item>
<div class="item right" v-show="moreOptionsVisible">
<div class="ui checkbox" @click.prevent="checkAll">
<input type="checkbox" v-model="isCheckingAll"/>
<label>全选</label>
</div>
</div>
</first-menu>
<div class="province-list" v-show="moreOptionsVisible" style="margin-top:0.5em">
<div class="item" v-for="province in provinces">
<div class="ui checkbox" @click.prevent="selectProvince(province)">
<input type="checkbox" v-model="province.isChecked"/>
<label>{{province.name}}</label>
</div>
</div>
</div>
<div class="clear"></div>
</td>
</tr>
<tr>
<td>例外URL &nbsp;<tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
<td class="title">仅允许的省份</td>
<td>
<http-firewall-province-selector :v-provinces="allowedProvinces" :v-type="'allow'" @change="changeAllowedProvinces"></http-firewall-province-selector>
</td>
</tr>
<tr>
<td>限制URL &nbsp;<tip-icon content="只对这些URL做限制。"></tip-icon></td>
<td><url-patterns-box v-model="onlyURLPatterns"></url-patterns-box></td>
<td class="title">仅封禁的省份</td>
<td>
<p class="comment" v-if="allowedProvinces.length > 0">由于你已设置"仅允许的省份",所以不需要再设置封禁省份。</p>
<http-firewall-province-selector :v-provinces="deniedProvinces" :v-type="'deny'" v-show="allowedProvinces.length == 0"></http-firewall-province-selector>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>例外URL &nbsp;<tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
</tr>
<tr>
<td>限制URL &nbsp;<tip-icon content="只对这些URL做限制。"></tip-icon></td>
<td><url-patterns-box v-model="onlyURLPatterns"></url-patterns-box></td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -1,40 +1,11 @@
Tea.context(function () {
this.isCheckingAll = false
this.countSelectedProvinces = this.provinces.$count(function (k, province) {
return province.isChecked
})
this.selectProvince = function (province) {
province.isChecked = !province.isChecked
this.change()
}
this.deselectProvince = function (province) {
province.isChecked = false
this.change()
}
this.checkAll = function () {
this.isCheckingAll = !this.isCheckingAll
let that = this
this.provinces.forEach(function (province) {
province.isChecked = that.isCheckingAll
})
this.change()
}
this.success = function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
this.change = function () {
this.countSelectedProvinces = this.provinces.$count(function (k, province) {
return province.isChecked
})
this.changeAllowedProvinces = function (event) {
this.allowedProvinces = event.provinces
}
})

View File

@@ -0,0 +1,28 @@
.region-letter-group .item {
padding-left: 0.8em !important;
padding-right: 0.8em !important;
}
.region-letter-group .item .count {
font-size: 0.8em;
color: grey;
}
.country-groups {
max-height: 23em;
overflow-y: auto;
}
.country-groups .country-group {
padding-bottom: 1em;
}
.country-groups .country-group .country-list .item {
float: left;
width: 9em;
margin-bottom: 0.5em;
}
.country-groups .country-group .country-list .item .checkbox label {
font-size: 12px !important;
cursor: pointer !important;
}
.country-groups::-webkit-scrollbar {
width: 4px;
}
/*# sourceMappingURL=selectCountriesPopup.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["selectCountriesPopup.less"],"names":[],"mappings":"AAAA,oBACC;EACC,mBAAA;EACA,oBAAA;;AAHF,oBACC,MAIC;EACC,gBAAA;EACA,WAAA;;AAKH;EACC,gBAAA;EACA,gBAAA;;AAFD,eAIC;EACC,mBAAA;;AALF,eAIC,eAGC,cACC;EACC,WAAA;EACA,UAAA;EACA,oBAAA;;AAXJ,eAIC,eAGC,cACC,MAKC,UAAU;EACT,0BAAA;EACA,0BAAA;;AAOL,eAAe;EACd,UAAA","file":"selectCountriesPopup.css"}

View File

@@ -0,0 +1,59 @@
{$layout "layout_popup"}
<h3 v-show="type == 'allow'">选择允许的区域</h3>
<h3 v-show="type == 'deny'">选择封禁的区域</h3>
<form class="ui form">
<div class="ui menu tabular tiny region-letter-group attached">
<a href="" v-for="group in letterGroups" class="item" :class="{active: group.code == selectedGroup, disabled: group.countMatched == 0}" @click.prevent="selectGroup(group)">{{group.code}}<span v-if="group.count > 0" class="count">&nbsp;({{group.count}})</span></a>
<div class="item right">
<div class="ui checkbox" @click.prevent="checkAll">
<input type="checkbox" v-model="isCheckingAll"/>
<label>全选</label>
</div>
</div>
</div>
<div class="country-groups ui segment attached">
<div v-for="group in letterGroups">
<div v-if="group.code == commonGroupName && group.code == selectedGroup">
<div class="country-group">
<div class="country-list">
<div class="item" v-for="country in letterCountries[commonGroupName]">
<div class="ui checkbox" @click.prevent="selectCountry(country)">
<input type="checkbox" v-model="country.isChecked"/>
<label><span :class="{blue: country.isMatched}">{{country.name}}</span></label>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
<div v-else>
<div v-for="letter in group.code" v-if="letterCountries[letter] != null && group.code == selectedGroup" class="country-group">
<h4>{{letter}}</h4>
<div class="country-list">
<div class="item" v-for="country in letterCountries[letter]">
<div class="ui checkbox" @click.prevent="selectCountry(country)">
<input type="checkbox" v-model="country.isChecked"/>
<label><span :class="{blue: country.isMatched}">{{country.name}}</span></label>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
<div class="margin"></div>
<div class="ui menu text basic">
<div class="item">
<button class="ui button primary" @click.prevent="submit">确定</button>
</div>
<div class="item right" v-show="!searchBoxVisible">
<a href="" @click.prevent="showSearchBox"><i class="icon search"></i></a>
</div>
<div class="item right" v-show="searchBoxVisible">
<search-box placeholder="关键词" ref="searchBox" @change="changeKeyword"></search-box>
</div>
</div>
</form>

View File

@@ -0,0 +1,197 @@
Tea.context(function () {
var commonGroupName = "常用"
this.letterGroups = [
{
"code": commonGroupName,
"count": 0,
"countMatched": 0
},
{
"code": "ABC",
"count": 0,
"countMatched": 0
},
{
"code": "DEF",
"count": 0,
"countMatched": 0
},
{
"code": "GHI",
"count": 0,
"countMatched": 0
},
{
"code": "JKL",
"count": 0,
"countMatched": 0
},
{
"code": "MNO",
"count": 0,
"countMatched": 0
},
{
"code": "PQR",
"count": 0,
"countMatched": 0
},
{
"code": "STU",
"count": 0,
"countMatched": 0
},
{
"code": "VWX",
"count": 0,
"countMatched": 0
},
{
"code": "YZ",
"count": 0,
"countMatched": 0
}
]
this.commonGroupName = commonGroupName
this.selectedGroup = commonGroupName
this.letterCountries = {}
let that = this
this.countSelectedCountries = this.countries.$count(function (k, country) {
return country.isChecked
})
this.countries.forEach(function (country) {
// letter
if (typeof (that.letterCountries[country.letter]) == "undefined") {
that.letterCountries[country.letter] = []
}
that.letterCountries[country.letter].push(country)
// common
if (country.isCommon) {
if (typeof that.letterCountries[commonGroupName] == "undefined") {
that.letterCountries[commonGroupName] = []
}
that.letterCountries[commonGroupName].push(country)
}
})
this.isCheckingAll = false
this.$delay(function () {
this.change()
})
this.checkAll = function () {
this.isCheckingAll = !this.isCheckingAll
this.countries.forEach(function (country) {
country.isChecked = that.isCheckingAll
})
this.change()
}
this.selectGroup = function (group) {
this.selectedGroup = group.code
}
this.selectCountry = function (country) {
country.isChecked = !country.isChecked
this.change()
}
this.deselectCountry = function (country) {
country.isChecked = false
this.change()
}
this.change = function () {
let that = this
this.letterGroups.forEach(function (group) {
group.count = 0
group.countMatched = 0
})
this.countries.forEach(function (country) {
that.letterGroups.forEach(function (group) {
if (group.code.indexOf(country.letter) >= 0 || (group.code == commonGroupName && country.isCommon)) {
if (country.isChecked) {
group.count++
}
if (that.matchCountry(country)) {
country.isMatched = (that.keyword.length > 0)
group.countMatched++
} else {
country.isMatched = false
}
}
})
})
}
this.submit = function () {
let selectedCountries = []
this.countries.forEach(function (country) {
if (country.isChecked) {
selectedCountries.push(country)
}
})
NotifyPopup({
code: 200,
data: {
selectedCountries: selectedCountries
}
})
}
/**
* searching
*/
this.searchBoxVisible = false
this.keyword = ""
this.showSearchBox = function () {
this.searchBoxVisible = true
this.$delay(function () {
this.$refs.searchBox.focus()
})
}
this.changeKeyword = function (event) {
this.keyword = event.value.trim()
this.change()
}
this.matchCountry = function (country) {
if (this.keyword.length == 0) {
return true
}
if (teaweb.match(country.name, this.keyword)) {
return true
}
if (country.pinyin != null && country.pinyin.length > 0) {
let matched = false
let that = this
country.pinyin.forEach(function (code) {
if (teaweb.match(code, that.keyword)) {
matched = true
}
})
if (matched) {
return true
}
}
if (country.codes != null && country.codes.length > 0) {
let matched = false
let that = this
country.codes.forEach(function (code) {
if (teaweb.match(code, that.keyword)) {
matched = true
}
})
if (matched) {
return true
}
}
return false
}
})

View File

@@ -0,0 +1,37 @@
.region-letter-group {
.item {
padding-left: 0.8em !important;
padding-right: 0.8em !important;
.count {
font-size: 0.8em;
color: grey;
}
}
}
.country-groups {
max-height: 23em;
overflow-y: auto;
.country-group {
padding-bottom: 1em;
.country-list {
.item {
float: left;
width: 9em;
margin-bottom: 0.5em;
.checkbox label {
font-size: 12px !important;
cursor: pointer !important;
}
}
}
}
}
.country-groups::-webkit-scrollbar {
width: 4px;
}

View File

@@ -7,4 +7,4 @@
font-size: 12px !important;
cursor: pointer !important;
}
/*# sourceMappingURL=provinces.css.map */
/*# sourceMappingURL=selectProvincesPopup.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["selectProvincesPopup.less"],"names":[],"mappings":"AAAA,cACC;EACC,WAAA;EACA,WAAA;EACA,oBAAA;;AAJF,cACC,MAKC,UAAU;EACT,0BAAA;EACA,0BAAA","file":"selectProvincesPopup.css"}

View File

@@ -0,0 +1,32 @@
{$layout "layout_popup"}
<h3 v-show="type == 'allow'">选择允许的省份</h3>
<h3 v-show="type == 'deny'">选择封禁的省份</h3>
<form class="ui form">
<table class="ui table">
<tr>
<td>
<first-menu>
<div class="item right">
<div class="ui checkbox" @click.prevent="checkAll">
<input type="checkbox" v-model="isCheckingAll"/>
<label>全选</label>
</div>
</div>
</first-menu>
<div class="province-list" style="margin-top:0.5em">
<div class="item" v-for="province in provinces">
<div class="ui checkbox" @click.prevent="selectProvince(province)">
<input type="checkbox" v-model="province.isChecked"/>
<label>{{province.name}}</label>
</div>
</div>
</div>
<div class="clear"></div>
</td>
</tr>
</table>
<button class="ui button primary" type="button" @click.prevent="submit">确定</button>
</form>

View File

@@ -0,0 +1,46 @@
Tea.context(function () {
this.isCheckingAll = false
this.countSelectedProvinces = this.provinces.$count(function (k, province) {
return province.isChecked
})
this.selectProvince = function (province) {
province.isChecked = !province.isChecked
this.change()
}
this.deselectProvince = function (province) {
province.isChecked = false
this.change()
}
this.checkAll = function () {
this.isCheckingAll = !this.isCheckingAll
let that = this
this.provinces.forEach(function (province) {
province.isChecked = that.isCheckingAll
})
this.change()
}
this.change = function () {
}
this.submit = function () {
let selectedProvinces = []
this.provinces.forEach(function (province) {
if (province.isChecked) {
selectedProvinces.push(province)
}
})
NotifyPopup({
code: 200,
data: {
selectedProvinces: selectedProvinces
}
})
}
})