Browse Source

Merge branch 'master' of ssh://192.168.3.207:10022/qmx/jyqyfw

wangchuanjin 7 years ago
parent
commit
120c5ebb51

+ 41 - 1
README.md

@@ -1 +1,41 @@
-剑鱼企业服务
+剑鱼企业服务
+****
+
+1.access_token维护
+access_token为获取数据接口的凭据,access_token的有效期为2个小时,需定时刷新,重复获取上次获取的access_token将失效。
+
+请求方式: POST
+
+/api1/user/access_token?appid=jyMi1XQgMABQNcSkBMIhBq&key=6PzVlCUa
+参数说明:
+	参数			类型				说明			是否必须
+	appide		string	 	用户唯一标识	是
+	key			string	 	用户密码		是
+--------------
+返回数据
+响应头 :
+	content-encoding:gzip 
+	content-type:application/json 
+	accept-charset:utf-8
+响应内容:
+{
+    "access_token": string类型	
+    "code": 		int类型		返回代码
+    "times":		int类型		返回当天已调用次数,每天限制1000次
+}
+
+2.数据获取
+获取数据时需要携带access_token。
+
+请求方式: POST
+/api1/data/getdata?access_token=BHKSJyQ9z3bhI%2B7qB4BeGMmeFhSs3UNdKgOnxb%2Fp%2BjOQ%2BSKo
+参数说明:
+	参数			类型				说明						是否必须
+access_token	string			获取数据唯一凭据			是
+day				int				默认为0(-1取昨天)			否
+								(可取5天内数据范围[-5至0])
+next			int
+all				int
+
+
+

BIN
api文档/剑鱼企业级数据服务接口.doc


BIN
api文档/剑鱼企业级数据服务接口.pdf


BIN
api文档/剑鱼企业级数据服务接口_v1.1 - 副本.doc


BIN
api文档/剑鱼企业级数据服务接口_v1.2.doc


BIN
api文档/剑鱼企业级数据服务接口_v1.2.pdf


+ 33 - 0
jyservice/src/config.json

@@ -0,0 +1,33 @@
+{
+    "webport": ":8801",
+    "mongodb": {
+        "addr": "192.168.3.207:27080",
+        "db": "jyqyfw",
+        "pool": 10
+    },
+    "redis": {
+        "addr": "jyqyfw=192.168.3.207:1380",
+        "pool": 50
+    },
+	"loglevel":5,
+    "plan": {
+        "A": {
+            "title": 1,
+            "detail": 1,
+            "publishtime": 1,
+            "href": 1
+        },
+        "B": {
+            "title": 1,
+            "detail": 1,
+            "publishtime": 1,
+            "href": 1,
+            "area": 1,
+            "toptype": 1,
+            "budget": 1,
+            "bidamount": 1,
+            "bidopentime": 1,
+            "buyer": 1
+        }
+    }
+}

+ 1 - 0
jyservice/src/github.com/89hmdys/toast

@@ -0,0 +1 @@
+Subproject commit 3a038d97263a2458545f6772c3ca218d6646954e

+ 1 - 0
jyservice/src/github.com/gorilla/mux

@@ -0,0 +1 @@
+Subproject commit 7f08801859139f86dfafd1c296e2cba9a80d292e

+ 1 - 0
jyservice/src/github.com/sirupsen/logrus

@@ -0,0 +1 @@
+Subproject commit 89742aefa4b206dcf400792f3bd35b542998eb3b

+ 1 - 0
jyservice/src/golang.org/x/crypto

@@ -0,0 +1 @@
+Subproject commit 6a293f2d4b14b8e6d3f0539e383f6d0d30fce3fd

+ 1 - 0
jyservice/src/golang.org/x/sys

@@ -0,0 +1 @@
+Subproject commit 4b45465282a4624cf39876842a017334f13b8aff

+ 15 - 0
jyservice/src/main.go

@@ -1,5 +1,20 @@
 package main
 
+import (
+	"net/http"
+	"usermanager"
+	"utils"
+
+	log "github.com/sirupsen/logrus"
+)
+
 func main() {
+	go Server()
+	//定时更新redis中的数据到数据库
+	log.Info("Start server...")
+	<-make(chan struct{}, 0)
+}
 
+func Server() {
+	http.ListenAndServe(utils.Sysconfig["webport"].(string), usermanager.Middleware(usermanager.Route))
 }

+ 15 - 0
jyservice/src/private.pem

