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() }