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 // 用户邀请 ) //go:generate goqueryset -in redeem_code.go // gen:qs 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"` } // gen:qs type UserRedeemCode struct { Model Uid uint32 `json:"uid" gorm:"index;comment:'用户id'"` Status string `json:"status" gorm:"index;comment:'兑换状态'"` // user-hold used 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-用户邀请 } //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) ([]UserRedeemCode, error) { var userRedeems []UserRedeemCode err := NewUserRedeemCodeQuerySet(DB).UidEq(uid).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 } holdList := make([]UserRedeemCode, 0) usedList := make([]UserRedeemCode, 0) for i, _ := range userRedeems { if userRedeems[i].Status == UserRedeemCodeStatusHold { //holdList = append(holdList, userRedeems[i]) } else { usedList = append(usedList, userRedeems[i]) } } 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 } 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 }