@@ -0,0 +1,15 @@
+-----BEGIN private-----
+MIICXQIBAAKBgQC32pYyKWAWiI4CWZzxLgpad2pz1r6F9opDJaNQvFTQJiQivHlh
+sHQvyZ90ZDZbDxxAX/sqK4HMkDfBPBmol4UHRg5kAv9xkVEmyBtoLLljYRszxOje
+693EyKDAeME8KNVgLLaCsMuiyy2EaZMBGAvxSTmnd+t1pMjHHp8n7DGunwIDAQAB
+AoGBAJf9oftYDzKxs0yoDsGnwTFm1V9sYVdYKJc4L1pYR3lIfskkrOgguvyinyrW
+icUfqchiUL5c91JIy375E3E3yeV/xoS4y+6Cf0dAiq/iiGoBqBtzbSpF+UA0o/pP
+3yMu8WaueG2En8mpTN9kAcW9Cn279PtwMALfKmW1/NZdXJ2pAkEA8RL0gXGukWOZ
+auEMxp0OWvQm0R/lVz2XyfjSVQWfDT2vGMgDv6+2bUeT8DomJmx3oWQX2gq0uidb
+/Ir9rEvhWwJBAMM8r8GVva1gicTswBWi7tDHC8OGYY9a0MQ3IPCKDCC513Se0SJi
+rhSU1IL2PBBgnSS/atwJ+FwY6Cbynrs1Rw0CQQDBKJ3upcboyXQgtgfFkAvzhpMf
+lr3s4/YeJ5dn9mQVeOo2IfUW/tRdxS9dGUp+GQTVtNyDoXZjfavvsvJEvlvnAkAJ
+h6nQmj2S+/ZdnWzW4YgkusKRPbr/Y2BzY3mBJEvpQQkKUUJGGmkC6izhY6GU7xJc
+m9dcfEQaQsD6PbePzc71AkBEanolW+cy+XzlqxQPoR64h9oP+QaVS0mlD+u3YBWn
+M0OVEU2E6lZ2xR25WmM/VAplMzklBlfIhsfkvBDHFUDX
+-----END private-----

+ 6 - 0
jyservice/src/public.pem

@@ -0,0 +1,6 @@
+-----BEGIN public-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC32pYyKWAWiI4CWZzxLgpad2pz
+1r6F9opDJaNQvFTQJiQivHlhsHQvyZ90ZDZbDxxAX/sqK4HMkDfBPBmol4UHRg5k
+Av9xkVEmyBtoLLljYRszxOje693EyKDAeME8KNVgLLaCsMuiyy2EaZMBGAvxSTmn
+d+t1pMjHHp8n7DGunwIDAQAB
+-----END public-----

+ 83 - 0
jyservice/src/usermanager/access_token.go

@@ -0,0 +1,83 @@
+package usermanager
+
+import (
+	"fmt"
+	"net/http"
+	"net/url"
+	"qfw/util"
+	"qfw/util/redis"
+	"sync"
+	"time"
+	. "utils"
+
+	//log "github.com/sirupsen/logrus"
+)
+
+const (
+	TOKEN_TIMEOUT     = 7200
+	TOKEN_LIMIT_TIMES = 1001
+	//key : 每天token上限tokenlimit_*  token的key token_*  每天调用数据api次数上限getlimit_*
+)
+
+//jyqyfw/user表
+//用户的accesstoken维护,每个用户分配一个 应用id=appid,用户密钥=key
+func GetAccessToken(w http.ResponseWriter, r *http.Request) {
+	defer util.Catch()
+	d := JSON{}
+	appid := r.FormValue("appid")
+	key := r.FormValue("key")
+	if appid != "" && key != "" {
+		res, b := Mgo.FindOneByField("user", &map[string]interface{}{
+			"appid": appid,
+			"key":   key,
+		}, `{"plan":1}`)
+		if b && res != nil && *res != nil {
+			GetDataMapLock.Lock()
+			appidLock := GetDataMap[appid]
+			if appidLock == nil {
+				appidLock = &sync.Mutex{}
+				GetDataMap[appid] = appidLock
+			}
+			GetDataMapLock.Unlock()
+			appidLock.Lock()
+			defer appidLock.Unlock()
+			t := time.Now()
+			limitKey := fmt.Sprintf("tokenlimit_%d_%s", t.Day(), appid)
+			limit := redis.GetInt(REDISDB, limitKey)
+			if limit < TOKEN_LIMIT_TIMES {
+				plan, _ := (*res)["plan"].(map[string]interface{})
+				if plan != nil && plan["name"] != nil {
+					access_token := RsaEncrypt(fmt.Sprintf("%d,%s,%s,%s", t.Unix(), appid, key, plan["name"]))
+					if access_token != "" {
+						if redis.Put(REDISDB, "token_"+appid, access_token, TOKEN_TIMEOUT) {
+							d["access_token"] = url.QueryEscape(access_token)
+							if limit == 0 {
+								tn := time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, time.Local).Unix()
+								expire := int(tn - t.Unix())
+								limit++
+								redis.Put(REDISDB, limitKey, limit, expire)
+							} else {
+								redis.Incr(REDISDB, limitKey)
+							}
+							d["expires_in"] = TOKEN_TIMEOUT
+						}
+					}
+				}
+				if len(d) == 0 {
+					//服务出错
+					d["code"] = CODE_ERR_E0
+					d["msg"] = MSG_ERR_E
+				}
+			} else {
+				//超过次数
+				d["code"] = CODE_E3
+				d["msg"] = MSG_E3
+			}
+		}
+	}
+	if len(d) == 0 {
+		d["code"] = CODE_E2
+		d["msg"] = MSG_E2
+	}
+	WriteJSON(w, d)
+}

