372 lines
10 KiB
Go
372 lines
10 KiB
Go
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
|
||
}
|