buyerListBYEs.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. package model
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. IC "jyBXBuyer/rpc/init"
  6. "jyBXBuyer/rpc/type/bxbuyer"
  7. "strconv"
  8. "strings"
  9. "sync"
  10. "time"
  11. MC "app.yhyue.com/moapp/jybase/common"
  12. "app.yhyue.com/moapp/jybase/encrypt"
  13. elastic "app.yhyue.com/moapp/jybase/es"
  14. "github.com/zeromicro/go-zero/core/logx"
  15. )
  16. type BScope struct {
  17. Keyword []string `json:"keyword"`
  18. AdditionalWords []string `json:"additionalWords"`
  19. ExcludedWords []string `json:"excludedWords"`
  20. }
  21. //获取采购单位查询query
  22. func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string) {
  23. query_bool_must_and := `{"bool": {"must": [%s]%s}}`
  24. multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
  25. query := `{"size": 0,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[%s],"minimum_should_match": %d}},%s}`
  26. //21.1.20 为和画像保持一致 数据组要求 budget 改成 bidamount
  27. query_aggs := `"aggs": {"group_field": {"terms": {"field": %s,"size": %d%s},"aggs": {"count": {"sum": {"field": "bidamount"}}}}}`
  28. query_sort := `,"order": {"count": "desc"}`
  29. query_bool_must := `{"terms":{"%s":[%s]}}`
  30. query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
  31. bools := []string{}
  32. musts := []string{}
  33. musts_should := []string{}
  34. //省份
  35. if len(in.Province) > 0 {
  36. musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.Join(in.Province, "\",\"")))
  37. }
  38. //城市
  39. if len(in.City) > 0 {
  40. musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"city":["%s"]}}`, strings.Join(in.City, "\",\"")))
  41. }
  42. if len(musts_should) > 0 {
  43. musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(musts_should, ",")))
  44. }
  45. //采购单位名称
  46. if len(in.BuyerName) > 0 {
  47. entNameQuery := `{"match_phrase":{"buyer.mbuyer":"` + in.BuyerName + `"}}`
  48. musts = append(musts, entNameQuery)
  49. }
  50. //采购单位类型
  51. buyerclass := in.BuyerClass
  52. if len(buyerclass) > 0 {
  53. Buyerclass := `{"terms":{"buyerclass":[`
  54. for k, v := range buyerclass {
  55. if k > 0 {
  56. Buyerclass += `,`
  57. }
  58. Buyerclass += `"` + v + `"`
  59. }
  60. Buyerclass += `]}}`
  61. musts = append(musts, Buyerclass)
  62. }
  63. //行业
  64. industry := in.Industry
  65. if len(industry) > 0 {
  66. musts = append(musts, fmt.Sprintf(query_bool_must, "subscopeclass", `"`+strings.Join(industry, `","`)+`"`))
  67. }
  68. if len(in.Customer) > 0 {
  69. entcustomerClass := `{"terms":{"buyer":[`
  70. for k, v := range in.Customer {
  71. if k > 0 {
  72. entcustomerClass += `,`
  73. }
  74. entcustomerClass += `"` + v + `"`
  75. }
  76. entcustomerClass += `]}}`
  77. musts = append(musts, entcustomerClass)
  78. }
  79. //业务范围
  80. boolsNum := 0
  81. if in.BusinessScope != "" {
  82. var BScopes = []BScope{}
  83. json.Unmarshal([]byte(in.BusinessScope), &BScopes)
  84. boolsNum = 1
  85. findfields := `"projectname.pname","purchasing"`
  86. multi_match = fmt.Sprintf(multi_match, "%s", findfields)
  87. for _, v := range BScopes {
  88. shoulds := []string{}
  89. must_not := []string{}
  90. //关键词
  91. if len(v.Keyword) > 0 {
  92. for _, kv := range v.Keyword {
  93. shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+kv+"\""))
  94. }
  95. }
  96. //附加词
  97. if len(v.AdditionalWords) > 0 {
  98. for _, av := range v.AdditionalWords {
  99. shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+av+"\""))
  100. }
  101. }
  102. if len(v.ExcludedWords) > 0 {
  103. //排除词
  104. for _, ev := range v.ExcludedWords {
  105. must_not = append(must_not, fmt.Sprintf(multi_match, "\""+ev+"\""))
  106. }
  107. }
  108. //添加
  109. if len(shoulds) > 0 {
  110. notStr := ""
  111. if len(must_not) > 0 {
  112. notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
  113. }
  114. bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
  115. }
  116. }
  117. }
  118. query_aggs = fmt.Sprintf(query_aggs, `"buyer"`, IC.C.BuyerCount, "%s")
  119. if in.SortRule == 0 { //项目总数排序
  120. query_sort = ""
  121. }
  122. query_aggs = fmt.Sprintf(query_aggs, query_sort)
  123. qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, query_aggs)
  124. return
  125. }
  126. const (
  127. P_INDEX = "projectset"
  128. P_TYPE = "projectset"
  129. P_redis_time = 15 * 24 * 60 * 60 //redis存15天
  130. P_redis_key = "buyerListCache"
  131. )
  132. //查询采购单位列表
  133. func GetBuyerList(qstr string, in *bxbuyer.BuyerListReq, isCache bool) (resp *bxbuyer.BuyerListResp) {
  134. t1 := time.Now()
  135. aggs := GetAggs(P_INDEX, P_TYPE, qstr)
  136. resp = &bxbuyer.BuyerListResp{
  137. Data: &bxbuyer.BuyerData{},
  138. }
  139. type GroupStruct struct {
  140. Buckets []struct {
  141. Key string `json:"key,omitempty"`
  142. Doc_count int64 `json:"doc_count,omitempty"`
  143. Count struct {
  144. Value float64 `json:"value,omitempty"`
  145. } `json:"count"`
  146. } `json:"buckets"`
  147. }
  148. var group = GroupStruct{}
  149. if aggs != nil && aggs["group_field"] != nil {
  150. bs, err := aggs["group_field"].MarshalJSON()
  151. if err != nil {
  152. resp.ErrCode = -1
  153. resp.ErrMsg = "获取数据异常"
  154. } else {
  155. if len(bs) == 0 {
  156. resp.ErrMsg = "暂无数据"
  157. } else {
  158. json.Unmarshal(bs, &group)
  159. if len(group.Buckets) > 0 {
  160. for _, v := range group.Buckets {
  161. var list = &bxbuyer.BuyerList{}
  162. list.Buyer = v.Key
  163. list.Budget = v.Count.Value
  164. list.PCount = v.Doc_count
  165. resp.Data.List = append(resp.Data.List, list)
  166. }
  167. }
  168. }
  169. }
  170. }
  171. resp.Data.Count = int64(len(resp.Data.List))
  172. logx.Info("=---count---===", resp.Data.Count)
  173. if len(resp.Data.List) > 0 {
  174. var wg sync.WaitGroup
  175. //省份和城市 是否查询已关注信息 是否查询已领取信息
  176. //企业信用库qyxy_std 和es buyer库 查询省份和城市
  177. var fiftyArr = []*bxbuyer.BuyerList{}
  178. var buyerNames = []string{}
  179. for bk, bv := range resp.Data.List {
  180. fiftyArr = append(fiftyArr, bv)
  181. buyerNames = append(buyerNames, bv.Buyer)
  182. if (bk+1)%50 == 0 || len(resp.Data.List) == bk+1 {
  183. wg.Add(1)
  184. go func(wg *sync.WaitGroup, fiftyArr []*bxbuyer.BuyerList, buyerNames []string, icf, icr bool, userId, entUserId string) {
  185. //省份城市 关注状态 领取状态
  186. infoMap := GetBuyerInfo(buyerNames)
  187. //关注状态
  188. isFws := map[string]bool{}
  189. if icf {
  190. isFws = IsFollowd(buyerNames, userId)
  191. }
  192. //领取状态
  193. isRws := map[string]string{}
  194. if icr {
  195. isRws = IsReceived(buyerNames, entUserId)
  196. }
  197. //log.Println("---:", isRws)
  198. for _, fv := range fiftyArr {
  199. fv.Province = infoMap[fv.Buyer].Province
  200. fv.City = infoMap[fv.Buyer].City
  201. if icf {
  202. fv.IsFollowed = isFws[fv.Buyer]
  203. }
  204. if icr {
  205. if isRws[fv.Buyer] != "" {
  206. fv.RecId = isRws[fv.Buyer]
  207. fv.IsReceived = true
  208. }
  209. }
  210. }
  211. wg.Done()
  212. }(&wg, fiftyArr, buyerNames, in.IsCheckFollow, in.IsCheckReceive, in.UserId, in.EntUserId)
  213. fiftyArr = []*bxbuyer.BuyerList{}
  214. buyerNames = []string{}
  215. }
  216. }
  217. wg.Wait()
  218. }
  219. logx.Info("耗时;", time.Since(t1).Seconds(), time.Since(t1).Microseconds())
  220. return
  221. }
  222. //聚合查询
  223. func GetAggs(index, itype, query string) (aggs map[string]json.RawMessage) {
  224. aggs, _, _ = elastic.GetAggs(index, itype, query)
  225. return
  226. }
  227. type buyerInfo struct {
  228. Province string
  229. City string
  230. }
  231. //潜在客户 获取省份和城市
  232. func GetBuyerInfo(buyerNames []string) (infoMap map[string]buyerInfo) {
  233. var buyerInfoQuery = `{"query": {"bool": {"must": [{"terms": {"%s": [%s]}}],"must_not": [],"should": []}},"from": 0,"size": 50,"sort": []}`
  234. query := fmt.Sprintf(buyerInfoQuery, "buyer_name", `"`+strings.Join(buyerNames, `","`)+`"`)
  235. list := *elastic.Get("buyer", "buyer", query)
  236. if list != nil {
  237. if len(list) > 0 {
  238. infoMap = map[string]buyerInfo{}
  239. for _, v := range list {
  240. infoMap[v["name"].(string)] = buyerInfo{
  241. Province: MC.If(v["province"] != nil, MC.ObjToString(v["province"]), "").(string),
  242. City: MC.If(v["city"] != nil, MC.ObjToString(v["city"]), "").(string),
  243. }
  244. }
  245. }
  246. } else {
  247. logx.Info("采购单位获取地区信息异常")
  248. }
  249. return
  250. }
  251. var fc = "follow_customer" //关注客户表
  252. //采购单位是否作为客户已被关注
  253. func IsFollowd(buyerNames []string, userId string) (isFws map[string]bool) {
  254. queryMap := map[string]interface{}{
  255. "userId": userId,
  256. "name": map[string]interface{}{
  257. "$in": buyerNames,
  258. },
  259. }
  260. list, ok := IC.Mgo.Find(fc, queryMap, `{"_id":1}`, nil, false, -1, -1)
  261. if ok && list != nil {
  262. if len(*list) > 0 {
  263. isFws = map[string]bool{}
  264. for _, lv := range *list {
  265. if MC.ObjToString(lv["name"]) != "" {
  266. isFws[MC.ObjToString(lv["name"])] = true
  267. }
  268. }
  269. }
  270. } else {
  271. logx.Info("采购单位是否已关注信息异常")
  272. }
  273. return
  274. }
  275. var (
  276. Entniche_customer = "entniche_customer"
  277. Entniche_user_customer = "entniche_user_customer"
  278. )
  279. //领取状态
  280. func IsReceived(buyerNames []string, entUserId string) (isRws map[string]string) {
  281. //新加领取的客户id----保证领取的唯一性
  282. receInfos := IC.MainMysql.SelectBySql(fmt.Sprintf("SELECT ecn.id, ecn.name FROM %s ecn,%s euu WHERE ecn.id = euu.customer_id AND euu.user_id =? AND ecn.`name` IN ('%s') AND (euu.source_type =1 or euu.source_type=4)", Entniche_customer, Entniche_user_customer, strings.Join(buyerNames, "','")), entUserId)
  283. if receInfos != nil {
  284. if len(*receInfos) > 0 {
  285. isRws = map[string]string{}
  286. for _, rv := range *receInfos {
  287. if MC.ObjToString(rv["name"]) != "" && strconv.Itoa(MC.IntAll(rv["id"])) != "" {
  288. isRws[MC.ObjToString(rv["name"])] = encrypt.SE.Encode2HexByCheck(strconv.Itoa(MC.IntAll(rv["id"])))
  289. }
  290. }
  291. }
  292. } else {
  293. logx.Info("采购单位是否已领取信息异常")
  294. }
  295. return
  296. }
  297. //是否为空请求
  298. func CheckEmpty(in *bxbuyer.BuyerListReq) bool {
  299. if in.BuyerName == "" && len(in.BuyerClass) == 0 && len(in.Province) == 0 && len(in.City) == 0 && len(in.Industry) == 0 && in.BusinessScope == "" && len(in.Customer) == 0 {
  300. return true
  301. }
  302. return false
  303. }
  304. //缓存数据查询
  305. //获取采购单位查询query
  306. func BuyerListRedisCacheQuery() (qstr string) {
  307. query := `{"size": 0,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[],"minimum_should_match": %d}},%s}`
  308. //21.1.20 为和画像保持一致 数据组要求 budget 改成 bidamount
  309. query_aggs := `"aggs": {"group_field": {"terms": {"field": %s,"size": %d%s},"aggs": {"count": {"sum": {"field": "bidamount"}}}}}`
  310. query_sort := `,"order": {"count": "desc"}`
  311. musts := []string{}
  312. boolsNum := 0
  313. entcustomerClass := `{"terms":{"buyer":[`
  314. for k, v := range IC.C.DefaultBuyerNames {
  315. if k > 0 {
  316. entcustomerClass += `,`
  317. }
  318. entcustomerClass += `"` + v + `"`
  319. }
  320. entcustomerClass += `]}}`
  321. musts = append(musts, entcustomerClass)
  322. query_aggs = fmt.Sprintf(query_aggs, `"buyer"`, len(IC.C.DefaultBuyerNames), "%s")
  323. query_aggs = fmt.Sprintf(query_aggs, query_sort)
  324. qstr = fmt.Sprintf(query, strings.Join(musts, ","), boolsNum, query_aggs)
  325. logx.Info("qstr:", qstr)
  326. return
  327. }