Files
web_huakui_server/app/service/rechargepackageser/package.go
T
rootandClaude Opus 4.7 85c0071fd8 feat: 从黄果 NET hgdjnet-server 9bfbafe 导入 HKDJ 官网后端
来源:hgdjnet-server 9bfbafe10d417deea959bd53117bc88a10e60a83
项目身份 HKDJ / JHA-216,独立官网仓库,Jenkins 守卫键 hkdjnet
测试目录 /server/hkdj_net,App/Web API 30331/30332

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-16 11:20:04 +08:00

109 lines
3.6 KiB
Go

package rechargepackageser
import (
"context"
"hkdj-web-server/app/api/proto"
"hkdj-web-server/app/service/rechargeser/jiahua"
"hkdj-web-server/pub/common/srvdef"
"hkdj-web-server/pub/models/rechargepackagemod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetRechargePackageList 查询购买套餐页所需的会员畅享和金币充值列表,并为各套餐附上可用支付方式。
// 内部统一调用一次嘉华通道查询,避免 N+1 请求。
func GetRechargePackageList(ctx context.Context, sysType string) (*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, sysType)
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, sysType string) 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, _ := jiahua.GetPayChannelByMoney(ctx, moneys, sysType)
channelMap := make(map[int64][]proto.PayMethodInfo, len(channels))
for _, ch := range channels {
methods := make([]proto.PayMethodInfo, 0, 3)
if ch.Alipay {
methods = append(methods, proto.PayMethodInfo{Type: "alipay", TypeName: "支付宝"})
}
if ch.Wechat {
methods = append(methods, proto.PayMethodInfo{Type: "wechat", TypeName: "微信"})
}
if ch.Union {
methods = append(methods, proto.PayMethodInfo{Type: "union", TypeName: "银联"})
}
channelMap[ch.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,
}
}