feat: add audit logs and system configs

This commit is contained in:
2026-01-15 20:07:36 +08:00
parent 914df9edf2
commit b3fc226bbe
25 changed files with 3325 additions and 108 deletions

View File

@@ -0,0 +1,28 @@
package v1
import (
dto "quyun/v2/app/http/super/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"github.com/gofiber/fiber/v3"
)
// @provider
type auditLogs struct{}
// List audit logs
//
// @Router /super/v1/audit-logs [get]
// @Summary List audit logs
// @Description List audit logs across tenants
// @Tags Audit
// @Accept json
// @Produce json
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.SuperAuditLogItem}
// @Bind filter query
func (c *auditLogs) List(ctx fiber.Ctx, filter *dto.SuperAuditLogListFilter) (*requests.Pager, error) {
return services.Super.ListAuditLogs(ctx, filter)
}

View File

@@ -0,0 +1,117 @@
package dto
import (
"encoding/json"
"quyun/v2/app/requests"
)
// SuperAuditLogListFilter 超管审计日志列表过滤条件。
type SuperAuditLogListFilter struct {
requests.Pagination
// ID 审计日志ID精确匹配。
ID *int64 `query:"id"`
// TenantID 租户ID过滤。
TenantID *int64 `query:"tenant_id"`
// TenantCode 租户编码,模糊匹配。
TenantCode *string `query:"tenant_code"`
// TenantName 租户名称,模糊匹配。
TenantName *string `query:"tenant_name"`
// OperatorID 操作者用户ID精确匹配。
OperatorID *int64 `query:"operator_id"`
// OperatorName 操作者用户名/昵称,模糊匹配。
OperatorName *string `query:"operator_name"`
// Action 动作标识过滤,精确匹配。
Action *string `query:"action"`
// TargetID 目标ID过滤精确匹配。
TargetID *string `query:"target_id"`
// Keyword 详情关键词,模糊匹配。
Keyword *string `query:"keyword"`
// CreatedAtFrom 创建时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 创建时间结束RFC3339
CreatedAtTo *string `query:"created_at_to"`
// Asc 升序字段id/created_at
Asc *string `query:"asc"`
// Desc 降序字段id/created_at
Desc *string `query:"desc"`
}
// SuperAuditLogItem 超管审计日志条目。
type SuperAuditLogItem struct {
// ID 审计日志ID。
ID int64 `json:"id"`
// TenantID 租户ID。
TenantID int64 `json:"tenant_id"`
// TenantCode 租户编码。
TenantCode string `json:"tenant_code"`
// TenantName 租户名称。
TenantName string `json:"tenant_name"`
// OperatorID 操作者用户ID。
OperatorID int64 `json:"operator_id"`
// OperatorName 操作者用户名/昵称。
OperatorName string `json:"operator_name"`
// Action 动作标识。
Action string `json:"action"`
// TargetID 目标ID。
TargetID string `json:"target_id"`
// Detail 操作详情。
Detail string `json:"detail"`
// CreatedAt 创建时间RFC3339
CreatedAt string `json:"created_at"`
}
// SuperSystemConfigListFilter 超管系统配置列表过滤条件。
type SuperSystemConfigListFilter struct {
requests.Pagination
// ConfigKey 配置Key精确匹配。
ConfigKey *string `query:"config_key"`
// Keyword Key或描述关键词模糊匹配。
Keyword *string `query:"keyword"`
// CreatedAtFrom 创建时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 创建时间结束RFC3339
CreatedAtTo *string `query:"created_at_to"`
// UpdatedAtFrom 更新时间起始RFC3339
UpdatedAtFrom *string `query:"updated_at_from"`
// UpdatedAtTo 更新时间结束RFC3339
UpdatedAtTo *string `query:"updated_at_to"`
// Asc 升序字段id/config_key/updated_at
Asc *string `query:"asc"`
// Desc 降序字段id/config_key/updated_at
Desc *string `query:"desc"`
}
// SuperSystemConfigCreateForm 超管系统配置创建参数。
type SuperSystemConfigCreateForm struct {
// ConfigKey 配置项Key唯一
ConfigKey string `json:"config_key"`
// Value 配置值JSON
Value json.RawMessage `json:"value"`
// Description 配置说明。
Description string `json:"description"`
}
// SuperSystemConfigUpdateForm 超管系统配置更新参数。
type SuperSystemConfigUpdateForm struct {
// Value 配置值JSON可选
Value *json.RawMessage `json:"value"`
// Description 配置说明(可选)。
Description *string `json:"description"`
}
// SuperSystemConfigItem 超管系统配置条目。
type SuperSystemConfigItem struct {
// ID 配置ID。
ID int64 `json:"id"`
// ConfigKey 配置项Key。
ConfigKey string `json:"config_key"`
// Value 配置值JSON
Value json.RawMessage `json:"value"`
// Description 配置说明。
Description string `json:"description"`
// CreatedAt 创建时间RFC3339
CreatedAt string `json:"created_at"`
// UpdatedAt 更新时间RFC3339
UpdatedAt string `json:"updated_at"`
}

View File

