xmy 3 anni fa
parent
commit
eb81061b1e
4 ha cambiato i file con 322 aggiunte e 1 eliminazioni
  1. 24 1
      config/config.go
  2. 8 0
      etc/config.yaml
  3. 102 0
      services/share/service.go
  4. 188 0
      services/share/sharecommon.go

+ 24 - 1
config/config.go

@@ -5,6 +5,7 @@ import (
 	qrpc "app.yhyue.com/moapp/message/model"
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/os/gcfg"
+	"github.com/gogf/gf/v2/os/gctx"
 )
 
 type config struct {
@@ -39,7 +40,10 @@ type config struct {
 	}
 }
 
-var PushConfig *pushConfig
+var (
+	PushConfig *pushConfig
+	Wx         *SysConfig
+)
 
 type pushConfig struct {
 	Webdomain    string `json:"webdomain"`
@@ -58,6 +62,16 @@ type pushConfig struct {
 	DelayedTime int    `json:"delayedTime"`
 }
 
+type SysConfig struct {
+	WxJianyu struct {
+		Appid     string `json:"appid"`
+		Appsecret string `json:"appsecret"`
+	} `json:"wxJianyu"`
+	Weixinrpc      string `json:"weixinrpc"`
+	PcSessionFlag  bool   `json:"pcSessionFlag"`
+	SessionTimeout int64  `json:"sessionTimeout"`
+}
+
 //var Config *config
 
 func init() {
@@ -66,4 +80,13 @@ func init() {
 	//系统配置文件
 	//common.ReadConfig(&Config)
 	g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetFileName("./etc/config.yaml")
+	var sysConfig SysConfig
+	if err := gcfg.Instance().MustGet(gctx.New(), "wx").Scan(&sysConfig); err == nil {
+		Wx = &SysConfig{
+			WxJianyu:       sysConfig.WxJianyu,
+			Weixinrpc:      sysConfig.Weixinrpc,
+			PcSessionFlag:  sysConfig.PcSessionFlag,
+			SessionTimeout: sysConfig.SessionTimeout,
+		}
+	}
 }

+ 8 - 0
etc/config.yaml

@@ -63,3 +63,11 @@ docPoints:
     max: 5
     jydocs_doc_open: 5
     jyweb_article_open: 5
+#wx
+wx:
+  wxJianyu:
+    appid: wxdedd73f450993685
+    appsecret: d55898fde0b7887e5fe4660bd2494700
+  weixinrpc: 127.0.0.1:8083
+  pcSessionFlag: true
+  sessionTimeout: 168

+ 102 - 0
services/share/service.go

@@ -12,6 +12,8 @@ import (
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/net/ghttp"
 	"log"
+	"net/url"
+	"regexp"
 	"strings"
 )
 
@@ -107,6 +109,11 @@ func (c *ShareRouter) List(r *ghttp.Request) {
 	}
 	count := db.Mgo.Count("user_share", query)
 	if count == 0 {
+		r.Response.WriteJson(g.Map{
+			"error_code": 0,
+			"error_msg":  "",
+			"data":       rdata,
+		})
 		return
 	}
 	result, _ := db.Mgo.Find("user_share", query, `{"createtime":-1}`, `{"shared_uid":1}`, false, pNum*pSize, pSize)
@@ -121,3 +128,98 @@ func (c *ShareRouter) List(r *ghttp.Request) {
 		"data":       rdata,
 	})
 }
