1.0
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
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))
|
||||
}
|
||||
Reference in New Issue
Block a user