+ 244 - 0
jyservice/src/usermanager/getdata.go

@@ -0,0 +1,244 @@
+/**
+数据获取服务
+**/
+package usermanager
+
+import (
+	"fmt"
+	//	"encoding/json"
+	"net/http"
+	"qfw/util"
+	"qfw/util/redis"
+	"strings"
+	"sync"
+	"time"
+	. "utils"
+
+	log "github.com/sirupsen/logrus"
+)
+
+//day:0
+//next:0
+const (
+	GETDATA_LIMIT_TIMES = 1001 //获取数据次数
+	QUERY_LIMIT         = 100
+)
+
+var (
+	GetDataMap     = map[string]*sync.Mutex{}
+	GetDataMapLock = &sync.Mutex{}
+)
+
+//取增量数据
+func GetData(w http.ResponseWriter, r *http.Request) {
+	defer util.Catch()
+	access_token := r.FormValue("access_token")
+	_, _, d := CheckUserInfo(access_token, 0, 0, 0)
+	WriteJSON(w, &d)
+}
+
+//取全量数据
+func GetAllData(w http.ResponseWriter, r *http.Request) {
+	defer util.Catch()
+	access_token := r.FormValue("access_token")
+	day := util.IntAll(r.FormValue("day"))
+	next := util.IntAll(r.FormValue("next"))
+	_, _, d := CheckUserInfo(access_token, day, next, 1)
+	WriteJSON(w, &d)
+}
+
+func CheckUserInfo(access_token string, day, next, all int) (bcheck bool, appid string, d JSON) {
+	defer util.Catch()
+	d = JSON{}
+	//第一层判断token是否失效或格式不对
+	planname := ""
+	if access_token != "" {
+		at := RsaDecrypt(access_token)
+		log.Debug("token:", at)
+		if at != "" {
+			tn := time.Now().Unix()
+			arr := strings.Split(at, ",")
+			if len(arr) == 4 { //时间,appid,key,套餐
+				t := util.Int64All(arr[0])
+				des := tn - t
+				log.Debug("des", des)
+				if des >= 0 && des <= TOKEN_TIMEOUT { //在有效时间内
+					appid = arr[1]
+					redis_token := redis.GetStr(REDISDB, "token_"+appid)
+					log.Debug("redis_token", "\t", redis_token, "\t", access_token)
+					if redis_token != "" && redis_token == access_token { //token验证通过,验证今日次数、总条数、服务时间
+						bcheck = true
+						planname = arr[3]
+					} else {
+						d["code"] = CODE_TOKEN_EXPIRE
+						d["msg"] = MSG_TOKEN_EXPIRE
+					}
+				} else {
+					d["code"] = CODE_TOKEN_EXPIRE
+					d["msg"] = MSG_TOKEN_EXPIRE
+				}
+			}
+		}
+	}
+	if !bcheck && len(d) == 0 {
+		d["code"] = CODE_E1
+		d["msg"] = MSG_E1
+	}
+	//第二层判断用户调用权限
+	if bcheck {
+		bcheck = false
+		tn := time.Now()
+		tnUnix := tn.Unix()
+		GetDataMapLock.Lock()
+		appidLock := GetDataMap[appid]
+		if appidLock == nil {
+			appidLock = &sync.Mutex{}
+			GetDataMap[appid] = appidLock
+		}
+		GetDataMapLock.Unlock()
+		appidLock.Lock()
+		defer appidLock.Unlock()
+		//"limittoday_" //值小于0时禁止
+		//"limitnum_" 值为小于零时实时判断
+		//"limittime_" 只判断一次,过期重新判断,用户续费时可以设置此值过期
+		validtime := redis.Get(REDISDB, "limittime_"+appid)
+		if validtime == nil {
+			if res, bflag := Mgo.FindOneByField("user", &map[string]interface{}{
+				"appid": appid,
+			}, `{"plan":1}`); bflag && res != nil && *res != nil && len(*res) > 0 {
+				if m1 := util.ObjToMap((*res)["plan"]); m1 != nil {
+					starttime := util.Int64All((*m1)["starttime"])
+					endtime := util.Int64All((*m1)["endtime"])
+					if starttime <= tnUnix && tnUnix <= endtime { //在服务时间内
+						limittime := int(endtime - tnUnix)
+						redis.Put(REDISDB, "limittime_"+appid, limittime, limittime) //存入值
+						validtime = limittime
+					}
+				}
+			}
+		}
+		limittodaykey := fmt.Sprintf("limittoday_%d_%s", tn.Day(), appid)
+		if validtime == nil {
+			d["code"] = CODE_ERR_E1
+			d["msg"] = MSG_ERR_E
+		} else {
+			limittime := util.IntAll(validtime)
+			if limittime > 0 { //在有效期内,判断今日调用次数,判断服务的总条数
+				limittoday := redis.GetInt(REDISDB, limittodaykey)
+				if limittoday > GETDATA_LIMIT_TIMES { //当天调用超过次数
+					d["code"] = CODE_E3
+					d["msg"] = MSG_E3
+				} else {
+					if limittoday == 0 {
+						_, max := GetDayMinMax(tn)
+						redis.Put(REDISDB, limittodaykey, 0, int(max-tnUnix))
+					}
+					//判断剩余服务条数
+					limitnum := redis.Get(REDISDB, "limitnum_"+appid) //值
+					if limitnum == nil {                              //值为空时从数据库中提取
+						if res1, bflag1 := Mgo.FindOneByField("user", &map[string]interface{}{
+							"appid": appid,
+						}, `{"plan":1}`); bflag1 && res1 != nil && *res1 != nil {
+							if m1 := util.ObjToMap((*res1)["plan"]); m1 != nil {
+								limitnum = (*m1)["current"]
+								if limitnum != nil {
+									redis.Put(REDISDB, "limitnum_"+appid, limitnum, 0)
+								}
+							}
+						}
+					}
+					if limitnum == nil {
+						d["code"] = CODE_ERR_E3
+						d["msg"] = MSG_ERR_E
+					} else {
+						num := util.IntAll(limitnum)
+						if num < 1 {
+							d["code"] = CODE_E5
+							d["msg"] = MSG_E5
+						} else {
+							bcheck = true
+						}
+					}
+				}
+			} else {
+				d["code"] = CODE_E4
+				d["msg"] = MSG_E4
+			}
+		}
+		//判断通过
+		if bcheck { //取数据
+			pn := planname[:1]
+			var fields map[string]interface{}
+			if pn == "A" {
+				fields = A
+			} else if pn == "B" {
+				fields = B
+			}
+			next, infos := getDataByAppid(appid, day, next, all, limittodaykey, fields)
+			if all == 1 && next > 0 {
+				d["next"] = next
+			}
+			if len(infos) == 0 {
+				d["data"] = []map[string]interface{}{}
+			} else {
+				d["data"] = infos
+			}
+		}
+	}
+	return
+}
+
+//获取数据
+func getDataByAppid(appid string, i_day, next, i_all int, limittodaykey string, fields map[string]interface{}) (i_next int, infos []map[string]interface{}) {
+	query := map[string]interface{}{"appid": appid}
+	blastid := false
+	if i_all == 0 { //必须是当天才能使用lastid按顺序取信息
+		blastid = true
+		lastid := redis.GetStr(REDISDB, "lastid_"+appid)
+		if lastid != "" {
+			query["_id"] = map[string]interface{}{
+				"$gt": util.StringTOBsonId(lastid),
+			}
+		}
+	}
+	createtime := map[string]interface{}{}
+	if !blastid && i_day > -6 && i_day < 1 {
+		min, max := GetDayMinMax(time.Now().AddDate(0, 0, i_day))
+		createtime["$gte"] = min
+		createtime["$lte"] = max
+		query["createtime"] = createtime
+	}
+
+	log.Debug("query:", query)
+	i_next = next
+	data, bdata := Mgo.Find("usermail", query, `{"_id":1}`, fields, false, i_next, QUERY_LIMIT)
+	if bdata && data != nil && *data != nil && len(*data) > 0 {
+		infos = *data
+		if blastid {
+			lastid := util.BsonIdToSId((*data)[len(*data)-1]["_id"])
+			if lastid != "" {
+				redis.Put(REDISDB, "lastid_"+appid, lastid, DesZero())
+			}
+		}
+		for _, v := range infos {
+			delete(v, "_id")
+		}
+		if len(*data) == QUERY_LIMIT && !blastid {
+			i_next = i_next + QUERY_LIMIT
+		} else {
+			i_next = -1
+		}
+		//处理总条数
+		redis.Decrby(REDISDB, "limitnum_"+appid, len(*data))
+		go Mgo.Save("userdatalog", map[string]interface{}{
+			"appid":   appid,
+			"datalen": len(*data),
+			"date":    time.Now().Unix(),
+		})
+	} else { //没有数据
+		i_next = 0
+	}
+	//处理今日调用次数
+	redis.Incr(REDISDB, limittodaykey)
+	return
+}

