- products 表新增 cost_price 字段(成本价/分) - activity_reward_settings 新增 drop_quantity(单次产出数量,默认1) 和 cost_snapshot_cents(成本价快照) - 奖品创建/修改时自动快照成本价,drop_quantity 限制 1-100 - 抽奖发放逻辑按 drop_quantity 循环创建多个库存项 - 抽奖结果接口按 drop_quantity 返回多条 item,前端自动合并显示 - 抽奖记录接口返回 drop_quantity 字段 - 商品管理 API 全链路支持 cost_price
260 lines
7.6 KiB
Go
Executable File
260 lines
7.6 KiB
Go
Executable File
package activity
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
"bindbox-game/internal/pkg/logger"
|
||
"bindbox-game/internal/repository/mysql"
|
||
"bindbox-game/internal/repository/mysql/dao"
|
||
"bindbox-game/internal/repository/mysql/model"
|
||
usersvc "bindbox-game/internal/service/user"
|
||
|
||
"github.com/redis/go-redis/v9"
|
||
)
|
||
|
||
type Service interface {
|
||
// ... (other methods)
|
||
// ProcessOrderLottery 处理订单开奖(统一幂等逻辑)
|
||
// 参数: ctx 上下文, orderID 订单ID
|
||
// 返回: 错误信息
|
||
ProcessOrderLottery(ctx context.Context, orderID int64) error
|
||
|
||
// CreateActivity 创建活动
|
||
// 参数: in 活动创建输入
|
||
// 返回: 活动记录与错误
|
||
CreateActivity(ctx context.Context, in CreateActivityInput) (*model.Activities, error)
|
||
// ModifyActivity 修改活动
|
||
// 参数: id 活动ID, in 修改输入
|
||
// 返回: 错误信息
|
||
ModifyActivity(ctx context.Context, id int64, in ModifyActivityInput) error
|
||
// DeleteActivity 删除活动
|
||
// 参数: id 活动ID
|
||
// 返回: 错误信息
|
||
DeleteActivity(ctx context.Context, id int64) error
|
||
// GetActivity 获取活动详情
|
||
// 参数: id 活动ID
|
||
// 返回: 活动记录与错误
|
||
GetActivity(ctx context.Context, id int64) (*model.Activities, error)
|
||
// ListActivities 活动列表
|
||
// 参数: in 列表查询输入
|
||
// 返回: 活动集合、总数与错误
|
||
ListActivities(ctx context.Context, in ListActivitiesInput) (items []*model.Activities, total int64, err error)
|
||
|
||
// ListIssues 活动期列表
|
||
// 参数: activityID 活动ID, page 页码, pageSize 每页数量
|
||
// 返回: 期列表、总数与错误
|
||
ListIssues(ctx context.Context, activityID int64, page, pageSize int) (items []*model.ActivityIssues, total int64, err error)
|
||
// CreateIssue 创建期
|
||
// 参数: activityID 活动ID, in 创建输入
|
||
// 返回: 期记录与错误
|
||
CreateIssue(ctx context.Context, activityID int64, in CreateIssueInput) (*model.ActivityIssues, error)
|
||
// ModifyIssue 修改期
|
||
// 参数: issueID 期ID, in 修改输入
|
||
// 返回: 错误信息
|
||
ModifyIssue(ctx context.Context, issueID int64, in ModifyIssueInput) error
|
||
// DeleteIssue 删除期
|
||
// 参数: issueID 期ID
|
||
// 返回: 错误信息
|
||
DeleteIssue(ctx context.Context, issueID int64) error
|
||
|
||
// CreateIssueRewards 批量创建期奖励
|
||
// 参数: issueID 期ID, rewards 奖励创建输入数组
|
||
// 返回: 错误信息
|
||
CreateIssueRewards(ctx context.Context, issueID int64, rewards []CreateRewardInput) error
|
||
// ListIssueRewards 查询期奖励列表
|
||
// 参数: issueID 期ID
|
||
// 返回: 奖励集合与错误
|
||
ListIssueRewards(ctx context.Context, issueID int64) (items []*model.ActivityRewardSettings, err error)
|
||
// ModifyIssueReward 修改单个奖励
|
||
// 参数: rewardID 奖励ID, in 修改输入
|
||
// 返回: 错误信息
|
||
ModifyIssueReward(ctx context.Context, rewardID int64, in ModifyRewardInput) error
|
||
// DeleteIssueReward 删除单个奖励
|
||
// 参数: rewardID 奖励ID
|
||
// 返回: 错误信息
|
||
DeleteIssueReward(ctx context.Context, rewardID int64) error
|
||
|
||
// ListDrawLogs 抽奖记录列表
|
||
// 参数: issueID 期ID, page/pageSize 分页, level 等级过滤
|
||
// 返回: 抽奖记录集合、总数与错误
|
||
ListDrawLogs(ctx context.Context, issueID int64, page, pageSize int, level *int32) (items []*model.ActivityDrawLogs, total int64, err error)
|
||
|
||
// GetCategoryNames 批量查询分类名称
|
||
// 参数: ids 分类ID数组
|
||
// 返回: id->名称映射与错误
|
||
GetCategoryNames(ctx context.Context, ids []int64) (map[int64]string, error)
|
||
|
||
// CopyActivity 复制活动及其期次与奖励
|
||
// 参数: activityID 源活动ID
|
||
// 返回: 新活动ID与错误
|
||
CopyActivity(ctx context.Context, activityID int64) (int64, error)
|
||
|
||
// SaveActivityDrawConfig 保存活动开奖配置
|
||
// 参数: activityID 活动ID, cfg 配置
|
||
// 返回: 错误信息
|
||
SaveActivityDrawConfig(ctx context.Context, activityID int64, cfg DrawConfig) error
|
||
// GetActivityDrawConfig 读取活动开奖配置
|
||
// 参数: activityID 活动ID
|
||
// 返回: 配置与错误
|
||
GetActivityDrawConfig(ctx context.Context, activityID int64) (*DrawConfig, error)
|
||
|
||
// ReconstructMatchingGame 还原对对碰游戏过程
|
||
ReconstructMatchingGame(ctx context.Context, orderNo string) (*MatchingGame, error)
|
||
// GetMatchingGameFromRedis 从缓存获取游戏
|
||
GetMatchingGameFromRedis(ctx context.Context, gameID string) (*MatchingGame, error)
|
||
// SaveMatchingGameToRedis 保存游戏到缓存
|
||
SaveMatchingGameToRedis(ctx context.Context, gameID string, game *MatchingGame) error
|
||
// ListMatchingCardTypes 获取卡牌类型配置
|
||
ListMatchingCardTypes(ctx context.Context) ([]CardTypeConfig, error)
|
||
// ClearIchibanPositionsByOrderID 清理订单对应的一番赏占位
|
||
ClearIchibanPositionsByOrderID(ctx context.Context, orderID int64) error
|
||
}
|
||
|
||
type service struct {
|
||
logger logger.CustomLogger
|
||
readDB *dao.Query
|
||
writeDB *dao.Query
|
||
repo mysql.Repo
|
||
user usersvc.Service
|
||
redis *redis.Client
|
||
}
|
||
|
||
func New(l logger.CustomLogger, db mysql.Repo, u usersvc.Service, rdb *redis.Client) Service {
|
||
return &service{
|
||
logger: l,
|
||
readDB: dao.Use(db.GetDbR()),
|
||
writeDB: dao.Use(db.GetDbW()),
|
||
repo: db,
|
||
user: u,
|
||
redis: rdb,
|
||
}
|
||
}
|
||
|
||
type CreateActivityInput struct {
|
||
// Name 活动名称
|
||
Name string
|
||
// Banner 活动头图
|
||
Banner string
|
||
// Image 活动主图
|
||
Image string
|
||
// GameplayIntro 玩法介绍
|
||
GameplayIntro string
|
||
// ActivityCategoryID 活动分类ID
|
||
ActivityCategoryID int64
|
||
// Status 活动状态
|
||
Status int32
|
||
// PriceDraw 单次抽奖价格(分)
|
||
PriceDraw int64
|
||
// IsBoss 是否Boss活动
|
||
IsBoss int32
|
||
// StartTime 活动开始时间(可选)
|
||
StartTime *time.Time
|
||
// EndTime 活动结束时间(可选)
|
||
EndTime *time.Time
|
||
AllowItemCards int32
|
||
AllowCoupons int32
|
||
}
|
||
|
||
type ModifyActivityInput struct {
|
||
// Name 活动名称
|
||
Name string
|
||
// Banner 活动头图
|
||
Banner string
|
||
// Image 活动主图
|
||
Image string
|
||
// GameplayIntro 玩法介绍
|
||
GameplayIntro string
|
||
// ActivityCategoryID 活动分类ID
|
||
ActivityCategoryID int64
|
||
// Status 活动状态
|
||
Status int32
|
||
// PriceDraw 单次抽奖价格(分)
|
||
PriceDraw int64
|
||
// IsBoss 是否Boss活动
|
||
IsBoss int32
|
||
// StartTime 活动开始时间(可选)
|
||
StartTime *time.Time
|
||
// EndTime 活动结束时间(可选)
|
||
EndTime *time.Time
|
||
AllowItemCards *int32
|
||
AllowCoupons *int32
|
||
}
|
||
|
||
type ListActivitiesInput struct {
|
||
// Name 名称过滤
|
||
Name string
|
||
// CategoryID 分类过滤
|
||
CategoryID int64
|
||
// IsBoss Boss过滤
|
||
IsBoss *int32
|
||
// Status 状态过滤
|
||
Status *int32
|
||
// Page 页码
|
||
Page int
|
||
// PageSize 每页数量
|
||
PageSize int
|
||
}
|
||
|
||
type CreateIssueInput struct {
|
||
// IssueNumber 期号
|
||
IssueNumber string
|
||
// Status 状态
|
||
Status int32
|
||
// Sort 排序
|
||
Sort int32
|
||
}
|
||
|
||
type ModifyIssueInput struct {
|
||
// IssueNumber 期号
|
||
IssueNumber string
|
||
// Status 状态
|
||
Status int32
|
||
// Sort 排序
|
||
Sort int32
|
||
}
|
||
|
||
type CreateRewardInput struct {
|
||
// ProductID 商品ID
|
||
ProductID int64
|
||
// Name 奖励名称
|
||
Name string
|
||
// Weight 权重
|
||
Weight int32
|
||
// Quantity 数量(-1 表示不限)
|
||
Quantity int64
|
||
// OriginalQty 初始数量
|
||
OriginalQty int64
|
||
// Level 奖励等级
|
||
Level int32
|
||
// Sort 排序
|
||
Sort int32
|
||
// IsBoss 是否Boss奖励
|
||
IsBoss int32
|
||
MinScore int64
|
||
// DropQuantity 单次抽中产出数量(默认1)
|
||
DropQuantity int32
|
||
}
|
||
|
||
type ModifyRewardInput struct {
|
||
// ProductID 商品ID
|
||
ProductID *int64
|
||
// Name 奖励名称
|
||
Name string
|
||
// Weight 权重
|
||
Weight *float64
|
||
// Quantity 数量(-1 表示不限)
|
||
Quantity *int64
|
||
// OriginalQty 初始数量
|
||
OriginalQty *int64
|
||
// Level 奖励等级
|
||
Level *int32
|
||
// Sort 排序
|
||
Sort *int32
|
||
// IsBoss 是否Boss奖励
|
||
IsBoss *int32
|
||
MinScore *int64
|
||
// DropQuantity 单次抽中产出数量
|
||
DropQuantity *int32
|
||
}
|