无订阅 支付后出现两个订阅
Build docker and publish / build (20.15.1) (push) Failing after 7m37s

This commit is contained in:
2026-03-05 21:53:36 -08:00
parent a1ab0fefa4
commit 7308aa9191
51 changed files with 2041 additions and 556 deletions
+22 -13
View File
@@ -202,27 +202,36 @@ func (m *customServerModel) ClearServerAllCache(ctx context.Context) error {
// CountNodesByIdsAndTags 根据节点ID和标签计算启用的节点数量
func (m *customServerModel) CountNodesByIdsAndTags(ctx context.Context, nodeIds []int64, tags []string) (int64, error) {
tags = normalizeNodeTags(tags)
if len(nodeIds) == 0 && len(tags) == 0 {
return 0, nil
}
var count int64
query := m.WithContext(ctx).Model(&Node{}).Where("enabled = ?", true)
if len(nodeIds) > 0 || len(tags) > 0 {
subQuery := m.WithContext(ctx).Model(&Node{}).Where("enabled = ?", true)
if len(nodeIds) > 0 && len(tags) > 0 {
subQuery = subQuery.Where("id IN ? OR ?", nodeIds, InSet("tags", tags))
} else if len(nodeIds) > 0 {
subQuery = subQuery.Where("id IN ?", nodeIds)
} else {
subQuery = subQuery.Scopes(InSet("tags", tags))
}
query = subQuery
if len(nodeIds) > 0 {
query = query.Where("id IN ?", nodeIds)
}
if len(tags) > 0 {
query = query.Scopes(InSet("tags", tags))
}
err := query.Count(&count).Error
return count, err
}
func normalizeNodeTags(tags []string) []string {
cleaned := make([]string, 0, len(tags))
for _, tag := range tags {
trimmed := strings.TrimSpace(tag)
if trimmed == "" {
continue
}
cleaned = append(cleaned, trimmed)
}
return tool.RemoveDuplicateElements(cleaned...)
}
// InSet 支持多值 OR 查询
func InSet(field string, values []string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
+12
View File
@@ -0,0 +1,12 @@
package node
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestNormalizeNodeTags(t *testing.T) {
tags := normalizeNodeTags([]string{"美国", " 日本 ", "", "美国", " ", "日本"})
require.Equal(t, []string{"美国", "日本"}, tags)
}
+40 -3
View File
@@ -15,7 +15,8 @@ import (
var _ Model = (*customSubscribeModel)(nil)
var (
cacheSubscribeIdPrefix = "cache:subscribe:id:"
cacheSubscribeIdPrefix = "cache:subscribe:id:"
cacheUserSubscribeUserPrefix = "cache:user:subscribe:user:"
)
type (
@@ -119,13 +120,31 @@ func (m *defaultSubscribeModel) Update(ctx context.Context, data *Subscribe, tx
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
var userIds []int64
err = m.QueryNoCacheCtx(ctx, &userIds, func(conn *gorm.DB, v interface{}) error {
return conn.Table("user_subscribe").
Where("subscribe_id = ? AND status IN (0, 1)", data.Id).
Distinct("user_id").
Pluck("user_id", &userIds).Error
})
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
userSubscribeCacheKeys := make([]string, 0, len(userIds))
for _, userId := range userIds {
userSubscribeCacheKeys = append(userSubscribeCacheKeys, fmt.Sprintf("%s%d", cacheUserSubscribeUserPrefix, userId))
}
allCacheKeys := append(m.getCacheKeys(old), userSubscribeCacheKeys...)
err = m.ExecCtx(ctx, func(conn *gorm.DB) error {
db := conn
if len(tx) > 0 {
db = tx[0]
}
return db.Save(data).Error
}, m.getCacheKeys(old)...)
}, allCacheKeys...)
return err
}
@@ -137,13 +156,31 @@ func (m *defaultSubscribeModel) Delete(ctx context.Context, id int64, tx ...*gor
}
return err
}
var userIds []int64
err = m.QueryNoCacheCtx(ctx, &userIds, func(conn *gorm.DB, v interface{}) error {
return conn.Table("user_subscribe").
Where("subscribe_id = ? AND status IN (0, 1)", id).
Distinct("user_id").
Pluck("user_id", &userIds).Error
})
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
userSubscribeCacheKeys := make([]string, 0, len(userIds))
for _, userId := range userIds {
userSubscribeCacheKeys = append(userSubscribeCacheKeys, fmt.Sprintf("%s%d", cacheUserSubscribeUserPrefix, userId))
}
allCacheKeys := append(m.getCacheKeys(data), userSubscribeCacheKeys...)
err = m.ExecCtx(ctx, func(conn *gorm.DB) error {
db := conn
if len(tx) > 0 {
db = tx[0]
}
return db.Delete(&Subscribe{}, id).Error
}, m.getCacheKeys(data)...)
}, allCacheKeys...)
return err
}
+10
View File
@@ -19,6 +19,7 @@ type customSystemLogicModel interface {
GetTosConfig(ctx context.Context) ([]*System, error)
GetCurrencyConfig(ctx context.Context) ([]*System, error)
GetVerifyCodeConfig(ctx context.Context) ([]*System, error)
GetSignatureConfig(ctx context.Context) ([]*System, error)
GetLogConfig(ctx context.Context) ([]*System, error)
UpdateNodeMultiplierConfig(ctx context.Context, config string) error
FindNodeMultiplierConfig(ctx context.Context) (*System, error)
@@ -154,6 +155,15 @@ func (m *customSystemModel) GetVerifyCodeConfig(ctx context.Context) ([]*System,
return configs, err
}
// GetSignatureConfig returns the signature config.
func (m *customSystemModel) GetSignatureConfig(ctx context.Context) ([]*System, error) {
var configs []*System
err := m.QueryCtx(ctx, &configs, config.SignatureConfigKey, func(conn *gorm.DB, v interface{}) error {
return conn.Where("`category` = ?", "signature").Find(v).Error
})
return configs, err
}
// GetLogConfig returns the log config.
func (m *customSystemModel) GetLogConfig(ctx context.Context) ([]*System, error) {
var configs []*System