feat: 添加用户统计功能,包括统计接口和相关数据结构
This commit is contained in:
@@ -14,6 +14,7 @@ type TenantFilter struct {
|
|||||||
requests.SortQueryFilter
|
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 {
|
type TenantItem struct {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type UserPageFilter struct {
|
|||||||
requests.SortQueryFilter
|
requests.SortQueryFilter
|
||||||
|
|
||||||
Username *string `query:"username"`
|
Username *string `query:"username"`
|
||||||
|
Status *string `query:"status"`
|
||||||
TenantID *int64 `query:"tenant_id"`
|
TenantID *int64 `query:"tenant_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,3 +24,9 @@ type UserItem struct {
|
|||||||
type UserStatusUpdateForm struct {
|
type UserStatusUpdateForm struct {
|
||||||
Status consts.UserStatus `json:"status" validate:"required,oneof=normal disabled"`
|
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"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ func (r *Routes) Register(router fiber.Router) {
|
|||||||
r.user.list,
|
r.user.list,
|
||||||
Query[dto.UserPageFilter]("filter"),
|
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")
|
r.log.Debugf("Registering route: Get /super/v1/users/statuses -> user.statusList")
|
||||||
router.Get("/super/v1/users/statuses", DataFunc0(
|
router.Get("/super/v1/users/statuses", DataFunc0(
|
||||||
r.user.statusList,
|
r.user.statusList,
|
||||||
|
|||||||
@@ -61,3 +61,18 @@ func (*user) statusList(ctx fiber.Ctx) ([]requests.KV, error) {
|
|||||||
return requests.NewKV(item.String(), item.Description())
|
return requests.NewKV(item.String(), item.Description())
|
||||||
}), nil
|
}), 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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,3 +107,19 @@ func (t *user) UpdateStatus(ctx context.Context, userID int64, status consts.Use
|
|||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ const docTemplate = `{
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"name": "page",
|
"name": "page",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -243,6 +248,11 @@ const docTemplate = `{
|
|||||||
"name": "page",
|
"name": "page",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"name": "tenantID",
|
"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": {
|
"/super/v1/users/statuses": {
|
||||||
"get": {
|
"get": {
|
||||||
"consumes": [
|
"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": {
|
"dto.UserStatusUpdateForm": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|||||||
@@ -87,6 +87,11 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"name": "page",
|
"name": "page",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -237,6 +242,11 @@
|
|||||||
"name": "page",
|
"name": "page",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"name": "tenantID",
|
"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": {
|
"/super/v1/users/statuses": {
|
||||||
"get": {
|
"get": {
|
||||||
"consumes": [
|
"consumes": [
|
||||||
@@ -530,6 +565,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.UserStatistics": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"count": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"$ref": "#/definitions/consts.UserStatus"
|
||||||
|
},
|
||||||
|
"status_description": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.UserStatusUpdateForm": {
|
"dto.UserStatusUpdateForm": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|||||||
@@ -134,6 +134,15 @@ definitions:
|
|||||||
verified_at:
|
verified_at:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
dto.UserStatistics:
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
status:
|
||||||
|
$ref: '#/definitions/consts.UserStatus'
|
||||||
|
status_description:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
dto.UserStatusUpdateForm:
|
dto.UserStatusUpdateForm:
|
||||||
properties:
|
properties:
|
||||||
status:
|
status:
|
||||||
@@ -288,6 +297,9 @@ paths:
|
|||||||
- in: query
|
- in: query
|
||||||
name: page
|
name: page
|
||||||
type: integer
|
type: integer
|
||||||
|
- in: query
|
||||||
|
name: status
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -382,6 +394,9 @@ paths:
|
|||||||
- in: query
|
- in: query
|
||||||
name: page
|
name: page
|
||||||
type: integer
|
type: integer
|
||||||
|
- in: query
|
||||||
|
name: status
|
||||||
|
type: string
|
||||||
- in: query
|
- in: query
|
||||||
name: tenantID
|
name: tenantID
|
||||||
type: integer
|
type: integer
|
||||||
@@ -426,6 +441,22 @@ paths:
|
|||||||
summary: 更新用户状态
|
summary: 更新用户状态
|
||||||
tags:
|
tags:
|
||||||
- Super
|
- 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:
|
/super/v1/users/statuses:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|||||||
Reference in New Issue
Block a user