238 lines
7.6 KiB
Go
238 lines
7.6 KiB
Go
package model
|
||
|
||
import (
|
||
"errors"
|
||
"math/rand"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
LotteryPrizeTypePoint = 1 // 积分奖品
|
||
LotteryPrizeTypeCoupon = 2 // 优惠券奖品
|
||
LotteryPrizeTypePhysical = 3 // 实物奖品
|
||
|
||
LotteryRecordStatusPending = 0 // 待处理
|
||
LotteryRecordStatusDelivered = 1 // 已发放
|
||
LotteryRecordStatusInProcess = 2 // 处理中
|
||
LotteryRecordStatusFailed = 3 // 失败
|
||
|
||
LotteryPrizeStatusEnabled = 1 // 启用奖品
|
||
LotteryPrizeStatusDisabled = 2 // 禁用奖品
|
||
|
||
LotteryPrizeTypeNone = 0 // 谢谢参与
|
||
)
|
||
|
||
// LotteryPrize 奖品信息表(抽奖)
|
||
type LotteryPrize struct {
|
||
Model
|
||
|
||
Name string `json:"name"` // 奖品名称
|
||
PrizeType int `json:"prize_type"` // 奖品类型:1-积分 2-优惠券 3-实物 0-谢谢参与
|
||
PrizeValue int `json:"prize_value"` // 奖品值(积分数或券ID等)
|
||
Level int `json:"level"` // 奖品等级,如1等奖、2等奖等
|
||
Weight int `json:"weight"` // 抽奖权重
|
||
Stock int `json:"stock"` // 剩余库存
|
||
Status int `json:"status"` // 奖品状态:1-启用 2-禁用
|
||
UnlockUserCount int `json:"unlock_user_count"` // 解锁条件:用户个人抽奖次数
|
||
UnlockTotalCount int `json:"unlock_total_count"` // 解锁条件:所有用户总抽奖次数
|
||
Images string `json:"images"` // 奖品图片
|
||
}
|
||
|
||
// LotteryRecord 抽奖记录
|
||
type LotteryRecord struct {
|
||
Model
|
||
|
||
Uid uint `json:"uid"` // 用户ID
|
||
PrizeId uint `json:"prize_id"` // 奖品ID
|
||
PrizeName string `json:"prize_name"` // 奖品名称
|
||
PrizeType int `json:"prize_type"` // 奖品类型
|
||
PrizeLevel int `json:"prize_level"` // 奖品等级
|
||
PrizeValue int `json:"prize_value"` // 奖品值(积分数或券ID等)
|
||
Status int `json:"status"` // 状态:0-待处理 1-已发放 2-处理中 3-失败
|
||
IsWin bool `json:"is_win"` // 是否中奖(false 表示“谢谢参与”等无奖项)
|
||
Images string `json:"images" gorm:"-"` // 奖品图片
|
||
}
|
||
|
||
// LotteryPrizeOrder 抽奖奖品订单(包含用户收件信息、物流信息、发货状态)
|
||
type LotteryPrizeOrder struct {
|
||
Model
|
||
|
||
RecordId uint `json:"record_id"` // 抽奖记录ID
|
||
Uid uint `json:"uid"` // 用户ID
|
||
Tel string `json:"tel"` // 用户手机号
|
||
PrizeId uint `json:"prize_id"` // 奖品ID
|
||
PrizeName string `json:"prize_name"` // 奖品名称
|
||
|
||
// 用户提交的收货信息
|
||
ReceiverName string `json:"receiver_name"` // 收件人
|
||
ReceiverPhone string `json:"receiver_phone"` // 收件人手机号
|
||
ReceiverAddr string `json:"receiver_addr"` // 收件地址
|
||
|
||
// 发货信息
|
||
LogisticsCompany string `json:"logistics_company"` // 快递公司
|
||
LogisticsNumber string `json:"logistics_number"` // 快递单号
|
||
ShippedAt time.Time `json:"shipped_at"` // 发货时间
|
||
ReceivedAt time.Time `json:"received_at"` // 收货时间
|
||
|
||
Status int `json:"status"` // 发货状态:0-待发货 1-已发货 2-已收货 3-取消
|
||
}
|
||
|
||
// LotteryStats 抽奖统计表
|
||
type LotteryStats struct {
|
||
Model
|
||
|
||
TotalDraw uint `json:"total_draw"` // 总抽奖数
|
||
}
|
||
|
||
// LotteryWhiteList 抽奖白名单表
|
||
type LotteryWhiteList struct {
|
||
Model
|
||
|
||
Uid uint `json:"uid"` // 用户ID
|
||
DrawNumber uint `json:"draw_number"` // 第几次抽奖命中(如第3次)
|
||
PrizeID uint `json:"prize_id"` // 奖品ID(外键指向 LotteryPrize)
|
||
}
|
||
|
||
type LotteryDrawResponse struct {
|
||
PrizeID int `json:"prize_id"` // 奖品id
|
||
PrizeName string `json:"prize_name"` // 奖品名称
|
||
PrizeLevel int `json:"prize_level"` // 奖品等级
|
||
Message string `json:"message"` // 中奖提示信息
|
||
}
|
||
|
||
type LotteryPrizeQuery struct {
|
||
PageNum int `json:"page_num"`
|
||
PageSize int `json:"page_size"`
|
||
}
|
||
|
||
type LotteryPrizePageResponse struct {
|
||
Count uint32 `json:"count"` // 奖品总数
|
||
PageNum int `json:"page_num"` // 当前页码
|
||
List []LotteryPrize `json:"list"` // 奖品列表
|
||
}
|
||
|
||
type LotteryRecordQuery struct {
|
||
PageNum int `json:"page_num"`
|
||
PageSize int `json:"page_size"`
|
||
WinStatus int `json:"win_status"` // 新增字段:0=全部,1=已中奖,2=未中奖
|
||
}
|
||
|
||
type LotteryRecordPageResponse struct {
|
||
Count uint32 `json:"count"` // 总记录数
|
||
PageNum int `json:"page_num"` // 当前页码
|
||
List []LotteryRecord `json:"list"` // 抽奖记录列表
|
||
}
|
||
|
||
func DrawFromDatabasePrizes(prizes []LotteryPrize, userDrawCount, globalDrawCount int) (LotteryPrize, error) {
|
||
var available []LotteryPrize
|
||
totalWeight := 0
|
||
|
||
for _, p := range prizes {
|
||
// 同时满足两个解锁条件才可参与抽奖
|
||
if userDrawCount >= p.UnlockUserCount && globalDrawCount >= p.UnlockTotalCount {
|
||
available = append(available, p)
|
||
totalWeight += p.Weight
|
||
}
|
||
}
|
||
|
||
if totalWeight == 0 {
|
||
return LotteryPrize{}, errors.New("无可抽奖奖品")
|
||
}
|
||
|
||
r := rand.Intn(totalWeight)
|
||
acc := 0
|
||
for _, p := range available {
|
||
acc += p.Weight
|
||
if r < acc {
|
||
return p, nil
|
||
}
|
||
}
|
||
|
||
return LotteryPrize{}, errors.New("抽奖失败")
|
||
}
|
||
|
||
func getUnlockDrawCount(level int) int {
|
||
switch level {
|
||
case 1:
|
||
return 5000
|
||
case 2:
|
||
return 2000
|
||
case 3:
|
||
return 1000
|
||
case 4:
|
||
return 500
|
||
default:
|
||
return 0
|
||
}
|
||
}
|
||
|
||
// IncrementTotalDraw 更新总抽奖数
|
||
func IncrementTotalDraw() error {
|
||
return DB.Exec("UPDATE lottery_stats SET total_draw = total_draw + 1 WHERE id = 1").Error
|
||
}
|
||
|
||
// GetLotteryDrawStats 查询某个用户的抽奖次数和全站总抽奖次数
|
||
func GetLotteryDrawStats(uid uint32) (userDrawCount int, totalDrawCount int, err error) {
|
||
// 查询用户抽奖次数
|
||
err = DB.Model(&LotteryRecord{}).
|
||
Where("uid = ?", uid).
|
||
Count(&userDrawCount).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 查询总抽奖次数(从 lottery_stats 表)
|
||
var stats LotteryStats
|
||
err = DB.First(&stats).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
totalDrawCount = int(stats.TotalDraw)
|
||
return
|
||
}
|
||
|
||
type RecentWinnersQuery struct {
|
||
Limit int `json:"limit"` // 期望获取的记录数
|
||
}
|
||
|
||
type RecentWinnersResponse struct {
|
||
Count uint32 `json:"count"` // 实际中奖总数
|
||
List []LotteryRecord `json:"list"` // 最近中奖记录列表
|
||
}
|
||
|
||
type SubmitDeliveryRequest struct {
|
||
RecordId uint `json:"record_id" binding:"required"` // 抽奖记录ID,必填
|
||
ReceiverName string `json:"receiver_name" binding:"required"` // 收件人姓名,必填
|
||
ReceiverPhone string `json:"receiver_phone" binding:"required"` // 收件人手机号,必填
|
||
ReceiverAddr string `json:"receiver_addr" binding:"required"` // 收件人地址,必填
|
||
}
|
||
|
||
type ConfirmReceiptRequest struct {
|
||
RecordId uint `json:"record_id" binding:"required"` // 抽奖记录ID,必填
|
||
}
|
||
|
||
type TodayDrawCountResponse struct {
|
||
DrawCount int `json:"draw_count"` // 今日抽奖次数
|
||
}
|
||
|
||
type GetLotteryPrizeOrderDetailRequest struct {
|
||
OrderID uint `json:"order_id" binding:"required"` // 奖品订单ID
|
||
}
|
||
|
||
type LotteryPrizeOrderDetailResponse struct {
|
||
LotteryPrizeOrder
|
||
|
||
// 用户信息
|
||
Nickname string `json:"nickname"` // 用户昵称
|
||
Tel string `json:"tel"` // 用户手机号
|
||
MemberLevel uint32 `json:"member_level"` // 当前会员等级
|
||
StoreName string `json:"store_name"` // 所属门店
|
||
|
||
// 奖品信息(扩展字段)
|
||
PrizeType int `json:"prize_type"` // 奖品类型
|
||
PrizeLevel int `json:"prize_level"` // 奖品等级
|
||
PrizeValue int `json:"prize_value"` // 奖品值
|
||
Images string `json:"images"` // 奖品图片
|
||
}
|