controller.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. package hall
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/public"
  5. "bet24.com/redis"
  6. "bet24.com/servers/common"
  7. "bet24.com/servers/coreservice/client"
  8. "bet24.com/servers/coreservice/shop"
  9. audioroom "bet24.com/servers/micros/audioroom/proto"
  10. dotservice "bet24.com/servers/micros/dotservice/proto"
  11. game "bet24.com/servers/micros/game/proto"
  12. item "bet24.com/servers/micros/item_inventory/proto"
  13. notification "bet24.com/servers/micros/notification/proto"
  14. userservices "bet24.com/servers/micros/userservices/proto"
  15. "bet24.com/servers/payment/config"
  16. "bet24.com/servers/transaction"
  17. "context"
  18. "encoding/json"
  19. "fmt"
  20. "github.com/gin-gonic/gin"
  21. "image"
  22. "math/rand"
  23. "net/http"
  24. "os"
  25. "strconv"
  26. "strings"
  27. "time"
  28. )
  29. // H5注册
  30. func Register(c *gin.Context) {
  31. var req register_req
  32. if err := c.ShouldBind(&req); err != nil {
  33. log.Debug("%s shouldBind err %v", "hall.Register", err)
  34. return
  35. }
  36. var (
  37. ret struct {
  38. RetCode int
  39. Items []item.ItemPack
  40. }
  41. info struct {
  42. Name string `json:"name"`
  43. Id string `json:"id"`
  44. }
  45. )
  46. id := strings.ReplaceAll(req.IMei, "fb.", "")
  47. // 去校验
  48. url := fmt.Sprintf("https://graph.facebook.com/%s?access_token=%s", id, req.AccessToken)
  49. respData := public.HttpGet(url)
  50. if err := json.Unmarshal([]byte(respData), &info); err != nil {
  51. log.Error("hall.Register respData=%s unmarshal err %v", respData, err)
  52. ret.RetCode = 15
  53. c.JSON(http.StatusOK, ret)
  54. return
  55. }
  56. log.Debug("hall.Register respData ==> %s", respData)
  57. // 校验失败
  58. if info.Name != req.NickName {
  59. ret.RetCode = 15
  60. c.JSON(http.StatusOK, ret)
  61. return
  62. }
  63. req.IpAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  64. regResp := register(req)
  65. // 注册成功
  66. if regResp.RetCode == 1 && regResp.UserID > 0 {
  67. // 去绑定师徒
  68. resp := client.BindTeacher(regResp.UserID, req.TeacherID, 1)
  69. if resp.RetCode == 1 {
  70. if err := json.Unmarshal([]byte(resp.Data), &ret); err != nil {
  71. log.Error("hall.Register unmarshal err %v", err)
  72. }
  73. }
  74. }
  75. c.JSON(http.StatusOK, ret)
  76. return
  77. }
  78. // 绑定代理
  79. func Bind(c *gin.Context) {
  80. var req register_req
  81. if err := c.ShouldBind(&req); err != nil {
  82. log.Debug("%s shouldBind err %v", "hall.Bind", err)
  83. return
  84. }
  85. var ret struct {
  86. RetCode int
  87. Items []item.ItemPack
  88. }
  89. if strings.HasPrefix(req.IMei, "fb.") {
  90. // facebook校验
  91. if ok := verifyFacebook(req.IMei, req.NickName, req.AccessToken); ok {
  92. ret.RetCode = 1
  93. }
  94. } else if strings.HasPrefix(req.IMei, "gg.") {
  95. // google校验
  96. if ok := verifyGoogle(req.NickName, req.AccessToken); ok {
  97. ret.RetCode = 1
  98. }
  99. }
  100. // 验证失败
  101. if ret.RetCode != 1 {
  102. ret.RetCode = 15
  103. c.JSON(http.StatusOK, ret)
  104. return
  105. }
  106. req.IpAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  107. regResp := register(req)
  108. // 注册成功
  109. if regResp.RetCode == 1 && regResp.UserID > 0 {
  110. // 去绑定师徒
  111. resp := client.AgentBind(regResp.UserID, req.TeacherID, req.IpAddress)
  112. if resp.RetCode == 1 {
  113. if err := json.Unmarshal([]byte(resp.Data), &ret); err != nil {
  114. log.Error("hall.Bind unmarshal err %v", err)
  115. }
  116. }
  117. }
  118. c.JSON(http.StatusOK, ret)
  119. return
  120. }
  121. // facebook 验证
  122. func verifyFacebook(iMei, nickName, accessToken string) bool {
  123. var info struct {
  124. Name string `json:"name"`
  125. Id string `json:"id"`
  126. }
  127. id := strings.ReplaceAll(iMei, "fb.", "")
  128. // 去校验
  129. url := fmt.Sprintf("https://graph.facebook.com/%s?access_token=%s", id, accessToken)
  130. respData := public.HttpGet(url)
  131. log.Debug("hall.verifyFacebook respData ==> %s", respData)
  132. if err := json.Unmarshal([]byte(respData), &info); err != nil {
  133. log.Error("hall.verifyFacebook respData=%s unmarshal err %v", respData, err)
  134. return false
  135. }
  136. // 校验失败
  137. if info.Name != nickName {
  138. return false
  139. }
  140. return true
  141. }
  142. // google 验证
  143. func verifyGoogle(nickName, accessToken string) bool {
  144. var info struct {
  145. Name string `json:"name"`
  146. Id string `json:"id"`
  147. }
  148. // 去校验
  149. // url := fmt.Sprintf("https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=%s", accessToken)
  150. url := fmt.Sprintf("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=%s", accessToken)
  151. respData := public.HttpGet(url)
  152. log.Debug("hall.verifyGoogle respData ==> %s", respData)
  153. if err := json.Unmarshal([]byte(respData), &info); err != nil {
  154. log.Error("hall.verifyGoogle respData=%s unmarshal err %v", respData, err)
  155. return false
  156. }
  157. // 校验失败
  158. if info.Name != nickName {
  159. return false
  160. }
  161. return true
  162. }
  163. // 币种列表
  164. func GetExchangeRateList(c *gin.Context) {
  165. resp := client.GetExchangeRateList()
  166. if resp.RetCode != 1 {
  167. c.JSON(http.StatusOK, "")
  168. return
  169. }
  170. c.String(http.StatusOK, resp.Data)
  171. return
  172. }
  173. // 商城列表
  174. func GetShopList(c *gin.Context) {
  175. var req struct {
  176. Currency string
  177. }
  178. if err := c.ShouldBind(&req); err != nil {
  179. log.Debug("%s shouldBind err %v", "hall.GetShopList", err)
  180. return
  181. }
  182. if req.Currency == "" {
  183. req.Currency = "EGP"
  184. }
  185. resp := client.GetShopList(0, shop.ShopType_Web, "")
  186. if resp.RetCode != 1 {
  187. c.JSON(http.StatusOK, "")
  188. return
  189. }
  190. c.String(http.StatusOK, resp.Data)
  191. return
  192. }
  193. // 用户信息
  194. func GetUserInfo(c *gin.Context) {
  195. var req struct {
  196. UserID int
  197. }
  198. if err := c.ShouldBind(&req); err != nil {
  199. log.Debug("%s shouldBind err %v", "hall.GetUserInfo", err)
  200. return
  201. }
  202. if req.UserID <= 0 {
  203. c.String(http.StatusOK, "fail")
  204. return
  205. }
  206. resp := userservices.GetUserInfo(req.UserID)
  207. d, _ := json.Marshal(resp)
  208. c.String(http.StatusOK, string(d))
  209. return
  210. }
  211. func IsInReview(c *gin.Context) {
  212. var req struct {
  213. VersionCode int
  214. PartnerId int
  215. }
  216. if err := c.ShouldBind(&req); err != nil {
  217. log.Debug("%s shouldBind err %v", "hall.IsInReview", err)
  218. return
  219. }
  220. reviewGame := ""
  221. done := make(chan int)
  222. go func() {
  223. reviewGame = game.GetReviewGame(c.ClientIP(), req.PartnerId, req.VersionCode)
  224. done <- 1
  225. }()
  226. ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
  227. select {
  228. case <-done:
  229. cancel()
  230. break
  231. case <-ctx.Done():
  232. log.Release("game.GetReviewGame timeout")
  233. cancel()
  234. break
  235. }
  236. // 打点
  237. go dotservice.AddDot(0, dotservice.DotScope{
  238. Scene: dotservice.Scene_HotUpdate,
  239. Action: dotservice.Action_Click,
  240. Extra: strconv.Itoa(common.GetTimeStamp()),
  241. IpAddress: c.ClientIP(),
  242. })
  243. c.String(http.StatusOK, reviewGame)
  244. return
  245. }
  246. func checkSection(userID int, token string) bool {
  247. if token == "" {
  248. return false
  249. }
  250. sectionKey := getSectionKey(userID)
  251. t, ok := redis.String_Get(sectionKey)
  252. if !ok {
  253. log.Release("redis error")
  254. return false
  255. }
  256. if t != token {
  257. return false
  258. }
  259. // 刷新有效期
  260. redis.String_SetEx(sectionKey, t, 1800)
  261. return true
  262. }
  263. func getSectionKey(userID int) string {
  264. return fmt.Sprintf("Section:%d", userID)
  265. }
  266. func getImageFormat(filename string) string {
  267. f, err := os.Open(filename)
  268. if err != nil {
  269. return ""
  270. }
  271. defer f.Close()
  272. _, format, err := image.Decode(f)
  273. if err != nil {
  274. return ""
  275. }
  276. return format
  277. }
  278. func isImageFile(fileName string) bool {
  279. f := getImageFormat(fileName)
  280. return f == "jpeg" || f == "png"
  281. }
  282. func deleteUserFace(userId int) {
  283. faceUrl := userservices.GetUserFaceUrl(userId)
  284. if faceUrl == "" {
  285. return
  286. }
  287. if !strings.HasPrefix(faceUrl, config.Server.UploadUrl) {
  288. return
  289. }
  290. fileName := strings.ReplaceAll(faceUrl, config.Server.UploadUrl, "")
  291. fileName = fmt.Sprintf("%s%s", config.Server.UploadDir, fileName)
  292. log.Debug("deleteUserFace %s", fileName)
  293. os.Remove(fileName)
  294. }
  295. func deleteUserRoomIamage(userId int) {
  296. roomUrl := audioroom.OnAudioRoomMsg(userId, "AudioRoomGetRoomImg", "")
  297. if roomUrl == "" {
  298. return
  299. }
  300. // 如果是头像复制的
  301. if strings.Contains(roomUrl, "user") {
  302. return
  303. }
  304. if !strings.HasPrefix(roomUrl, config.Server.UploadUrl) {
  305. return
  306. }
  307. fileName := strings.ReplaceAll(roomUrl, config.Server.UploadUrl, "")
  308. fileName = fmt.Sprintf("%s%s", config.Server.UploadDir, fileName)
  309. log.Debug("deleteUserRoomIamage %s", fileName)
  310. os.Remove(fileName)
  311. }
  312. func UploadFile(c *gin.Context) {
  313. _, err := c.MultipartForm()
  314. if err != nil {
  315. log.Debug("UploadFile failed MultipartForm %v", err)
  316. c.String(http.StatusBadRequest, "Bad request")
  317. return
  318. }
  319. log.Debug("headers %v", c.Request.Header)
  320. // 获得token
  321. token, ok := c.Request.Header["Authorization"]
  322. if !ok {
  323. log.Debug("UploadFile no Authorization")
  324. c.String(http.StatusBadRequest, "Bad request")
  325. return
  326. }
  327. var userToken UserToken
  328. err = json.Unmarshal([]byte(token[0]), &userToken)
  329. if err != nil {
  330. log.Debug("UploadFile failed usertoken %v", err)
  331. c.String(http.StatusBadRequest, "Bad request")
  332. return
  333. }
  334. log.Debug("UploadFile UserId :%d token :%s", userToken.UserId, userToken.Token)
  335. // 校验token
  336. if !checkSection(userToken.UserId, userToken.Token) {
  337. log.Debug("UploadFile failed checkSection failed")
  338. c.String(http.StatusBadRequest, "Bad request")
  339. return
  340. }
  341. file, err := c.FormFile("fileName")
  342. if err != nil {
  343. log.Debug("UploadFile failed %v", err)
  344. c.String(http.StatusBadRequest, "Bad request")
  345. return
  346. }
  347. tmpFileName := fmt.Sprintf("temp/%d_%s", userToken.UserId, file.Filename)
  348. log.Debug("UploadFile UserId :%d file save to :%s", userToken.UserId, tmpFileName)
  349. // Save the file to disk
  350. err = c.SaveUploadedFile(file, tmpFileName)
  351. if err != nil {
  352. c.String(http.StatusInternalServerError, "Internal server error")
  353. log.Debug("UploadFile save to file %s error %v", tmpFileName, err)
  354. return
  355. }
  356. /*format := getImageFormat(tmpFileName)
  357. if format != "jpeg" && format != "png" {
  358. c.String(http.StatusInternalServerError, "Internal server error")
  359. log.Debug("UploadFile checkIsImageFormat %s failed format[%s]", tmpFileName, format)
  360. os.Remove(tmpFileName)
  361. return
  362. }*/
  363. isRoomImage := strings.Contains(file.Filename, "roomImage")
  364. var faceFile string
  365. // 找出玩家之前头像,尝试删除
  366. if isRoomImage {
  367. log.Debug("UploadFile UserId :%d file is roomImage", userToken.UserId)
  368. deleteUserRoomIamage(userToken.UserId)
  369. faceFile = fmt.Sprintf("%d_roomImage_%d.jpg", userToken.UserId, rand.Intn(10000))
  370. } else {
  371. deleteUserFace(userToken.UserId)
  372. faceFile = fmt.Sprintf("%d_face_%d.jpg", userToken.UserId, rand.Intn(10000))
  373. }
  374. finalFileName := fmt.Sprintf("%s/%s", config.Server.UploadDir, faceFile)
  375. os.Rename(tmpFileName, finalFileName)
  376. url := fmt.Sprintf("%s/%s", config.Server.UploadUrl, faceFile)
  377. // update db
  378. if !isRoomImage {
  379. if transaction.ChangeUserFace(userToken.UserId, -1, url) {
  380. log.Debug("UploadFile changed user[%d] face[%s]", userToken.UserId, url)
  381. notification.AddNotification(userToken.UserId, notification.Notification_UserInfoChanged, fmt.Sprintf(`{"FaceUrl":"%s"}`, url))
  382. // 刷新coreservice中的用户信息
  383. userservices.UpdateUserInfo(userToken.UserId)
  384. }
  385. } else {
  386. audioroom.OnAudioRoomMsg(userToken.UserId, "updateRoomImg", url)
  387. notification.AddNotification(userToken.UserId, notification.Notification_RoomImageChanged, fmt.Sprintf(`{"RoomImageUrl":"%s"}`, url))
  388. }
  389. c.String(http.StatusOK, "File uploaded successfully")
  390. }
  391. func Feedback(c *gin.Context) {
  392. var req struct {
  393. Email string
  394. Msg string
  395. }
  396. if err := c.ShouldBind(&req); err != nil {
  397. log.Debug("%s shouldBind err %v", "hall.Feedback", err)
  398. return
  399. }
  400. if req.Email == "" || req.Msg == "" {
  401. c.String(http.StatusBadRequest, "failed")
  402. return
  403. }
  404. obj := transaction.NewFeedback()
  405. obj.In.IPAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  406. obj.In.Email = req.Email
  407. obj.In.Msg = req.Msg
  408. obj.DoAction()
  409. c.String(http.StatusOK, "ok")
  410. }