package handlers import ( "awesomeProject/internal/common" "awesomeProject/internal/models" "net/http" "strconv" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ScoreRecordCreateRequest 用于接收创建积分记录的请求 type ScoreRecordCreateRequest struct { UserID uint `json:"user_id" binding:"required"` ChangeNumber int `json:"change_number" binding:"required"` Note string `json:"note" binding:"required"` } // AdminScoreHandler 管理端积分处理器 type AdminScoreHandler struct{} // GetScoreRecords 获取积分记录列表 func (h *AdminScoreHandler) GetScoreRecords(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 分页参数 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 10 } // 搜索参数 userID := c.Query("user_id") phone := c.Query("phone") changeType := c.Query("change_type") // positive: 正数, negative: 负数 db := common.GetDB() var records []models.ScoreRecord var total int64 // 构建查询条件 query := db.Model(&models.ScoreRecord{}).Preload("User") // 如果是代理商,只能查看自己邀请的用户的积分记录 if user.SystemRole == 1 { // 子查询:获取代理商邀请的用户ID列表 subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode) query = query.Where("user_id IN (?)", subQuery) } // 添加搜索条件 if userID != "" { query = query.Where("user_id = ?", userID) } if phone != "" { // 通过关联用户表搜索手机号 query = query.Joins("JOIN users ON users.id = score_records.user_id").Where("users.phone LIKE ?", "%"+phone+"%") } if changeType == "positive" { query = query.Where("change_number > 0") } else if changeType == "negative" { query = query.Where("change_number < 0") } // 获取总数 query.Count(&total) // 分页查询 offset := (page - 1) * pageSize err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&records).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询积分记录失败")) return } // 构建返回数据 result := map[string]interface{}{ "list": records, "total": total, "page": page, "page_size": pageSize, } c.JSON(http.StatusOK, common.Success(result)) } // GetScoreRecord 获取单个积分记录详情 func (h *AdminScoreHandler) GetScoreRecord(c *gin.Context) { recordID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "记录ID无效")) return } currentUser, _ := c.Get("current_user") user := currentUser.(models.User) var record models.ScoreRecord query := common.GetDB().Preload("User") err = query.First(&record, uint(recordID)).Error if err != nil { if err == gorm.ErrRecordNotFound { c.JSON(http.StatusOK, common.Error(404, "积分记录不存在")) } else { c.JSON(http.StatusOK, common.Error(500, "查询积分记录失败")) } return } // 如果是代理商,检查权限 if user.SystemRole == 1 { // 检查用户是否为代理商邀请的用户 if record.User.ReferrerIdentityCode != user.IdentityCode { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } } c.JSON(http.StatusOK, common.Success(record)) } // CreateScoreRecord 创建积分记录(仅管理员) func (h *AdminScoreHandler) CreateScoreRecord(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以创建积分记录 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } var newRecord1 ScoreRecordCreateRequest if err := c.ShouldBindJSON(&newRecord1); err != nil { c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error())) return } // 检查用户是否存在 var targetUser models.User if err := common.GetDB().First(&targetUser, newRecord1.UserID).Error; err != nil { c.JSON(http.StatusOK, common.Error(404, "用户不存在")) return } newRecord := models.ScoreRecord{ UserID: newRecord1.UserID, ChangeNumber: newRecord1.ChangeNumber, Note: newRecord1.Note, } // 开启事务 tx := common.GetDB().Begin() // 创建积分记录 if err := tx.Create(&newRecord).Error; err != nil { tx.Rollback() c.JSON(http.StatusOK, common.Error(500, "创建积分记录失败")) return } // 更新用户积分 newPoints := targetUser.CurrentPoints + newRecord.ChangeNumber if newPoints < 0 { tx.Rollback() c.JSON(http.StatusOK, common.Error(400, "用户积分不足")) return } if err := tx.Model(&targetUser).Update("current_points", newPoints).Error; err != nil { tx.Rollback() c.JSON(http.StatusOK, common.Error(500, "更新用户积分失败")) return } // 提交事务 tx.Commit() // 返回创建的记录(包含用户信息) var createdRecord models.ScoreRecord common.GetDB().Preload("User").First(&createdRecord, newRecord.ID) c.JSON(http.StatusOK, common.Success(createdRecord)) } // UpdateScoreRecord 更新积分记录(仅管理员) func (h *AdminScoreHandler) UpdateScoreRecord(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以更新积分记录 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } recordID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "记录ID无效")) return } var updateData struct { ChangeNumber int `json:"change_number" binding:"required"` Note string `json:"note" binding:"required"` } if err := c.ShouldBindJSON(&updateData); err != nil { c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error())) return } // 检查积分记录是否存在 var existRecord models.ScoreRecord if err := common.GetDB().Preload("User").First(&existRecord, uint(recordID)).Error; err != nil { c.JSON(http.StatusOK, common.Error(404, "积分记录不存在")) return } // 开启事务 tx := common.GetDB().Begin() // 计算积分差值 pointsDiff := updateData.ChangeNumber - existRecord.ChangeNumber newUserPoints := existRecord.User.CurrentPoints + pointsDiff if newUserPoints < 0 { tx.Rollback() c.JSON(http.StatusOK, common.Error(400, "用户积分不足")) return } // 更新积分记录 if err := tx.Model(&existRecord).Updates(map[string]interface{}{ "change_number": updateData.ChangeNumber, "note": updateData.Note, }).Error; err != nil { tx.Rollback() c.JSON(http.StatusOK, common.Error(500, "更新积分记录失败")) return } // 更新用户积分 if err := tx.Model(&existRecord.User).Update("current_points", newUserPoints).Error; err != nil { tx.Rollback() c.JSON(http.StatusOK, common.Error(500, "更新用户积分失败")) return } // 提交事务 tx.Commit() // 返回更新后的记录 var updatedRecord models.ScoreRecord common.GetDB().Preload("User").First(&updatedRecord, uint(recordID)) c.JSON(http.StatusOK, common.Success(updatedRecord)) } // DeleteScoreRecord 删除积分记录(仅管理员) func (h *AdminScoreHandler) DeleteScoreRecord(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以删除积分记录 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } recordID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "记录ID无效")) return } // 检查积分记录是否存在 var existRecord models.ScoreRecord if err := common.GetDB().Preload("User").First(&existRecord, uint(recordID)).Error; err != nil { c.JSON(http.StatusOK, common.Error(404, "积分记录不存在")) return } // 开启事务 tx := common.GetDB().Begin() // 恢复用户积分(减去这条记录的变化值) newUserPoints := existRecord.User.CurrentPoints - existRecord.ChangeNumber if newUserPoints < 0 { tx.Rollback() c.JSON(http.StatusOK, common.Error(400, "删除此记录会导致用户积分为负数")) return } // 更新用户积分 if err := tx.Model(&existRecord.User).Update("current_points", newUserPoints).Error; err != nil { tx.Rollback() c.JSON(http.StatusOK, common.Error(500, "更新用户积分失败")) return } // 删除积分记录 if err := tx.Delete(&existRecord).Error; err != nil { tx.Rollback() c.JSON(http.StatusOK, common.Error(500, "删除积分记录失败")) return } // 提交事务 tx.Commit() c.JSON(http.StatusOK, common.Success(nil)) } // GetScoreStats 获取积分统计信息 func (h *AdminScoreHandler) GetScoreStats(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) db := common.GetDB() stats := make(map[string]interface{}) // 构建基础查询 baseQuery := db.Model(&models.ScoreRecord{}) if user.SystemRole == 1 { // 代理商只统计自己邀请的用户的积分记录 subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode) baseQuery = baseQuery.Where("user_id IN (?)", subQuery) } // 总积分变化记录数 var totalRecords int64 baseQuery.Count(&totalRecords) stats["total_records"] = totalRecords // 总积分增加 var totalIncrease int64 baseQuery.Where("change_number > 0").Select("COALESCE(SUM(change_number), 0)").Scan(&totalIncrease) stats["total_increase"] = totalIncrease // 总积分减少 var totalDecrease int64 baseQuery.Where("change_number < 0").Select("COALESCE(SUM(ABS(change_number)), 0)").Scan(&totalDecrease) stats["total_decrease"] = totalDecrease // 今日积分变化 todayQuery := baseQuery if user.SystemRole == 1 { subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode) todayQuery = todayQuery.Where("user_id IN (?)", subQuery) } var todayIncrease int64 todayQuery.Where("change_number > 0 AND DATE(created_at) = CURDATE()").Select("COALESCE(SUM(change_number), 0)").Scan(&todayIncrease) stats["today_increase"] = todayIncrease var todayDecrease int64 todayQuery.Where("change_number < 0 AND DATE(created_at) = CURDATE()").Select("COALESCE(SUM(ABS(change_number)), 0)").Scan(&todayDecrease) stats["today_decrease"] = todayDecrease c.JSON(http.StatusOK, common.Success(stats)) }