public.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package public
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "regexp"
  7. "strings"
  8. "time"
  9. util "app.yhyue.com/moapp/jybase/common"
  10. . "app.yhyue.com/moapp/jybase/encrypt"
  11. elastic "app.yhyue.com/moapp/jybase/esv1"
  12. . "app.yhyue.com/moapp/jybase/mongodb"
  13. "app.yhyue.com/moapp/jybase/redis"
  14. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
  15. )
  16. var ClearHtml = regexp.MustCompile("<[^>]*>")
  17. var ClearOther = regexp.MustCompile("[\n\r\\s\u3000\u2003\u00a0]")
  18. var filterReg_3 = regexp.MustCompile("(项目|公告|公示)$")
  19. var filterReg_2 = regexp.MustCompile("^[)\\)>》】\\]}}〕,,;;::'\"“”。.\\??、/+=\\_—*&……\\^%$¥@!!`~·(\\(<《【\\[{{〔]+$")
  20. var filterReg_1 = regexp.MustCompile("^([0-9]{1,3}|[零一二三四五六七八九十]{1,2}|联系人?|电话|地址|编号|采购|政府采购|成交|更正|招标|中标|变更|结果)$")
  21. var filterReg = regexp.MustCompile("^[的人号时元万公告项目地址电话邮编日期联系招标中结果成交项目项目采购采购项目政府采购公告更正公告]+$")
  22. var MgoBiddingFields = `{"_id":1,"projectname":1,"projectcode":1,"title":1,"s_winner":1,"buyertel":1,"bidstatus":1,"site":1,"bidamount":1,"toptype":1,"winneraddr":1,"winner":1,"agency":1,"buyer":1,"detail":1,"city":1,"subtype":1,"buyerclass":1,"href":1,"comeintime":1,"winnertel":1,"area":1,"publishtime":1,"buyeraddr":1,"agencytel":1,"budget":1,"entidlist":1,"buyerperson":1,"winnerperson":1,"agencyaddr":1,"recommended_service":1,"competehref":1,"owner":1,"total_investment":1,"projectaddr":1,"projectperiod":1,"approvedept":1,"approvecontent":1,"approvecode":1,"approvenumber":1,"approvetime":1,"approvestatus":1,"project_scale":1}`
  23. const (
  24. INDEX = "bidding"
  25. TYPE = "bidding"
  26. )
  27. func FilteKey(k string) string {
  28. k = strings.TrimSpace(k)
  29. k = filterReg_3.ReplaceAllString(k, "")
  30. k = filterReg_2.ReplaceAllString(k, "")
  31. k = filterReg_1.ReplaceAllString(k, "")
  32. k = filterReg.ReplaceAllString(k, "")
  33. return k
  34. }
  35. /*
  36. * 结果列表转换,目前只换行行业字段
  37. * 所有的招标搜索都要调用此方法,列表中有展示行业的也可以用
  38. * industry 搜索条件中的行业,默认为空
  39. */
  40. func BidListConvert(industry string, list *[]map[string]interface{}) {
  41. if list == nil {
  42. return
  43. }
  44. commonSubstring := func(v string) (value string) {
  45. bcs := strings.Split(v, "_")
  46. if len(bcs) == 1 {
  47. value = bcs[0]
  48. } else if len(bcs) == 2 {
  49. value = bcs[0]
  50. if strings.TrimSpace(value) == "" {
  51. value = bcs[0]
  52. }
  53. }
  54. return
  55. }
  56. for _, v := range *list {
  57. budget, _ := v["budget"].(float64)
  58. bidamount, _ := v["bidamount"].(float64)
  59. if budget == 0 || strings.TrimSpace(fmt.Sprint(v["budget"])) == "" {
  60. delete(v, "budget")
  61. }
  62. if bidamount == 0 || strings.TrimSpace(fmt.Sprint(v["bidamount"])) == "" {
  63. delete(v, "bidamount")
  64. }
  65. value := ""
  66. subscopeclass, _ := v["s_subscopeclass"].(string)
  67. subscopeclass = strings.Trim(subscopeclass, ",")
  68. bct := strings.Split(subscopeclass, ",")
  69. if bct == nil || len(bct) == 0 {
  70. continue
  71. }
  72. //搜索条件中没有行业的话,取查询结果中第一个行业
  73. if industry == "" {
  74. value = commonSubstring(bct[0])
  75. } else { //搜索条件中有行业的话,取行业中和搜索条件相对应的第一个
  76. industrys := strings.Split(industry, ",")
  77. L:
  78. for _, bc := range bct {
  79. for _, is := range industrys {
  80. if bc == is {
  81. value = commonSubstring(bc)
  82. break L
  83. }
  84. }
  85. }
  86. }
  87. if strings.TrimSpace(value) == "" {
  88. continue
  89. }
  90. v["industry"] = value
  91. }
  92. }
  93. // a_mergeorder 根据这三个字段产生的顺序,决定用哪个当作openid
  94. func GetOldOpenId(userId string) (*map[string]interface{}, string) {
  95. user, ok := MQFW.FindById("user", userId, `{"s_m_openid":1,"a_m_openid":1,"s_phone":1,"a_mergeorder":1,"o_jy":1,"l_firstpushtime":1}`)
  96. if !ok || user == nil {
  97. return nil, ""
  98. }
  99. s_m_openid, _ := (*user)["s_m_openid"].(string)
  100. a_m_openid, _ := (*user)["a_m_openid"].(string)
  101. s_phone, _ := (*user)["s_phone"].(string)
  102. openid := jy.GetOldOpenid(s_m_openid, a_m_openid, s_phone, (*user)["a_mergeorder"])
  103. return user, openid
  104. }
  105. func PushViewDatas(userid, allquery, field string, pageNum, pageSize int) (keys []interface{}, list *[]map[string]interface{}) {
  106. keys, list = PushView(userid, allquery, field, pageNum, pageSize)
  107. if list != nil {
  108. for _, v := range *list {
  109. v["_id"] = EncodeArticleId2ByCheck(util.ObjToString(v["_id"]))
  110. }
  111. }
  112. return
  113. }
  114. func PushView(userid, allquery, field string, pageNum, pageSize int) (keys []interface{}, list *[]map[string]interface{}) {
  115. if userid == "" {
  116. return
  117. }
  118. tmp, ok := MQFW.FindById("user", userid, `{"_id":1,"o_jy":1}`)
  119. if !ok || tmp == nil || len(*tmp) == 0 {
  120. return
  121. }
  122. o_jy := (*tmp)["o_jy"].(map[string]interface{})
  123. a_key, _ := o_jy["a_key"].([]interface{})
  124. if len(a_key) == 0 {
  125. return
  126. }
  127. for _, v := range a_key {
  128. keyMap, _ := v.(map[string]interface{})
  129. key, _ := keyMap["key"].([]interface{})
  130. keys = append(keys, key)
  131. }
  132. var allkeys []elastic.KeyConfig //用户配置
  133. _bs, err := json.Marshal(a_key)
  134. if err == nil {
  135. json.Unmarshal(_bs, &allkeys)
  136. }
  137. list = elastic.GetResForJY(INDEX, TYPE, allkeys, allquery, `"title"`, `{"publishtime":"desc"}`, field, (pageNum-1)*pageSize, pageSize)
  138. return
  139. }
  140. // 查询获取最多订阅词
  141. func GetHotkeys() []interface{} {
  142. sess := MQFW.GetMgoConn()
  143. defer MQFW.DestoryMongoConn(sess)
  144. var res []map[string]interface{}
  145. var keys []interface{}
  146. sess.DB("qfw").C("user").Pipe([]map[string]interface{}{
  147. map[string]interface{}{"$match": map[string]interface{}{"o_jy.a_key": map[string]interface{}{"$exists": 1}}},
  148. map[string]interface{}{"$project": map[string]interface{}{"o_jy.a_key.key": 1}},
  149. map[string]interface{}{"$unwind": "$o_jy.a_key"},
  150. map[string]interface{}{"$project": map[string]interface{}{"key": "$o_jy.a_key.key"}},
  151. map[string]interface{}{"$unwind": "$key"},
  152. map[string]interface{}{"$group": map[string]interface{}{"_id": "$key", "sum": map[string]interface{}{"$sum": 1}}},
  153. map[string]interface{}{"$sort": map[string]interface{}{"sum": -1}},
  154. map[string]interface{}{"$limit": 6},
  155. }).All(&res)
  156. for _, v := range res {
  157. keys = append(keys, v["_id"])
  158. }
  159. return keys
  160. }
  161. func GetWinnerNewestDatas(winner string) *[]map[string]interface{} {
  162. if winner == "" {
  163. return nil
  164. }
  165. //判断用户是否关注
  166. fields := `"_id","projectname","bidamount","title","publishtime","subtype","toptype","href"`
  167. data := elastic.GetPage("bidding", "bidding", `{"TERM_s_winner":"`+winner+`"}`, `{"publishtime":-1}`, fields, 0, 100)
  168. if *data != nil {
  169. for _, v := range *data {
  170. v["_id"] = EncodeArticleId2ByCheck(BsonIdToSId(v["_id"]))
  171. v["bidamount"], _ = v["bidamount"].(float64)
  172. }
  173. }
  174. return data
  175. }
  176. // 删除redis相关数据
  177. func DelRelRedis(userid interface{}, relationinfo interface{}) {
  178. defer util.Catch()
  179. uid, _ := userid.(string)
  180. if uid == "" || relationinfo == nil {
  181. return
  182. }
  183. array, _ := relationinfo.([]interface{})
  184. for _, v := range util.ObjArrToMapArr(array) {
  185. sid, _ := v["s_id"].(string)
  186. redis.Del("push", "push_"+uid+"_"+sid)
  187. }
  188. }
  189. // 合并两次检索结果(根据filed从大到小)
  190. // sortFiled 排序字段
  191. // Mergefiled 判重字段
  192. func MapArrSortMerge(arr1, arr2 []map[string]interface{}, mergeFiled, sortFiled string) *[]map[string]interface{} {
  193. for _, v := range arr1 {
  194. for n, m := range arr2 {
  195. if util.ObjToString(v["_id"]) == util.ObjToString(m["_id"]) {
  196. arr2 = append((arr2)[0:n], (arr2)[n+1:]...)
  197. break
  198. }
  199. }
  200. }
  201. arr1 = append(arr1, arr2...)
  202. return &arr1
  203. // var tmp []map[string]interface{}
  204. // i, j := 0, 0
  205. // var idMap = map[string]bool{}
  206. // MaxLenArr1, MaxLenArr2 := len(arr1), len(arr2)
  207. // for i < MaxLenArr1 || j < MaxLenArr2 {
  208. // var mergeTmp interface{}
  209. // var sign map[string]interface{}
  210. // if len(tmp) > 0 {
  211. // mergeTmp = tmp[len(tmp)-1][mergeFiled]
  212. // }
  213. // if i <= MaxLenArr1-1 {
  214. // sign = arr1[i]
  215. // }
  216. // if j <= MaxLenArr2-1 {
  217. // if util.Int64All(sign[sortFiled]) > util.Int64All(arr2[j][sortFiled]) {
  218. // i++
  219. // } else {
  220. // sign = arr2[j]
  221. // j++
  222. // }
  223. // } else {
  224. // i++
  225. // }
  226. // if mergeTmp != sign[mergeFiled] {
  227. // if !idMap[util.ObjToString(sign[mergeFiled])] {
  228. // idMap[util.ObjToString(sign[mergeFiled])] = true
  229. // tmp = append(tmp, sign)
  230. // }
  231. // }
  232. // }
  233. // return &tmp
  234. }
  235. // 保存用户搜索日志
  236. func SaveUserSearchLog(request *http.Request, userid string, count int64, platform, source string, condition map[string]interface{}) {
  237. go func() {
  238. data := map[string]interface{}{
  239. "ip": util.GetIp(request),
  240. "count": count,
  241. "s_userid": userid,
  242. "platform": platform,
  243. "source": source,
  244. "createtime": time.Now().Unix(),
  245. "userAgent": request.Header.Get("User-Agent"),
  246. }
  247. for _, v := range []string{"pagenum", "pagesize", "search_word", "search_area", "search_publishtime", "search_industry", "search_price", "search_type", "bid_field"} {
  248. if vv := condition[v]; vv != nil {
  249. data[v] = vv
  250. }
  251. }
  252. Mgo_Log.Save("jy_search_log", data)
  253. }()
  254. }
  255. func isPhone(value string) bool {
  256. var phonePattern = regexp.MustCompile("^[1][3-9][0-9]{9}$")
  257. return phonePattern.MatchString(value)
  258. }
  259. func isEmail(value string) bool {
  260. var emailPattern = regexp.MustCompile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")
  261. return emailPattern.MatchString(value)
  262. }