package user import ( "encoding/json" "errors" "github.com/gin-gonic/gin" "github.com/silenceper/wechat/v2/miniprogram/auth" admin2 "hongze/hongze_yb/models/tables/admin" "hongze/hongze_yb/models/tables/rddp/session" "hongze/hongze_yb/models/tables/research_variety_tag_relation" "hongze/hongze_yb/models/tables/user_record" "hongze/hongze_yb/models/tables/wx_user" "hongze/hongze_yb/models/tables/wx_user_log" "hongze/hongze_yb/utils" "strconv" "time" ) var ERR_NO_USER_RECORD = errors.New("用户关系没有入库") var ERR_USER_NOT_BIND = errors.New("用户没有绑定") type UserInfo struct { wx_user.WxUser RecordInfo *user_record.UserRecord LoginToken string } // GetWxUserItemByOpenId 通过openid获取用户信息 func GetWxUserItemByOpenId(openid string) (userInfo UserInfo, err error) { //通过openid获取用户关联信息 userRecord, e := user_record.GetByOpenID(openid) if e != nil { if e == utils.ErrNoRow { err = ERR_NO_USER_RECORD return } err = e return } //该openid在系统中没有关联关系 if userRecord == nil { err = ERR_NO_USER_RECORD return } //该openid没有绑定用户 if userRecord.UserID <= 0 { err = ERR_USER_NOT_BIND item := new(wx_user.WxUser) //格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } //获取用户信息 item, wxUserErr := wx_user.GetByUserId(userRecord.UserID) if wxUserErr != nil { err = wxUserErr //如果是找不到数据,那么可能是该用户被删除了,但是user_record没有删除对应的关系 if wxUserErr == utils.ErrNoRow { //用户被删除了,但是user_record没有删除对应的关系,那么去解除绑定 userUnbindErr := user_record.UnBindUserRecordByOpenid(openid) if userUnbindErr != nil { err = userUnbindErr return } //返回状态为 用户未绑定 逻辑代码 err = ERR_USER_NOT_BIND item := new(wx_user.WxUser) //格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } return } //格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } // GetWxUserItemByUserId 根据用户id和平台id获取用户信息 func GetWxUserItemByUserId(userId, platform int) (userInfo UserInfo, err error) { //获取用户信息 wxUser, err := wx_user.GetByUserId(userId) if err != nil { return } //格式化返回用户数据 userInfo = formatWxUser(wxUser, platform) return } // GetWxUserItemByEmail 根据用户邮箱和平台id获取用户信息 func GetWxUserItemByEmail(email string, platform int) (userInfo UserInfo, err error) { //获取用户信息 wxUser, err := wx_user.GetByEmail(email) if err != nil { return } //格式化返回用户数据 userInfo = formatWxUser(wxUser, platform) return } // GetWxUserItemByMobile 根据用户手机号和平台id获取用户信息 func GetWxUserItemByMobile(mobile string, platform int) (userInfo UserInfo, err error) { //获取用户信息 wxUser, err := wx_user.GetByMobile(mobile) if err != nil { return } //格式化返回用户数据 userInfo = formatWxUser(wxUser, platform) return } // GetWxUserItemByUnionId 根据用户unionid和平台id获取用户信息 func GetWxUserItemByUnionId(unionId string, platform int) (userInfo UserInfo, err error) { // 获取用户信息 userRecord, userRecordErr := user_record.GetByUnionID(unionId, platform) if userRecordErr != nil { if userRecordErr == utils.ErrNoRow { err = ERR_NO_USER_RECORD return } else { err = userRecordErr return } } // 该union在系统中没有关联关系 if userRecord == nil { err = ERR_NO_USER_RECORD return } // 该openid没有绑定用户 if userRecord.UserID <= 0 { err = ERR_USER_NOT_BIND item := new(wx_user.WxUser) //格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } item, wxUserErr := wx_user.GetByUserId(userRecord.UserID) if wxUserErr != nil { err = wxUserErr // 如果是找不到数据,那么可能是该用户被删除了,但是user_record没有删除对应的关系 if wxUserErr == utils.ErrNoRow { // 用户被删除了,但是user_record没有删除对应的关系,那么去解除绑定 userUnbindErr := user_record.UnBindUserRecordByUnionId(unionId, platform) if userUnbindErr != nil { err = userUnbindErr return } // 返回状态为用户未绑定 err = ERR_USER_NOT_BIND item := new(wx_user.WxUser) // 格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } return } // 格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } // GetFirstWxUserItemByUnionId 根据用户unionid获取最小平台的用户信息(已经绑定了user_id的) func GetFirstWxUserItemByUnionId(unionId string) (userInfo UserInfo, err error) { // 获取用户信息 userRecord, userRecordErr := user_record.GetFirstByUnionID(unionId) if userRecordErr != nil { if userRecordErr == utils.ErrNoRow { err = ERR_NO_USER_RECORD return } else { err = userRecordErr return } } // 该union在系统中没有关联关系 if userRecord == nil { err = ERR_NO_USER_RECORD return } // 该openid没有绑定用户 if userRecord.UserID <= 0 { err = ERR_USER_NOT_BIND item := new(wx_user.WxUser) //格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } item, wxUserErr := wx_user.GetByUserId(userRecord.UserID) if wxUserErr != nil { err = wxUserErr // 如果是找不到数据,那么可能是该用户被删除了,但是user_record没有删除对应的关系 if wxUserErr == utils.ErrNoRow { // 用户被删除了,但是user_record没有删除对应的关系,那么去解除绑定 userUnbindErr := user_record.UnBindUserRecordByUnionId(unionId, int(userRecord.CreatePlatform)) if userUnbindErr != nil { err = userUnbindErr return } // 返回状态为用户未绑定 err = ERR_USER_NOT_BIND item := new(wx_user.WxUser) // 格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } return } // 格式化返回用户数据 userInfo = formatWxUserAndUserRecord(item, userRecord) return } // formatWxUserAndUserRecord 通过用户 关系表记录 和 用户记录 格式化返回 用户数据 func formatWxUserAndUserRecord(wxUser *wx_user.WxUser, userRecord *user_record.UserRecord) (userInfo UserInfo) { wxUser.OpenID = userRecord.OpenID wxUser.UnionID = userRecord.UnionID //wxUser.NickName = userRecord.NickName //wxUser.RealName = userRecord.RealName //wxUser.BindAccount = userRecord.BindAccount //wxUser.Headimgurl = userRecord.Headimgurl wxUserJson, _ := json.Marshal(wxUser) _ = json.Unmarshal(wxUserJson, &userInfo) userInfo.RecordInfo = userRecord return } // formatWxUser 通过用户 用户记录 和 来源平台 格式化返回 用户数据 func formatWxUser(wxUser *wx_user.WxUser, platform int) (userInfo UserInfo) { //根据用户id和平台id获取用户关系 userRecord, userRecordErr := user_record.GetByUserId(int(wxUser.UserID), platform) if userRecordErr != nil { if userRecordErr != utils.ErrNoRow { return } } //该openid在系统中没有关联关系 if userRecord == nil { wxUserJson, _ := json.Marshal(wxUser) _ = json.Unmarshal(wxUserJson, &userInfo) return } else { userInfo = formatWxUserAndUserRecord(wxUser, userRecord) } return } // WxLogin 微信登录 func WxLogin(wxPlatform int, wxSession auth.ResCode2Session) (token string, userId int, isBind bool, err error) { openId := wxSession.OpenID unionId := wxSession.UnionID sessionKey := wxSession.SessionKey needUpdateSessionKey := true //是否更新sessionKey QUERY_WX_USER: wxUser, wxUserErr := GetWxUserItemByOpenId(openId) if wxUserErr == ERR_NO_USER_RECORD { //没有用户openid记录 _, recordErr := AddUserRecord(openId, unionId, "", "", "", "", "", "", sessionKey, wxPlatform, 0, 0) //如果插入失败,那么直接将错误信息返回 if recordErr != nil { err = recordErr return } needUpdateSessionKey = false //因为是新增用户微信信息,所以不需要更新sessionKey的数据了 //插入成功后,需要重新查询该用户,并进入下面的逻辑 goto QUERY_WX_USER } else if wxUserErr == ERR_USER_NOT_BIND { // 未绑定则去查询unionId是否已经绑定了用户(其他平台,不区分平台),有相应的手机号邮箱信息则自动绑定 //platformUser, platformErr := GetFirstWxUserItemByUnionId(unionId) //if platformErr == nil { // // 当公众号用户存在时 // if platformUser.Mobile != "" || platformUser.Email != "" { // // 有手机号或邮箱则绑定信息则自动绑定并新增wx_user // countryCode := 0 // if platformUser.CountryCode != "" { // countryCode, _ = strconv.Atoi(platformUser.CountryCode) // } // tempToken, tempUser, tempErr, errMsg := BindWxUser(openId, platformUser.Mobile, platformUser.Email, "", 3, countryCode, 1) // if tempErr != nil { // err = errors.New("自动绑定公众号用户失败,Err:" + tempErr.Error() + ", errMsg:" + errMsg) // return // } // token = tempToken // userId = int(tempUser.UserID) // isBind = true // return // } //} } else if wxUserErr != nil { err = wxUserErr return } //更新微信用户的sessionKey if needUpdateSessionKey { _ = user_record.ModifySessionKeyByOpenid(openId, sessionKey) } // 如果已经登录注册绑定的情况下/或者首次登录且为弘则研究公众号用户 if wxUserErr == nil { userId = int(wxUser.UserID) // 如果账户有绑定了手机号或者邮箱,那么标记为已绑定 if wxUser.Mobile != "" || wxUser.Email != "" { isBind = true } } //获取登录token tokenItem, tokenErr := session.GetTokenByOpenId(openId) if tokenErr != nil && tokenErr != utils.ErrNoRow { err = errors.New("登录失败,获取token失败:" + tokenErr.Error()) return } if tokenErr != nil && tokenErr == utils.ErrNoRow { timeUnix := time.Now().Unix() timeUnixStr := strconv.FormatInt(timeUnix, 10) token = utils.MD5(openId) + utils.MD5(timeUnixStr) //新增session { sessionItem := &session.Session{ OpenID: openId, UserID: int64(userId), CreatedTime: time.Now(), LastUpdatedTime: time.Now(), ExpireTime: time.Now().AddDate(0, 3, 0), AccessToken: token, } sessionErr := sessionItem.Create() if err != nil { err = errors.New("登录失败,新增用户session信息失败:" + sessionErr.Error()) return } } } else { token = tokenItem.AccessToken //如果联系人编号不为空,且联系人编号与session里面的联系人编号不一致的时候,需要做session变更 //if userId > 0 && tokenItem.UserID != int64(userId) { // _ = tokenItem.UpdateSession(int64(userId), time.Now().AddDate(0, 1, 0)) //} //if userId > 0 { //} _ = tokenItem.UpdateSession(int64(userId), time.Now().AddDate(0, 1, 0)) } //新增登录日志 { loginLog := &wx_user_log.WxUserLog{ UserID: userId, OpenID: openId, UnionID: unionId, CreateTime: time.Now(), Handle: "yb_login", Remark: token, } go loginLog.Create() } return } // AddUserRecord 添加第三方用户(微信)记录 func AddUserRecord(openId, unionId, nickName, realName, province, city, country, headimgurl, sessionKey string, platform, sex, subscribe int) (userRecordInfo *user_record.UserRecord, err error) { find, err := user_record.GetByOpenID(openId) if err == nil { userRecordInfo = find return } if err != utils.ErrNoRow { return } userRecordInfo = &user_record.UserRecord{ OpenID: openId, //用户open_id UnionID: unionId, //用户union_id Subscribe: int8(subscribe), NickName: nickName, //用户昵称,最大长度:32 RealName: realName, //用户实际名称,最大长度:32 Sex: int64(sex), //普通用户性别,1为男性,2为女性 Province: province, //普通用户个人资料填写的省份,最大长度:30 City: city, //普通用户个人资料填写的城市,最大长度:30 Country: country, //国家,如中国为CN,最大长度:30 Headimgurl: headimgurl, //用户第三方(微信)头像,最大长度:512 CreateTime: time.Now(), //创建时间,关系添加时间、用户授权时间 CreatePlatform: int8(platform), //注册平台,1:日度点评公众号,2:管理后台,3:pc端网站,4:查研观向小程序;默认:1 SessionKey: sessionKey, //微信小程序会话密钥,最大长度:255 } err = userRecordInfo.Create() return } // GetInfoByClaims 从Claims中获取用户信息 func GetInfoByClaims(c *gin.Context) (userInfo UserInfo) { //获取jwt数据失败 claims, _ := c.Get("userInfo") userInfo = claims.(UserInfo) return } // GetAdminByUserInfo 判断当前用户是否为内部人员 func GetAdminByUserInfo(userInfo UserInfo) (ok bool, adminInfo *admin2.Admin, err error) { mobile := userInfo.Mobile if mobile == "" { // 用户有可能是通过邮箱登录 return } if userInfo.CompanyID != utils.HzCompanyId { return } adminInfo, err = admin2.GetAdminByMobile(mobile) if err != nil { if err == utils.ErrNoRow { err = nil return } return } if adminInfo.Enabled != 1 { return } ok = true return } // GetResearcherByUserInfo 判断当前用户是否为研究员-以是否有研究分组为判断标准 func GetResearcherByUserInfo(userInfo UserInfo) (ok bool, adminInfo *admin2.Admin, err error) { mobile := userInfo.Mobile if mobile == "" { // 用户有可能是通过邮箱登录 return } if userInfo.CompanyID != utils.HzCompanyId { return } adminInfo, err = admin2.GetAdminByMobile(mobile) if err != nil { if err == utils.ErrNoRow { err = nil return } return } if adminInfo.Enabled != 1 { return } researchGroupList, e := research_variety_tag_relation.GetResearchVarietyTagRelationByAdminId(int(adminInfo.AdminID)) if e != nil { err = e return } if len(researchGroupList) > 0 { ok = true } return } // GetUserInfoByToken 通过token获取用户信息 func GetUserInfoByToken(token string) (userInfo UserInfo, err error) { sessionInfo, e := session.GetTokenByToken(token) if e != nil { err = errors.New("找不到对应session") return } if sessionInfo.SessionID <= 0 { err = errors.New("找不到对应session") return } if sessionInfo.OpenID != "" { u, e := GetWxUserItemByOpenId(sessionInfo.OpenID) if e != nil { err = errors.New("用户记录不存在或未绑定") return } userInfo = u } else { // PC端 u, e := GetWxUserItemByUserId(int(sessionInfo.UserID), utils.USER_RECORD_PLATFORM_PC) if e != nil { err = errors.New("用户PC记录不存在或未绑定") return } userInfo = u } return }