classificationTag.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. package front
  2. import (
  3. qu "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/encrypt"
  5. elastic "app.yhyue.com/moapp/jybase/es"
  6. "app.yhyue.com/moapp/jybase/redis"
  7. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/bidsearch"
  8. "app.yhyue.com/moapp/jypkg/public"
  9. "encoding/json"
  10. "fmt"
  11. "jy/src/jfw/config"
  12. "jy/src/jfw/jyutil"
  13. "jy/src/jfw/paging"
  14. "log"
  15. "math"
  16. "math/rand"
  17. "strconv"
  18. "sync"
  19. "time"
  20. "net/http"
  21. "app.yhyue.com/moapp/jybase/date"
  22. "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
  23. )
  24. type KeyType struct {
  25. Name string `json:"name"`
  26. Url string `json:"url"`
  27. SeedData []KeyType `json:"seedData"`
  28. }
  29. // RegionAndInformationAndTender 1地域 2信息类型 3热门招标
  30. func RegionAndInformationAndTender() map[string]interface{} {
  31. if bytes, err := redis.GetBytes(RedisNameNew, "regionAndInformationAndTender"); err == nil && bytes != nil {
  32. rData := map[string]interface{}{}
  33. if err := json.Unmarshal(*bytes, &rData); err != nil {
  34. log.Printf("[MANAGER-ERR]RegionAndInformationAndTender GetData Error %v \n", err)
  35. return nil
  36. }
  37. return rData
  38. }
  39. data := make(map[string]interface{})
  40. for _, v := range []int{1, 2, 3} {
  41. data[fmt.Sprintf("labUrl_%d", v)] = GetLabUrl(v) //1地域 2信息类型 3热门招标
  42. }
  43. if bytes, err := json.Marshal(data); err == nil && bytes != nil {
  44. _ = redis.PutBytes(RedisNameNew, "regionAndInformationAndTender", &bytes, 2*60*60)
  45. }
  46. return data
  47. }
  48. // HotSubjectMatter 热门标的物
  49. func HotSubjectMatter() []map[string]interface{} {
  50. checkedLetter := LetterArr[getRandomWithAll(0, len(LetterArr))]
  51. industryHref := fmt.Sprintf("/tags/industry/%s_%s_all_%s.html", "%v", "all", "%v")
  52. letterLabel, _, _ := GetLetterPaging(1, checkedLetter) //热门标的物 随机字母标签
  53. tradeLabel := GetIndustry(industryHref) //热门标的物 行业分类标签
  54. letterLabel = append(letterLabel, tradeLabel...)
  55. var subjectMatter []map[string]interface{}
  56. if len(letterLabel) > 0 {
  57. for _, v := range jyutil.GenerateRandomNumber(0, len(letterLabel)-1, 200) {
  58. subjectMatter = append(subjectMatter, letterLabel[v])
  59. }
  60. }
  61. return subjectMatter
  62. }
  63. // 随机展示200中标企业
  64. func GetWinnerInfo() (data []BuyerList) {
  65. randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
  66. from := randGen.Intn(100)
  67. //关联中标企业
  68. r := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"bool": {"must": []}},"_source": ["_id","company_name"],"from": %d,"size": 200}`, from))
  69. if r != nil {
  70. for _, v := range *r {
  71. var vs BuyerList
  72. id := encrypt.EncodeArticleId2ByCheck(qu.InterfaceToStr(v["_id"]))
  73. vs.Name = qu.InterfaceToStr(v["company_name"])
  74. vs.Url = fmt.Sprintf("/swordfish/page_big_pc/ent_portrait/%s", id)
  75. data = append(data, vs)
  76. }
  77. }
  78. return
  79. }
  80. // ContentRecommendation 实用内容推荐
  81. func ContentRecommendation() []KeyType {
  82. if bytes, err := redis.GetBytes(RedisNameNew, "contentRecommendation"); err == nil && bytes != nil {
  83. var rData []KeyType
  84. log.Println()
  85. if err := json.Unmarshal(*bytes, &rData); err != nil {
  86. log.Printf("[MANAGER-ERR]contentRecommendation GetData Error %v \n", err)
  87. return nil
  88. }
  89. return rData
  90. }
  91. columnCode, _ := config.Sysconfig["columnCode"].(map[string]interface{})
  92. jySchoolCode := qu.InterfaceToStr(columnCode["招投标攻略"])
  93. industryInfoCode := qu.InterfaceToStr(columnCode["行业资讯"])
  94. industryInfoUrl, _ := config.Sysconfig["industryInfoUrl"].(map[string]interface{})
  95. jySchoolUrl, _ := config.Sysconfig["jySchoolUrl"].(map[string]interface{})
  96. column, ok := mongodb.Find("column", map[string]interface{}{"$or": []map[string]interface{}{
  97. {"pid": "ztbgl"}, {"pid": "hyzx"}, {"pid": "bzzx"},
  98. }}, `{"i_order":1}`, "", false, -1, -1)
  99. dataMap := make(map[string][]KeyType)
  100. if ok && column != nil && len(*column) > 0 {
  101. for _, v := range *column {
  102. pid := qu.InterfaceToStr(v["pid"])
  103. code := qu.InterfaceToStr(v["s_columncode"])
  104. var v1 KeyType
  105. v1.Name = qu.InterfaceToStr(v["s_columnname"])
  106. if pid == jySchoolCode {
  107. v1.Url = fmt.Sprintf(qu.InterfaceToStr(jySchoolUrl["towUrl"]), code)
  108. } else if pid == industryInfoCode {
  109. v1.Url = fmt.Sprintf(qu.InterfaceToStr(industryInfoUrl["towUrl"]), code)
  110. } else if pid == "bzzx" {
  111. v1.Url = fmt.Sprintf("/helpCenter/catalog/%s", code)
  112. }
  113. dataMap[pid] = append(dataMap[pid], v1)
  114. }
  115. }
  116. var data []KeyType
  117. for _, v := range []string{jySchoolCode, industryInfoCode, "bzzx"} {
  118. if v1, ok1 := dataMap[v]; ok1 && v1 != nil {
  119. var d KeyType
  120. switch v {
  121. case jySchoolCode:
  122. d.Name = "招投标攻略"
  123. d.Url = qu.InterfaceToStr(jySchoolUrl["homeUrl"])
  124. d.SeedData = v1
  125. case industryInfoCode:
  126. d.Name = "行业资讯"
  127. d.Url = qu.InterfaceToStr(industryInfoUrl["homeUrl"])
  128. d.SeedData = v1
  129. case "bzzx":
  130. d.Name = "帮助中心"
  131. d.Url = "/helpCenter/index"
  132. d.SeedData = v1
  133. }
  134. data = append(data, d)
  135. }
  136. }
  137. if bytes, err := json.Marshal(data); err == nil && bytes != nil {
  138. _ = redis.PutBytes(RedisNameNew, "contentRecommendation", &bytes, 12*60*60)
  139. }
  140. return data
  141. }
  142. type Signal struct {
  143. Name string `json:"name"`
  144. Url string `json:"url"`
  145. Data []map[string]interface{} `json:"data"`
  146. }
  147. // 推荐标讯
  148. func RecommendationBeacon() []Signal {
  149. if bytes, err := redis.GetBytes(RedisNameNew, "recommendationBeacon"); err == nil && bytes != nil {
  150. var rData []Signal
  151. if err := json.Unmarshal(*bytes, &rData); err != nil {
  152. log.Printf("[MANAGER-ERR]recommendationBeacon GetData Error %v \n", err)
  153. return nil
  154. }
  155. return rData
  156. }
  157. sy := sync.RWMutex{}
  158. wg := sync.WaitGroup{}
  159. var data, dataArr []Signal
  160. for _, v := range []string{"招标预告", "招标公告", "招标结果", "招标信用信息"} {
  161. wg.Add(1)
  162. go func(vst string) {
  163. defer wg.Done()
  164. var list []map[string]interface{}
  165. _, _, lists := bidsearch.GetPcBidSearchData("", "", "", "", vst, "", "", "", "", "", "", "", "", 1, false, nil, bidSearch_field_1, "", false, false, "", 8, "")
  166. if lists != nil {
  167. for _, v1 := range *lists {
  168. v1["_id"] = encrypt.CommonEncodeArticle("content", v1["_id"].(string))
  169. delete(v1, "toptype")
  170. delete(v1, "s_subscopeclass")
  171. tmpdate := v1["publishtime"]
  172. v1["publishtime"] = qu.Int64All(tmpdate.(float64))
  173. if v1["budget"] != nil {
  174. v1["budget"] = ConversionMoeny(v1["budget"])
  175. } else if v1["bidamount"] != nil {
  176. v1["budget"] = ConversionMoeny(v1["bidamount"])
  177. }
  178. }
  179. list = *lists
  180. }
  181. var d Signal
  182. d.Name = vst
  183. d.Url = fmt.Sprintf("/jylab/supsearch/index.html?subtype=%s", vst)
  184. d.Data = list
  185. sy.Lock()
  186. dataArr = append(dataArr, d)
  187. sy.Unlock()
  188. }(v)
  189. }
  190. wg.Wait()
  191. for _, v := range []string{"招标预告", "招标公告", "招标结果", "招标信用信息"} {
  192. for _, v1 := range dataArr {
  193. if v == v1.Name {
  194. data = append(data, v1)
  195. }
  196. }
  197. }
  198. if bytes, err := json.Marshal(data); err == nil && bytes != nil {
  199. _ = redis.PutBytes(RedisNameNew, "recommendationBeacon", &bytes, 5*60)
  200. }
  201. return data
  202. }
  203. // 不包含上限 [min, max)
  204. func getRandomWithAll(min, max int) int {
  205. rand.Seed(time.Now().UnixNano())
  206. return rand.Intn(max-min) + min
  207. }
  208. // this.T["letterList"],this.T["letterListCount"],this.T["pagingMap"]=this.GetLetterPaging(pageNum,checkedLetter)
  209. func GetLetterPaging(pageNum int, checkedLetter string) (letterList []map[string]interface{}, letterListCount int64, pagingMap map[string]interface{}) {
  210. seoLetterPageSize := qu.Int64All(config.Seoconfig["seoLetterPageSize"])
  211. if pageNum == 0 {
  212. pageNum = 1
  213. }
  214. letterList, letterListCount = GetLetterMap(seoLetterPageSize, int64(pageNum), checkedLetter)
  215. pagecount := int(math.Ceil(qu.Float64All(letterListCount) / float64(seoLetterPageSize)))
  216. paging := paging.PaggingHtml(pageNum, pagecount, fmt.Sprintf("/tags/letter/%s", checkedLetter)+"_%v.html")
  217. pagingMap = map[string]interface{}{
  218. "paging": paging,
  219. "pageNum": pageNum,
  220. "pageCount": pagecount,
  221. "pageSize": seoLetterPageSize,
  222. }
  223. return
  224. }
  225. func GetLetterMap(pageSize, pageNum int64, letter string) ([]map[string]interface{}, int64) {
  226. m := []map[string]interface{}{}
  227. sql := `select id,name,letter from seo_words.seo_resource where letter = ? order by id desc`
  228. cql := `select count(1) from seo_words.seo_resource where letter = ?`
  229. offset := (pageNum - 1) * pageSize
  230. sql += fmt.Sprintf(" limit %v,%v", offset, pageSize)
  231. data := public.BaseMysql.SelectBySql(sql, letter)
  232. count := public.BaseMysql.CountBySql(cql, letter)
  233. if data != nil {
  234. for _, v := range *data {
  235. letter := qu.ObjToString(v["letter"])
  236. id := qu.Int64All(v["id"])
  237. name := qu.ObjToString(v["name"])
  238. name += qu.ObjToString(config.Seoconfig["seoKeywordSuffix"])
  239. m = append(m, map[string]interface{}{
  240. "name": name,
  241. "url": fmt.Sprintf("/tags/letter/all_all_all_%v_%v.html", letter, id),
  242. })
  243. }
  244. }
  245. return m, count
  246. }
  247. func GetIndustry(industryHref string) []map[string]interface{} {
  248. data := public.BaseMysql.SelectBySql(`select a.id,a.name,b.id class_id,b.name class_1 from seo_words.seo_industry a left join seo_words.seo_industry_class b on a.class_1=b.name order by a.class_1`)
  249. industryArr := []string{}
  250. industryMap := map[string][]map[string]interface{}{}
  251. if len(*data) > 0 && data != nil {
  252. for _, v := range *data {
  253. class := qu.ObjToString(v["class_1"])
  254. name := qu.ObjToString(v["name"])
  255. id := qu.Int64All(v["id"])
  256. industryId := qu.Int64All(v["class_id"])
  257. if !IsInArr(industryArr, class) {
  258. industryArr = append(industryArr, class)
  259. }
  260. industryMap[class] = append(industryMap[class], map[string]interface{}{
  261. "name": name + qu.ObjToString(config.Seoconfig["seoKeywordSuffix"]),
  262. // "url": fmt.Sprintf("/tags/industry/%v_all_all_%v.html", industryId, id),
  263. "url": fmt.Sprintf(industryHref, industryId, id),
  264. })
  265. }
  266. }
  267. m := []map[string]interface{}{}
  268. //
  269. for _, v := range industryArr {
  270. m = append(m, industryMap[v]...)
  271. }
  272. return m
  273. }
  274. type BuyerList struct {
  275. Name string `json:"name"`
  276. Url string `json:"url"`
  277. }
  278. // 热门采购单位
  279. func HotBuyerList(entIsNew bool) []*BuyerList {
  280. // 使用当前时间作为随机数生成器的种子
  281. randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
  282. // 获取一个范围在 [0, 100) 的随机整数
  283. start := randGen.Intn(100)
  284. buyerQuery := fmt.Sprintf(`{"query": {"bool": {"must": [{"exists": {"field": "name"}}]}},"from": %d,"size": %d}`, start, 200)
  285. log.Println("buyerQuery:", buyerQuery)
  286. data := elastic.Get("buyer", "buyer", buyerQuery)
  287. if data != nil && len(*data) > 0 {
  288. var buyerList []*BuyerList
  289. for _, b := range *data {
  290. name := qu.ObjToString(b["name"])
  291. buyerId := qu.ObjToString(b["id"])
  292. if name != "" && buyerId != "" {
  293. idEncode := encrypt.EncodeArticleId2ByCheck(buyerId)
  294. buyerList = append(buyerList, &BuyerList{
  295. Name: name,
  296. Url: qu.If(entIsNew, fmt.Sprintf("/entpc/unit_portrayal_id/%s", idEncode), fmt.Sprintf("/swordfish/page_big_pc/unit_portrayal_id/%s", idEncode)).(string),
  297. })
  298. }
  299. }
  300. return buyerList
  301. }
  302. return nil
  303. }
  304. func GetIncludedInfo() map[string]interface{} {
  305. if bytes, err := redis.GetBytes(RedisNameNew, "jyIncludedInfo"); err == nil && bytes != nil {
  306. rData := map[string]interface{}{}
  307. if err := json.Unmarshal(*bytes, &rData); err != nil {
  308. log.Printf("[MANAGER-ERR]jyIncludedInfo GetData Error %v \n", err)
  309. return nil
  310. }
  311. return rData
  312. }
  313. data := public.BaseMysql.SelectBySql(`select bid,project,ent,buyer,bid_day_update,bid_field,field_accuracy,create_time from included_info order by create_time desc limit 1`)
  314. if data == nil || len(*data) <= 0 {
  315. return nil
  316. }
  317. info := (*data)[0]
  318. //招标信息的数值
  319. bid := qu.Int64All(info["bid"])
  320. Bid, BidUnit := formdataNum(bid)
  321. //招标采购项目的数值
  322. project := qu.Int64All(info["project"])
  323. Project, ProjectUnit := formdataNum(project)
  324. //企业数据库的数值
  325. ent := qu.Int64All(info["ent"])
  326. Ent, EntUnit := formdataNum(ent)
  327. //采购单位库的数值
  328. buyer := qu.Int64All(info["buyer"])
  329. Buyer, BuyerUnit := formdataNum(buyer)
  330. //每日更新招标信息的数值
  331. bid_day_update := qu.Int64All(info["bid_day_update"])
  332. BidDayUpdate, BidDayUpdateUnit := formdataNum(bid_day_update)
  333. mdata, ok := public.MQFW.Find("swordfish_index", map[string]interface{}{
  334. "i_push": map[string]interface{}{
  335. "$exists": true,
  336. },
  337. }, `{"_id":-1}`, `{"i_push":1}`, false, 0, 1)
  338. i_push := 0
  339. if mdata != nil && ok && len(*mdata) > 0 {
  340. swordData := (*mdata)[0]
  341. i_push = qu.IntAll(swordData["i_push"])
  342. }
  343. Push, PushUnit := formdataNum(int64(i_push))
  344. m := map[string]interface{}{
  345. "bid": Bid,
  346. "bidUnit": BidUnit,
  347. "project": Project,
  348. "projectUnit": ProjectUnit,
  349. "ent": Ent,
  350. "entUnit": EntUnit,
  351. "buyer": Buyer,
  352. "buyerUnit": BuyerUnit,
  353. "bidDayUpdate": BidDayUpdate,
  354. "bidDayUpdateUnit": BidDayUpdateUnit,
  355. "push": Push,
  356. "pushUnit": PushUnit,
  357. }
  358. if bytes, err := json.Marshal(m); err == nil && bytes != nil {
  359. _ = redis.PutBytes(RedisNameNew, "jyIncludedInfo", &bytes, 2*60*60)
  360. }
  361. return m
  362. }
  363. func HotKey() []string {
  364. if bytes, err := redis.GetBytes(RedisNameNew, "jyhotkey_7"); err == nil && bytes != nil {
  365. rData := []string{}
  366. if err := json.Unmarshal(*bytes, &rData); err != nil {
  367. log.Printf("[MANAGER-ERR]jyhotkey_7 GetData Error %v \n", err)
  368. return nil
  369. }
  370. return rData
  371. }
  372. num := 7
  373. count := public.BaseMysql.CountBySql(`select count(1) from seo_words.seo_resource;`)
  374. rand.Seed(time.Now().UnixNano())
  375. randNum := rand.Intn(int(count) - num)
  376. data := public.BaseMysql.SelectBySql(`select name from seo_words.seo_resource limit ?,?`, randNum, num)
  377. arr := []string{}
  378. for _, v := range *data {
  379. arr = append(arr, qu.ObjToString(v["name"]))
  380. }
  381. if bytes, err := json.Marshal(arr); err == nil && bytes != nil {
  382. _ = redis.PutBytes(RedisNameNew, "jyhotkey_7", &bytes, 10*60)
  383. }
  384. return arr
  385. }
  386. func NewIndexbids(session *httpsession.Session, r *http.Request) []map[string]interface{} {
  387. if bytes, err := redis.GetBytes(RedisNameNew, "jyNewIndexbids"); err == nil && bytes != nil {
  388. rData := []map[string]interface{}{}
  389. if err := json.Unmarshal(*bytes, &rData); err != nil {
  390. log.Printf("[MANAGER-ERR]jyNewIndexbids GetData Error %v \n", err)
  391. return rData
  392. }
  393. return rData
  394. }
  395. /*
  396. userInfo := jy.GetVipState(session, *config.Middleground, "")
  397. so := NewSearchOptimize("", "", "", "", "招标预告,招标公告,招标结果,招标信用信息", "", "", "title", "", "", "", "", "", "", "", "", "", "PC", "", 0, 50, 0, 0, 0, *userInfo, true, r)
  398. so.DefaultSearchParamsAuto()
  399. //缓存数据
  400. _, total, _ := so.GetBidSearchList(true)
  401. data.Count = total
  402. */
  403. _, _, lists := bidsearch.GetPcBidSearchData("", "", "", "", "", "", "", "", "", "", "", "", "", 1, false, nil, bidSearch_field_1, "", false, false, "", 10, "")
  404. if lists != nil {
  405. for _, v1 := range *lists {
  406. v1["_id"] = encrypt.CommonEncodeArticle("content", v1["_id"].(string))
  407. delete(v1, "toptype")
  408. delete(v1, "s_subscopeclass")
  409. tmpdate := v1["publishtime"]
  410. v1["publishtime"] = time.Unix(qu.Int64All(tmpdate.(float64)), 0).Format(date.Date_Short_Layout)
  411. if v1["budget"] != nil {
  412. v1["budget"] = ConversionMoeny(v1["budget"])
  413. } else if v1["bidamount"] != nil {
  414. v1["budget"] = ConversionMoeny(v1["bidamount"])
  415. }
  416. }
  417. }
  418. if bytes, err := json.Marshal(*lists); err == nil && bytes != nil {
  419. _ = redis.PutBytes(RedisNameNew, "jyNewIndexbids", &bytes, 5*60)
  420. }
  421. return *lists
  422. }
  423. // 格式输出数据
  424. // 亿亿、万亿、亿、万 只有一位的时候保留1位小数点 两位及以上不保留 1.1亿 11亿
  425. func formdataNum(num int64) (floatNum float64, unit string) {
  426. s_num := strconv.Itoa(int(num))
  427. len_m := len(s_num)
  428. m := ""
  429. indexArr := []int{17, 13, 9, 5}
  430. unitArr := []string{"亿亿", "万亿", "亿", "万"}
  431. for k, v := range indexArr {
  432. if len_m > v {
  433. if qu.IntAll(s_num[len_m-(v-1):len_m-(v-2)]) >= 5 {
  434. if qu.IntAll(s_num[0:len_m-(v-1)])+1 == 10 {
  435. //满10 进 1
  436. m1, _ := strconv.Atoi(s_num[0 : len_m-(v-1)])
  437. m = strconv.Itoa(m1 + 1)
  438. } else {
  439. //满 万 进1 单位
  440. if qu.IntAll(s_num[0:len_m-(v-1)])+1 == 10000 {
  441. m = "1"
  442. unit = unitArr[k-1]
  443. } else {
  444. m = strconv.Itoa(qu.IntAll(s_num[0:len_m-(v-1)]) + 1)
  445. }
  446. }
  447. // log.Println("m1:", m)
  448. } else {
  449. m = s_num[0 : len_m-(v-1)]
  450. // log.Println("m2:", m)
  451. }
  452. } else if len_m == v { //
  453. if qu.IntAll(s_num[len_m-(v-2):len_m-(v-3)]) >= 5 {
  454. m = s_num[0 : len_m-(v-1)]
  455. //满10 进 1
  456. if qu.IntAll(s_num[len_m-(v-1):len_m-(v-2)])+1 == 10 {
  457. m1, _ := strconv.Atoi(s_num[0 : len_m-(v-1)])
  458. m = strconv.Itoa(m1 + 1)
  459. } else {
  460. m += "." + strconv.Itoa(qu.IntAll(s_num[len_m-(v-1):len_m-(v-2)])+1)
  461. }
  462. // log.Println("m3:", m)
  463. } else {
  464. m = s_num[0 : len_m-(v-1)]
  465. m += "." + s_num[len_m-(v-1):len_m-(v-2)]
  466. // log.Println("m4:", m)
  467. }
  468. }
  469. if m != "" {
  470. if unit == "" {
  471. unit = unitArr[k]
  472. }
  473. break
  474. }
  475. }
  476. if m == "" {
  477. m = s_num
  478. }
  479. //string 转float
  480. floatNum, _ = strconv.ParseFloat(m, 64)
  481. return floatNum, unit
  482. }