package models import ( "crypto/sha512" "errors" "fmt" orm "go-admin/common/global" "go-admin/logger" "strings" "time" ) const ( RedeemCodeStatusStock = "stocking" // 库存 RedeemCodeStatusHold = "user-hold" // 用户持有 RedeemCodeStatusUsed = "used" // 已使用 ) const ( CodeTypeMemberCard30 = "member-card-30" CodeTypeMemberGoldMember = "member-card-gold-member" CodeTypeMemberPlatinumMember = "member-card-platinum-member" CodeTypeMemberBlackGoldMember = "member-card-black-gold-member" ) 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"` // CodeTypeMemberCard30 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"` // 过期时间 } func (*RedeemCode) TableName() string { return "redeem_code" } // 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-用户邀请 } func (*UserRedeemCode) TableName() string { return "user_redeem_code" } //type BindingRedeemCodeRecord struct { // Model //} // 会员兑换码 // 用户押金 // 支付押金 // 押金 // 开通会员 // 管理端 发 会员 Sign 校验 // 押金300 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] } type RedeemCodeListReq struct { PageIndex int `json:"pageIndex"` PageSize int `json:"pageSize"` Status string `json:"status" ` // user-hold used SerialCode string `json:"serial_code" ` // 兑换编码 } type RedeemCodeListResp struct { List []RedeemCode `json:"list"` PageIndex int `json:"pageIndex"` Count int `json:"count"` } func (m *RedeemCodeListReq) RedeemCodeStockList() (*RedeemCodeListResp, error) { resp := &RedeemCodeListResp{ PageIndex: m.PageIndex, } redeem := &RedeemCode{} qs := orm.Eloquent.Table(redeem.TableName()) if m.Status != "" { qs = qs.Where("status=?", m.Status) } if m.SerialCode != "" { qs = qs.Where("serial_code=?", m.SerialCode) } var count int64 err := qs.Count(&count).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) return resp, err } resp.Count = int(count) + 1 page := m.PageIndex - 1 if page < 0 { page = 0 } var redeems []RedeemCode err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&redeems).Error if err != nil && err != RecordNotFound { logger.Errorf("err:", logger.Field("err", err)) return resp, err } for i, _ := range redeems { redeems[i].CodeSecret = "" } resp.List = redeems return resp, nil } type UserRedeemCodeListReq struct { PageIndex int `json:"pageIndex"` PageSize int `json:"pageSize"` Status string `json:"status" ` // user-hold used SerialCode string `json:"serial_code" ` // 兑换编码 Uid int `json:"uid"` ConvertStart string `json:"convert_start"` ConvertEnd string `json:"convert_end"` } type UserRedeemCodeListResp struct { List []UserRedeemCodeInfo `json:"list"` PageIndex int `json:"pageIndex"` Count int `json:"count"` } type UserRedeemCodeInfo struct { UserRedeemCode WxName string `json:"wxName"` // 昵称 WxAvatar string `json:"wxAvatar"` // 头像 Tel string `json:"tel"` // 电话 } func (m *UserRedeemCodeListReq) UserSendRedeemCodeList() (*UserRedeemCodeListResp, error) { resp := &UserRedeemCodeListResp{ PageIndex: m.PageIndex, } qs := orm.Eloquent.Table("user_redeem_code").Debug() if m.Status != "" { qs = qs.Where("status=?", m.Status) } if m.SerialCode != "" { qs = qs.Where("serial_code=?", m.SerialCode) } if m.Uid != 0 { qs = qs.Where("uid=?", m.Uid) } if m.ConvertStart != "" { parse, err := time.Parse(DateTimeFormat, m.ConvertStart) if err != nil { logger.Errorf("err:", logger.Field("err", err)) return resp, err } qs = qs.Where("created_at >= ?", parse) } if m.ConvertEnd != "" { parse, err := time.Parse(DateTimeFormat, m.ConvertEnd) if err != nil { logger.Errorf("err:", logger.Field("err", err)) return resp, err } qs = qs.Where("created_at <= ?", parse) } var count int64 err := qs.Count(&count).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) return resp, err } resp.Count = int(count) page := m.PageIndex - 1 if page < 0 { page = 0 } var userRedeemCodes []UserRedeemCode err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&userRedeemCodes).Error if err != nil && err != RecordNotFound { logger.Errorf("err:", logger.Field("err", err)) return resp, err } fmt.Println("userRedeemCodes:", len(userRedeemCodes)) redeemCodeInfo := UserRedeemCodeToInfo(userRedeemCodes) resp.List = redeemCodeInfo fmt.Println("redeemCodeInfo:", len(redeemCodeInfo)) return resp, nil } func CodeSendToUser(uid, storeId uint32, codeType string) error { var redeemCode RedeemCode err := orm.Eloquent.Table("redeem_code").Where("status=?", RedeemCodeStatusStock). Where("code_type=?", codeType).Order("id ASC").Limit(1).Find(&redeemCode).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) return err } memberRedeemCode := int64(0) err = orm.Eloquent.Table("user_redeem_code").Where("uid=?", uid). Where("code_type in (?)", []string{CodeTypeMemberGoldMember, CodeTypeMemberPlatinumMember, CodeTypeMemberBlackGoldMember}).Count(&memberRedeemCode).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) return err } if memberRedeemCode > 0 && codeType != CodeTypeMemberCard30 { logger.Errorf("err:", logger.Field("err", err)) return errors.New("member_redeem_code_only") } userInfo, err := GetUserInfoByUid(uid) if err != nil { logger.Errorf("err:", logger.Field("err", err)) return err } if userInfo.MemberLevel != 1 && userInfo.MemberLevel != 3 && codeType != CodeTypeMemberCard30 { logger.Errorf("user is member:") return errors.New("user_is_member") } fmt.Println("CodeSendToUser uid:", uid) _, err = IsUserInfoByUid(uid) if err != nil { logger.Error("err:", logger.Field("err", err)) return err } begin := orm.Eloquent.Begin() sql := fmt.Sprintf("UPDATE redeem_code SET `status` ='%s',store_id=%d WHERE id =%d", RedeemCodeStatusHold, storeId, redeemCode.ID) err = begin.Exec(sql).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) begin.Rollback() return err } userRedeemCode := &UserRedeemCode{ Uid: uid, Status: UserRedeemCodeStatusHold, SerialCode: redeemCode.SerialCode, CodeType: redeemCode.CodeType, ActivityType: RedeemCodeActivityTypeStore, StoreId: storeId, } err = begin.Create(userRedeemCode).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) begin.Rollback() return err } err = begin.Commit().Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) begin.Rollback() return err } return nil } func UserRedeemCodeToInfo(userRedeems []UserRedeemCode) []UserRedeemCodeInfo { uids := make([]uint32, 0, len(userRedeems)) for i, _ := range userRedeems { uids = append(uids, userRedeems[i].Uid) } //UserInfo{} list := make([]UserRedeemCodeInfo, 0, len(userRedeems)) var users []UserInfo err := orm.Eloquent.Table("user").Where("uid in (?)", uids).Find(&users).Error if err != nil { logger.Errorf("err:", logger.Field("err", err)) return list } userMap := make(map[uint32]UserInfo, 0) for i, _ := range users { userMap[users[i].Uid] = users[i] } for i, _ := range userRedeems { userInfo, ok := userMap[userRedeems[i].Uid] if ok { info := UserRedeemCodeInfo{ UserRedeemCode: userRedeems[i], WxName: userInfo.WxName, WxAvatar: userInfo.WxAvatar, Tel: userInfo.Tel, } list = append(list, info) } } return list }