137 lines
4.3 KiB
Go

package http
import (
"net/http"
"strings"
walletv1 "hyapp.local/api/proto/wallet/v1"
"hyapp/pkg/appcode"
"hyapp/services/gateway-service/internal/auth"
)
// getMyVIP 返回当前用户 VIP 状态。
func (h *Handler) getMyVIP(writer http.ResponseWriter, request *http.Request) {
if h.walletClient == nil {
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
return
}
resp, err := h.walletClient.GetMyVip(request.Context(), &walletv1.GetMyVipRequest{
RequestId: requestIDFromContext(request.Context()),
AppCode: appcode.FromContext(request.Context()),
UserId: auth.UserIDFromContext(request.Context()),
})
if err != nil {
writeRPCError(writer, request, err)
return
}
writeOK(writer, request, vipFromProto(resp.GetVip()))
}
// listVIPPackages 返回可购买 VIP 包和当前会员状态。
func (h *Handler) listVIPPackages(writer http.ResponseWriter, request *http.Request) {
if h.walletClient == nil {
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
return
}
resp, err := h.walletClient.ListVipPackages(request.Context(), &walletv1.ListVipPackagesRequest{
RequestId: requestIDFromContext(request.Context()),
AppCode: appcode.FromContext(request.Context()),
UserId: auth.UserIDFromContext(request.Context()),
})
if err != nil {
writeRPCError(writer, request, err)
return
}
packages := make([]vipPackageData, 0, len(resp.GetPackages()))
for _, item := range resp.GetPackages() {
packages = append(packages, vipPackageFromProto(item))
}
writeOK(writer, request, map[string]any{"current_vip": vipFromProto(resp.GetCurrentVip()), "packages": packages})
}
// purchaseVIP 购买、续期或升级 VIP。
func (h *Handler) purchaseVIP(writer http.ResponseWriter, request *http.Request) {
if h.walletClient == nil {
writeError(writer, request, http.StatusBadGateway, codeUpstreamError, "upstream service error")
return
}
var body vipPurchaseRequestBody
if !decode(writer, request, &body) {
return
}
commandID := strings.TrimSpace(body.CommandID)
if commandID == "" {
commandID = strings.TrimSpace(body.CommandIDAlt)
}
if commandID == "" || body.Level <= 0 {
writeError(writer, request, http.StatusBadRequest, codeInvalidArgument, "invalid argument")
return
}
resp, err := h.walletClient.PurchaseVip(request.Context(), &walletv1.PurchaseVipRequest{
CommandId: commandID,
AppCode: appcode.FromContext(request.Context()),
UserId: auth.UserIDFromContext(request.Context()),
Level: body.Level,
})
if err != nil {
writeRPCError(writer, request, err)
return
}
writeOK(writer, request, map[string]any{
"order_id": resp.GetOrderId(),
"transaction_id": resp.GetTransactionId(),
"vip": vipFromProto(resp.GetVip()),
"coin_spent": resp.GetCoinSpent(),
"coin_balance_after": resp.GetCoinBalanceAfter(),
"reward_items": vipRewardItemsFromProto(resp.GetRewardItems()),
})
}
func vipFromProto(vip *walletv1.UserVip) overviewVIPData {
if vip == nil {
return overviewVIPData{}
}
return overviewVIPData{
Level: vip.GetLevel(),
Name: vip.GetName(),
Active: vip.GetActive(),
StartedAtMS: vip.GetStartedAtMs(),
ExpiresAtMS: vip.GetExpiresAtMs(),
}
}
func vipPackageFromProto(item *walletv1.VipLevel) vipPackageData {
if item == nil {
return vipPackageData{}
}
return vipPackageData{
Level: item.GetLevel(),
Name: item.GetName(),
Status: item.GetStatus(),
PriceCoin: item.GetPriceCoin(),
DurationMS: item.GetDurationMs(),
RewardResourceGroupID: item.GetRewardResourceGroupId(),
RewardItems: vipRewardItemsFromProto(item.GetRewardItems()),
CanPurchase: item.GetCanPurchase(),
SortOrder: item.GetSortOrder(),
}
}
func vipRewardItemsFromProto(items []*walletv1.VipRewardItem) []vipRewardItemData {
resp := make([]vipRewardItemData, 0, len(items))
for _, item := range items {
if item == nil {
continue
}
resp = append(resp, vipRewardItemData{
ResourceID: item.GetResourceId(),
ResourceCode: item.GetResourceCode(),
ResourceType: item.GetResourceType(),
Name: item.GetName(),
Quantity: item.GetQuantity(),
ExpiresAtMS: item.GetExpiresAtMs(),
})
}
return resp
}