|
@@ -2,15 +2,146 @@ package front
|
|
|
|
|
|
import (
|
|
import (
|
|
"fmt"
|
|
"fmt"
|
|
- "jfw/tools"
|
|
|
|
- "log"
|
|
|
|
- "math/rand"
|
|
|
|
|
|
+ // "jfw/tools"
|
|
|
|
+ //"log"
|
|
|
|
+ //"math/rand"
|
|
|
|
+ "qfw/util"
|
|
"qfw/util/redis"
|
|
"qfw/util/redis"
|
|
- "strconv"
|
|
|
|
|
|
+ //"strconv"
|
|
"sync"
|
|
"sync"
|
|
"time"
|
|
"time"
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+var (
|
|
|
|
+ InvalidTime = int64(35 * 60) //定时任务判断二维码失效时间35分钟
|
|
|
|
+ ValidTime = 30 * 60 //前端二维码有效时间30分钟
|
|
|
|
+ QrValid = int64(28 * 86400)
|
|
|
|
+ PoolSize = 100
|
|
|
|
+ RedisList = "mylist"
|
|
|
|
+ QrGCList = make([]*QrGC, PoolSize) //定义回收对象池
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+func init() {
|
|
|
|
+ //1.生成50个线程池
|
|
|
|
+ for i := 0; i < PoolSize; i++ {
|
|
|
|
+ q := &QrGC{make(chan string, 100), map[string]int64{}, &sync.Mutex{}, i}
|
|
|
|
+ go q.PoolGC()
|
|
|
|
+ go q.SetTimeGC()
|
|
|
|
+ QrGCList[i] = q
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//二维码回收对象
|
|
|
|
+type QrGC struct {
|
|
|
|
+ CodePool chan string
|
|
|
|
+ CodeList map[string]int64
|
|
|
|
+ Lock *sync.Mutex
|
|
|
|
+ Index int
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (q *QrGC) Add(str string, t int64) {
|
|
|
|
+ q.Lock.Lock()
|
|
|
|
+ q.CodeList[str] = t
|
|
|
|
+ q.Lock.Unlock()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//二维码回收机制,定时回收
|
|
|
|
+func (q *QrGC) SetTimeGC() {
|
|
|
|
+ for {
|
|
|
|
+ time.Sleep(3 * time.Minute)
|
|
|
|
+ now := time.Now().Unix()
|
|
|
|
+ q.Lock.Lock()
|
|
|
|
+ for k, v := range q.CodeList {
|
|
|
|
+ if now-v > InvalidTime { //失效
|
|
|
|
+ delete(q.CodeList, k)
|
|
|
|
+ //补充逻辑
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ q.Lock.Unlock()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//二维码回收机制,使用完回收
|
|
|
|
+func (q *QrGC) PoolGC() {
|
|
|
|
+ for {
|
|
|
|
+ select {
|
|
|
|
+ case code := <-q.CodePool:
|
|
|
|
+ //调用回收逻辑
|
|
|
|
+ q.Lock.Lock()
|
|
|
|
+ delete(q.CodeList, code)
|
|
|
|
+ q.Lock.Unlock()
|
|
|
|
+ //删除redis中的参数,取出二维码的失效时间判断
|
|
|
|
+ //补充逻辑
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//生成二维码串,定义24位串,返回时间,返回回收池索引
|
|
|
|
+var qrSimpleEncrypt = &util.SimpleEncrypt{"qrcode_jywx2017"}
|
|
|
|
+
|
|
|
|
+//生成二维码代码
|
|
|
|
+func NewQrCodeStr() (string, int64, int) {
|
|
|
|
+ now := time.Now()
|
|
|
|
+ str := fmt.Sprintf("A%s%d%s", util.GetLetterRandom(4), now.UnixNano()/1000, util.GetLetterRandom(3))
|
|
|
|
+ str = qrSimpleEncrypt.EncodeString(str)
|
|
|
|
+ return str, now.Unix(), HashVal(str) % PoolSize
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//计算哈希值
|
|
|
|
+func HashVal(src string) int {
|
|
|
|
+ check := 0
|
|
|
|
+ for i := len(src) / 2; i < len(src); i++ {
|
|
|
|
+ check += int(src[i])
|
|
|
|
+ }
|
|
|
|
+ return check
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//计算二维码
|
|
|
|
+func ComputeQrCode(str string) int64 {
|
|
|
|
+ str1 := qrSimpleEncrypt.DecodeString(str)
|
|
|
|
+ if len(str1) == 24 {
|
|
|
|
+ return util.Int64All(str1[5:15])
|
|
|
|
+ }
|
|
|
|
+ return 0
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//获取二维码代码
|
|
|
|
+func GetQRCode() (code string) {
|
|
|
|
+ ret := redis.LPOP("sso", RedisList)
|
|
|
|
+ bnew := false
|
|
|
|
+ res := ""
|
|
|
|
+ if ret != nil {
|
|
|
|
+ res, _ = ret.(string)
|
|
|
|
+ if len(res) != 24 || time.Now().Unix()-ComputeQrCode(res) > QrValid { //过期
|
|
|
|
+ bnew = true
|
|
|
|
+ } else {
|
|
|
|
+ qrgc := QrGCList[HashVal(res)%PoolSize]
|
|
|
|
+ qrgc.Add(res, time.Now().Unix())
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ bnew = true
|
|
|
|
+ }
|
|
|
|
+ if bnew {
|
|
|
|
+ str, times, index := NewQrCodeStr()
|
|
|
|
+ qrgc := QrGCList[index]
|
|
|
|
+ qrgc.Add(str, times)
|
|
|
|
+ return str
|
|
|
|
+ }
|
|
|
|
+ return res
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//获取二维码图片
|
|
|
|
+func GetQRData(code string) (pngdata *[]byte) {
|
|
|
|
+ tmp, err := redis.GetBytes("sso", "qr_"+code)
|
|
|
|
+ if err == nil {
|
|
|
|
+ if tmp == nil {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
//var QrMap = map[string]*SingleQR{}
|
|
//var QrMap = map[string]*SingleQR{}
|
|
//var QrMapLock = &sync.RWMutex{}
|
|
//var QrMapLock = &sync.RWMutex{}
|
|
|
|
|
|
@@ -112,3 +243,4 @@ func WXQRData(shareid string) (pngdata *SingleQR) {
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+**/
|