queryStruct.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gogf/gf/v2/container/gvar"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gtime"
  8. "github.com/gogf/gf/v2/util/gconv"
  9. "jybxseo/internal/consts"
  10. "jybxseo/utility"
  11. "strings"
  12. )
  13. type (
  14. SeoBiddingQuery struct {
  15. status int
  16. keys string
  17. area string
  18. city string
  19. district string
  20. topType string
  21. subType string
  22. topClass string
  23. subClass string
  24. }
  25. InfoList struct {
  26. Title string
  27. Url string
  28. Area string
  29. City string
  30. Industry string
  31. Subtype string
  32. Price string
  33. Site string
  34. Detail string
  35. Keyword string
  36. FileExists bool
  37. PublishTime int64
  38. }
  39. ListResp struct {
  40. Total int
  41. List []*InfoList
  42. }
  43. )
  44. func NewBiddingQuery() *SeoBiddingQuery {
  45. return &SeoBiddingQuery{}
  46. }
  47. func (query *SeoBiddingQuery) QueryState(value int) *SeoBiddingQuery {
  48. if value > 0 {
  49. query.status = value
  50. }
  51. return query
  52. }
  53. // EquipArea 装备地区查询
  54. func (query *SeoBiddingQuery) EquipArea(areaNode *AreaNode) *SeoBiddingQuery {
  55. if areaNode.Type == 2 {
  56. query.city = areaNode.Name
  57. } else {
  58. query.area = areaNode.Name
  59. }
  60. return query
  61. }
  62. func (query *SeoBiddingQuery) EquipKeyWord(keyword string) *SeoBiddingQuery {
  63. query.keys = keyword
  64. return query
  65. }
  66. func (query *SeoBiddingQuery) EquipIndustry(topClass, subClass string) *SeoBiddingQuery {
  67. if topClass != "" {
  68. query.topClass = topClass
  69. }
  70. if subClass != "" {
  71. query.subClass = subClass
  72. }
  73. return query
  74. }
  75. func (query *SeoBiddingQuery) dataFormat(data []map[string]interface{}) (bList []*InfoList) {
  76. if len(data) > 0 {
  77. titleReduction := map[string]bool{}
  78. for _, v := range data {
  79. bl := &InfoList{
  80. Title: gconv.String(fmt.Sprintf("【%s】%s", consts.TopTypeMap[gconv.String(v["toptype"])], v["title"])),
  81. Url: fmt.Sprintf("/jybx/%s_%s.html", gtime.NewFromTimeStamp(gconv.Int64(v["publish_time"])).Format("20060102"), gconv.String(v["seo_id"])),
  82. Area: gconv.String(v["area"]),
  83. City: gconv.String(v["city"]),
  84. Subtype: gconv.String(v["subtype"]),
  85. Detail: gconv.String(v["desc"]),
  86. Keyword: gconv.String(v["keyword"]),
  87. }
  88. //重复标题加数字后缀
  89. if titleReduction[bl.Title] {
  90. continue
  91. }
  92. titleReduction[bl.Title] = true
  93. bl.PublishTime = gconv.Int64(v["publish_time"])
  94. if gconv.String(v["area"]) == "剑鱼信息发布平台" {
  95. bl.Site = "用户发布"
  96. }
  97. if industry := gconv.String(v["industry"]); industry != "" {
  98. bl.Industry = industry
  99. }
  100. if isValidFile, _ := v["isValidFile"].(bool); isValidFile {
  101. bl.FileExists = true
  102. }
  103. if budget := gconv.Float64(v["budget"]); budget > 0 {
  104. bl.Price = utility.ConversionMoney(v["budget"])
  105. } else if bidamount := gconv.Float64(v["bidamount"]); bidamount > 0 {
  106. bl.Price = utility.ConversionMoney(v["bidamount"])
  107. }
  108. bList = append(bList, bl)
  109. }
  110. }
  111. return
  112. }
  113. // getBidListCacheKey 获取列表缓存
  114. func (query *SeoBiddingQuery) getDataPageListCacheKey(pageNum, maxTotal int, flag string) string {
  115. return fmt.Sprintf("JybxSeoBidDataPageList_%s_%d_%d_%s_%s_%s_%s_%s_%s_%s_%s", flag, pageNum, maxTotal, query.keys, query.area, query.city, query.district, query.topType, query.subType, query.topClass, query.subClass)
  116. }
  117. // GetDataPageList 翻页列表页查询
  118. // 一次性查询全部信息,生成每页cache
  119. func (query *SeoBiddingQuery) GetDataPageList(ctx context.Context, pageNum, maxTotal int, flag string, getData func(context.Context, int, *SeoBiddingQuery) []map[string]interface{}) (res *ListResp, err error) {
  120. var vars *gvar.Var
  121. res = &ListResp{}
  122. vars, err = g.Redis().Get(ctx, query.getDataPageListCacheKey(pageNum, maxTotal, flag))
  123. if err != nil || vars.IsNil() {
  124. //并发限制
  125. if ok := utility.JySeoQueryListLimit.Limit(); !ok {
  126. err = fmt.Errorf("请求超时")
  127. return
  128. }
  129. defer utility.JySeoQueryListLimit.Reset()
  130. data := getData(ctx, maxTotal, query)
  131. formatData := query.dataFormat(data)
  132. count := len(formatData)
  133. if count > maxTotal {
  134. count = maxTotal
  135. }
  136. if data != nil && len(data) > 0 {
  137. totalPage := count / consts.SettingPageSize
  138. if count%consts.SettingPageSize != 0 {
  139. totalPage++
  140. }
  141. for i := 1; i <= gconv.Int(totalPage); i++ {
  142. start, end := (i-1)*consts.SettingPageSize, (i)*consts.SettingPageSize
  143. if end > count {
  144. end = count
  145. }
  146. pageTmp := &ListResp{
  147. Total: totalPage,
  148. List: formatData[start:end],
  149. }
  150. if i == pageNum {
  151. res = pageTmp
  152. }
  153. if err := g.Redis().SetEX(ctx, query.getDataPageListCacheKey(i, maxTotal, flag), pageTmp, consts.SettingBidCacheTime); err != nil {
  154. g.Log().Errorf(ctx, "第%d页数据 存储redis err:%v", err)
  155. }
  156. }
  157. }
  158. } else {
  159. err = vars.Struct(res)
  160. }
  161. return
  162. }
  163. // getTabDataCacheKey 获取列表缓存
  164. func (query *SeoBiddingQuery) getOnceDataCacheKey(total int, flag string) string {
  165. return fmt.Sprintf("JybxSeoBidDataOnceList_%s_%d_%s_%s_%s_%s_%s_%s_%s_%s", flag, total, query.keys, query.area, query.city, query.district, query.topType, query.subType, query.topClass, query.subClass)
  166. }
  167. // GetOnceData 获取数据
  168. func (query *SeoBiddingQuery) GetOnceData(ctx context.Context, total int, flag string, getData func(context.Context, int, *SeoBiddingQuery) []map[string]interface{}) (res []*InfoList, err error) {
  169. var vars *gvar.Var
  170. cacheKey := query.getOnceDataCacheKey(total, flag)
  171. vars, err = g.Redis().Get(ctx, cacheKey)
  172. if err != nil || vars.IsNil() {
  173. //并发限制
  174. if ok := utility.JySeoQueryTabLimit.Limit(); !ok {
  175. err = fmt.Errorf("请求超时")
  176. return
  177. }
  178. defer utility.JySeoQueryTabLimit.Reset()
  179. data := getData(ctx, total, query)
  180. if len(data) > total {
  181. data = data[:total]
  182. }
  183. if data != nil && len(data) > 0 {
  184. res = query.dataFormat(data)
  185. }
  186. if err := g.Redis().SetEX(ctx, cacheKey, res, consts.SettingBidCacheTime); err != nil {
  187. g.Log().Errorf(ctx, "GetOnceData 存储redis err:%v", err)
  188. }
  189. } else {
  190. err = vars.Struct(&res)
  191. }
  192. return
  193. }
  194. func FillingBiddingBaseFields(ctx context.Context, res []map[string]interface{}) []map[string]interface{} {
  195. bidIdStrings := make([]string, 0, len(res))
  196. for _, m := range res {
  197. if bidId := gconv.String(m["bid_id"]); bidId != "" {
  198. bidIdStrings = append(bidIdStrings, bidId)
  199. }
  200. }
  201. bidRes, _ := g.DB().Query(ctx, fmt.Sprintf(`SELECT * FROM jyseo.new_bidList WHERE bid_id IN ('%s')`, strings.Join(bidIdStrings, "','")))
  202. if bidRes.IsEmpty() {
  203. return nil
  204. }
  205. bidMap := map[string]map[string]interface{}{}
  206. for _, m := range bidRes.List() {
  207. if bidIdStr := gconv.String(m["bid_id"]); bidIdStr != "" {
  208. bidMap[bidIdStr] = m
  209. }
  210. }
  211. var finalArr []map[string]interface{}
  212. for i := 0; i < len(res); i++ {
  213. if tBid := gconv.String(res[i]["bid_id"]); tBid != "" && bidMap[tBid] != nil && len(bidMap[tBid]) > 0 {
  214. for k, v := range bidMap[tBid] {
  215. res[i][k] = v
  216. }
  217. finalArr = append(finalArr, res[i])
  218. }
  219. }
  220. return finalArr
  221. }