+ 41 - 0
jyservice/src/usermanager/task.go

@@ -0,0 +1,41 @@
+package usermanager
+
+import (
+	"qfw/util"
+	"qfw/util/redis"
+	"time"
+	. "utils"
+
+	log "github.com/sirupsen/logrus"
+)
+
+func init() {
+	//定时修改redis中的数据总条数到数据库
+	go func() {
+		for {
+			tn := time.Now()
+			_, max := GetDayMinMax(tn)
+			des := max - tn.Unix()
+			log.Debug("启动定时任务:", des)
+			time.Sleep(time.Duration(des) * time.Second)
+			//更新数据
+			keys := redis.GetKeysByPattern(REDISDB, "limitnum_*")
+			for _, key := range keys {
+				k := string(key.([]uint8))
+				v := redis.Get(REDISDB, k)
+				if v != nil {
+					val := util.IntAll(v)
+					b := Mgo.Update("user", `{"appid":"`+k[9:]+`"}`, map[string]interface{}{
+						"$set": map[string]interface{}{
+							"plan.current": val,
+						},
+					}, false, false)
+					log.Debug("更新剩余条数到数据库:", b, " val:", val, " appid: ", k[9:])
+				}
+			}
+			//清空
+			//redis.DelByCodePattern(REDISDB, "tokenlimit_*")
+			//redis.DelByCodePattern(REDISDB, "limittoday_*")
+		}
+	}()
+}

