package rechargepackageser import ( "context" "videoweb/app/api/proto" "videoweb/pub/common/log" "videoweb/pub/common/srvdef" "videoweb/pub/models/rechargepackagemod" "videoweb/pub/payCenter" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) // GetRechargePackageList 查询购买套餐页所需的会员畅享和金币充值列表,并为各套餐附上可用支付方式。 // 内部统一调用一次新支付中心通道查询,避免 N+1 请求。 func GetRechargePackageList(ctx context.Context) (*proto.RechargePackageListResp, *srvdef.SrvErr) { filter := bson.M{rechargepackagemod.FN.RechargePackage.Status: rechargepackagemod.StatusEnabled} opts := options.Find().SetSort(bson.D{ {Key: rechargepackagemod.FN.RechargePackage.PackageType, Value: 1}, {Key: rechargepackagemod.FN.RechargePackage.Sort, Value: 1}, {Key: rechargepackagemod.FN.RechargePackage.Id, Value: -1}, }) list, err := rechargepackagemod.FindManyRechargePackage(ctx, filter, opts) if err != nil { return nil, err } if len(list) == 0 { return &proto.RechargePackageListResp{ VipList: make([]*proto.RechargePackageItem, 0), CoinList: make([]*proto.RechargePackageItem, 0), }, nil } channelMap := buildPayMethodMap(ctx, list) resp := &proto.RechargePackageListResp{ VipList: make([]*proto.RechargePackageItem, 0), CoinList: make([]*proto.RechargePackageItem, 0), } for _, item := range list { data := rechargePackageToAppItem(item, channelMap[item.Price]) switch item.PackageType { case rechargepackagemod.PackageTypeVip: resp.VipList = append(resp.VipList, data) case rechargepackagemod.PackageTypeCoin: resp.CoinList = append(resp.CoinList, data) } } return resp, nil } // buildPayMethodMap 按金额批量查询可用支付方式;查询失败时返回空映射,不影响套餐列表展示。 func buildPayMethodMap(ctx context.Context, list rechargepackagemod.RechargePackageList) map[int64][]proto.PayMethodInfo { seen := map[int64]struct{}{} moneys := make([]int64, 0) for _, item := range list { if item == nil || item.Price <= 0 { continue } if _, ok := seen[item.Price]; ok { continue } seen[item.Price] = struct{}{} moneys = append(moneys, item.Price) } if len(moneys) == 0 { return map[int64][]proto.PayMethodInfo{} } channels, serr := payCenter.GetPayChannelByMoney(ctx, moneys) if serr != nil { log.Error("rechargepackageser:查询支付通道失败", log.E(serr)) return map[int64][]proto.PayMethodInfo{} } channelMap := make(map[int64][]proto.PayMethodInfo, len(moneys)) for _, money := range moneys { payTypes := channels.GetPayType(money) methods := make([]proto.PayMethodInfo, 0, len(payTypes)) for _, payType := range payTypes { methods = append(methods, proto.PayMethodInfo{Type: payType.Type, TypeName: payType.TypeName}) } channelMap[money] = methods } return channelMap } // rechargePackageToAppItem 将购买套餐表数据转换为 App 展示字段 func rechargePackageToAppItem(item *rechargepackagemod.RechargePackage, payMethods []proto.PayMethodInfo) *proto.RechargePackageItem { if payMethods == nil { payMethods = []proto.PayMethodInfo{} } return &proto.RechargePackageItem{ Id: item.Id, PackageType: item.PackageType, Name: item.Name, SubTitle: item.SubTitle, Price: item.Price, OriginalPrice: item.OriginalPrice, DurationDays: item.DurationDays, DurationHours: item.DurationDays * 24, BaseCoin: item.BaseCoin, GiftCoin: item.GiftCoin, TotalCoin: item.BaseCoin + item.GiftCoin, Sort: item.Sort, PayMethods: payMethods, } }