feat: 用户创建充值优化、侧边栏导航修复、在线实例统计修复

This commit is contained in:
2026-05-03 06:07:11 +08:00
parent fa521de836
commit ecf5690505
8 changed files with 331 additions and 84 deletions
+3 -1
View File
@@ -1,4 +1,4 @@
package admin
package admin
import (
"fmt"
@@ -135,7 +135,9 @@ func handleGetCardTypes(c *gin.Context) {
"user_id": ct.UserID,
"application_id": ct.ApplicationID,
"name": ct.Name,
"recharge_type": ct.RechargeType,
"value": ct.Value,
"value_unit": ct.ValueUnit,
"price": ct.Price,
"description": ct.Description,
"status": ct.Status,
+141 -4
View File
@@ -1,4 +1,4 @@
package admin
package admin
import (
"fmt"
@@ -8,6 +8,7 @@ import (
"verification-platform-backend/internal/model"
"verification-platform-backend/internal/service"
"verification-platform-backend/pkg/response"
"verification-platform-backend/pkg/utils"
"github.com/gin-gonic/gin"
)
@@ -233,6 +234,8 @@ func handleCreateUser(c *gin.Context) {
Email string `json:"email"`
Password string `json:"password"`
ApplicationID uint `json:"application_id"`
CardTypeID *uint `json:"card_type_id"`
CardQuantity int `json:"card_quantity"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, 400, "参数错误")
@@ -254,6 +257,14 @@ func handleCreateUser(c *gin.Context) {
return
}
if req.CardQuantity < 1 {
req.CardQuantity = 1
}
if req.CardQuantity > 100 {
response.Error(c, 400, "卡密数量不能超过100")
return
}
var app model.Application
if err := database.DB.First(&app, req.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
@@ -274,6 +285,18 @@ func handleCreateUser(c *gin.Context) {
return
}
var cardType *model.CardType
if req.CardTypeID != nil && *req.CardTypeID > 0 {
var ct model.CardType
if err := database.DB.Where("id = ? AND application_id = ?", *req.CardTypeID, req.ApplicationID).First(&ct).Error; err != nil {
response.Error(c, 400, "卡密类型不存在或不属于该应用")
return
}
cardType = &ct
}
tx := database.DB.Begin()
user := model.AppUser{
Username: req.Username,
Email: req.Email,
@@ -283,14 +306,128 @@ func handleCreateUser(c *gin.Context) {
ApplicationID: app.ID,
}
if err := database.DB.Create(&user).Error; err != nil {
if err := tx.Create(&user).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "创建用户失败")
return
}
service.LogOperation(c, "create", "app_user", &user.ID, fmt.Sprintf("创建用户: %s (应用: %s)", user.Username, app.Name), nil)
var cards []model.Card
if cardType != nil {
now := time.Now()
response.Success(c, user)
for i := 0; i < req.CardQuantity; i++ {
cardKey := "CK" + utils.GenerateRandomString(16)
card := model.Card{
ApplicationID: req.ApplicationID,
CardTypeID: cardType.ID,
CardKey: cardKey,
CreatorID: userID,
AppUserID: &user.ID,
Status: "used",
}
card.UsedAt = &now
if err := tx.Create(&card).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "生成卡密失败")
return
}
user.IsTrialUser = false
if cardType.Value == -1 {
if cardType.RechargeType == "subscription" {
permanentExpiry := time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
user.ExpiryAt = &permanentExpiry
user.Balance = -1
} else {
user.Balance = -1
user.ExpiryAt = nil
}
} else {
switch cardType.RechargeType {
case "subscription":
var baseTime time.Time
if user.ExpiryAt != nil && user.ExpiryAt.After(now) {
baseTime = *user.ExpiryAt
} else {
baseTime = now
}
var duration time.Duration
switch cardType.ValueUnit {
case "minute":
duration = time.Duration(cardType.Value) * time.Minute
case "hour":
duration = time.Duration(cardType.Value) * time.Hour
case "day":
duration = time.Duration(cardType.Value) * 24 * time.Hour
case "month":
duration = time.Duration(cardType.Value) * 30 * 24 * time.Hour
case "year":
duration = time.Duration(cardType.Value) * 365 * 24 * time.Hour
default:
duration = time.Duration(cardType.Value) * time.Second
}
newExpiry := baseTime.Add(duration)
user.ExpiryAt = &newExpiry
case "balance":
fallthrough
default:
user.Balance += cardType.Value
}
}
rechargeRecord := model.RechargeRecord{
UserID: user.ID,
OrderNo: generateUserOrderNo("R"),
CardID: &card.ID,
CardCode: card.CardKey,
Amount: cardType.Price,
Status: "success",
PaymentType: "card",
Remark: "创建用户充值 - " + cardType.Name,
}
if err := tx.Create(&rechargeRecord).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "创建充值记录失败")
return
}
cards = append(cards, card)
}
if err := tx.Save(&user).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "充值失败")
return
}
}
if err := tx.Commit().Error; err != nil {
response.Error(c, 500, "创建用户失败")
return
}
logDesc := fmt.Sprintf("创建用户: %s (应用: %s)", user.Username, app.Name)
if cardType != nil {
logDesc += fmt.Sprintf(",充值卡密: %s x%d", cardType.Name, req.CardQuantity)
}
service.LogOperation(c, "create", "app_user", &user.ID, logDesc, nil)
result := gin.H{
"user": user,
}
if len(cards) > 0 {
result["cards"] = cards
}
response.Success(c, result)
}
func generateUserOrderNo(prefix string) string {
return prefix + time.Now().Format("20060102150405") + utils.GenerateRandomString(6)
}
func handleGetUser(c *gin.Context) {