Files
verify/backend/internal/router/admin/users.go
T
admin d0ef52ab4f 优化分页和筛选功能:实现服务端分页和筛选,修复总数不匹配问题
- 优化设备管理、版本管理、用户管理、在线实例、公告管理页面的分页功能
- 后端添加筛选参数支持(application_id, status, type, search等)
- 前端移除冗余的前端筛选逻辑,改为服务端筛选
- 修复分页总数与筛选数据不匹配的问题
- 优化云端变量记录页面的时间筛选和搜索功能
- 修复DateTimePicker组件关闭后不自动更新的问题
2026-05-08 13:45:21 +08:00

888 lines
24 KiB
Go

package admin
import (
"fmt"
"log"
"strconv"
"time"
"verification-platform-backend/internal/database"
"verification-platform-backend/internal/model"
"verification-platform-backend/internal/service"
"verification-platform-backend/pkg/response"
"verification-platform-backend/pkg/utils"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type UserWithStatus struct {
model.AppUser
OnlineStatus string `json:"online_status"`
DeviceCount int `json:"device_count"`
}
func getUserOnlineStatus(user model.AppUser, heartbeatTimeout int) string {
if user.Status == "banned" {
return "banned"
}
if user.LastHeartbeatAt == nil {
return "offline"
}
offlineThreshold := time.Duration(heartbeatTimeout) * time.Second
if time.Since(*user.LastHeartbeatAt) > offlineThreshold {
return "offline"
}
return "online"
}
func SetupUserRoutes(r *gin.RouterGroup) {
appUsers := r.Group("/app-users")
{
appUsers.GET("", handleGetUsers)
appUsers.POST("", handleCreateUser)
appUsers.GET("/:id", handleGetUser)
appUsers.PUT("/:id", handleUpdateUser)
appUsers.DELETE("/:id", handleDeleteUser)
appUsers.GET("/:id/devices", handleGetUserDevices)
appUsers.DELETE("/:id/devices/:deviceId", handleUnbindDevice)
appUsers.PUT("/:id/expiry", handleUpdateExpiry)
appUsers.POST("/batch/status", handleBatchUpdateStatus)
appUsers.DELETE("/batch", handleBatchDelete)
}
}
func handleGetUsers(c *gin.Context) {
userID := c.GetUint("user_id")
log.Printf("[DEBUG] handleGetUsers called, userID: %d", userID)
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
applicationID := c.Query("application_id")
statusFilter := c.Query("status")
var users []model.AppUser
var appHeartbeatTimeoutMap map[uint]int
if applicationID != "" {
var appID uint
if _, err := fmt.Sscanf(applicationID, "%d", &appID); err != nil {
response.Error(c, 400, "应用ID格式错误")
return
}
var app model.Application
if err := database.DB.First(&app, appID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
appHeartbeatTimeoutMap = make(map[uint]int)
timeout := app.HeartbeatTimeout
if timeout == 0 {
timeout = 300
}
appHeartbeatTimeoutMap[app.ID] = timeout
query := database.DB.Preload("Application").Where("application_id = ?", appID)
if statusFilter != "" {
query = query.Where("status = ?", statusFilter)
}
if app.UserID == userID {
if err := query.Find(&users).Error; err != nil {
response.Error(c, 500, "获取用户列表失败")
return
}
} else {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", appID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限查看该应用的用户")
return
}
var cardUserIDs []uint
if err := database.DB.Model(&model.Card{}).
Where("creator_id = ? AND application_id = ? AND app_user_id IS NOT NULL", userID, appID).
Pluck("app_user_id", &cardUserIDs).Error; err != nil {
response.Error(c, 500, "获取用户列表失败")
return
}
if len(cardUserIDs) > 0 {
query = database.DB.Preload("Application").Where("id IN ?", cardUserIDs)
if statusFilter != "" {
query = query.Where("status = ?", statusFilter)
}
if err := query.Find(&users).Error; err != nil {
response.Error(c, 500, "获取用户列表失败")
return
}
}
}
} else {
var ownApps []model.Application
if err := database.DB.Where("user_id = ?", userID).Find(&ownApps).Error; err != nil {
response.Error(c, 500, "获取应用列表失败")
return
}
var agentApps []model.AgentApplication
if err := database.DB.Where("agent_id = ? AND is_received = ?", userID, true).Find(&agentApps).Error; err != nil {
log.Printf("[DEBUG] Failed to get agent apps: %v", err)
response.Error(c, 500, "获取授权列表失败")
return
}
log.Printf("[DEBUG] Found %d agent apps for user %d", len(agentApps), userID)
appHeartbeatTimeoutMap = make(map[uint]int)
ownAppIDs := make([]uint, len(ownApps))
for i, app := range ownApps {
ownAppIDs[i] = app.ID
timeout := app.HeartbeatTimeout
if timeout == 0 {
timeout = 300
}
appHeartbeatTimeoutMap[app.ID] = timeout
}
if len(ownAppIDs) > 0 {
query := database.DB.Preload("Application").Where("application_id IN ?", ownAppIDs)
if statusFilter != "" {
query = query.Where("status = ?", statusFilter)
}
if err := query.Find(&users).Error; err != nil {
response.Error(c, 500, "获取用户列表失败")
return
}
}
agentAppIDs := make([]uint, len(agentApps))
for i, agentApp := range agentApps {
agentAppIDs[i] = agentApp.ApplicationID
}
var agentAppModels []model.Application
if len(agentAppIDs) > 0 {
database.DB.Where("id IN ?", agentAppIDs).Find(&agentAppModels)
}
agentAppMap := make(map[uint]model.Application)
for _, app := range agentAppModels {
agentAppMap[app.ID] = app
timeout := app.HeartbeatTimeout
if timeout == 0 {
timeout = 300
}
appHeartbeatTimeoutMap[app.ID] = timeout
}
var allCardUserIDs []uint
for _, agentApp := range agentApps {
app, exists := agentAppMap[agentApp.ApplicationID]
if !exists {
continue
}
log.Printf("[DEBUG] Processing agent app: ApplicationID=%d, AppName=%s", app.ID, app.Name)
var cardUserIDs []uint
database.DB.Model(&model.Card{}).
Where("creator_id = ? AND application_id = ? AND app_user_id IS NOT NULL", userID, app.ID).
Pluck("app_user_id", &cardUserIDs)
allCardUserIDs = append(allCardUserIDs, cardUserIDs...)
}
if len(allCardUserIDs) > 0 {
query := database.DB.Preload("Application").Where("id IN ?", allCardUserIDs)
if statusFilter != "" {
query = query.Where("status = ?", statusFilter)
}
var appUsers []model.AppUser
if err := query.Find(&appUsers).Error; err != nil {
log.Printf("[DEBUG] Failed to get users: %v", err)
} else {
users = append(users, appUsers...)
}
}
}
totalCount := len(users)
onlineCount := 0
offlineCount := 0
bannedCount := 0
userIDs := make([]uint, len(users))
for i, u := range users {
userIDs[i] = u.ID
}
deviceCountMap := make(map[uint]int)
if len(userIDs) > 0 {
type DeviceCountResult struct {
UserID uint
Count int
}
var deviceCounts []DeviceCountResult
database.DB.Model(&model.UserDevice{}).
Select("user_id, COUNT(*) as count").
Where("user_id IN ?", userIDs).
Group("user_id").
Find(&deviceCounts)
for _, dc := range deviceCounts {
deviceCountMap[dc.UserID] = dc.Count
}
}
usersWithStatus := make([]UserWithStatus, 0, len(users))
for _, user := range users {
log.Printf("[DEBUG] User ID=%d, Username=%s, LastLoginAt=%v, LastHeartbeatAt=%v", user.ID, user.Username, user.LastLoginAt, user.LastHeartbeatAt)
heartbeatTimeout := 300
if applicationID != "" {
heartbeatTimeout = appHeartbeatTimeoutMap[user.ApplicationID]
} else if appHeartbeatTimeoutMap != nil {
heartbeatTimeout = appHeartbeatTimeoutMap[user.ApplicationID]
}
onlineStatus := getUserOnlineStatus(user, heartbeatTimeout)
switch onlineStatus {
case "online":
onlineCount++
case "offline":
offlineCount++
case "banned":
bannedCount++
}
log.Printf("[DEBUG] 用户 %s (ID=%d) 余额: %f", user.Username, user.ID, user.Balance)
usersWithStatus = append(usersWithStatus, UserWithStatus{
AppUser: user,
OnlineStatus: onlineStatus,
DeviceCount: deviceCountMap[user.ID],
})
}
offset := (page - 1) * pageSize
end := offset + pageSize
if offset > len(usersWithStatus) {
offset = len(usersWithStatus)
}
if end > len(usersWithStatus) {
end = len(usersWithStatus)
}
paginatedUsers := usersWithStatus[offset:end]
responseData := gin.H{
"users": paginatedUsers,
"total": totalCount,
"page": page,
"page_size": pageSize,
"online_count": onlineCount,
"offline_count": offlineCount,
"banned_count": bannedCount,
}
log.Printf("[DEBUG] Response data: %+v", responseData)
response.Success(c, responseData)
}
func handleCreateUser(c *gin.Context) {
userID := c.GetUint("user_id")
var req struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
ApplicationID uint `json:"application_id"`
CardTypeID *uint `json:"card_type_id"`
CardQuantity int `json:"card_quantity"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, 400, "参数错误")
return
}
if req.Username == "" {
response.Error(c, 400, "用户名不能为空")
return
}
if req.Password == "" {
response.Error(c, 400, "密码不能为空")
return
}
if req.ApplicationID == 0 {
response.Error(c, 400, "所属应用不能为空")
return
}
if req.CardQuantity < 1 {
req.CardQuantity = 1
}
if req.CardQuantity > 100 {
response.Error(c, 400, "卡密数量不能超过100")
return
}
var app model.Application
if err := database.DB.First(&app, req.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
if app.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", req.ApplicationID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限在该应用下创建用户")
return
}
}
var existingUser model.AppUser
if err := database.DB.Where("username = ? AND application_id = ?", req.Username, app.ID).First(&existingUser).Error; err == nil {
response.Error(c, 400, "用户已存在")
return
}
var cardType *model.CardType
if req.CardTypeID != nil && *req.CardTypeID > 0 {
var ct model.CardType
if err := database.DB.Where("id = ? AND application_id = ?", *req.CardTypeID, req.ApplicationID).First(&ct).Error; err != nil {
response.Error(c, 400, "卡密类型不存在或不属于该应用")
return
}
cardType = &ct
}
tx := database.DB.Begin()
user := model.AppUser{
Username: req.Username,
Email: req.Email,
Password: req.Password,
Avatar: "",
Status: "active",
ApplicationID: app.ID,
}
if err := tx.Create(&user).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "创建用户失败")
return
}
var cards []model.Card
if cardType != nil {
now := time.Now()
for i := 0; i < req.CardQuantity; i++ {
cardKey := "CK" + utils.GenerateRandomString(16)
card := model.Card{
ApplicationID: req.ApplicationID,
CardTypeID: cardType.ID,
CardKey: cardKey,
CreatorID: userID,
AppUserID: &user.ID,
Status: "used",
}
card.UsedAt = &now
if err := tx.Create(&card).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "生成卡密失败")
return
}
user.IsTrialUser = false
if cardType.Value == -1 {
if cardType.RechargeType == "subscription" {
permanentExpiry := time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
user.ExpiryAt = &permanentExpiry
user.Balance = -1
} else {
user.Balance = -1
user.ExpiryAt = nil
}
} else {
switch cardType.RechargeType {
case "subscription":
var baseTime time.Time
if user.ExpiryAt != nil && user.ExpiryAt.After(now) {
baseTime = *user.ExpiryAt
} else {
baseTime = now
}
var duration time.Duration
switch cardType.ValueUnit {
case "minute":
duration = time.Duration(cardType.Value) * time.Minute
case "hour":
duration = time.Duration(cardType.Value) * time.Hour
case "day":
duration = time.Duration(cardType.Value) * 24 * time.Hour
case "month":
duration = time.Duration(cardType.Value) * 30 * 24 * time.Hour
case "year":
duration = time.Duration(cardType.Value) * 365 * 24 * time.Hour
default:
duration = time.Duration(cardType.Value) * time.Second
}
newExpiry := baseTime.Add(duration)
user.ExpiryAt = &newExpiry
case "balance":
fallthrough
default:
user.Balance += cardType.Value
}
}
rechargeRecord := model.RechargeRecord{
UserID: user.ID,
OrderNo: generateUserOrderNo("R"),
CardID: &card.ID,
CardCode: card.CardKey,
Amount: cardType.Price,
Status: "success",
PaymentType: "card",
Remark: "创建用户充值 - " + cardType.Name,
}
if err := tx.Create(&rechargeRecord).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "创建充值记录失败")
return
}
cards = append(cards, card)
}
if err := tx.Save(&user).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "充值失败")
return
}
}
if err := tx.Commit().Error; err != nil {
response.Error(c, 500, "创建用户失败")
return
}
logDesc := fmt.Sprintf("创建用户: %s (应用: %s)", user.Username, app.Name)
if cardType != nil {
logDesc += fmt.Sprintf(",充值卡密: %s x%d", cardType.Name, req.CardQuantity)
}
service.LogOperation(c, "create", "app_user", &user.ID, logDesc, nil)
result := gin.H{
"user": user,
}
if len(cards) > 0 {
result["cards"] = cards
}
response.Success(c, result)
}
func generateUserOrderNo(prefix string) string {
return prefix + time.Now().Format("20060102150405") + utils.GenerateRandomString(6)
}
func handleGetUser(c *gin.Context) {
userID := c.GetUint("user_id")
id := c.Param("id")
var user model.AppUser
if err := database.DB.Preload("Application").First(&user, id).Error; err != nil {
response.Error(c, 404, "用户不存在")
return
}
var app model.Application
if err := database.DB.First(&app, user.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
if app.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限查看该用户")
return
}
var card model.Card
if err := database.DB.Where("creator_id = ? AND app_user_id = ?", userID, user.ID).First(&card).Error; err != nil {
response.Error(c, 403, "无权限查看该用户")
return
}
}
response.Success(c, gin.H{
"user": user,
})
}
func handleUpdateUser(c *gin.Context) {
userID := c.GetUint("user_id")
id := c.Param("id")
var req struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
Status string `json:"status"`
ApplicationID uint `json:"application_id"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, 400, "参数错误")
return
}
var user model.AppUser
if err := database.DB.First(&user, id).Error; err != nil {
response.Error(c, 404, "用户不存在")
return
}
var app model.Application
if err := database.DB.First(&app, user.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
if app.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限修改该用户")
return
}
var card model.Card
if err := database.DB.Where("creator_id = ? AND app_user_id = ?", userID, user.ID).First(&card).Error; err != nil {
response.Error(c, 403, "无权限修改该用户")
return
}
}
if req.Username != "" {
user.Username = req.Username
}
if req.Email != "" {
user.Email = req.Email
}
if req.Password != "" {
user.Password = req.Password
}
if req.Status != "" {
user.Status = req.Status
}
if req.ApplicationID != 0 {
var newApp model.Application
if err := database.DB.First(&newApp, req.ApplicationID).Error; err != nil {
response.Error(c, 404, "目标应用不存在")
return
}
if newApp.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", req.ApplicationID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限将用户转移到该应用")
return
}
}
user.ApplicationID = req.ApplicationID
}
if err := database.DB.Save(&user).Error; err != nil {
response.Error(c, 500, "更新用户失败")
return
}
service.LogOperation(c, "update", "app_user", &user.ID, fmt.Sprintf("更新用户: %s", user.Username), nil)
response.Success(c, user)
}
func handleDeleteUser(c *gin.Context) {
userID := c.GetUint("user_id")
id := c.Param("id")
var user model.AppUser
if err := database.DB.First(&user, id).Error; err != nil {
response.Error(c, 404, "用户不存在")
return
}
var app model.Application
if err := database.DB.First(&app, user.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
if app.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限删除该用户")
return
}
var card model.Card
if err := database.DB.Where("creator_id = ? AND app_user_id = ?", userID, user.ID).First(&card).Error; err != nil {
response.Error(c, 403, "无权限删除该用户")
return
}
}
if err := database.DB.Delete(&user).Error; err != nil {
response.Error(c, 500, "删除用户失败")
return
}
service.LogOperation(c, "delete", "app_user", &user.ID, fmt.Sprintf("删除用户: %s (应用: %s)", user.Username, app.Name), nil)
response.Success(c, nil)
}
func handleGetUserDevices(c *gin.Context) {
userID := c.GetUint("user_id")
id := c.Param("id")
var user model.AppUser
if err := database.DB.First(&user, id).Error; err != nil {
response.Error(c, 404, "用户不存在")
return
}
var app model.Application
if err := database.DB.First(&app, user.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
if app.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限查看该用户设备")
return
}
}
var devices []model.UserDevice
if err := database.DB.Where("user_id = ? AND application_id = ?", user.ID, app.ID).Find(&devices).Error; err != nil {
response.Error(c, 500, "获取设备列表失败")
return
}
response.Success(c, devices)
}
func handleUpdateExpiry(c *gin.Context) {
userID := c.GetUint("user_id")
id := c.Param("id")
var req struct {
Amount float64 `json:"amount"`
Type string `json:"type"`
Field string `json:"field"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, 400, "参数错误")
return
}
var appUser model.AppUser
if err := database.DB.First(&appUser, id).Error; err != nil {
response.Error(c, 404, "用户不存在")
return
}
var app model.Application
if err := database.DB.First(&app, appUser.ApplicationID).Error; err != nil {
response.Error(c, 404, "应用不存在")
return
}
if app.UserID != userID {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err != nil {
response.Error(c, 403, "无权限修改该用户")
return
}
var card model.Card
if err := database.DB.Where("creator_id = ? AND app_user_id = ?", userID, appUser.ID).First(&card).Error; err != nil {
response.Error(c, 403, "无权限修改该用户")
return
}
}
if req.Amount == 0 {
response.Error(c, 400, "数值不能为0")
return
}
if appUser.Balance == -1 {
response.Error(c, 400, "该用户为永久会员,无需操作")
return
}
now := time.Now()
if app.BillingType == "subscription" || req.Field == "days" {
if req.Type == "recharge" {
var baseTime time.Time
if appUser.ExpiryAt != nil && appUser.ExpiryAt.After(now) {
baseTime = *appUser.ExpiryAt
} else {
baseTime = now
}
duration := time.Duration(req.Amount) * 24 * time.Hour
newExpiry := baseTime.Add(duration)
appUser.ExpiryAt = &newExpiry
} else if req.Type == "deduct" {
if appUser.ExpiryAt == nil || appUser.ExpiryAt.Before(now) {
response.Error(c, 400, "用户订阅已过期")
return
}
duration := time.Duration(req.Amount) * 24 * time.Hour
newExpiry := appUser.ExpiryAt.Add(-duration)
if newExpiry.Before(now) {
newExpiry = now
}
appUser.ExpiryAt = &newExpiry
} else {
response.Error(c, 400, "操作类型错误")
return
}
} else {
if req.Type == "recharge" {
if err := database.DB.Model(&model.AppUser{}).Where("id = ?", appUser.ID).
Update("balance", gorm.Expr("balance + ?", req.Amount)).Error; err != nil {
response.Error(c, 500, "充值失败")
return
}
} else if req.Type == "deduct" {
result := database.DB.Model(&model.AppUser{}).Where("id = ? AND balance >= ?", appUser.ID, req.Amount).
Update("balance", gorm.Expr("balance - ?", req.Amount))
if result.Error != nil {
response.Error(c, 500, "扣费失败")
return
}
if result.RowsAffected == 0 {
response.Error(c, 400, "余额不足")
return
}
} else {
response.Error(c, 400, "操作类型错误")
return
}
}
if app.BillingType == "balance" {
database.DB.Where("id = ?", appUser.ID).First(&appUser)
} else {
if err := database.DB.Save(&appUser).Error; err != nil {
response.Error(c, 500, "更新失败")
return
}
}
response.Success(c, appUser)
}
func handleBatchUpdateStatus(c *gin.Context) {
userID := c.GetUint("user_id")
var req struct {
UserIDs []uint `json:"user_ids"`
Status string `json:"status"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, 400, "参数错误")
return
}
var users []model.AppUser
if err := database.DB.Where("id IN ?", req.UserIDs).Find(&users).Error; err != nil {
response.Error(c, 500, "获取用户列表失败")
return
}
var validUserIDs []uint
for _, user := range users {
var app model.Application
if err := database.DB.First(&app, user.ApplicationID).Error; err != nil {
continue
}
if app.UserID == userID {
validUserIDs = append(validUserIDs, user.ID)
} else {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err == nil {
var card model.Card
if err := database.DB.Where("creator_id = ? AND app_user_id = ?", userID, user.ID).First(&card).Error; err == nil {
validUserIDs = append(validUserIDs, user.ID)
}
}
}
}
if len(validUserIDs) > 0 {
if err := database.DB.Model(&model.AppUser{}).Where("id IN ?", validUserIDs).Update("status", req.Status).Error; err != nil {
response.Error(c, 500, "批量更新状态失败")
return
}
}
response.Success(c, nil)
}
func handleBatchDelete(c *gin.Context) {
userID := c.GetUint("user_id")
var req struct {
UserIDs []uint `json:"user_ids"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, 400, "参数错误")
return
}
var users []model.AppUser
if err := database.DB.Where("id IN ?", req.UserIDs).Find(&users).Error; err != nil {
response.Error(c, 500, "获取用户列表失败")
return
}
var validUserIDs []uint
for _, user := range users {
var app model.Application
if err := database.DB.First(&app, user.ApplicationID).Error; err != nil {
continue
}
if app.UserID == userID {
validUserIDs = append(validUserIDs, user.ID)
} else {
var agentApp model.AgentApplication
if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", app.ID, userID, true).First(&agentApp).Error; err == nil {
var card model.Card
if err := database.DB.Where("creator_id = ? AND app_user_id = ?", userID, user.ID).First(&card).Error; err == nil {
validUserIDs = append(validUserIDs, user.ID)
}
}
}
}
if len(validUserIDs) > 0 {
if err := database.DB.Where("id IN ?", validUserIDs).Delete(&model.AppUser{}).Error; err != nil {
response.Error(c, 500, "批量删除失败")
return
}
}
response.Success(c, nil)
}