mh_server/model/redeem_code.go

372 lines
10 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 (
"crypto/sha512"
"errors"
"fmt"
"github.com/codinl/go-logger"
"strings"
"time"
)
const (
RedeemCodeStatusStock = "stocking" // 库存
RedeemCodeStatusHold = "user-hold" // 用户持有
RedeemCodeStatusUsed = "used" // 已使用
)
const (
CodeTypeMemberCard30 = "member-card-30" // 会员卡 30天
CodeTypeMemberGoldMember = "member-card-gold-member"
CodeTypeMemberPlatinumMember = "member-card-platinum-member"
CodeTypeMemberBlackGoldMember = "member-card-black-gold-member"
CodeTypeDeductionCoupon5 = "deduction-coupon-5"
)
const (
RedeemCodeSecretKey = "046033a527d1b723ed0a1012e6518d490"
)
const (
UserRedeemCodeStatusHold = "user-hold"
UserRedeemCodeStatusUsed = "used"
)
const (
RedeemCodeActivityTypeStore = 1 // 门店赠送
RedeemCodeActivityTypeUserInvite = 2 // 用户邀请
)
// gen:qs
//
//go:generate goqueryset -in redeem_code.go
type RedeemCode struct {
Model
SerialCode string `json:"serial_code" gorm:"index;comment:'兑换编码'"` // 兑换编码
CodeType string `json:"code_type"` // memberCard
Status string `json:"status" gorm:"index;comment:'兑换状态'"` // stocking user-hold used
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
CodeSecret string `json:"code_secret"` // 兑换密码
EffectiveTime time.Time `json:"effective_time"` // 生效时间
ExpirationTime time.Time `json:"expiration_time"` // 过期时间
CouponId uint32 `json:"coupon_id" gorm:"index"`
//Remark string `json:"remark"`
}
const (
UserRedeemCodeStatsExpired = "expired"
)
// gen:qs
type UserRedeemCode struct {
Model
Uid uint32 `json:"uid" gorm:"index;comment:'用户id'"`
Status string `json:"status" gorm:"index;comment:'兑换状态'"` // user-hold used expired
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
SerialCode string `json:"serial_code" gorm:"index;comment:'兑换编码'"` // 兑换编码
CodeType string `json:"code_type"` // memberCard
ConvertTime time.Time `json:"convert_time"` // 绑定时间
ActivityType uint32 `json:"activity_type"` // 1-门店赠送 2-用户邀请
ExpiredTime time.Time `json:"expired_time"` // 过期时间:
}
//type BindingRedeemCodeRecord struct {
// Model
//}
// 会员兑换码
// 用户押金
// 支付押金
// 押金
// 开通会员
// 管理端 发 会员 Sign 校验
func RedeemSecretCode(redeem string) string {
semen := redeem[:13] + strings.ToUpper(RedeemCodeSecretKey)
shaer := sha512.New()
shaer.Write([]byte(semen))
r := shaer.Sum(nil)
hs := fmt.Sprintf("%x", r)
return hs[:7]
}
func UserRedeemCodeList(uid uint32, status string) ([]UserRedeemCode, error) {
var userRedeems []UserRedeemCode
qs := NewUserRedeemCodeQuerySet(DB).UidEq(uid)
//if status != "" {
//}
if status == UserRedeemCodeStatsExpired {
qs = qs.StatusEq(status)
} else {
qs = qs.StatusNe(UserRedeemCodeStatsExpired)
}
err := qs.OrderDescByID().All(&userRedeems)
if err != nil && err != RecordNotFound {
logger.Error("user redeem code err:", err)
return userRedeems, err
}
if len(userRedeems) == 0 {
return userRedeems, nil
}
nowTime := time.Now()
holdList := make([]UserRedeemCode, 0)
usedList := make([]UserRedeemCode, 0)
expiredIds := make([]uint32, 0)
for i, _ := range userRedeems {
if userRedeems[i].ExpiredTime.Year() == 1 {
userRedeems[i].ExpiredTime = userRedeems[i].CreatedAt.AddDate(1, 0, 0)
}
if userRedeems[i].Status == UserRedeemCodeStatusHold {
holdList = append(holdList, userRedeems[i])
if userRedeems[i].CreatedAt.AddDate(1, 0, 0).Before(nowTime) {
expiredIds = append(expiredIds, userRedeems[i].ID)
}
} else {
usedList = append(usedList, userRedeems[i])
}
}
if len(expiredIds) != 0 {
err = NewUserRedeemCodeQuerySet(DB).IDIn(expiredIds...).GetUpdater().
SetStatus(UserRedeemCodeStatsExpired).Update()
if err != nil {
logger.Error("updater user redeem code status err:", err)
}
}
return append(holdList, usedList...), nil
}
// 会员兑换码兑换
func UserRedeemCodeConvert(uid uint32, serialCode string) error {
var userRedeem UserRedeemCode
err := NewUserRedeemCodeQuerySet(DB).UidEq(uid).SerialCodeEq(serialCode).One(&userRedeem)
if err != nil {
logger.Error("user redeem code err:", err)
return err
}
if userRedeem.Status != UserRedeemCodeStatusHold {
return errors.New("user redeem code not exist")
}
begin := DB.Begin()
num, err := NewRedeemCodeQuerySet(begin).SerialCodeEq(serialCode).GetUpdater().SetStatus(RedeemCodeStatusUsed).UpdateNum()
if err != nil {
logger.Error("user redeem code err:", err)
begin.Rollback()
return err
}
if num == 0 {
logger.Error("num is 0 err:")
begin.Rollback()
return err
}
//qsUserRedeem := NewUserRedeemCodeQuerySet(begin).UidEq(uid).SerialCodeEq(serialCode).GetUpdater()
//if userRedeem.CodeType == CodeTypeMemberGoldMember {
// //qsUserRedeem = qsUserRedeem.SetCodeType()
//}
updateNum, err := NewUserRedeemCodeQuerySet(begin).UidEq(uid).SerialCodeEq(serialCode).GetUpdater().
SetStatus(UserRedeemCodeStatusUsed).SetConvertTime(time.Now()).UpdateNum()
if err != nil {
logger.Error("user redeem code err:", err)
begin.Rollback()
return err
}
if updateNum == 0 {
logger.Error("num is 0 err:")
begin.Rollback()
return err
}
user := GetUserByUid(uid)
qs := NewUserQuerySet(begin).UidEq(uid).GetUpdater()
if user.MemberLevel != 1 && user.MemberLevel != 3 &&
userRedeem.CodeType != CodeTypeMemberCard30 {
logger.Error("code type used by consumer:")
begin.Rollback()
return errors.New("code type used by consumer")
}
addDates := 0
memberLevel := uint32(0)
switch userRedeem.CodeType {
case CodeTypeMemberCard30:
addDates = 30
memberLevel = 3
case CodeTypeMemberGoldMember:
addDates = 365
memberLevel = 2
qs = qs.SetMemberLevel(MemberLevelGold).SetOpenMemberTime(time.Now()).SetOpenMemberChannel(OpenMemberChannelRedeemCode)
case CodeTypeMemberPlatinumMember:
addDates = 365
memberLevel = 4
qs = qs.SetMemberLevel(MemberLevelPlatinum).SetOpenMemberTime(time.Now()).SetOpenMemberChannel(OpenMemberChannelRedeemCode)
case CodeTypeMemberBlackGoldMember:
addDates = 365
memberLevel = 5
qs = qs.SetMemberLevel(MemberLevelBlackGold).SetOpenMemberTime(time.Now()).SetOpenMemberChannel(OpenMemberChannelRedeemCode)
default:
logger.Error(" code type err:", err)
begin.Rollback()
return err
}
if user.MemberExpire.After(time.Now()) {
qs = qs.SetMemberExpire(user.MemberExpire.AddDate(0, 0, addDates))
} else {
qs = qs.SetMemberExpire(time.Now().AddDate(0, 0, addDates))
}
if user.MemberLevel == 1 || user.MemberLevel == 3 {
qs = qs.SetMemberLevel(memberLevel)
}
userNum, err := qs.UpdateNum()
if err != nil {
logger.Error("user redeem code err:", err)
begin.Rollback()
return err
}
if userNum == 0 {
logger.Error("num is 0 err:")
begin.Rollback()
return err
}
err = begin.Commit().Error
if err != nil {
logger.Error("user redeem code err:", err)
begin.Rollback()
return err
}
return nil
}
func CodeSendToUser(uid uint32, codeType string, activityType uint32) error {
count, err := NewUserRedeemCodeQuerySet(DB).UidEq(uid).Count()
if err != nil {
logger.Error("err:", err)
return err
}
if count > 24 {
logger.Error("redeem code limit 24")
return errors.New("redeem code limit 24")
}
var redeemCode RedeemCode
err = NewRedeemCodeQuerySet(DB).StatusEq(RedeemCodeStatusStock).CodeTypeEq(codeType).Limit(1).One(&redeemCode)
if err != nil {
logger.Errorf("err:%#v", err)
return err
}
begin := DB.Begin()
sql := fmt.Sprintf("UPDATE redeem_code SET `status` ='%s' WHERE id =%d", RedeemCodeStatusHold, redeemCode.ID)
err = begin.Exec(sql).Error
if err != nil {
logger.Errorf("err:%#v", err)
begin.Rollback()
return err
}
userRedeemCode := &UserRedeemCode{
Uid: uid,
Status: UserRedeemCodeStatusHold,
SerialCode: redeemCode.SerialCode,
CodeType: redeemCode.CodeType,
ActivityType: activityType,
//ActivityType: RedeemCodeActivityTypeUserInvite,
}
err = begin.Create(userRedeemCode).Error
if err != nil {
logger.Errorf("err:%#v", err)
begin.Rollback()
return err
}
err = begin.Commit().Error
if err != nil {
logger.Errorf("err:%#v", err)
begin.Rollback()
return err
}
return nil
}
func SendUserVm(uid, memberLevel, inviteLevel uint32) error {
if memberLevel == 3 {
return nil
}
config, err := GetMemberVmConfig(memberLevel)
if err != nil {
logger.Error("err:", err)
return err
}
amount := 0
describe := ""
event := ""
if inviteLevel == 0 {
amount = int(config.MemberVm)
describe = "开通会员奖励"
event = VmEventOpenMember
} else if inviteLevel == 1 {
amount = int(config.Invite1Vm)
describe = "邀请会员奖励"
event = VmEventInvite1Member
} else if inviteLevel == 2 {
amount = int(config.Invite2Vm)
describe = "邀请会员奖励"
event = VmEventInvite2Member
} else if inviteLevel == 100 {
amount = int(config.AutomationMemberVm)
describe = "开通会员奖励"
event = VmEventOpenMember
}
err = UserVmUpdate(uid, amount, event, describe)
if err != nil {
logger.Error("err:", err)
return err
}
return nil
}
// NewSendUserVm 会员积分:开通会员、续费/升级会员积分规则为1:1邀请不再有积分
func NewSendUserVm(uid, nAmount, nType uint32) error {
describe := ""
event := ""
if nType == 2 { // 开通会员
describe = "开通会员"
event = VmEventOpenMember
} else if nType == 3 { // 续费会员
describe = "续费/升级会员"
event = VmEventRenewMember
} else if nType == 4 { // 升级会员
describe = "续费/升级会员"
event = VmEventUpgradeMember
} else {
logger.Errorf("err:", "记录会员积分失败nType类型错误为%d", nType)
return errors.New("记录会员积分失败")
}
err := UserVmUpdate(uid, int(nAmount), event, describe)
if err != nil {
logger.Error("err:", err)
return err
}
return nil
}
func GetUserRenewalCouponIds() ([]uint32, error) {
ids := make([]uint32, 0)
var coupons []Coupon
err := NewCouponQuerySet(DB).ActivityIdEq(1).All(&coupons)
if err != nil {
logger.Error("coupons err:", err)
return ids, err
}
for i, _ := range coupons {
ids = append(ids, coupons[i].ID)
}
return ids, nil
}