redpacket.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package admin
  2. import (
  3. "app/commons/core"
  4. "app/commons/i18n"
  5. "app/commons/model/entity"
  6. "app/commons/services"
  7. "app/telegram"
  8. "fmt"
  9. "github.com/gin-gonic/gin"
  10. "github.com/shopspring/decimal"
  11. )
  12. // SendRedPacketAdmin 管理端发送红包(不需要JWT,使用签名验证)
  13. func (s *Server) SendRedPacketAdmin(ctx *gin.Context) {
  14. c := s.FromContext(ctx)
  15. type request struct {
  16. GroupID string `json:"groupId" binding:"required"` // Telegram群组ID
  17. TotalAmount decimal.Decimal `json:"totalAmount" binding:"required"` // 红包总金额
  18. TotalCount int `json:"totalCount" binding:"required"` // 红包个数
  19. PacketType int `json:"packetType" binding:"required"` // 1=普通, 2=手气
  20. Symbol string `json:"symbol"` // 币种,默认VND
  21. BlessingWords string `json:"blessingWords"` // 祝福语
  22. ExpireMinutes int `json:"expireMinutes"` // 过期时间(分钟),默认10
  23. MaxGrabAmount decimal.Decimal `json:"maxGrabAmount"` // 单人最大可领取金额(0=不限制)
  24. Lang string `json:"lang"` // 消息语言: vi/id/en/zh
  25. }
  26. req := new(request)
  27. if err := c.ShouldBindBodyWithJSON(req); err != nil {
  28. c.Fail(fmt.Sprintf("参数错误: %v", err))
  29. return
  30. }
  31. // 参数验证
  32. if req.PacketType != 1 && req.PacketType != 2 {
  33. c.Fail("红包类型错误,必须是1(普通)或2(手气)")
  34. return
  35. }
  36. if req.TotalCount <= 0 || req.TotalCount > 100 {
  37. c.Fail("红包个数必须在1-100之间")
  38. return
  39. }
  40. if req.TotalAmount.LessThanOrEqual(decimal.Zero) {
  41. c.Fail("红包金额必须大于0")
  42. return
  43. }
  44. // 默认语言
  45. if req.Lang == "" {
  46. req.Lang = "vi"
  47. }
  48. // 默认币种(根据语言)
  49. if req.Symbol == "" {
  50. req.Symbol = i18n.DefaultSymbol(req.Lang)
  51. }
  52. // 默认祝福语(根据语言)
  53. if req.BlessingWords == "" {
  54. m := i18n.GetLang(req.Lang)
  55. if req.PacketType == 1 {
  56. req.BlessingWords = m.BlessingDefault1
  57. } else {
  58. req.BlessingWords = m.BlessingDefault2
  59. }
  60. }
  61. // 创建红包(使用管理员ID,这里简化处理用0)
  62. redPacketService := &services.RedPacketService{}
  63. packet, err := redPacketService.CreateRedPacket(
  64. 0, // 管理员发送,userId 为 0
  65. req.GroupID,
  66. req.PacketType,
  67. req.TotalAmount,
  68. req.TotalCount,
  69. req.Symbol,
  70. req.BlessingWords,
  71. req.ExpireMinutes,
  72. req.MaxGrabAmount,
  73. req.Lang,
  74. )
  75. if err != nil {
  76. core.Log.Errorf("创建红包失败: %v", err)
  77. c.Fail(fmt.Sprintf("创建红包失败: %v", err))
  78. return
  79. }
  80. // 发送到 Telegram 群组并保存消息ID
  81. adminName := i18n.GetLang(req.Lang).AdminName
  82. go func() {
  83. sendToTelegramAndSaveMsg(packet, adminName, req.ExpireMinutes, req.Lang)
  84. }()
  85. c.Resp(gin.H{
  86. "packetId": packet.Id,
  87. "packetNo": packet.PacketNo,
  88. "message": "红包发送成功",
  89. })
  90. }
  91. // sendToTelegramAndSaveMsg 发送红包到Telegram群组并保存消息ID
  92. func sendToTelegramAndSaveMsg(packet *entity.TgRedPacket, senderName string, expireMinutes int, lang string) {
  93. if packet == nil {
  94. return
  95. }
  96. // 调用 telegram 包的发送函数,获取返回的消息ID
  97. msgId := telegram.SendRedPacketToGroup(
  98. packet.GroupId,
  99. packet.PacketNo,
  100. senderName,
  101. packet.TotalAmount.InexactFloat64(),
  102. packet.TotalCount,
  103. packet.PacketType,
  104. packet.BlessingWords,
  105. expireMinutes,
  106. lang,
  107. packet.Symbol,
  108. )
  109. // 保存 Telegram 消息ID到红包记录(用于过期时编辑消息)
  110. if msgId > 0 {
  111. db := services.NewComService().DB()
  112. db.Model(&entity.TgRedPacket{}).Where("id = ?", packet.Id).Update("message_id", msgId)
  113. core.Log.Infof("红包已发送到Telegram群组 - PacketNo: %s, GroupID: %s, MessageID: %d",
  114. packet.PacketNo, packet.GroupId, msgId)
  115. } else {
  116. core.Log.Infof("红包已发送到Telegram群组 - PacketNo: %s, GroupID: %s (未获取到消息ID)",
  117. packet.PacketNo, packet.GroupId)
  118. }
  119. }