mirror of
				https://github.com/TeaOSLab/EdgeAPI.git
				synced 2025-11-04 16:00:24 +08:00 
			
		
		
		
	增加国家/地区封禁管理
This commit is contained in:
		
							
								
								
									
										3461
									
								
								build/resources/ipdata/ip2region/global_region.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3461
									
								
								build/resources/ipdata/ip2region/global_region.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										113
									
								
								cmd/ip2region/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								cmd/ip2region/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
 | 
						_ "github.com/iwind/TeaGo/bootstrap"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/dbs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/lists"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						// 导入数据
 | 
				
			||||||
 | 
						if lists.ContainsString(os.Args, "import") {
 | 
				
			||||||
 | 
							dbs.NotifyReady()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data, err := ioutil.ReadFile(Tea.Root + "/resources/ipdata/ip2region/global_region.csv")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(data) == 0 {
 | 
				
			||||||
 | 
								logs.Println("[ERROR]file content should not be empty")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							lines := bytes.Split(data, []byte{'\n'})
 | 
				
			||||||
 | 
							for _, line := range lines {
 | 
				
			||||||
 | 
								line = bytes.TrimSpace(line)
 | 
				
			||||||
 | 
								if len(line) == 0 {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								s := string(line)
 | 
				
			||||||
 | 
								reg := regexp.MustCompile(`(?U)(\d+),(\d+),(.+),(\d+),`)
 | 
				
			||||||
 | 
								if !reg.MatchString(s) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								result := reg.FindStringSubmatch(s)
 | 
				
			||||||
 | 
								dataId := result[1]
 | 
				
			||||||
 | 
								parentDataId := result[2]
 | 
				
			||||||
 | 
								name := result[3]
 | 
				
			||||||
 | 
								level := result[4]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								switch level {
 | 
				
			||||||
 | 
								case "1": // 国家|地区
 | 
				
			||||||
 | 
									countryId, err := models.SharedRegionCountryDAO.FindCountryIdWithDataId(dataId)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if countryId == 0 {
 | 
				
			||||||
 | 
										logs.Println("creating country or region ", name)
 | 
				
			||||||
 | 
										_, err = models.SharedRegionCountryDAO.CreateCountry(name, dataId)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case "2": // 省份|地区
 | 
				
			||||||
 | 
									provinceId, err := models.SharedRegionProvinceDAO.FindProvinceIdWithDataId(dataId)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if provinceId == 0 {
 | 
				
			||||||
 | 
										logs.Println("creating province", name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										countryId, err := models.SharedRegionCountryDAO.FindCountryIdWithDataId(parentDataId)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if countryId == 0 {
 | 
				
			||||||
 | 
											logs.Println("[ERROR]can not find country from data id '" + parentDataId + "'")
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										_, err = models.SharedRegionProvinceDAO.CreateProvince(countryId, name, dataId)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case "3": // 城市
 | 
				
			||||||
 | 
									cityId, err := models.SharedRegionCityDAO.FindCityWithDataId(dataId)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if cityId == 0 {
 | 
				
			||||||
 | 
										logs.Println("creating city", name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										provinceId, err := models.SharedRegionProvinceDAO.FindProvinceIdWithDataId(parentDataId)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_, err = models.SharedRegionCityDAO.CreateCity(provinceId, name, dataId)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											logs.Println("[ERROR]" + err.Error())
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							logs.Println("done")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -11,6 +11,8 @@ require (
 | 
				
			|||||||
	github.com/golang/protobuf v1.4.2
 | 
						github.com/golang/protobuf v1.4.2
 | 
				
			||||||
	github.com/iwind/TeaGo v0.0.0-20201020081413-7cf62d6f420f
 | 
						github.com/iwind/TeaGo v0.0.0-20201020081413-7cf62d6f420f
 | 
				
			||||||
	github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
 | 
						github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
 | 
				
			||||||
 | 
						github.com/mattn/go-isatty v0.0.12 // indirect
 | 
				
			||||||
 | 
						github.com/mozillazg/go-pinyin v0.18.0
 | 
				
			||||||
	github.com/pkg/sftp v1.12.0
 | 
						github.com/pkg/sftp v1.12.0
 | 
				
			||||||
	golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 | 
						golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 | 
				
			||||||
	google.golang.org/grpc v1.32.0
 | 
						google.golang.org/grpc v1.32.0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								go.sum
									
									
									
									
									
								
							@@ -64,6 +64,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
				
			|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
					github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
				
			||||||
github.com/lionsoul2014/ip2region v2.2.0-release+incompatible h1:1qp9iks+69h7IGLazAplzS9Ca14HAxuD5c0rbFdPGy4=
 | 
					github.com/lionsoul2014/ip2region v2.2.0-release+incompatible h1:1qp9iks+69h7IGLazAplzS9Ca14HAxuD5c0rbFdPGy4=
 | 
				
			||||||
github.com/lionsoul2014/ip2region v2.2.0-release+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI=
 | 
					github.com/lionsoul2014/ip2region v2.2.0-release+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 | 
					github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 | 
				
			||||||
@@ -72,6 +74,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD
 | 
				
			|||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
					github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
				
			||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 | 
					github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 | 
				
			||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
					github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
				
			||||||
 | 
					github.com/mozillazg/go-pinyin v0.18.0 h1:hQompXO23/0ohH8YNjvfsAITnCQImCiR/Fny8EhIeW0=
 | 
				
			||||||
 | 
					github.com/mozillazg/go-pinyin v0.18.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
 | 
				
			||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
					github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
				
			||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
					github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
				
			||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 | 
					github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 | 
				
			||||||
@@ -140,6 +144,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
 | 
				
			|||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
 | 
					golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -136,6 +136,22 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInboundAndOutbound(policy
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 修改策略的Inbound
 | 
				
			||||||
 | 
					func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInbound(policyId int64, inboundJSON []byte) error {
 | 
				
			||||||
 | 
						if policyId <= 0 {
 | 
				
			||||||
 | 
							return errors.New("invalid policyId")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						op := NewHTTPFirewallPolicyOperator()
 | 
				
			||||||
 | 
						op.Id = policyId
 | 
				
			||||||
 | 
						if len(inboundJSON) > 0 {
 | 
				
			||||||
 | 
							op.Inbound = inboundJSON
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							op.Inbound = "null"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err := this.Save(op)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 修改策略
 | 
					// 修改策略
 | 
				
			||||||
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(policyId int64, isOn bool, name string, description string, inboundJSON []byte, outboundJSON []byte) error {
 | 
					func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(policyId int64, isOn bool, name string, description string, inboundJSON []byte, outboundJSON []byte) error {
 | 
				
			||||||
	if policyId <= 0 {
 | 
						if policyId <= 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,11 @@
 | 
				
			|||||||
package models
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	_ "github.com/go-sql-driver/mysql"
 | 
						_ "github.com/go-sql-driver/mysql"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
						"github.com/iwind/TeaGo/dbs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -69,3 +71,32 @@ func (this *RegionCityDAO) FindRegionCityName(id uint32) (string, error) {
 | 
				
			|||||||
		Result("name").
 | 
							Result("name").
 | 
				
			||||||
		FindStringCol("")
 | 
							FindStringCol("")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 根据数据ID查找城市
 | 
				
			||||||
 | 
					func (this *RegionCityDAO) FindCityWithDataId(dataId string) (int64, error) {
 | 
				
			||||||
 | 
						return this.Query().
 | 
				
			||||||
 | 
							Attr("dataId", dataId).
 | 
				
			||||||
 | 
							ResultPk().
 | 
				
			||||||
 | 
							FindInt64Col(0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 创建城市
 | 
				
			||||||
 | 
					func (this *RegionCityDAO) CreateCity(provinceId int64, name string, dataId string) (int64, error) {
 | 
				
			||||||
 | 
						op := NewRegionCityOperator()
 | 
				
			||||||
 | 
						op.ProvinceId = provinceId
 | 
				
			||||||
 | 
						op.Name = name
 | 
				
			||||||
 | 
						op.DataId = dataId
 | 
				
			||||||
 | 
						op.State = RegionCityStateEnabled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codes := []string{name}
 | 
				
			||||||
 | 
						codesJSON, err := json.Marshal(codes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						op.Codes = codesJSON
 | 
				
			||||||
 | 
						_, err = this.Save(op)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return types.Int64(op.Id), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ type RegionCity struct {
 | 
				
			|||||||
	Name       string `field:"name"`       // 名称
 | 
						Name       string `field:"name"`       // 名称
 | 
				
			||||||
	Codes      string `field:"codes"`      // 代号
 | 
						Codes      string `field:"codes"`      // 代号
 | 
				
			||||||
	State      uint8  `field:"state"`      // 状态
 | 
						State      uint8  `field:"state"`      // 状态
 | 
				
			||||||
 | 
						DataId     string `field:"dataId"`     // 原始数据ID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RegionCityOperator struct {
 | 
					type RegionCityOperator struct {
 | 
				
			||||||
@@ -15,6 +16,7 @@ type RegionCityOperator struct {
 | 
				
			|||||||
	Name       interface{} // 名称
 | 
						Name       interface{} // 名称
 | 
				
			||||||
	Codes      interface{} // 代号
 | 
						Codes      interface{} // 代号
 | 
				
			||||||
	State      interface{} // 状态
 | 
						State      interface{} // 状态
 | 
				
			||||||
 | 
						DataId     interface{} // 原始数据ID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewRegionCityOperator() *RegionCityOperator {
 | 
					func NewRegionCityOperator() *RegionCityOperator {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,13 @@
 | 
				
			|||||||
package models
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	_ "github.com/go-sql-driver/mysql"
 | 
						_ "github.com/go-sql-driver/mysql"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
						"github.com/iwind/TeaGo/dbs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
 | 
						"github.com/mozillazg/go-pinyin"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -42,7 +46,7 @@ func (this *RegionCountryDAO) EnableRegionCountry(id uint32) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 禁用条目
 | 
					// 禁用条目
 | 
				
			||||||
func (this *RegionCountryDAO) DisableRegionCountry(id uint32) error {
 | 
					func (this *RegionCountryDAO) DisableRegionCountry(id int64) error {
 | 
				
			||||||
	_, err := this.Query().
 | 
						_, err := this.Query().
 | 
				
			||||||
		Pk(id).
 | 
							Pk(id).
 | 
				
			||||||
		Set("state", RegionCountryStateDisabled).
 | 
							Set("state", RegionCountryStateDisabled).
 | 
				
			||||||
@@ -51,7 +55,7 @@ func (this *RegionCountryDAO) DisableRegionCountry(id uint32) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 查找启用中的条目
 | 
					// 查找启用中的条目
 | 
				
			||||||
func (this *RegionCountryDAO) FindEnabledRegionCountry(id uint32) (*RegionCountry, error) {
 | 
					func (this *RegionCountryDAO) FindEnabledRegionCountry(id int64) (*RegionCountry, error) {
 | 
				
			||||||
	result, err := this.Query().
 | 
						result, err := this.Query().
 | 
				
			||||||
		Pk(id).
 | 
							Pk(id).
 | 
				
			||||||
		Attr("state", RegionCountryStateEnabled).
 | 
							Attr("state", RegionCountryStateEnabled).
 | 
				
			||||||
@@ -63,9 +67,56 @@ func (this *RegionCountryDAO) FindEnabledRegionCountry(id uint32) (*RegionCountr
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据主键查找名称
 | 
					// 根据主键查找名称
 | 
				
			||||||
func (this *RegionCountryDAO) FindRegionCountryName(id uint32) (string, error) {
 | 
					func (this *RegionCountryDAO) FindRegionCountryName(id int64) (string, error) {
 | 
				
			||||||
	return this.Query().
 | 
						return this.Query().
 | 
				
			||||||
		Pk(id).
 | 
							Pk(id).
 | 
				
			||||||
		Result("name").
 | 
							Result("name").
 | 
				
			||||||
		FindStringCol("")
 | 
							FindStringCol("")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 根据数据ID查找国家
 | 
				
			||||||
 | 
					func (this *RegionCountryDAO) FindCountryIdWithDataId(dataId string) (int64, error) {
 | 
				
			||||||
 | 
						return this.Query().
 | 
				
			||||||
 | 
							Attr("dataId", dataId).
 | 
				
			||||||
 | 
							ResultPk().
 | 
				
			||||||
 | 
							FindInt64Col(0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 根据数据ID创建国家
 | 
				
			||||||
 | 
					func (this *RegionCountryDAO) CreateCountry(name string, dataId string) (int64, error) {
 | 
				
			||||||
 | 
						op := NewRegionCountryOperator()
 | 
				
			||||||
 | 
						op.Name = name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pinyinPieces := pinyin.Pinyin(name, pinyin.NewArgs())
 | 
				
			||||||
 | 
						pinyinResult := []string{}
 | 
				
			||||||
 | 
						for _, piece := range pinyinPieces {
 | 
				
			||||||
 | 
							pinyinResult = append(pinyinResult, strings.Join(piece, " "))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pinyinJSON, err := json.Marshal([]string{strings.Join(pinyinResult, " ")})
 | 
				
			||||||
 | 
						op.Pinyin = pinyinJSON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codes := []string{name}
 | 
				
			||||||
 | 
						codesJSON, err := json.Marshal(codes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						op.Codes = codesJSON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						op.DataId = dataId
 | 
				
			||||||
 | 
						op.State = RegionCountryStateEnabled
 | 
				
			||||||
 | 
						_, err = this.Save(op)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return types.Int64(op.Id), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查找所有可用的国家
 | 
				
			||||||
 | 
					func (this *RegionCountryDAO) FindAllEnabledCountriesOrderByPinyin() (result []*RegionCountry, err error) {
 | 
				
			||||||
 | 
						_, err = this.Query().
 | 
				
			||||||
 | 
							State(RegionCountryStateEnabled).
 | 
				
			||||||
 | 
							Slice(&result).
 | 
				
			||||||
 | 
							Asc("pinyin").
 | 
				
			||||||
 | 
							FindAll()
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,8 @@ type RegionCountry struct {
 | 
				
			|||||||
	Name   string `field:"name"`   // 名称
 | 
						Name   string `field:"name"`   // 名称
 | 
				
			||||||
	Codes  string `field:"codes"`  // 代号
 | 
						Codes  string `field:"codes"`  // 代号
 | 
				
			||||||
	State  uint8  `field:"state"`  // 状态
 | 
						State  uint8  `field:"state"`  // 状态
 | 
				
			||||||
 | 
						DataId string `field:"dataId"` // 原始数据ID
 | 
				
			||||||
 | 
						Pinyin string `field:"pinyin"` // 拼音
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RegionCountryOperator struct {
 | 
					type RegionCountryOperator struct {
 | 
				
			||||||
@@ -13,6 +15,8 @@ type RegionCountryOperator struct {
 | 
				
			|||||||
	Name   interface{} // 名称
 | 
						Name   interface{} // 名称
 | 
				
			||||||
	Codes  interface{} // 代号
 | 
						Codes  interface{} // 代号
 | 
				
			||||||
	State  interface{} // 状态
 | 
						State  interface{} // 状态
 | 
				
			||||||
 | 
						DataId interface{} // 原始数据ID
 | 
				
			||||||
 | 
						Pinyin interface{} // 拼音
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewRegionCountryOperator() *RegionCountryOperator {
 | 
					func NewRegionCountryOperator() *RegionCountryOperator {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,11 @@
 | 
				
			|||||||
package models
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	_ "github.com/go-sql-driver/mysql"
 | 
						_ "github.com/go-sql-driver/mysql"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
						"github.com/iwind/TeaGo/dbs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -69,3 +71,43 @@ func (this *RegionProvinceDAO) FindRegionProvinceName(id uint32) (string, error)
 | 
				
			|||||||
		Result("name").
 | 
							Result("name").
 | 
				
			||||||
		FindStringCol("")
 | 
							FindStringCol("")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 根据数据ID查找省份
 | 
				
			||||||
 | 
					func (this *RegionProvinceDAO) FindProvinceIdWithDataId(dataId string) (int64, error) {
 | 
				
			||||||
 | 
						return this.Query().
 | 
				
			||||||
 | 
							Attr("dataId", dataId).
 | 
				
			||||||
 | 
							ResultPk().
 | 
				
			||||||
 | 
							FindInt64Col(0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 创建省份
 | 
				
			||||||
 | 
					func (this *RegionProvinceDAO) CreateProvince(countryId int64, name string, dataId string) (int64, error) {
 | 
				
			||||||
 | 
						op := NewRegionProvinceOperator()
 | 
				
			||||||
 | 
						op.CountryId = countryId
 | 
				
			||||||
 | 
						op.Name = name
 | 
				
			||||||
 | 
						op.DataId = dataId
 | 
				
			||||||
 | 
						op.State = RegionProvinceStateEnabled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codes := []string{name}
 | 
				
			||||||
 | 
						codesJSON, err := json.Marshal(codes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						op.Codes = codesJSON
 | 
				
			||||||
 | 
						_, err = this.Save(op)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return types.Int64(op.Id), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查找所有省份
 | 
				
			||||||
 | 
					func (this *RegionProvinceDAO) FindAllEnabledProvincesWithCountryId(countryId int64) (result []*RegionProvince, err error) {
 | 
				
			||||||
 | 
						_, err = this.Query().
 | 
				
			||||||
 | 
							State(RegionProvinceStateEnabled).
 | 
				
			||||||
 | 
							Attr("countryId", countryId).
 | 
				
			||||||
 | 
							Asc("name").
 | 
				
			||||||
 | 
							Slice(&result).
 | 
				
			||||||
 | 
							FindAll()
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ type RegionProvince struct {
 | 
				
			|||||||
	Name      string `field:"name"`      // 名称
 | 
						Name      string `field:"name"`      // 名称
 | 
				
			||||||
	Codes     string `field:"codes"`     // 代号
 | 
						Codes     string `field:"codes"`     // 代号
 | 
				
			||||||
	State     uint8  `field:"state"`     // 状态
 | 
						State     uint8  `field:"state"`     // 状态
 | 
				
			||||||
 | 
						DataId    string `field:"dataId"`    // 原始数据ID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RegionProvinceOperator struct {
 | 
					type RegionProvinceOperator struct {
 | 
				
			||||||
@@ -15,6 +16,7 @@ type RegionProvinceOperator struct {
 | 
				
			|||||||
	Name      interface{} // 名称
 | 
						Name      interface{} // 名称
 | 
				
			||||||
	Codes     interface{} // 代号
 | 
						Codes     interface{} // 代号
 | 
				
			||||||
	State     interface{} // 状态
 | 
						State     interface{} // 状态
 | 
				
			||||||
 | 
						DataId    interface{} // 原始数据ID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewRegionProvinceOperator() *RegionProvinceOperator {
 | 
					func NewRegionProvinceOperator() *RegionProvinceOperator {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -176,6 +176,8 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
 | 
				
			|||||||
	pb.RegisterIPLibraryServiceServer(rpcServer, &services.IPLibraryService{})
 | 
						pb.RegisterIPLibraryServiceServer(rpcServer, &services.IPLibraryService{})
 | 
				
			||||||
	pb.RegisterFileChunkServiceServer(rpcServer, &services.FileChunkService{})
 | 
						pb.RegisterFileChunkServiceServer(rpcServer, &services.FileChunkService{})
 | 
				
			||||||
	pb.RegisterFileServiceServer(rpcServer, &services.FileService{})
 | 
						pb.RegisterFileServiceServer(rpcServer, &services.FileService{})
 | 
				
			||||||
 | 
						pb.RegisterRegionCountryServiceServer(rpcServer, &services.RegionCountryService{})
 | 
				
			||||||
 | 
						pb.RegisterRegionProvinceServiceServer(rpcServer, &services.RegionProvinceService{})
 | 
				
			||||||
	err := rpcServer.Serve(listener)
 | 
						err := rpcServer.Serve(listener)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.New("[API]start rpc failed: " + err.Error())
 | 
							return errors.New("[API]start rpc failed: " + err.Error())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -251,6 +251,22 @@ func (this *HTTPFirewallPolicyService) UpdateHTTPFirewallPolicyGroups(ctx contex
 | 
				
			|||||||
	return rpcutils.RPCUpdateSuccess()
 | 
						return rpcutils.RPCUpdateSuccess()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 修改inbound信息
 | 
				
			||||||
 | 
					func (this *HTTPFirewallPolicyService) UpdateHTTPFirewallInboundConfig(ctx context.Context, req *pb.UpdateHTTPFirewallInboundConfigRequest) (*pb.RPCUpdateSuccess, error) {
 | 
				
			||||||
 | 
						// 校验请求
 | 
				
			||||||
 | 
						_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = models.SharedHTTPFirewallPolicyDAO.UpdateFirewallPolicyInbound(req.FirewallPolicyId, req.InboundJSON)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rpcutils.RPCUpdateSuccess()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 计算可用的防火墙策略数量
 | 
					// 计算可用的防火墙策略数量
 | 
				
			||||||
func (this *HTTPFirewallPolicyService) CountAllEnabledFirewallPolicies(ctx context.Context, req *pb.CountAllEnabledFirewallPoliciesRequest) (*pb.CountAllEnabledFirewallPoliciesResponse, error) {
 | 
					func (this *HTTPFirewallPolicyService) CountAllEnabledFirewallPolicies(ctx context.Context, req *pb.CountAllEnabledFirewallPoliciesRequest) (*pb.CountAllEnabledFirewallPoliciesResponse, error) {
 | 
				
			||||||
	// 校验请求
 | 
						// 校验请求
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								internal/rpc/services/service_region_country.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								internal/rpc/services/service_region_country.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					package services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
				
			||||||
 | 
						rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 国家相关服务
 | 
				
			||||||
 | 
					type RegionCountryService struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查找所有的国家列表
 | 
				
			||||||
 | 
					func (this *RegionCountryService) FindAllEnabledRegionCountries(ctx context.Context, req *pb.FindAllEnabledRegionCountriesRequest) (*pb.FindAllEnabledRegionCountriesResponse, error) {
 | 
				
			||||||
 | 
						// 校验请求
 | 
				
			||||||
 | 
						_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						countries, err := models.SharedRegionCountryDAO.FindAllEnabledCountriesOrderByPinyin()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result := []*pb.RegionCountry{}
 | 
				
			||||||
 | 
						for _, country := range countries {
 | 
				
			||||||
 | 
							pinyinStrings := []string{}
 | 
				
			||||||
 | 
							err = json.Unmarshal([]byte(country.Pinyin), &pinyinStrings)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(pinyinStrings) == 0 {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result = append(result, &pb.RegionCountry{
 | 
				
			||||||
 | 
								Id:     int64(country.Id),
 | 
				
			||||||
 | 
								Name:   country.Name,
 | 
				
			||||||
 | 
								Pinyin: pinyinStrings,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &pb.FindAllEnabledRegionCountriesResponse{
 | 
				
			||||||
 | 
							Countries: result,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								internal/rpc/services/service_region_province.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								internal/rpc/services/service_region_province.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					package services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
				
			||||||
 | 
						rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 省份相关服务
 | 
				
			||||||
 | 
					type RegionProvinceService struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查找所有省份
 | 
				
			||||||
 | 
					func (this *RegionProvinceService) FindAllEnabledRegionProvincesWithCountryId(ctx context.Context, req *pb.FindAllEnabledRegionProvincesWithCountryIdRequest) (*pb.FindAllEnabledRegionProvincesWithCountryIdResponse, error) {
 | 
				
			||||||
 | 
						// 校验请求
 | 
				
			||||||
 | 
						_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						provinces, err := models.SharedRegionProvinceDAO.FindAllEnabledProvincesWithCountryId(req.CountryId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result := []*pb.RegionProvince{}
 | 
				
			||||||
 | 
						for _, province := range provinces {
 | 
				
			||||||
 | 
							result = append(result, &pb.RegionProvince{
 | 
				
			||||||
 | 
								Id:   int64(province.Id),
 | 
				
			||||||
 | 
								Name: province.Name,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &pb.FindAllEnabledRegionProvincesWithCountryIdResponse{
 | 
				
			||||||
 | 
							Provinces: result,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user