+ 94 - 0
jyservice/src/usermanager/user.go

@@ -0,0 +1,94 @@
+/**
+初始化用户服务
+1.创建用户
+2.购买服务
+**/
+package usermanager
+
+import (
+	"fmt"
+	"net/http"
+	"qfw/util"
+	"regexp"
+	"time"
+	. "utils"
+
+	log "github.com/sirupsen/logrus"
+)
+
+//生成appid和key
+//用户名称 appid 注册时间 key
+//套餐类型(A1,A2,A3,B1,B2,B3) 服务开始时间 服务结束时间
+var (
+	EncodeUtil = &util.SimpleEncrypt{"qyfw2017jy"}
+)
+
+//创建新用户
+func NewUser(w http.ResponseWriter, r *http.Request) {
+	username := r.FormValue("username")
+	t := time.Now()
+	//	randomstr := util.GetLetterRandom(5)
+	//	str := fmt.Sprintf("%s%d%s", randomstr[:2], t.Unix(), randomstr[2:])
+	//	appid := "jy" + EncodeUtil.EncodeString(str)
+	appid := GetAppid(t.Unix())
+	key := util.GetComplexRandom(8, 3, 5)
+	id := Mgo.Save("user", &map[string]interface{}{"username": username, "createtime": t.Unix(), "appid": appid, "key": key})
+	log.Debug("create user success!", "\t", username)
+	ret := JSON{"msg": "err"}
+	if len(id) > 10 {
+		ret["msg"] = "ok"
+	}
+	WriteJSON(w, &ret)
+}
+
+var strReg = regexp.MustCompile("^[0-9a-zA-Z]+$")
+
+func GetAppid(tn int64) (appid string) {
+	for {
+		randomstr := util.GetLetterRandom(5)
+		str := fmt.Sprintf("%s%d%s", randomstr[:2], tn, randomstr[2:])
+		appid = EncodeUtil.EncodeString(str)
+		if strReg.MatchString(appid) {
+			break
+		}
+	}
+	appid = "jy" + appid
+	return
+}
+
+//购买服务
+func NewService(w http.ResponseWriter, r *http.Request) {
+	appid := r.FormValue("appid")
+	plan := r.FormValue("plan")
+	ret := JSON{"msg": "err!"}
+	if appid != "" && plan != "" && Mgo.Count("user", `{"appid":"`+appid+`"}`) == 1 {
+		res, bp := Mgo.FindOne("serviceplan", &map[string]interface{}{
+			"_id": plan,
+		})
+		if bp && res != nil && *res != nil {
+			limit := (*res)["limit"]
+			t := time.Now()
+			end := t.AddDate(1, 0, 1)
+			end1 := time.Date(end.Year(), end.Month(), end.Day(), 0, 0, 0, 0, time.Local)
+			//log.Debug(t.Unix(), "-", end.Unix(), util.FormatDate(&t, util.Date_Full_Layout), util.FormatDate(&end1, util.Date_Full_Layout))
+			id := Mgo.Save("buyrecord", &map[string]interface{}{"appid": appid, "plan": plan, "createtime": t.Unix(), "starttime": t.Unix(), "endtime": end1.Unix()})
+			if id != "" {
+				//后结考虑延期时间
+				if Mgo.Update("user", `{"appid":"`+appid+`"}`, &map[string]interface{}{
+					"$set": map[string]interface{}{
+						"plan": map[string]interface{}{
+							"name":      plan,
+							"starttime": t.Unix(),
+							"endtime":   end1.Unix(),
+							"recordid":  id,
+							"current":   limit,
+						},
+					},
+				}, false, false) {
+					ret["msg"] = "ok"
+				}
+			}
+		}
+	}
+	WriteJSON(w, &ret)
+}

