search.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package service
  2. import (
  3. MC "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. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/entity"
  8. IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/init"
  9. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/model/es"
  10. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/type/bxcore"
  11. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/util"
  12. "bp.jydev.jianyu360.cn/BaseService/powerCheckCenter/rpc/pb"
  13. userPb "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
  14. "context"
  15. "fmt"
  16. "log"
  17. "strings"
  18. "time"
  19. )
  20. const (
  21. entQuery = `{"query":{"bool":{"must":[%s],"must_not":[%s]}},"_source":["_id","company_name","company_status","legal_person","capital","company_address","company_shortname","company_phone","establish_date"],"sort":[{"capital":{"order":"desc"}}]}`
  22. entQueryCount = `{"query":{"bool":{"must":[%s],"must_not":[%s]}}}`
  23. index, itype = "qyxy", "qyxy"
  24. query = `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}]}}}`
  25. BuyerIndex = "buyer" // 采购单位index
  26. BuyerType = "buyer"
  27. )
  28. // GetBidSearchData 默认查询缓存数据 只查标题
  29. // 登录用户默认搜索500条数据,付费用户字段和免费用户字段不同,未登录用户查询5000条。
  30. // 标信息搜索 isCache:是否是获取缓存信息
  31. func GetBidSearchData(in *bxcore.SearchReq, isCache bool) (count int64, list []*bxcore.SearchList) {
  32. var start = int((in.PageNum - 1) * in.PageSize)
  33. if start >= 0 {
  34. t := time.Now()
  35. fields := MC.If(in.IsPay, es.BidSearchFieldOfVip, es.BidSearchFieldBase).(string)
  36. switch in.BidField {
  37. case "BIProperty": //物业专版-BI
  38. fields = es.BidSearchFieldProperty
  39. case "medical": //(医疗)领域化字段
  40. fields = es.BidSearchDomainField
  41. }
  42. //IC.C.FileSignBool列表是否显示附件开关
  43. if IC.C.FileSignBool {
  44. fields = fields + es.BidSearchFieldFile
  45. }
  46. biddingSearch := es.SearchByES{
  47. Index: MC.If(in.UserId == "", es.INDEXNoLogin, es.INDEX).(string),
  48. IType: MC.If(in.UserId == "", es.TYPENoLogin, es.TYPE).(string),
  49. Query: es.GetSearchQuery(in, es.GetBidSearchQuery(in)),
  50. //FindFields: MC.If(isCache, "title", "detail").(string),
  51. FindFields: in.SelectType,
  52. Order: es.BidSearchSort,
  53. Fields: fields,
  54. Start: MC.If(isCache, 0, start).(int),
  55. Limit: MC.If(isCache, MC.If(in.IsPay, IC.C.DefaultBidInfo.PayCount, IC.C.DefaultBidInfo.Count).(int), int(in.PageSize)).(int),
  56. Count: MC.If(strings.Contains(in.SelectType, "detail"), 115, 0).(int), //高亮正文数量
  57. HighLight: MC.If(strings.Contains(in.SelectType, "detail"), true, false).(bool) || MC.If(strings.Contains(in.SelectType, "filetext"), true, false).(bool), //是否高亮正文
  58. }
  59. var loginType int
  60. // 处理免费用户index
  61. if in.UserId == "" {
  62. loginType = es.LoginTypeNoLogin
  63. } else if !in.IsPay {
  64. biddingSearch.Index = IC.DB.EsFree.Index
  65. biddingSearch.IType = IC.DB.EsFree.Type
  66. loginType = es.LoginTypeFree
  67. } else {
  68. loginType = es.LoginTypePay
  69. }
  70. var repl *[]map[string]interface{}
  71. if in.UserId != "" {
  72. count, repl = biddingSearch.GetAllByNgramWithCount(loginType)
  73. } else {
  74. if IC.C.NoLoginSearch.Switch {
  75. if flag := IC.ReqLimitInit.Limit(context.Background()); flag == 1 {
  76. defer IC.ReqLimitInit.Release()
  77. } else {
  78. if flag == -2 {
  79. log.Println("等待队列已满")
  80. } else if flag == -1 {
  81. log.Println("等待超时")
  82. }
  83. return 0, nil
  84. }
  85. }
  86. count, repl = biddingSearch.GetAllByNgramWithCount(loginType)
  87. }
  88. if repl != nil && *repl != nil && len(*repl) > 0 {
  89. if repl != nil && *repl != nil && len(*repl) > 0 {
  90. //格式化查询结果
  91. var words []string
  92. words = strings.Split(in.KeyWords, " ")
  93. if in.AdditionalWords != "" {
  94. words = append(words, strings.Split(in.AdditionalWords, ",")...)
  95. }
  96. list = util.SearchListFormat(in.UserId, in.SubInformation, in.PropertyForm, in.Industry, repl, strings.Contains(in.SelectType, "detail"), in.BidField, words)
  97. }
  98. } else {
  99. log.Println("查询数据异常")
  100. }
  101. log.Println(in.KeyWords, "关键词 -1- 查询耗时:", time.Since(t).Seconds())
  102. }
  103. return
  104. }
  105. func GetBidSearchCount(in *bxcore.SearchReq) int64 {
  106. bidIndex := MC.If(in.UserId == "", es.INDEXNoLogin, es.INDEX).(string)
  107. bidIType := MC.If(in.UserId == "", es.TYPENoLogin, es.TYPE).(string)
  108. var loginType int
  109. // 处理免费用户index
  110. if in.UserId == "" {
  111. loginType = es.LoginTypeNoLogin
  112. } else if !in.IsPay {
  113. bidIndex = IC.DB.EsFree.Index
  114. bidIType = IC.DB.EsFree.Type
  115. loginType = es.LoginTypeFree
  116. } else {
  117. loginType = es.LoginTypePay
  118. }
  119. switch loginType {
  120. case es.LoginTypePay:
  121. return elastic.Count(bidIndex, bidIType, es.GetSearchQuery(in, es.GetBidSearchQuery(in)))
  122. case es.LoginTypeFree:
  123. // 免费用户
  124. return IC.FreeEs.Count(bidIndex, bidIType, es.GetSearchQuery(in, es.GetBidSearchQuery(in)))
  125. default:
  126. // 未登录
  127. return IC.NoLoginEs.Count(bidIndex, bidIType, es.GetSearchQuery(in, es.GetBidSearchQuery(in)))
  128. }
  129. }
  130. func EntSearch(searchCode string) ([]*bxcore.Search, int64) {
  131. data := make([]*bxcore.Search, 0, 0)
  132. count := int64(0)
  133. musts := make([]string, 0, 0)
  134. musts = append(musts, `{"range":{"company_type_int":{"to":"22"}}}`)
  135. thisQuery := []string{}
  136. //查询指定内容
  137. thisQuery = append(thisQuery, fmt.Sprintf(`{"match_phrase":{"name":"%s"}}`, searchCode))
  138. musts = append(musts, fmt.Sprintf(`{"bool":{"should":[%s],"minimum_should_match": 1}}`, strings.Join(thisQuery, ",")))
  139. sql := fmt.Sprintf(entQuery, strings.Join(musts, ","), "")
  140. sql = sql[:len(sql)-1] + fmt.Sprintf(`,"from":%d,"size":%d}`, 0, 5)
  141. log.Println("企业搜索sql:", sql)
  142. count, list := elastic.GetWithCount(index, itype, "", sql)
  143. if list != nil {
  144. for _, value := range *list {
  145. data = append(data, &bxcore.Search{
  146. Title: MC.InterfaceToStr(value["company_name"]),
  147. Url: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(value["_id"])),
  148. })
  149. }
  150. }
  151. return data, count
  152. }
  153. func ProcureSearch(searchCode string) ([]*bxcore.Search, int64) {
  154. data := []*bxcore.Search{}
  155. count := int64(0)
  156. //数据查询处理
  157. entNameQuery := fmt.Sprintf(`{"multi_match": {"query": "%s","type": "phrase", "fields": ["name"]}}`, searchCode)
  158. qstr := fmt.Sprintf(query, fmt.Sprintf(`"from":%d,"size": %d,`, 0, 5), entNameQuery)
  159. log.Println("采购单位搜索sql:", qstr)
  160. count, rs := elastic.GetWithCount(BuyerIndex, BuyerType, "", qstr)
  161. //rs := elastic.Get(BuyerIndex, BuyerType, qstr) // 采购单位列表
  162. if rs == nil || len(*rs) == 0 {
  163. return data, count
  164. }
  165. for i := 0; i < len(*rs); i++ {
  166. data = append(data, &bxcore.Search{
  167. Title: MC.ObjToString((*rs)[i]["name"]),
  168. })
  169. }
  170. return data, count
  171. }
  172. // 菜单搜索
  173. func MenuSearch(in *bxcore.PolymerizeSearchReq) []*bxcore.MenuList {
  174. data := []*bxcore.MenuList{}
  175. workData := IC.Middleground.UserCenter.WorkDesktopMenuInfo(userPb.WorkDesktopMenuInfoReq{
  176. UserId: in.UserId,
  177. AppId: in.AppId,
  178. Platform: "PC",
  179. NewUserId: MC.InterfaceToStr(in.NewUserId),
  180. EntId: MC.InterfaceToStr(in.EntId),
  181. EntUserId: MC.InterfaceToStr(in.EntUserId),
  182. AccountId: MC.InterfaceToStr(in.AccountId),
  183. PositionType: MC.InterfaceToStr(in.PositionType),
  184. PositionId: MC.InterfaceToStr(in.PositionId),
  185. EntAccountId: MC.InterfaceToStr(in.EntAccountId),
  186. })
  187. if workData != nil && len(workData.Data.MenuList) > 0 {
  188. for _, value1 := range workData.Data.MenuList {
  189. for _, value2 := range value1.Child {
  190. for _, value3 := range value2.Child {
  191. if strings.Contains(value3.Name, in.SearchCode) {
  192. tipInfo := &bxcore.TipInfo{}
  193. if value3.TipInfo != nil {
  194. tipInfo = &bxcore.TipInfo{
  195. Title: value3.TipInfo.Title,
  196. Content: value3.TipInfo.Content,
  197. ConfirmUrl: value3.TipInfo.ConfirmUrl,
  198. ConfirmText: value3.TipInfo.ConfirmText,
  199. IsShowCancel: value3.TipInfo.IsShowCancel,
  200. AppType: value3.TipInfo.AppType,
  201. OpenType: value3.TipInfo.OpenType,
  202. }
  203. }
  204. data = append(data, &bxcore.MenuList{
  205. Name: value3.Name,
  206. Icon: value3.Icon,
  207. Url: value3.Url,
  208. Usable: value3.Usable,
  209. AppType: value3.AppType,
  210. OpenType: value3.OpenType,
  211. TipInfo: tipInfo,
  212. Match: value3.Match,
  213. Path: fmt.Sprintf("%s>%s>%s", value1.Name, value2.Name, value3.Name),
  214. })
  215. }
  216. }
  217. }
  218. }
  219. }
  220. return data
  221. }
  222. func SubscribeSearch(searchCode string, powerCheck *pb.CheckResp) []*bxcore.Search {
  223. data := []*bxcore.Search{}
  224. in := &bxcore.SearchReq{
  225. PageNum: int64(1),
  226. PageSize: int64(10),
  227. IsPay: false,
  228. SelectType: "title",
  229. KeyWords: searchCode,
  230. PublishTime: fmt.Sprintf("%v_%v", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix()),
  231. }
  232. isLimit := int64(0)
  233. isLimit = util.IsLimited(in.LimitFlag, in.UserId, powerCheck.Vip.Status > 0 || powerCheck.Member.Status > 0, in.IsNew)
  234. if isLimit == 1 { //没有被限制
  235. defer util.Limit()
  236. }
  237. list := []*bxcore.SearchList{}
  238. if isLimit == 1 {
  239. //付费用户搜索优化--默认搜索5年数据,数据量太多,接口反应太慢,前两页数据 时间范围根据配置缩小查询以达到快速查询的目的。
  240. t1 := time.Now()
  241. _, list = GetBidSearchData(in, false)
  242. log.Println("1查询耗时:", time.Since(t1))
  243. }
  244. if list != nil && len(list) > 0 {
  245. for _, value := range list {
  246. data = append(data, &bxcore.Search{
  247. Title: value.Title,
  248. Url: value.Id,
  249. DataTime: value.PublishTime,
  250. })
  251. }
  252. }
  253. return data
  254. }
  255. // IsOnTheWhitelist 是否在白名单
  256. func IsOnTheWhitelist(userId, mgoUserId string) (flag bool, err error) {
  257. // mongoid 在白名单中没有查到 再去查职位id有没有在白名单里面
  258. flag, err = redis.Exists(entity.RedisPoly, fmt.Sprintf(entity.WhitelistRedisKey, mgoUserId))
  259. if err == nil && flag {
  260. return
  261. }
  262. flag, err = redis.Exists(entity.RedisPoly, fmt.Sprintf(entity.WhitelistRedisKey, userId))
  263. return
  264. }
  265. // FilterGeneric 通用词处理
  266. func FilterGeneric(keyWords string) string {
  267. keyWords = entity.FilterReg_3.ReplaceAllString(keyWords, "")
  268. keyWords = entity.FilterReg_2.ReplaceAllString(keyWords, "")
  269. keyWords = entity.FilterReg_1.ReplaceAllString(keyWords, "")
  270. keyWords = entity.FilterReg.ReplaceAllString(keyWords, "")
  271. return keyWords
  272. }
  273. // AdditionalFilterGeneric 附加词处理通用词
  274. // 逗号分割后再空格分割然后再过滤
  275. // 过滤完再合回去
  276. func AdditionalFilterGeneric(keyWords string) (additionalWords string) {
  277. keyWordsArr := strings.Split(keyWords, ",")
  278. var finalArr []string
  279. for i := 0; i < len(keyWordsArr); i++ {
  280. var tmpArr []string
  281. words := strings.Split(keyWordsArr[i], " ")
  282. for j := 0; j < len(words); j++ {
  283. word := FilterGeneric(words[j])
  284. if word != "" {
  285. tmpArr = append(tmpArr, word)
  286. }
  287. }
  288. if len(tmpArr) > 0 {
  289. // 还原空格分割
  290. spaceWord := strings.Join(tmpArr, " ")
  291. finalArr = append(finalArr, spaceWord)
  292. }
  293. }
  294. // 还原逗号分割
  295. if len(finalArr) > 0 {
  296. additionalWords = strings.Join(finalArr, ",")
  297. }
  298. return additionalWords
  299. }