sharecommon.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package share
  2. import (
  3. qu "app.yhyue.com/moapp/jybase/common"
  4. se "app.yhyue.com/moapp/jybase/encrypt"
  5. "app.yhyue.com/moapp/jybase/redis"
  6. "app.yhyue.com/moapp/message/config"
  7. "app.yhyue.com/moapp/message/db"
  8. "bytes"
  9. cr "crypto/rand"
  10. "encoding/json"
  11. "fmt"
  12. "github.com/gogf/gf/v2/os/gsession"
  13. "go.mongodb.org/mongo-driver/bson/primitive"
  14. "io/ioutil"
  15. "log"
  16. "math/big"
  17. "math/rand"
  18. "net/http"
  19. "net/rpc"
  20. "regexp"
  21. "strings"
  22. "sync"
  23. "time"
  24. )
  25. var PhoneReg = regexp.MustCompile("^[1][3-9][0-9]{9}$")
  26. //获取用户头像,手机号
  27. func GetInfo(userid string) map[string]interface{} {
  28. 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}`)
  29. if ok && len(*rdata) > 0 && rdata != nil {
  30. nickname, headimageurl := "", ""
  31. if s_phone, _ := (*rdata)["s_phone"].(string); s_phone != "" {
  32. nickname = s_phone
  33. } else if s_m_phone, _ := (*rdata)["s_m_phone"].(string); s_m_phone != "" {
  34. nickname = s_m_phone
  35. } else if s_nickname, _ := (*rdata)["s_nickname"].(string); s_nickname != "" {
  36. nickname = s_nickname
  37. }
  38. if IsPhone(nickname) {
  39. nickname = string(nickname[0:3]) + "****" + string(nickname[len(nickname)-4:])
  40. }
  41. if s_headimageurl, _ := (*rdata)["s_headimageurl"].(string); s_headimageurl != "" {
  42. headimageurl = s_headimageurl
  43. } else if s_headimage, _ := (*rdata)["s_headimage"].(string); s_headimage != "" {
  44. headimageurl = config.PushConfig.Webdomain + s_headimage
  45. }
  46. return map[string]interface{}{
  47. "nickname": nickname,
  48. "headimageurl": headimageurl,
  49. "createtime": (*rdata)["l_registedate"],
  50. }
  51. }
  52. return nil
  53. }
  54. //手机号校验
  55. func IsPhone(phone string) bool {
  56. return PhoneReg.MatchString(phone)
  57. }
  58. //到期时间
  59. func timeOut() int {
  60. now := time.Now()
  61. return int(now.AddDate(0, 0, 7).Unix() - now.Unix())
  62. }
  63. func BsonIdToSId(uid interface{}) string {
  64. if uid == nil {
  65. return ""
  66. } else if u, ok := uid.(string); ok {
  67. return u
  68. } else if u, ok := uid.(primitive.ObjectID); ok {
  69. return u.Hex()
  70. } else {
  71. return ""
  72. }
  73. }
  74. //获取用户openid
  75. func Getopenid(code string) (openid string) {
  76. //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`
  77. 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`
  78. recturl := fmt.Sprintf(Wxoauthinfo, code)
  79. resp, err := http.Get(recturl)
  80. if err != nil {
  81. log.Println(err.Error())
  82. return
  83. }
  84. defer resp.Body.Close()
  85. bs, _ := ioutil.ReadAll(resp.Body)
  86. data := map[string]interface{}{}
  87. json.Unmarshal(bs, &data)
  88. openid, _ = data["openid"].(string)
  89. return
  90. }
  91. //检查用户是否关注
  92. func CheckUserIsSubscribe(openid string) bool {
  93. user, ok := db.Mgo.FindOneByField("user", map[string]interface{}{
  94. "i_appid": 2,
  95. "s_m_openid": openid,
  96. "s_unionid": map[string]interface{}{"$ne": openid},
  97. }, `{"i_ispush":1}`)
  98. if ok && user != nil {
  99. if (*user)["_id"] == nil || qu.IntAllDef((*user)["i_ispush"], 1) == 0 {
  100. return false
  101. } else {
  102. return true
  103. }
  104. }
  105. return false
  106. }
  107. //wxsdk
  108. func SignJSSDK(url string) []string {
  109. var signature []string
  110. var key = "wxsignature_" + url
  111. if ret := redis.Get("other", key); ret != nil {
  112. if d, err := json.Marshal(ret); err == nil {
  113. json.Unmarshal(d, &signature)
  114. }
  115. }
  116. if signature == nil || len(signature) == 0 {
  117. qu.Try(func() {
  118. client, err := rpc.DialHTTP("tcp", qu.ObjToString(config.Wx.Weixinrpc))
  119. defer client.Close()
  120. if err != nil {
  121. log.Println(err.Error())
  122. return
  123. }
  124. err = client.Call("WeiXinRpc.GetJSInterfaceParam", url, &signature)
  125. if err != nil {
  126. log.Println(err.Error())
  127. }
  128. }, func(e interface{}) {})
  129. if signature == nil || len(signature) != 4 || signature[3] == "" {
  130. signature = []string{"", "", "", ""}
  131. } else {
  132. redis.Put("other", key, signature, 90*60)
  133. }
  134. }
  135. return signature
  136. }
  137. //判断是否是微信访问
  138. func CheckWxBrowser(Request *http.Request) bool {
  139. if strings.Index(Request.UserAgent(), "MicroMessenger") > -1 || strings.Index(Request.UserAgent(), "Wechat") > -1 {
  140. return true
  141. } else {
  142. return false
  143. }
  144. }
  145. //查找用户并创建session
  146. func FindUserAndCreateSess(openid string, sess *gsession.Session, typ string, flag bool) (bool, *map[string]interface{}, map[string]interface{}) {
  147. return CreateSession(map[string]interface{}{
  148. "s_m_openid": openid,
  149. "s_unionid": map[string]interface{}{"$ne": openid}, //处理排除未关注用户点击菜单创建的用户
  150. "i_ispush": 1,
  151. }, sess, typ, flag)
  152. }
  153. func CreateSession(q map[string]interface{}, sess *gsession.Session, typ string, flag bool) (bool, *map[string]interface{}, map[string]interface{}) {
  154. if q == nil || len(q) == 0 {
  155. return false, nil, nil
  156. }
  157. person, sessionVal := GetSessionVal(q)
  158. if person == nil {
  159. return false, nil, nil
  160. }
  161. userid := qu.ObjToString(sessionVal["userId"])
  162. if pcSessionFlag := config.Wx.PcSessionFlag; pcSessionFlag && flag {
  163. //无限制登陆用户
  164. if qu.IntAll(sessionVal["i_unlimited"]) <= 0 {
  165. redis.Put("other", LoginRedisKey(userid), sess.Id, 3600*qu.IntAllDef(config.Wx.SessionTimeout, 168))
  166. }
  167. }
  168. sessionVal["platform"] = typ
  169. //sess.SetMultiple(sessionVal)
  170. sess.SetMap(sessionVal)
  171. s_nickname := qu.If(sessionVal["s_nickname"] != nil, sessionVal["s_nickname"], sessionVal["phone"])
  172. if qu.ObjToString(s_nickname) == "" {
  173. s_nickname = sessionVal["s_jyname"]
  174. }
  175. infoData := map[string]interface{}{
  176. "result": "ok",
  177. "s_nickname": s_nickname,
  178. "s_headimage": sessionVal["s_avatar"],
  179. }
  180. if openid, _ := (*person)["s_m_openid"].(string); openid != "" {
  181. infoData["openid"] = se.SE.EncodeString(openid)
  182. } else {
  183. infoData["openid"] = ""
  184. }
  185. //大会员动画 清除首页缓存
  186. redis.Del("other", "jypcindex")
  187. //清除企业基础架构给虚拟账号重置密码后需要重新登录的标识
  188. redis.Del("other", "resetpwd_"+userid)
  189. return true, person, infoData
  190. }
  191. //value 用户sessionid
  192. func LoginRedisKey(userid string) string {
  193. return fmt.Sprintf("login_%s", userid)
  194. }
  195. //
  196. func GetSessionVal(q map[string]interface{}) (*map[string]interface{}, map[string]interface{}) {
  197. 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}`)
  198. sessionVal := make(map[string]interface{})
  199. if !ok || person == nil || len(*person) == 0 {
  200. return nil, sessionVal
  201. }
  202. sessionVal["user"] = *person
  203. if (*person)["i_shareknow"] != nil {
  204. sessionVal["shareknow"] = (*person)["i_shareknow"]
  205. }
  206. sessionVal["userId"] = BsonIdToSId((*person)["_id"])
  207. nickName, _ := (*person)["s_nickname"].(string)
  208. phone := qu.ObjToString((*person)["s_phone"])
  209. if nickName == "" {
  210. if phone != "" && len(phone) > 3 {
  211. nickName = string(phone[0:3]) + "****" + string(phone[len(phone)-4:])
  212. }
  213. }
  214. if qu.ObjToString((*person)["s_jyname"]) != "" {
  215. sessionVal["s_jyname"] = qu.ObjToString((*person)["s_jyname"])
  216. }
  217. sessionVal["s_nickname"] = nickName
  218. sessionVal["nickname"] = nickName
  219. avatar, _ := (*person)["s_headimageurl"].(string)
  220. if avatar == "" {
  221. avatar, _ = (*person)["s_headimage"].(string)
  222. }
  223. sessionVal["s_avatar"] = strings.Replace(avatar, "http://", "https://", 1)
  224. sessionVal["s_m_openid"], _ = (*person)["s_m_openid"].(string)
  225. sessionVal["openid"] = sessionVal["s_m_openid"]
  226. if phone == "" {
  227. phone = qu.ObjToString((*person)["s_m_phone"])
  228. }
  229. sessionVal["phone"] = phone
  230. sessionVal["i_unlimited"] = qu.IntAll((*person)["i_unlimited"])
  231. return person, sessionVal
  232. }
  233. type UserInfo struct {
  234. HeadImg interface{} `json:"headimg"`
  235. Name interface{} `json:"name"`
  236. Createtime interface{} `json:"createtime"`
  237. }
  238. func Info(data *[]map[string]interface{}) []*UserInfo {
  239. userinfo := []*UserInfo{}
  240. if len(*data) > 0 {
  241. for _, v := range *data {
  242. sharedId := qu.ObjToString(v["shared_uid"])
  243. if rdata := GetInfo(sharedId); rdata != nil {
  244. userinfo = append(userinfo, &UserInfo{
  245. HeadImg: rdata["headimageurl"],
  246. Name: rdata["nickname"],
  247. Createtime: rdata["createtime"],
  248. })
  249. }
  250. }
  251. }
  252. return userinfo
  253. }
  254. var VarLSCPool = &LSCPool{
  255. JobQueue: make(chan string, 10),
  256. WorkerNum: 10,
  257. Lock: &sync.Mutex{},
  258. Randoms: "",
  259. }
  260. type LSCPool struct {
  261. JobQueue chan string //待取的口令
  262. WorkerNum int //当前工作的协程数
  263. Lock *sync.Mutex //口令锁
  264. Randoms string //口令集合
  265. }
  266. func (this *LSCPool) GetJob() string {
  267. return <-this.JobQueue
  268. }
  269. var r *rand.Rand
  270. func init() {
  271. r = rand.New(rand.NewSource(time.Now().Unix()))
  272. for i := 0; i < VarLSCPool.WorkerNum/2; i++ {
  273. go func() {
  274. for {
  275. VarLSCPool.JobQueue <- VarLSCPool.GetRandom()
  276. }
  277. }()
  278. }
  279. }
  280. //获取随机字符串
  281. func (this *LSCPool) GetRandom() string {
  282. this.Lock.Lock()
  283. defer this.Lock.Unlock()
  284. //如果使用过了 重新获取
  285. for {
  286. LSC := this.SpecialChar(0) + this.LetterRandom(8)
  287. if strings.Contains(this.Randoms, LSC) {
  288. continue
  289. }
  290. this.Randoms += LSC + "|"
  291. ok, _ := redis.Exists("other", "shareId_"+LSC)
  292. if ok {
  293. continue
  294. }
  295. return LSC
  296. }
  297. return ""
  298. }
  299. //字母随机串
  300. func (this *LSCPool) LetterRandom(LL int) (LR string) {
  301. bytes := make([]byte, LL)
  302. for i := 0; i < LL; i++ {
  303. b := r.Intn(26) + 65
  304. bytes[i] = byte(b)
  305. }
  306. LR = string(bytes)
  307. return
  308. }
  309. //特殊字符随机串
  310. func (this *LSCPool) SpecialChar(LL int) (SC string) {
  311. var str = "$#"
  312. b := bytes.NewBufferString(str)
  313. length := b.Len()
  314. bigInt := big.NewInt(int64(length))
  315. for i := 0; i < LL; i++ {
  316. randomInt, _ := cr.Int(cr.Reader, bigInt)
  317. SC += string(str[randomInt.Int64()])
  318. }
  319. return
  320. }