+
+func (c *ShareRouter) Followgift(r *ghttp.Request) {
+	client := r.Header.Get("User-Agent")
+	var mobileReg = regexp.MustCompile("(?i)(Android|Mobile|Phone)")
+	Wxoauth := `https://open.weixin.qq.com/connect/oauth2/authorize?appid=` + qu.ObjToString(config.Wx.WxJianyu.Appid) + `&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect`
+	fdata := map[string]interface{}{
+		"error_code": 0,
+		"error_msg":  "",
+	}
+	idata := map[string]interface{}{}
+	bm := mobileReg.MatchString(client)
+	openid := r.Header.Get("s_m_openid")
+	nickname := r.Header.Get("s_nickname")
+	redisName := "other"
+	headImg := ""
+	qrstr := ""
+	infos := ""
+	shareid := r.Get("shareId").String()
+	if !strings.Contains(shareid, "shareId_") {
+		rdata, ok := db.Mgo.FindOneByField("user", map[string]interface{}{"s_m_openid": shareid, "i_appid": 2}, `{"_id":1}`)
+		if rdata != nil && ok && len(*rdata) > 0 {
+			uid := BsonIdToSId((*rdata)["_id"])
+			infos = redis.GetStr(redisName, fmt.Sprintf("SF_%s", uid))
+		}
+	}
+	if shareUserid := redis.GetStr(redisName, shareid); shareUserid == "" && infos == "" {
+		r.Response.WriteJson(g.Map{
+			"error_code": -1,
+			"error_msg":  "无数据",
+		})
+		return
+	} else {
+		if infos == "" {
+			infos = redis.GetStr(redisName, fmt.Sprintf("SF_%s", shareUserid))
+		}
+		if infos != "" {
+			nickname = strings.Split(infos, "#@#@")[1]
+			headImg = strings.Split(infos, "#@#@")[2]
+			link := fmt.Sprintf("%s/front/followGift/%s", qu.ObjToString(config.PushConfig.Webdomain), strings.Split(infos, "#@#@")[3])
+			r, _ := qr.Encode(link, qr.M)
+			pngdat := r.PNG()
+			qrstr = base64.StdEncoding.EncodeToString(pngdat)
+			shareid = strings.Split(infos, "#@#@")[3]
+			if IsPhone(nickname) {
+				nickname = string(nickname[0:3]) + "****" + string(nickname[len(nickname)-4:])
+			}
+		}
+	}
+	if bm {
+		if openid == "" {
+			if r.Header.Get("s_m_openid") == "" {
+				if r.Get("state").String() == "wx" {
+					//微信跳回来的
+					code := r.Get("code").String()
+					if code != "" {
+						openid = Getopenid(code)
+						if openid != "" {
+							if CheckUserIsSubscribe(openid) {
+								FindUserAndCreateSess(openid, r.Session, "wx", false)
+							}
+						}
+					}
+				} else {
+					if CheckWxBrowser(r.Request) {
+						//所有参数都不再使用,跳到微信验证用户
+						idata["data"] = fmt.Sprintf(Wxoauth, url.QueryEscape(r.Host+r.URL.String()), "wx")
+						fdata["data"] = idata
+						r.Response.WriteJson(fdata)
+					}
+				}
+			}
+		}
+		idata["shareid"] = shareid
+		idata["share_nickname"] = nickname
+		idata["share_headImg"] = headImg
+		idata["openid"] = se.SE.EncodeString(openid)
+		idata["share_qr"] = qrstr
+		mynickname := r.Header.Get("s_nickname")
+		myavatar := r.Header.Get("s_avatar")
+		idata["nickname"] = mynickname
+		idata["avatar"] = myavatar
+		idata["signature"] = SignJSSDK(r.Host + r.URL.String())
+		fdata["data"] = idata
+		r.Response.WriteJson(fdata)
+	} else {
+		idata["shareid"] = shareid
+		idata["share_nickname"] = nickname
+		idata["share_headImg"] = headImg
+		idata["signature"] = SignJSSDK(r.Host + r.URL.String())
+		idata["isWeixin"] = CheckWxBrowser(r.Request)
+		idata["share_qr"] = qrstr
+		fdata["data"] = idata
+		r.Response.WriteJson(fdata)
+	}
+}

+ 188 - 0
services/share/sharecommon.go

@@ -2,13 +2,22 @@ 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"
@@ -57,6 +66,185 @@ func timeOut() int {
 	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"`