2026-04-28 14:53:04 +08:00
|
|
|
|
package handler
|
2026-03-14 18:01:55 +08:00
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
2026-04-22 16:01:59 +08:00
|
|
|
|
"with_you/internal/dto"
|
|
|
|
|
|
"with_you/internal/model"
|
|
|
|
|
|
"with_you/internal/pkg/response"
|
|
|
|
|
|
"with_you/internal/service"
|
2026-03-14 18:01:55 +08:00
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// AdminUserHandler 管理端用户处理器
|
|
|
|
|
|
type AdminUserHandler struct {
|
|
|
|
|
|
adminUserService service.AdminUserService
|
2026-06-18 20:07:24 +08:00
|
|
|
|
pushService service.PushService
|
2026-03-14 18:01:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewAdminUserHandler 创建管理端用户处理器
|
2026-06-18 20:07:24 +08:00
|
|
|
|
func NewAdminUserHandler(adminUserService service.AdminUserService, pushService service.PushService) *AdminUserHandler {
|
2026-03-14 18:01:55 +08:00
|
|
|
|
return &AdminUserHandler{
|
|
|
|
|
|
adminUserService: adminUserService,
|
2026-06-18 20:07:24 +08:00
|
|
|
|
pushService: pushService,
|
2026-03-14 18:01:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetUserList 获取用户列表
|
|
|
|
|
|
// GET /api/v1/admin/users
|
|
|
|
|
|
func (h *AdminUserHandler) GetUserList(c *gin.Context) {
|
|
|
|
|
|
// 解析分页参数
|
|
|
|
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
|
|
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
|
|
|
|
|
|
|
|
|
|
|
if page <= 0 {
|
|
|
|
|
|
page = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
if pageSize <= 0 || pageSize > 100 {
|
|
|
|
|
|
pageSize = 20
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取筛选参数
|
|
|
|
|
|
keyword := c.Query("keyword")
|
|
|
|
|
|
status := c.Query("status")
|
|
|
|
|
|
|
|
|
|
|
|
// 验证状态参数
|
|
|
|
|
|
if status != "" && status != string(model.UserStatusActive) && status != string(model.UserStatusBanned) {
|
|
|
|
|
|
response.BadRequest(c, "invalid status value")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
users, total, err := h.adminUserService.GetUserList(c.Request.Context(), page, pageSize, keyword, status)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
response.InternalServerError(c, "failed to get user list")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response.Paginated(c, users, total, page, pageSize)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetUserDetail 获取用户详情
|
|
|
|
|
|
// GET /api/v1/admin/users/:id
|
|
|
|
|
|
func (h *AdminUserHandler) GetUserDetail(c *gin.Context) {
|
|
|
|
|
|
userID := c.Param("id")
|
|
|
|
|
|
if userID == "" {
|
|
|
|
|
|
response.BadRequest(c, "user id is required")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
userDetail, err := h.adminUserService.GetUserDetail(c.Request.Context(), userID)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
response.NotFound(c, "user not found")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response.Success(c, userDetail)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UpdateUserStatus 更新用户状态
|
|
|
|
|
|
// PUT /api/v1/admin/users/:id/status
|
|
|
|
|
|
func (h *AdminUserHandler) UpdateUserStatus(c *gin.Context) {
|
|
|
|
|
|
userID := c.Param("id")
|
|
|
|
|
|
if userID == "" {
|
|
|
|
|
|
response.BadRequest(c, "user id is required")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var req dto.AdminUpdateUserStatusRequest
|
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
|
response.BadRequest(c, "invalid request body: "+err.Error())
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证状态值
|
|
|
|
|
|
if req.Status != string(model.UserStatusActive) && req.Status != string(model.UserStatusBanned) {
|
|
|
|
|
|
response.BadRequest(c, "invalid status value, must be 'active' or 'banned'")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
userDetail, err := h.adminUserService.UpdateUserStatus(c.Request.Context(), userID, model.UserStatus(req.Status))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
response.HandleError(c, err, "failed to update user status")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response.Success(c, userDetail)
|
|
|
|
|
|
}
|
2026-06-18 20:07:24 +08:00
|
|
|
|
|
|
|
|
|
|
// GetUserDevices 获取用户设备列表(含 registration_id)
|
|
|
|
|
|
// GET /api/v1/admin/users/:id/devices
|
|
|
|
|
|
// 供后台查询目标用户各设备的 JPush RegistrationID(push_token),用于排查推送问题或手动推送测试。
|
|
|
|
|
|
func (h *AdminUserHandler) GetUserDevices(c *gin.Context) {
|
|
|
|
|
|
userID := c.Param("id")
|
|
|
|
|
|
if userID == "" {
|
|
|
|
|
|
response.BadRequest(c, "user id is required")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
devices, err := h.pushService.GetUserDevices(c.Request.Context(), userID)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
response.InternalServerError(c, "failed to get user devices")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response.Success(c, dto.DeviceTokensToAdminResponse(devices))
|
|
|
|
|
|
}
|