Files
2026-10-27 16:44:55 +08:00

239 lines
7.2 KiB
Go

package srv_homebanner
import (
"context"
"regexp"
"strings"
"time"
"videoweb/pub/common/playletcache"
"videoweb/pub/common/response"
"videoweb/pub/common/srvdef"
"videoweb/pub/models/homebannermod"
"videoweb/pub/models/mwacc"
"videoweb/web/api/proto"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
const (
defaultHomeBannerPageSize int64 = 10
maxHomeBannerPageSize int64 = 100
)
var homeBannerWebProjection = bson.D{
{Key: homebannermod.FN.HomeBanner.Id, Value: 1},
{Key: homebannermod.FN.HomeBanner.Name, Value: 1},
{Key: homebannermod.FN.HomeBanner.Image, Value: 1},
{Key: homebannermod.FN.HomeBanner.VerticalImage, Value: 1},
{Key: homebannermod.FN.HomeBanner.Url, Value: 1},
{Key: homebannermod.FN.HomeBanner.Rank, Value: 1},
{Key: homebannermod.FN.HomeBanner.Status, Value: 1},
{Key: homebannermod.FN.HomeBanner.CreatedById, Value: 1},
{Key: homebannermod.FN.HomeBanner.CreatedByName, Value: 1},
{Key: homebannermod.FN.HomeBanner.UpdatedByName, Value: 1},
{Key: homebannermod.FN.HomeBanner.CreatedAt, Value: 1},
{Key: homebannermod.FN.HomeBanner.UpdatedAt, Value: 1},
}
// ListHomeBanner 分页查询首页 banner 列表
func ListHomeBanner(ctx context.Context, req *proto.HomeBannerListReq) (*proto.HomeBannerListPageResp, *srvdef.SrvErr) {
if req == nil {
return nil, srvdef.New(srvdef.ErrParamError, "", "")
}
filter := bson.M{}
if req.Id != nil && *req.Id > 0 {
filter[homebannermod.FN.HomeBanner.Id] = *req.Id
}
if req.Status != nil {
filter[homebannermod.FN.HomeBanner.Status] = *req.Status
}
if name := strings.TrimSpace(req.Name); name != "" {
filter[homebannermod.FN.HomeBanner.Name] = bson.M{"$regex": regexp.QuoteMeta(name)}
}
pageNum, pageSize := normalizeHomeBannerPage(req.PageNum, req.PageSize)
totalCount, err := homebannermod.CountHomeBanner(ctx, filter)
if err != nil {
return nil, err
}
resp := &proto.HomeBannerListPageResp{
BasePageResp: response.BasePageResp{
TotalCount: totalCount,
PageSize: int(pageSize),
PageNum: int(pageNum),
List: make([]*proto.HomeBannerListResp, 0),
},
}
if totalCount == 0 {
return resp, nil
}
list, err := homebannermod.FindManyHomeBanner(ctx, filter, options.Find().
SetProjection(homeBannerWebProjection).
SetSort(bson.D{
{Key: homebannermod.FN.HomeBanner.Rank, Value: -1},
{Key: homebannermod.FN.HomeBanner.UpdatedAt, Value: -1},
{Key: homebannermod.FN.HomeBanner.Id, Value: -1},
}).
SetSkip((pageNum-1)*pageSize).
SetLimit(pageSize))
if err != nil {
return nil, err
}
items := make([]*proto.HomeBannerListResp, 0, len(list))
for _, item := range list {
if item == nil {
continue
}
items = append(items, &proto.HomeBannerListResp{
Id: item.Id,
Name: item.Name,
Image: item.Image,
VerticalImage: item.VerticalImage,
Url: item.Url,
Rank: item.Rank,
Status: item.Status,
CreatedById: item.CreatedById,
CreatedByName: item.CreatedByName,
UpdatedByName: item.UpdatedByName,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}
resp.List = items
return resp, nil
}
// AddHomeBanner 新增首页 banner
func AddHomeBanner(ctx context.Context, req *proto.HomeBannerAddReq, operatorId int64) (*proto.HomeBannerAddResp, *srvdef.SrvErr) {
if req == nil {
return nil, srvdef.New(srvdef.ErrParamError, "", "")
}
name := strings.TrimSpace(req.Name)
image := strings.TrimSpace(req.Image)
if name == "" {
return nil, srvdef.New(srvdef.ErrParamError, "名称不能为空", "")
}
if image == "" {
return nil, srvdef.New(srvdef.ErrParamError, "图片不能为空", "")
}
if req.Status == nil {
return nil, srvdef.New(srvdef.ErrParamError, "状态不能为空", "")
}
operatorId, operatorName := resolveHomeBannerOperator(ctx, operatorId)
doc := &homebannermod.HomeBanner{
Name: name,
Image: image,
VerticalImage: strings.TrimSpace(req.VerticalImage),
Url: strings.TrimSpace(req.Url),
Rank: req.Rank,
Status: *req.Status,
CreatedById: operatorId,
CreatedByName: operatorName,
UpdatedByName: operatorName,
}
if err := homebannermod.InsertOneHomeBanner(ctx, doc); err != nil {
return nil, err
}
clearHomeBannerCache()
return &proto.HomeBannerAddResp{Id: doc.Id}, nil
}
// UpdateHomeBanner 更新首页 banner
func UpdateHomeBanner(ctx context.Context, req *proto.HomeBannerUpdateReq, operatorId int64) *srvdef.SrvErr {
if req == nil || req.Id <= 0 {
return srvdef.New(srvdef.ErrParamError, "首页banner ID无效", "")
}
setDoc := bson.M{homebannermod.FN.HomeBanner.UpdatedAt: time.Now()}
if req.Name != nil {
name := strings.TrimSpace(*req.Name)
if name == "" {
return srvdef.New(srvdef.ErrParamError, "名称不能为空", "")
}
setDoc[homebannermod.FN.HomeBanner.Name] = name
}
if req.Image != nil {
image := strings.TrimSpace(*req.Image)
if image == "" {
return srvdef.New(srvdef.ErrParamError, "图片不能为空", "")
}
setDoc[homebannermod.FN.HomeBanner.Image] = image
}
if req.VerticalImage != nil {
setDoc[homebannermod.FN.HomeBanner.VerticalImage] = strings.TrimSpace(*req.VerticalImage)
}
if req.Url != nil {
setDoc[homebannermod.FN.HomeBanner.Url] = strings.TrimSpace(*req.Url)
}
if req.Rank != nil {
setDoc[homebannermod.FN.HomeBanner.Rank] = *req.Rank
}
if req.Status != nil {
setDoc[homebannermod.FN.HomeBanner.Status] = *req.Status
}
if len(setDoc) <= 1 {
return srvdef.New(srvdef.ErrParamError, "没有可更新字段", "")
}
_, operatorName := resolveHomeBannerOperator(ctx, operatorId)
setDoc[homebannermod.FN.HomeBanner.UpdatedByName] = operatorName
if err := homebannermod.UpdateOneHomeBanner(ctx,
bson.M{homebannermod.FN.HomeBanner.Id: req.Id},
bson.M{"$set": setDoc},
); err != nil {
return err
}
clearHomeBannerCache()
return nil
}
// DelHomeBanner 删除首页 banner
func DelHomeBanner(ctx context.Context, req *proto.HomeBannerDelReq) *srvdef.SrvErr {
if req == nil || req.Id <= 0 {
return srvdef.New(srvdef.ErrParamError, "首页banner ID无效", "")
}
count, err := homebannermod.DelOneHomeBanner(ctx, bson.M{homebannermod.FN.HomeBanner.Id: req.Id})
if err != nil {
return err
}
if count == 0 {
return srvdef.New(srvdef.ErrNoData, "", "")
}
clearHomeBannerCache()
return nil
}
// normalizeHomeBannerPage 规范分页参数,限制单页数量避免大分页拖慢查询
func normalizeHomeBannerPage(pageNum, pageSize int64) (int64, int64) {
if pageNum <= 0 {
pageNum = 1
}
if pageSize <= 0 {
pageSize = defaultHomeBannerPageSize
}
if pageSize > maxHomeBannerPageSize {
pageSize = maxHomeBannerPageSize
}
return pageNum, pageSize
}
// resolveHomeBannerOperator 从后台账号表解析当前操作人名称
func resolveHomeBannerOperator(ctx context.Context, operatorId int64) (int64, string) {
if operatorId <= 0 {
return 0, ""
}
acc, err := mwacc.FindOneAccByFilter(ctx, bson.M{
mwacc.FN.MwAcc.Id: operatorId,
}, options.FindOne().SetProjection(bson.D{
{Key: mwacc.FN.MwAcc.Id, Value: 1},
{Key: mwacc.FN.MwAcc.UserName, Value: 1},
}))
if err != nil || acc == nil {
return operatorId, ""
}
return acc.Id, acc.UserName
}
// clearHomeBannerCache 清除短剧首页缓存
func clearHomeBannerCache() {
playletcache.ClearHomeCache()
}