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(¤tUseruser).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)) }