push.go 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. package model
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/encrypt"
  6. "app.yhyue.com/moapp/jybase/esv1"
  7. "app.yhyue.com/moapp/jybase/mongodb"
  8. "app.yhyue.com/moapp/jybase/mysql"
  9. "app.yhyue.com/moapp/jybase/redis"
  10. "database/sql"
  11. "encoding/json"
  12. "fmt"
  13. "github.com/zeromicro/go-zero/core/logx"
  14. "go.mongodb.org/mongo-driver/bson/primitive"
  15. IC "jyBXSubscribe/rpc/init"
  16. ms "jyBXSubscribe/rpc/model/service"
  17. "jyBXSubscribe/rpc/type/bxsubscribe"
  18. "log"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. "time"
  23. )
  24. //
  25. const (
  26. pageSize = 50
  27. AllSubPushCacheSize = 250
  28. query = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","area", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "buyerclass","bidamount","budget","projectname","buyer","bidopentime","s_winner","filetext"],"from":0,"size":%d}`
  29. mongodb_fields = `{"_id":1,"area":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}`
  30. SubFreeFlag = "fType"
  31. SubVipFlag = "vType"
  32. MemberFlag = "mType"
  33. EntnicheFlag = "eType"
  34. oneDay = 24 * 60 * 60
  35. Pushbidding = "pushbidding"
  36. Province = "province"
  37. )
  38. var (
  39. buildingInsertCollKey = []string{"infoid", "area", "city", "buyerclass", "toptype", "subtype", "subscopeclass", "budget", "bidamount", "attachment_count", "publishtime"}
  40. ennicheInsertCollKey = []string{"entid", "deptid", "userid", "bidid", "matchkeys", "date"}
  41. subscribeInsertCollKey = []string{"userid", "bidid", "matchkeys", "date"}
  42. memberInsertCollKey = []string{"userid", "bidid", "matchkeys", "date"}
  43. )
  44. var aboutDbMsg map[string]*AboutDbMsg = map[string]*AboutDbMsg{
  45. SubFreeFlag: &AboutDbMsg{"pushsubscribe", "subpush"},
  46. SubVipFlag: &AboutDbMsg{"pushsubscribe", "subpush"},
  47. MemberFlag: &AboutDbMsg{"pushmember", "memberpush"},
  48. EntnicheFlag: &AboutDbMsg{"pushentniche", "entnichepush"},
  49. }
  50. type AboutDbMsg struct {
  51. MysqlTable string
  52. RedisKeyFlag string
  53. }
  54. type SubPush struct {
  55. Date string
  56. Datas []*bxsubscribe.SubscribeInfo
  57. Count int64
  58. }
  59. type PushCa struct {
  60. Date int64
  61. InfoId string
  62. Visit int
  63. Index int64
  64. Keys []string
  65. Type int
  66. Isvip int
  67. FileExists bool
  68. }
  69. //查询参数
  70. type SubPushQueryParam struct {
  71. Mgo_bidding mongodb.MongodbSim //
  72. Bidding string //
  73. Bidding_back string //
  74. UserId string //用户id
  75. PageNum int //页面
  76. PageSize int //每页数量
  77. SelectTime string //时间
  78. Area string //区域
  79. City string //城市
  80. Buyerclass string //采购单位行业
  81. Subtype string //信息类型 二级分类
  82. Subscopeclass string //信息行业
  83. Key string //订阅词
  84. Export bool //导出
  85. EntId string //企业id
  86. Price string //价格
  87. FileExists string //是否有附件;默认全部;1:有附件;-1:无附件
  88. EntUserId string //商机管理用户id
  89. DeptId string //商机管理用户部门id
  90. BaseServiceMysql *mysql.Mysql
  91. NewUserId int64
  92. }
  93. func (spqp *SubPushQueryParam) IsEmpty() bool {
  94. return spqp.SelectTime == "" && spqp.Area == "" && spqp.City == "" && spqp.Buyerclass == "" && spqp.Subscopeclass == "" && spqp.Subtype == "" && spqp.Key == "" && spqp.Price == "" && spqp.FileExists == ""
  95. }
  96. type subscribePush struct {
  97. ModuleFlag string
  98. }
  99. func NewSubscribePush(module ...string) *subscribePush {
  100. m := ""
  101. if len(module) > 0 {
  102. m = module[0]
  103. }
  104. return &subscribePush{m}
  105. }
  106. //从pushcache_2_a中取
  107. func (s *subscribePush) GetTodayCache(userId string) (*SubPush, error) {
  108. pc_a, err := redis.GetNewBytes("pushcache_2_b", s.todayKey(userId))
  109. if err != nil {
  110. return nil, err
  111. }
  112. if pc_a == nil {
  113. return nil, nil
  114. }
  115. var p *SubPush
  116. if err := json.Unmarshal(*pc_a, &p); err != nil {
  117. return nil, err
  118. }
  119. return p, nil
  120. }
  121. //往pushcache_2_a中放
  122. func (s *subscribePush) PutTodayCache(userId string, pc_a *SubPush) {
  123. redis.Put("pushcache_2_b", s.todayKey(userId), pc_a, oneDay)
  124. }
  125. //获取redis key
  126. func (s *subscribePush) todayKey(userId string) string {
  127. return fmt.Sprintf("%s_%s", aboutDbMsg[s.ModuleFlag].RedisKeyFlag, userId)
  128. }
  129. func (s *subscribePush) allKey(userId string) string {
  130. return fmt.Sprintf("all_%s_%s", aboutDbMsg[s.ModuleFlag].RedisKeyFlag, userId)
  131. }
  132. //历史推送记录中单条信息格式化
  133. func (s *subscribePush) InfoFormat(p *PushCa, info *map[string]interface{}) *bxsubscribe.SubscribeInfo {
  134. area := common.ObjToString((*info)["area"])
  135. if area == "A" {
  136. area = "全国"
  137. }
  138. industry := common.ObjToString((*info)["s_subscopeclass"])
  139. scs := strings.Split(industry, ",")
  140. if len(scs) > 0 {
  141. industry = scs[0]
  142. if industry != "" {
  143. iss := strings.Split(industry, "_")
  144. if len(iss) > 0 {
  145. industry = iss[0]
  146. }
  147. }
  148. }
  149. infotype := common.ObjToString((*info)["subtype"])
  150. if infotype == "" {
  151. infotype = common.ObjToString((*info)["toptype"])
  152. }
  153. if infotype == "" {
  154. infotype = common.ObjToString((*info)["type"])
  155. if infotype == "tender" {
  156. infotype = "招标"
  157. } else if infotype == "bid" {
  158. infotype = "中标"
  159. }
  160. }
  161. _id := p.InfoId
  162. if _id == "" {
  163. _id = common.ObjToString((*info)["_id"])
  164. }
  165. return &bxsubscribe.SubscribeInfo{
  166. XId: encrypt.EncodeArticleId2ByCheck(_id),
  167. Title: common.ObjToString((*info)["title"]),
  168. Area: area,
  169. BuyerClass: common.ObjToString((*info)["buyerclass"]),
  170. Subtype: infotype,
  171. Industry: industry,
  172. PublishTime: common.Int64All((*info)["publishtime"]),
  173. CaIndex: p.Index,
  174. CaDate: p.Date,
  175. CaIsvisit: int64(p.Visit),
  176. CaIsvip: int64(p.Isvip),
  177. CaType: int64(p.Type),
  178. MatchKeys: p.Keys,
  179. Budget: common.ObjToString((*info)["budget"]),
  180. BidAmount: common.ObjToString((*info)["bidamount"]),
  181. Buyer: common.ObjToString((*info)["buyer"]),
  182. ProjectName: common.ObjToString((*info)["projectname"]),
  183. Winner: common.ObjToString((*info)["s_winner"]),
  184. BidOpenTime: common.ObjToString((*info)["bidopentime"]),
  185. CaFileExists: p.FileExists,
  186. }
  187. }
  188. func (s *subscribePush) Datas(spqp *SubPushQueryParam) (hasNextPage bool, total int64, result []*bxsubscribe.SubscribeInfo) {
  189. logx.Info(spqp.UserId, spqp.NewUserId, s.ModuleFlag, "subscribePush query param:", "SelectTime:", spqp.SelectTime, "Area:", spqp.Area, "City:", spqp.City, "Subtype:", spqp.Subtype, "Subscopeclass:", spqp.Subscopeclass, "Buyerclass:", spqp.Buyerclass, "Key:", spqp.Key, "PageNum:", spqp.PageNum, "Price:", spqp.Price, "FileExists:", spqp.FileExists)
  190. if spqp.UserId == "" {
  191. return
  192. }
  193. if spqp.PageNum < 1 {
  194. spqp.PageNum = 1
  195. }
  196. if spqp.PageSize < 1 || spqp.PageSize > pageSize {
  197. if !spqp.Export {
  198. spqp.PageSize = pageSize
  199. } else { //数据导出查询20000条限制
  200. if spqp.PageSize < 1 || spqp.PageSize > 20000 {
  201. spqp.PageSize = 20000
  202. }
  203. }
  204. }
  205. starttime, endtime := int64(0), int64(0)
  206. logx.Info(4444)
  207. if len(strings.Split(spqp.SelectTime, "_")) == 2 {
  208. st := strings.Split(spqp.SelectTime, "_")[0]
  209. et := strings.Split(spqp.SelectTime, "_")[1]
  210. if st != "" && et != "" {
  211. starttime, _ = strconv.ParseInt(st, 0, 64)
  212. endtime, _ = strconv.ParseInt(et, 0, 64)
  213. if endtime > 0 {
  214. etTime := time.Unix(endtime, 0)
  215. endtime = time.Date(etTime.Year(), etTime.Month(), etTime.Day(), 23, 59, 59, 0, time.Local).Unix()
  216. }
  217. }
  218. }
  219. nowFormat := date.NowFormat(date.Date_Short_Layout)
  220. start := (spqp.PageNum - 1) * spqp.PageSize
  221. end := start + spqp.PageSize
  222. //时间是今天,没有别的过滤条件--首先读取当前推送缓存数据 其次查询数据库
  223. if nowFormat == date.FormatDateByInt64(&starttime, date.Date_Short_Layout) && spqp.Area == "" && spqp.City == "" && spqp.Buyerclass == "" && spqp.Subscopeclass == "" && spqp.Subtype == "" && spqp.Key == "" && spqp.Price == "" && spqp.FileExists == "" {
  224. logx.Info("a1:", s.todayKey(spqp.UserId))
  225. subPush, err := s.GetTodayCache(spqp.UserId)
  226. if err != nil {
  227. logx.Info(spqp.UserId, "GetTodayCache Error", err)
  228. }
  229. if err != nil || subPush == nil || subPush.Date != nowFormat || len(subPush.Datas) == 0 {
  230. list, countSearch := s.getDatasFromMysql(spqp, starttime, endtime, spqp.PageSize, false)
  231. subPush = &SubPush{
  232. Date: nowFormat,
  233. Datas: list,
  234. Count: countSearch,
  235. }
  236. s.PutTodayCache(spqp.UserId, subPush)
  237. }
  238. length := len(subPush.Datas)
  239. if end > length {
  240. end = length
  241. }
  242. if start < length {
  243. result = subPush.Datas[start:end]
  244. }
  245. total = int64(length)
  246. } else if spqp.IsEmpty() && (spqp.PageNum-1)*spqp.PageSize <= 250 { //全部,没有过滤条件 之前缓存5页*50条=250
  247. logx.Info("a2:", s.allKey(spqp.UserId))
  248. allCache, err := s.GetAllCache(spqp.UserId)
  249. if err != nil {
  250. logx.Info(spqp.UserId, "GetAllCache Error", err)
  251. }
  252. if err != nil || allCache == nil || allCache.Date != nowFormat || len(allCache.Datas) == 0 {
  253. spqp.PageNum = 1
  254. logx.Info(1111)
  255. list, countSearch := s.getDatasFromMysql(spqp, starttime, endtime, AllSubPushCacheSize, true)
  256. allCache = &SubPush{
  257. Date: nowFormat,
  258. Datas: list,
  259. Count: countSearch,
  260. }
  261. s.PutAllCache(spqp.UserId, allCache)
  262. }
  263. length := len(allCache.Datas)
  264. if end > length {
  265. end = length
  266. }
  267. if start < length {
  268. result = allCache.Datas[start:end]
  269. }
  270. total = allCache.Count
  271. } else {
  272. logx.Info("a4")
  273. result, total = s.getDatasFromMysql(spqp, starttime, endtime, spqp.PageSize, true)
  274. }
  275. logx.Info("-------------------------------------------------", len(result))
  276. if result == nil {
  277. result = []*bxsubscribe.SubscribeInfo{}
  278. }
  279. hasNextPage = len(result) >= spqp.PageSize
  280. return
  281. }
  282. //
  283. func (s *subscribePush) getDatasFromMysql(spqp *SubPushQueryParam, starttime, endtime int64, size int, isLimit bool) (result []*bxsubscribe.SubscribeInfo, count int64) {
  284. querys := []string{fmt.Sprintf("a.userid='%s'", common.If(s.ModuleFlag == "eType", spqp.EntUserId, common.InterfaceToStr(spqp.NewUserId)))}
  285. //时间
  286. if starttime > 0 && endtime > 0 {
  287. querys = append(querys, fmt.Sprintf("a.date>=%d and date<=%d", starttime, endtime))
  288. } else if starttime > 0 && endtime == 0 {
  289. querys = append(querys, fmt.Sprintf("a.date>=%d", starttime))
  290. } else if starttime == 0 && endtime > 0 {
  291. querys = append(querys, fmt.Sprintf("a.date<=%d", endtime))
  292. }
  293. if spqp.Area != "" || spqp.City != "" {
  294. var sqlAreaCity = ""
  295. //城市
  296. city := []string{}
  297. for _, v := range strings.Split(spqp.City, ",") {
  298. if IC.PushMapping.City[v] > 0 {
  299. city = append(city, fmt.Sprint(IC.PushMapping.City[v]))
  300. } else {
  301. city = append(city, "-1")
  302. }
  303. }
  304. if len(city) == 1 {
  305. city = append(city, "9999")
  306. }
  307. if len(city) > 0 {
  308. sqlAreaCity = fmt.Sprintf("p.city in (%s)", strings.Join(city, ","))
  309. }
  310. //区域
  311. var sqlArea = ""
  312. area := []string{}
  313. for _, v := range strings.Split(spqp.Area, ",") {
  314. if IC.PushMapping.Area[v] > 0 {
  315. area = append(area, fmt.Sprint(IC.PushMapping.Area[v]))
  316. } else {
  317. area = append(area, "-1")
  318. }
  319. }
  320. if len(area) == 1 {
  321. area = append(area, "9999")
  322. }
  323. if len(area) > 0 {
  324. sqlArea = fmt.Sprintf("p.area in (%s)", strings.Join(area, ","))
  325. }
  326. if sqlAreaCity != "" && sqlArea != "" {
  327. sqlAreaCity = "( " + sqlAreaCity + " or " + sqlArea + " )"
  328. } else if sqlAreaCity == "" && sqlArea != "" {
  329. sqlAreaCity = sqlArea
  330. }
  331. if sqlAreaCity != "" {
  332. querys = append(querys, sqlAreaCity)
  333. }
  334. }
  335. //采购单位行业
  336. if spqp.Buyerclass != "" {
  337. buyerclass := []string{}
  338. for _, v := range strings.Split(spqp.Buyerclass, ",") {
  339. buyerclass = append(buyerclass, fmt.Sprint(IC.PushMapping.Buyerclass[v]))
  340. }
  341. if len(buyerclass) == 1 {
  342. buyerclass = append(buyerclass, "9999")
  343. }
  344. if len(buyerclass) > 0 {
  345. querys = append(querys, fmt.Sprintf("b.buyerclass in (%s)", strings.Join(buyerclass, ",")))
  346. }
  347. }
  348. //信息类型
  349. if spqp.Subtype != "" {
  350. subtype := []string{}
  351. for _, v := range strings.Split(spqp.Subtype, ",") {
  352. subtype = append(subtype, fmt.Sprint(IC.PushMapping.Subtype[v]))
  353. }
  354. if len(subtype) == 1 {
  355. subtype = append(subtype, "9999")
  356. }
  357. if len(subtype) > 0 {
  358. querys = append(querys, fmt.Sprintf("b.subtype in (%s)", strings.Join(subtype, ",")))
  359. }
  360. }
  361. //信息行业
  362. if spqp.Subscopeclass != "" {
  363. find_in_set := []string{}
  364. for _, v := range strings.Split(spqp.Subscopeclass, ",") {
  365. find_in_set = append(find_in_set, fmt.Sprintf("find_in_set('%d',b.subscopeclass)", IC.PushMapping.Subscopeclass[v]))
  366. }
  367. if len(find_in_set) == 1 {
  368. querys = append(querys, find_in_set[0])
  369. } else if len(find_in_set) > 1 {
  370. querys = append(querys, fmt.Sprintf("(%s)", strings.Join(find_in_set, " or ")))
  371. }
  372. }
  373. //关键词
  374. if spqp.Key != "" {
  375. find_in_set := []string{}
  376. for _, v := range strings.Split(spqp.Key, ",") {
  377. find_in_set = append(find_in_set, fmt.Sprintf("find_in_set('%s',replace(replace(a.matchkeys,'+',','),' ',','))", v))
  378. }
  379. if len(find_in_set) == 1 {
  380. querys = append(querys, find_in_set[0])
  381. } else if len(find_in_set) > 1 {
  382. querys = append(querys, fmt.Sprintf("(%s)", strings.Join(find_in_set, " or ")))
  383. }
  384. }
  385. //价格- 预算和中标金额
  386. if spqp.Price != "" && strings.Contains(spqp.Price, "-") {
  387. minPriceStr, maxPriceStr := strings.Split(spqp.Price, "-")[0], strings.Split(spqp.Price, "-")[1]
  388. minPrice := common.Int64All(common.Float64All(minPriceStr) * 10000) //换成元
  389. maxPrice := common.Int64All(common.Float64All(maxPriceStr) * 10000) //换成元
  390. if minPriceStr != "" && maxPriceStr != "" {
  391. querys = append(querys, fmt.Sprintf("((b.bidamount>=%d and b.bidamount<=%d) or (b.budget>=%d and b.budget<=%d and b.bidamount is null))", minPrice, maxPrice, minPrice, maxPrice))
  392. } else if minPriceStr != "" {
  393. querys = append(querys, fmt.Sprintf("(b.bidamount>=%d or (b.budget>=%d and b.bidamount is null))", minPrice, minPrice))
  394. } else if maxPriceStr != "" {
  395. querys = append(querys, fmt.Sprintf("(b.bidamount<=%d or (b.budget<=%d and b.bidamount is null))", maxPrice, maxPrice))
  396. }
  397. }
  398. //附件
  399. if spqp.FileExists != "" {
  400. if spqp.FileExists == "1" {
  401. querys = append(querys, fmt.Sprintf("b.attachment_count is not null"))
  402. } else if spqp.FileExists == "-1" {
  403. querys = append(querys, fmt.Sprintf("b.attachment_count is null"))
  404. }
  405. }
  406. searchSql := fmt.Sprintf(" from %s a LEFT JOIN %s b ON a.bidid = b.id LEFT JOIN %s p on b.area=p.id or b.city=p.id where %s"+
  407. " order by a.id desc", aboutDbMsg[s.ModuleFlag].MysqlTable, Pushbidding, Province, strings.Join(querys, " and "))
  408. fmt.Println("searchSql", searchSql)
  409. //查询总数
  410. count = spqp.BaseServiceMysql.CountBySql(fmt.Sprintf("select count(a.id)" + searchSql))
  411. logx.Info("count:", count, "---", s.ModuleFlag)
  412. findSql := "select a.id,a.date,b.infoid,a.isvisit,a.matchkeys,a.type"
  413. if s.ModuleFlag != MemberFlag && s.ModuleFlag != EntnicheFlag {
  414. findSql += ",isvip"
  415. }
  416. findSql += searchSql
  417. if isLimit {
  418. findSql += fmt.Sprintf(" limit %d,%d", (spqp.PageNum-1)*size, size)
  419. }
  420. logx.Info(spqp.NewUserId, "subscribePush query sql:", findSql)
  421. list := spqp.BaseServiceMysql.SelectBySql(findSql)
  422. if list != nil && len(*list) > 0 {
  423. pushCas := s.GetJyPushs(*list)
  424. result = s.GetInfoByIds(spqp.Mgo_bidding, spqp.Bidding, spqp.Bidding_back, pushCas)
  425. } else {
  426. result = []*bxsubscribe.SubscribeInfo{}
  427. }
  428. return
  429. }
  430. //根据id取内容
  431. func (s *subscribePush) GetInfoByIds(Mgo_bidding mongodb.MongodbSim, bidding, bidding_back string, pushCas []*PushCa) []*bxsubscribe.SubscribeInfo {
  432. array := make([]*bxsubscribe.SubscribeInfo, len(pushCas))
  433. if len(pushCas) == 0 {
  434. return array
  435. }
  436. m := map[string]bool{}
  437. ids := []string{}
  438. for _, v := range pushCas {
  439. if m[v.InfoId] {
  440. continue
  441. }
  442. m[v.InfoId] = true
  443. ids = append(ids, v.InfoId)
  444. }
  445. infos := map[string]map[string]interface{}{}
  446. //redis
  447. es_ids := []string{}
  448. for _, v := range ids {
  449. //剑鱼程序未找到赋值 位置;猜测在推送程序中
  450. info_i := redis.Get("pushcache_1", fmt.Sprintf("info_%s", v))
  451. if info_i != nil {
  452. info_m, _ := info_i.(map[string]interface{})
  453. info_m["_id"] = v
  454. infos[v] = info_m
  455. } else {
  456. es_ids = append(es_ids, v)
  457. }
  458. }
  459. //elasticsearch
  460. if len(es_ids) > 0 {
  461. list := elastic.Get("bidding", "bidding", fmt.Sprintf(query, strings.Join(es_ids, `","`), len(es_ids)))
  462. if list != nil {
  463. for _, v := range *list {
  464. _id := common.ObjToString(v["_id"])
  465. infos[_id] = v
  466. }
  467. }
  468. }
  469. //mongodb bidding
  470. mgo_ids := []primitive.ObjectID{}
  471. for _, v := range es_ids {
  472. if infos[v] == nil {
  473. _id, _ := primitive.ObjectIDFromHex(v)
  474. mgo_ids = append(mgo_ids, _id)
  475. }
  476. }
  477. if len(mgo_ids) > 0 {
  478. list, ok := Mgo_bidding.Find(bidding, map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_ids}}, nil, mongodb_fields, false, -1, -1)
  479. if ok && *list != nil {
  480. for _, v := range *list {
  481. _id := mongodb.BsonIdToSId(v["_id"])
  482. v["_id"] = _id
  483. infos[_id] = v
  484. }
  485. }
  486. }
  487. //mongodb bidding_back
  488. mgo_back_ids := []primitive.ObjectID{}
  489. for _, v := range mgo_ids {
  490. if infos[mongodb.BsonIdToSId(v)] == nil {
  491. mgo_back_ids = append(mgo_back_ids, v)
  492. }
  493. }
  494. if len(mgo_back_ids) > 0 {
  495. list, ok := Mgo_bidding.Find(bidding_back, map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_back_ids}}, nil, mongodb_fields, false, -1, -1)
  496. if ok && *list != nil {
  497. for _, v := range *list {
  498. _id := mongodb.BsonIdToSId(v["_id"])
  499. v["_id"] = _id
  500. infos[_id] = v
  501. }
  502. }
  503. }
  504. //
  505. for k, v := range pushCas {
  506. info := infos[v.InfoId]
  507. if info == nil {
  508. info = map[string]interface{}{}
  509. }
  510. array[k] = s.InfoFormat(v, &info)
  511. }
  512. return array
  513. }
  514. //获取历史推送
  515. func (s *subscribePush) GetJyPushs(datas []map[string]interface{}) (pushCas []*PushCa) {
  516. pushCas = []*PushCa{}
  517. for _, v := range datas {
  518. keys := []string{}
  519. if matchkeys := common.ObjToString(v["matchkeys"]); matchkeys != "" {
  520. keys = strings.Split(matchkeys, " ")
  521. }
  522. pushCas = append(pushCas, &PushCa{
  523. Date: common.Int64All(v["date"]),
  524. InfoId: common.ObjToString(v["infoid"]),
  525. Visit: common.IntAll(v["isvisit"]),
  526. Index: common.Int64All(v["id"]),
  527. Keys: keys,
  528. Type: common.IntAll(v["type"]),
  529. Isvip: common.IntAll(v["isvip"]),
  530. FileExists: common.IntAll(v["attachment_count"]) > 0,
  531. })
  532. }
  533. return
  534. }
  535. //查看全部列表缓存
  536. func (s *subscribePush) PutAllCache(userId string, datas *SubPush) {
  537. redis.Put("pushcache_2_a", s.allKey(userId), datas, oneDay)
  538. }
  539. func (s *subscribePush) GetAllCache(userId string) (*SubPush, error) {
  540. return s.GetCache("pushcache_2_a", s.allKey(userId))
  541. }
  542. func (s *subscribePush) GetCache(code, key string) (*SubPush, error) {
  543. pc_a, err := redis.GetNewBytes(code, key)
  544. if err != nil {
  545. return nil, err
  546. }
  547. if pc_a == nil {
  548. return nil, nil
  549. }
  550. var p *SubPush
  551. if err := json.Unmarshal(*pc_a, &p); err != nil {
  552. return nil, err
  553. }
  554. return p, nil
  555. }
  556. //是否收藏
  557. func (s *subscribePush) MakeCollection(userId string, list []*bxsubscribe.SubscribeInfo) {
  558. if list == nil || len(list) == 0 {
  559. return
  560. }
  561. param := []interface{}{userId}
  562. wh := []string{}
  563. for _, v := range list {
  564. array := encrypt.DecodeArticleId2ByCheck(v.XId)
  565. if len(array) == 1 && array[0] != "" {
  566. param = append(param, array[0])
  567. wh = append(wh, "?")
  568. }
  569. }
  570. if len(wh) > 0 {
  571. result := IC.MainMysql.SelectBySql(`select bid from bdcollection where userid=? and bid in (`+strings.Join(wh, ",")+`)`, param...)
  572. bid_map := map[string]bool{}
  573. if result != nil {
  574. for _, v := range *result {
  575. bid_map[encrypt.EncodeArticleId2ByCheck(common.ObjToString(v["bid"]))] = true
  576. }
  577. }
  578. for _, v := range list {
  579. if bid_map[v.XId] {
  580. v.Collection = 1
  581. }
  582. }
  583. }
  584. }
  585. //仅移动端首页使用,历史推送7天信息
  586. func (s *subscribePush) sevenDayKey(userId string) string {
  587. return fmt.Sprintf("7day_subpush_%s", userId)
  588. }
  589. func (s *subscribePush) PutSevenDayCache(userId string, datas []*bxsubscribe.SubscribeInfo) {
  590. redis.Put("pushcache_2_a", s.sevenDayKey(userId), SubPush{Datas: datas}, 7*24*60*60)
  591. }
  592. //从pushcache_2_a中取
  593. func (s *subscribePush) GetSevenDayCache(userId string) ([]*bxsubscribe.SubscribeInfo, error) {
  594. allPush, _ := s.GetCache("pushcache_2_a", s.sevenDayKey(userId))
  595. if allPush != nil && allPush.Datas != nil && len(allPush.Datas) > 0 {
  596. return allPush.Datas, nil
  597. }
  598. return nil, nil
  599. }
  600. //历史推送记录中单条信息格式化
  601. func InfoFormats(info map[string]interface{}, tmp map[string]interface{}) map[string]interface{} {
  602. area := common.ObjToString(info["area"])
  603. if area == "A" {
  604. area = "全国"
  605. }
  606. industry := common.ObjToString(info["s_subscopeclass"])
  607. scs := strings.Split(industry, ",")
  608. if len(scs) > 0 {
  609. industry = scs[0]
  610. if industry != "" {
  611. iss := strings.Split(industry, "_")
  612. if len(iss) > 0 {
  613. industry = iss[0]
  614. }
  615. }
  616. }
  617. infotype := common.ObjToString(info["subtype"])
  618. if infotype == "" {
  619. infotype = common.ObjToString(info["toptype"])
  620. }
  621. if infotype == "" {
  622. infotype = common.ObjToString(info["type"])
  623. if infotype == "tender" {
  624. infotype = "招标"
  625. } else if infotype == "bid" {
  626. infotype = "中标"
  627. }
  628. }
  629. info["type"] = infotype
  630. return info
  631. }
  632. //UpdateUserPushUnread 更新app未读标识为已读
  633. func UpdateUserPushUnread(userid string, vt string) {
  634. if vt == MemberFlag {
  635. IC.Mgo.UpdateById("user", userid, map[string]interface{}{"$set": map[string]interface{}{"i_member_apppushunread": 0}})
  636. } else if vt == EntnicheFlag {
  637. IC.Mgo.UpdateById("user", userid, map[string]interface{}{"$set": map[string]interface{}{"i_entniche_apppushunread": 0}})
  638. } else {
  639. IC.Mgo.UpdateById("user", userid, map[string]interface{}{"$set": map[string]interface{}{"i_apppushunread": 0}})
  640. }
  641. }
  642. //
  643. //获取用户信息
  644. func (s *subscribePush) UserInfo(userId string) (*map[string]interface{}, int64) {
  645. user, ok := IC.Mgo.FindById("user", userId, `{"s_m_openid":1,"a_m_openid":1,"s_phone":1,"a_mergeorder":1,"o_jy":1,"l_firstpushtime":1,"i_vip_status":1,"l_vip_endtime":1,"o_vipjy":1,"i_member_status":1,"o_member_jy":1}`)
  646. if !ok || user == nil {
  647. return nil, 0
  648. }
  649. return user, common.Int64All((*user)["l_firstpushtime"])
  650. }
  651. //是否有订阅词
  652. func GetKeySet(t string, u *map[string]interface{}, data []string) (bool, []string) {
  653. var industry_ = []string{}
  654. if u != nil {
  655. if t == SubFreeFlag {
  656. o_jy, _ := (*u)["o_jy"].(map[string]interface{})
  657. a_key, _ := o_jy["a_key"].([]interface{})
  658. return len(a_key) > 0, industry_
  659. } else {
  660. var obj map[string]interface{}
  661. if t == SubVipFlag {
  662. obj, _ = (*u)["o_vipjy"].(map[string]interface{})
  663. } else if t == MemberFlag {
  664. obj, _ = (*u)["o_member_jy"].(map[string]interface{})
  665. } else if t == EntnicheFlag {
  666. if len(data) > 0 {
  667. return true, data
  668. } else {
  669. return false, data
  670. }
  671. }
  672. if obj != nil {
  673. if buyerclassObj, ok := obj["a_buyerclass"].([]interface{}); ok {
  674. industry_ = common.ObjArrToStringArr(buyerclassObj)
  675. }
  676. itmes, _ := obj["a_items"].([]interface{})
  677. for _, v := range itmes {
  678. item, _ := v.(map[string]interface{})
  679. keys, _ := item["a_key"].([]interface{})
  680. if len(keys) > 0 {
  681. return true, industry_
  682. }
  683. }
  684. }
  685. }
  686. }
  687. return false, industry_
  688. }
  689. const (
  690. INDEX = "bidding"
  691. TYPE = "bidding"
  692. bidField = `"_id","title","publishtime","toptype","subtype","type","area","city","s_subscopeclass","buyerclass","budget","bidamount","filetext","spidercode","site"`
  693. bidTime = `{"range":{"publishtime":{"gt":%d}}}`
  694. bidSort = `{"publishtime":"desc"}`
  695. findfields = `"title"`
  696. )
  697. //首次访问推送页面 默认生成推送数据
  698. //默认匹配es 7天内数据
  699. func (s *subscribePush) DefaultDatas(spqp *SubPushQueryParam) (hasNextPage bool, total int64, result []*bxsubscribe.SubscribeInfo) {
  700. if spqp.UserId == "" {
  701. return false, 0, nil
  702. }
  703. t1 := time.Now()
  704. log.Println("userId:", spqp.UserId)
  705. log.Println("newUserId:", spqp.NewUserId)
  706. //用户信息
  707. bsp := s.getUserInfo(spqp)
  708. logx.Info("获取用户信息耗时:", time.Since(t1))
  709. t2 := time.Now()
  710. if len(bsp.Keyword) > 0 {
  711. logx.Info(time.Since(t1), "--bsp:", bsp)
  712. //获取查询语句
  713. qstr := s.getDefaultDatasSQL(bsp)
  714. list := elastic.GetAllByNgram(INDEX, TYPE, qstr, findfields, bidSort, bidField, 0, bsp.Size, 0, false)
  715. logx.Info(time.Since(t1), "count:", len(*list))
  716. if list != nil && len(*list) > 0 {
  717. total = int64(len(*list))
  718. //超过50条先处理50条 返回前50条
  719. listOne := *list
  720. if len(*list) > pageSize {
  721. listOne = (*list)[:pageSize]
  722. }
  723. result = s.listManager(spqp, listOne, bsp.Keyword, (len(listOne)+pageSize)/pageSize)
  724. if len(*list) > pageSize {
  725. hasNextPage = true
  726. listOther := (*list)[pageSize:]
  727. go s.listManager(spqp, listOther, bsp.Keyword, (len(listOther)+pageSize)/pageSize)
  728. }
  729. }
  730. }
  731. logx.Info("请求耗时:", time.Since(t2))
  732. return
  733. }
  734. //保存推送表
  735. func (s *subscribePush) listManager(spqp *SubPushQueryParam, list []map[string]interface{}, keyword []ViewKeyWord, ccount int) (resultList []*bxsubscribe.SubscribeInfo) {
  736. t2 := time.Now()
  737. now := time.Now().Unix()
  738. var (
  739. wg = &sync.WaitGroup{}
  740. wc = make(chan bool, ccount)
  741. )
  742. for _, v := range list {
  743. wg.Add(1)
  744. wc <- true
  745. go func(v map[string]interface{}) {
  746. defer func() {
  747. wg.Done()
  748. <-wc
  749. }()
  750. redisKey := fmt.Sprintf("pushinfo_%s_%s", spqp.UserId, common.ObjToString(v["_id"]))
  751. title := strings.Replace(common.ObjToString(v["title"]), "\n", "", -1)
  752. var pushInsert = []interface{}{}
  753. //招投标信息表
  754. var buildingInsert = []interface{}{}
  755. infoid := ""
  756. area := ""
  757. city := ""
  758. subtype := ""
  759. toptype := ""
  760. buyerclass := ""
  761. attachment_count := ""
  762. bidamount := "0"
  763. budget := "0"
  764. subscopeClass := ""
  765. infoid = common.InterfaceToStr(v["_id"])
  766. if v["area"] != nil {
  767. area = common.InterfaceToStr(common.If(common.ObjToString(v["area"]) == "A", 0, common.If(IC.PushMapping.Area[common.ObjToString(v["area"])] > 0, IC.PushMapping.Area[common.ObjToString(v["area"])], 0)))
  768. }
  769. publishtime := ""
  770. if v["publishtime"] != nil {
  771. publishtime = time.Unix(common.Int64All(v["publishtime"]), 0).Format(date.Date_Full_Layout)
  772. }
  773. if v["city"] != nil {
  774. city = common.InterfaceToStr(common.If(IC.PushMapping.City[common.ObjToString(v["city"])] > 0, IC.PushMapping.City[common.ObjToString(v["city"])], 0))
  775. }
  776. if v["subtype"] != nil {
  777. subtype = common.InterfaceToStr(common.If(IC.PushMapping.Subtype[common.ObjToString(v["subtype"])] > 0, IC.PushMapping.Subtype[common.ObjToString(v["subtype"])], 0))
  778. }
  779. if v["toptype"] != nil {
  780. toptype = common.InterfaceToStr(common.If(IC.PushMapping.Toptype[common.ObjToString(v["toptype"])] > 0, IC.PushMapping.Toptype[common.ObjToString(v["toptype"])], 0))
  781. }
  782. if v["buyerclass"] != nil {
  783. buyerclass = common.InterfaceToStr(common.If(IC.PushMapping.Buyerclass[common.ObjToString(v["buyerclass"])] > 0, IC.PushMapping.Buyerclass[common.ObjToString(v["buyerclass"])], 0))
  784. }
  785. if v["isValidFile"] != nil {
  786. isValidFile, _ := v["isValidFile"].(bool)
  787. attachment_count = common.InterfaceToStr(common.If(isValidFile, 1, 0)) //附件 :检索库 只有附件字段,无法识别附件数量 暂定为1;为识别有附件
  788. }
  789. if v["bidamount"] != nil {
  790. bidamount = common.InterfaceToStr(v["bidamount"])
  791. }
  792. if v["budget"] != nil {
  793. budget = common.InterfaceToStr(v["budget"])
  794. }
  795. if s_subscopeclass := common.ObjToString(v["s_subscopeclass"]); s_subscopeclass != "" {
  796. subscopeclass := []string{}
  797. for _, v := range strings.Split(s_subscopeclass, ",") {
  798. if subscopeclass_mapping, ok := IC.PushMapping.Subscopeclass[v]; ok {
  799. subscopeclass = append(subscopeclass, fmt.Sprint(subscopeclass_mapping))
  800. }
  801. }
  802. if len(subscopeclass) > 0 {
  803. subscopeClass = strings.Join(subscopeclass, ",")
  804. }
  805. }
  806. buildingInsert = append(buildingInsert, infoid, area, city, buyerclass, toptype, subtype, subscopeClass, budget, bidamount, attachment_count, publishtime)
  807. spqp.BaseServiceMysql.ExecTx("推送记录保存", func(tx *sql.Tx) bool {
  808. id1, id2 := spqp.BaseServiceMysql.InsertIgnoreBatchByTx(tx, Pushbidding, buildingInsertCollKey, buildingInsert)
  809. log.Println(id1, id2)
  810. if id1 == 0 {
  811. //有历史记录,需要查询信息id
  812. data := spqp.BaseServiceMysql.FindOne(Pushbidding, map[string]interface{}{
  813. "infoid": infoid,
  814. }, "id", "")
  815. if data != nil {
  816. id2 = common.Int64All((*data)["id"])
  817. } else {
  818. return false
  819. }
  820. }
  821. //推送记录
  822. matchkeys := getKeys(title, keyword)
  823. matchkey := strings.Join(matchkeys, " ")
  824. entid := spqp.EntId
  825. entUserId := spqp.EntUserId
  826. deptid := spqp.DeptId
  827. id := int64(0)
  828. switch s.ModuleFlag {
  829. case "eType":
  830. pushInsert = append(pushInsert, entid, deptid, entUserId, common.InterfaceToStr(id2), matchkey, now)
  831. id, _ = spqp.BaseServiceMysql.InsertIgnoreBatch(aboutDbMsg[s.ModuleFlag].MysqlTable, ennicheInsertCollKey, pushInsert)
  832. case "mType":
  833. pushInsert = append(pushInsert, common.InterfaceToStr(spqp.NewUserId), common.InterfaceToStr(id2), matchkey, now)
  834. id, _ = spqp.BaseServiceMysql.InsertIgnoreBatch(aboutDbMsg[s.ModuleFlag].MysqlTable, memberInsertCollKey, pushInsert)
  835. default:
  836. pushInsert = append(pushInsert, common.InterfaceToStr(spqp.NewUserId), common.InterfaceToStr(id2), matchkey, now)
  837. id, _ = spqp.BaseServiceMysql.InsertIgnoreBatch(aboutDbMsg[s.ModuleFlag].MysqlTable, subscribeInsertCollKey, pushInsert)
  838. }
  839. if id > 0 {
  840. return true
  841. redis.Put("pushcache_2_a", redisKey, 1, 86400)
  842. resultList = append(resultList, s.InfoFormat(&PushCa{
  843. InfoId: common.ObjToString(v["_id"]),
  844. Date: time.Now().Unix(),
  845. Index: id,
  846. Keys: matchkeys,
  847. FileExists: v["filetext"] != nil,
  848. }, &v))
  849. }
  850. return false
  851. })
  852. }(v)
  853. }
  854. wg.Wait()
  855. log.Println("数据处理耗时:", time.Since(t2))
  856. return
  857. }
  858. //获取匹配得关键词
  859. func getKeys(title string, keywords []ViewKeyWord) (str []string) {
  860. if len(keywords) > 0 {
  861. L:
  862. for _, v := range keywords {
  863. for _, vk := range v.Keyword {
  864. if strings.Contains(title, vk) {
  865. str = append(str, v.Keyword...)
  866. break L
  867. }
  868. }
  869. for _, va := range v.Appended {
  870. if strings.Contains(title, va) {
  871. str = append(str, v.Appended...)
  872. break L
  873. }
  874. }
  875. }
  876. }
  877. return
  878. }
  879. //获取查询语句
  880. func (s *subscribePush) getDefaultDatasSQL(bsp *ViewCondition) (str string) {
  881. query := `{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}}`
  882. query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
  883. multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
  884. query_bool_must_and := `{"bool":{"must":[%s]%s}}`
  885. bools := []string{}
  886. musts := []string{}
  887. //发布时间最新7天
  888. musts = append(musts, fmt.Sprintf(bidTime, time.Now().AddDate(0, 0, -7).Unix()))
  889. //省份
  890. areaCity := []string{}
  891. if len(bsp.Area) > 0 {
  892. areaquery := `{"terms":{"area":[`
  893. for k, v := range bsp.Area {
  894. if k > 0 {
  895. areaquery += `,`
  896. }
  897. areaquery += `"` + v + `"`
  898. }
  899. areaquery += `]}}`
  900. areaCity = append(areaCity, areaquery)
  901. }
  902. //城市
  903. if len(bsp.City) > 0 {
  904. areaquery := `{"terms":{"city":[`
  905. for k, v := range bsp.City {
  906. if k > 0 {
  907. areaquery += `,`
  908. }
  909. areaquery += `"` + v + `"`
  910. }
  911. areaquery += `]}}`
  912. areaCity = append(areaCity, areaquery)
  913. }
  914. if len(areaCity) > 0 {
  915. musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(areaCity, ",")))
  916. }
  917. if len(bsp.Subtype) > 0 {
  918. subquery := `{"terms":{"subtype":[`
  919. for k, v := range bsp.Subtype {
  920. if k > 0 {
  921. subquery += `,`
  922. }
  923. subquery += `"` + v + `"`
  924. }
  925. subquery += `]}}`
  926. musts = append(musts, subquery)
  927. }
  928. if len(bsp.Buyerclass) > 0 {
  929. Buyerclass := `{"terms":{"buyerclass":[`
  930. for k, v := range bsp.Buyerclass {
  931. if k > 0 {
  932. Buyerclass += `,`
  933. }
  934. Buyerclass += `"` + v + `"`
  935. }
  936. Buyerclass += `]}}`
  937. musts = append(musts, Buyerclass)
  938. }
  939. boolsNum := 0 //should
  940. if len(bsp.Keyword) > 0 {
  941. boolsNum = 1
  942. if bsp.SelectType == "" || bsp.SelectType == "2" {
  943. bsp.SelectType = "detail\", \"title"
  944. } else {
  945. bsp.SelectType = "title"
  946. }
  947. multi_match = fmt.Sprintf(multi_match, "%s", "\""+bsp.SelectType+"\"")
  948. for _, v := range bsp.Keyword {
  949. shoulds := []string{}
  950. must_not := []string{}
  951. //附加词
  952. for _, vv := range v.Keyword {
  953. vv = strings.TrimSpace(vv)
  954. if vv == "" {
  955. continue
  956. }
  957. shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
  958. }
  959. for _, vv := range v.Appended {
  960. vv = strings.TrimSpace(vv)
  961. if vv == "" {
  962. continue
  963. }
  964. shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
  965. }
  966. //排除词
  967. for _, vv := range v.Exclude {
  968. vv = strings.TrimSpace(vv)
  969. if vv == "" {
  970. continue
  971. }
  972. must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
  973. }
  974. //添加
  975. if len(shoulds) > 0 {
  976. notStr := ""
  977. if len(must_not) > 0 {
  978. notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
  979. }
  980. bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
  981. }
  982. }
  983. }
  984. qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum)
  985. logx.Info("----", qstr)
  986. return qstr
  987. }
  988. /*已选条件--关键词*/
  989. type ViewKeyWord struct {
  990. Keyword []string `json:"key"` //关键词
  991. Appended []string `json:"appendkey"` //附加词
  992. Exclude []string `json:"notkey"` //排除词
  993. MatchWay int `json:"matchway"` //匹配模式
  994. }
  995. /*已选条件*/
  996. type ViewCondition struct {
  997. Area []string //地区-省份
  998. City []string //地区-城市
  999. Buyerclass []string //采购行业
  1000. Keyword []ViewKeyWord //关键词
  1001. SelectType string //筛选(正文 or 标题)
  1002. Subtype []string //信息类型
  1003. Size int //数量
  1004. }
  1005. //获取用户信息
  1006. func (s *subscribePush) getUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition) {
  1007. var isPayBool = false
  1008. var tmpInfo = struct {
  1009. Items []interface{}
  1010. BuyerClass []interface{}
  1011. SubType []interface{}
  1012. Area map[string]interface{}
  1013. SelectType string
  1014. }{}
  1015. switch s.ModuleFlag {
  1016. case "mType":
  1017. userMap, ok := IC.Mgo.FindById("user", spqp.UserId, `{"o_member_jy":1,"i_member_status":1}`)
  1018. if !ok || userMap == nil || len(*userMap) == 0 {
  1019. return &ViewCondition{}
  1020. }
  1021. //大会员
  1022. if common.IntAll((*userMap)["i_member_status"]) > 0 {
  1023. isPayBool = true
  1024. o_member_jy, _ := (*userMap)["o_member_jy"].(map[string]interface{})
  1025. tmpInfo.Items, _ = o_member_jy["a_items"].([]interface{})
  1026. tmpInfo.BuyerClass, _ = o_member_jy["a_buyerclass"].([]interface{})
  1027. tmpInfo.SubType, _ = o_member_jy["a_infotype"].([]interface{})
  1028. tmpInfo.Area, _ = o_member_jy["o_area"].(map[string]interface{})
  1029. }
  1030. case "vType":
  1031. userMap, ok := IC.Mgo.FindById("user", spqp.UserId, `{"o_vipjy":1,"i_vip_status":1}`)
  1032. if !ok || userMap == nil || len(*userMap) == 0 {
  1033. return &ViewCondition{}
  1034. }
  1035. if common.IntAll((*userMap)["i_vip_status"]) > 0 {
  1036. isPayBool = true
  1037. o_vipjy, _ := (*userMap)["o_vipjy"].(map[string]interface{})
  1038. tmpInfo.Items, _ = o_vipjy["a_items"].([]interface{})
  1039. tmpInfo.BuyerClass, _ = o_vipjy["a_buyerclass"].([]interface{})
  1040. tmpInfo.SubType, _ = o_vipjy["a_infotype"].([]interface{})
  1041. tmpInfo.Area, _ = o_vipjy["o_area"].(map[string]interface{})
  1042. }
  1043. case "eType":
  1044. //商机管理
  1045. entUserId, _ := strconv.Atoi(spqp.EntUserId)
  1046. entId, _ := strconv.Atoi(spqp.EntId)
  1047. entInfo, deptId := (&ms.MatchJob{}).Start(entId, entUserId)
  1048. if entInfo != nil && len(entInfo) > 0 {
  1049. spqp.DeptId = strconv.Itoa(deptId)
  1050. isPayBool = true
  1051. tmpInfo.Items, _ = entInfo["a_items"].([]interface{})
  1052. tmpInfo.BuyerClass, _ = entInfo["a_buyerclass"].([]interface{})
  1053. tmpInfo.SubType, _ = entInfo["a_infotype"].([]interface{})
  1054. tmpInfo.Area, _ = entInfo["o_area"].(map[string]interface{})
  1055. }
  1056. default:
  1057. userMap, ok := IC.Mgo.FindById("user", spqp.UserId, `{"o_jy":1}`)
  1058. if !ok || userMap == nil || len(*userMap) == 0 {
  1059. return &ViewCondition{}
  1060. }
  1061. o_jy, _ := (*userMap)["o_jy"].(map[string]interface{})
  1062. if o_jy["a_key"] != nil {
  1063. tmpInfo.Items, _ = o_jy["a_key"].([]interface{})
  1064. //信息类型
  1065. tmpInfo.SubType, _ = o_jy["a_infotype"].([]interface{})
  1066. //省份
  1067. tmpInfo.Area, _ = o_jy["o_area"].(map[string]interface{})
  1068. if common.IntAllDef(o_jy["i_ppstatus"], 0) == 1 && o_jy["o_area_p"] != nil {
  1069. tmpInfo.Area, _ = o_jy["o_area_p"].(map[string]interface{})
  1070. }
  1071. }
  1072. }
  1073. vc = &ViewCondition{
  1074. Buyerclass: common.ObjArrToStringArr(tmpInfo.BuyerClass),
  1075. Subtype: common.ObjArrToStringArr(tmpInfo.SubType),
  1076. Area: getStringArrFromDbResult(tmpInfo.Area, 1),
  1077. City: getStringArrFromDbResult(tmpInfo.Area, 2),
  1078. SelectType: "1",
  1079. }
  1080. //付费用户
  1081. if isPayBool {
  1082. vc.Size = IC.C.DefaulCount.Pay
  1083. vc.Keyword = getKeyWordArrFromDbResult(tmpInfo.Items, "", -1)
  1084. } else {
  1085. vc.Size = IC.C.DefaulCount.Free
  1086. vc.Keyword = getKeyWordArrFromDbResultByFree(tmpInfo.Items, "", -1)
  1087. }
  1088. vc.Size = 10
  1089. return
  1090. }
  1091. //关键词 附加词 排除词
  1092. func getKeyWordArrFromDbResult(a_items []interface{}, item string, index int) (arr []ViewKeyWord) {
  1093. if a_items == nil {
  1094. return
  1095. }
  1096. for _, v := range a_items {
  1097. vm, _ := v.(map[string]interface{})
  1098. if item != "" && index >= 0 && item != common.ObjToString(vm["s_item"]) {
  1099. continue
  1100. }
  1101. kwsArr := vm["a_key"]
  1102. for i, k := range kwsArr.([]interface{}) {
  1103. if item != "" && index >= 0 && i != index {
  1104. continue
  1105. }
  1106. kw := ViewKeyWord{}
  1107. b, e := json.Marshal(k)
  1108. if e != nil {
  1109. log.Println(e.Error())
  1110. }
  1111. json.Unmarshal(b, &kw)
  1112. if kw.MatchWay == 1 {
  1113. for _, kk := range kw.Keyword {
  1114. arr = append(arr, ViewKeyWord{
  1115. Keyword: []string{kk},
  1116. Exclude: kw.Exclude,
  1117. })
  1118. }
  1119. for _, kk := range kw.Appended {
  1120. arr = append(arr, ViewKeyWord{
  1121. Keyword: []string{kk},
  1122. Exclude: kw.Exclude,
  1123. })
  1124. }
  1125. } else {
  1126. arr = append(arr, kw)
  1127. }
  1128. }
  1129. }
  1130. return
  1131. }
  1132. // //关键词 附加词 排除词 省份订阅包 - 普通用户
  1133. func getKeyWordArrFromDbResultByFree(a_items []interface{}, item string, index int) (arr []ViewKeyWord) {
  1134. if a_items == nil {
  1135. return
  1136. }
  1137. for _, v := range a_items {
  1138. vmr, _ := v.([]interface{})
  1139. vm, _ := vmr[0].(map[string]interface{})
  1140. if item != "" && index >= 0 && item != common.ObjToString(vm["s_item"]) {
  1141. continue
  1142. }
  1143. kwsArr := vmr
  1144. for i, k := range kwsArr {
  1145. if item != "" && index >= 0 && i != index {
  1146. continue
  1147. }
  1148. kw := ViewKeyWord{}
  1149. b, e := json.Marshal(k)
  1150. if e != nil {
  1151. log.Println(e.Error())
  1152. }
  1153. json.Unmarshal(b, &kw)
  1154. if kw.MatchWay == 1 {
  1155. for _, kk := range kw.Keyword {
  1156. arr = append(arr, ViewKeyWord{
  1157. Keyword: []string{kk},
  1158. Exclude: kw.Exclude,
  1159. })
  1160. }
  1161. for _, kk := range kw.Appended {
  1162. arr = append(arr, ViewKeyWord{
  1163. Keyword: []string{kk},
  1164. Exclude: kw.Exclude,
  1165. })
  1166. }
  1167. } else {
  1168. arr = append(arr, kw)
  1169. }
  1170. }
  1171. }
  1172. return
  1173. }
  1174. //地区格式化
  1175. func getStringArrFromDbResult(area map[string]interface{}, i int) (arr []string) {
  1176. if area == nil {
  1177. return
  1178. }
  1179. var eareArr []string
  1180. var cityArr []string
  1181. for k, v := range area {
  1182. if len(v.([]interface{})) > 0 {
  1183. cityArr = append(cityArr, common.ObjArrToStringArr(v.([]interface{}))...)
  1184. } else {
  1185. eareArr = append(eareArr, k)
  1186. }
  1187. }
  1188. if i == 1 {
  1189. arr = eareArr
  1190. } else {
  1191. arr = cityArr
  1192. }
  1193. return
  1194. }