This commit is contained in:
solosw
2026-01-05 14:11:34 +08:00
parent 35ef825371
commit 99b11b04e4
658 changed files with 99266 additions and 0 deletions
+633
View File
@@ -0,0 +1,633 @@
package handlers
import (
"awesomeProject/internal/common"
"awesomeProject/internal/middleware"
"awesomeProject/internal/models"
"crypto/md5"
"fmt"
"github.com/google/uuid"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// AdminUserHandler 管理端用户处理器
type AdminUserHandler struct{}
// GetUsers 获取用户列表
func (h *AdminUserHandler) GetUsers(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
}
// 搜索参数
phone := c.Query("phone")
realName := c.Query("real_name")
systemRole := c.Query("system_role")
identityCode := c.Query("identity_code")
db := common.GetDB()
var users []models.User
var total int64
// 构建查询条件
query := db.Model(&models.User{})
// 如果是代理商,只能查看自己邀请的用户
if user.SystemRole == 1 {
query = query.Where("referrer_identity_code = ?", user.IdentityCode)
}
// 添加搜索条件
if phone != "" {
query = query.Where("phone LIKE ?", "%"+phone+"%")
}
if realName != "" {
query = query.Where("real_name LIKE ?", "%"+realName+"%")
}
if systemRole != "" {
query = query.Where("system_role = ?", systemRole)
} else {
query = query.Where("system_role > 0")
}
if identityCode != "" {
query = query.Where("identity_code LIKE ? OR referrer_identity_code LIKE ?", "%"+identityCode+"%", "%"+identityCode+"%")
}
// 获取总数
query.Count(&total)
// 分页查询
offset := (page - 1) * pageSize
err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&users).Error
if err != nil {
c.JSON(http.StatusOK, common.Error(500, "查询用户列表失败"))
return
}
// 构建返回数据
result := map[string]interface{}{
"list": users,
"total": total,
"page": page,
"page_size": pageSize,
}
c.JSON(http.StatusOK, common.Success(result))
}
// GetUser 获取单个用户信息
func (h *AdminUserHandler) GetUser(c *gin.Context) {
userID, err := middleware.GetUserIDFromParam(c, "id")
if err != nil {
c.JSON(http.StatusOK, common.Error(400, err.Error()))
return
}
var user models.User
err = common.GetDB().First(&user, userID).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusOK, common.Error(404, "用户不存在"))
} else {
c.JSON(http.StatusOK, common.Error(500, "查询用户信息失败"))
}
return
}
c.JSON(http.StatusOK, common.Success(user))
}
// CreateUser 创建用户(仅管理员)
func (h *AdminUserHandler) CreateUser(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 newUser models.User
if err := c.ShouldBindJSON(&newUser); err != nil {
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
return
}
// 检查手机号是否已存在
var existUser models.User
if err := common.GetDB().Where("phone = ?", newUser.Phone).First(&existUser).Error; err == nil {
c.JSON(http.StatusOK, common.Error(400, "手机号已存在"))
return
}
if newUser.SystemRole == 1 {
newUser.IdentityCode = "T" + uuid.New().String()[:8]
} else {
newUser.IdentityCode = "U" + uuid.New().String()[:8]
}
if newUser.Password != "" {
newUser.Password = fmt.Sprintf("%x", md5.Sum([]byte(newUser.Password)))
}
// 保存用户
if err := common.GetDB().Create(&newUser).Error; err != nil {
c.JSON(http.StatusOK, common.Error(500, "创建用户失败"))
return
}
c.JSON(http.StatusOK, common.Success(newUser))
}
// UpdateUser 更新用户信息(仅管理员)
func (h *AdminUserHandler) UpdateUser(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 只有管理员可以更新用户
if user.SystemRole != 0 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
userID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "用户ID无效"))
return
}
var updateData models.User
if err := c.ShouldBindJSON(&updateData); err != nil {
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
return
}
fmt.Println(updateData)
// 检查用户是否存在
var existUser models.User
if err := common.GetDB().First(&existUser, uint(userID)).Error; err != nil {
c.JSON(http.StatusOK, common.Error(404, "用户不存在"))
return
}
// 更新用户信息
updateData.ID = uint(userID)
if updateData.Password != "" {
updateData.Password = fmt.Sprintf("%x", md5.Sum([]byte(updateData.Password)))
}
if err := common.GetDB().Model(&existUser).Updates(&updateData).Error; err != nil {
c.JSON(http.StatusOK, common.Error(500, "更新用户信息失败"))
return
}
if err := common.GetDB().Model(&existUser).Updates(map[string]interface{}{
"status": updateData.Status,
}).Error; err != nil {
c.JSON(http.StatusOK, common.Error(500, "更新用户信息失败"))
return
}
// 返回更新后的用户信息
var updatedUser models.User
common.GetDB().First(&updatedUser, uint(userID))
c.JSON(http.StatusOK, common.Success(updatedUser))
}
// DeleteUser 删除用户(仅管理员)
func (h *AdminUserHandler) DeleteUser(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 只有管理员可以删除用户
if user.SystemRole != 0 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
userID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "用户ID无效"))
return
}
// 检查用户是否存在
var existUser models.User
if err := common.GetDB().First(&existUser, uint(userID)).Error; err != nil {
c.JSON(http.StatusOK, common.Error(404, "用户不存在"))
return
}
// 删除用户
if err := common.GetDB().Delete(&existUser).Error; err != nil {
c.JSON(http.StatusOK, common.Error(500, "删除用户失败"))
return
}
c.JSON(http.StatusOK, common.Success(nil))
}
// GetUserStats 获取用户统计信息
func (h *AdminUserHandler) GetUserStats(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
db := common.GetDB()
stats := make(map[string]interface{})
// 如果是代理商,只统计自己邀请的用户
baseQuery := db.Model(&models.User{})
if user.SystemRole == 1 {
baseQuery = baseQuery.Where("referrer_identity_code = ?", user.IdentityCode)
}
// 总用户数
var totalUsers int64
baseQuery.Count(&totalUsers)
stats["total_users"] = totalUsers
// 按角色统计
var roleCounts []struct {
SystemRole uint8 `json:"system_role"`
Count int64 `json:"count"`
}
roleQuery := baseQuery
if user.SystemRole == 1 {
roleQuery = roleQuery.Where("referrer_identity_code = ?", user.IdentityCode)
}
roleQuery.Select("system_role, count(*) as count").Group("system_role").Scan(&roleCounts)
stats["role_counts"] = roleCounts
// 今日新增用户
var todayUsers int64
todayQuery := baseQuery
if user.SystemRole == 1 {
todayQuery = todayQuery.Where("referrer_identity_code = ?", user.IdentityCode)
}
todayQuery.Where("DATE(created_at) = CURDATE()").Count(&todayUsers)
stats["today_users"] = todayUsers
c.JSON(http.StatusOK, common.Success(stats))
}
// SetUserExpiryDate 设置用户过期时间(仅管理员)
func (h *AdminUserHandler) SetUserExpiryDate(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 只有管理员可以设置用户过期时间
if user.SystemRole != 0 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
userID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "用户ID无效"))
return
}
var req struct {
ExpiryDate *string `json:"expiry_date"` // ISO 8601 格式,如 "2024-12-31T23:59:59Z"null表示永不过期
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusOK, common.Error(400, "请求参数错误"))
return
}
db := common.GetDB()
// 检查用户是否存在
var targetUser models.User
if err := db.First(&targetUser, uint(userID)).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusOK, common.Error(404, "用户不存在"))
} else {
c.JSON(http.StatusOK, common.Error(500, "查询用户失败"))
}
return
}
// 防止设置管理员的过期时间
if targetUser.SystemRole == 0 {
c.JSON(http.StatusOK, common.Error(400, "不能设置管理员的过期时间"))
return
}
// 解析过期时间
var expiryDate *time.Time
if req.ExpiryDate != nil && *req.ExpiryDate != "" {
parsedTime, err := time.Parse(time.RFC3339, *req.ExpiryDate)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "过期时间格式错误,请使用ISO 8601格式"))
return
}
expiryDate = &parsedTime
}
// 更新用户过期时间
if err := db.Model(&targetUser).Update("expiry_date", expiryDate).Error; err != nil {
c.JSON(http.StatusOK, common.Error(500, "设置用户过期时间失败"))
return
}
var message string
if expiryDate == nil {
message = "用户已设置为永不过期"
} else {
message = fmt.Sprintf("用户过期时间已设置为:%s", expiryDate.Format("2006-01-02 15:04:05"))
}
c.JSON(http.StatusOK, common.Success(map[string]interface{}{
"message": message,
"expiry_date": expiryDate,
}))
}
// SearchUserStats 搜索用户统计信息
func (h *AdminUserHandler) SearchUserStats(c *gin.Context) {
// 获取当前用户信息
currentUser, _ := c.Get("current_user")
currentUseruser := currentUser.(models.User)
// 仅管理员可访问
if currentUseruser.SystemRole > 1 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
query := c.Query("query")
if query == "" {
c.JSON(http.StatusOK, common.Error(400, "搜索条件不能为空"))
return
}
// 获取时间范围参数
startDate := c.Query("start_date")
endDate := c.Query("end_date")
db := common.GetDB()
var user models.User
//err2 := db.Where("id=?", currentUseruser.ID).First(&currentUseruser).Error
//if err2 != nil {
// c.JSON(http.StatusOK, common.Error(403, "权限不足"))
// return
//}
// 按手机号或姓名搜索用户
err := db.Where("phone = ? OR customer_name LIKE ? OR real_name LIKE ?",
query, "%"+query+"%", "%"+query+"%").First(&user).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 currentUseruser.SystemRole == 1 && user.ReferrerIdentityCode != currentUseruser.IdentityCode {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
// 统计该用户的数据
stats := make(map[string]interface{})
// 构建采购订单查询
purchaseQuery := db.Model(&models.PurchaseOrder{}).Where("buyer_id = ? and order_status=?", user.ID, 2)
if startDate != "" && endDate != "" {
purchaseQuery = purchaseQuery.Where("created_at >= ? AND created_at <= ?", startDate+" 00:00:00", endDate+" 23:59:59")
}
// 采购订单统计
var purchaseOrdersCount int64
var totalPurchaseAmount float64
purchaseQuery.Count(&purchaseOrdersCount)
purchaseQuery.Select("COALESCE(SUM(total_amount), 0)").Scan(&totalPurchaseAmount)
// 构建销售订单查询
salesQuery := db.Model(&models.SalesOrder{}).Where("seller_id = ? and order_status=?", user.ID, 2)
if startDate != "" && endDate != "" {
salesQuery = salesQuery.Where("created_at >= ? AND created_at <= ?", startDate+" 00:00:00", endDate+" 23:59:59")
}
// 销售订单统计
var salesOrdersCount int64
var totalSalesAmount float64
salesQuery.Count(&salesOrdersCount)
salesQuery.Select("COALESCE(SUM(total_amount), 0)").Scan(&totalSalesAmount)
// 库存统计
var warehouseItemsCount int64
var totalWarehouseQuantity int64
if startDate != "" && endDate != "" {
db.Model(&models.UserWarehouse{}).Where("user_id = ? and created_at >= ? AND created_at <= ?", user.ID, startDate+" 00:00:00", endDate+" 23:59:59").Count(&warehouseItemsCount)
db.Model(&models.UserWarehouse{}).Where("user_id = ? and created_at >= ? AND created_at <= ?", user.ID, startDate+" 00:00:00", endDate+" 23:59:59").Select("COALESCE(SUM(quantity), 0)").Scan(&totalWarehouseQuantity)
} else {
db.Model(&models.UserWarehouse{}).Where("user_id = ? ", user.ID).Count(&warehouseItemsCount)
db.Model(&models.UserWarehouse{}).Where("user_id = ? ", user.ID).Select("COALESCE(SUM(quantity), 0)").Scan(&totalWarehouseQuantity)
}
// 积分余额
var scoreBalance int
//db.Model(&models.ScoreRecord{}).Where("user_id = ?", user.ID).Select("COALESCE(SUM(score_change), 0)").Scan(&scoreBalance)
scoreBalance = user.CurrentPoints
// 最后活动时间(最近的订单时间)
var lastActivityTime *time.Time
var lastPurchaseTime, lastSalesTime time.Time
// 查找最近的采购订单时间
db.Model(&models.PurchaseOrder{}).Where("user_id = ?", user.ID).
Select("created_at").Order("created_at DESC").Limit(1).Scan(&lastPurchaseTime)
// 查找最近的销售订单时间
db.Model(&models.SalesOrder{}).Where("user_id = ?", user.ID).
Select("created_at").Order("created_at DESC").Limit(1).Scan(&lastSalesTime)
// 取两个时间中的最大值
if !lastPurchaseTime.IsZero() && !lastSalesTime.IsZero() {
if lastPurchaseTime.After(lastSalesTime) {
lastActivityTime = &lastPurchaseTime
} else {
lastActivityTime = &lastSalesTime
}
} else if !lastPurchaseTime.IsZero() {
lastActivityTime = &lastPurchaseTime
} else if !lastSalesTime.IsZero() {
lastActivityTime = &lastSalesTime
}
stats["purchase_orders_count"] = purchaseOrdersCount
stats["total_purchase_amount"] = totalPurchaseAmount
stats["sales_orders_count"] = salesOrdersCount
stats["total_sales_amount"] = totalSalesAmount
stats["warehouse_items_count"] = warehouseItemsCount
stats["total_warehouse_quantity"] = totalWarehouseQuantity
stats["score_balance"] = scoreBalance
stats["last_activity_time"] = lastActivityTime
result := map[string]interface{}{
"user": user,
"stats": stats,
}
c.JSON(http.StatusOK, common.Success(result))
}
// GetAllUserWarehouses 获取所有用户库存汇总(管理员专用)
func (h *AdminUserHandler) GetAllUserWarehouses(c *gin.Context) {
// 获取当前用户信息
currentUser, _ := c.Get("current_user")
currentUseruser := currentUser.(models.User)
// 仅管理员可访问
if currentUseruser.SystemRole > 1 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
// 分页参数
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
}
// 搜索参数
searchQuery := c.Query("search") // 搜索手机号或姓名
productType := c.Query("product_type") // 商品类型:1一级商品,2二级商品
status := c.Query("status") // 状态:0已出售,1库存中
db := common.GetDB()
// 构建库存记录查询(带用户信息)
warehouseQuery := db.Model(&models.UserWarehouse{}).
Select("user_warehouse.*, users.phone, users.customer_name, users.real_name").
Joins("JOIN users ON users.id = user_warehouse.user_id")
// 搜索用户(基于手机号或姓名)
if searchQuery != "" {
warehouseQuery = warehouseQuery.Where("users.phone LIKE ? OR users.customer_name LIKE ? OR users.real_name LIKE ?",
"%"+searchQuery+"%", "%"+searchQuery+"%", "%"+searchQuery+"%")
}
// 应用商品类型筛选
if productType != "" {
warehouseQuery = warehouseQuery.Where("user_warehouse.product_type = ?", productType)
}
// 应用状态筛选
if status != "" {
warehouseQuery = warehouseQuery.Where("user_warehouse.status = ?", status)
}
// 获取总数
var total int64
warehouseQuery.Count(&total)
// 分页查询库存记录
var userWarehouses []models.UserWarehouse
offset := (page - 1) * pageSize
err := warehouseQuery.Offset(offset).Limit(pageSize).Order("user_warehouse.created_at DESC").Find(&userWarehouses).Error
if err != nil {
c.JSON(http.StatusOK, common.Error(500, "查询用户库存列表失败"))
return
}
// 转换数据结构以包含用户信息,并按用户ID、商品类型、商品名称、状态聚合
var resultList []struct {
UserID uint `json:"user_id"`
Phone string `json:"phone"`
CustomerName string `json:"customer_name"`
RealName string `json:"real_name"`
ProductType uint8 `json:"product_type"`
ProductName string `json:"product_name"`
TotalQuantity int `json:"total_quantity"`
TotalValue float64 `json:"total_value"`
Status uint8 `json:"status"`
}
// 按用户ID、商品类型、商品名称、状态聚合库存
userWarehouseMap := make(map[string]*struct {
UserID uint `json:"user_id"`
Phone string `json:"phone"`
CustomerName string `json:"customer_name"`
RealName string `json:"real_name"`
ProductType uint8 `json:"product_type"`
ProductName string `json:"product_name"`
TotalQuantity int `json:"total_quantity"`
TotalValue float64 `json:"total_value"`
Status uint8 `json:"status"`
})
for _, warehouse := range userWarehouses {
// 生成唯一键:用户ID_商品类型_商品名称_状态
key := fmt.Sprintf("%d_%d_%s_%d", warehouse.UserID, warehouse.ProductType, warehouse.ProductName, warehouse.Status)
// 获取用户信息(第一次出现时)
var user models.User
db.First(&user, warehouse.UserID)
if item, exists := userWarehouseMap[key]; exists {
// 累加数量和价值
item.TotalQuantity += warehouse.Quantity
item.TotalValue += float64(warehouse.Quantity) * warehouse.WarehousePrice
} else {
// 创建新的聚合记录
userWarehouseMap[key] = &struct {
UserID uint `json:"user_id"`
Phone string `json:"phone"`
CustomerName string `json:"customer_name"`
RealName string `json:"real_name"`
ProductType uint8 `json:"product_type"`
ProductName string `json:"product_name"`
TotalQuantity int `json:"total_quantity"`
TotalValue float64 `json:"total_value"`
Status uint8 `json:"status"`
}{
UserID: warehouse.UserID,
Phone: user.Phone,
CustomerName: user.CustomerName,
RealName: user.RealName,
ProductType: warehouse.ProductType,
ProductName: warehouse.ProductName,
TotalQuantity: warehouse.Quantity,
TotalValue: float64(warehouse.Quantity) * warehouse.WarehousePrice,
Status: warehouse.Status,
}
}
}
// 转换为切片
for _, item := range userWarehouseMap {
resultList = append(resultList, *item)
}
// 构建返回数据
result := map[string]interface{}{
"list": resultList,
"total": total,
"page": page,
"page_size": pageSize,
}
c.JSON(http.StatusOK, common.Success(result))
}