newestBidding.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. package model
  2. import (
  3. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/entity"
  4. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/rpc/bxbase"
  5. IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/rpc/init"
  6. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/rpc/internal/config"
  7. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/rpc/util"
  8. "context"
  9. "encoding/json"
  10. "fmt"
  11. "log"
  12. "sort"
  13. "strings"
  14. "time"
  15. "app.yhyue.com/moapp/jybase/redis"
  16. MC "app.yhyue.com/moapp/jybase/common"
  17. ME "app.yhyue.com/moapp/jybase/encrypt"
  18. elastic "app.yhyue.com/moapp/jybase/es"
  19. "app.yhyue.com/moapp/jybase/mongodb"
  20. "app.yhyue.com/moapp/jybase/mysql"
  21. "github.com/zeromicro/go-zero/core/logx"
  22. "go.mongodb.org/mongo-driver/bson/primitive"
  23. )
  24. const (
  25. search_index = "bidding"
  26. search_type = "bidding"
  27. mongodb_fields = `{"_id":1,"area":1,"city":1,"district":1,"publishtime":1,"s_subscopeclass":1,"subtype":1,"title":1,"toptype":1,"type":1, "buyerclass":1,"budget":1,"bidamount":1,"s_winner":1,"bidopentime":1,"buyer":1,"projectname":1,"spidercode":1,"site":1}`
  28. query = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","area","city","district", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "buyerclass","bidamount","budget","projectname","buyer","bidopentime","s_winner","filetext","spidercode","site"],"from":0,"size":%d}`
  29. multi_match = `{"multi_match": {"query": %s,"type": "phrase", "fields": ["title"]}}`
  30. query_bool_must = `{"terms":{"%s":[%s]}}`
  31. query_bool_must_and = `{"bool":{"must":[%s],"must_not":[%s]}}`
  32. search_field = `"_id","area","city","district","publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "buyerclass","bidamount","budget","projectname","buyer","bidopentime","s_winner","filetext","isValidFile","spidercode","site"`
  33. query_city_hkeys = `{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match":%d}},"highlight": {"pre_tags": ["<a>"],"post_tags": ["</a>"],"fields": {"title": {"fragment_size": 0,"number_of_fragments": 1}}},"_source":[` + search_field + `],"sort":[{"publishtime":"desc"},{"budget":"desc"}],"from":0,"size":%d}`
  34. Pushbidding = "global_common_data.dws_f_bid_baseinfo"
  35. Province = "province"
  36. StatusCache = iota // 0 -不存缓存 本来查的就是缓存的数据
  37. StatusNoLogin // 1-未登录用户
  38. StatusLoginUser // 2-用户自己的key
  39. StatusLogin // 3-登录用户最新标讯
  40. )
  41. type NewestInfo struct {
  42. TableName string
  43. UserId string
  44. MysqlDb *mysql.Mysql
  45. NewUserId int64
  46. PushMysql *mysql.Mysql
  47. NewsLimitNum int64 // 最新标讯数量条数限制
  48. IsEnt bool
  49. }
  50. var mysqlTables = map[string]string{
  51. "f": "push.pushsubscribe",
  52. "v": "push.pushsubscribe",
  53. "m": "push.pushmember",
  54. "e": "push.pushentniche",
  55. }
  56. func GetRoleNewestInfoService(AppId, MgoUserId string, NewUserId, AccountId, EntId, EntUserId, PositionType, PositionId int64) (roleNewestInfo *NewestInfo, flag string) {
  57. powerCheck := IC.Middleground.PowerCheckCenter.Check(AppId, MgoUserId, NewUserId, AccountId, EntId, PositionType, PositionId)
  58. thisUserId := MC.If(PositionType == 1, MC.InterfaceToStr(EntUserId), MC.InterfaceToStr(NewUserId)).(string)
  59. thisNewUserId := MC.If(PositionType == 1, EntUserId, NewUserId).(int64)
  60. if powerCheck.Member.Status > 0 {
  61. // 大会员
  62. flag = "m"
  63. } else if powerCheck.Entniche.Status > 0 && powerCheck.Entniche.PowerSource != 1 && powerCheck.Entniche.IsEntPower == 1 {
  64. // 商机管理
  65. flag = "e"
  66. } else if powerCheck.Vip.Status > 0 {
  67. // 超级订阅
  68. flag = "v"
  69. } else {
  70. // 普通用户
  71. flag = "f"
  72. }
  73. thisUserType := MC.If(PositionType == 1, "e", flag).(string)
  74. return GetNewestInfo(thisUserId, thisUserType, thisNewUserId), flag
  75. }
  76. func GetNewestInfo(userId, userType string, newUserId int64) *NewestInfo {
  77. nt := &NewestInfo{
  78. UserId: userId,
  79. TableName: mysqlTables[userType],
  80. MysqlDb: IC.BaseServiceMysql,
  81. NewUserId: newUserId,
  82. NewsLimitNum: IC.C.NewsLimitNum,
  83. }
  84. return nt
  85. }
  86. // GetPushHistoryCount 缓存code 配置最新的redis code;可以感觉redis内存大小 调节redis存储;
  87. // 根据GetPushHistoryCount 返回值 作为列表缓存key中一个参数
  88. func (n *NewestInfo) GetPushHistoryCount() int64 {
  89. countKey := fmt.Sprintf(IC.C.NewsCache.Count.Key, n.TableName, n.UserId)
  90. if b := redis.GetInt("new", countKey); b != 0 {
  91. return int64(b)
  92. }
  93. countSql := "SELECT COUNT(1) FROM (SELECT 1 FROM %s WHERE userid = %d LIMIT 1) AS ph"
  94. //countSql := "select count(1) from %s a where a.userid=%d order by a.id desc"
  95. countSql = fmt.Sprintf(countSql, n.TableName, n.NewUserId)
  96. timeOut := IC.C.NewsCache.Count.Timeout
  97. c := n.MysqlDb.CountBySql(countSql)
  98. if c > 0 {
  99. timeOut = timeOut * 7
  100. } else {
  101. c = -1
  102. }
  103. redis.Put("new", countKey, c, timeOut) //过期时间走配置,比最新标讯列表缓存时间 要短1/10 尽量不超过两分钟
  104. return c
  105. }
  106. // 判断当前用户是否有最新推送信息
  107. func (n *NewestInfo) IsHasNewPushData(time int64) bool {
  108. return n.MysqlDb.CountBySql(fmt.Sprintf("SELECT COUNT(1) FROM (SELECT 1 FROM %s WHERE userid = %d AND date > %d LIMIT 1) AS ph", n.TableName, n.NewUserId, time)) > 0
  109. }
  110. // GetPushHistory
  111. func (n *NewestInfo) GetPushHistory() (res []*bxbase.NewestList) {
  112. findSQL := "select a.infoid,REPLACE(a.matchkeys,'+',' ') as matchkeys,a.attachment_count,a.budget,a.bidamount from %s a where a.userid=%d and a.date>0 order by a.date desc,a.id desc limit ?"
  113. findSQL = fmt.Sprintf(findSQL, n.TableName, n.NewUserId)
  114. logx.Info(n.TableName, "-------", n.NewUserId, ",findSQL:", findSQL)
  115. t := time.Now()
  116. list := n.MysqlDb.SelectBySql(findSQL, n.NewsLimitNum)
  117. log.Println("SQL 订阅信息耗时:", time.Since(t))
  118. if list != nil && len(*list) > 0 {
  119. m := map[string]bool{}
  120. es_ids := []string{}
  121. infos := map[string]*bxbase.NewestList{}
  122. for _, v := range *list {
  123. infoId := MC.ObjToString(v["infoid"])
  124. if m[infoId] {
  125. continue
  126. }
  127. es_ids = append(es_ids, infoId)
  128. m[MC.ObjToString(v["infoid"])] = true
  129. //
  130. infos[infoId] = &bxbase.NewestList{
  131. Id: ME.EncodeArticleId2ByCheck(MC.ObjToString(v["infoid"])),
  132. Matchkeys: strings.Split(MC.ObjToString(v["matchkeys"]), " "),
  133. Budget: MC.Int64All(v["budget"]),
  134. Bidamount: MC.Int64All(v["bidamount"]),
  135. FileExists: MC.Int64All(v["attachment_count"]) > 0,
  136. }
  137. }
  138. if len(es_ids) > 0 {
  139. t = time.Now()
  140. esList := elastic.Get(search_index, search_type, fmt.Sprintf(query, strings.Join(es_ids, `","`), len(es_ids)))
  141. log.Println("elastic 招标信息耗时:", time.Since(t))
  142. if esList != nil && len(*esList) > 0 {
  143. for _, v := range *esList {
  144. _id := MC.ObjToString(v["_id"])
  145. bn := infos[_id]
  146. bn.Title = MC.ObjToString(v["title"])
  147. bn.PublishTime = MC.Int64All(v["publishtime"])
  148. bn.Subtype = MC.If(v["subtype"] != nil, MC.ObjToString(v["subtype"]), MC.ObjToString(v["toptype"])).(string)
  149. bn.Area = MC.If(MC.ObjToString(v["area"]) == "A", "全国", MC.ObjToString(v["area"])).(string)
  150. bn.Buyerclass = MC.ObjToString(v["buyerclass"])
  151. bn.City = MC.ObjToString(v["city"])
  152. bn.District = MC.InterfaceToStr(v["district"]) //县区
  153. bn.Industry = MC.If(MC.ObjToString(v["s_subscopeclass"]) != "", strings.Split(strings.Split(MC.ObjToString(v["s_subscopeclass"]), ",")[0], "_")[0], "").(string)
  154. bn.SpiderCode = MC.ObjToString(v["spidercode"])
  155. bn.Site = MC.ObjToString(v["site"])
  156. }
  157. }
  158. }
  159. //mongodb bidding
  160. mgo_ids := []primitive.ObjectID{}
  161. for _, v := range es_ids {
  162. if infos[v].Title == "" {
  163. mgo_ids = append(mgo_ids, mongodb.StringTOBsonId(v))
  164. }
  165. }
  166. if len(mgo_ids) > 0 {
  167. t = time.Now()
  168. mgoList, ok := IC.MgoBidding.Find("bidding", map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_ids}}, nil, mongodb_fields, false, -1, -1)
  169. log.Println("mongodb bidding 招标信息耗时:", time.Since(t))
  170. if ok && *mgoList != nil && len(*mgoList) > 0 {
  171. for _, v := range *mgoList {
  172. _id := mongodb.BsonIdToSId(v["_id"])
  173. bn := infos[_id]
  174. bn.Title = MC.ObjToString(v["title"])
  175. bn.PublishTime = MC.Int64All(v["publishtime"])
  176. bn.Subtype = MC.If(v["subtype"] != nil, MC.ObjToString(v["subtype"]), MC.ObjToString(v["toptype"])).(string)
  177. bn.Area = MC.If(MC.ObjToString(v["area"]) == "A", "全国", MC.ObjToString(v["area"])).(string)
  178. bn.Buyerclass = MC.ObjToString(v["buyerclass"])
  179. bn.City = MC.ObjToString(v["city"])
  180. bn.District = MC.InterfaceToStr(v["district"]) //县区
  181. bn.Industry = MC.If(MC.ObjToString(v["s_subscopeclass"]) != "", strings.Split(strings.Split(MC.ObjToString(v["s_subscopeclass"]), ",")[0], "_")[0], "").(string)
  182. bn.SpiderCode = MC.ObjToString(v["spidercode"])
  183. bn.Site = MC.ObjToString(v["site"])
  184. }
  185. }
  186. }
  187. //mongodb bidding_back
  188. mgo_back_ids := []primitive.ObjectID{}
  189. for _, v := range mgo_ids {
  190. if infos[mongodb.BsonIdToSId(v)].Title == "" {
  191. mgo_back_ids = append(mgo_back_ids, v)
  192. }
  193. }
  194. if len(mgo_back_ids) > 0 {
  195. t = time.Now()
  196. mgoBKList, ok := IC.MgoBidding.Find("bidding_back", map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_back_ids}}, nil, mongodb_fields, false, -1, -1)
  197. log.Println("mongodb bidding_back 招标信息耗时:", time.Since(t))
  198. if ok && *mgoBKList != nil && len(*mgoBKList) > 0 {
  199. for _, v := range *mgoBKList {
  200. _id := mongodb.BsonIdToSId(v["_id"])
  201. bn := infos[_id]
  202. bn.Title = MC.ObjToString(v["title"])
  203. bn.PublishTime = MC.Int64All(v["publishtime"])
  204. bn.Subtype = MC.If(v["subtype"] != nil, MC.ObjToString(v["subtype"]), MC.ObjToString(v["toptype"])).(string)
  205. bn.Area = MC.If(MC.ObjToString(v["area"]) == "A", "全国", MC.ObjToString(v["area"])).(string)
  206. bn.Buyerclass = MC.ObjToString(v["buyerclass"])
  207. bn.City = MC.ObjToString(v["city"])
  208. bn.District = MC.InterfaceToStr(v["district"]) //县区
  209. bn.Industry = MC.If(MC.ObjToString(v["s_subscopeclass"]) != "", strings.Split(strings.Split(MC.ObjToString(v["s_subscopeclass"]), ",")[0], "_")[0], "").(string)
  210. bn.SpiderCode = MC.ObjToString(v["spidercode"])
  211. bn.Site = MC.ObjToString(v["site"])
  212. }
  213. }
  214. }
  215. //
  216. for _, v := range infos {
  217. res = append(res, v)
  218. }
  219. }
  220. return
  221. }
  222. // 根据定位或者搜索历史 查es
  223. func NewestQuery(city, keys, subtype string) (str string) {
  224. var musts, bools []string
  225. if keys != "" {
  226. for _, v := range strings.Split(keys, ",") {
  227. keys := strings.Split(v, " ") //历史搜索 空格划分
  228. must_tmp := []string{}
  229. for _, key := range keys {
  230. must_tmp = append(must_tmp, fmt.Sprintf(multi_match, "\""+key+"\""))
  231. }
  232. bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(must_tmp, ","), ""))
  233. }
  234. }
  235. if city != "" {
  236. musts = append(musts, fmt.Sprintf(query_bool_must, "city", `"`+city+`"`))
  237. }
  238. //未登录首页推送数据限制
  239. if subtype != "" {
  240. musts = append(musts, fmt.Sprintf(query_bool_must, "subtype", subtype))
  241. }
  242. minimum_should_match := 0
  243. if len(bools) > 0 {
  244. minimum_should_match = 1
  245. }
  246. str = fmt.Sprintf(query_city_hkeys, strings.Join(musts, ","), strings.Join(bools, ","), minimum_should_match, IC.C.NewsLimitNum)
  247. logx.Info("str:", str)
  248. return
  249. }
  250. // es查询
  251. func NewestES(doSearchStr string) (res []*bxbase.NewestList) {
  252. list := elastic.Get(search_index, search_type, doSearchStr)
  253. if list != nil && len(*list) > 0 {
  254. for _, v := range *list {
  255. _id := mongodb.BsonIdToSId(v["_id"])
  256. isValidFile, _ := v["isValidFile"].(bool)
  257. res = append(res, &bxbase.NewestList{
  258. Id: ME.EncodeArticleId2ByCheck(_id),
  259. Title: MC.ObjToString(v["title"]),
  260. Subtype: MC.If(v["subtype"] != nil, MC.ObjToString(v["subtype"]), MC.ObjToString(v["toptype"])).(string),
  261. Area: MC.If(MC.ObjToString(v["area"]) == "A", "全国", MC.ObjToString(v["area"])).(string),
  262. Buyerclass: MC.ObjToString(v["buyerclass"]),
  263. City: MC.ObjToString(v["city"]),
  264. District: MC.ObjToString(v["district"]), //县区
  265. Industry: MC.If(MC.ObjToString(v["s_subscopeclass"]) != "", strings.Split(strings.Split(MC.ObjToString(v["s_subscopeclass"]), ",")[0], "_")[0], "").(string),
  266. Budget: MC.Int64All(v["budget"]),
  267. Bidamount: MC.Int64All(v["bidamount"]),
  268. FileExists: isValidFile, //附件
  269. PublishTime: MC.Int64All(v["publishtime"]),
  270. Site: MC.ObjToString(v["site"]),
  271. SpiderCode: MC.ObjToString(v["spidercode"]),
  272. })
  273. }
  274. }
  275. return
  276. }
  277. // GetRedisKeyTimeout 获取缓存的key 和超时时间
  278. func GetRedisKeyTimeout(status int, positionId int64) config.CacheConfig {
  279. var (
  280. redisKey, cuKey string
  281. timeOut, cuTimeOut int
  282. )
  283. switch status {
  284. case StatusNoLogin:
  285. redisKey = IC.C.NewsCache.NoLogin.Key
  286. //redisKey = fmt.Sprintf(redisKey, time.Now().Year(), time.Now().Month(), time.Now().Day())
  287. redisKey = fmt.Sprintf(redisKey, time.Now().Year(), 8, 8) //最开始逻辑是每日更新---》每7天更新一次;不麻烦改配置,就改代码默认月份是8 日期是8
  288. timeOut = IC.C.NewsCache.NoLogin.Timeout
  289. cuKey = fmt.Sprintf("%s_%s", redisKey, IC.C.NewsCache.NoLogin.CacheUpdateKey)
  290. cuTimeOut = IC.C.NewsCache.NoLogin.CacheUpdateTimeout
  291. case StatusLoginUser:
  292. redisKey = IC.C.NewsCache.LoginUser.Key // 登录用户使用的缓存key
  293. //redisKey = fmt.Sprintf(redisKey, positionId, time.Now().Year(), time.Now().Month(), time.Now().Day())
  294. redisKey = fmt.Sprintf(redisKey, positionId, time.Now().Year(), 8, 8) //
  295. timeOut = IC.C.NewsCache.LoginUser.Timeout
  296. cuKey = fmt.Sprintf("%s_%s", redisKey, IC.C.NewsCache.LoginUser.CacheUpdateKey)
  297. cuTimeOut = IC.C.NewsCache.LoginUser.CacheUpdateTimeout
  298. case StatusLogin:
  299. redisKey = IC.C.NewsCache.Login.Key // 登录用户使用的最新标讯缓存key
  300. //redisKey = fmt.Sprintf(redisKey, time.Now().Year(), time.Now().Month(), time.Now().Day())
  301. redisKey = fmt.Sprintf(redisKey, time.Now().Year(), 8, 8) //
  302. timeOut = IC.C.NewsCache.Login.Timeout
  303. cuKey = fmt.Sprintf("%s_%s", redisKey, IC.C.NewsCache.Login.CacheUpdateKey)
  304. cuTimeOut = IC.C.NewsCache.Login.CacheUpdateTimeout
  305. }
  306. return config.CacheConfig{
  307. Key: redisKey,
  308. Timeout: timeOut,
  309. CacheUpdateKey: cuKey,
  310. CacheUpdateTimeout: cuTimeOut,
  311. }
  312. }
  313. // PutNewsCache 存缓存
  314. func PutNewsCache(redisKey string, redisTimeout int, list []*bxbase.NewestList) {
  315. b, err := json.Marshal(list)
  316. if err != nil {
  317. log.Printf("保存缓存 序列化异常,data:%s,err:%s\n", list, err.Error())
  318. return
  319. }
  320. //redisTimeout = redisTimeout + util.GetRand(604800) //缓存时间随机性7d+
  321. if err = redis.PutBytes("new", redisKey, &b, redisTimeout); err != nil {
  322. log.Printf("保存缓存 redis 异常,key:%s,err:%s\n", redisKey, err.Error())
  323. }
  324. }
  325. // GetNewsCache 取缓存
  326. func GetNewsCache(cc config.CacheConfig) (list []*bxbase.NewestList, err error) {
  327. redisByte, err := redis.GetBytes("new", cc.Key)
  328. if err != nil || redisByte == nil || len(*redisByte) == 0 {
  329. return list, err
  330. }
  331. err = json.Unmarshal(*redisByte, &list)
  332. if err != nil {
  333. logx.Info(fmt.Sprintf("读取缓存 序列化异常,err:%s", err.Error()))
  334. return nil, err
  335. }
  336. return list, nil
  337. }
  338. type NewSet struct {
  339. Status int
  340. RedisKeyModel config.CacheConfig
  341. RedisStatus int
  342. Query string
  343. }
  344. // 排序 入缓存
  345. // status : 0 -拿到的是缓存 不用再处理也不用存缓存 1-存到未登录用户 2-存到用户自己的key 3-存到登录用户最新标讯
  346. func DataSortInRedis(r *bxbase.NewsetBiddingResp, status int, positionId int64) {
  347. //排序
  348. sort.Slice(r.Data.List, func(i, j int) bool {
  349. return r.Data.List[i].PublishTime > r.Data.List[j].PublishTime
  350. })
  351. redisKeyModel := GetRedisKeyTimeout(status, positionId)
  352. timeout := redisKeyModel.Timeout
  353. if status != StatusNoLogin { //未登录用户修改缓存时间p574
  354. timeout += util.GetRand(604800) //缓存时间随机性7d+
  355. }
  356. go PutNewsCache(redisKeyModel.Key, timeout, r.Data.List)
  357. }
  358. // 延长缓存
  359. // 获取最新数据 -- 延长缓存时间7天---待调整: 1、判断是否需要更新;2、判断订阅信息是否存在,如果存在是否是最新推送,3、订阅信息查推送缓存(只有个人版有缓存:pushcache_2_a )
  360. func ExtendNewListCache(n *NewSet, in *bxbase.NewestBiddingReq, list []*bxbase.NewestList) {
  361. if flag := entity.ReqLimitInit.Limit(context.Background()); flag != 1 {
  362. if flag == -2 {
  363. log.Println("等待队列已满")
  364. } else if flag == -1 {
  365. log.Println("等待超时")
  366. }
  367. } else {
  368. defer entity.ReqLimitInit.Release()
  369. if n.RedisKeyModel.Key != "" {
  370. now := time.Now()
  371. if n.RedisKeyModel.CacheUpdateKey != "" {
  372. var (
  373. res = &bxbase.NewsetBiddingResp{
  374. Data: &bxbase.NewsetBidding{
  375. List: []*bxbase.NewestList{},
  376. },
  377. }
  378. updateTime = redis.GetInt("new", n.RedisKeyModel.CacheUpdateKey)
  379. isDoing bool
  380. )
  381. //防止穿透
  382. entity.ReqLimitLock.Lock()
  383. isDoing, _ = redis.Exists("new", fmt.Sprintf("p1_indexMessage_new_recovery_%d", in.PositionId))
  384. entity.ReqLimitLock.Unlock()
  385. if !isDoing {
  386. entity.ReqLimitLock.Lock()
  387. redis.Put("new", fmt.Sprintf("p1_indexMessage_new_recovery_%d", in.PositionId), "1", 15*60) //十五分钟
  388. entity.ReqLimitLock.Unlock()
  389. switch n.RedisStatus {
  390. case StatusLoginUser:
  391. //十五分钟内 更新过一次 不再更新
  392. if int(now.Unix())-updateTime > n.RedisKeyModel.CacheUpdateTimeout {
  393. // 登录用户
  394. roleNewestInfo, _ := GetRoleNewestInfoService(in.AppId, in.MgoUserId, in.NewUserId, in.AccountId, in.EntId, in.EntUserId, in.PositionType, in.PositionId)
  395. //当前用户有最新推送信息
  396. lastPublishTime := list[len(list)-1].PublishTime
  397. if roleNewestInfo.IsHasNewPushData(lastPublishTime) {
  398. // 查推送
  399. subscribeTime := time.Now()
  400. res.Data.List = roleNewestInfo.GetPushHistory()
  401. log.Println(in.PositionId, "获取订阅数据 存缓存 耗时:", time.Since(subscribeTime).Seconds())
  402. } else {
  403. res.Data.List = list
  404. }
  405. }
  406. default:
  407. //十五分钟内 更新过一次 不再更新
  408. if int(now.Unix())-updateTime > n.RedisKeyModel.CacheUpdateTimeout {
  409. res.Data.List = NewestES(n.Query)
  410. }
  411. }
  412. if len(res.Data.List) > 0 {
  413. //更新update time
  414. redis.Put("new", n.RedisKeyModel.CacheUpdateKey, now.Unix(), n.RedisKeyModel.CacheUpdateTimeout)
  415. go DataSortInRedis(res, n.RedisStatus, in.PositionId)
  416. }
  417. }
  418. }
  419. ////剩余时间 在 IC.C.NewsTimeOut 之内
  420. //if ttl := redis.GetTTL("new", n.RedisKeyModel.Key); ttl-IC.C.NewsTimeOut < 0 {
  421. //
  422. //}
  423. }
  424. }
  425. }