diff --git a/controller/account.go b/controller/account.go index d3036f9..2f3ded6 100644 --- a/controller/account.go +++ b/controller/account.go @@ -544,6 +544,14 @@ func UserData(c *gin.Context) { m.RoleName = roleInfo.RoleName } + // 查询最近一条邀请记录 + var inviteRecord model.UserInviteRecord + err = model.NewUserInviteRecordQuerySet(model.DB).ToUidEq(uc.Uid).OrderDescByCreatedAt().OrderDescByID().Limit(1).Find(&inviteRecord) + if err != nil { + logger.Error(err) + } + m.LatestInviteRecord = inviteRecord + ret := m RespOK(c, ret) return @@ -810,7 +818,7 @@ func UserCodeToCoupon(c *gin.Context) { } var inviteUid, inviteStoreId, userMemberLevel uint32 - if len(req.Code) == 6 { + if len(req.Code) == 6 { // 续费优惠券 user := model.GetUserByUid(uc.Uid) if user == nil { logger.Error("user is nil") @@ -836,7 +844,7 @@ func UserCodeToCoupon(c *gin.Context) { err := model.NewShopperPromotionCodeQuerySet(model.DB).CodeEq(req.Code).One(&shopperPromotionCode) if err != nil { logger.Error("shopper promotion code err:", err) - RespJson(c, status.InternalServerError, nil) + RespJson(c, status.NotAvailableCode, nil) return } inviteUid = shopperPromotionCode.Uid @@ -1012,6 +1020,79 @@ func UserCodeToCoupon(c *gin.Context) { } } + RespOK(c, nil) + return + } else if len(req.Code) == 8 { // 开通优惠券(新店开业可用) + user := model.GetUserByUid(uc.Uid) + if user == nil { + logger.Error("user is nil") + RespJson(c, status.Unauthorized, nil) + return + } + + userMemberLevel = user.MemberLevel + if !user.OpenMemberTime.IsZero() || !user.MemberExpire.IsZero() || user.IsMember() { // 判断用户是否为新用户 + logger.Error("user is not new user") + RespJson(c, status.NotNewUser, nil) + return + } + + var shopperPromotionCode model.ShopperPromotionCode + err := model.NewShopperPromotionCodeQuerySet(model.DB).CodeEq(req.Code).One(&shopperPromotionCode) + if err != nil { + logger.Error("shopper promotion code err:", err) + RespJson(c, status.NotAvailableCode, nil) + return + } + logger.Error("shopper promotion code store is:", shopperPromotionCode.StoreId) + logger.Error("user store is:", user.StoreId) + + exist, err := model.QueryRecordExist(fmt.Sprintf( + "SELECT * FROM user_coupon WHERE uid=%d AND approach=1 AND activity_id=4 AND state=1", uc.Uid)) + if err != nil { + logger.Error("exist err:", err) + RespJson(c, status.InternalServerError, nil) + return + } + if exist { + logger.Error("coupon received err:", err) + RespJson(c, status.CouponReceived, nil) + return + } + + var coupons []model.Coupon + err = model.NewCouponQuerySet(model.DB).ActivityIdEq(4).All(&coupons) + if err != nil { + logger.Error("coupons err:", err) + RespJson(c, status.InternalServerError, nil) + return + } + + for i, _ := range coupons { + userCoupon := &model.UserCoupon{ + Uid: uc.Uid, + CouponId: coupons[i].ID, + CouponType: coupons[i].CouponType, + ActivityType: coupons[i].ActivityType, + ActivityId: coupons[i].ActivityId, + Value: coupons[i].Value, + State: 1, + ActiveStart: time.Now(), + ActiveEnd: time.Now().AddDate(0, 0, 7), + UseTime: time.Time{}, + MemberLevel: coupons[i].MemberLevel, + Approach: 1, + PromotionalSales: 0, + RedeemCode: shopperPromotionCode.Code, + } + + err = model.DB.Create(userCoupon).Error + if err != nil { + logger.Error("user coupon err:", err) + continue + } + } + RespOK(c, nil) return } @@ -1019,12 +1100,12 @@ func UserCodeToCoupon(c *gin.Context) { err := model.NewRedeemCodeQuerySet(model.DB).SerialCodeEq(req.Code).One(&redeemCode) if err != nil { logger.Error("redeem code err:", err) - RespJson(c, status.InternalServerError, nil) + RespJson(c, status.NotAvailableCode, nil) return } if req.Code != "DC5709BC7375B9F5FA89D0" && redeemCode.Status != model.RedeemCodeStatusHold { logger.Error("redeem code status err") - RespJson(c, status.InternalServerError, nil) + RespJson(c, status.NotAvailableCode, nil) return } diff --git a/controller/activity.go b/controller/activity.go index ce0da7d..15ba369 100644 --- a/controller/activity.go +++ b/controller/activity.go @@ -600,6 +600,22 @@ func MemberRenewalUserCouponList(c *gin.Context) { if user.MemberGenre == 201 || user.MemberGenre == 202 { coupons[i].Availability = 1 } + var shopperPromotionCode model.ShopperPromotionCode + err = model.NewShopperPromotionCodeQuerySet(model.DB).CodeEq(coupons[i].RedeemCode).One(&shopperPromotionCode) + if err != nil { + logger.Error(err) + } + coupons[i].StoreId = shopperPromotionCode.StoreId + + var couponInfo model.Coupon + err = model.NewCouponQuerySet(model.DB).IDEq(coupons[i].CouponId).One(&couponInfo) + if err != nil { + logger.Error("coupons err:", err) + RespJson(c, status.InternalServerError, nil) + return + } + coupons[i].Coupon = &couponInfo + list = append(list, coupons[i]) } diff --git a/controller/user.go b/controller/user.go index 861e033..639be9f 100644 --- a/controller/user.go +++ b/controller/user.go @@ -269,9 +269,7 @@ func OpenMember(c *gin.Context) { return } - // 用户已开通会员且优惠券可用 - //if user.IsMember() && coupon.Uid == uc.Uid && coupon.MemberLevel == req.MemberLevel && - // coupon.ActivityId == 1 && coupon.State == 1 { + // 使用续费优惠券:用户已开通会员(开通会员时间不为空)、优惠券可用 if !user.OpenMemberTime.IsZero() && coupon.Uid == uc.Uid && coupon.MemberLevel == req.MemberLevel && coupon.ActivityId == 1 && coupon.State == 1 { totalFee -= coupon.Value @@ -298,6 +296,32 @@ func OpenMember(c *gin.Context) { _ = userLog.Add() }() } + } else if user.OpenMemberTime.IsZero() && coupon.Uid == uc.Uid && coupon.MemberLevel == req.MemberLevel && + coupon.ActivityId == 4 && coupon.State == 1 { // 使用开通优惠券:用户未开通过会员(开通会员时间为空),优惠券可用 + // 判断最近一条邀请记录,邀请人的门店id跟优惠券id相同才能使用 + var inviteRecord model.UserInviteRecord + err = model.NewUserInviteRecordQuerySet(model.DB).ToUidEq(user.Uid).OrderDescByCreatedAt().OrderDescByID().Limit(1).Find(&inviteRecord) + if err != nil || inviteRecord.ID == 0 { + RespJson(c, status.NotShopperCodeStoreUser, nil) + return + } + + var shopperPromotionCode model.ShopperPromotionCode + err := model.NewShopperPromotionCodeQuerySet(model.DB).CodeEq(coupon.RedeemCode).One(&shopperPromotionCode) + if err != nil { + logger.Error("shopper promotion code err:", err) + RespJson(c, status.NotShopperCodeStoreUser, nil) + return + } + + if shopperPromotionCode.StoreId != uint32(inviteRecord.StoreId) { + logger.Error("shopper promotion code err:", err) + RespJson(c, status.NotShopperCodeStoreUser, nil) + return + } + + logger.Infof("使用开通优惠券,coupon_id is:", coupon.CouponId) + totalFee -= coupon.Value } else if coupon.State == 1 && coupon.ActivityType == 2 { // 关注公众号领取的优惠券 totalFee -= coupon.Value } else { // 不符合优惠条件 diff --git a/lib/status/status.go b/lib/status/status.go index b15d954..1690dd2 100644 --- a/lib/status/status.go +++ b/lib/status/status.go @@ -112,6 +112,9 @@ const ( DepositRestraint = 500527 // 押金受限 ShortMemberNotUpgradeMember = 500530 // 短期会员暂不升级 ThePhoneHasBeenRegistered = 500531 // 该手机号已经注册账号 + NotNewUser = 500532 // 您不是新用户,请领取续费优惠券 + NotShopperCodeStoreUser = 500533 // 您不是推广门店用户,请扫店员推广码后再使用优惠券 + NotAvailableCode = 500534 // 兑换码错误 ToastErr = 600 // 报错 ) @@ -274,6 +277,10 @@ var statusMsg = map[int]string{ RedirectBindPhonePage: "需要绑定手机号", ThePhoneHasBeenRegistered: "该手机号已经注册账号", + + NotNewUser: "您不是新用户,请领取续费优惠券", + NotShopperCodeStoreUser: "您不是推广门店用户,请扫店员推广码后再使用优惠券", + NotAvailableCode: "兑换码错误", } func StatusDesc(code int) string { diff --git a/model/autogenerated_invite.go b/model/autogenerated_invite.go index d25d785..d95a246 100644 --- a/model/autogenerated_invite.go +++ b/model/autogenerated_invite.go @@ -1475,6 +1475,10 @@ func (qs UserInviteRecordQuerySet) Offset(offset int) UserInviteRecordQuerySet { return qs.w(qs.db.Offset(offset)) } +func (qs UserInviteRecordQuerySet) Find(ret *UserInviteRecord) error { + return qs.db.Find(ret).Error +} + // One is used to retrieve one result. It returns gorm.ErrRecordNotFound // if nothing was fetched func (qs UserInviteRecordQuerySet) One(ret *UserInviteRecord) error { diff --git a/model/coupon.go b/model/coupon.go index 9f9fa9e..d11da7e 100644 --- a/model/coupon.go +++ b/model/coupon.go @@ -28,7 +28,7 @@ type Coupon struct { Name string `json:"name"` Describe string `json:"describe" gorm:"type:text;"` // 描述 CouponType string `json:"coupon_type"` - ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费 2-关注公众号 3-运费包 + ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费 2-关注公众号 3-运费包 4-开通会员(2024/7/17新增) ActivityId uint32 `json:"activity_id" gorm:"index"` Value uint32 `json:"value"` OutCount uint32 `json:"out_count"` // 用户已领取数量 @@ -58,6 +58,7 @@ type UserCoupon struct { Approach uint32 `json:"approach"` // 获取途径:1-通过店员兑换码获取 PromotionalSales uint32 `json:"promotional_sales"` // 推广人员用户id RedeemCode string `json:"redeem_code"` // + StoreId uint32 `json:"store_id" gorm:"-"` // 邀请码对应门店id Availability uint32 `json:"availability" gorm:"-"` // 1-不可用 2-可用 Coupon *Coupon `json:"coupon" gorm:"-"` } diff --git a/model/user.go b/model/user.go index beca40c..dcddf10 100644 --- a/model/user.go +++ b/model/user.go @@ -21,45 +21,46 @@ import ( type User struct { Model - Uid uint32 `json:"uid" gorm:"column:uid;unique_index"` - MemberLevel uint32 `json:"member_level"` // 当前会员等级:10-普通用户 1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 - MemberGenre uint32 `json:"member_genre"` // 会员类型 - MemberExpire time.Time `json:"member_expire"` // 会员到期时间 - OpenMemberTime time.Time `json:"open_member_time"` // 开通会员 - Bond uint32 `json:"bond"` // 保证金 - WxName string `json:"wx_name"` // 昵称 - WxAvatar string `json:"wx_avatar"` // 头像 - WxOpenID string `json:"wx_open_id"` // 微信openid - AppOpenID string `json:"app_open_id"` // - WxUnionID string `json:"wx_union_id"` // 微信uniodid - Tel string `json:"tel"` // 电话 - Gender uint8 `json:"gender"` // 性别 - City string `json:"city"` // 城市 - Province string `json:"province"` // 省 - Country string `json:"country"` // 市 - Deposit uint32 `json:"deposit"` // 押金 - UserType uint32 `json:"user_type"` // 用户类型: 1-普通用户 2-店员 - XcxRoleId uint32 `json:"xcx_role_id"` // 角色id - OpenMemberChannel string `json:"open_member_channel" ` // 开通会员渠道: -门店推广 -用户邀请 -兑换码 - StoreId uint64 `json:"store_id"` // 门店id - InviteCodeUrl string `json:"invite_code_url"` // 分享二维码 - LastLoginAt time.Time `json:"last_login_at"` // 最近登录时间 - IP string `json:"-" gorm:"type:varchar(60)"` // ip - InBlack bool `json:"in_black"` // 是否在黑名单 - StoreType uint32 `json:"store_type"` // 1-订单门店 - CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id - CooperativeName string `json:"cooperative_name"` // 合作商名称 - ShopAssistantName string `json:"shop_assistant_name"` // 店员名称 - OpenMemberLevel uint32 `json:"open_member_level"` // 开通会员级别:2-黄金会员 4-白金会员 5-黑金会员 - FirstRetailOrder time.Time `json:"first_retail_order"` // - Version uint32 `json:"-"` // - UserVm *UserVm `json:"user_vm" gorm:"-"` // - InviteTime time.Time `json:"invite_time"` // - DepositType uint32 `json:"deposit_type"` // 押金类型: 3-未充值 - StoreList []StoreInfo `gorm:"-" json:"store_list"` // 有效门店列表 - RoleId uint32 `json:"role_id" gorm:"-"` // 角色id - RoleKey string `json:"role_key" gorm:"-"` // 角色代码 - RoleName string `json:"role_name" gorm:"-"` // 角色名称 + Uid uint32 `json:"uid" gorm:"column:uid;unique_index"` + MemberLevel uint32 `json:"member_level"` // 当前会员等级:10-普通用户 1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 + MemberGenre uint32 `json:"member_genre"` // 会员类型 + MemberExpire time.Time `json:"member_expire"` // 会员到期时间 + OpenMemberTime time.Time `json:"open_member_time"` // 开通会员 + Bond uint32 `json:"bond"` // 保证金 + WxName string `json:"wx_name"` // 昵称 + WxAvatar string `json:"wx_avatar"` // 头像 + WxOpenID string `json:"wx_open_id"` // 微信openid + AppOpenID string `json:"app_open_id"` // + WxUnionID string `json:"wx_union_id"` // 微信uniodid + Tel string `json:"tel"` // 电话 + Gender uint8 `json:"gender"` // 性别 + City string `json:"city"` // 城市 + Province string `json:"province"` // 省 + Country string `json:"country"` // 市 + Deposit uint32 `json:"deposit"` // 押金 + UserType uint32 `json:"user_type"` // 用户类型: 1-普通用户 2-店员 + XcxRoleId uint32 `json:"xcx_role_id"` // 角色id + OpenMemberChannel string `json:"open_member_channel" ` // 开通会员渠道: -门店推广 -用户邀请 -兑换码 + StoreId uint64 `json:"store_id"` // 门店id + InviteCodeUrl string `json:"invite_code_url"` // 分享二维码 + LastLoginAt time.Time `json:"last_login_at"` // 最近登录时间 + IP string `json:"-" gorm:"type:varchar(60)"` // ip + InBlack bool `json:"in_black"` // 是否在黑名单 + StoreType uint32 `json:"store_type"` // 1-订单门店 + CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id + CooperativeName string `json:"cooperative_name"` // 合作商名称 + ShopAssistantName string `json:"shop_assistant_name"` // 店员名称 + OpenMemberLevel uint32 `json:"open_member_level"` // 开通会员级别:2-黄金会员 4-白金会员 5-黑金会员 + FirstRetailOrder time.Time `json:"first_retail_order"` // + Version uint32 `json:"-"` // + UserVm *UserVm `json:"user_vm" gorm:"-"` // + InviteTime time.Time `json:"invite_time"` // + DepositType uint32 `json:"deposit_type"` // 押金类型: 3-未充值 + StoreList []StoreInfo `gorm:"-" json:"store_list"` // 有效门店列表 + RoleId uint32 `json:"role_id" gorm:"-"` // 角色id + RoleKey string `json:"role_key" gorm:"-"` // 角色代码 + RoleName string `json:"role_name" gorm:"-"` // 角色名称 + LatestInviteRecord UserInviteRecord `json:"latest_invite_record" gorm:"-"` // 最近的邀请记录 //RenewalTime time.Time `json:"renewal_time"` //RenewalMemberLevel uint32 `json:"renewal_member_level"` //MemberLevelString string `json:"member_level_string" gorm:"-"` // 会员类型