+ 130 - 0
jyservice/src/usermanager/usermanager.go

@@ -0,0 +1,130 @@
+package usermanager
+
+import (
+	"net"
+	"net/http"
+	"strings"
+	"sync"
+	"time"
+	. "utils"
+
+	"github.com/gorilla/mux"
+	log "github.com/sirupsen/logrus"
+)
+
+var (
+	Route = mux.NewRouter()
+)
+
+func init() {
+	//用户使用地址
+	Route.HandleFunc("/user/access_token", GetAccessToken).Methods("POST")
+	Route.HandleFunc("/data/getdata", GetData).Methods("POST")
+	Route.HandleFunc("/data/getalldata", GetAllData).Methods("POST")
+	//管理地址
+	Route.HandleFunc("/api1/user/jy_newuser", NewUser).Methods("POST")
+	Route.HandleFunc("/api1/user/jy_newservice", NewService).Methods("POST")
+
+	//http.Handle("/", middleware(Route))
+	go SaveLogTask()
+}
+
+func Middleware(next http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		//访问时间控制去掉
+		//fmt.Println("before")
+		//		t := time.Now()
+		//		if t.Hour() > 22 || t.Hour() < 6 {
+		//			WriteJSON(w, &JSON{
+		//				"code": CODE_OUTTIME,
+		//				"msg":  MSG_OUTTIME,
+		//			})
+		//			return
+		//		}
+		//记录日志
+		go addLog(req)
+		next.ServeHTTP(w, req)
+		//fmt.Println("after")
+	})
+}
+
+//定时保存日志
+func SaveLogTask() {
+	lock.Lock()
+	if len(arr) >= 1 {
+		tmp := arr
+		arr = make([]map[string]interface{}, 0)
+		go func() {
+			log.Debug("timer..save..visit..log", len(tmp))
+			Mgo.SaveBulk("logs", tmp...)
+		}()
+	}
+	lock.Unlock()
+	time.AfterFunc(2*time.Minute, SaveLogTask)
+}
+
+//内存缓存日志数量,超过此数量存库
+var nc = 50
+
+//内存缓存日志map
+var arr = make([]map[string]interface{}, 0)
+
+//对map的同步
+var lock sync.Mutex
+
+//用线程处理,增加日志
+
+func addLog(req *http.Request) {
+	timeNow := time.Now()
+	agent := req.Header.Get("user-agent")
+	ref := req.Referer()
+	s_url := req.RequestURI
+	date := timeNow.Unix()
+	logs := map[string]interface{}{
+		"l_date":     date,
+		"s_ip":       req.Proto,
+		"s_refer":    ref,
+		"i_year":     timeNow.Year(),
+		"i_month":    timeNow.Month(),
+		"i_day":      timeNow.Day(),
+		"i_hour":     timeNow.Hour(),
+		"i_minutes":  timeNow.Minute(),
+		"s_describe": req.Form,
+		"s_client":   agent,
+		"s_method":   req.Method,
+		"s_url":      s_url,
+	}
+	lock.Lock()
+	arr = append(arr, logs)
+	if len(arr) >= nc || s_url == "/sl" {
+		tmp := arr
+		arr = make([]map[string]interface{}, 0)
+		go func() {
+			log.Println("save..visit..log", len(tmp))
+			Mgo.SaveBulk("logs", tmp...)
+		}()
+	}
+	lock.Unlock()
+}
+
+//获取请求ip
+func GetIp(req *http.Request) string {
+	if req == nil {
+		return ""
+	}
+	ip_for := req.Header.Get("x-forwarded-for")
+	ip_client := req.Header.Get("http_client_ip")
+	ip_addr := req.Header.Get("Remote_addr")
+	un := "unknown"
+	if (ip_for != un) && (len(strings.TrimSpace(ip_for)) > 0) {
+		return ip_for
+	}
+	if (ip_client != un) && (len(strings.TrimSpace(ip_client)) > 0) {
+		return ip_client
+	}
+	if (ip_addr != un) && (len(strings.TrimSpace(ip_addr)) > 0) {
+		return ip_addr
+	}
+	ip, _, _ := net.SplitHostPort(req.RemoteAddr)
+	return ip
+}

+ 38 - 0
jyservice/src/utils/gzip.go

@@ -0,0 +1,38 @@
+package utils
+
+import (
+	"bytes"
+	"compress/gzip"
+	"io/ioutil"
+)
+
+func GzipEncode(in []byte) ([]byte, error) {
+	var (
+		buffer bytes.Buffer
+		out    []byte
+		err    error
+	)
+	writer := gzip.NewWriter(&buffer)
+	_, err = writer.Write(in)
+	if err != nil {
+		writer.Close()
+		return out, err
+	}
+	err = writer.Close()
+	if err != nil {
+		return out, err
+	}
+
+	return buffer.Bytes(), nil
+}
+
+func GzipDecode(in []byte) ([]byte, error) {
+	reader, err := gzip.NewReader(bytes.NewReader(in))
+	if err != nil {
+		var out []byte
+		return out, err
+	}
+	defer reader.Close()
+
+	return ioutil.ReadAll(reader)
+}

