重构提取逻辑,新增 area 表

This commit is contained in:
2026-06-10 14:32:45 +08:00
parent dd482dd6b0
commit ebac8042ea
26 changed files with 7939 additions and 666 deletions

View File

@@ -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("套餐不存在")