package jy import ( "fmt" "time" qutil "app.yhyue.com/moapp/jybase/common" mg "app.yhyue.com/moapp/jybase/mongodb" ) type PhoneUtil struct { UserMgoDB mg.MongodbSim } func NewPhoneUtil(db mg.MongodbSim) *PhoneUtil { return &PhoneUtil{db} } func (this *PhoneUtil) Log(userId, operation, value string) { go this.UserMgoDB.Save("user_relation_log", map[string]interface{}{ "s_userId": userId, "s_operation": operation, "s_updateValue": value, "l_createtime": time.Now().Unix(), }) } // 获取微信关联字段 func (this *PhoneUtil) getWxRelationMap(userId string) *map[string]interface{} { rData, _ := this.UserMgoDB.FindById("user", userId, `{"s_unionid":1,"s_name":1,"s_nickname":1,"s_headimageurl":1}`) if rData == nil || len(*rData) == 0 { return nil } delete(*rData, "_id") return rData } // 获取手机号 func (this *PhoneUtil) getUserPhone(userId string) (phone string) { rData, _ := this.UserMgoDB.FindById("user", userId, `{"s_phone":1}`) if rData != nil && len(*rData) > 0 { phone, _ = (*rData)["s_phone"].(string) } return } // 绑定微信 func (this *PhoneUtil) bindWeixin(phoneUserId string, wxRelationMap *map[string]interface{}, opera string) error { if !this.UserMgoDB.UpdateById("user", phoneUserId, map[string]interface{}{ "$set": wxRelationMap, }) { return fmt.Errorf("建立Phone绑定异常") } //存日志 this.Log(phoneUserId, fmt.Sprintf("%s_bindWeixin", opera), qutil.ObjToString((*wxRelationMap)["s_unionid"])) return nil } // 解绑微信 func (this *PhoneUtil) unBindWeixin(phoneUserId, opera string) error { //查询解绑微信unionid logMap := this.getWxRelationMap(phoneUserId) if !this.UserMgoDB.UpdateById("user", phoneUserId, map[string]interface{}{ "$unset": map[string]interface{}{"s_name": 1, "s_nickname": 1, "i_sex": 1, "s_country": 1, "s_province": 1, "s_city": 1, "s_headimageurl": 1, "s_m_openid": 1, "a_m_openid": 1, "i_ispush": 1, "s_unionid": 1, "i_applystatus": 1}, }) { return fmt.Errorf("解除微信关联异常") } //存日志 logUnionid := "" if logMap != nil && len(*logMap) > 0 { logUnionid, _ = (*logMap)["s_unionid"].(string) } this.Log(phoneUserId, fmt.Sprintf("%s_unBindWeixin", opera), logUnionid) return nil } // 绑定手机号 func (this *PhoneUtil) bindPhone(weixinUserId, phone, email, opera string) error { data := map[string]interface{}{ "s_m_phone": phone, "l_bindphonetime": time.Now().Unix(), } if EmailPattern.MatchString(email) { data["s_email"] = email } if !this.UserMgoDB.UpdateById("user", weixinUserId, map[string]interface{}{ "$set": data, }) { return fmt.Errorf("建立微信绑定异常") } //存日志 this.Log(weixinUserId, fmt.Sprintf("%s_bindPhone", opera), phone) return nil } // 解除手机号关联 func (this *PhoneUtil) unBindPhone(weixinUserId, opera string) error { logPhone := this.getUserPhone(weixinUserId) if !this.UserMgoDB.UpdateById("user", weixinUserId, map[string]interface{}{ "$unset": map[string]interface{}{"s_m_phone": 0}, }) { return fmt.Errorf("解除手机关联异常") } //存日志 this.Log(weixinUserId, fmt.Sprintf("%s_unBindPhone", opera), logPhone) return nil } //============================================= // 建立双向关联关系 func (this *PhoneUtil) buildRelation(wxUserId, phoneUserId, phone string, wxRelationMap *map[string]interface{}, opera string) error { //建立双向关联关系 if wxRelationMap == nil { wxRelationMap = this.getWxRelationMap(wxUserId) } if phone == "" { phone = this.getUserPhone(phoneUserId) } if wxRelationMap == nil || phone == "" { return fmt.Errorf("获取绑定关系异常") } if err := this.bindWeixin(phoneUserId, wxRelationMap, opera); err != nil { return err } if err := this.bindPhone(wxUserId, phone, qutil.InterfaceToStr((*wxRelationMap)["s_email"]), opera); err != nil { return err } return nil } // 解除双向绑定 func (this *PhoneUtil) RelieveRelation(weixinId, phoneId, opera string) error { if err := this.unBindPhone(weixinId, opera); err != nil { return err } if err := this.unBindWeixin(phoneId, opera); err != nil { return err } return nil } // 查询是否存在双向关联关系 func (this *PhoneUtil) QueryRelation(phone string) (wId, pId string, err error) { relationUser, _ := this.UserMgoDB.Find("user", map[string]interface{}{ "i_appid": 2, "$or": []map[string]interface{}{ map[string]interface{}{"s_phone": phone}, map[string]interface{}{"s_m_phone": phone}, }, }, nil, `{"s_phone":1}`, false, -1, -1) if relationUser == nil || len(*relationUser) == 0 { return "", "", fmt.Errorf("未查询到用户信息") } if len(*relationUser) > 2 { return "", "", fmt.Errorf("查询异常") } if len(*relationUser) == 2 { for _, m := range *relationUser { if m["s_phone"] != nil { pId = mg.BsonIdToSId((m)["_id"]) } else { wId = mg.BsonIdToSId((m)["_id"]) } } if pId == "" || wId == "" { return "", "", fmt.Errorf("获取用户异常") } } return } //============================================= /* 微信账号绑定手机号判断是否存在 param unionId:当前微信的s_unionid phone:要绑定的手机号 return exists:是否存在 relationPhoneId:需要建立关联关系的手机号用户id rule 1.不存在手机号,2.存在手机号用户,但此手机号未绑定微信 3.存在手机号用户,或绑定微信和当前账户绑定微信一致 */ func (this *PhoneUtil) BindPhoneIsOccupy(userId, unionId, phone string) (exists bool, relationPhoneId string) { //已经有微信账户绑定过 if this.UserMgoDB.Count("user", map[string]interface{}{"i_appid": 2, "s_m_phone": phone, "s_phone": map[string]interface{}{"$exists": 0}}) > 0 { return true, "" } relationUser, _ := this.UserMgoDB.Find("user", map[string]interface{}{ "i_appid": 2, "s_phone": phone, }, nil, `{"s_unionid":1}`, false, -1, -1) //不存在手机号用户 if relationUser == nil || len(*relationUser) == 0 { return false, "" } for _, userData := range *relationUser { unionidTmp, _ := userData["s_unionid"].(string) //没绑定微信或绑定微信和当前账户绑定微信一致 if unionidTmp == "" || unionidTmp == unionId { relationPhoneId = mg.BsonIdToSId(userData["_id"]) } else { return true, "" } } //但此手机号未绑定微信 if userId == relationPhoneId { return true, "" } return false, relationPhoneId } /* 绑定手机号 param wxUserId:绑定手机号的微信 relationPhoneId:存在关联的手机号账户 phone:绑定的手机号 wxRelationMap:相关联的微信信息 */ func (this *PhoneUtil) BindPhone(wxUserId, relationPhoneId, phone, email string, wxRelationMap *map[string]interface{}) error { if relationPhoneId == "" { //单独绑定手机号 return this.bindPhone(wxUserId, phone, email, "BindPhone") } else { //绑定及建立双向关联 return this.buildRelation(wxUserId, relationPhoneId, phone, wxRelationMap, "BindPhone") } } /* 更改手机号 param phone要更改的手机号 needMerge:当前账户是否需要合并 return exists:是否存在 relationPhoneId:需要建立关联关系的手机号用户id rule:在合并状态的微信账户,可以更换存在但未绑定微信的手机号;其他情况只能更换新手机号 */ func (this *PhoneUtil) ChangePhoneIsOccupy(phone string, isWxAndNeedMerge bool) (exists bool, relationPhoneId string) { if isWxAndNeedMerge { relationUser, _ := this.UserMgoDB.Find("user", map[string]interface{}{ "i_appid": 2, "$or": []map[string]interface{}{ map[string]interface{}{ //存在手机号未绑定微信的用户 "s_unionid": map[string]interface{}{"$exists": 1}, "s_phone": phone, }, map[string]interface{}{ //手机号已绑定 "s_m_phone": phone, }, }, }, nil, `{"s_unionid":1,"s_phone":1}`, false, -1, -1) if relationUser == nil || len(*relationUser) == 0 { return false, "" } for _, userData := range *relationUser { if userData["s_unionid"] == nil && userData["s_phone"] != nil { return false, mg.BsonIdToSId(userData["_id"]) } } return true, "" } else { if this.UserMgoDB.Count("user", map[string]interface{}{ "i_appid": 2, "$or": []map[string]interface{}{ map[string]interface{}{ //手机号用户 "s_m_phone": phone, }, map[string]interface{}{ //手机号已被绑定的用户 "s_phone": phone, }, }, }) > 0 { return true, "" } } return false, "" } /* 手机号账号绑定微信判断微信是否存在 param phone:当前手机号 unionId:要绑定的微信s_unionid return exists:是否存在 relationWeixinId:需要建立关联关系的微信用户id rule 存在对应的微信 1.未绑定手机号 2.绑定手机号为当前账户手机号 */ func (this *PhoneUtil) BindWeixinIsOccupy(phone, unionId string) (exists bool, relationWeixinId string) { if wxBindNum := this.UserMgoDB.Count("user", map[string]interface{}{"i_appid": 2, "s_unionid": unionId}); wxBindNum > 0 { relationUser, _ := this.UserMgoDB.FindOneByField("user", map[string]interface{}{ "i_appid": 2, "s_unionid": unionId, "s_phone": map[string]interface{}{"$exists": 0}, "$or": []map[string]interface{}{ map[string]interface{}{ "s_m_phone": map[string]interface{}{"$exists": 0}, }, map[string]interface{}{ "s_m_phone": phone, }, }, }, `{"_id":1}`) if relationUser != nil && len(*relationUser) > 0 { if relation := mg.BsonIdToSId((*relationUser)["_id"]); relation != "" { return false, mg.BsonIdToSId((*relationUser)["_id"]) } } return true, "" } //全新微信账户 return false, "" } /* 手机号账号绑定微信 param phoneUserId:绑定微信的手机账户 relationWeixinId:存在相关联的微信信息 phone:当前手机账号手机号 wxRelationMap:相关联的微信信息 */ func (this *PhoneUtil) BindWeixin(phoneUserId, relationWeixinId, phone string, wxRelationMap *map[string]interface{}, opear ...string) error { logFlag := "BindWeixin" if len(opear) == 1 { logFlag = opear[0] } if relationWeixinId == "" { return this.bindWeixin(phoneUserId, wxRelationMap, logFlag) } else { return this.buildRelation(relationWeixinId, phoneUserId, phone, wxRelationMap, logFlag) } } /* 手机号解绑微信 param phoneUserId:绑定微信的手机账户 relationWeixinId:存在相关联的微信信息 */ func (this *PhoneUtil) UnBindWeixin(phoneUserId, relationWeixinId string, opear ...string) error { logFlag := "UnBindWeixin" if len(opear) == 1 { logFlag = opear[0] } if relationWeixinId == "" { return this.unBindWeixin(phoneUserId, logFlag) } else { return this.RelieveRelation(relationWeixinId, phoneUserId, logFlag) } }