From 4a821c1fcad30903c496e3366e564e8a5d98c327 Mon Sep 17 00:00:00 2001 From: yangzhongjiao Date: Tue, 6 Jan 2026 05:41:20 +0000 Subject: [PATCH 1/5] feat(user): add filtering options for email, phone, status, authentication type, and system in user listing requests --- internal/dms/service/user.go | 45 +++++++++++++++++++++++++++++++ pkg/dms-common/api/dms/v1/user.go | 15 +++++++++++ pkg/dms-common/dmsobject/user.go | 45 ++++++++++++++++++++++++++++--- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/internal/dms/service/user.go b/internal/dms/service/user.go index 4279e741..27cfc978 100644 --- a/internal/dms/service/user.go +++ b/internal/dms/service/user.go @@ -209,6 +209,51 @@ func (d *DMSService) ListUsers(ctx context.Context, req *dmsCommonV1.ListUserReq }) } + // 按邮箱过滤 + if req.FilterByEmail != "" { + andConditions = append(andConditions, pkgConst.FilterCondition{ + Field: string(biz.UserFieldEmail), + Operator: pkgConst.FilterOperatorContains, + Value: req.FilterByEmail, + }) + } + + // 按手机号过滤 + if req.FilterByPhone != "" { + andConditions = append(andConditions, pkgConst.FilterCondition{ + Field: string(biz.UserFieldPhone), + Operator: pkgConst.FilterOperatorContains, + Value: req.FilterByPhone, + }) + } + + // 按用户状态过滤 + if req.FilterByStat != nil { + andConditions = append(andConditions, pkgConst.FilterCondition{ + Field: string(biz.UserFieldStat), + Operator: pkgConst.FilterOperatorEqual, + Value: *req.FilterByStat, + }) + } + + // 按认证类型过滤 + if req.FilterByAuthenticationType != "" { + andConditions = append(andConditions, pkgConst.FilterCondition{ + Field: string(biz.UserFieldUserAuthenticationType), + Operator: pkgConst.FilterOperatorEqual, + Value: string(req.FilterByAuthenticationType), + }) + } + + // 按用户系统过滤 + if req.FilterBySystem != "" { + andConditions = append(andConditions, pkgConst.FilterCondition{ + Field: "system", + Operator: pkgConst.FilterOperatorEqual, + Value: string(req.FilterBySystem), + }) + } + if len(andConditions) > 0 { filterByOptions.Groups = append(filterByOptions.Groups, pkgConst.NewConditionGroup(pkgConst.FilterLogicAnd, andConditions...)) } diff --git a/pkg/dms-common/api/dms/v1/user.go b/pkg/dms-common/api/dms/v1/user.go index bb774e8b..300a2be5 100644 --- a/pkg/dms-common/api/dms/v1/user.go +++ b/pkg/dms-common/api/dms/v1/user.go @@ -390,6 +390,21 @@ type ListUserReq struct { // fuzzy keyword // in:query FuzzyKeyword string `query:"fuzzy_keyword" json:"fuzzy_keyword"` + // filter the user email + // in:query + FilterByEmail string `query:"filter_by_email" json:"filter_by_email"` + // filter the user phone + // in:query + FilterByPhone string `query:"filter_by_phone" json:"filter_by_phone"` + // filter the user stat (0: normal, 1: disabled) + // in:query + FilterByStat *uint `query:"filter_by_stat" json:"filter_by_stat"` + // filter the user authentication type (ldap, dms, oauth2) + // in:query + FilterByAuthenticationType UserAuthenticationType `query:"filter_by_authentication_type" json:"filter_by_authentication_type"` + // filter the user system (WORKBENCH, MANAGEMENT) + // in:query + FilterBySystem UserSystem `query:"filter_by_system" json:"filter_by_system"` } // swagger:enum UserOrderByField diff --git a/pkg/dms-common/dmsobject/user.go b/pkg/dms-common/dmsobject/user.go index 0bece897..5f8e42e8 100644 --- a/pkg/dms-common/dmsobject/user.go +++ b/pkg/dms-common/dmsobject/user.go @@ -3,6 +3,8 @@ package dmsobject import ( "context" "fmt" + "net/url" + "strconv" dmsV1 "github.com/actiontech/dms/pkg/dms-common/api/dms/v1" pkgHttp "github.com/actiontech/dms/pkg/dms-common/pkg/http" @@ -98,10 +100,47 @@ func ListUsers(ctx context.Context, dmsAddr string, req dmsV1.ListUserReq) (ret reply := &dmsV1.ListUserReply{} - url := fmt.Sprintf("%v%v?page_size=%v&page_index=%v&filter_del_user=%v&filter_by_uids=%v", dmsAddr, dmsV1.GetUsersRouter(), req.PageSize, req.PageIndex, req.FilterDeletedUser, req.FilterByUids) + // 构建查询参数 + params := url.Values{} + params.Set("page_size", strconv.FormatUint(uint64(req.PageSize), 10)) + if req.PageIndex > 0 { + params.Set("page_index", strconv.FormatUint(uint64(req.PageIndex), 10)) + } + if req.OrderBy != "" { + params.Set("order_by", string(req.OrderBy)) + } + if req.FilterByName != "" { + params.Set("filter_by_name", req.FilterByName) + } + if req.FilterByUids != "" { + params.Set("filter_by_uids", req.FilterByUids) + } + if req.FilterDeletedUser { + params.Set("filter_del_user", "true") + } + if req.FuzzyKeyword != "" { + params.Set("fuzzy_keyword", req.FuzzyKeyword) + } + if req.FilterByEmail != "" { + params.Set("filter_by_email", req.FilterByEmail) + } + if req.FilterByPhone != "" { + params.Set("filter_by_phone", req.FilterByPhone) + } + if req.FilterByStat != nil { + params.Set("filter_by_stat", strconv.FormatUint(uint64(*req.FilterByStat), 10)) + } + if req.FilterByAuthenticationType != "" { + params.Set("filter_by_authentication_type", string(req.FilterByAuthenticationType)) + } + if req.FilterBySystem != "" { + params.Set("filter_by_system", string(req.FilterBySystem)) + } - if err := pkgHttp.Get(ctx, url, header, nil, reply); err != nil { - return nil, 0, fmt.Errorf("failed to list users from %v: %v", url, err) + requestURL := fmt.Sprintf("%v%v?%v", dmsAddr, dmsV1.GetUsersRouter(), params.Encode()) + + if err := pkgHttp.Get(ctx, requestURL, header, nil, reply); err != nil { + return nil, 0, fmt.Errorf("failed to list users from %v: %v", requestURL, err) } if reply.Code != 0 { return nil, 0, fmt.Errorf("http reply code(%v) error: %v", reply.Code, reply.Message) From 2fce3513d0e1410b73c342b78a9df28ee75e623c Mon Sep 17 00:00:00 2001 From: yangzhongjiao Date: Tue, 6 Jan 2026 06:40:13 +0000 Subject: [PATCH 2/5] feat(user): enhance fuzzy search functionality to include uid, email, and phone fields in user listing requests --- internal/dms/service/user.go | 15 +++++++++++++++ pkg/dms-common/api/dms/v1/user.go | 2 ++ 2 files changed, 17 insertions(+) diff --git a/internal/dms/service/user.go b/internal/dms/service/user.go index 27cfc978..a73843f8 100644 --- a/internal/dms/service/user.go +++ b/internal/dms/service/user.go @@ -267,6 +267,21 @@ func (d *DMSService) ListUsers(ctx context.Context, req *dmsCommonV1.ListUserReq Operator: pkgConst.FilterOperatorContains, Value: req.FuzzyKeyword, }, + pkgConst.FilterCondition{ + Field: string(biz.UserFieldUID), + Operator: pkgConst.FilterOperatorContains, + Value: req.FuzzyKeyword, + }, + pkgConst.FilterCondition{ + Field: string(biz.UserFieldEmail), + Operator: pkgConst.FilterOperatorContains, + Value: req.FuzzyKeyword, + }, + pkgConst.FilterCondition{ + Field: string(biz.UserFieldPhone), + Operator: pkgConst.FilterOperatorContains, + Value: req.FuzzyKeyword, + }, )) } diff --git a/pkg/dms-common/api/dms/v1/user.go b/pkg/dms-common/api/dms/v1/user.go index 300a2be5..0833c98e 100644 --- a/pkg/dms-common/api/dms/v1/user.go +++ b/pkg/dms-common/api/dms/v1/user.go @@ -389,6 +389,8 @@ type ListUserReq struct { FilterDeletedUser bool `query:"filter_del_user" json:"filter_del_user"` // fuzzy keyword // in:query + // fuzzy keyword, search in name, uid, email, phone fields (OR relationship) + // in:query FuzzyKeyword string `query:"fuzzy_keyword" json:"fuzzy_keyword"` // filter the user email // in:query From db50e71e68de4ae8934c92be1efce988032d8d32 Mon Sep 17 00:00:00 2001 From: yangzhongjiao Date: Fri, 20 Mar 2026 05:23:37 +0000 Subject: [PATCH 3/5] gen swagger --- api/swagger.json | 50 +++++++++++++++++++++++++++++++++++++++++++++- api/swagger.yaml | 52 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/api/swagger.json b/api/swagger.json index 05a40727..f8c8729f 100644 --- a/api/swagger.json +++ b/api/swagger.json @@ -5707,6 +5707,54 @@ "description": "fuzzy keyword", "name": "fuzzy_keyword", "in": "query" + }, + { + "type": "string", + "x-go-name": "FilterByEmail", + "description": "filter the user email", + "name": "filter_by_email", + "in": "query" + }, + { + "type": "string", + "x-go-name": "FilterByPhone", + "description": "filter the user phone", + "name": "filter_by_phone", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "x-go-name": "FilterByStat", + "description": "filter the user stat (0: normal, 1: disabled)", + "name": "filter_by_stat", + "in": "query" + }, + { + "enum": [ + "ldap", + "dms", + "oauth2", + "unknown" + ], + "type": "string", + "x-go-enum-desc": "ldap UserAuthenticationTypeLDAP\ndms UserAuthenticationTypeDMS\noauth2 UserAuthenticationTypeOAUTH2\nunknown UserAuthenticationTypeUnknown", + "x-go-name": "FilterByAuthenticationType", + "description": "filter the user authentication type (ldap, dms, oauth2)\nldap UserAuthenticationTypeLDAP\ndms UserAuthenticationTypeDMS\noauth2 UserAuthenticationTypeOAUTH2\nunknown UserAuthenticationTypeUnknown", + "name": "filter_by_authentication_type", + "in": "query" + }, + { + "enum": [ + "WORKBENCH", + "MANAGEMENT" + ], + "type": "string", + "x-go-enum-desc": "WORKBENCH UserSystemWorkbench\nMANAGEMENT UserSystemManagement", + "x-go-name": "FilterBySystem", + "description": "filter the user system (WORKBENCH, MANAGEMENT)\nWORKBENCH UserSystemWorkbench\nMANAGEMENT UserSystemManagement", + "name": "filter_by_system", + "in": "query" } ], "responses": { @@ -9277,7 +9325,7 @@ "x-go-name": "Message" } }, - "x-go-package": "github.com/actiontech/dms/pkg/dms-common/api/dms/v1" + "x-go-package": "github.com/actiontech/dms/api/dms/service/v1" }, "GetOauth2ConfigurationResData": { "type": "object", diff --git a/api/swagger.yaml b/api/swagger.yaml index e6c660b7..d416a2df 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1875,7 +1875,7 @@ definitions: type: string x-go-name: Message type: object - x-go-package: github.com/actiontech/dms/pkg/dms-common/api/dms/v1 + x-go-package: github.com/actiontech/dms/api/dms/service/v1 GetOauth2ConfigurationResData: properties: access_token_tag: @@ -10812,6 +10812,56 @@ paths: name: fuzzy_keyword type: string x-go-name: FuzzyKeyword + - description: filter the user email + in: query + name: filter_by_email + type: string + x-go-name: FilterByEmail + - description: filter the user phone + in: query + name: filter_by_phone + type: string + x-go-name: FilterByPhone + - description: 'filter the user stat (0: normal, 1: disabled)' + format: uint64 + in: query + name: filter_by_stat + type: integer + x-go-name: FilterByStat + - description: |- + filter the user authentication type (ldap, dms, oauth2) + ldap UserAuthenticationTypeLDAP + dms UserAuthenticationTypeDMS + oauth2 UserAuthenticationTypeOAUTH2 + unknown UserAuthenticationTypeUnknown + enum: + - ldap + - dms + - oauth2 + - unknown + in: query + name: filter_by_authentication_type + type: string + x-go-enum-desc: |- + ldap UserAuthenticationTypeLDAP + dms UserAuthenticationTypeDMS + oauth2 UserAuthenticationTypeOAUTH2 + unknown UserAuthenticationTypeUnknown + x-go-name: FilterByAuthenticationType + - description: |- + filter the user system (WORKBENCH, MANAGEMENT) + WORKBENCH UserSystemWorkbench + MANAGEMENT UserSystemManagement + enum: + - WORKBENCH + - MANAGEMENT + in: query + name: filter_by_system + type: string + x-go-enum-desc: |- + WORKBENCH UserSystemWorkbench + MANAGEMENT UserSystemManagement + x-go-name: FilterBySystem responses: "200": description: ListUserReply From 4bd3e7bc32ab18dd3278611e3b744b94aa636138 Mon Sep 17 00:00:00 2001 From: yangzhongjiao Date: Fri, 20 Mar 2026 05:47:48 +0000 Subject: [PATCH 4/5] feat(user): update user status filtering to use string enums - Changed FilterByStat in ListUserReq from a pointer to a uint to a string enum for better clarity and type safety. - Updated ListUsers method to handle the new string enum for user status filtering, converting it to the corresponding uint value. - Adjusted parameter handling in the user listing request to reflect the new enum type. --- internal/dms/service/user.go | 14 ++++++++++++-- pkg/dms-common/api/dms/v1/user.go | 10 +++++++++- pkg/dms-common/dmsobject/user.go | 4 ++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/internal/dms/service/user.go b/internal/dms/service/user.go index a73843f8..8dd74523 100644 --- a/internal/dms/service/user.go +++ b/internal/dms/service/user.go @@ -228,11 +228,21 @@ func (d *DMSService) ListUsers(ctx context.Context, req *dmsCommonV1.ListUserReq } // 按用户状态过滤 - if req.FilterByStat != nil { + if req.FilterByStat != "" { + // 将字符串枚举转换为 uint + var statValue uint + switch req.FilterByStat { + case dmsCommonV1.UserStatFilterNormal: + statValue = 0 + case dmsCommonV1.UserStatFilterDisabled: + statValue = 1 + default: + return nil, fmt.Errorf("invalid user stat filter: %s", req.FilterByStat) + } andConditions = append(andConditions, pkgConst.FilterCondition{ Field: string(biz.UserFieldStat), Operator: pkgConst.FilterOperatorEqual, - Value: *req.FilterByStat, + Value: statValue, }) } diff --git a/pkg/dms-common/api/dms/v1/user.go b/pkg/dms-common/api/dms/v1/user.go index 0833c98e..9e164317 100644 --- a/pkg/dms-common/api/dms/v1/user.go +++ b/pkg/dms-common/api/dms/v1/user.go @@ -95,6 +95,14 @@ const ( UserSystemManagement UserSystem = "MANAGEMENT" ) +// swagger:enum UserStatFilter +type UserStatFilter string + +const ( + UserStatFilterNormal UserStatFilter = "Normal" // normal + UserStatFilterDisabled UserStatFilter = "Disabled" // disabled +) + // swagger:model GetUserReply type GetUserReply struct { // Get user reply @@ -400,7 +408,7 @@ type ListUserReq struct { FilterByPhone string `query:"filter_by_phone" json:"filter_by_phone"` // filter the user stat (0: normal, 1: disabled) // in:query - FilterByStat *uint `query:"filter_by_stat" json:"filter_by_stat"` + FilterByStat UserStatFilter `query:"filter_by_stat" json:"filter_by_stat"` // filter the user authentication type (ldap, dms, oauth2) // in:query FilterByAuthenticationType UserAuthenticationType `query:"filter_by_authentication_type" json:"filter_by_authentication_type"` diff --git a/pkg/dms-common/dmsobject/user.go b/pkg/dms-common/dmsobject/user.go index 5f8e42e8..015a14a0 100644 --- a/pkg/dms-common/dmsobject/user.go +++ b/pkg/dms-common/dmsobject/user.go @@ -127,8 +127,8 @@ func ListUsers(ctx context.Context, dmsAddr string, req dmsV1.ListUserReq) (ret if req.FilterByPhone != "" { params.Set("filter_by_phone", req.FilterByPhone) } - if req.FilterByStat != nil { - params.Set("filter_by_stat", strconv.FormatUint(uint64(*req.FilterByStat), 10)) + if req.FilterByStat != "" { + params.Set("filter_by_stat", string(req.FilterByStat)) } if req.FilterByAuthenticationType != "" { params.Set("filter_by_authentication_type", string(req.FilterByAuthenticationType)) From 808cc4ba8ca6054aa949bb0a3498ffc3cb8e1a4c Mon Sep 17 00:00:00 2001 From: yangzhongjiao Date: Fri, 20 Mar 2026 05:49:13 +0000 Subject: [PATCH 5/5] gen swag --- api/swagger.json | 25 ++++++++++++++++++++----- api/swagger.yaml | 26 +++++++++++++++++++++----- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/api/swagger.json b/api/swagger.json index f8c8729f..87f312a2 100644 --- a/api/swagger.json +++ b/api/swagger.json @@ -5723,10 +5723,14 @@ "in": "query" }, { - "type": "integer", - "format": "uint64", + "enum": [ + "Normal", + "Disabled" + ], + "type": "string", + "x-go-enum-desc": "Normal UserStatFilterNormal\nDisabled UserStatFilterDisabled", "x-go-name": "FilterByStat", - "description": "filter the user stat (0: normal, 1: disabled)", + "description": "filter the user stat (0: normal, 1: disabled)\nNormal UserStatFilterNormal\nDisabled UserStatFilterDisabled", "name": "filter_by_stat", "in": "query" }, @@ -9305,7 +9309,7 @@ "x-go-name": "Users" } }, - "x-go-package": "github.com/actiontech/dms/pkg/dms-common/api/dms/v1" + "x-go-package": "github.com/actiontech/dms/api/dms/service/v1" }, "GetMemberGroupReply": { "type": "object", @@ -11861,6 +11865,17 @@ "ListMemberRoleWithOpRange": { "type": "object", "properties": { + "member_group": { + "$ref": "#/definitions/ProjectMemberGroup" + }, + "op_permissions": { + "description": "member op permissions", + "type": "array", + "items": { + "$ref": "#/definitions/UidWithName" + }, + "x-go-name": "OpPermissions" + }, "op_range_type": { "description": "op permission range type, only support db service now\nunknown OpRangeTypeUnknown\nglobal OpRangeTypeGlobal 全局权限: 该权限只能被用户使用\nproject OpRangeTypeProject 项目权限: 该权限只能被成员使用\ndb_service OpRangeTypeDBService 项目内的数据源权限: 该权限只能被成员使用", "type": "string", @@ -11885,7 +11900,7 @@ "$ref": "#/definitions/UidWithName" } }, - "x-go-package": "github.com/actiontech/dms/pkg/dms-common/api/dms/v1" + "x-go-package": "github.com/actiontech/dms/api/dms/service/v1" }, "ListMemberTipsItem": { "type": "object", diff --git a/api/swagger.yaml b/api/swagger.yaml index d416a2df..682eda9c 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1860,7 +1860,7 @@ definitions: type: array x-go-name: Users type: object - x-go-package: github.com/actiontech/dms/pkg/dms-common/api/dms/v1 + x-go-package: github.com/actiontech/dms/api/dms/service/v1 GetMemberGroupReply: properties: code: @@ -3877,6 +3877,14 @@ definitions: x-go-package: github.com/actiontech/dms/api/dms/service/v1 ListMemberRoleWithOpRange: properties: + member_group: + $ref: '#/definitions/ProjectMemberGroup' + op_permissions: + description: member op permissions + items: + $ref: '#/definitions/UidWithName' + type: array + x-go-name: OpPermissions op_range_type: description: |- op permission range type, only support db service now @@ -3905,7 +3913,7 @@ definitions: role_uid: $ref: '#/definitions/UidWithName' type: object - x-go-package: github.com/actiontech/dms/pkg/dms-common/api/dms/v1 + x-go-package: github.com/actiontech/dms/api/dms/service/v1 ListMemberTipsItem: properties: user_id: @@ -10822,11 +10830,19 @@ paths: name: filter_by_phone type: string x-go-name: FilterByPhone - - description: 'filter the user stat (0: normal, 1: disabled)' - format: uint64 + - description: |- + filter the user stat (0: normal, 1: disabled) + Normal UserStatFilterNormal + Disabled UserStatFilterDisabled + enum: + - Normal + - Disabled in: query name: filter_by_stat - type: integer + type: string + x-go-enum-desc: |- + Normal UserStatFilterNormal + Disabled UserStatFilterDisabled x-go-name: FilterByStat - description: |- filter the user authentication type (ldap, dms, oauth2)