feat(subscription): implement FilterList method for subscription queries and update related logic

This commit is contained in:
Chang lue Tsen 2025-09-04 10:20:35 -04:00
parent 8f11380e7a
commit 0636a4bddf
7 changed files with 156 additions and 103 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"strings"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
@ -29,7 +30,12 @@ func NewGetSubscribeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
}
func (l *GetSubscribeListLogic) GetSubscribeList(req *types.GetSubscribeListRequest) (resp *types.GetSubscribeListResponse, err error) {
total, list, err := l.svcCtx.SubscribeModel.QuerySubscribeListByPage(l.ctx, int(req.Page), int(req.Size), req.Language, req.Search)
total, list, err := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
Page: int(req.Page),
Size: int(req.Size),
Language: req.Language,
Search: req.Search,
})
if err != nil {
l.Logger.Error("[GetSubscribeListLogic] get subscribe list failed: ", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscribe list failed: %v", err.Error())
@ -60,8 +66,8 @@ func (l *GetSubscribeListLogic) GetSubscribeList(req *types.GetSubscribeListRequ
}
for i, item := range resultList {
if subscribe, ok := subscribeMaps[item.Id]; ok {
resultList[i].Sold = subscribe
if sub, ok := subscribeMaps[item.Id]; ok {
resultList[i].Sold = sub
}
}

View File

@ -3,6 +3,7 @@ package subscribe
import (
"context"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/server/pkg/xerr"
"github.com/pkg/errors"
"gorm.io/gorm"
@ -40,7 +41,11 @@ func (l *SubscribeSortLogic) SubscribeSort(req *types.SubscribeSortRequest) erro
l.Logger.Error("[SubscribeSortLogic] query subscribe list by ids error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query subscribe list by ids error: %v", err.Error())
}
subs, err := l.svcCtx.SubscribeModel.QuerySubscribeListByIds(l.ctx, ids)
_, subs, err := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
Page: 1,
Size: 9999,
Ids: ids,
})
if err != nil {
l.Logger.Error("[SubscribeSortLogic] query subscribe list by ids error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query subscribe list by ids error: %v", err.Error())

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
@ -32,20 +33,17 @@ func (l *GetSubscriptionLogic) GetSubscription(req *types.GetSubscriptionRequest
List: make([]types.Subscribe, 0),
}
// Get the subscription list
data, err := l.svcCtx.SubscribeModel.QuerySubscribeListByShow(l.ctx, req.Language)
_, data, err := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
Page: 1,
Size: 9999,
Show: true,
Language: req.Language,
DefaultLanguage: true,
})
if err != nil {
l.Errorw("[Site GetSubscription]", logger.Field("err", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscription list error: %v", err.Error())
}
// If no data is found for the specified language, query default language data
if len(data) == 0 && req.Language != "" {
data, err = l.svcCtx.SubscribeModel.QuerySubscribeListByShow(l.ctx, "")
if err != nil {
l.Errorw("[Site GetSubscription]", logger.Field("err", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscription list error: %v", err.Error())
}
}
list := make([]types.Subscribe, len(data))
for i, item := range data {
var sub types.Subscribe

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
@ -29,22 +30,20 @@ func NewQuerySubscribeListLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *QuerySubscribeListLogic) QuerySubscribeList(req *types.QuerySubscribeListRequest) (resp *types.QuerySubscribeListResponse, err error) {
total, data, err := l.svcCtx.SubscribeModel.QuerySubscribeListByPage(l.ctx, 1, 1000, req.Language, "")
total, data, err := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
Page: 1,
Size: 9999,
Language: req.Language,
Sell: true,
DefaultLanguage: true,
})
if err != nil {
l.Errorw("[QuerySubscribeListLogic] Database Error", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "QuerySubscribeList error: %v", err.Error())
}
// If no data is found for the specified language, query default language data
if total == 0 && req.Language != "" {
total, data, err = l.svcCtx.SubscribeModel.QuerySubscribeListByPage(l.ctx, 1, 1000, "", "")
if err != nil {
l.Errorw("[QuerySubscribeListLogic] Database Error", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "QuerySubscribeList error: %v", err.Error())
}
}
resp = &types.QuerySubscribeListResponse{
Total: int64(len(data)),
Total: total,
}
list := make([]types.Subscribe, len(data))
for i, item := range data {

View File

@ -21,7 +21,7 @@ type GetServerConfigLogic struct {
svcCtx *svc.ServiceContext
}
// Get server config
// NewGetServerConfigLogic Get server config
func NewGetServerConfigLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *GetServerConfigLogic {
return &GetServerConfigLogic{
Logger: logger.WithContext(ctx.Request.Context()),

View File

@ -7,6 +7,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
@ -73,7 +74,12 @@ func (l *GetServerUserListLogic) GetServerUserList(req *types.GetServerUserListR
}
}
subs, err := l.svcCtx.SubscribeModel.QuerySubscribeIdsByNodeIdAndNodeTag(l.ctx, nodeIds, nodeTag)
_, subs, err := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
Page: 1,
Size: 9999,
Node: nodeIds,
Tags: nodeTag,
})
if err != nil {
l.Errorw("QuerySubscribeIdsByServerIdAndServerGroupId error", logger.Field("error", err.Error()))
return nil, err

View File

@ -7,14 +7,32 @@ import (
"gorm.io/gorm"
)
type FilterParams struct {
Page int // Page Number
Size int // Page Size
Ids []int64 // Subscribe IDs
Node []int64 // Node IDs
Tags []string // Node Tags
Show bool // Show Portal Page
Sell bool // Sell
Language string // Language
DefaultLanguage bool // Default Subscribe Language Data
Search string // Search Keywords
}
func (p *FilterParams) Normalize() {
if p.Page <= 0 {
p.Page = 1
}
if p.Size <= 0 {
p.Size = 10
}
}
type customSubscribeLogicModel interface {
QuerySubscribeListByPage(ctx context.Context, page, size int, lang string, search string) (total int64, list []*Subscribe, err error)
QuerySubscribeList(ctx context.Context) ([]*Subscribe, error)
QuerySubscribeListByShow(ctx context.Context, lang string) ([]*Subscribe, error)
QuerySubscribeIdsByNodeIdAndNodeTag(ctx context.Context, node []int64, tags []string) ([]*Subscribe, error)
QuerySubscribeMinSortByIds(ctx context.Context, ids []int64) (int64, error)
QuerySubscribeListByIds(ctx context.Context, ids []int64) ([]*Subscribe, error)
FilterList(ctx context.Context, params *FilterParams) (int64, []*Subscribe, error)
ClearCache(ctx context.Context, id ...int64) error
QuerySubscribeMinSortByIds(ctx context.Context, ids []int64) (int64, error)
}
// NewModel returns a model for the database table.
@ -24,69 +42,6 @@ func NewModel(conn *gorm.DB, c *redis.Client) Model {
}
}
// QuerySubscribeListByPage Get Subscribe List
func (m *customSubscribeModel) QuerySubscribeListByPage(ctx context.Context, page, size int, lang string, search string) (total int64, list []*Subscribe, err error) {
err = m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
// About to be abandoned
_ = conn.Model(&Subscribe{}).
Where("sort = ?", 0).
Update("sort", gorm.Expr("id"))
conn = conn.Model(&Subscribe{})
if lang != "" {
conn = conn.Where("`language` = ?", lang)
}
if search != "" {
conn = conn.Where("`name` like ? or `description` like ?", "%"+search+"%", "%"+search+"%")
}
err = conn.Count(&total).Order("sort ASC").Limit(size).Offset((page - 1) * size).Find(v).Error
return nil
})
return total, list, err
}
// QuerySubscribeList Get Subscribe List
func (m *customSubscribeModel) QuerySubscribeList(ctx context.Context) ([]*Subscribe, error) {
var list []*Subscribe
err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
conn = conn.Model(&Subscribe{})
return conn.Where("`sell` = true").Order("sort ").Find(v).Error
})
return list, err
}
func (m *customSubscribeModel) QuerySubscribeIdsByNodeIdAndNodeTag(ctx context.Context, node []int64, tags []string) ([]*Subscribe, error) {
var data []*Subscribe
err := m.QueryNoCacheCtx(ctx, &data, func(conn *gorm.DB, v interface{}) error {
db := conn.Model(&Subscribe{})
if len(node) > 0 {
for _, id := range node {
db = db.Or("FIND_IN_SET(?, nodes)", id)
}
}
if len(tags) > 0 {
// 拼接多个 tag 条件
for _, t := range tags {
db = db.Or("FIND_IN_SET(?, node_tags)", t)
}
}
return db.Find(v).Error
})
return data, err
}
// QuerySubscribeListByShow Get Subscribe List By Show
func (m *customSubscribeModel) QuerySubscribeListByShow(ctx context.Context, lang string) ([]*Subscribe, error) {
var list []*Subscribe
err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
conn = conn.Model(&Subscribe{})
return conn.Where("`show` = true AND `language` = ?", lang).Find(v).Error
})
return list, err
}
func (m *customSubscribeModel) QuerySubscribeMinSortByIds(ctx context.Context, ids []int64) (int64, error) {
var minSort int64
err := m.QueryNoCacheCtx(ctx, &minSort, func(conn *gorm.DB, v interface{}) error {
@ -95,14 +50,6 @@ func (m *customSubscribeModel) QuerySubscribeMinSortByIds(ctx context.Context, i
return minSort, err
}
func (m *customSubscribeModel) QuerySubscribeListByIds(ctx context.Context, ids []int64) ([]*Subscribe, error) {
var list []*Subscribe
err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
return conn.Model(&Subscribe{}).Where("id IN ?", ids).Find(v).Error
})
return list, err
}
func (m *customSubscribeModel) ClearCache(ctx context.Context, ids ...int64) error {
if len(ids) <= 0 {
return nil
@ -118,3 +65,95 @@ func (m *customSubscribeModel) ClearCache(ctx context.Context, ids ...int64) err
}
return m.CachedConn.DelCacheCtx(ctx, cacheKeys...)
}
// FilterList Filter Subscribe List
func (m *customSubscribeModel) FilterList(ctx context.Context, params *FilterParams) (int64, []*Subscribe, error) {
if params == nil {
params = &FilterParams{}
}
params.Normalize()
var list []*Subscribe
var total int64
// 构建查询函数
buildQuery := func(conn *gorm.DB, lang string) *gorm.DB {
query := conn.Model(&Subscribe{})
if params.Search != "" {
s := "%" + params.Search + "%"
query = query.Where("`name` LIKE ? OR `description` LIKE ?", s, s)
}
if params.Show {
query = query.Where("`show` = true")
}
if params.Sell {
query = query.Where("`sell` = true")
}
if len(params.Ids) > 0 {
query = query.Where("id IN ?", params.Ids)
}
if len(params.Node) > 0 {
query = query.Where(func(db *gorm.DB) *gorm.DB {
for i, id := range params.Node {
if i == 0 {
db = db.Where("FIND_IN_SET(?, nodes)", id)
} else {
db = db.Or("FIND_IN_SET(?, nodes)", id)
}
}
return db
})
}
if len(params.Tags) > 0 {
query = query.Where(func(db *gorm.DB) *gorm.DB {
for i, tag := range params.Tags {
if i == 0 {
db = db.Where("FIND_IN_SET(?, node_tags)", tag)
} else {
db = db.Or("FIND_IN_SET(?, node_tags)", tag)
}
}
return db
})
}
if lang != "" {
query = query.Where("language = ?", lang)
} else if params.DefaultLanguage {
query = query.Where("language = ''")
}
return query
}
// 查询数据
queryFunc := func(lang string) error {
return m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
query := buildQuery(conn, lang)
if err := query.Count(&total).Error; err != nil {
return err
}
return query.Order("sort ASC").
Limit(params.Size).
Offset((params.Page - 1) * params.Size).
Find(v).Error
})
}
err := queryFunc(params.Language)
if err != nil {
return 0, nil, err
}
// fallback 默认语言
if params.DefaultLanguage && total == 0 {
err = queryFunc("")
if err != nil {
return 0, nil, err
}
}
return total, list, nil
}