255 lines
8.3 KiB
Go
255 lines
8.3 KiB
Go
package redpacket
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"hyapp-admin-server/internal/appctx"
|
|
"hyapp-admin-server/internal/integration/walletclient"
|
|
"hyapp-admin-server/internal/middleware"
|
|
"hyapp-admin-server/internal/modules/shared"
|
|
"hyapp-admin-server/internal/response"
|
|
walletv1 "hyapp.local/api/proto/wallet/v1"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type Handler struct {
|
|
wallet walletclient.Client
|
|
audit shared.OperationLogger
|
|
}
|
|
|
|
func New(wallet walletclient.Client, audit shared.OperationLogger) *Handler {
|
|
return &Handler{wallet: wallet, audit: audit}
|
|
}
|
|
|
|
type configRequest struct {
|
|
Enabled bool `json:"enabled"`
|
|
CountTiers []int32 `json:"count_tiers"`
|
|
AmountTiers []int64 `json:"amount_tiers"`
|
|
DelayedOpenSeconds int32 `json:"delayed_open_seconds"`
|
|
ExpireSeconds int32 `json:"expire_seconds"`
|
|
DailySendLimit int32 `json:"daily_send_limit"`
|
|
}
|
|
|
|
type configDTO struct {
|
|
AppCode string `json:"app_code"`
|
|
Enabled bool `json:"enabled"`
|
|
CountTiers []int32 `json:"count_tiers"`
|
|
AmountTiers []int64 `json:"amount_tiers"`
|
|
DelayedOpenSeconds int32 `json:"delayed_open_seconds"`
|
|
ExpireSeconds int32 `json:"expire_seconds"`
|
|
DailySendLimit int32 `json:"daily_send_limit"`
|
|
UpdatedByAdminID int64 `json:"updated_by_admin_id"`
|
|
CreatedAtMS int64 `json:"created_at_ms"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
}
|
|
|
|
type packetDTO struct {
|
|
AppCode string `json:"app_code"`
|
|
PacketID string `json:"packet_id"`
|
|
CommandID string `json:"command_id"`
|
|
SenderUserID int64 `json:"sender_user_id"`
|
|
RoomID string `json:"room_id"`
|
|
RegionID int64 `json:"region_id"`
|
|
PacketType string `json:"packet_type"`
|
|
TotalAmount int64 `json:"total_amount"`
|
|
PacketCount int32 `json:"packet_count"`
|
|
RemainingAmount int64 `json:"remaining_amount"`
|
|
RemainingCount int32 `json:"remaining_count"`
|
|
Status string `json:"status"`
|
|
OpenAtMS int64 `json:"open_at_ms"`
|
|
ExpiresAtMS int64 `json:"expires_at_ms"`
|
|
CreatedAtMS int64 `json:"created_at_ms"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
Claims []claimDTO `json:"claims,omitempty"`
|
|
}
|
|
|
|
type claimDTO struct {
|
|
AppCode string `json:"app_code"`
|
|
ClaimID string `json:"claim_id"`
|
|
CommandID string `json:"command_id"`
|
|
PacketID string `json:"packet_id"`
|
|
UserID int64 `json:"user_id"`
|
|
Amount int64 `json:"amount"`
|
|
WalletTransactionID string `json:"wallet_transaction_id"`
|
|
Status string `json:"status"`
|
|
FailureReason string `json:"failure_reason"`
|
|
CreatedAtMS int64 `json:"created_at_ms"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
}
|
|
|
|
func (h *Handler) GetConfig(c *gin.Context) {
|
|
if h.wallet == nil {
|
|
response.ServerError(c, "钱包服务未配置")
|
|
return
|
|
}
|
|
resp, err := h.wallet.GetRedPacketConfig(c.Request.Context(), &walletv1.GetRedPacketConfigRequest{
|
|
AppCode: appctx.FromContext(c.Request.Context()),
|
|
})
|
|
if err != nil {
|
|
response.ServerError(c, "获取红包配置失败")
|
|
return
|
|
}
|
|
response.OK(c, configFromProto(resp.GetConfig()))
|
|
}
|
|
|
|
func (h *Handler) UpdateConfig(c *gin.Context) {
|
|
if h.wallet == nil {
|
|
response.ServerError(c, "钱包服务未配置")
|
|
return
|
|
}
|
|
var req configRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "红包配置参数不正确")
|
|
return
|
|
}
|
|
resp, err := h.wallet.UpdateRedPacketConfig(c.Request.Context(), &walletv1.UpdateRedPacketConfigRequest{
|
|
AppCode: appctx.FromContext(c.Request.Context()),
|
|
Enabled: req.Enabled,
|
|
CountTiers: req.CountTiers,
|
|
AmountTiers: req.AmountTiers,
|
|
DelayedOpenSeconds: req.DelayedOpenSeconds,
|
|
ExpireSeconds: req.ExpireSeconds,
|
|
DailySendLimit: req.DailySendLimit,
|
|
OperatorUserId: int64(middleware.CurrentUserID(c)),
|
|
})
|
|
if err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
item := configFromProto(resp.GetConfig())
|
|
shared.OperationLogWithResourceID(c, h.audit, "update-red-packet-config", "red_packet_configs", item.AppCode, "success", "")
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) ListPackets(c *gin.Context) {
|
|
if h.wallet == nil {
|
|
response.ServerError(c, "钱包服务未配置")
|
|
return
|
|
}
|
|
options := shared.ListOptions(c)
|
|
req := &walletv1.ListRedPacketsRequest{
|
|
AppCode: appctx.FromContext(c.Request.Context()),
|
|
RoomId: strings.TrimSpace(c.Query("room_id")),
|
|
PacketType: strings.TrimSpace(c.Query("packet_type")),
|
|
Status: strings.TrimSpace(options.Status),
|
|
Page: int32(options.Page),
|
|
PageSize: int32(options.PageSize),
|
|
SenderUserId: parseInt64Query(c, "sender_user_id"),
|
|
RegionId: parseInt64Query(c, "region_id"),
|
|
StartAtMs: parseInt64Query(c, "start_at_ms"),
|
|
EndAtMs: parseInt64Query(c, "end_at_ms"),
|
|
}
|
|
resp, err := h.wallet.ListRedPackets(c.Request.Context(), req)
|
|
if err != nil {
|
|
response.ServerError(c, "获取红包列表失败")
|
|
return
|
|
}
|
|
items := make([]packetDTO, 0, len(resp.GetPackets()))
|
|
for _, packet := range resp.GetPackets() {
|
|
items = append(items, packetFromProto(packet))
|
|
}
|
|
response.OK(c, response.Page{Items: items, Page: options.Page, PageSize: options.PageSize, Total: resp.GetTotal()})
|
|
}
|
|
|
|
func (h *Handler) GetPacket(c *gin.Context) {
|
|
if h.wallet == nil {
|
|
response.ServerError(c, "钱包服务未配置")
|
|
return
|
|
}
|
|
packetID := strings.TrimSpace(c.Param("packet_id"))
|
|
if packetID == "" {
|
|
response.BadRequest(c, "红包 ID 不正确")
|
|
return
|
|
}
|
|
resp, err := h.wallet.GetRedPacket(c.Request.Context(), &walletv1.GetRedPacketRequest{
|
|
AppCode: appctx.FromContext(c.Request.Context()),
|
|
PacketId: packetID,
|
|
IncludeClaims: true,
|
|
})
|
|
if err != nil {
|
|
response.ServerError(c, "获取红包详情失败")
|
|
return
|
|
}
|
|
response.OK(c, packetFromProto(resp.GetPacket()))
|
|
}
|
|
|
|
func configFromProto(config *walletv1.RedPacketConfig) configDTO {
|
|
if config == nil {
|
|
return configDTO{}
|
|
}
|
|
return configDTO{
|
|
AppCode: config.GetAppCode(),
|
|
Enabled: config.GetEnabled(),
|
|
CountTiers: append([]int32(nil), config.GetCountTiers()...),
|
|
AmountTiers: append([]int64(nil), config.GetAmountTiers()...),
|
|
DelayedOpenSeconds: config.GetDelayedOpenSeconds(),
|
|
ExpireSeconds: config.GetExpireSeconds(),
|
|
DailySendLimit: config.GetDailySendLimit(),
|
|
UpdatedByAdminID: config.GetUpdatedByAdminId(),
|
|
CreatedAtMS: config.GetCreatedAtMs(),
|
|
UpdatedAtMS: config.GetUpdatedAtMs(),
|
|
}
|
|
}
|
|
|
|
func packetFromProto(packet *walletv1.RedPacket) packetDTO {
|
|
if packet == nil {
|
|
return packetDTO{}
|
|
}
|
|
claims := make([]claimDTO, 0, len(packet.GetClaims()))
|
|
for _, claim := range packet.GetClaims() {
|
|
claims = append(claims, claimFromProto(claim))
|
|
}
|
|
return packetDTO{
|
|
AppCode: packet.GetAppCode(),
|
|
PacketID: packet.GetPacketId(),
|
|
CommandID: packet.GetCommandId(),
|
|
SenderUserID: packet.GetSenderUserId(),
|
|
RoomID: packet.GetRoomId(),
|
|
RegionID: packet.GetRegionId(),
|
|
PacketType: packet.GetPacketType(),
|
|
TotalAmount: packet.GetTotalAmount(),
|
|
PacketCount: packet.GetPacketCount(),
|
|
RemainingAmount: packet.GetRemainingAmount(),
|
|
RemainingCount: packet.GetRemainingCount(),
|
|
Status: packet.GetStatus(),
|
|
OpenAtMS: packet.GetOpenAtMs(),
|
|
ExpiresAtMS: packet.GetExpiresAtMs(),
|
|
CreatedAtMS: packet.GetCreatedAtMs(),
|
|
UpdatedAtMS: packet.GetUpdatedAtMs(),
|
|
Claims: claims,
|
|
}
|
|
}
|
|
|
|
func claimFromProto(claim *walletv1.RedPacketClaim) claimDTO {
|
|
if claim == nil {
|
|
return claimDTO{}
|
|
}
|
|
return claimDTO{
|
|
AppCode: claim.GetAppCode(),
|
|
ClaimID: claim.GetClaimId(),
|
|
CommandID: claim.GetCommandId(),
|
|
PacketID: claim.GetPacketId(),
|
|
UserID: claim.GetUserId(),
|
|
Amount: claim.GetAmount(),
|
|
WalletTransactionID: claim.GetWalletTransactionId(),
|
|
Status: claim.GetStatus(),
|
|
FailureReason: claim.GetFailureReason(),
|
|
CreatedAtMS: claim.GetCreatedAtMs(),
|
|
UpdatedAtMS: claim.GetUpdatedAtMs(),
|
|
}
|
|
}
|
|
|
|
func parseInt64Query(c *gin.Context, key string) int64 {
|
|
value := strings.TrimSpace(c.Query(key))
|
|
if value == "" {
|
|
return 0
|
|
}
|
|
parsed, _ := strconv.ParseInt(value, 10, 64)
|
|
if parsed < 0 {
|
|
return 0
|
|
}
|
|
return parsed
|
|
}
|