feat: 添加用户统计功能,包括统计接口和相关数据结构

This commit is contained in:
2025-12-17 14:57:03 +08:00
parent 9efd188628
commit e4c8deaacf
9 changed files with 185 additions and 1 deletions

View File

@@ -13,7 +13,8 @@ type TenantFilter struct {
requests.Pagination
requests.SortQueryFilter
Name *string `json:"name,omitempty" query:"name"`
Name *string `json:"name,omitempty" query:"name"`
Status *string `json:"status,omitempty" query:"status"`
}
type TenantItem struct {

View File

@@ -11,6 +11,7 @@ type UserPageFilter struct {
requests.SortQueryFilter
Username *string `query:"username"`
Status *string `query:"status"`
TenantID *int64 `query:"tenant_id"`
}
@@ -23,3 +24,9 @@ type UserItem struct {
type UserStatusUpdateForm struct {
Status consts.UserStatus `json:"status" validate:"required,oneof=normal disabled"`
}
type UserStatistics struct {
Status consts.UserStatus `json:"status"`
StatusDescription string `json:"status_description"`
Count int64 `json:"count"`
}

View File

@@ -74,6 +74,10 @@ func (r *Routes) Register(router fiber.Router) {
r.user.list,
Query[dto.UserPageFilter]("filter"),
))
r.log.Debugf("Registering route: Get /super/v1/users/statistics -> user.statistics")
router.Get("/super/v1/users/statistics", DataFunc0(
r.user.statistics,
))
r.log.Debugf("Registering route: Get /super/v1/users/statuses -> user.statusList")
router.Get("/super/v1/users/statuses", DataFunc0(
r.user.statusList,

View File

@@ -61,3 +61,18 @@ func (*user) statusList(ctx fiber.Ctx) ([]requests.KV, error) {
return requests.NewKV(item.String(), item.Description())
}), nil
}
// statistics
//
// @Summary 用户统计信息
// @Tags Super
// @Accept json
// @Produce json
// @Success 200 {array} dto.UserStatistics
//
// @Router /super/v1/users/statistics [get]
// @Bind userID path
// @Bind form body
func (*user) statistics(ctx fiber.Ctx) ([]*dto.UserStatistics, error) {
return services.User.Statistics(ctx)
}

View File

@@ -107,3 +107,19 @@ func (t *user) UpdateStatus(ctx context.Context, userID int64, status consts.Use
return nil
}
// Statistics
func (t *user) Statistics(ctx context.Context) ([]*dto.UserStatistics, error) {
tbl, query := models.UserQuery.QueryContext(ctx)
var statistics []*dto.UserStatistics
err := query.Select(tbl.Status, tbl.ID.Count().As("count")).Group(tbl.Status).Scan(&statistics)
if err != nil {
return nil, err
}
return lo.Map(statistics, func(item *dto.UserStatistics, _ int) *dto.UserStatistics {
item.StatusDescription = item.Status.Description()
return item
}), nil
}

View File

@@ -261,3 +261,15 @@ func (t *UserTestSuite) Test_Relations() {
})
})
}
func (t *UserTestSuite) Test_Statistics() {
Convey("test page", t.T(), func() {
Convey("filter tenant users", func() {
m, err := User.Statistics(t.T().Context())
So(err, ShouldBeNil)
// So(m.OwnedTenant, ShouldNotBeNil)
// So(m.Tenants, ShouldHaveLength, 10)
t.T().Logf("%s", utils.MustJsonString(m))
})
})
}

View File

@@ -93,6 +93,11 @@ const docTemplate = `{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "string",
"name": "status",
"in": "query"
}
],
"responses": {
@@ -243,6 +248,11 @@ const docTemplate = `{
"name": "page",
"in": "query"
},
{
"type": "string",
"name": "status",
"in": "query"
},
{
"type": "integer",
"name": "tenantID",
@@ -276,6 +286,31 @@ const docTemplate = `{
}
}
},
"/super/v1/users/statistics": {
"get": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Super"
],
"summary": "用户统计信息",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.UserStatistics"
}
}
}
}
}
},
"/super/v1/users/statuses": {
"get": {
"consumes": [
@@ -536,6 +571,20 @@ const docTemplate = `{
}
}
},
"dto.UserStatistics": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"status": {
"$ref": "#/definitions/consts.UserStatus"
},
"status_description": {
"type": "string"
}
}
},
"dto.UserStatusUpdateForm": {
"type": "object",
"required": [

View File

@@ -87,6 +87,11 @@
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "string",
"name": "status",
"in": "query"
}
],
"responses": {
@@ -237,6 +242,11 @@
"name": "page",
"in": "query"
},
{
"type": "string",
"name": "status",
"in": "query"
},
{
"type": "integer",
"name": "tenantID",
@@ -270,6 +280,31 @@
}
}
},
"/super/v1/users/statistics": {
"get": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Super"
],
"summary": "用户统计信息",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.UserStatistics"
}
}
}
}
}
},
"/super/v1/users/statuses": {
"get": {
"consumes": [
@@ -530,6 +565,20 @@
}
}
},
"dto.UserStatistics": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"status": {
"$ref": "#/definitions/consts.UserStatus"
},
"status_description": {
"type": "string"
}
}
},
"dto.UserStatusUpdateForm": {
"type": "object",
"required": [

View File

@@ -134,6 +134,15 @@ definitions:
verified_at:
type: string
type: object
dto.UserStatistics:
properties:
count:
type: integer
status:
$ref: '#/definitions/consts.UserStatus'
status_description:
type: string
type: object
dto.UserStatusUpdateForm:
properties:
status:
@@ -288,6 +297,9 @@ paths:
- in: query
name: page
type: integer
- in: query
name: status
type: string
produces:
- application/json
responses:
@@ -382,6 +394,9 @@ paths:
- in: query
name: page
type: integer
- in: query
name: status
type: string
- in: query
name: tenantID
type: integer
@@ -426,6 +441,22 @@ paths:
summary: 更新用户状态
tags:
- Super
/super/v1/users/statistics:
get:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/dto.UserStatistics'
type: array
summary: 用户统计信息
tags:
- Super
/super/v1/users/statuses:
get:
consumes: