mh_server/model/lottery.go

238 lines
7.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"` // 奖品图片
}