Forráskód Böngészése

feat:分享接口

xmy 3 éve
szülő
commit
a86a5719ec
4 módosított fájl, 296 hozzáadás és 8 törlés
  1. 16 1
      db/db.go
  2. 9 2
      etc/config.yaml
  3. 115 5
      services/share/service.go
  4. 156 0
      services/share/sharecommon.go

+ 16 - 1
db/db.go

@@ -9,7 +9,10 @@ import (
 	"app.yhyue.com/moapp/jybase/redis"
 )
 
-var Mgo_Log *mongodb.MongodbSim
+var (
+	Mgo_Log *mongodb.MongodbSim
+	Mgo     *mongodb.MongodbSim
+)
 
 type MgoConf struct {
 	Address         string
@@ -39,5 +42,17 @@ func init() {
 		Mgo_Log.InitPool()
 		log.Printf("初始化 mongodb log 完成 %+v\n", mgoConf)
 	}
+	if err := gcfg.Instance().MustGet(gctx.New(), "databases.mongodb").Scan(&mgoConf); err == nil {
+		Mgo = &mongodb.MongodbSim{
+			MongodbAddr: mgoConf.Address,
+			Size:        mgoConf.Size,
+			DbName:      mgoConf.DbName,
+			ReplSet:     mgoConf.ReplSet,
+			UserName:    mgoConf.UserName,
+			Password:    mgoConf.Password,
+		}
+		Mgo.InitPool()
+		log.Printf("初始化 mongodb 完成 %+v\n", mgoConf)
+	}
 
 }

+ 9 - 2
etc/config.yaml

@@ -31,12 +31,12 @@ etcd:
 
 #消息队列
 nsq:
-  address: 192.168.3.240:4161
+  address: 192.168.3.206:4150
 
 #数据库配置
 databases:
   # redis配置
-  redis: main=192.168.3.206:1712
+  redis: other=192.168.3.206:1712
   # nsq操作日志库
   mogLog:
     address: 192.168.3.206:27090
@@ -45,6 +45,13 @@ databases:
     replSet:
     userName: admin
     password: 123456
+  mongodb:
+    address: 192.168.3.206:27080
+    size: 5
+    dbName: qfw
+    replSet:
+    userName:
+    password:
 
 #其他配置
 docPoints:

+ 115 - 5
services/share/service.go

@@ -1,13 +1,123 @@
 package share
 
-import "github.com/gogf/gf/v2/net/ghttp"
+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"
+	"encoding/base64"
+	"fmt"
+	"github.com/SKatiyar/qr"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"log"
+	"strings"
+)
 
 type ShareRouter struct{}
 
-func (c *ShareRouter) Index(r *ghttp.Request) {
-	r.Response.Write("index")
+func (c *ShareRouter) Info(r *ghttp.Request) {
+	userid := r.Header.Get("userId")
+	res := map[string]interface{}{}
+	keyUser := fmt.Sprintf("SF_%s", userid)
+	if value := redis.GetStr("other", keyUser); value != "" {
+		varr := strings.Split(value, "#@#@")
+		link := fmt.Sprintf("%s/front/followGift/%s", config.PushConfig.Webdomain, varr[3])
+		r, _ := qr.Encode(link, qr.M)
+		pngdat := r.PNG()
+		res["data"] = map[string]interface{}{
+			"shareId":   varr[3], //口令
+			"shareLink": link,    //微信分享链接
+			"erUrl":     base64.StdEncoding.EncodeToString(pngdat),
+		}
+		res["error_code"] = 0
+		res["error_msg"] = ""
+	} else {
+		nickname, headimageurl := "", ""
+		if data := GetInfo(userid); data != nil {
+			nickname = qu.ObjToString(data["nickname"])
+			headimageurl = qu.ObjToString(data["headimageurl"])
+		}
+		shareId := VarLSCPool.GetJob()
+		shareIdKey := fmt.Sprintf("shareId_%s", shareId)
+		value := fmt.Sprintf("%s#@#@%s#@#@%s#@#@%s", userid, nickname, headimageurl, shareIdKey)
+		redis.Put("other", shareIdKey, userid, -1)
+		redis.Put("other", keyUser, value, -1)
+		link := fmt.Sprintf("%s/front/followGift/%s", config.PushConfig.Webdomain, shareIdKey)
+		r, _ := qr.Encode(link, qr.M)
+		pngdat := r.PNG()
+		res["data"] = map[string]interface{}{
+			"shareId":   shareIdKey, //口令
+			"shareLink": link,       //微信分享链接
+			"erUrl":     base64.StdEncoding.EncodeToString(pngdat),
+		}
+		res["error_code"] = 0
+		res["error_msg"] = ""
+	}
+	r.Response.WriteJson(res)
 }
 
-func (c *ShareRouter) Show(r *ghttp.Request) {
-	r.Response.Write("show")
+func (c *ShareRouter) Receive(r *ghttp.Request) {
+	openid := se.SE.DecodeString(r.Get("oid").String()) //被分享者openid
+	if db.Mgo.Count("user", map[string]interface{}{"s_m_openid": openid, "i_appid": 2}) > 0 {
+		r.Response.WriteJson(g.Map{
+			"error_code": -1,
+			"error_msg":  "老用户无法领取奖励",
+			"data": map[string]interface{}{
+				"status": false,
+			},
+		})
+		return
+	}
+	shareId := r.Get("shareId").String()
+	redisKey := fmt.Sprintf("rec_%s", openid)
+	log.Println(openid, shareId, redisKey)        //分享者和被分享者对应关系
+	shareUserid := redis.GetStr("other", shareId) //获取分享者
+	if shareUserid == "" {
+		r.Response.WriteJson(g.Map{
+			"error_code": -1,
+			"error_msg":  "领取失败",
+			"data": map[string]interface{}{
+				"status": false,
+			},
+		})
+		return
+	}
+	r.Response.WriteJson(g.Map{
+		"error_code": 0,
+		"error_msg":  "",
+		"data": map[string]interface{}{
+			"status": redis.Put("other", redisKey, shareUserid, timeOut()),
+		},
+	})
+}
+
+func (c *ShareRouter) List(r *ghttp.Request) {
+	userid := r.Get("userId").String()
+	pNum := r.Get("pageNum").Int()
+	pSize := r.Get("pagesize").Int()
+	rdata := map[string]interface{}{
+		"count":        0,
+		"haveNextPage": false,
+		"res":          []map[string]interface{}{},
+	}
+	query := map[string]interface{}{
+		"share_uid": userid,
+	}
+	count := db.Mgo.Count("user_share", query)
+	if count == 0 {
+		return
+	}
+	result, _ := db.Mgo.Find("user_share", query, `{"createtime":-1}`, `{"shared_uid":1}`, false, pNum*pSize, pSize)
+	haveNextPage := (pNum+1)*pSize < count
+	rdata["count"] = count
+	rdata["haveNextPage"] = haveNextPage
+	rdata["pageSize"] = pSize
+	rdata["res"] = Info(result)
+	r.Response.WriteJson(g.Map{
+		"error_code": 0,
+		"error_msg":  "",
+		"data":       rdata,
+	})
 }

+ 156 - 0
services/share/sharecommon.go

@@ -0,0 +1,156 @@
+package share
+
+import (
+	qu "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/message/config"
+	"app.yhyue.com/moapp/message/db"
+	"bytes"
+	cr "crypto/rand"
+	"math/big"
+	"math/rand"
+	"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())
+}
+
+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
+}