@@ -17,6 +17,13 @@ func Provide(opts ...opt.Option) error {
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*auditLogs, error) {
obj := &auditLogs{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*contents, error) {
obj := &contents{}
@@ -75,6 +82,7 @@ func Provide(opts ...opt.Option) error {
}
if err := container.Container.Provide(func(
assets *assets,
auditLogs *auditLogs,
contents *contents,
coupons *coupons,
creatorApplications *creatorApplications,
@@ -84,12 +92,14 @@ func Provide(opts ...opt.Option) error {
orders *orders,
payoutAccounts *payoutAccounts,
reports *reports,
systemConfigs *systemConfigs,
tenants *tenants,
users *users,
withdrawals *withdrawals,
) (contracts.HttpRoute, error) {
obj := &Routes{
assets: assets,
auditLogs: auditLogs,
contents: contents,
coupons: coupons,
creatorApplications: creatorApplications,
@@ -99,6 +109,7 @@ func Provide(opts ...opt.Option) error {
orders: orders,
payoutAccounts: payoutAccounts,
reports: reports,
systemConfigs: systemConfigs,
tenants: tenants,
users: users,
withdrawals: withdrawals,
@@ -111,6 +122,13 @@ func Provide(opts ...opt.Option) error {
}, atom.GroupRoutes); err != nil {
return err
}
if err := container.Container.Provide(func() (*systemConfigs, error) {
obj := &systemConfigs{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*tenants, error) {
obj := &tenants{}

View File

@@ -26,6 +26,7 @@ type Routes struct {
middlewares *middlewares.Middlewares
// Controller instances
assets *assets
auditLogs *auditLogs
contents *contents
coupons *coupons
creatorApplications *creatorApplications
@@ -34,6 +35,7 @@ type Routes struct {
orders *orders
payoutAccounts *payoutAccounts
reports *reports
systemConfigs *systemConfigs
tenants *tenants
users *users
withdrawals *withdrawals
@@ -71,6 +73,12 @@ func (r *Routes) Register(router fiber.Router) {
r.assets.Usage,
Query[dto.SuperAssetUsageFilter]("filter"),
))
// Register routes for controller: auditLogs
r.log.Debugf("Registering route: Get /super/v1/audit-logs -> auditLogs.List")
router.Get("/super/v1/audit-logs"[len(r.Path()):], DataFunc1(
r.auditLogs.List,
Query[dto.SuperAuditLogListFilter]("filter"),
))
// Register routes for controller: contents
r.log.Debugf("Registering route: Get /super/v1/contents -> contents.List")
router.Get("/super/v1/contents"[len(r.Path()):], DataFunc1(
@@ -243,6 +251,25 @@ func (r *Routes) Register(router fiber.Router) {
r.reports.Export,
Body[dto.SuperReportExportForm]("form"),
))
// Register routes for controller: systemConfigs
r.log.Debugf("Registering route: Get /super/v1/system-configs -> systemConfigs.List")
router.Get("/super/v1/system-configs"[len(r.Path()):], DataFunc1(
r.systemConfigs.List,
Query[dto.SuperSystemConfigListFilter]("filter"),
))
r.log.Debugf("Registering route: Patch /super/v1/system-configs/:id<int> -> systemConfigs.Update")
router.Patch("/super/v1/system-configs/:id<int>"[len(r.Path()):], DataFunc3(
r.systemConfigs.Update,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.SuperSystemConfigUpdateForm]("form"),
))
r.log.Debugf("Registering route: Post /super/v1/system-configs -> systemConfigs.Create")
router.Post("/super/v1/system-configs"[len(r.Path()):], DataFunc2(
r.systemConfigs.Create,
Local[*models.User]("__ctx_user"),
Body[dto.SuperSystemConfigCreateForm]("form"),
))
// Register routes for controller: tenants
r.log.Debugf("Registering route: Get /super/v1/tenant-join-requests -> tenants.ListJoinRequests")
router.Get("/super/v1/tenant-join-requests"[len(r.Path()):], DataFunc1(

View File

@@ -0,0 +1,63 @@
package v1
import (
dto "quyun/v2/app/http/super/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"quyun/v2/database/models"
"github.com/gofiber/fiber/v3"
)
// @provider
type systemConfigs struct{}
// List system configs
//
// @Router /super/v1/system-configs [get]
// @Summary List system configs
// @Description List platform system configs
// @Tags SystemConfig
// @Accept json
// @Produce json
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.SuperSystemConfigItem}
// @Bind filter query
func (c *systemConfigs) List(ctx fiber.Ctx, filter *dto.SuperSystemConfigListFilter) (*requests.Pager, error) {
return services.Super.ListSystemConfigs(ctx, filter)
}
// Create system config
//
// @Router /super/v1/system-configs [post]
// @Summary Create system config
// @Description Create platform system config
// @Tags SystemConfig
// @Accept json
// @Produce json
// @Param form body dto.SuperSystemConfigCreateForm true "Create form"
// @Success 200 {object} dto.SuperSystemConfigItem
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *systemConfigs) Create(ctx fiber.Ctx, user *models.User, form *dto.SuperSystemConfigCreateForm) (*dto.SuperSystemConfigItem, error) {
return services.Super.CreateSystemConfig(ctx, user.ID, form)
}
// Update system config
//
// @Router /super/v1/system-configs/:id<int> [patch]
// @Summary Update system config
// @Description Update platform system config
// @Tags SystemConfig
// @Accept json
// @Produce json
// @Param id path int64 true "Config ID"
// @Param form body dto.SuperSystemConfigUpdateForm true "Update form"
// @Success 200 {object} dto.SuperSystemConfigItem
// @Bind user local key(__ctx_user)
// @Bind id path
// @Bind form body
func (c *systemConfigs) Update(ctx fiber.Ctx, user *models.User, id int64, form *dto.SuperSystemConfigUpdateForm) (*dto.SuperSystemConfigItem, error) {
return services.Super.UpdateSystemConfig(ctx, user.ID, id, form)
}