user.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package service
  2. import (
  3. "context"
  4. "go-common/app/interface/bbq/app-bbq/api/http/v1"
  5. "go-common/app/interface/bbq/app-bbq/model"
  6. user "go-common/app/service/bbq/user/api"
  7. "go-common/library/ecode"
  8. "go-common/library/log"
  9. )
  10. // UserBase 获取用户信息
  11. func (s *Service) UserBase(c context.Context, mid int64) (res *v1.UserInfo, err error) {
  12. res = new(v1.UserInfo)
  13. var userInfos map[int64]*v1.UserInfo
  14. userInfos, err = s.dao.BatchUserInfo(c, mid, []int64{mid}, true, false, false)
  15. if err != nil {
  16. log.Errorv(c, log.KV("event", "user_base failed"), log.KV("err", err))
  17. err = ecode.GetUserBaseErr
  18. return
  19. }
  20. userInfo, exists := userInfos[mid]
  21. if exists && userInfo != nil {
  22. res = userInfo
  23. } else {
  24. log.Errorv(c, log.KV("event", "UserBase empty"), log.KV("err", err))
  25. err = ecode.GetUserBaseErr
  26. }
  27. return
  28. }
  29. //SpaceUserProfile ...
  30. func (s *Service) SpaceUserProfile(c context.Context, mid int64, upMid int64) (res *v1.UserInfo, err error) {
  31. if upMid == 0 {
  32. err = ecode.UPMIDNotExists
  33. return
  34. }
  35. res = &v1.UserInfo{}
  36. userInfos, err := s.dao.BatchUserInfo(c, mid, []int64{upMid}, true, true, true)
  37. if err != nil {
  38. log.Errorv(c, log.KV("event", "batch_user_info"), log.KV("err", err))
  39. return
  40. }
  41. res, exists := userInfos[upMid]
  42. if !exists {
  43. err = ecode.UPMIDNotExists
  44. log.Errorv(c, log.KV("event", "user_info_not_found"), log.KV("up_mid", upMid), log.KV("err", err))
  45. return
  46. }
  47. return
  48. }
  49. // UserEdit 完善用户信息
  50. // 该请求需要保证请求的mid已经存在,如果不存在,该接口会返回失败
  51. func (s *Service) UserEdit(c context.Context, userBase *user.UserBase) (res *v1.NumResponse, err error) {
  52. res = new(v1.NumResponse)
  53. if err = s.dao.EditUserBase(c, userBase); err != nil {
  54. return
  55. }
  56. return
  57. }
  58. //AddUserLike 点赞
  59. func (s *Service) AddUserLike(c context.Context, mid, svid int64) (res *v1.NumResponse, err error) {
  60. res = new(v1.NumResponse)
  61. var upMid, num int64
  62. videoBase, err := s.dao.VideoBase(c, mid, svid)
  63. if err != nil {
  64. log.Warnw(c, "log", "get video base fail", "svid", svid)
  65. return
  66. }
  67. upMid = videoBase.Mid
  68. likeNum, err := s.dao.AddLike(c, mid, upMid, svid)
  69. if err != nil {
  70. log.Warnv(c, log.KV("log", "add like fail"))
  71. return
  72. }
  73. if likeNum == 0 {
  74. log.Infow(c, "log", "repeated like", "mid", mid, "svid", svid)
  75. return
  76. }
  77. // TODO:考虑消息队列解耦等
  78. tx, err := s.dao.BeginTran(c)
  79. if err != nil {
  80. log.Error("add user like begin tran err(%v) mid(%d) svid(%d)", err, mid, svid)
  81. err = ecode.AddUserLikeErr
  82. return
  83. }
  84. if num, err = s.dao.TxIncrVideoStatisticsLike(tx, svid); err != nil {
  85. err = ecode.AddUserLikeErr
  86. tx.Rollback()
  87. return
  88. }
  89. if num == 0 {
  90. log.Errorw(c, "log", "incr video statistics fail maybe due to the missing in video_statistics table", "svid", svid)
  91. videoStatistics := &model.VideoStatistics{SVID: svid, Like: 1}
  92. if num, err = s.dao.TxAddVideoStatistics(tx, videoStatistics); err != nil || num == 0 {
  93. err = ecode.AddUserLikeErr
  94. tx.Rollback()
  95. return
  96. }
  97. res.Num = 1
  98. }
  99. tx.Commit()
  100. return
  101. }
  102. //CancelUserLike 取消点赞
  103. func (s *Service) CancelUserLike(c context.Context, mid, svid int64) (res *v1.NumResponse, err error) {
  104. res = new(v1.NumResponse)
  105. var upMid, num int64
  106. videoBase, err := s.dao.VideoBase(c, mid, svid)
  107. if ecode.IsCancelSvLikeAvailable(err) {
  108. err = nil
  109. log.Infow(c, "log", "allow cancel like when video unreachable", "svid", svid, "mid", mid)
  110. } else if err != nil {
  111. log.Warnw(c, "log", "get video base fail", "svid", svid)
  112. return
  113. }
  114. upMid = videoBase.Mid
  115. likeNum, err := s.dao.CancelLike(c, mid, upMid, svid)
  116. if err != nil {
  117. log.Warnv(c, log.KV("log", "cancel like fail"))
  118. return
  119. }
  120. if likeNum == 0 {
  121. log.Infow(c, "log", "repeated cancel like", "mid", mid, "svid", svid)
  122. return
  123. }
  124. tx, err := s.dao.BeginTran(c)
  125. if err != nil {
  126. log.Error("cancel user like begin tran err(%v) mid(%d) svid(%d)", err, mid, svid)
  127. err = ecode.CancelUserLikeErr
  128. return
  129. }
  130. if num, err = s.dao.TxDecrVideoStatisticsLike(tx, svid); err != nil {
  131. err = ecode.CancelUserLikeErr
  132. tx.Rollback()
  133. return
  134. }
  135. if num == 0 {
  136. log.Errorw(c, "log", "desc video statistics fail maybe due to the missing in video_statistics table", "svid", svid)
  137. videoStatistics := &model.VideoStatistics{SVID: svid, Like: 0}
  138. if num, err = s.dao.TxAddVideoStatistics(tx, videoStatistics); err != nil || num == 0 {
  139. err = ecode.AddUserLikeErr
  140. tx.Rollback()
  141. return
  142. }
  143. res.Num = 1
  144. }
  145. tx.Commit()
  146. return
  147. }
  148. // UserLikeList 用户点赞列表
  149. // TODO: 这段代码和SpaceSvList基本一样,后面抽出共同代码
  150. func (s *Service) UserLikeList(c context.Context, req *v1.SpaceSvListRequest) (res v1.SpaceSvListResponse, err error) {
  151. // 0.前期校验
  152. // 这里就不校验up主是否存在
  153. upMid := req.UpMid
  154. if upMid == 0 {
  155. err = ecode.ReqParamErr
  156. log.Errorv(c, log.KV("event", "req_param"), log.KV("up_mid", 0))
  157. return
  158. }
  159. res.List = make([]*v1.SvDetail, 0)
  160. // 1. 获取svid列表
  161. likeReply, err := s.dao.UserLikeList(c, upMid, req.CursorPrev, req.CursorNext)
  162. if err != nil {
  163. log.Errorv(c, log.KV("event", "user_like_list"), log.KV("error", err))
  164. return
  165. }
  166. res.HasMore = likeReply.HasMore
  167. var svids []int64
  168. // svid, LikeSv
  169. likeSvs := make(map[int64]*user.LikeSv)
  170. for _, likeSv := range likeReply.List {
  171. svids = append(svids, likeSv.Svid)
  172. likeSvs[likeSv.Svid] = likeSv
  173. }
  174. // 2.获取sv详情
  175. detailMap, err := s.getVideoDetail(c, req.MID, req.Qn, req.Device, svids, true)
  176. if err != nil {
  177. log.Warnv(c, log.KV("event", "get video detail fail"))
  178. return
  179. }
  180. for _, svID := range svids {
  181. item, exists := detailMap[svID]
  182. if !exists {
  183. item = new(v1.SvDetail)
  184. item.SVID = svID
  185. // TODO: 操蛋的客户端,这里等版本收敛之后可以删除
  186. item.IsLike = true
  187. item.Play.SVID = svID
  188. item.Play.FileInfo = []*v1.FileInfo{
  189. {},
  190. }
  191. item.Play.SupportQuality = make([]int64, 0)
  192. }
  193. if likeSv, exists := likeSvs[svID]; exists {
  194. item.CursorValue = likeSv.CursorValue
  195. }
  196. res.List = append(res.List, item)
  197. }
  198. return
  199. }
  200. // ModifyRelation 关注、取关、拉黑、取消拉黑
  201. func (s *Service) ModifyRelation(c context.Context, mid, upMid int64, action int32) (res *user.ModifyRelationReply, err error) {
  202. res, err = s.dao.ModifyRelation(c, mid, upMid, action)
  203. if err != nil {
  204. log.Warnv(c, log.KV("log", "modify reltaion fail"))
  205. }
  206. return
  207. }
  208. // UserFollowList 关注列表
  209. // 注意:这里出现3种mid,visitor/host/host关注的mid,按顺序缩写为V、H、HF,其中根据H获取HF,然后计算V和HF的关注关系
  210. func (s *Service) UserFollowList(c context.Context, req *user.ListRelationUserInfoReq) (res *v1.UserRelationListResponse, err error) {
  211. res, err = s.dao.UserRelationList(c, req, user.Follow)
  212. return
  213. }
  214. // UserFanList 粉丝列表
  215. func (s *Service) UserFanList(c context.Context, req *user.ListRelationUserInfoReq) (res *v1.UserRelationListResponse, err error) {
  216. res, err = s.dao.UserRelationList(c, req, user.Fan)
  217. return
  218. }
  219. // UserBlackList 黑名单列表
  220. func (s *Service) UserBlackList(c context.Context, req *user.ListRelationUserInfoReq) (res *v1.UserRelationListResponse, err error) {
  221. // 强制只能访问自己的拉黑名单
  222. req.UpMid = req.Mid
  223. res, err = s.dao.UserRelationList(c, req, user.Black)
  224. return
  225. }
  226. //Login .
  227. func (s *Service) Login(c context.Context, req *user.UserBase) (res *user.UserBase, err error) {
  228. res, err = s.dao.Login(c, req)
  229. return
  230. }
  231. //PhoneCheck ..
  232. func (s *Service) PhoneCheck(c context.Context, mid int64) (err error) {
  233. telStatus, err := s.dao.PhoneCheck(c, mid)
  234. if err != nil {
  235. return
  236. }
  237. if telStatus == 0 {
  238. err = ecode.BBQNoBindPhone
  239. return
  240. }
  241. return
  242. }