package handlers import ( "strconv" "github.com/gin-gonic/gin" "go.uber.org/zap" subordinate_app "tyapi-server/internal/application/subordinate" "tyapi-server/internal/application/subordinate/dto/commands" "tyapi-server/internal/shared/interfaces" ) // SubordinateHandler 下属账号 type SubordinateHandler struct { app subordinate_app.SubordinateApplicationService response interfaces.ResponseBuilder validator interfaces.RequestValidator logger *zap.Logger } // NewSubordinateHandler 构造 func NewSubordinateHandler( app subordinate_app.SubordinateApplicationService, response interfaces.ResponseBuilder, validator interfaces.RequestValidator, logger *zap.Logger, ) *SubordinateHandler { return &SubordinateHandler{app: app, response: response, validator: validator, logger: logger} } // SubPortalRegister 子站注册 func (h *SubordinateHandler) SubPortalRegister(c *gin.Context) { var cmd commands.SubPortalRegisterCommand if err := h.validator.BindAndValidate(c, &cmd); err != nil { return } res, err := h.app.RegisterSubPortal(c.Request.Context(), &cmd) if err != nil { h.logger.Error("子站注册失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Created(c, res, "注册成功") } // CreateInvitation 主账号创建邀请 func (h *SubordinateHandler) CreateInvitation(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } var body struct { ExpiresInHours int `json:"expires_in_hours"` } _ = c.ShouldBindJSON(&body) res, err := h.app.CreateInvitation(c.Request.Context(), &commands.CreateInvitationCommand{ ParentUserID: parentID, ExpiresInHours: body.ExpiresInHours, }) if err != nil { h.logger.Error("创建邀请失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, res, "邀请已创建") } // ListSubordinates 下属列表 func (h *SubordinateHandler) ListSubordinates(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) res, err := h.app.ListMySubordinates(c.Request.Context(), parentID, page, size) if err != nil { h.logger.Error("获取下属列表失败", zap.Error(err)) h.response.InternalError(c, "获取下属列表失败") return } h.response.Success(c, res, "获取成功") } // Allocate 划款 func (h *SubordinateHandler) Allocate(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } var cmd commands.AllocateToChildCommand if err := h.validator.BindAndValidate(c, &cmd); err != nil { return } cmd.ParentUserID = parentID if err := h.app.AllocateToChild(c.Request.Context(), &cmd); err != nil { h.logger.Error("划拨失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, nil, "划拨成功") } // ListAllocations 下属划拨记录 func (h *SubordinateHandler) ListAllocations(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) cmd := &commands.ListChildAllocationsCommand{ ParentUserID: parentID, ChildUserID: c.Query("child_user_id"), Page: page, PageSize: size, } if cmd.ChildUserID == "" { h.response.BadRequest(c, "child_user_id 不能为空") return } res, err := h.app.ListChildAllocations(c.Request.Context(), cmd) if err != nil { h.logger.Error("获取划拨记录失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, res, "获取成功") } // AssignSubscription 代配订阅 func (h *SubordinateHandler) AssignSubscription(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } var cmd commands.AssignChildSubscriptionCommand if err := h.validator.BindAndValidate(c, &cmd); err != nil { return } cmd.ParentUserID = parentID if err := h.app.AssignChildSubscription(c.Request.Context(), &cmd); err != nil { h.logger.Error("代配订阅失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, nil, "已保存下属订阅") } // ListChildSubscriptions 下属订阅列表 func (h *SubordinateHandler) ListChildSubscriptions(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } childID := c.Query("child_user_id") if childID == "" { h.response.BadRequest(c, "child_user_id 不能为空") return } res, err := h.app.ListChildSubscriptions(c.Request.Context(), &commands.ListChildSubscriptionsCommand{ ParentUserID: parentID, ChildUserID: childID, }) if err != nil { h.logger.Error("获取下属订阅失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, res, "获取成功") } // RemoveChildSubscription 删除下属订阅 func (h *SubordinateHandler) RemoveChildSubscription(c *gin.Context) { parentID := c.GetString("user_id") if parentID == "" { h.response.Unauthorized(c, "未登录") return } var body struct { ChildUserID string `json:"child_user_id"` } _ = c.ShouldBindJSON(&body) if body.ChildUserID == "" { h.response.BadRequest(c, "child_user_id 不能为空") return } subID := c.Param("subscription_id") if subID == "" { h.response.BadRequest(c, "subscription_id 不能为空") return } err := h.app.RemoveChildSubscription(c.Request.Context(), &commands.RemoveChildSubscriptionCommand{ ParentUserID: parentID, ChildUserID: body.ChildUserID, SubscriptionID: subID, }) if err != nil { h.logger.Error("删除下属订阅失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, nil, "删除成功") }