459 lines
11 KiB
Go
459 lines
11 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"goalfymax-admin/internal/config"
|
|
"goalfymax-admin/internal/models"
|
|
"goalfymax-admin/internal/services"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type InviteCodeHandler struct {
|
|
service services.InviteCodeService
|
|
userLevelService services.UserLevelConfigService
|
|
}
|
|
|
|
func NewInviteCodeHandler(service services.InviteCodeService, userLevelService services.UserLevelConfigService) *InviteCodeHandler {
|
|
return &InviteCodeHandler{
|
|
service: service,
|
|
userLevelService: userLevelService,
|
|
}
|
|
}
|
|
|
|
// GetInviteCodeList 获取邀请码列表
|
|
func (h *InviteCodeHandler) GetInviteCodeList(c *gin.Context) {
|
|
var req models.InviteCodeListRequest
|
|
if err := c.ShouldBindQuery(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "参数错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
// 设置默认分页参数
|
|
if req.Page <= 0 {
|
|
req.Page = 1
|
|
}
|
|
if req.Size <= 0 {
|
|
req.Size = 20
|
|
}
|
|
|
|
response, err := h.service.List(&req)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"code": 500,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
// enrich invite_url
|
|
base := config.GetConfig().SSO.SSOServerURL
|
|
base = strings.TrimRight(base, "/")
|
|
enriched := make([]gin.H, 0, len(response.List))
|
|
for _, item := range response.List {
|
|
// 获取用户等级信息
|
|
var userLevelName string
|
|
if item.UserLevelID != nil {
|
|
if level, err := h.userLevelService.GetByID(*item.UserLevelID); err == nil {
|
|
userLevelName = level.LevelName
|
|
}
|
|
}
|
|
|
|
enriched = append(enriched, gin.H{
|
|
"id": item.ID,
|
|
"code": item.Code,
|
|
"is_used": item.IsUsed,
|
|
"client_id": item.ClientID,
|
|
"client_label": config.GetClientValue(item.ClientID),
|
|
"email": item.Email,
|
|
"user_level_id": item.UserLevelID,
|
|
"user_level_name": userLevelName,
|
|
"expires_at": item.ExpiresAt,
|
|
"created_at": item.CreatedAt,
|
|
"invite_url": base + "/invite/" + item.Code,
|
|
})
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "获取成功",
|
|
"data": gin.H{
|
|
"list": enriched,
|
|
"total": response.Total,
|
|
},
|
|
})
|
|
}
|
|
|
|
// GetInviteCodeDetail 获取邀请码详情
|
|
func (h *InviteCodeHandler) GetInviteCodeDetail(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "ID格式错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
inviteCode, err := h.service.GetByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{
|
|
"code": 404,
|
|
"message": "邀请码不存在",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
base := config.GetConfig().SSO.SSOServerURL
|
|
base = strings.TrimRight(base, "/")
|
|
|
|
// 获取用户等级信息
|
|
var userLevelName string
|
|
if inviteCode.UserLevelID != nil {
|
|
if level, err := h.userLevelService.GetByID(*inviteCode.UserLevelID); err == nil {
|
|
userLevelName = level.LevelName
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "获取成功",
|
|
"data": gin.H{
|
|
"id": inviteCode.ID,
|
|
"code": inviteCode.Code,
|
|
"is_used": inviteCode.IsUsed,
|
|
"client_id": inviteCode.ClientID,
|
|
"client_label": config.GetClientValue(inviteCode.ClientID),
|
|
"email": inviteCode.Email,
|
|
"user_level_id": inviteCode.UserLevelID,
|
|
"user_level_name": userLevelName,
|
|
"expires_at": inviteCode.ExpiresAt,
|
|
"created_at": inviteCode.CreatedAt,
|
|
"invite_url": base + "/invite/" + inviteCode.Code,
|
|
},
|
|
})
|
|
}
|
|
|
|
// validateEmail 验证邮箱格式
|
|
func validateEmail(email string) bool {
|
|
emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
|
|
return emailRegex.MatchString(email)
|
|
}
|
|
|
|
// CreateInviteCode 创建邀请码(支持设置过期时间和邮箱列表)
|
|
func (h *InviteCodeHandler) CreateInviteCode(c *gin.Context) {
|
|
var req models.InviteCodeCreateRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "参数错误:" + err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
// 验证邮箱格式
|
|
if len(req.Emails) > 0 {
|
|
for _, email := range req.Emails {
|
|
if email != "" && !validateEmail(email) {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "邮箱格式不正确: " + email,
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// 验证用户等级ID是否存在且启用
|
|
if req.UserLevelID != nil {
|
|
userLevel, err := h.userLevelService.GetByID(*req.UserLevelID)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "用户等级不存在",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
if userLevel.Status != 1 {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "用户等级已禁用",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
}
|
|
|
|
inviteCodes, err := h.service.Create(&req)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"code": 500,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
base := config.GetConfig().SSO.SSOServerURL
|
|
base = strings.TrimRight(base, "/")
|
|
|
|
// 如果只创建了一个邀请码,返回单个对象(向后兼容)
|
|
if len(inviteCodes) == 1 {
|
|
inviteCode := inviteCodes[0]
|
|
var userLevelName string
|
|
if inviteCode.UserLevelID != nil {
|
|
if level, err := h.userLevelService.GetByID(*inviteCode.UserLevelID); err == nil {
|
|
userLevelName = level.LevelName
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "创建成功",
|
|
"data": gin.H{
|
|
"id": inviteCode.ID,
|
|
"code": inviteCode.Code,
|
|
"is_used": inviteCode.IsUsed,
|
|
"client_id": inviteCode.ClientID,
|
|
"client_label": config.GetClientValue(inviteCode.ClientID),
|
|
"email": inviteCode.Email,
|
|
"user_level_id": inviteCode.UserLevelID,
|
|
"user_level_name": userLevelName,
|
|
"expires_at": inviteCode.ExpiresAt,
|
|
"created_at": inviteCode.CreatedAt,
|
|
"invite_url": base + "/invite/" + inviteCode.Code,
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
// 如果创建了多个邀请码,返回数组
|
|
enriched := make([]gin.H, 0, len(inviteCodes))
|
|
for _, inviteCode := range inviteCodes {
|
|
var userLevelName string
|
|
if inviteCode.UserLevelID != nil {
|
|
if level, err := h.userLevelService.GetByID(*inviteCode.UserLevelID); err == nil {
|
|
userLevelName = level.LevelName
|
|
}
|
|
}
|
|
|
|
enriched = append(enriched, gin.H{
|
|
"id": inviteCode.ID,
|
|
"code": inviteCode.Code,
|
|
"is_used": inviteCode.IsUsed,
|
|
"client_id": inviteCode.ClientID,
|
|
"client_label": config.GetClientValue(inviteCode.ClientID),
|
|
"email": inviteCode.Email,
|
|
"user_level_id": inviteCode.UserLevelID,
|
|
"user_level_name": userLevelName,
|
|
"expires_at": inviteCode.ExpiresAt,
|
|
"created_at": inviteCode.CreatedAt,
|
|
"invite_url": base + "/invite/" + inviteCode.Code,
|
|
})
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "创建成功",
|
|
"data": enriched,
|
|
})
|
|
}
|
|
|
|
// UpdateInviteCode 更新邀请码(支持更新过期时间)
|
|
func (h *InviteCodeHandler) UpdateInviteCode(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "ID格式错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.InviteCodeUpdateRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "参数错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
inviteCode, err := h.service.Update(uint(id), &req)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
base := config.GetConfig().SSO.SSOServerURL
|
|
base = strings.TrimRight(base, "/")
|
|
|
|
// 获取用户等级信息
|
|
var userLevelName string
|
|
if inviteCode.UserLevelID != nil {
|
|
if level, err := h.userLevelService.GetByID(*inviteCode.UserLevelID); err == nil {
|
|
userLevelName = level.LevelName
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "更新成功",
|
|
"data": gin.H{
|
|
"id": inviteCode.ID,
|
|
"code": inviteCode.Code,
|
|
"is_used": inviteCode.IsUsed,
|
|
"client_id": inviteCode.ClientID,
|
|
"client_label": config.GetClientValue(inviteCode.ClientID),
|
|
"email": inviteCode.Email,
|
|
"user_level_id": inviteCode.UserLevelID,
|
|
"user_level_name": userLevelName,
|
|
"expires_at": inviteCode.ExpiresAt,
|
|
"created_at": inviteCode.CreatedAt,
|
|
"invite_url": base + "/invite/" + inviteCode.Code,
|
|
},
|
|
})
|
|
}
|
|
|
|
// DeleteInviteCode 删除邀请码
|
|
func (h *InviteCodeHandler) DeleteInviteCode(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "ID格式错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
err = h.service.Delete(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"code": 500,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "删除成功",
|
|
"data": nil,
|
|
})
|
|
}
|
|
|
|
// GetInviteCodeStatistics 获取统计信息
|
|
func (h *InviteCodeHandler) GetInviteCodeStatistics(c *gin.Context) {
|
|
stats, err := h.service.GetStatistics()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"code": 500,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "获取成功",
|
|
"data": stats,
|
|
})
|
|
}
|
|
|
|
// MarkInviteCodeAsUsed 标记邀请码为已使用
|
|
func (h *InviteCodeHandler) MarkInviteCodeAsUsed(c *gin.Context) {
|
|
var req struct {
|
|
Code string `json:"code" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "参数错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
err := h.service.MarkAsUsed(req.Code)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "标记成功",
|
|
"data": nil,
|
|
})
|
|
}
|
|
|
|
// ValidateInviteCode 验证邀请码是否有效
|
|
func (h *InviteCodeHandler) ValidateInviteCode(c *gin.Context) {
|
|
var req struct {
|
|
Code string `json:"code" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": "参数错误",
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
err := h.service.ValidateInviteCode(req.Code)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"code": 400,
|
|
"message": err.Error(),
|
|
"data": nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "邀请码有效",
|
|
"data": nil,
|
|
})
|
|
}
|
|
|
|
// GetClientOptions 获取客户端选项列表
|
|
func (h *InviteCodeHandler) GetClientOptions(c *gin.Context) {
|
|
options := config.GetClientOptions()
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"code": 200,
|
|
"message": "获取成功",
|
|
"data": options,
|
|
})
|
|
}
|