重构提取逻辑,新增 area 表
This commit is contained in:
@@ -40,12 +40,21 @@ type channelServer struct {
|
||||
}
|
||||
|
||||
func (s *channelServer) CreateChannels(source netip.Addr, resourceNo string, authWhitelist bool, authPassword bool, count int, edgeFilter *EdgeFilter) ([]*m.Channel, error) {
|
||||
var area *m.Area
|
||||
if edgeFilter.AreaID != nil {
|
||||
var err error
|
||||
area, err = Area.Get(*edgeFilter.AreaID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateChannelArea(area); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
batchNo := ID.GenReadable("bat")
|
||||
var channels []*m.Channel
|
||||
if edgeFilter == nil {
|
||||
edgeFilter = &EdgeFilter{}
|
||||
}
|
||||
|
||||
var whitelistText *string
|
||||
err := g.Redsync.WithLock(lockChannelCreateKey(resourceNo), func() error {
|
||||
@@ -80,6 +89,7 @@ func (s *channelServer) CreateChannels(source netip.Addr, resourceNo string, aut
|
||||
Expire: expire,
|
||||
Count: count,
|
||||
Filter: edgeFilter,
|
||||
Area: area,
|
||||
AuthWhitelist: authWhitelist,
|
||||
AuthPassword: authPassword,
|
||||
Whitelists: whitelists,
|
||||
@@ -160,6 +170,7 @@ type channelCreateContext struct {
|
||||
Expire time.Time
|
||||
Count int
|
||||
Filter *EdgeFilter
|
||||
Area *m.Area
|
||||
AuthWhitelist bool
|
||||
AuthPassword bool
|
||||
Whitelists []string
|
||||
@@ -172,6 +183,7 @@ type channelCreateResult struct {
|
||||
}
|
||||
|
||||
func newBaseChannel(ctx *channelCreateContext, port uint16) *m.Channel {
|
||||
prov, city := areaProvinceCity(ctx.Area)
|
||||
return &m.Channel{
|
||||
UserID: ctx.Resource.User.ID,
|
||||
ResourceID: ctx.Resource.ID,
|
||||
@@ -180,8 +192,8 @@ func newBaseChannel(ctx *channelCreateContext, port uint16) *m.Channel {
|
||||
Host: u.Else(ctx.Proxy.Host, ctx.Proxy.IP.String()),
|
||||
Port: port,
|
||||
FilterISP: ctx.Filter.Isp,
|
||||
FilterProv: ctx.Filter.Prov,
|
||||
FilterCity: ctx.Filter.City,
|
||||
FilterProv: prov,
|
||||
FilterCity: city,
|
||||
ExpiredAt: ctx.Expire,
|
||||
Proxy: ctx.Proxy,
|
||||
}
|
||||
@@ -202,6 +214,7 @@ func applyChannelAuth(ctx *channelCreateContext, channel *m.Channel) (username s
|
||||
}
|
||||
|
||||
func persistChannelCreate(ctx *channelCreateContext, channels []*m.Channel) error {
|
||||
prov, city := areaProvinceCity(ctx.Area)
|
||||
return q.Q.Transaction(func(tx *q.Query) error {
|
||||
var (
|
||||
result gen.ResultInfo
|
||||
@@ -252,8 +265,8 @@ func persistChannelCreate(ctx *channelCreateContext, channels []*m.Channel) erro
|
||||
BatchNo: ctx.BatchNo,
|
||||
Count: int32(ctx.Count),
|
||||
ISP: u.X(ctx.Filter.Isp.String()),
|
||||
Prov: ctx.Filter.Prov,
|
||||
City: ctx.Filter.City,
|
||||
Prov: prov,
|
||||
City: city,
|
||||
IP: orm.Inet{Addr: ctx.Source},
|
||||
Time: ctx.Now,
|
||||
}); err != nil {
|
||||
@@ -264,6 +277,37 @@ func persistChannelCreate(ctx *channelCreateContext, channels []*m.Channel) erro
|
||||
})
|
||||
}
|
||||
|
||||
func validateChannelArea(area *m.Area) error {
|
||||
if area == nil {
|
||||
return nil
|
||||
}
|
||||
switch area.Level {
|
||||
case m.AreaLevelProvince:
|
||||
return nil
|
||||
case m.AreaLevelCity:
|
||||
if area.ParentID == nil || area.Parent == nil {
|
||||
return core.NewServErr("地区数据异常", nil)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return core.NewBizErr("地区层级不支持")
|
||||
}
|
||||
}
|
||||
|
||||
func areaProvinceCity(area *m.Area) (prov *string, city *string) {
|
||||
if area == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch area.Level {
|
||||
case m.AreaLevelProvince:
|
||||
return u.P(area.Name), nil
|
||||
case m.AreaLevelCity:
|
||||
return u.P(area.Parent.Name), u.P(area.Name)
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func findExpiredChannelBatches(proxyId int32, now time.Time) (map[string]struct{}, error) {
|
||||
keys, err := g.Redis.Keys(context.Background(), usedChansKey(proxyId, "*")).Result()
|
||||
if err != nil {
|
||||
@@ -778,6 +822,20 @@ redis.call("DEL", batch_key)
|
||||
return 1
|
||||
`)
|
||||
|
||||
// 节点筛选条件
|
||||
type EdgeFilter struct {
|
||||
Isp *m.EdgeISP `json:"isp"`
|
||||
AreaID *int32 `json:"area_id"`
|
||||
}
|
||||
|
||||
func (f *EdgeFilter) IsEmpty() bool {
|
||||
if f == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return u.X(f.Isp.String()) == nil && f.AreaID == nil
|
||||
}
|
||||
|
||||
// 错误信息
|
||||
var (
|
||||
ErrResourceNotExist = core.NewBizErr("套餐不存在")
|
||||
|
||||
Reference in New Issue
Block a user