feat: 用户管理显示资格和消费金额,订单管理添加详情功能
- 用户管理: 显示资格数和消费金额,支持编辑资格 - 订单管理: 添加订单详情查看功能 - 后端: AdminGetUsers返回消费金额, AdminGetByID获取订单详情 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -376,7 +376,42 @@ func (h *AuthHandler) Install(c *gin.Context) {
|
||||
func (h *AuthHandler) AdminGetUsers(c *gin.Context) {
|
||||
var users []models.User
|
||||
utils.DB.Select("id, username, email, role, purchase_credits, is_active, email_verified, created_at").Find(&users)
|
||||
c.JSON(http.StatusOK, gin.H{"data": users})
|
||||
|
||||
// 计算每个用户的消费金额
|
||||
type UserWithSpent struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Role string `json:"role"`
|
||||
PurchaseCredits int `json:"purchase_credits"`
|
||||
IsActive bool `json:"is_active"`
|
||||
EmailVerified bool `json:"email_verified"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
TotalSpent float64 `json:"total_spent"`
|
||||
}
|
||||
|
||||
result := make([]UserWithSpent, len(users))
|
||||
for i, user := range users {
|
||||
var totalSpent float64
|
||||
utils.DB.Model(&models.Order{}).
|
||||
Where("user_id = ? AND status IN ?", user.ID, []string{"completed", "shipped"}).
|
||||
Select("COALESCE(SUM(total_amount), 0)").
|
||||
Scan(&totalSpent)
|
||||
|
||||
result[i] = UserWithSpent{
|
||||
ID: user.ID,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
Role: user.Role,
|
||||
PurchaseCredits: user.PurchaseCredits,
|
||||
IsActive: user.IsActive,
|
||||
EmailVerified: user.EmailVerified,
|
||||
CreatedAt: user.CreatedAt,
|
||||
TotalSpent: totalSpent,
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": result})
|
||||
}
|
||||
|
||||
func (h *AuthHandler) AdminUpdateUser(c *gin.Context) {
|
||||
@@ -388,10 +423,11 @@ func (h *AuthHandler) AdminUpdateUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Username *string `json:"username"`
|
||||
Email *string `json:"email"`
|
||||
Role *string `json:"role"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
Username *string `json:"username"`
|
||||
Email *string `json:"email"`
|
||||
Role *string `json:"role"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
PurchaseCredits *int `json:"purchase_credits"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
@@ -411,6 +447,9 @@ func (h *AuthHandler) AdminUpdateUser(c *gin.Context) {
|
||||
if req.IsActive != nil {
|
||||
updates["is_active"] = *req.IsActive
|
||||
}
|
||||
if req.PurchaseCredits != nil {
|
||||
updates["purchase_credits"] = *req.PurchaseCredits
|
||||
}
|
||||
|
||||
utils.DB.Model(&user).Updates(updates)
|
||||
utils.DB.First(&user, id)
|
||||
|
||||
@@ -503,6 +503,20 @@ func (h *OrderHandler) AdminList(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (h *OrderHandler) AdminGetByID(c *gin.Context) {
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
|
||||
var order models.Order
|
||||
if err := utils.DB.Preload("OrderItems.Product").Preload("ShippingAddress").Preload("User").First(&order, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Order not found"})
|
||||
return
|
||||
}
|
||||
|
||||
checkOrderExpired(&order)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": order})
|
||||
}
|
||||
|
||||
func (h *OrderHandler) ProcessRefund(c *gin.Context) {
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
|
||||
|
||||
@@ -174,6 +174,7 @@ func SetupRoutes(r *gin.Engine) {
|
||||
adminOrders := admin.Group("/orders")
|
||||
{
|
||||
adminOrders.GET("", orderHandler.AdminList)
|
||||
adminOrders.GET("/:id", orderHandler.AdminGetByID)
|
||||
adminOrders.GET("/export", orderHandler.Export)
|
||||
adminOrders.PUT("/:id/refund", orderHandler.ProcessRefund)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user