enterpriseStruct.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. package service
  2. import (
  3. elastic "app.yhyue.com/moapp/jybase/es"
  4. "context"
  5. "fmt"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/util/gconv"
  8. "math/rand"
  9. "strings"
  10. "time"
  11. )
  12. var (
  13. JySeoEnterprises *Enterprises = &Enterprises{}
  14. )
  15. type (
  16. Enterprises struct{}
  17. MapsTotalResp struct {
  18. Total int `json:"total"`
  19. List []map[string]interface{} `json:"list"`
  20. UpdateTime int64 `json:"updateTime"`
  21. }
  22. )
  23. const (
  24. NewMustSearch = `{"query":{"bool":{"must":[%s]}}%s}`
  25. biddingIndex, biddingType = "bidding", "bidding"
  26. )
  27. // GetEnterprisesList 获取最新采购单位或中标企业列表
  28. // identityType : 0 采购单位 1-中标单位
  29. // limit: 数量
  30. func (*Enterprises) GetEnterprisesList(ctx context.Context, identityType, pageNum, pageSize, limit int) (res *MapsTotalResp, err error) {
  31. key := fmt.Sprintf("enterpriseList_%d_%d_%d_%d", identityType, pageNum, pageSize, limit)
  32. gVal, err := g.Redis().Get(ctx, key)
  33. if err == nil && !gVal.IsNil() {
  34. res = &MapsTotalResp{}
  35. if err := gVal.Struct(res); err == nil {
  36. return res, nil
  37. }
  38. }
  39. var sql string
  40. if identityType == 0 {
  41. sql = fmt.Sprintf(`
  42. SELECT c.seo_id AS sid,c.name,c.company_id AS id,b.NAME AS buyerclass,p.area AS province,ca.city AS city
  43. FROM (
  44. SELECT dfeb.seo_id,dfeb.NAME, dfeb.company_id, dfeb.area_code, dfeb.city_code, dfeb.name_id,dfet.labelvalues
  45. FROM global_common_data.dws_f_ent_baseinfo dfeb
  46. INNER JOIN global_common_data.dws_f_ent_tags dfet
  47. ON (dfeb.identity_type &(1 << 0)) > 0 AND dfeb.name_id = dfet.name_id
  48. ORDER BY dfeb.latest_time DESC LIMIT %d
  49. ) c LEFT JOIN global_common_data.code_buyerclass b ON (b. CODE = c.labelvalues)
  50. LEFT JOIN global_common_data.code_area p ON (p. CODE = c.area_code)
  51. LEFT JOIN global_common_data.code_area ca ON (ca. CODE = c.city_code)`, limit)
  52. } else if identityType == 1 {
  53. sql = fmt.Sprintf(`
  54. SELECT c.seo_id AS sid,c.name, c.company_id AS id,c.address,cb.legal_person,cb.company_status,cb.capital,DATE_FORMAT(cb.establish_date, '%s') AS establish_date,cb.company_phone
  55. FROM (
  56. SELECT seo_id,name, company_id,address
  57. FROM global_common_data.dws_f_ent_baseinfo
  58. WHERE company_id!=''and (identity_type & (1 << 1)) > 0
  59. order by latest_time desc LIMIT %d
  60. ) c left join global_common_data.company_baseinfo cb on(cb.company_id=c.company_id)`, "%Y-%m-%d", limit)
  61. }
  62. rData, err := g.DB("tidb").Query(ctx, sql)
  63. if err != nil {
  64. return nil, fmt.Errorf("查询数据异常")
  65. }
  66. if count := rData.Len(); count > 0 {
  67. urlFlag := "dw"
  68. if identityType == 1 {
  69. urlFlag = "qy"
  70. }
  71. finalList := rData.List()
  72. for i := 0; i < count; i++ {
  73. finalList[i]["url"] = fmt.Sprintf("/%s/%s.html", urlFlag, gconv.String(finalList[i]["sid"]))
  74. if state := gconv.String(finalList[i]["company_status"]); state != "" {
  75. finalList[i]["company_status"] = strings.Split(state, "(")[0]
  76. }
  77. }
  78. totalPage := count / pageSize
  79. if count%pageSize != 0 {
  80. totalPage++
  81. }
  82. for i := 1; i <= gconv.Int(totalPage); i++ {
  83. start, end := (i-1)*pageSize, (i)*pageSize
  84. if end > count {
  85. end = count
  86. }
  87. pageTmp := &MapsTotalResp{
  88. Total: totalPage,
  89. List: finalList[start:end],
  90. }
  91. if i == pageNum {
  92. res = pageTmp
  93. }
  94. if err := g.Redis().SetEX(ctx, fmt.Sprintf("enterpriseList_%d_%d_%d_%d", identityType, i, pageSize, limit), pageTmp, 60*60*24); err != nil {
  95. g.Log().Errorf(ctx, "第%d页数据 存储redis err:%v", i, err)
  96. }
  97. }
  98. }
  99. return res, nil
  100. }
  101. // GetEntDetailMsg 查询企业详细信息
  102. func (*Enterprises) GetEntDetailMsg(ctx context.Context, seoId string, isWinner bool) map[string]interface{} {
  103. if isWinner {
  104. res, err := g.DB("tidb").Query(context.Background(), `
  105. SELECT c.seo_id AS sid,c.name,cb.*,DATE_FORMAT(cb.establish_date, '%Y-%m-%d') AS establish_formatDate,ca.area as areaName
  106. FROM (
  107. SELECT seo_id,name, company_id,address
  108. FROM global_common_data.dws_f_ent_baseinfo
  109. WHERE company_id !='' and (identity_type & (1 << 1)) > 0
  110. and seo_id = ?
  111. ) c LEFT JOIN global_common_data.company_baseinfo cb on(cb.company_id=c.company_id)
  112. LEFT JOIN global_common_data.code_area ca on(cb.area_code=ca.code )`, seoId)
  113. if err != nil {
  114. g.Log().Errorf(ctx, "GetEntDetailMsg 异常", err)
  115. }
  116. if res.Len() == 1 {
  117. return res.List()[0]
  118. }
  119. } else {
  120. res, err := g.DB("tidb").Query(context.Background(), `
  121. SELECT c.*,cb.name AS buyerclass,ca.area as areaName ,ca.city as cityName FROM
  122. (SELECT name,area_code,city_code,name_id FROM global_common_data.dws_f_ent_baseinfo WHERE seo_id = ?) c
  123. LEFT JOIN global_common_data.dws_f_ent_tags dfet on(c.name_id=dfet.name_id )
  124. LEFT JOIN global_common_data.code_buyerclass cb on(dfet.labelvalues=cb.code)
  125. LEFT JOIN global_common_data.code_area ca on(IF(c.city_code,ca.code=c.city_code,ca.code=c.area_code))`, seoId)
  126. if err != nil {
  127. g.Log().Errorf(ctx, "GetEntDetailMsg 异常", err)
  128. }
  129. if res.Len() == 1 {
  130. return res.List()[0]
  131. }
  132. }
  133. return nil
  134. }
  135. // GetDynamicNews 未登录用户动态信息
  136. func (pwp *Enterprises) GetDynamicNews(ctx context.Context, name string, isWinner bool) (res *MapsTotalResp, err error) {
  137. if name == "" {
  138. return
  139. }
  140. res = &MapsTotalResp{}
  141. redisKey := fmt.Sprintf("free_portrait_list_%s", name)
  142. gVal, err := g.Redis().Get(ctx, redisKey)
  143. if err == nil && !gVal.IsNil() {
  144. if err := gVal.Struct(res); err == nil {
  145. return res, nil
  146. }
  147. }
  148. res.Total = gconv.Int(elastic.Count(biddingIndex, biddingType, pareSelect(name, isWinner, true)))
  149. if res.Total == 0 {
  150. return
  151. }
  152. list := elastic.Get(biddingIndex, biddingType, pareSelect(name, isWinner, false))
  153. if list != nil && len(*list) > 0 {
  154. res.List = *list
  155. }
  156. res.UpdateTime = time.Now().Unix()
  157. _ = g.Redis().SetEX(ctx, redisKey, res, 60*60*24*7)
  158. return
  159. }
  160. // RelevanceData 关联单位
  161. func (pwp *Enterprises) RelevanceData(ctx context.Context, name string, isWinner bool) (randomMaps []map[string]interface{}) {
  162. if name == "" {
  163. return nil
  164. }
  165. redisKey := fmt.Sprintf("portrait_relevance_%v_%s", isWinner, name)
  166. getFullArr, fromCache := func() (data []map[string]interface{}, fromCache bool) {
  167. gVal, err := g.Redis().Get(ctx, redisKey)
  168. if err == nil && !gVal.IsNil() {
  169. if err := gVal.Struct(&data); err == nil {
  170. fromCache = true
  171. return
  172. }
  173. }
  174. data = []map[string]interface{}{}
  175. querySql := `{"query": {"bool": {"must": [%s]}},"_source":["buyer","s_winner","entidlist"],"size": 200}`
  176. var mustSql string
  177. if isWinner {
  178. mustSql = fmt.Sprintf(`{"terms": {"entidlist": ["%s"]}},{"exists": {"field": "buyer"}}`, name)
  179. } else {
  180. mustSql = fmt.Sprintf(`{"match": {"buyer": "%s"}},{"exists": {"field": "s_winner"}},{"exists": {"field": "entidlist"}}`, name)
  181. }
  182. getData := elastic.Get(biddingIndex, biddingType, fmt.Sprintf(querySql, mustSql))
  183. if getData != nil && len(*getData) > 0 {
  184. queryMap := make(map[string]bool)
  185. if !isWinner { //采购关联企业 校验正确性
  186. for _, v := range *getData {
  187. for _, name := range gconv.Strings(v["entidlist"]) {
  188. queryMap[name] = true
  189. }
  190. }
  191. } else {
  192. for _, v := range *getData {
  193. for _, name := range gconv.Strings(v["buyer"]) {
  194. queryMap[name] = true
  195. }
  196. }
  197. }
  198. if len(queryMap) == 0 {
  199. return
  200. }
  201. var queryArr []string = make([]string, 0, len(queryMap))
  202. for name, _ := range queryMap {
  203. queryArr = append(queryArr, name)
  204. }
  205. var sql string
  206. if !isWinner {
  207. sql = fmt.Sprintf(`SELECT name,seo_id FROM global_common_data.dws_f_ent_baseinfo WHERE company_id in ("%s")`, strings.Join(queryArr, `","`))
  208. } else {
  209. sql = fmt.Sprintf(`SELECT name,seo_id FROM global_common_data.dws_f_ent_baseinfo WHERE name in ("%s")`, strings.Join(queryArr, `","`))
  210. }
  211. //根据采购单位名字或中标企业id查询seo_id
  212. dbRes, _ := g.DB("tidb").Query(ctx, sql)
  213. if dbRes.IsEmpty() {
  214. return
  215. }
  216. for _, m := range dbRes.List() {
  217. name, seo_id := gconv.String(m["name"]), gconv.String(m["seo_id"])
  218. if name == "" || seo_id == "" {
  219. continue
  220. }
  221. var url string
  222. if isWinner {
  223. url = fmt.Sprintf("/dw/%s.html", seo_id)
  224. } else {
  225. url = fmt.Sprintf("/qy/%s.html", seo_id)
  226. }
  227. data = append(data, map[string]interface{}{
  228. "name": name,
  229. "url": url,
  230. })
  231. }
  232. }
  233. return
  234. }()
  235. if !fromCache {
  236. _ = g.Redis().SetEX(ctx, redisKey, getFullArr, 60*60*24)
  237. }
  238. if len(getFullArr) > 10 { //大于10 随机取10个
  239. rand.Seed(time.Now().UnixNano())
  240. start := rand.Intn(len(getFullArr) - 10)
  241. randomMaps = getFullArr[start : start+10]
  242. }
  243. return
  244. }
  245. // RecommendedData 其他推荐
  246. // name 名称 province 省份 isWinner 来源是否中标企业画像 false 来源企业画像
  247. func (pwp *Enterprises) RecommendedData(ctx context.Context, name, province string, isWinner bool) (rData []map[string]interface{}) {
  248. if name == "" || province == "" || len(province) != 6 {
  249. return
  250. }
  251. redisKey := fmt.Sprintf("jyseo_portrait_recommended_%v_%s", isWinner, province)
  252. getFullArr, formCache := func() (data []map[string]interface{}, formCache bool) {
  253. data = []map[string]interface{}{}
  254. province = province[:2] + "0000"
  255. gVal, err := g.Redis().Get(ctx, redisKey)
  256. if err == nil && !gVal.IsNil() {
  257. if err := gVal.Struct(&data); err == nil {
  258. formCache = true
  259. return
  260. }
  261. }
  262. var sql string
  263. if isWinner {
  264. sql = fmt.Sprintf(`
  265. SELECT name,seo_id FROM global_common_data.dws_f_ent_baseinfo
  266. WHERE area_code = %s
  267. AND (identity_type & (1 << 1)) > 0
  268. ORDER BY latest_time desc limit 200
  269. `, province)
  270. } else {
  271. sql = fmt.Sprintf(`
  272. SELECT name,seo_id FROM global_common_data.dws_f_ent_baseinfo
  273. WHERE area_code = %s
  274. AND (identity_type &(1 << 0)) > 0
  275. ORDER BY latest_time desc limit 200
  276. `, province)
  277. }
  278. dbRes, _ := g.DB("tidb").Query(ctx, sql)
  279. if dbRes.IsEmpty() {
  280. return
  281. }
  282. for _, m := range dbRes.List() {
  283. name, seo_id := gconv.String(m["name"]), gconv.String(m["seo_id"])
  284. if name == "" || seo_id == "" {
  285. continue
  286. }
  287. var url string
  288. if isWinner {
  289. url = fmt.Sprintf("/qy/%s.html", seo_id)
  290. } else {
  291. url = fmt.Sprintf("/dw/%s.html", seo_id)
  292. }
  293. data = append(data, map[string]interface{}{
  294. "name": name,
  295. "url": url,
  296. })
  297. }
  298. return
  299. }()
  300. if !formCache {
  301. _ = g.Redis().SetEX(ctx, redisKey, getFullArr, 60*60*24)
  302. }
  303. if len(getFullArr) > 0 { //大于10 随机取10个
  304. if len(getFullArr) > 10 {
  305. rand.Seed(time.Now().UnixNano())
  306. start := rand.Intn(len(getFullArr) - 10)
  307. return getFullArr[start : start+10]
  308. }
  309. return getFullArr
  310. } else { //TODO 无数据从运行数据从取
  311. }
  312. return
  313. }
  314. func pareSelect(name string, isWinner, onlyCount bool) string {
  315. sYear := 2018
  316. //返回默认时间
  317. sTimeStamp := time.Date(sYear, 1, 1, 0, 0, 0, 0, time.Local)
  318. var (
  319. mustQueryArr []string
  320. fields string
  321. )
  322. if isWinner {
  323. fields = `"_id","projectname","bidamount","budget","title","publishtime","subtype","toptype","area","bidopentime","buyer"`
  324. mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, name))
  325. mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"publishtime":{"gte":"%d","lte":"%d"}}}`, sTimeStamp.Unix(), time.Now().Unix()))
  326. } else {
  327. fields = `"bidstatus","_id","title","subtype","projectname","publishtime","area","bidamount","budget","bidopentime","s_winner","entidlist"`
  328. mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"buyer":"%s"}}`, name))
  329. mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"publishtime":{"gte":"%d","lte":"%d"}}}`, sTimeStamp.Unix(), time.Now().Unix()))
  330. }
  331. if onlyCount {
  332. return fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), "")
  333. } else {
  334. return fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), fmt.Sprintf(`,"_source":[%s],"sort":{%s},"from":0,"size":30`, fields, `"publishtime":"desc","id":"desc"`))
  335. }
  336. }