feat: complete superadmin management endpoints

This commit is contained in:
2026-01-09 09:52:23 +08:00
parent 3e095c57f3
commit c0cebb6fb9
6 changed files with 877 additions and 33 deletions

View File

@@ -27,6 +27,28 @@ func (c *contents) List(ctx fiber.Ctx, filter *dto.SuperContentListFilter) (*req
return services.Super.ListContents(ctx, filter)
}
// List tenant contents
//
// @Router /super/v1/tenants/:tenantID<int>/contents [get]
// @Summary List tenant contents
// @Description List contents by tenant
// @Tags Content
// @Accept json
// @Produce json
// @Param tenantID path int64 true "Tenant ID"
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.AdminContentItem}
// @Bind tenantID path
// @Bind filter query
func (c *contents) ListTenantContents(ctx fiber.Ctx, tenantID int64, filter *dto.SuperContentListFilter) (*requests.Pager, error) {
if filter == nil {
filter = &dto.SuperContentListFilter{}
}
filter.TenantID = &tenantID
return services.Super.ListContents(ctx, filter)
}
// Update content status
//
// @Router /super/v1/tenants/:tenantID<int>/contents/:contentID<int>/status [patch]

View File

@@ -9,12 +9,88 @@ import (
// Filters
type UserListFilter struct {
requests.Pagination
// ID 用户ID精确匹配。
ID *int64 `query:"id"`
// TenantID 租户ID筛选加入该租户的用户。
TenantID *int64 `query:"tenant_id"`
// Username 用户名/昵称,模糊匹配。
Username *string `query:"username"`
// Status 用户状态过滤。
Status *consts.UserStatus `query:"status"`
// Role 角色过滤roles 包含该角色)。
Role *consts.Role `query:"role"`
// CreatedAtFrom 创建时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 创建时间结束RFC3339
CreatedAtTo *string `query:"created_at_to"`
// VerifiedAtFrom 认证时间起始RFC3339
VerifiedAtFrom *string `query:"verified_at_from"`
// VerifiedAtTo 认证时间结束RFC3339
VerifiedAtTo *string `query:"verified_at_to"`
// Asc 升序字段id/username/status/created_at/verified_at
Asc *string `query:"asc"`
// Desc 降序字段id/username/status/created_at/verified_at
Desc *string `query:"desc"`
}
type TenantListFilter struct {
requests.Pagination
// ID 租户ID精确匹配。
ID *int64 `query:"id"`
// UserID 租户所有者用户ID精确匹配。
UserID *int64 `query:"user_id"`
// Name 租户名称,模糊匹配。
Name *string `query:"name"`
// Code 租户编码,模糊匹配。
Code *string `query:"code"`
// Status 租户状态过滤。
Status *consts.TenantStatus `query:"status"`
// ExpiredAtFrom 过期时间起始RFC3339
ExpiredAtFrom *string `query:"expired_at_from"`
// ExpiredAtTo 过期时间结束RFC3339
ExpiredAtTo *string `query:"expired_at_to"`
// CreatedAtFrom 创建时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 创建时间结束RFC3339
CreatedAtTo *string `query:"created_at_to"`
// Asc 升序字段id/name/code/status/expired_at/created_at
Asc *string `query:"asc"`
// Desc 降序字段id/name/code/status/expired_at/created_at
Desc *string `query:"desc"`
}
type SuperTenantUserListFilter struct {
requests.Pagination
// UserID 用户ID精确匹配。
UserID *int64 `query:"user_id"`
// Username 用户名/昵称,模糊匹配。
Username *string `query:"username"`
// Role 成员角色过滤role 包含该角色)。
Role *consts.TenantUserRole `query:"role"`
// Status 成员状态过滤。
Status *consts.UserStatus `query:"status"`
}
type SuperUserTenantListFilter struct {
requests.Pagination
// TenantID 租户ID精确匹配。
TenantID *int64 `query:"tenant_id"`
// Code 租户编码,模糊匹配。
Code *string `query:"code"`
// Name 租户名称,模糊匹配。
Name *string `query:"name"`
// Role 成员角色过滤role 包含该角色)。
Role *consts.TenantUserRole `query:"role"`
// Status 成员状态过滤。
Status *consts.UserStatus `query:"status"`
// CreatedAtFrom 加入时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 加入时间结束RFC3339
CreatedAtTo *string `query:"created_at_to"`
// Asc 升序字段tenant_id/created_at
Asc *string `query:"asc"`
// Desc 降序字段tenant_id/created_at
Desc *string `query:"desc"`
}
type SuperContentListFilter struct {

View File

@@ -50,6 +50,12 @@ func (r *Routes) Register(router fiber.Router) {
r.contents.List,
Query[dto.SuperContentListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /super/v1/tenants/:tenantID<int>/contents -> contents.ListTenantContents")
router.Get("/super/v1/tenants/:tenantID<int>/contents"[len(r.Path()):], DataFunc2(
r.contents.ListTenantContents,
PathParam[int64]("tenantID"),
Query[dto.SuperContentListFilter]("filter"),
))
r.log.Debugf("Registering route: Patch /super/v1/tenants/:tenantID<int>/contents/:contentID<int>/status -> contents.UpdateStatus")
router.Patch("/super/v1/tenants/:tenantID<int>/contents/:contentID<int>/status"[len(r.Path()):], Func3(
r.contents.UpdateStatus,
@@ -89,6 +95,12 @@ func (r *Routes) Register(router fiber.Router) {
r.tenants.Get,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /super/v1/tenants/:tenantID<int>/users -> tenants.ListUsers")
router.Get("/super/v1/tenants/:tenantID<int>/users"[len(r.Path()):], DataFunc2(
r.tenants.ListUsers,
PathParam[int64]("tenantID"),
Query[dto.SuperTenantUserListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /super/v1/tenants/statuses -> tenants.Statuses")
router.Get("/super/v1/tenants/statuses"[len(r.Path()):], DataFunc0(
r.tenants.Statuses,
@@ -121,6 +133,12 @@ func (r *Routes) Register(router fiber.Router) {
r.users.Get,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /super/v1/users/:id<int>/tenants -> users.ListTenants")
router.Get("/super/v1/users/:id<int>/tenants"[len(r.Path()):], DataFunc2(
r.users.ListTenants,
PathParam[int64]("id"),
Query[dto.SuperUserTenantListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /super/v1/users/statistics -> users.Statistics")
router.Get("/super/v1/users/statistics"[len(r.Path()):], DataFunc0(
r.users.Statistics,

View File

@@ -28,6 +28,24 @@ func (c *tenants) List(ctx fiber.Ctx, filter *dto.TenantListFilter) (*requests.P
return services.Super.ListTenants(ctx, filter)
}
// List tenant users
//
// @Router /super/v1/tenants/:tenantID<int>/users [get]
// @Summary List tenant users
// @Description List tenant users
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenantID path int64 true "Tenant ID"
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.SuperTenantUserItem}
// @Bind tenantID path
// @Bind filter query
func (c *tenants) ListUsers(ctx fiber.Ctx, tenantID int64, filter *dto.SuperTenantUserListFilter) (*requests.Pager, error) {
return services.Super.ListTenantUsers(ctx, tenantID, filter)
}
// Create tenant
//
// @Router /super/v1/tenants [post]

View File

@@ -43,6 +43,24 @@ func (c *users) Get(ctx fiber.Ctx, id int64) (*dto.UserItem, error) {
return services.Super.GetUser(ctx, id)
}
// List user tenants
//
// @Router /super/v1/users/:id<int>/tenants [get]
// @Summary List user tenants
// @Description List tenants joined by user
// @Tags User
// @Accept json
// @Produce json
// @Param id path int64 true "User ID"
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.UserTenantItem}
// @Bind id path
// @Bind filter query
func (c *users) ListTenants(ctx fiber.Ctx, id int64, filter *dto.SuperUserTenantListFilter) (*requests.Pager, error) {
return services.Super.ListUserTenants(ctx, id, filter)
}
// Update user status
//
// @Router /super/v1/users/:id<int>/status [patch]