+ 28 - 0
jyservice/src/utils/httputil.go

@@ -0,0 +1,28 @@
+package utils
+
+import (
+	"compress/gzip"
+	"encoding/json"
+	"net/http"
+
+	log "github.com/sirupsen/logrus"
+)
+
+//开启gzip压缩
+func WriteJSON(w http.ResponseWriter, data interface{}) {
+	//	resByte, err := json.Marshal(data)
+	//	if err != nil {
+	//		log.Error("writejson err", err.Error())
+	//		return
+	//	}
+	w.Header().Set("Accept-Charset", "utf-8")
+	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Content-Encoding", "gzip")
+	gz := gzip.NewWriter(w)
+	defer gz.Close()
+	err := json.NewEncoder(gz).Encode(data)
+	if err != nil {
+		log.Error("writejson err", err.Error())
+	}
+	//w.Write(resByte)
+}

+ 20 - 0
jyservice/src/utils/mongodb.go

@@ -0,0 +1,20 @@
+package utils
+
+import (
+	"qfw/util"
+	"qfw/util/mongodb"
+)
+
+var (
+	Mgo *mongodb.MongodbSim
+)
+
+func initmongo() {
+	mconf := Sysconfig["mongodb"].(map[string]interface{})
+	Mgo = &mongodb.MongodbSim{
+		MongodbAddr: mconf["addr"].(string),
+		DbName:      mconf["db"].(string),
+		Size:        util.IntAllDef(mconf["pool"], 5),
+	}
+	Mgo.InitPool()
+}

+ 129 - 0
jyservice/src/utils/ras.go

