Compare commits

...

14 Commits

Author SHA1 Message Date
f8f774ca1c 1.修改创建租赁订单时异常退出导致数据库死锁问题; 2024-09-17 01:19:57 +08:00
b96590ab28 1.修改用户使用运费包租赁时报错的问题; 2024-09-04 19:10:28 +08:00
90d606835f 1.修复会员升级时,支付回调通知创建邀请记录没有记录用户uid的缺陷; 2024-08-27 16:22:06 +08:00
6055ddc7fc 1.修复自动开通会员时,河马付回调通知创建邀请记录没有记录用户uid的缺陷; 2024-08-27 15:18:44 +08:00
db83bd9d8a 1.修改GameCardInfo接口,查看详情无需用户登录;
2.修改搜索相关接口,搜索无需登录;
3.修改租赁订单接口,解决重复下单缺陷;
2024-08-26 18:14:41 +08:00
d467e3b978 1.优化电源线绩效接口assistant_list,出参增加字段count;门店查询改成有效门店并跟PC端排序规则保持一致。 2024-08-19 14:46:29 +08:00
8a62ad0ee5 1.财务统计增加"降级续费"类型:白金会员过期后未退押金直接开通黄金会员,支付金额为99或者49; 2024-08-12 16:55:05 +08:00
06a35591a8 1.优惠券Coupon表增加规则字段rule; 2024-07-24 09:50:00 +08:00
092f8fba5d 1.新增门店开通优惠券功能; 2024-07-19 10:31:22 +08:00
7d142fd887 1.修复店员邀请记录缺陷,部分续费会员被当成了开通会员类型; 2024-07-16 20:46:52 +08:00
1e7a7352fe 1.获取用户数据接口增加出参;
2.店员绩效接口调整;
3.店员邀请用户生成记录时,默认为自动续费类型;
2024-07-12 19:44:24 +08:00
1a83ce356a 1.优惠券列表接口调整;
2.用户信息接口(/api/v1/user/data)出参增加字段role_key,配合处理临时店员功能;
2024-07-10 17:07:41 +08:00
99a798923e 1.修复用户登录时邀请人有效门店为空则无法登录的情况;
2.通过店员兑换码领取优惠券规则调整,只要曾经开通过会员的用户都可以领取;
3.开通会员时使用优惠券条件判断,只要曾经开通过会员的用户都可以使用已领取的优惠券;
2024-07-06 17:24:35 +08:00
2265cb5afb 1.修复卡带状态(抢光了,不在本店)不准确的情况; 2024-07-05 17:04:41 +08:00
15 changed files with 751 additions and 441 deletions

View File

