package model import ( "errors" "fmt" "github.com/codinl/go-logger" "mh-server/lib/utils" "sync" "time" ) //go:generate goqueryset -in user.go // gen:qs type User struct { Model Uid uint32 `json:"uid" gorm:"column:uid;unique_index"` MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员 MemberExpire time.Time `json:"member_expire"` // 会员到期时间 Bond uint32 `json:"bond"` // 保证金 WxName string `json:"wx_name"` // 昵称 WxAvatar string `json:"wx_avatar"` // 头像 WxOpenID string `json:"wx_open_id"` AppOpenID string `json:"app_open_id"` WxUnionID string `json:"wx_union_id"` 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 uint8 `json:"user_type"` // 用户类型 1-普通用户 2-店员 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 uint8 `json:"store_type"` // 1-订单门店 Version uint32 `json:"-"` } func (o *User) TableName() string { return "user" } const ( MemberTypeConsumer = 1 // 普通用户 MemberTypeMember = 2 // 黄金会员 ) const ( MemberLevelConsumer = 1 // 普通用户 MemberLevelGold = 2 // 黄金会员 MemberLevelPeriod = 3 MemberLevelPlatinum = 4 // 白金会员 MemberLevelBlackGold = 5 // 黑金会员 ) const DateTimeFormat = "2006-01-02" // gen:qs type UserInvite struct { Model FromUid uint32 `json:"from_uid"` // 邀请用户id UserType uint8 `json:"user_type"` // 用户类型 StoreId uint64 `json:"store_id"` // 门店id MemberOpenTime time.Time `json:"member_open_time"` // 开通会员 MemberType uint8 `json:"member_type"` // 被邀请用户 1-普通用户 2-会员 MemberStatus uint8 `json:"member_status"` // 被邀请用户 1-未开通 2-已开通 3-已取消会员 ToUid uint32 `json:"to_uid"` // 被邀请用户 StoreType uint32 `json:"store_type"` // 门店类型 MemberLevel uint32 `json:"member_level"` // 会员等级 } const ( DepositRefundStatusUnconfirmed = 1 // 待确认 DepositRefundStatusConfirmed = 2 // 已确认 DepositRefundStatusRefunded = 3 // 已退款 DepositRefundStatusRefused = 4 // 已拒绝 ) // gen:qs type DepositRefundRecord struct { Model Uid uint32 `json:"uid"` Status uint32 `json:"status"` // 1 // 待确认 2 // 已确认 3 // 已退款 4 // 已拒绝 Amount uint32 `json:"amount"` Operator uint32 `json:"operator"` ConfirmTime time.Time `json:"confirm_time"` User User `json:"user" gorm:"-"` } // 黄金会员 member_gold 白金会员 member_platinum 黑金会员 member_black_gold // member_gold_deposit member_platinum_deposit member_black_gold_platinum // express_fee const ( UserConsumeTypeMemberGold = "member_gold" UserConsumeTypeMemberPlatinum = "member_platinum" UserConsumeTypeMemberBlackGold = "member_black_gold" UserConsumeTypeMemberGoldDeposit = "member_gold_deposit" UserConsumeTypeMemberPlatinumDeposit = "member_platinum_deposit" UserConsumeTypeMemberBlackGoldDeposit = "member_black_gold_platinum" UserConsumeTypeExpressFee = "express_fee" ) // gen:qs type UserConsumeRecord struct { Model Uid uint32 `json:"uid"` ConsumeType string `json:"consume_type"` // 黄金会员 member_gold 白金会员 member_platinum 黑金会员 member_black_gold Amount uint32 `json:"amount"` Status uint32 `json:"status"` // 1-待支付 2-已支付 3-已退款 } // gen:qs type UserRentCard struct { Model Uid uint32 `json:"uid"` MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员 LevelRentCount uint32 `json:"level_rent_count"` // 等级借卡数量 HaveRentCount uint32 `json:"have_rent_count"` // 已借卡数量 CanRentCount uint32 `json:"can_rent_count"` // 可借卡数量 Status uint32 `json:"status"` // 状态 } func GetUserByUid(uid uint32) *User { user := new(User) if err := NewUserQuerySet(DB).UidEq(uid).One(user); err != nil { logger.Error(err, uid) return nil } return user } func GetUserRentCard(uid uint32) *UserRentCard { userRent := new(UserRentCard) if err := NewUserRentCardQuerySet(DB).UidEq(uid).One(userRent); err != nil { logger.Error(err, uid) return nil } return userRent } func UserUpdate(user *User) error { if user.Uid == 0 { return errors.New("uid is null") } fields := make([]UserDBSchemaField, 0) if user.WxName != "" { fields = append(fields, UserDBSchema.WxName) } if user.WxAvatar != "" { fields = append(fields, UserDBSchema.WxAvatar) } if user.Tel != "" { fields = append(fields, UserDBSchema.Tel) } if user.MemberLevel != 0 { fields = append(fields, UserDBSchema.MemberLevel) fields = append(fields, UserDBSchema.MemberExpire) } if user.Deposit != 0 { fields = append(fields, UserDBSchema.Deposit) } if len(fields) > 0 { err := user.Update(DB.Where(&User{Uid: user.Uid}), fields...) if err != nil { logger.Error("err:", err) return err } } return nil } // gen:qs type UserOpenMemberRecord struct { Model Uid uint32 `json:"uid"` OpenNo string `json:"open_no" gorm:"index"` OrderId uint32 `json:"order_id"` OrderType uint32 `json:"order_type"` // 1-物流支付 MemberLevel uint32 `json:"member_level"` } func (o *UserOpenMemberRecord) TableName() string { return "user_open_member_record" } func (m UserOpenMemberRecord) Insert() error { err := m.Create(DB) if err != nil { logger.Error("err:", err) return err } return nil } func (m *UserOpenMemberRecord) GetByOpenNo() error { err := NewUserOpenMemberRecordQuerySet(DB).OpenNoEq(m.OpenNo).One(m) if err != nil && err != RecordNotFound { logger.Error("err:", err) return err } return nil } // gen:qs type CommonProblem struct { Model Question string `json:"question"` Answer string `json:"answer" gorm:"type:text"` Sort uint32 `json:"sort" gorm:"index"` } type GroupSendMessageTemplate struct { Model Title string `json:"title" ` Message string `json:"message"` UserType uint32 `json:"user_type" gorm:"index,column:user_type"` // 1-所有用户 2-会员 3-非会员 4-指定用户 SendTime time.Time `json:"send_time"` Tels string `json:"tels"` Status uint32 `json:"status"` // 1-待发送 2-已发送 } func (*CommonProblem) TableName() string { return "common_problem" } func (*CommonProblem) List() ([]CommonProblem, error) { commons := make([]CommonProblem, 0) err := NewCommonProblemQuerySet(DB).OrderDescBySort().All(&commons) if err != nil && err != RecordNotFound { logger.Error("err:", err) return commons, err } return commons, err } func (m *User) AppletQRCodeUpdate() error { num, err := NewUserQuerySet(DB).UidEq(m.Uid).GetUpdater().SetInviteCodeUrl(m.InviteCodeUrl).UpdateNum() if err != nil || num != 1 { logger.Error("AppletQRCodeUpdate err") return errors.New("AppletQRCodeUpdate err") } return nil } type UserInviteListReq struct { Page int `json:"page"` PageSize int `json:"page_size"` Uid uint32 `json:"uid"` MemberType int `json:"member_type"` // 0-全部 1-普通用户 2-会员 StartTime string `json:"start_time"` // 开始时间 EndTime string `json:"end_time"` // 结束时间 } type UserInviteListResp struct { Page int `json:"page"` TotalPage int `json:"total_page"` List []UserInviteList `json:"list"` Count int `json:"count"` } type UserInviteList struct { User User `json:"user"` UserInvite UserInvite `json:"user_invite"` } func (m *UserInviteListReq) InviteUserList() (*UserInviteListResp, error) { list := make([]User, 0) resp := &UserInviteListResp{ Page: m.Page, List: make([]UserInviteList, 0), } page := m.Page - 1 if page < 0 { page = 0 } if m.PageSize == 0 { m.PageSize = 10 } qs := NewUserInviteQuerySet(DB).FromUidEq(m.Uid) if m.MemberType != 0 { qs = qs.MemberTypeEq(uint8(m.MemberType)) } if m.StartTime != "" { parse, err := time.Parse(DateTimeFormat, m.StartTime) if err != nil { logger.Errorf("err:%#v", err) return resp, err } if m.MemberType == 2 { qs = qs.MemberOpenTimeGte(parse) } else { qs = qs.CreatedAtGte(parse) } } if m.EndTime != "" { parse, err := time.Parse(DateTimeFormat, m.EndTime) if err != nil { logger.Errorf("err:%#v", err) return resp, err } if m.MemberType == 2 { qs = qs.MemberOpenTimeLte(parse.AddDate(0, 0, 1)) } else { qs = qs.CreatedAtLte(parse.AddDate(0, 0, 1)) } } count, err := qs.Count() if err != nil { logger.Error("err:", err) return resp, err } resp.TotalPage = count/m.PageSize + 1 resp.Count = count var invites []UserInvite err = qs.Offset(page * m.PageSize).Limit(m.PageSize).OrderDescByID().All(&invites) if err != nil && err != RecordNotFound { logger.Error("err:", err) return resp, err } if len(invites) == 0 { return resp, nil } uids := make([]uint32, 0) inviteMap := make(map[uint32]UserInvite, 0) for i, _ := range invites { uids = append(uids, invites[i].ToUid) inviteMap[invites[i].ToUid] = invites[i] } err = NewUserQuerySet(DB).UidIn(uids...).All(&list) if err != nil { logger.Error("err:", err) return resp, err } userMap := make(map[uint32]User, 0) for i, _ := range list { userMap[list[i].Uid] = list[i] } //users := make([]User, 0) users := make([]UserInviteList, 0) for i, _ := range uids { user, ok1 := userMap[uids[i]] invite, ok2 := inviteMap[uids[i]] if !ok1 || !ok2 { continue } userInvite := UserInviteList{ User: user, UserInvite: invite, } users = append(users, userInvite) } resp.List = users return resp, nil } func GetOrderSn() string { var orderSn string for { orderSn = utils.GetSerialNo32HEXString() count, err := NewUserOpenMemberRecordQuerySet(DB).OpenNoEq(orderSn).Count() if err != nil { logger.Error("err:", err) } if count == 0 { break } } return orderSn } func (m *User) Edit() { err := DB.Save(m).Error if err != nil { logger.Error("err:", err) } return } func GetWxPayExpressFeeRefundRecord(orderId uint32) (string, error) { var openMemberRecord UserOpenMemberRecord err := NewUserOpenMemberRecordQuerySet(DB).OrderIdEq(orderId).OrderTypeEq(1).OrderDescByID().Limit(1).One(&openMemberRecord) if err != nil { logger.Error("err:", err) return "", err } return openMemberRecord.OpenNo, nil } func GetDepositRefundRecordList(uid uint32) ([]DepositRefundRecord, error) { var deposits []DepositRefundRecord err := NewDepositRefundRecordQuerySet(DB).UidEq(uid).OrderDescByID().All(&deposits) if err != nil { logger.Error("deposit refund record err:", err) return deposits, err } return deposits, nil } var userMutexMap map[string]*sync.Mutex func GetUserMutexMap() map[string]*sync.Mutex { if userMutexMap == nil { userMutexMap = make(map[string]*sync.Mutex, 0) } return userMutexMap } func GetUserMutex(mutexKey string) *sync.Mutex { mutexMap := GetUserMutexMap() if v, ok := mutexMap[mutexKey]; ok { return v } else { mutexMap[mutexKey] = new(sync.Mutex) return mutexMap[mutexKey] } } //func AuthLoginMutex(uid uint32) *sync.Mutex { // return GetUserMutex(fmt.Sprintf("AuthLogin:%d", uid)) //} var AuthLoginMutex = sync.Mutex{} func OrderCardUserRentCard(uid uint32, count uint32, memberConfig *MemberConfig) error { //UserRentCard{} var userRentCard UserRentCard err := NewUserRentCardQuerySet(DB).UidEq(uid).One(&userRentCard) if err != nil && err != RecordNotFound { logger.Error("err:", err) return err } if err == RecordNotFound { user := GetUserByUid(uid) if user == nil { logger.Error("user nil") return errors.New("user nil") } if memberConfig == nil { memberConfig, err = GetMemberConfig(user.MemberLevel) if err != nil { logger.Error("GetMemberConfig err:", err) return err } } rentCard := &UserRentCard{ Uid: uid, MemberLevel: user.MemberLevel, LevelRentCount: memberConfig.CardMax, HaveRentCount: uint32(count), CanRentCount: uint32(memberConfig.CardMax - count), Status: 0, } err := DB.Create(rentCard).Error if err != nil { logger.Error("err", err) return err } return nil } sql := fmt.Sprintf("UPDATE user_rent_card SET have_rent_count=have_rent_count+%d ,can_rent_count=can_rent_count-%d WHERE uid = %d", count, count, uid) err = DB.Exec(sql).Error if err != nil { logger.Error("err", err) return err } return nil }