@@ -0,0 +1,129 @@
+package utils
+
+import (
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/base64"
+	"encoding/pem"
+	"os"
+
+	log "github.com/sirupsen/logrus"
+)
+
+var (
+	Private = []byte(`-----BEGIN private-----
+MIICXQIBAAKBgQC32pYyKWAWiI4CWZzxLgpad2pz1r6F9opDJaNQvFTQJiQivHlh
+sHQvyZ90ZDZbDxxAX/sqK4HMkDfBPBmol4UHRg5kAv9xkVEmyBtoLLljYRszxOje
+693EyKDAeME8KNVgLLaCsMuiyy2EaZMBGAvxSTmnd+t1pMjHHp8n7DGunwIDAQAB
+AoGBAJf9oftYDzKxs0yoDsGnwTFm1V9sYVdYKJc4L1pYR3lIfskkrOgguvyinyrW
+icUfqchiUL5c91JIy375E3E3yeV/xoS4y+6Cf0dAiq/iiGoBqBtzbSpF+UA0o/pP
+3yMu8WaueG2En8mpTN9kAcW9Cn279PtwMALfKmW1/NZdXJ2pAkEA8RL0gXGukWOZ
+auEMxp0OWvQm0R/lVz2XyfjSVQWfDT2vGMgDv6+2bUeT8DomJmx3oWQX2gq0uidb
+/Ir9rEvhWwJBAMM8r8GVva1gicTswBWi7tDHC8OGYY9a0MQ3IPCKDCC513Se0SJi
+rhSU1IL2PBBgnSS/atwJ+FwY6Cbynrs1Rw0CQQDBKJ3upcboyXQgtgfFkAvzhpMf
+lr3s4/YeJ5dn9mQVeOo2IfUW/tRdxS9dGUp+GQTVtNyDoXZjfavvsvJEvlvnAkAJ
+h6nQmj2S+/ZdnWzW4YgkusKRPbr/Y2BzY3mBJEvpQQkKUUJGGmkC6izhY6GU7xJc
+m9dcfEQaQsD6PbePzc71AkBEanolW+cy+XzlqxQPoR64h9oP+QaVS0mlD+u3YBWn
+M0OVEU2E6lZ2xR25WmM/VAplMzklBlfIhsfkvBDHFUDX
+-----END private-----`)
+	Public = []byte(`-----BEGIN public-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC32pYyKWAWiI4CWZzxLgpad2pz
+1r6F9opDJaNQvFTQJiQivHlhsHQvyZ90ZDZbDxxAX/sqK4HMkDfBPBmol4UHRg5k
+Av9xkVEmyBtoLLljYRszxOje693EyKDAeME8KNVgLLaCsMuiyy2EaZMBGAvxSTmn
+d+t1pMjHHp8n7DGunwIDAQAB
+-----END public-----`)
+)
+
+func initrsa() {
+	//GenRsaKey(1024)
+	//	str := RsaEncrypt("你好")
+	//	log.Debug(str)
+	//	log.Debug(RsaDecrypt(str))
+}
+
+func RsaEncrypt(orig string) (encodestr string) {
+	origData := []byte(orig)
+	block, _ := pem.Decode(Public)
+	if block == nil {
+		log.Error("public key error")
+		return
+	}
+	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
+	if err != nil {
+		return
+	}
+	pub := pubInterface.(*rsa.PublicKey)
+	res, err := rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
+	if err == nil {
+		encodestr = base64.StdEncoding.EncodeToString(res)
+	} else {
+		log.Error("rsa en err", err.Error())
+	}
+	return
+}
+
+// 解密
+func RsaDecrypt(text string) (orig string) {
+	ciphertext, err := base64.StdEncoding.DecodeString(text)
+	if err != nil {
+		log.Error("ras De error", err.Error())
+		return
+	}
+	block, _ := pem.Decode(Private)
+	if block == nil {
+		log.Error("private key error!")
+		return
+	}
+	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		return
+	}
+	res, err := rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
+	if err == nil {
+		orig = string(res)
+	} else {
+		log.Error("ras De error", err.Error())
+	}
+	return
+}
+
+func GenRsaKey(bits int) error {
+	// 生成私钥文件
+	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
+	if err != nil {
+		return err
+	}
+	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
+	block := &pem.Block{
+		Type:  "private",
+		Bytes: derStream,
+	}
+	file, err := os.Create("private.pem")
+	if err != nil {
+		return err
+	}
+	err = pem.Encode(file, block)
+	if err != nil {
+		return err
+	}
+	// 生成公钥文件
+	publicKey := &privateKey.PublicKey
+	derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
+	if err != nil {
+		return err
+	}
+	block = &pem.Block{
+		Type:  "public",
+		Bytes: derPkix,
+	}
+	file, err = os.Create("public.pem")
+	if err != nil {
+		return err
+	}
+	err = pem.Encode(file, block)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 78 - 0
jyservice/src/utils/utils.go

@@ -0,0 +1,78 @@
+package utils
+
+import (
+	"os"
+	"qfw/util"
+	"qfw/util/redis"
+	"time"
+
+	log "github.com/sirupsen/logrus"
+)
+
+type JSON map[string]interface{}
+
+const (
+	REDISDB           = "jyqyfw"
+	CODE_TOKEN_EXPIRE = 1000 //token过期
+	MSG_TOKEN_EXPIRE  = "token已过期"
+	CODE_E1           = 1001
+	MSG_E1            = "token错误"
+	CODE_E2           = 1002
+	MSG_E2            = "参数错误"
+	CODE_E3           = 1003
+	MSG_E3            = "调用次数过超限制"
+	CODE_E4           = 1004
+	MSG_E4            = "服务过期"
+	CODE_E5           = 1005
+	MSG_E5            = "服务条数过超限制"
+	CODE_ERR_E0       = 4000
+	MSG_ERR_E         = "内部错误"
+	CODE_ERR_E1       = 4001
+	CODE_ERR_E2       = 4002
+	CODE_ERR_E3       = 4003
+	CODE_ERR_E4       = 4004
+	//------
+	//	CODE_OUTTIME      = 0
+	//	MSG_OUTTIME       = "不在服务时间(服务时间06:00-23:00)"
+	CODE_SUCCESS = 1
+	MSG_SUCCESS  = "请求成功"
+)
+
+var (
+	Sysconfig map[string]interface{}
+	A         map[string]interface{}
+	B         map[string]interface{}
+)
+
+func init() {
+	//初始化日志
+	util.ReadConfig(&Sysconfig)
+	t := &log.TextFormatter{}
+	t.TimestampFormat = "01-02 15:04:05.000"
+	t.ForceColors = true
+	t.DisableTimestamp = false
+	t.FullTimestamp = true
+	log.SetFormatter(t)
+	log.SetOutput(os.Stdout)
+	log.SetLevel(log.Level(util.IntAllDef(Sysconfig["loglevel"], 5)))
+	//
+	plan, _ := Sysconfig["plan"].(map[string]interface{})
+	A = plan["A"].(map[string]interface{})
+	B = plan["B"].(map[string]interface{})
+	initmongo()
+	redisconf := Sysconfig["redis"].(map[string]interface{})
+	redis.InitRedisBySize(util.ObjToString(redisconf["addr"]), util.IntAllDef(redisconf["pool"], 10), 20, 240)
+	log.Info("Util init over...")
+	initrsa()
+}
+
+func GetDayMinMax(t time.Time) (int64, int64) {
+	min := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.Local).Unix()
+	return min, min + 86400
+}
+
+func DesZero() int {
+	t := time.Now()
+	d := time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, time.Local).Unix()
+	return int(d - t.Unix())
+}