help.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. package dao
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "go-common/app/interface/main/web/model"
  10. "go-common/library/cache/redis"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. "go-common/library/time"
  14. )
  15. const (
  16. _notRobot = -1
  17. _rsOk = "000000"
  18. _hlKey = "hl_%s"
  19. _hdKey = "hd_%s_%d_%d_%d"
  20. )
  21. // HelpList get help list.
  22. func (d *Dao) HelpList(c context.Context, pTypeID string) (data []*model.HelpList, err error) {
  23. var (
  24. req *http.Request
  25. params = url.Values{}
  26. )
  27. params.Set("parentTypeId", pTypeID)
  28. params.Set("robotFlag", strconv.Itoa(_notRobot))
  29. listURL := d.helpListURL + "?" + params.Encode()
  30. if req, err = http.NewRequest("GET", listURL, nil); err != nil {
  31. log.Error("Help http.NewRequest(%s) error(%v)", listURL, err)
  32. return
  33. }
  34. var res struct {
  35. Code string `json:"retCode"`
  36. Data []*model.HelpList `json:"items"`
  37. }
  38. err = d.httpHelp.Do(c, req, &res)
  39. if err != nil {
  40. log.Error("Help d.httpHelp.Do(%s) error(%v)", listURL, err)
  41. return
  42. }
  43. if res.Code != _rsOk {
  44. log.Error("Help dao.httpHelp.Do(%s) error(%v)", listURL, err)
  45. err = ecode.HelpListError
  46. return
  47. }
  48. data = res.Data
  49. return
  50. }
  51. func keyHl(pTypeID string) string {
  52. return fmt.Sprintf(_hlKey, pTypeID)
  53. }
  54. func keyHd(qTypeID string, keyFlag, pn, ps int) string {
  55. return fmt.Sprintf(_hdKey, qTypeID, keyFlag, pn, ps)
  56. }
  57. // SetHlCache set help list to cache.
  58. func (d *Dao) SetHlCache(c context.Context, pTypeID string, Hl []*model.HelpList) (err error) {
  59. conn := d.redisBak.Get(c)
  60. defer conn.Close()
  61. count := 0
  62. key := keyHl(pTypeID)
  63. if err = conn.Send("DEL", key); err != nil {
  64. log.Error("conn.Send(DEL, %s) error(%v)", key, err)
  65. return
  66. }
  67. count++
  68. var bs []byte
  69. for _, list := range Hl {
  70. if bs, err = json.Marshal(list); err != nil {
  71. log.Error("json.Marshal(%v) error (%v)", list, err)
  72. return
  73. }
  74. if err = conn.Send("ZADD", key, list.SortNo, bs); err != nil {
  75. log.Error("conn.Send(ZADD, %s, %s) error(%v)", key, string(bs), err)
  76. return
  77. }
  78. count++
  79. }
  80. if err = conn.Send("EXPIRE", key, d.redisHelpBakExpire); err != nil {
  81. log.Error("conn.Send(Expire, %s, %d) error(%v)", key, d.redisHelpBakExpire, err)
  82. return
  83. }
  84. count++
  85. if err = conn.Flush(); err != nil {
  86. log.Error("conn.Flush error(%v)", err)
  87. return
  88. }
  89. for i := 0; i < count; i++ {
  90. if _, err = conn.Receive(); err != nil {
  91. log.Error("conn.Receive() error(%v)", err)
  92. return
  93. }
  94. }
  95. return
  96. }
  97. // HlCache get help list from cache.
  98. func (d *Dao) HlCache(c context.Context, pTypeID string) (res []*model.HelpList, err error) {
  99. key := keyHl(pTypeID)
  100. conn := d.redisBak.Get(c)
  101. defer conn.Close()
  102. values, err := redis.Values(conn.Do("ZREVRANGE", key, 0, -1))
  103. if err != nil {
  104. log.Error("conn.Do(ZREVRANGE, %s) error(%v)", key, err)
  105. return
  106. }
  107. if len(values) == 0 {
  108. return
  109. }
  110. if err = conn.Flush(); err != nil {
  111. log.Error("conn.Flush() err(%v)", err)
  112. return
  113. }
  114. for len(values) > 0 {
  115. bs := []byte{}
  116. if values, err = redis.Scan(values, &bs); err != nil {
  117. log.Error("redis.Scan(%v) error(%v)", values, err)
  118. return
  119. }
  120. list := &model.HelpList{}
  121. if err = json.Unmarshal(bs, list); err != nil {
  122. log.Error("json.Unmarshal(%v) error(%v)", bs, err)
  123. return
  124. }
  125. res = append(res, list)
  126. }
  127. return
  128. }
  129. // HelpDetail get help detail.
  130. func (d *Dao) HelpDetail(c context.Context, qTypeID string, keyFlag, pn, ps int, ip string) (data []*model.HelpDeatil, total int, err error) {
  131. var (
  132. req *http.Request
  133. params = url.Values{}
  134. )
  135. params.Set("questionTypeId", qTypeID)
  136. params.Set("keyFlag", strconv.Itoa(keyFlag))
  137. params.Set("keyWords", "")
  138. params.Set("pageNo", strconv.Itoa(pn))
  139. params.Set("pageSize", strconv.Itoa(ps))
  140. params.Set("robotFlag", strconv.Itoa(_notRobot))
  141. searchURL := d.helpSearchURL + "?" + params.Encode()
  142. if req, err = http.NewRequest("GET", searchURL, nil); err != nil {
  143. log.Error("Help http.NewRequest(%s) error(%v)", searchURL, err)
  144. return
  145. }
  146. var res struct {
  147. Code string `json:"retCode"`
  148. Data []*model.HelpDeatil `json:"items"`
  149. Total int `json:"totalCount"`
  150. }
  151. err = d.httpHelp.Do(c, req, &res)
  152. if err != nil {
  153. log.Error("Help d.httpHelp.Do(%s) error(%v)", searchURL, err)
  154. return
  155. }
  156. if res.Code != _rsOk {
  157. log.Error("Help dao.httpHelp.Do(%s) error(%v)", searchURL, err)
  158. err = ecode.HelpDetailError
  159. return
  160. }
  161. total = res.Total
  162. data = res.Data
  163. return
  164. }
  165. // HelpSearch get help search.
  166. func (d *Dao) HelpSearch(c context.Context, pTypeID, keyWords string, keyFlag, pn, ps int) (data []*model.HelpDeatil, total int, err error) {
  167. var (
  168. req *http.Request
  169. params = url.Values{}
  170. )
  171. params.Set("questionTypeId", pTypeID)
  172. params.Set("keyWords", keyWords)
  173. params.Set("keyFlag", strconv.Itoa(keyFlag))
  174. params.Set("pageNo", strconv.Itoa(pn))
  175. params.Set("pageSize", strconv.Itoa(ps))
  176. params.Set("robotFlag", strconv.Itoa(_notRobot))
  177. searchURL := d.helpSearchURL + "?" + params.Encode()
  178. if req, err = http.NewRequest("GET", searchURL, nil); err != nil {
  179. log.Error("Help http.NewRequest(%s) error(%v)", searchURL, err)
  180. return
  181. }
  182. var res struct {
  183. Code string `json:"retCode"`
  184. Data []*model.HelpDeatil `json:"items"`
  185. Total int `json:"totalCount"`
  186. }
  187. err = d.httpHelp.Do(c, req, &res)
  188. if err != nil {
  189. log.Error("Help d.httpHelp.Do(%s) error(%v)", searchURL, err)
  190. return
  191. }
  192. if res.Code != _rsOk {
  193. log.Error("Help dao.httpHelp.Do(%s) error(%v)", searchURL, err)
  194. err = ecode.HelpSearchError
  195. return
  196. }
  197. total = res.Total
  198. data = res.Data
  199. return
  200. }
  201. // SetDetailCache set help detail to cache.
  202. func (d *Dao) SetDetailCache(c context.Context, qTypeID string, keyFlag, pn, ps, total int, data []*model.HelpDeatil) (err error) {
  203. conn := d.redisBak.Get(c)
  204. defer conn.Close()
  205. count := 0
  206. key := keyHd(qTypeID, keyFlag, pn, ps)
  207. if err = conn.Send("DEL", key); err != nil {
  208. log.Error("conn.Send(DEL, %s) error(%v)", key, err)
  209. return
  210. }
  211. count++
  212. var bs []byte
  213. for _, detail := range data {
  214. if bs, err = json.Marshal(detail); err != nil {
  215. log.Error("json.Marshal(%v) error (%v)", detail, err)
  216. return
  217. }
  218. if err = conn.Send("ZADD", key, combineHd(detail.UpdateTime, total), bs); err != nil {
  219. log.Error("conn.Send(ZADD, %s, %s) error(%v)", key, string(bs), err)
  220. return
  221. }
  222. count++
  223. }
  224. if err = conn.Send("EXPIRE", key, d.redisHelpBakExpire); err != nil {
  225. log.Error("conn.Send(Expire, %s, %d) error(%v)", key, d.redisHelpBakExpire, err)
  226. return
  227. }
  228. count++
  229. if err = conn.Flush(); err != nil {
  230. log.Error("conn.Flush error(%v)", err)
  231. return
  232. }
  233. for i := 0; i < count; i++ {
  234. if _, err = conn.Receive(); err != nil {
  235. log.Error("conn.Receive() error(%v)", err)
  236. return
  237. }
  238. }
  239. return
  240. }
  241. // DetailCache get help detail to cache.
  242. func (d *Dao) DetailCache(c context.Context, qTypeID string, keyFlag, pn, ps int) (res []*model.HelpDeatil, count int, err error) {
  243. conn := d.redisBak.Get(c)
  244. defer conn.Close()
  245. key := keyHd(qTypeID, keyFlag, pn, ps)
  246. values, err := redis.Values(conn.Do("ZREVRANGE", key, 0, -1, "WITHSCORES"))
  247. if err != nil {
  248. log.Error("conn.Do(ZREVRANGE, %s) error(%v)", key, err)
  249. return
  250. }
  251. if len(values) == 0 {
  252. return
  253. }
  254. if err = conn.Flush(); err != nil {
  255. log.Error("conn.Flush() err(%v)", err)
  256. return
  257. }
  258. var num int64
  259. for len(values) > 0 {
  260. bs := []byte{}
  261. if values, err = redis.Scan(values, &bs, &num); err != nil {
  262. log.Error("redis.Scan(%v) error(%v)", values, err)
  263. return
  264. }
  265. detail := &model.HelpDeatil{}
  266. if err = json.Unmarshal(bs, detail); err != nil {
  267. log.Error("json.Unmarshal(%v) error(%v)", bs, err)
  268. return
  269. }
  270. res = append(res, detail)
  271. }
  272. count = fromHd(num)
  273. return
  274. }
  275. func fromHd(i int64) int {
  276. return int(i & 0xffff)
  277. }
  278. func combineHd(create time.Time, count int) int64 {
  279. return create.Time().Unix()<<16 | int64(count)
  280. }