|
@@ -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
|
|
|
+}
|