tvvip.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. package http
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. "go-common/app/interface/main/tv/conf"
  7. tvmdl "go-common/app/interface/main/tv/model/tvvip"
  8. "go-common/library/ecode"
  9. "go-common/library/log"
  10. bm "go-common/library/net/http/blademaster"
  11. "go-common/library/net/http/blademaster/binding"
  12. "go-common/library/net/http/blademaster/render"
  13. "go-common/library/net/metadata"
  14. )
  15. const (
  16. userAgentWechat = "MicroMessenger"
  17. userAgentAliPay = "AlipayClient"
  18. userAgentIphone = "iPhone"
  19. userAgentIpad = "iPad"
  20. agentAndroid = "Android"
  21. platformAndroid = 1
  22. platformIos = 3
  23. platformOther = 4
  24. errPageURL = "https://www.bilibili.com/blackboard/activity-kWDq8R7f6R.html?code=%d"
  25. errOrderInvalid = 93018
  26. errQrDeviceUnsupported = 93019
  27. errOrderUnknownErr = 93020
  28. errPanelErr = 93021
  29. errBuyRateExceededErr = 93022
  30. ystErrBadRequest = "93030"
  31. ystErrNotFound = "93031"
  32. ystErrInternalErr = "93032"
  33. )
  34. func ystErrResp(result string, msg string) map[string]interface{} {
  35. return map[string]interface{}{
  36. "result": result,
  37. "msg": msg,
  38. }
  39. }
  40. func ystRender(ctx *bm.Context, data map[string]interface{}) {
  41. ctx.Render(http.StatusOK, render.MapJSON(data))
  42. }
  43. func errPage(err error) string {
  44. if ecode.EqualError(ecode.TVIPQrDevideUnsupported, err) {
  45. return fmt.Sprintf(errPageURL, errQrDeviceUnsupported)
  46. }
  47. if ecode.EqualError(ecode.TVIPTokenErr, err) {
  48. return fmt.Sprintf(errPageURL, errOrderInvalid)
  49. }
  50. if ecode.EqualError(ecode.TVIPTokenExpire, err) {
  51. return fmt.Sprintf(errPageURL, errOrderInvalid)
  52. }
  53. if ecode.EqualError(ecode.TVIPDupOrderNo, err) {
  54. return fmt.Sprintf(errPageURL, errOrderInvalid)
  55. }
  56. if ecode.EqualError(ecode.TVIPPanelNotSuitalbe, err) {
  57. return fmt.Sprintf(errPageURL, errPanelErr)
  58. }
  59. if ecode.EqualError(ecode.TVIPPanelNotFound, err) {
  60. return fmt.Sprintf(errPageURL, errPanelErr)
  61. }
  62. if ecode.EqualError(ecode.TVIPBuyNumExceeded, err) {
  63. return fmt.Sprintf(errPageURL, errPanelErr)
  64. }
  65. if ecode.EqualError(ecode.TVIPBuyRateExceeded, err) {
  66. return fmt.Sprintf(errPageURL, errBuyRateExceededErr)
  67. }
  68. if ecode.EqualError(ecode.TVIPMVipRateExceeded, err) {
  69. return fmt.Sprintf(errPageURL, errBuyRateExceededErr)
  70. }
  71. log.Error("errPage(%+v) err(UnExpectedErr)", err)
  72. return fmt.Sprintf(errPageURL, errOrderUnknownErr)
  73. }
  74. func payTypeFromUA(ctx *bm.Context) (payType string, err error) {
  75. ua := ctx.Request.UserAgent()
  76. if strings.Contains(ua, userAgentWechat) {
  77. return "", ecode.TVIPQrDevideUnsupported
  78. //return "wechat", nil
  79. } else if strings.Contains(ua, userAgentAliPay) {
  80. return "alipay", nil
  81. } else {
  82. return "", ecode.TVIPQrDevideUnsupported
  83. }
  84. }
  85. func platformFromUA(ctx *bm.Context) (platform int8, err error) {
  86. ua := ctx.Request.UserAgent()
  87. if strings.Contains(ua, userAgentIpad) {
  88. return platformIos, nil
  89. } else if strings.Contains(ua, userAgentIphone) {
  90. return platformIos, nil
  91. } else if strings.Contains(ua, agentAndroid) {
  92. return platformAndroid, nil
  93. }
  94. return platformOther, nil
  95. }
  96. func isIpValid(ip string) bool {
  97. log.Info("ip: %s ipWhiteList: %+v", ip, conf.Conf.IP.White.TvVip)
  98. if len(conf.Conf.IP.White.TvVip) == 0 {
  99. return true
  100. }
  101. for _, wip := range conf.Conf.IP.White.TvVip {
  102. if wip == ip {
  103. return true
  104. }
  105. }
  106. return false
  107. }
  108. // VipInfo implementation
  109. func vipInfo(ctx *bm.Context) {
  110. mid, ok := ctx.Get("mid")
  111. if !ok {
  112. ctx.JSON(nil, ecode.NoLogin)
  113. return
  114. }
  115. ctx.JSON(tvVipSvc.VipInfo(ctx, mid.(int64)))
  116. }
  117. // ystVipInfo implementation
  118. func ystVipInfo(ctx *bm.Context) {
  119. req := new(tvmdl.YstUserInfoReq)
  120. if err := ctx.BindWith(req, binding.Query); err != nil {
  121. ystRender(ctx, ystErrResp(ystErrBadRequest, err.Error()))
  122. return
  123. }
  124. res, err := tvVipSvc.YstVipInfo(ctx, req.Mid, req.Sign)
  125. if err != nil && ecode.EqualError(ecode.NothingFound, err) {
  126. ystRender(ctx, ystErrResp(ystErrNotFound, err.Error()))
  127. return
  128. }
  129. if err != nil && ecode.EqualError(ecode.TVIPSignErr, err) {
  130. ystRender(ctx, ystErrResp(ystErrBadRequest, "SignErr"))
  131. return
  132. }
  133. if err != nil {
  134. ystRender(ctx, ystErrResp(ystErrInternalErr, err.Error()))
  135. return
  136. }
  137. data := map[string]interface{}{
  138. "mid": res.Mid,
  139. "status": res.Status,
  140. "overdue_time": res.OverdueTime,
  141. "pay_channel_id": res.PayChannelId,
  142. "vip_type": res.VipType,
  143. "pay_type": res.PayType,
  144. "result": res.Result,
  145. "msg": res.Msg,
  146. }
  147. ctx.Render(http.StatusOK, render.MapJSON(data))
  148. }
  149. // PanelInfo .
  150. func panelInfo(ctx *bm.Context) {
  151. mid, ok := ctx.Get("mid")
  152. if !ok {
  153. ctx.JSON(nil, ecode.NoLogin)
  154. return
  155. }
  156. res, err := tvVipSvc.PanelInfo(ctx, mid.(int64))
  157. if err != nil {
  158. ctx.JSON(nil, err)
  159. return
  160. }
  161. ctx.JSON(res.PriceConfigs, err)
  162. }
  163. func guestPanelInfo(ctx *bm.Context) {
  164. res, err := tvVipSvc.GuestPanelInfo(ctx)
  165. if err != nil {
  166. ctx.JSON(nil, err)
  167. return
  168. }
  169. ctx.JSON(res.PriceConfigs, err)
  170. }
  171. func createQr(ctx *bm.Context) {
  172. req := new(tvmdl.CreateQrReq)
  173. if err := ctx.Bind(req); err != nil {
  174. ctx.JSON(nil, err)
  175. return
  176. }
  177. if req.AppChannel == "" {
  178. log.Warn("createQr(%+v), msg(EmptyAppChannel)", req)
  179. }
  180. buvid := ctx.Request.Header.Get("buvid")
  181. if buvid == "" {
  182. ctx.JSON(nil, ecode.RequestErr)
  183. return
  184. }
  185. req.Guid = buvid
  186. res, err := tvVipSvc.CreateQr(ctx, req)
  187. ctx.JSON(res, err)
  188. }
  189. func createGuestQr(ctx *bm.Context) {
  190. req := new(tvmdl.CreateGuestQrReq)
  191. if err := ctx.Bind(req); err != nil {
  192. ctx.JSON(nil, err)
  193. return
  194. }
  195. if req.AppChannel == "" {
  196. log.Warn("createQr(%+v), msg(EmptyAppChannel)", req)
  197. }
  198. buvid := ctx.Request.Header.Get("buvid")
  199. if buvid == "" {
  200. ctx.JSON(nil, ecode.RequestErr)
  201. return
  202. }
  203. req.Guid = buvid
  204. res, err := tvVipSvc.CreateGuestQr(ctx, req)
  205. ctx.JSON(res, err)
  206. }
  207. func createOrder(ctx *bm.Context) {
  208. var (
  209. err error
  210. )
  211. req := new(tvmdl.CreateOrderReq)
  212. if err = ctx.Bind(req); err != nil {
  213. ctx.JSON(nil, err)
  214. return
  215. }
  216. if req.Platform, err = platformFromUA(ctx); err != nil {
  217. ctx.JSON(nil, ecode.RequestErr)
  218. return
  219. }
  220. if req.PaymentType, err = payTypeFromUA(ctx); err != nil {
  221. ctx.Redirect(302, errPage(err))
  222. return
  223. }
  224. ip := metadata.String(ctx, metadata.RemoteIP)
  225. if ip == "" {
  226. ctx.JSON(nil, ecode.RequestErr)
  227. return
  228. }
  229. res, err := tvVipSvc.CreateOrder(ctx, ip, req)
  230. if err != nil {
  231. ctx.Redirect(302, errPage(err))
  232. return
  233. }
  234. ctx.Redirect(302, res.CodeUrl)
  235. }
  236. func createGuestOrder(ctx *bm.Context) {
  237. var (
  238. err error
  239. )
  240. mid, ok := ctx.Get("mid")
  241. if !ok {
  242. ctx.JSON(nil, ecode.NoLogin)
  243. return
  244. }
  245. req := new(tvmdl.CreateGuestOrderReq)
  246. if err = ctx.Bind(req); err != nil {
  247. ctx.JSON(nil, err)
  248. return
  249. }
  250. if req.Platform, err = platformFromUA(ctx); err != nil {
  251. ctx.JSON(nil, ecode.RequestErr)
  252. return
  253. }
  254. if req.PaymentType, err = payTypeFromUA(ctx); err != nil {
  255. ctx.Redirect(302, errPage(err))
  256. return
  257. }
  258. ip := metadata.String(ctx, metadata.RemoteIP)
  259. if ip == "" {
  260. ctx.JSON(nil, ecode.RequestErr)
  261. return
  262. }
  263. res, err := tvVipSvc.CreateGuestOrder(ctx, mid.(int64), ip, req)
  264. if err != nil {
  265. ctx.Redirect(302, errPage(err))
  266. return
  267. }
  268. ctx.Redirect(302, res.CodeUrl)
  269. }
  270. func tokenStatus(ctx *bm.Context) {
  271. query := ctx.Request.URL.Query()
  272. tokens := query["token"]
  273. res, err := tvVipSvc.TokenInfo(ctx, tokens)
  274. if err != nil {
  275. ctx.JSON(nil, err)
  276. return
  277. }
  278. ctx.JSON(res.Tokens, err)
  279. }
  280. func payCallback(ctx *bm.Context) {
  281. ip := metadata.String(ctx, metadata.RemoteIP)
  282. if !isIpValid(ip) {
  283. log.Error("payCallback(%s) err(InvalidIP)", ip)
  284. ystRender(ctx, ystErrResp(ystErrBadRequest, "InvalidIP"))
  285. return
  286. }
  287. req := new(tvmdl.YstPayCallbackReq)
  288. if err := ctx.BindWith(req, binding.JSON); err != nil {
  289. ystRender(ctx, ystErrResp(ystErrBadRequest, err.Error()))
  290. return
  291. }
  292. res := tvVipSvc.PayCallback(ctx, req)
  293. data := map[string]interface{}{
  294. "traceno": res.TraceNo,
  295. "result": res.Result,
  296. "msg": res.Msg,
  297. }
  298. ystRender(ctx, data)
  299. }
  300. func wxContractCallback(ctx *bm.Context) {
  301. req := new(tvmdl.WxContractCallbackReq)
  302. if err := ctx.BindWith(req, binding.JSON); err != nil {
  303. ystRender(ctx, ystErrResp(ystErrBadRequest, err.Error()))
  304. return
  305. }
  306. res := tvVipSvc.WxContractCallback(ctx, req)
  307. data := map[string]interface{}{
  308. "contract_id": res.ContractId,
  309. "result": res.Result,
  310. "msg": res.Msg,
  311. }
  312. ystRender(ctx, data)
  313. }