mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-03 12:20:28 +08:00
优化WAF区域/省份封禁:增加仅允许、增加中国香港澳台、内地等特殊区域
This commit is contained in:
@@ -7,13 +7,12 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
const ChinaCountryId = 1
|
||||
|
||||
type ProvincesAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -43,7 +42,7 @@ func (this *ProvincesAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{
|
||||
RegionCountryId: int64(ChinaCountryId),
|
||||
RegionCountryId: regionconfigs.RegionChinaId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -12,8 +12,6 @@ import (
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
const ChinaCountryId = 1
|
||||
|
||||
type ProvincesAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ func init() {
|
||||
Get("/ipadmin/allowList", new(ipadmin.AllowListAction)).
|
||||
Get("/ipadmin/denyList", new(ipadmin.DenyListAction)).
|
||||
GetPost("/ipadmin/countries", new(ipadmin.CountriesAction)).
|
||||
Get("/ipadmin/selectCountriesPopup", new(ipadmin.SelectCountriesPopupAction)).
|
||||
Get("/ipadmin/selectProvincesPopup", new(ipadmin.SelectProvincesPopupAction)).
|
||||
GetPost("/ipadmin/provinces", new(ipadmin.ProvincesAction)).
|
||||
GetPost("/ipadmin/updateIPPopup", new(ipadmin.UpdateIPPopupAction)).
|
||||
Post("/ipadmin/deleteIP", new(ipadmin.DeleteIPAction)).
|
||||
|
||||
@@ -42,9 +42,11 @@ func (this *CountriesAction) RunGet(params struct {
|
||||
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
||||
return
|
||||
}
|
||||
var selectedCountryIds = []int64{}
|
||||
var deniedCountryIds = []int64{}
|
||||
var allowedCountryIds = []int64{}
|
||||
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||
selectedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
|
||||
deniedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
|
||||
allowedCountryIds = policyConfig.Inbound.Region.AllowCountryIds
|
||||
}
|
||||
|
||||
countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.AdminContext(), &pb.FindAllRegionCountriesRequest{})
|
||||
@@ -52,16 +54,23 @@ func (this *CountriesAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var countryMaps = []maps.Map{}
|
||||
var deniesCountryMaps = []maps.Map{}
|
||||
var allowedCountryMaps = []maps.Map{}
|
||||
for _, country := range countriesResp.RegionCountries {
|
||||
countryMaps = append(countryMaps, maps.Map{
|
||||
"id": country.Id,
|
||||
"name": country.DisplayName,
|
||||
"letter": strings.ToUpper(string(country.Pinyin[0][0])),
|
||||
"isChecked": lists.ContainsInt64(selectedCountryIds, country.Id),
|
||||
})
|
||||
var countryMap = maps.Map{
|
||||
"id": country.Id,
|
||||
"name": country.DisplayName,
|
||||
"letter": strings.ToUpper(string(country.Pinyin[0][0])),
|
||||
}
|
||||
if lists.ContainsInt64(deniedCountryIds, country.Id) {
|
||||
deniesCountryMaps = append(deniesCountryMaps, countryMap)
|
||||
}
|
||||
if lists.ContainsInt64(allowedCountryIds, country.Id) {
|
||||
allowedCountryMaps = append(allowedCountryMaps, countryMap)
|
||||
}
|
||||
}
|
||||
this.Data["countries"] = countryMaps
|
||||
this.Data["deniedCountries"] = deniesCountryMaps
|
||||
this.Data["allowedCountries"] = allowedCountryMaps
|
||||
|
||||
// except & only URL Patterns
|
||||
this.Data["exceptURLPatterns"] = []*shared.URLPattern{}
|
||||
@@ -88,7 +97,8 @@ func (this *CountriesAction) RunGet(params struct {
|
||||
|
||||
func (this *CountriesAction) RunPost(params struct {
|
||||
FirewallPolicyId int64
|
||||
CountryIds []int64
|
||||
DenyCountryIds []int64
|
||||
AllowCountryIds []int64
|
||||
|
||||
ExceptURLPatternsJSON []byte
|
||||
OnlyURLPatternsJSON []byte
|
||||
@@ -98,6 +108,8 @@ func (this *CountriesAction) RunPost(params struct {
|
||||
// 日志
|
||||
defer this.CreateLogInfo(codes.WAF_LogUpdateForbiddenCountries, params.FirewallPolicyId)
|
||||
|
||||
// TODO validate denied and allowed countries
|
||||
|
||||
policyConfig, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.AdminContext(), params.FirewallPolicyId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -116,7 +128,8 @@ func (this *CountriesAction) RunPost(params struct {
|
||||
IsOn: true,
|
||||
}
|
||||
}
|
||||
policyConfig.Inbound.Region.DenyCountryIds = params.CountryIds
|
||||
policyConfig.Inbound.Region.DenyCountryIds = params.DenyCountryIds
|
||||
policyConfig.Inbound.Region.AllowCountryIds = params.AllowCountryIds
|
||||
|
||||
// 例外URL
|
||||
var exceptURLPatterns = []*shared.URLPattern{}
|
||||
|
||||
@@ -7,14 +7,13 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
const ChinaCountryId = 1
|
||||
|
||||
type ProvincesAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -42,27 +41,36 @@ func (this *ProvincesAction) RunGet(params struct {
|
||||
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
||||
return
|
||||
}
|
||||
var selectedProvinceIds = []int64{}
|
||||
var deniedProvinceIds = []int64{}
|
||||
var allowedProvinceIds = []int64{}
|
||||
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||
selectedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
|
||||
deniedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
|
||||
allowedProvinceIds = policyConfig.Inbound.Region.AllowProvinceIds
|
||||
}
|
||||
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{
|
||||
RegionCountryId: int64(ChinaCountryId),
|
||||
RegionCountryId: regionconfigs.RegionChinaId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var provinceMaps = []maps.Map{}
|
||||
var deniedProvinceMaps = []maps.Map{}
|
||||
var allowedProvinceMaps = []maps.Map{}
|
||||
for _, province := range provincesResp.RegionProvinces {
|
||||
provinceMaps = append(provinceMaps, maps.Map{
|
||||
"id": province.Id,
|
||||
"name": province.DisplayName,
|
||||
"isChecked": lists.ContainsInt64(selectedProvinceIds, province.Id),
|
||||
})
|
||||
var provinceMap = maps.Map{
|
||||
"id": province.Id,
|
||||
"name": province.DisplayName,
|
||||
}
|
||||
if lists.ContainsInt64(deniedProvinceIds, province.Id) {
|
||||
deniedProvinceMaps = append(deniedProvinceMaps, provinceMap)
|
||||
}
|
||||
if lists.ContainsInt64(allowedProvinceIds, province.Id) {
|
||||
allowedProvinceMaps = append(allowedProvinceMaps, provinceMap)
|
||||
}
|
||||
}
|
||||
this.Data["provinces"] = provinceMaps
|
||||
this.Data["deniedProvinces"] = deniedProvinceMaps
|
||||
this.Data["allowedProvinces"] = allowedProvinceMaps
|
||||
|
||||
// except & only URL Patterns
|
||||
this.Data["exceptURLPatterns"] = []*shared.URLPattern{}
|
||||
@@ -89,7 +97,8 @@ func (this *ProvincesAction) RunGet(params struct {
|
||||
|
||||
func (this *ProvincesAction) RunPost(params struct {
|
||||
FirewallPolicyId int64
|
||||
ProvinceIds []int64
|
||||
DenyProvinceIds []int64
|
||||
AllowProvinceIds []int64
|
||||
|
||||
ExceptURLPatternsJSON []byte
|
||||
OnlyURLPatternsJSON []byte
|
||||
@@ -117,7 +126,8 @@ func (this *ProvincesAction) RunPost(params struct {
|
||||
IsOn: true,
|
||||
}
|
||||
}
|
||||
policyConfig.Inbound.Region.DenyProvinceIds = params.ProvinceIds
|
||||
policyConfig.Inbound.Region.DenyProvinceIds = params.DenyProvinceIds
|
||||
policyConfig.Inbound.Region.AllowProvinceIds = params.AllowProvinceIds
|
||||
|
||||
// 例外URL
|
||||
var exceptURLPatterns = []*shared.URLPattern{}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package ipadmin
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SelectCountriesPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SelectCountriesPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *SelectCountriesPopupAction) RunGet(params struct {
|
||||
Type string
|
||||
SelectedCountryIds string
|
||||
}) {
|
||||
this.Data["type"] = params.Type
|
||||
|
||||
var selectedCountryIds = utils.SplitNumbers(params.SelectedCountryIds)
|
||||
|
||||
countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.AdminContext(), &pb.FindAllRegionCountriesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// special regions
|
||||
|
||||
var countryMaps = []maps.Map{}
|
||||
for _, country := range countriesResp.RegionCountries {
|
||||
countryMaps = append(countryMaps, maps.Map{
|
||||
"id": country.Id,
|
||||
"name": country.DisplayName,
|
||||
"letter": strings.ToUpper(string(country.Pinyin[0][0])),
|
||||
"pinyin": country.Pinyin,
|
||||
"codes": country.Codes,
|
||||
"isCommon": country.IsCommon,
|
||||
"isChecked": lists.ContainsInt64(selectedCountryIds, country.Id),
|
||||
})
|
||||
}
|
||||
this.Data["countries"] = countryMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package ipadmin
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type SelectProvincesPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SelectProvincesPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *SelectProvincesPopupAction) RunGet(params struct {
|
||||
Type string
|
||||
SelectedProvinceIds string
|
||||
}) {
|
||||
this.Data["type"] = params.Type
|
||||
|
||||
var selectedProvinceIds = utils.SplitNumbers(params.SelectedProvinceIds)
|
||||
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{
|
||||
RegionCountryId: regionconfigs.RegionChinaId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var provinceMaps = []maps.Map{}
|
||||
for _, province := range provincesResp.RegionProvinces {
|
||||
provinceMaps = append(provinceMaps, maps.Map{
|
||||
"id": province.Id,
|
||||
"name": province.DisplayName,
|
||||
"isChecked": lists.ContainsInt64(selectedProvinceIds, province.Id),
|
||||
})
|
||||
}
|
||||
this.Data["provinces"] = provinceMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -5,6 +5,7 @@ package ui
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
@@ -13,7 +14,7 @@ type ProvinceOptionsAction struct {
|
||||
}
|
||||
|
||||
func (this *ProvinceOptionsAction) RunPost(params struct{}) {
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{RegionCountryId: ChinaCountryId})
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{RegionCountryId: regionconfigs.RegionChinaId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -4,13 +4,12 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
const ChinaCountryId = 1
|
||||
|
||||
type SelectProvincesPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -24,7 +23,7 @@ func (this *SelectProvincesPopupAction) RunGet(params struct {
|
||||
}) {
|
||||
var selectedProvinceIds = utils.SplitNumbers(params.ProvinceIds)
|
||||
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{RegionCountryId: ChinaCountryId})
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{RegionCountryId: regionconfigs.RegionChinaId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
33
web/public/js/components/common/search-box.js
Normal file
33
web/public/js/components/common/search-box.js
Normal file
@@ -0,0 +1,33 @@
|
||||
Vue.component("search-box", {
|
||||
props: ["placeholder", "width"],
|
||||
data: function () {
|
||||
let width = this.width
|
||||
if (width == null) {
|
||||
width = "10em"
|
||||
}
|
||||
return {
|
||||
realWidth: width,
|
||||
realValue: ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onInput: function () {
|
||||
this.$emit("input", { value: this.realValue})
|
||||
this.$emit("change", { value: this.realValue})
|
||||
},
|
||||
clearValue: function () {
|
||||
this.realValue = ""
|
||||
this.focus()
|
||||
this.onInput()
|
||||
},
|
||||
focus: function () {
|
||||
this.$refs.valueRef.focus()
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<div class="ui input small" :class="{'right labeled': realValue.length > 0}">
|
||||
<input type="text" :placeholder="placeholder" :style="{width: realWidth}" @input="onInput" v-model="realValue" ref="valueRef"/>
|
||||
<a href="" class="ui label blue" v-if="realValue.length > 0" @click.prevent="clearValue" style="padding-right: 0"><i class="icon remove"></i></a>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
@@ -0,0 +1,55 @@
|
||||
Vue.component("http-firewall-province-selector", {
|
||||
props: ["v-type", "v-provinces"],
|
||||
data: function () {
|
||||
let provinces = this.vProvinces
|
||||
if (provinces == null) {
|
||||
provinces = []
|
||||
}
|
||||
|
||||
return {
|
||||
listType: this.vType,
|
||||
provinces: provinces
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addProvince: function () {
|
||||
let selectedProvinceIds = this.provinces.map(function (province) {
|
||||
return province.id
|
||||
})
|
||||
let that = this
|
||||
teaweb.popup("/servers/server/settings/waf/ipadmin/selectProvincesPopup?type=" + this.listType + "&selectedProvinceIds=" + selectedProvinceIds.join(","), {
|
||||
width: "50em",
|
||||
height: "26em",
|
||||
callback: function (resp) {
|
||||
that.provinces = resp.data.selectedProvinces
|
||||
that.$forceUpdate()
|
||||
that.notifyChange()
|
||||
}
|
||||
})
|
||||
},
|
||||
removeProvince: function (index) {
|
||||
this.provinces.$remove(index)
|
||||
this.notifyChange()
|
||||
},
|
||||
resetProvinces: function () {
|
||||
this.provinces = []
|
||||
this.notifyChange()
|
||||
},
|
||||
notifyChange: function () {
|
||||
this.$emit("change", {
|
||||
"provinces": this.provinces
|
||||
})
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<span v-if="provinces.length == 0" class="disabled">暂时没有选择<span v-if="listType =='allow'">允许</span><span v-else>封禁</span>的省份。</span>
|
||||
<div v-show="provinces.length > 0">
|
||||
<div class="ui label tiny basic" v-for="(province, index) in provinces" style="margin-bottom: 0.5em">
|
||||
<input type="hidden" :name="listType + 'ProvinceIds'" :value="province.id"/>
|
||||
{{province.name}} <a href="" @click.prevent="removeProvince(index)" title="删除"><i class="icon remove"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<button type="button" class="ui button tiny" @click.prevent="addProvince">修改</button> <button type="button" class="ui button tiny" v-show="provinces.length > 0" @click.prevent="resetProvinces">清空</button>
|
||||
</div>`
|
||||
})
|
||||
@@ -0,0 +1,55 @@
|
||||
Vue.component("http-firewall-region-selector", {
|
||||
props: ["v-type", "v-countries"],
|
||||
data: function () {
|
||||
let countries = this.vCountries
|
||||
if (countries == null) {
|
||||
countries = []
|
||||
}
|
||||
|
||||
return {
|
||||
listType: this.vType,
|
||||
countries: countries
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addCountry: function () {
|
||||
let selectedCountryIds = this.countries.map(function (country) {
|
||||
return country.id
|
||||
})
|
||||
let that = this
|
||||
teaweb.popup("/servers/server/settings/waf/ipadmin/selectCountriesPopup?type=" + this.listType + "&selectedCountryIds=" + selectedCountryIds.join(","), {
|
||||
width: "52em",
|
||||
height: "30em",
|
||||
callback: function (resp) {
|
||||
that.countries = resp.data.selectedCountries
|
||||
that.$forceUpdate()
|
||||
that.notifyChange()
|
||||
}
|
||||
})
|
||||
},
|
||||
removeCountry: function (index) {
|
||||
this.countries.$remove(index)
|
||||
this.notifyChange()
|
||||
},
|
||||
resetCountries: function () {
|
||||
this.countries = []
|
||||
this.notifyChange()
|
||||
},
|
||||
notifyChange: function () {
|
||||
this.$emit("change", {
|
||||
"countries": this.countries
|
||||
})
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<span v-if="countries.length == 0" class="disabled">暂时没有选择<span v-if="listType =='allow'">允许</span><span v-else>封禁</span>的区域。</span>
|
||||
<div v-show="countries.length > 0">
|
||||
<div class="ui label tiny basic" v-for="(country, index) in countries" style="margin-bottom: 0.5em">
|
||||
<input type="hidden" :name="listType + 'CountryIds'" :value="country.id"/>
|
||||
({{country.letter}}){{country.name}} <a href="" @click.prevent="removeCountry(index)" title="删除"><i class="icon remove"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<button type="button" class="ui button tiny" @click.prevent="addCountry">修改</button> <button type="button" class="ui button tiny" v-show="countries.length > 0" @click.prevent="resetCountries">清空</button>
|
||||
</div>`
|
||||
})
|
||||
@@ -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 */
|
||||
@@ -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"}
|
||||
@@ -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 <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 <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 <tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
|
||||
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>限制URL <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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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"}
|
||||
@@ -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 <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 <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 <tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
|
||||
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>限制URL <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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
@@ -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 */
|
||||
@@ -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"}
|
||||
@@ -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"> ({{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>
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
@@ -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;
|
||||
}
|
||||
@@ -7,4 +7,4 @@
|
||||
font-size: 12px !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
/*# sourceMappingURL=provinces.css.map */
|
||||
/*# sourceMappingURL=selectProvincesPopup.css.map */
|
||||
@@ -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"}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user