package share import ( qu "app.yhyue.com/moapp/jybase/common" se "app.yhyue.com/moapp/jybase/encrypt" "app.yhyue.com/moapp/jybase/redis" "app.yhyue.com/moapp/message/config" "app.yhyue.com/moapp/message/db" "bytes" cr "crypto/rand" "encoding/json" "fmt" "github.com/gogf/gf/v2/os/gsession" "go.mongodb.org/mongo-driver/bson/primitive" "io/ioutil" "log" "math/big" "math/rand" "net/http" "net/rpc" "regexp" "strings" "sync" "time" ) var PhoneReg = regexp.MustCompile("^[1][3-9][0-9]{9}$") //获取用户头像,手机号 func GetInfo(userid string) map[string]interface{} { rdata, ok := db.Mgo.FindById("user", userid, `{"s_headimageurl":1,"s_headimage":1,"s_phone":1,"s_m_phone":1,"s_nickname":1,"l_registedate":1}`) if ok && len(*rdata) > 0 && rdata != nil { nickname, headimageurl := "", "" if s_phone, _ := (*rdata)["s_phone"].(string); s_phone != "" { nickname = s_phone } else if s_m_phone, _ := (*rdata)["s_m_phone"].(string); s_m_phone != "" { nickname = s_m_phone } else if s_nickname, _ := (*rdata)["s_nickname"].(string); s_nickname != "" { nickname = s_nickname } if IsPhone(nickname) { nickname = string(nickname[0:3]) + "****" + string(nickname[len(nickname)-4:]) } if s_headimageurl, _ := (*rdata)["s_headimageurl"].(string); s_headimageurl != "" { headimageurl = s_headimageurl } else if s_headimage, _ := (*rdata)["s_headimage"].(string); s_headimage != "" { headimageurl = config.PushConfig.Webdomain + s_headimage } return map[string]interface{}{ "nickname": nickname, "headimageurl": headimageurl, "createtime": (*rdata)["l_registedate"], } } return nil } //手机号校验 func IsPhone(phone string) bool { return PhoneReg.MatchString(phone) } //到期时间 func timeOut() int { now := time.Now() return int(now.AddDate(0, 0, 7).Unix() - now.Unix()) } func BsonIdToSId(uid interface{}) string { if uid == nil { return "" } else if u, ok := uid.(string); ok { return u } else if u, ok := uid.(primitive.ObjectID); ok { return u.Hex() } else { return "" } } //获取用户openid func Getopenid(code string) (openid string) { //Wxoauth := `https://open.weixin.qq.com/connect/oauth2/authorize?appid=` + qu.ObjToString(WeixinConfig["appid"]) + `&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect` Wxoauthinfo := `https://api.weixin.qq.com/sns/oauth2/access_token?appid=` + qu.ObjToString(config.Wx.WxJianyu.Appid) + `&secret=` + qu.ObjToString(config.Wx.WxJianyu.Appsecret) + `&code=%s&grant_type=authorization_code` recturl := fmt.Sprintf(Wxoauthinfo, code) resp, err := http.Get(recturl) if err != nil { log.Println(err.Error()) return } defer resp.Body.Close() bs, _ := ioutil.ReadAll(resp.Body) data := map[string]interface{}{} json.Unmarshal(bs, &data) openid, _ = data["openid"].(string) return } //检查用户是否关注 func CheckUserIsSubscribe(openid string) bool { user, ok := db.Mgo.FindOneByField("user", map[string]interface{}{ "i_appid": 2, "s_m_openid": openid, "s_unionid": map[string]interface{}{"$ne": openid}, }, `{"i_ispush":1}`) if ok && user != nil { if (*user)["_id"] == nil || qu.IntAllDef((*user)["i_ispush"], 1) == 0 { return false } else { return true } } return false } //wxsdk func SignJSSDK(url string) []string { var signature []string var key = "wxsignature_" + url if ret := redis.Get("other", key); ret != nil { if d, err := json.Marshal(ret); err == nil { json.Unmarshal(d, &signature) } } if signature == nil || len(signature) == 0 { qu.Try(func() { client, err := rpc.DialHTTP("tcp", qu.ObjToString(config.Wx.Weixinrpc)) defer client.Close() if err != nil { log.Println(err.Error()) return } err = client.Call("WeiXinRpc.GetJSInterfaceParam", url, &signature) if err != nil { log.Println(err.Error()) } }, func(e interface{}) {}) if signature == nil || len(signature) != 4 || signature[3] == "" { signature = []string{"", "", "", ""} } else { redis.Put("other", key, signature, 90*60) } } return signature } //判断是否是微信访问 func CheckWxBrowser(Request *http.Request) bool { if strings.Index(Request.UserAgent(), "MicroMessenger") > -1 || strings.Index(Request.UserAgent(), "Wechat") > -1 { return true } else { return false } } //查找用户并创建session func FindUserAndCreateSess(openid string, sess *gsession.Session, typ string, flag bool) (bool, *map[string]interface{}, map[string]interface{}) { return CreateSession(map[string]interface{}{ "s_m_openid": openid, "s_unionid": map[string]interface{}{"$ne": openid}, //处理排除未关注用户点击菜单创建的用户 "i_ispush": 1, }, sess, typ, flag) } func CreateSession(q map[string]interface{}, sess *gsession.Session, typ string, flag bool) (bool, *map[string]interface{}, map[string]interface{}) { if q == nil || len(q) == 0 { return false, nil, nil } person, sessionVal := GetSessionVal(q) if person == nil { return false, nil, nil } userid := qu.ObjToString(sessionVal["userId"]) if pcSessionFlag := config.Wx.PcSessionFlag; pcSessionFlag && flag { //无限制登陆用户 if qu.IntAll(sessionVal["i_unlimited"]) <= 0 { redis.Put("other", LoginRedisKey(userid), sess.Id, 3600*qu.IntAllDef(config.Wx.SessionTimeout, 168)) } } sessionVal["platform"] = typ //sess.SetMultiple(sessionVal) sess.SetMap(sessionVal) s_nickname := qu.If(sessionVal["s_nickname"] != nil, sessionVal["s_nickname"], sessionVal["phone"]) if qu.ObjToString(s_nickname) == "" { s_nickname = sessionVal["s_jyname"] } infoData := map[string]interface{}{ "result": "ok", "s_nickname": s_nickname, "s_headimage": sessionVal["s_avatar"], } if openid, _ := (*person)["s_m_openid"].(string); openid != "" { infoData["openid"] = se.SE.EncodeString(openid) } else { infoData["openid"] = "" } //大会员动画 清除首页缓存 redis.Del("other", "jypcindex") //清除企业基础架构给虚拟账号重置密码后需要重新登录的标识 redis.Del("other", "resetpwd_"+userid) return true, person, infoData } //value 用户sessionid func LoginRedisKey(userid string) string { return fmt.Sprintf("login_%s", userid) } // func GetSessionVal(q map[string]interface{}) (*map[string]interface{}, map[string]interface{}) { person, ok := db.Mgo.FindOneByField("user", q, `{"_id":1,"i_shareknow":1,"s_m_openid":1,"s_nickname":1,"s_headimage":1,"s_headimageurl":1,"s_phone":1,"s_m_phone":1,"l_registedate":1,"b_merge_remind":1,"i_ispush":1,"i_unlimited":1,"s_jyname":1}`) sessionVal := make(map[string]interface{}) if !ok || person == nil || len(*person) == 0 { return nil, sessionVal } sessionVal["user"] = *person if (*person)["i_shareknow"] != nil { sessionVal["shareknow"] = (*person)["i_shareknow"] } sessionVal["userId"] = BsonIdToSId((*person)["_id"]) nickName, _ := (*person)["s_nickname"].(string) phone := qu.ObjToString((*person)["s_phone"]) if nickName == "" { if phone != "" && len(phone) > 3 { nickName = string(phone[0:3]) + "****" + string(phone[len(phone)-4:]) } } if qu.ObjToString((*person)["s_jyname"]) != "" { sessionVal["s_jyname"] = qu.ObjToString((*person)["s_jyname"]) } sessionVal["s_nickname"] = nickName sessionVal["nickname"] = nickName avatar, _ := (*person)["s_headimageurl"].(string) if avatar == "" { avatar, _ = (*person)["s_headimage"].(string) } sessionVal["s_avatar"] = strings.Replace(avatar, "http://", "https://", 1) sessionVal["s_m_openid"], _ = (*person)["s_m_openid"].(string) sessionVal["openid"] = sessionVal["s_m_openid"] if phone == "" { phone = qu.ObjToString((*person)["s_m_phone"]) } sessionVal["phone"] = phone sessionVal["i_unlimited"] = qu.IntAll((*person)["i_unlimited"]) return person, sessionVal } type UserInfo struct { HeadImg interface{} `json:"headimg"` Name interface{} `json:"name"` Createtime interface{} `json:"createtime"` } func Info(data *[]map[string]interface{}) []*UserInfo { userinfo := []*UserInfo{} if len(*data) > 0 { for _, v := range *data { sharedId := qu.ObjToString(v["shared_uid"]) if rdata := GetInfo(sharedId); rdata != nil { userinfo = append(userinfo, &UserInfo{ HeadImg: rdata["headimageurl"], Name: rdata["nickname"], Createtime: rdata["createtime"], }) } } } return userinfo } var VarLSCPool = &LSCPool{ JobQueue: make(chan string, 10), WorkerNum: 10, Lock: &sync.Mutex{}, Randoms: "", } type LSCPool struct { JobQueue chan string //待取的口令 WorkerNum int //当前工作的协程数 Lock *sync.Mutex //口令锁 Randoms string //口令集合 } func (this *LSCPool) GetJob() string { return <-this.JobQueue } var r *rand.Rand func init() { r = rand.New(rand.NewSource(time.Now().Unix())) for i := 0; i < VarLSCPool.WorkerNum/2; i++ { go func() { for { VarLSCPool.JobQueue <- VarLSCPool.GetRandom() } }() } } //获取随机字符串 func (this *LSCPool) GetRandom() string { this.Lock.Lock() defer this.Lock.Unlock() //如果使用过了 重新获取 for { LSC := this.SpecialChar(0) + this.LetterRandom(8) if strings.Contains(this.Randoms, LSC) { continue } this.Randoms += LSC + "|" ok, _ := redis.Exists("other", "shareId_"+LSC) if ok { continue } return LSC } return "" } //字母随机串 func (this *LSCPool) LetterRandom(LL int) (LR string) { bytes := make([]byte, LL) for i := 0; i < LL; i++ { b := r.Intn(26) + 65 bytes[i] = byte(b) } LR = string(bytes) return } //特殊字符随机串 func (this *LSCPool) SpecialChar(LL int) (SC string) { var str = "$#" b := bytes.NewBufferString(str) length := b.Len() bigInt := big.NewInt(int64(length)) for i := 0; i < LL; i++ { randomInt, _ := cr.Int(cr.Reader, bigInt) SC += string(str[randomInt.Int64()]) } return }