Vue.component("ns-route-ranges-box", { props: ["v-ranges"], data: function () { let ranges = this.vRanges if (ranges == null) { ranges = [] } return { ranges: ranges, isAdding: false, isAddingBatch: false, // 类型 rangeType: "ipRange", isReverse: false, // IP范围 ipRangeFrom: "", ipRangeTo: "", batchIPRange: "", // CIDR ipCIDR: "", batchIPCIDR: "", // region regions: [], regionType: "country" } }, methods: { addIPRange: function () { this.isAdding = true let that = this setTimeout(function () { that.$refs.ipRangeFrom.focus() }, 100) }, addCIDR: function () { this.isAdding = true let that = this setTimeout(function () { that.$refs.ipCIDR.focus() }, 100) }, addRegions: function () { this.isAdding = true }, addRegion: function (regionType) { this.regionType = regionType }, remove: function (index) { this.ranges.$remove(index) }, cancelIPRange: function () { this.isAdding = false this.ipRangeFrom = "" this.ipRangeTo = "" this.isReverse = false }, cancelIPCIDR: function () { this.isAdding = false this.ipCIDR = "" this.isReverse = false }, cancelRegions: function () { this.isAdding = false this.regions = [] this.regionType = "country" this.isReverse = false }, confirmIPRange: function () { // 校验IP let that = this this.ipRangeFrom = this.ipRangeFrom.trim() if (!this.validateIP(this.ipRangeFrom)) { teaweb.warn("开始IP填写错误", function () { that.$refs.ipRangeFrom.focus() }) return } this.ipRangeTo = this.ipRangeTo.trim() if (!this.validateIP(this.ipRangeTo)) { teaweb.warn("结束IP填写错误", function () { that.$refs.ipRangeTo.focus() }) return } this.ranges.push({ type: "ipRange", params: { ipFrom: this.ipRangeFrom, ipTo: this.ipRangeTo, isReverse: this.isReverse } }) this.cancelIPRange() }, confirmIPCIDR: function () { let that = this if (this.ipCIDR.length == 0) { teaweb.warn("请填写CIDR", function () { that.$refs.ipCIDR.focus() }) return } if (!this.validateCIDR(this.ipCIDR)) { teaweb.warn("请输入正确的CIDR", function () { that.$refs.ipCIDR.focus() }) return } this.ranges.push({ type: "cidr", params: { cidr: this.ipCIDR, isReverse: this.isReverse } }) this.cancelIPCIDR() }, confirmRegions: function () { if (this.regions.length == 0) { this.cancelRegions() return } this.ranges.push({ type: "region", params: { regions: this.regions, isReverse: this.isReverse } }) this.cancelRegions() }, addBatchIPRange: function () { this.isAddingBatch = true let that = this setTimeout(function () { that.$refs.batchIPRange.focus() }, 100) }, addBatchCIDR: function () { this.isAddingBatch = true let that = this setTimeout(function () { that.$refs.batchIPCIDR.focus() }, 100) }, cancelBatchIPRange: function () { this.isAddingBatch = false this.batchIPRange = "" this.isReverse = false }, cancelBatchIPCIDR: function () { this.isAddingBatch = false this.batchIPCIDR = "" this.isReverse = false }, confirmBatchIPRange: function () { let that = this let rangesText = this.batchIPRange if (rangesText.length == 0) { teaweb.warn("请填写要加入的IP范围", function () { that.$refs.batchIPRange.focus() }) return } let validRanges = [] let invalidLine = "" rangesText.split("\n").forEach(function (line) { line = line.trim() if (line.length == 0) { return } line = line.replace(",", ",") let pieces = line.split(",") if (pieces.length != 2) { invalidLine = line return } let ipFrom = pieces[0].trim() let ipTo = pieces[1].trim() if (!that.validateIP(ipFrom) || !that.validateIP(ipTo)) { invalidLine = line return } validRanges.push({ type: "ipRange", params: { ipFrom: ipFrom, ipTo: ipTo, isReverse: that.isReverse } }) }) if (invalidLine.length > 0) { teaweb.warn("'" + invalidLine + "'格式错误", function () { that.$refs.batchIPRange.focus() }) return } validRanges.forEach(function (v) { that.ranges.push(v) }) this.cancelBatchIPRange() }, confirmBatchIPCIDR: function () { let that = this let rangesText = this.batchIPCIDR if (rangesText.length == 0) { teaweb.warn("请填写要加入的CIDR", function () { that.$refs.batchIPCIDR.focus() }) return } let validRanges = [] let invalidLine = "" rangesText.split("\n").forEach(function (line) { let cidr = line.trim() if (cidr.length == 0) { return } if (!that.validateCIDR(cidr)) { invalidLine = line return } validRanges.push({ type: "cidr", params: { cidr: cidr, isReverse: that.isReverse } }) }) if (invalidLine.length > 0) { teaweb.warn("'" + invalidLine + "'格式错误", function () { that.$refs.batchIPCIDR.focus() }) return } validRanges.forEach(function (v) { that.ranges.push(v) }) this.cancelBatchIPCIDR() }, selectRegionCountry: function (country) { if (country == null) { return } this.regions.push({ type: "country", id: country.id, name: country.name }) this.$refs.regionCountryComboBox.clear() }, selectRegionProvince: function (province) { if (province == null) { return } this.regions.push({ type: "province", id: province.id, name: province.name }) this.$refs.regionProvinceComboBox.clear() }, selectRegionCity: function (city) { if (city == null) { return } this.regions.push({ type: "city", id: city.id, name: city.name }) this.$refs.regionCityComboBox.clear() }, selectRegionProvider: function (provider) { if (provider == null) { return } this.regions.push({ type: "provider", id: provider.id, name: provider.name }) this.$refs.regionProviderComboBox.clear() }, removeRegion: function (index) { this.regions.$remove(index) }, validateIP: function (ip) { if (ip.length == 0) { return } // IPv6 if (ip.indexOf(":") >= 0) { let pieces = ip.split(":") if (pieces.length > 8) { return false } let isOk = true pieces.forEach(function (piece) { if (!/^[\da-fA-F]{0,4}$/.test(piece)) { isOk = false } }) return isOk } if (!ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)) { return false } let pieces = ip.split(".") let isOk = true pieces.forEach(function (v) { let v1 = parseInt(v) if (v1 > 255) { isOk = false } }) return isOk }, validateCIDR: function (cidr) { let pieces = cidr.split("/") if (pieces.length != 2) { return false } let ip = pieces[0] if (!this.validateIP(ip)) { return false } let mask = pieces[1] if (!/^\d{1,3}$/.test(mask)) { return false } mask = parseInt(mask, 10) if (cidr.indexOf(":") >= 0) { // IPv6 return mask <= 128 } return mask <= 32 }, updateRangeType: function (rangeType) { this.rangeType = rangeType } }, template: `