@ -230,11 +230,12 @@ func AuthLogin(c *gin.Context) {
inviteUser := model.GetUserByUid(req.InviteUid)
effectiveStoreInfo, err := model.GetUserEffectiveStore(req.InviteUid)
if err != nil {
RespJson(c, status.InviteUserFail, nil)
return
//RespJson(c, status.InviteUserFail, nil)
//return
logger.Error("login GetUserEffectiveStore err")
}
if user.StoreId == 0 { // 用户所属门店id为空则更新
if user.StoreId == 0 && effectiveStoreInfo.StoreID != 0 { // 用户所属门店id为空则更新
_, err = model.NewUserQuerySet(model.DB).UidEq(user.Uid).GetUpdater().SetStoreId(effectiveStoreInfo.StoreID).
UpdateNum()
if err != nil {
@ -253,8 +254,8 @@ func AuthLogin(c *gin.Context) {
user.Uid, req.InviteUid))
if err != nil {
logger.Error("query err:", err)
RespJson(c, status.InternalServerError, nil)
return
//RespJson(c, status.InternalServerError, nil)
//return
}
if !exist { // 未邀请过,则添加邀请记录:首次邀请记录
firstInviteRecord := &model.UserInviteRecord{
@ -332,9 +333,9 @@ func AuthLogin(c *gin.Context) {
}
if err := invite.Create(model.DB); err != nil {
logger.Error(err)
RespJson(c, status.InternalServerError, nil)
return
logger.Error("create UserInvite err:", err)
//RespJson(c, status.InternalServerError, nil)
//return
}
}
//// 已经邀请过,则更新扫码记录
@ -532,6 +533,25 @@ func UserData(c *gin.Context) {
}
m.StoreList = sysUser.StoreList
m.RoleId = uint32(sysUser.RoleId)
if m.RoleId != 0 {
var roleInfo model.SysRole
err = model.NewSysRoleQuerySet(model.DB).IDEq(m.RoleId).Find(&roleInfo)
if err != nil {
logger.Error(err)
}
m.RoleKey = roleInfo.RoleKey
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
@ -798,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")
@ -806,25 +826,25 @@ func UserCodeToCoupon(c *gin.Context) {
return
}
if !user.IsMember() { // 判断用户是否为会员
logger.Error("user is not member")
RespJson(c, status.UserNotMember, nil)
return
}
userMemberLevel = user.MemberLevel
//if user.OpenMemberTime.IsZero() {
//if !user.IsMember() { // 判断用户是否为会员
// logger.Error("user is not member")
// RespJson(c, status.UserNotMember, nil)
// return
//}
userMemberLevel = user.MemberLevel
if user.OpenMemberTime.IsZero() { // 判断用户是否曾经开过会员
logger.Error("user is not member")
RespJson(c, status.UserNotMember, 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.InternalServerError, nil)
RespJson(c, status.NotAvailableCode, nil)
return
}
inviteUid = shopperPromotionCode.Uid
@ -1000,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
}
@ -1007,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
}

View File

@ -594,12 +594,28 @@ func MemberRenewalUserCouponList(c *gin.Context) {
list := make([]model.UserCoupon, 0, len(coupons))
for i, _ := range coupons {
if !user.IsMember() && coupons[i].ActivityType == 1 {
if user.OpenMemberTime.IsZero() && coupons[i].ActivityType == 1 {
continue
}
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])
}

View File

@ -449,6 +449,10 @@ func CooperativeGameCardGoodsList(c *gin.Context) {
return
}
const (
ShopManagerKey = "store-manager"
)
func AssistantMemberPromotionList(c *gin.Context) {
req := model.AssistantMemberPromotionReq{}
if c.ShouldBindJSON(&req) != nil {
@ -466,17 +470,34 @@ func AssistantMemberPromotionList(c *gin.Context) {
req.AssistantUid = uc.Uid
req.Assistant = model.GetUserByUid(uc.Uid)
if req.Assistant.XcxRoleId != 2 {
logger.Error("xcx role err:")
RespJson(c, status.NoAuth, nil)
return
}
if req.Assistant.UserType != 2 {
logger.Error("not assistant")
RespJson(c, status.InternalServerError, nil)
return
}
list, totalPage, err := req.List()
var sysUser model.SysUser
if err := model.NewSysUserQuerySet(model.DB).UidEq(uc.Uid).One(&sysUser); err != nil && err != model.RecordNotFound {
logger.Error(err)
RespJson(c, status.Unauthorized, nil)
return
}
req.Assistant.RoleId = uint32(sysUser.RoleId)
if req.Assistant.RoleId != 0 {
var roleInfo model.SysRole
err := model.NewSysRoleQuerySet(model.DB).IDEq(req.Assistant.RoleId).Find(&roleInfo)
if err != nil {
logger.Error(err)
}
req.Assistant.RoleKey = roleInfo.RoleKey
}
if req.Assistant.RoleKey != ShopManagerKey {
logger.Error("xcx role err:", req.Assistant.RoleKey)
RespJson(c, status.NoAuth, nil)
return
}
list, totalPage, count, err := req.List()
if err != nil {
logger.Error("list err:", err)
RespJson(c, status.InternalServerError, nil)
@ -487,6 +508,7 @@ func AssistantMemberPromotionList(c *gin.Context) {
"list": list,
"total_page": totalPage,
"page_num": req.PageNum,
"count": count,
}
RespOK(c, ret)
return

View File

@ -80,8 +80,20 @@ func GameCardInfo(c *gin.Context) {
return
}
uc := auth.GetCurrentUser(c)
if uc == nil {
RespJson(c, status.Unauthorized, nil)
if uc == nil { // 如果没有登录,则只查看详情
//RespJson(c, status.Unauthorized, nil)
//return
info, err := model.GetGameCardInfo(req.GameId, req.StoreId)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
ret := map[string]interface{}{
"card_info": info,
"is_collection": false,
}
RespOK(c, ret)
return
}
@ -127,8 +139,8 @@ func GameCardSearch(c *gin.Context) {
}
uc := auth.GetCurrentUser(c)
if uc == nil {
RespJson(c, status.Unauthorized, nil)
return
//RespJson(c, status.Unauthorized, nil)
//return
}
cardList, totalPage, err := model.GetGameCardSearch(req.Name, req.Page, req.PageSize, req.StoreId)
@ -137,12 +149,16 @@ func GameCardSearch(c *gin.Context) {
RespJson(c, status.InternalServerError, nil)
return
}
err = model.SearchHistoryAdd(uc.Uid, req.Name)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
if uc != nil { // 登录过的用户才记录搜索历史
err = model.SearchHistoryAdd(uc.Uid, req.Name)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
}
ret := map[string]interface{}{
"card_list": cardList,
"cur_page": req.Page,
@ -154,7 +170,8 @@ func GameCardSearch(c *gin.Context) {
func GameCardSearchHistory(c *gin.Context) {
uc := auth.GetCurrentUser(c)
if uc == nil {
RespJson(c, status.Unauthorized, nil)
//RespJson(c, status.Unauthorized, nil)
RespOK(c, []model.SearchHistory{})
return
}
historyList, err := model.GetSearchHistoryList(uc.Uid)
@ -454,6 +471,10 @@ func PushWXPayNotice(c *gin.Context) {
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeMemberFee
fundRecord.Remark = remark
// 支付金额小于10099或者49的情况是白金会员过期后没退押金然后直接开通黄金会员
if notifyInfo.TotalFee < 10000 {
fundRecord.FundType = model.FundTypeDowngradeRenewal
}
memberRecord := &model.UserMemberRecord{
Uid: record.Uid,
AfterMemberLevel: record.MemberLevel,
@ -568,7 +589,9 @@ func PushWXPayNotice(c *gin.Context) {
qs := model.NewUserInviteQuerySet(model.DB).IDEq(invite.ID).GetUpdater()
if isShopAssistantCode {
qs = qs.SetInviteForm(1)
invite.RenewHide = 0
invite.RenewHide = 0 // 干预
} else {
invite.RenewHide = 1 // 自动
}
qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
_, err = qs.SetMemberType(2).SetMemberStatus(2).
@ -953,7 +976,9 @@ func PushWXPayNotice(c *gin.Context) {
qs := model.NewUserInviteQuerySet(model.DB).IDEq(invite.ID).GetUpdater()
if isShopAssistantCode {
qs = qs.SetInviteForm(1)
invite.RenewHide = 0
invite.RenewHide = 0 // 干预
} else {
invite.RenewHide = 1 // 自动
}
qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
_, err = qs.SetMemberType(record.MemberLevel).SetMemberStatus(2).
@ -1023,6 +1048,7 @@ func PushWXPayNotice(c *gin.Context) {
}
} else if err == model.RecordNotFound { // 没有邀请记录,完全是用户自己开通会员,自己续费;按产品要求也需要有记录
inviteRecordNew := &model.UserInviteRecord{
ToUid: user.Uid,
Action: 2,
SpendType: 4,
MemberLevel: record.MemberLevel,
@ -1478,6 +1504,10 @@ func HmPushWXPayNotice(c *gin.Context) {
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeMemberFee
fundRecord.Remark = remark
// 支付金额小于10099或者49的情况是白金会员过期后没退押金然后直接开通黄金会员
if fundRecord.Amount < 10000 {
fundRecord.FundType = model.FundTypeDowngradeRenewal
}
memberRecord := &model.UserMemberRecord{
Uid: record.Uid,
AfterMemberLevel: record.MemberLevel,
@ -1491,7 +1521,8 @@ func HmPushWXPayNotice(c *gin.Context) {
return
} else {
spendType = uint32(2) // 2-开通会员
if !user.OpenMemberTime.IsZero() && user.MemberExpire.After(time.Now()) {
//if !user.OpenMemberTime.IsZero() && user.MemberExpire.After(time.Now()) {
if !user.OpenMemberTime.IsZero() {
spendType = 3 // 3-续费
}
isShopAssistantCode := false
@ -1588,7 +1619,9 @@ func HmPushWXPayNotice(c *gin.Context) {
if isShopAssistantCode {
qs = qs.SetInviteForm(1)
invite.RenewHide = 0
invite.RenewHide = 0 // 干预
} else {
invite.RenewHide = 1 // 自动
}
qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
_, err = qs.SetMemberType(2).SetMemberStatus(2).
@ -1713,6 +1746,7 @@ func HmPushWXPayNotice(c *gin.Context) {
}
} else if err == model.RecordNotFound { // 没有邀请记录,完全是用户自己开通会员,自己续费;按产品要求也需要有记录
inviteRecordNew := &model.UserInviteRecord{
ToUid: user.Uid,
Action: 2,
SpendType: spendType,
MemberLevel: record.MemberLevel,
@ -1980,7 +2014,9 @@ func HmPushWXPayNotice(c *gin.Context) {
qs := model.NewUserInviteQuerySet(model.DB).IDEq(invite.ID).GetUpdater()
if isShopAssistantCode {
qs = qs.SetInviteForm(1)
invite.RenewHide = 0
invite.RenewHide = 0 // 干预
} else {
invite.RenewHide = 1 // 自动
}
qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
_, err = qs.SetMemberType(record.MemberLevel).SetMemberStatus(2).
@ -2050,6 +2086,7 @@ func HmPushWXPayNotice(c *gin.Context) {
}
} else if err == model.RecordNotFound { // 没有邀请记录,完全是用户自己开通会员,自己续费;按产品要求也需要有记录
inviteRecordNew := &model.UserInviteRecord{
ToUid: user.Uid,
Action: 2,
SpendType: 4,
MemberLevel: record.MemberLevel,

View File

@ -6,6 +6,7 @@ import (
"fmt"
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"golang.org/x/sync/errgroup"
"io/ioutil"
"mh-server/kuaidi"
@ -241,19 +242,40 @@ func RentCardOrderCreate(c *gin.Context) {
cardCount += v.Count
}
rentCard := model.GetUserRentCard(uc.Uid)
if rentCard == nil {
//logger.Error(errors.New("GetUserByUid err"))
//RespJson(c, status.InternalServerError, nil)
//return
rentCard = &model.UserRentCard{LevelRentCount: memberConfig.CardMax, CanRentCount: memberConfig.CardMax}
var rentCard *model.UserRentCard
var tx *gorm.DB
if req.Price == 0 {
fmt.Println("*********** req.Price == 0 ***********")
tx = model.TransactionBegin()
rentCard = model.GetUserRentCard(tx, uc.Uid)
fmt.Println("*********** rentCard is:", rentCard)
if rentCard == nil {
//logger.Error(errors.New("GetUserByUid err"))
//RespJson(c, status.InternalServerError, nil)
//return
rentCard = &model.UserRentCard{LevelRentCount: memberConfig.CardMax, CanRentCount: memberConfig.CardMax}
}
} else {
fmt.Println("*********** req.Price != 0 ***********")
rentCard = model.GetUserRentCard(nil, uc.Uid)
fmt.Println("*********** rentCard is:", rentCard)
if rentCard == nil {
//logger.Error(errors.New("GetUserByUid err"))
//RespJson(c, status.InternalServerError, nil)
//return
rentCard = &model.UserRentCard{LevelRentCount: memberConfig.CardMax, CanRentCount: memberConfig.CardMax}
}
}
//if uc.Uid == 45935373 {
// rentCard.CanRentCount -= 1
//}
if cardCount > rentCard.CanRentCount {
logger.Error("GetMemberConfig err:", err)
if req.Price == 0 {
tx.Rollback()
}
logger.Error("err:", "会员超过可借卡数")
RespJson(c, status.OrderOutRentCount, nil)
return
}
@ -267,11 +289,17 @@ func RentCardOrderCreate(c *gin.Context) {
isRentCount, err := rentCard.IsHaveUnreturnedOrders(cardCount)
//unreturnedOrders, err := model.IsHaveUnreturnedOrders(uc.Uid) //
if err != nil {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
if isRentCount {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("unreturnedOrders")
RespJson(c, status.HaveUnreturnedOrders, nil)
return
@ -279,11 +307,17 @@ func RentCardOrderCreate(c *gin.Context) {
online, err := model.IsGameCardListOnline(req.GameCardList)
if err != nil {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
if !online {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("unreturnedOrders")
RespJson(c, status.GoodsSoldOut, nil)
return
@ -292,6 +326,9 @@ func RentCardOrderCreate(c *gin.Context) {
store.ID = req.StoreId
err = store.Info()
if err != nil {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("store err:", err)
RespJson(c, status.InternalServerError, nil)
return
@ -323,6 +360,9 @@ func RentCardOrderCreate(c *gin.Context) {
// OrderAscByID().Limit(1).One(&userCoupon)
err = model.NewUserCouponQuerySet(model.DB).IDEq(req.UserCouponId).One(&userCoupon)
if err != nil && err != model.RecordNotFound {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("user coupon err:", err)
RespJson(c, status.InternalServerError, nil)
return
@ -348,11 +388,17 @@ func RentCardOrderCreate(c *gin.Context) {
//}
stockEnough, err := model.IsCardGoodsStockEnough(req.GameCardList, req.StoreId)
if err != nil {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("err:", err)
RespJson(c, status.OrderStockOut, nil)
return
}
if stockEnough {
if req.Price == 0 {
tx.Rollback()
}
logger.Error("order stock out ")
RespJson(c, status.OrderStockOut, nil)
return
@ -376,7 +422,9 @@ func RentCardOrderCreate(c *gin.Context) {
//fmt.Println("PayPrice:", order.PayPrice)
if req.Price == 0 {
tx := model.TransactionBegin()
if tx == nil {
tx = model.TransactionBegin()
}
order.PayStatus = model.PayStatusPaid
fmt.Println("orderId:", order.PayStatus)
err = order.OrderCreate(tx)
@ -396,7 +444,7 @@ func RentCardOrderCreate(c *gin.Context) {
// RespJson(c, status.InternalServerError, nil)
// return
//}
err := model.GameCardGoodsInventoryReduction(req.GameCardList, req.StoreId, tx)
err = model.GameCardGoodsInventoryReduction(req.GameCardList, req.StoreId, tx)
if err != nil {
tx.Rollback()
logger.Error("inventory reduction err:", err.Error())

View File

@ -269,8 +269,8 @@ func OpenMember(c *gin.Context) {
return
}
// 用户已开通会员且优惠券可用
if user.IsMember() && coupon.Uid == uc.Uid && coupon.MemberLevel == req.MemberLevel &&
// 使用续费优惠券:用户已开通会员(开通会员时间不为空)、优惠券可用
if !user.OpenMemberTime.IsZero() && coupon.Uid == uc.Uid && coupon.MemberLevel == req.MemberLevel &&
coupon.ActivityId == 1 && coupon.State == 1 {
totalFee -= coupon.Value
@ -296,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 { // 不符合优惠条件

View File

@ -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 {

View File

@ -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 {

File diff suppressed because it is too large Load Diff

View File

@ -26,9 +26,10 @@ type Coupon struct {
Model
Name string `json:"name"`
Describe string `json:"describe" gorm:"type:text;"` // 描述
Describe string `json:"describe" gorm:"type:text"` // 描述
Rule string `json:"rule" 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 +59,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:"-"`
}

View File

@ -1740,7 +1740,7 @@ type AssistantMemberPromotionReq struct {
Assistant *User `json:"assistant"`
}
func (m *AssistantMemberPromotionReq) List() ([]InviteMemberReport, int, error) {
func (m *AssistantMemberPromotionReq) List() ([]InviteMemberReport, int, int, error) {
var reports []InviteMemberReport
m.PageNum -= 1
@ -1751,7 +1751,14 @@ func (m *AssistantMemberPromotionReq) List() ([]InviteMemberReport, int, error)
m.PageSize = 10
}
m.StoreId = uint32(m.Assistant.StoreId)
//m.StoreId = uint32(m.Assistant.StoreId)
effectiveStoreInfo, err := GetUserEffectiveStore(m.Assistant.Uid)
if err != nil {
logger.Error("err:", err)
return reports, 0, 0, err
}
m.StoreId = uint32(effectiveStoreInfo.StoreID)
qs := NewInviteMemberReportQuerySet(DB).CooperativeBusinessIdEq(m.Assistant.CooperativeBusinessId).
StoreIdEq(m.StoreId)
@ -1761,17 +1768,19 @@ func (m *AssistantMemberPromotionReq) List() ([]InviteMemberReport, int, error)
count, err := qs.Count()
if err != nil {
logger.Error("err:", err)
return reports, 0, err
return reports, 0, 0, err
}
totalPage := int(count)/m.PageSize + 1
err = qs.OrderDescByID().Offset(m.PageNum * m.PageSize).Limit(m.PageSize).All(&reports)
//totalPage := int(count)/m.PageSize + 1
totalPage := (int(count) + m.PageSize - 1) / m.PageSize
err = qs.OrderDescByDateAndAscByStoreId().Offset(m.PageNum * m.PageSize).Limit(m.PageSize).All(&reports)
if err != nil && err != RecordNotFound {
logger.Error("err:", err)
return reports, totalPage, err
return reports, totalPage, 0, err
}
reports = InviteMemberReportListSetUser(reports)
return reports, totalPage, nil
return reports, totalPage, count, nil
}
func uint32ToUint64(slice []uint32) []uint64 {
@ -1807,32 +1816,35 @@ func GameCardListSetStockState(list []GameCard, storeId uint32, storeList []uint
}
}
err = NewGameCardGoodsStockQuerySet(DB).StoreIdEq(uint64(storeId)).StoreIdIn(uint32ToUint64(storeList)...).
GameCardIdIn(gameCardIds...).RentStockGt(0).All(&cardStocks)
if err != nil {
logger.Error("GetGameIdByType err:", err)
}
for i, _ := range cardStocks {
_, ok := gameIdMap[uint32(cardStocks[i].GameCardId)]
if !ok {
//gameIds = append(gameIds, uint32(cardStocks[i].GameCardId))
gameIdMap[uint32(cardStocks[i].GameCardId)] = 1
}
}
err = NewGameCardGoodsStockQuerySet(DB).StoreIdNe(uint64(storeId)).StoreIdIn(uint32ToUint64(storeList)...).
GameCardIdIn(gameCardIds...).RentStockGt(0).All(&cardStocks)
if err != nil {
logger.Error("GetGameIdByType err:", err)
}
for i, _ := range cardStocks {
_, ok := gameIdMap[uint32(cardStocks[i].GameCardId)]
if !ok {
//gameIds = append(gameIds, uint32(cardStocks[i].GameCardId))
gameIdMap[uint32(cardStocks[i].GameCardId)] = 2
}
//_, ok := gameIdMap[uint32(cardStocks[i].GameCardId)]
//if !ok {
// //gameIds = append(gameIds, uint32(cardStocks[i].GameCardId))
// gameIdMap[uint32(cardStocks[i].GameCardId)] = 2
//}
gameIdMap[uint32(cardStocks[i].GameCardId)] = 2
}
err = NewGameCardGoodsStockQuerySet(DB).StoreIdEq(uint64(storeId)).StoreIdIn(uint32ToUint64(storeList)...).
GameCardIdIn(gameCardIds...).RentStockGt(0).All(&cardStocks)
if err != nil {
logger.Error("GetGameIdByType err:", err)
}
for i, _ := range cardStocks {
//_, ok := gameIdMap[uint32(cardStocks[i].GameCardId)]
//if !ok {
// //gameIds = append(gameIds, uint32(cardStocks[i].GameCardId))
// gameIdMap[uint32(cardStocks[i].GameCardId)] = 1
//}
gameIdMap[uint32(cardStocks[i].GameCardId)] = 1
}
} else {
var cardStocks []GameCardGoodsStock
err := NewGameCardGoodsStockQuerySet(DB).GameCardIdIn(gameCardIds...).StoreIdIn(uint32ToUint64(storeList)...).
@ -1853,10 +1865,12 @@ func GameCardListSetStockState(list []GameCard, storeId uint32, storeList []uint
logger.Error("GetGameIdByType err:", err)
}
for i, _ := range cardStocks {
_, ok := gameIdMap[uint32(cardStocks[i].GameCardId)]
if !ok {
gameIdMap[uint32(cardStocks[i].GameCardId)] = 1
}
//_, ok := gameIdMap[uint32(cardStocks[i].GameCardId)]
//if !ok {
// gameIdMap[uint32(cardStocks[i].GameCardId)] = 1
//}
gameIdMap[uint32(cardStocks[i].GameCardId)] = 1
}
}

View File

@ -1277,21 +1277,21 @@ func AddMemberPromotion() {
}
func TestXcxRoleAdd(t *testing.T) {
InitTestDB()
role := &XcxRole{
RoleName: "店长",
RoleKey: "shop_manager",
RoleSort: 2,
Status: "normal",
Flag: "",
CreateBy: "",
UpdateBy: "",
Remark: "",
}
err := DBDev.Create(role).Error
if err != nil {
logger.Error("err:")
}
//InitTestDB()
//role := &XcxRole{
// RoleName: "店长",
// RoleKey: "shop_manager",
// RoleSort: 2,
// Status: "normal",
// Flag: "",
// CreateBy: "",
// UpdateBy: "",
// Remark: "",
//}
//err := DBDev.Create(role).Error
//if err != nil {
// logger.Error("err:")
//}
// assistant
//shop_manager 长
}

View File

@ -21,43 +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
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:"-"` // 会员类型
@ -181,6 +184,7 @@ const (
FundTypeBuyGoodsRefund = "buy_goods_refund" // 购买商品退货
FundTypeRecycleCard = "recycle_card" // 回收卡带
FundTypePostagePackageFee = "postage_package_fee" // 购买运费包
FundTypeDowngradeRenewal = "downgrade_renewal" // 降级续费
)
// gen:qs
@ -221,24 +225,44 @@ type UserMemberExpireDelay struct {
IsPay uint32 `json:"is_pay"` // 1-已支付
}
// gen:qs
type XcxRole struct {
// gen:gs
type SysRole struct {
Model
RoleId uint32 `json:"role_id" gorm:"unique_index,not null"`
RoleName string `json:"role_name" gorm:"size:255;"` // 角色名称
RoleKey string `json:"role_key" gorm:"size:255;"` // 角色代码
RoleSort int `json:"role_sort" gorm:""` // 角色排序
Status string `json:"status" gorm:"size:255;"` // 状态:1-停用 2-正常
Flag string `json:"flag" gorm:"size:255;"` //
CreateBy string `json:"create_by" gorm:"size:255;"` //
UpdateBy string `json:"update_by" gorm:"size:255;"` //
Remark string `json:"remark" gorm:"size:255;"` // 备注
RoleId int `json:"roleId" gorm:"primary_key;AUTO_INCREMENT"` // 角色编码
RoleName string `json:"roleName" gorm:"size:128;"` // 角色名称
Status string `json:"status" gorm:"size:4;"` //
RoleKey string `json:"roleKey" gorm:"size:128;"` //角色代码
RoleSort int `json:"roleSort" gorm:""` //角色排序
Flag string `json:"flag" gorm:"size:128;"` //
CreateBy string `json:"createBy" gorm:"size:128;"` //
UpdateBy string `json:"updateBy" gorm:"size:128;"` //
Remark string `json:"remark" gorm:"size:255;"` //备注
Admin bool `json:"admin" gorm:"size:4;"`
DataScope string `json:"dataScope" gorm:"size:128;"`
Params string `json:"params" gorm:"-"`
MenuIds []int `json:"menuIds" gorm:"-"`
DeptIds []int `json:"deptIds" gorm:"-"`
}
//// gen:qs
//type XcxRole struct {
// Model
// RoleId uint32 `json:"role_id" gorm:"unique_index,not null"`
// RoleName string `json:"role_name" gorm:"size:255;"` // 角色名称
// RoleKey string `json:"role_key" gorm:"size:255;"` // 角色代码
// RoleSort int `json:"role_sort" gorm:""` // 角色排序
// Status string `json:"status" gorm:"size:255;"` // 状态:1-停用 2-正常
// Flag string `json:"flag" gorm:"size:255;"` //
// CreateBy string `json:"create_by" gorm:"size:255;"` //
// UpdateBy string `json:"update_by" gorm:"size:255;"` //
// Remark string `json:"remark" gorm:"size:255;"` // 备注
//
// Params string `json:"params" gorm:"-"`
// MenuIds []int `json:"menuIds" gorm:"-"`
// DeptIds []int `json:"deptIds" gorm:"-"`
//}
// gen:qs
// ShopperPromotionCode 店员优惠码
type ShopperPromotionCode struct {
@ -338,12 +362,21 @@ func GetUserEffectiveStore(uid uint32) (*StoreInfo, error) {
return &validStores[0], nil
}
func GetUserRentCard(uid uint32) *UserRentCard {
func GetUserRentCard(db *gorm.DB, uid uint32) *UserRentCard {
userRent := new(UserRentCard)
if err := NewUserRentCardQuerySet(DB).UidEq(uid).One(userRent); err != nil {
logger.Error(err, uid)
return nil
if db == nil {
if err := NewUserRentCardQuerySet(DB).UidEq(uid).One(userRent); err != nil {
logger.Error(err, uid)
return nil
}
} else {
// 手动加锁查询
if err := db.Raw(`SELECT * FROM user_rent_card WHERE uid = ? FOR UPDATE`, uid).Scan(userRent).Error; err != nil {
logger.Error(err, uid)
return nil
}
}
return userRent
}

View File

@ -1,6 +1,6 @@
{
"server": {
"port": 6001
"port": 8001
},
"jwt": {
"user": {
@ -23,11 +23,11 @@
},
"db": {
"driver": "mysql",
"host": "39.108.188.218",
"host": "112.33.14.191",
"port": 3306,
"user": "mh_new_pro",
"password": "YnzexdTfBHMSGZki",
"db_name": "mh_new_pro"
"user": "mh_dev",
"password": "d9qy46ONI0ZTF9eH",
"db_name": "mh_dev"
},
"wx": {
"app_id": "wx806c079463b5b56c",

View File

@ -58,7 +58,7 @@ func ConfigAppRouter(r gin.IRouter) {
gameCard.POST("game_type", controller.GameCardTypes) // 游戏标签
gameCard.POST("type/list", controller.GameCardTypeList) // 游戏类型列表
gameCard.Use(auth.UserAccessAuth)
//gameCard.Use(auth.UserAccessAuth)
gameCard.POST("info", controller.GameCardInfo) // 游戏卡详情
gameCard.POST("list", controller.GameCardList) // 游戏卡列表
gameCard.POST("banner", controller.HomeCarouselList) // 轮播图
@ -69,7 +69,7 @@ func ConfigAppRouter(r gin.IRouter) {
search.POST("list", controller.GameCardSearch) // 游戏卡搜索列表
search.POST("hot", controller.GameCardHotSearch) // 游戏卡搜索列表
search.Use(auth.UserAccessAuth)
//search.Use(auth.UserAccessAuth)
search.POST("history", controller.GameCardSearchHistory) // 游戏卡搜索历史
}