vrew.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. package util
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. qutil "qfw/util"
  7. "qfw/util/elastic"
  8. "strconv"
  9. "strings"
  10. "time"
  11. "go.mongodb.org/mongo-driver/bson"
  12. )
  13. /*已选条件--关键词*/
  14. type ViewKeyWord struct {
  15. Keyword []string `json:"key"` //关键词
  16. Appended []string `json:"appendkey"` //附加词
  17. Exclude []string `json:"notkey"` //排除词
  18. }
  19. /*已选条件*/
  20. type ViewCondition struct {
  21. Area []string //地区-省份
  22. City []string //地区-城市
  23. Buyerclass []string //采购行业
  24. Keyword []ViewKeyWord //关键词
  25. SelectType string //筛选(正文 or 标题)
  26. Subtype []string //信息类型
  27. }
  28. const (
  29. INDEX = "bidding"
  30. TYPE = "bidding"
  31. bidSearch_sort = `{"publishtime":-1}`
  32. findfields = `"title"`
  33. view_maxPageNum = 20
  34. view_pageSize = 50
  35. bidSearch_field = `"_id","title","publishtime","toptype","subtype","type","area","buyerclass","budget","bidamount"`
  36. )
  37. func SubViewDatas(userId, allquery string, pageNum int) (keys []interface{}, list *[]map[string]interface{}, hasNextPage bool) {
  38. if userId == "" {
  39. return
  40. }
  41. sql := GetSqlObjFromId(userId)
  42. for _, v := range sql.Keyword {
  43. var keys_one []string
  44. for _, k := range v.Keyword {
  45. keys_one = append(keys_one, k)
  46. }
  47. //dev3.5 附加词也要高亮
  48. for _, k := range v.Appended {
  49. keys_one = append(keys_one, k)
  50. }
  51. keys = append(keys, strings.Join(keys_one, "++"))
  52. }
  53. qstr := GetVIPViewSql(sql)
  54. list = elastic.GetAllByNgram(INDEX, TYPE, qstr, findfields, bidSearch_sort, bidSearch_field, (pageNum-1)*view_pageSize, view_pageSize, 0, false)
  55. if list != nil {
  56. for _, v := range *list {
  57. v["_id"] = qutil.EncodeArticleId2ByCheck(qutil.ObjToString(v["_id"]))
  58. }
  59. }
  60. hasNextPage = list != nil && len(*list) == view_pageSize && pageNum < view_maxPageNum
  61. return
  62. }
  63. //获取vip订阅预览的查询语句
  64. func GetVIPViewSql(scd *ViewCondition) string {
  65. query := `{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}}`
  66. query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
  67. multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
  68. query_bool_must_and := `{"bool":{"must":[%s]%s}}`
  69. bools := []string{}
  70. musts := []string{}
  71. //省份
  72. areaCity := []string{}
  73. if len(scd.Area) > 0 {
  74. areaquery := `{"terms":{"area":[`
  75. for k, v := range scd.Area {
  76. if k > 0 {
  77. areaquery += `,`
  78. }
  79. areaquery += `"` + v + `"`
  80. }
  81. areaquery += `]}}`
  82. areaCity = append(areaCity, areaquery)
  83. }
  84. //城市
  85. if len(scd.City) > 0 {
  86. areaquery := `{"terms":{"city":[`
  87. for k, v := range scd.City {
  88. if k > 0 {
  89. areaquery += `,`
  90. }
  91. areaquery += `"` + v + `"`
  92. }
  93. areaquery += `]}}`
  94. areaCity = append(areaCity, areaquery)
  95. }
  96. if len(areaCity) > 0 {
  97. musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(areaCity, ",")))
  98. }
  99. if len(scd.Subtype) > 0 {
  100. subquery := `{"terms":{"subtype":[`
  101. for k, v := range scd.Subtype {
  102. if k > 0 {
  103. subquery += `,`
  104. }
  105. subquery += `"` + v + `"`
  106. }
  107. subquery += `]}}`
  108. musts = append(musts, subquery)
  109. }
  110. if len(scd.Buyerclass) > 0 {
  111. Buyerclass := `{"terms":{"buyerclass":[`
  112. for k, v := range scd.Buyerclass {
  113. if k > 0 {
  114. Buyerclass += `,`
  115. }
  116. Buyerclass += `"` + v + `"`
  117. }
  118. Buyerclass += `]}}`
  119. musts = append(musts, Buyerclass)
  120. }
  121. boolsNum := 0 //should
  122. if len(scd.Keyword) > 0 {
  123. boolsNum = 1
  124. if scd.SelectType == "" || scd.SelectType == "2" {
  125. scd.SelectType = "detail\", \"title"
  126. } else {
  127. scd.SelectType = "title"
  128. }
  129. multi_match = fmt.Sprintf(multi_match, "%s", "\""+scd.SelectType+"\"")
  130. for _, v := range scd.Keyword {
  131. shoulds := []string{}
  132. must_not := []string{}
  133. //附加词
  134. for _, vv := range v.Keyword {
  135. shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
  136. }
  137. for _, vv := range v.Appended {
  138. shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
  139. }
  140. //排除词
  141. for _, vv := range v.Exclude {
  142. must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
  143. }
  144. //添加
  145. if len(shoulds) > 0 {
  146. notStr := ""
  147. if len(must_not) > 0 {
  148. notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
  149. }
  150. bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
  151. }
  152. }
  153. }
  154. qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum)
  155. // log.Println("------qstr", qstr)
  156. return qstr
  157. }
  158. //
  159. func GetSqlObjFromId(_id string) *ViewCondition {
  160. var (
  161. query *map[string]interface{}
  162. ok bool
  163. )
  164. if query, ok = MQFW.FindById("user", _id, `{"o_vipjy":1}`); !ok {
  165. return nil
  166. }
  167. o_vipjy, _ := (*query)["o_vipjy"].(map[string]interface{})
  168. a_items := o_vipjy["a_items"].([]interface{})
  169. a_buyerclass := o_vipjy["a_buyerclass"].([]interface{})
  170. if len(a_buyerclass) > 0 && qutil.IntAllDef(o_vipjy["i_matchbuyerclass_other"], 1) == 1 && len(a_items) > 0 {
  171. a_buyerclass = append(a_buyerclass, "其它")
  172. }
  173. a_infotype := o_vipjy["a_infotype"].([]interface{})
  174. o_area := o_vipjy["o_area"].(map[string]interface{})
  175. return &ViewCondition{
  176. Keyword: getKeyWordArrFromDbResult(a_items),
  177. Buyerclass: qutil.ObjArrToStringArr(a_buyerclass),
  178. Subtype: qutil.ObjArrToStringArr(a_infotype),
  179. Area: getStringArrFromDbResult(o_area, 1),
  180. City: getStringArrFromDbResult(o_area, 2),
  181. SelectType: strconv.Itoa(qutil.IntAll(o_vipjy["i_matchway"])),
  182. }
  183. }
  184. //
  185. func getStringArrFromDbResult(area map[string]interface{}, i int) (arr []string) {
  186. if area == nil {
  187. return
  188. }
  189. var eareArr []string
  190. var cityArr []string
  191. for k, v := range area {
  192. if len(v.([]interface{})) > 0 {
  193. cityArr = append(cityArr, qutil.ObjArrToStringArr(v.([]interface{}))...)
  194. } else {
  195. eareArr = append(eareArr, k)
  196. }
  197. }
  198. if i == 1 {
  199. arr = eareArr
  200. } else {
  201. arr = cityArr
  202. }
  203. return
  204. }
  205. //关键词 附加词 排除词
  206. func getKeyWordArrFromDbResult(a_items []interface{}) (arr []ViewKeyWord) {
  207. if a_items == nil {
  208. return
  209. }
  210. for _, v := range a_items {
  211. kwsArr := v.(map[string]interface{})["a_key"]
  212. for _, k := range kwsArr.([]interface{}) {
  213. kw := ViewKeyWord{}
  214. b, e := json.Marshal(k)
  215. if e != nil {
  216. log.Println(e.Error())
  217. }
  218. json.Unmarshal(b, &kw)
  219. arr = append(arr, kw)
  220. }
  221. }
  222. return
  223. }
  224. //初始化vip订阅关键词
  225. func MergeKws(userId string) {
  226. defer qutil.Catch()
  227. if userId == "" { //11-11 取消此操作
  228. return
  229. }
  230. data, ok := MQFW.FindById("user", userId, `{"o_jy":1,"o_vipjy":1}`)
  231. var o_vipjy map[string]interface{}
  232. if ok && data != nil && len(*data) > 0 {
  233. o_vipjy, _ = (*data)["o_vipjy"].(map[string]interface{})
  234. a_items, _ := o_vipjy["a_items"].([]interface{})
  235. if a_items == nil { //首次
  236. a := MQFW.UpdateById("user", userId, bson.M{
  237. "$set": bson.M{"o_vipjy.i_matchway": 1, "o_vipjy.i_ratemode": 1, "o_vipjy.i_wxpush": 1, "o_vipjy.i_apppush": 1, "o_vipjy.i_projectmatch": 0, "o_vipjy.a_infotype": []string{}, "o_vipjy.a_items": []string{}, "o_vipjy.l_modifydate": time.Now().Unix()},
  238. })
  239. log.Println(a)
  240. }
  241. }
  242. }
  243. //m 月 超过一年传12+n月 如14; endtime 当前周期结束时间戳 int64 ;val - 1:年 2:月
  244. func GetDATE(val int, m int, endtime int64) (_endtime time.Time) {
  245. if val == 1 {
  246. m = m * 12
  247. }
  248. endFormat := qutil.FormatDateByInt64(&endtime, qutil.Date_Short_Layout)
  249. date_y, _ := strconv.Atoi(strings.Split(endFormat, "-")[0])
  250. date_m, _ := strconv.Atoi(strings.Split(endFormat, "-")[1])
  251. date_d, _ := strconv.Atoi(strings.Split(endFormat, "-")[2])
  252. if date_m+m > 12 {
  253. date_y = date_y + (date_m+m-1)/12
  254. date_m = date_m + m - 12*((date_m+m-1)/12)
  255. } else {
  256. date_m = date_m + m
  257. }
  258. mstr := strconv.Itoa(date_m)
  259. if date_m < 10 {
  260. mstr = "0" + mstr
  261. }
  262. _date := strconv.Itoa(date_y) + "-" + mstr + "-01"
  263. p, _ := time.ParseInLocation(qutil.Date_Short_Layout, _date, time.Local)
  264. date := time.Unix(p.Unix(), 0).AddDate(0, 1, -1)
  265. thisD, _ := strconv.Atoi(strings.Split(qutil.FormatDate(&date, qutil.Date_Short_Layout), "-")[2])
  266. dstr := "01"
  267. if thisD < date_d {
  268. dstr = strconv.Itoa(thisD)
  269. if thisD < 10 {
  270. dstr = "0" + strconv.Itoa(thisD)
  271. }
  272. } else {
  273. dstr = strconv.Itoa(date_d)
  274. if date_d < 10 {
  275. dstr = "0" + strconv.Itoa(date_d)
  276. }
  277. }
  278. _date = strconv.Itoa(date_y) + "-" + mstr + "-" + dstr + " 23:59:59"
  279. lastDate, _ := time.ParseInLocation(qutil.Date_Full_Layout, _date, time.Local)
  280. return lastDate
  281. }