Skip to content

Commit c6a62d7

Browse files
authored
support global workflow feature (#4288)
* support global workflow feature Signed-off-by: Patrick Zhao <[email protected]> * fix responseHelper panic Signed-off-by: Patrick Zhao <[email protected]> * add search in global workflow feature Signed-off-by: Patrick Zhao <[email protected]> --------- Signed-off-by: Patrick Zhao <[email protected]>
1 parent 761beab commit c6a62d7

File tree

11 files changed

+581
-29
lines changed

11 files changed

+581
-29
lines changed

pkg/microservice/aslan/core/common/repository/mongodb/workflow_v4.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/koderover/zadig/v2/pkg/microservice/aslan/config"
3232
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models"
3333
"github.com/koderover/zadig/v2/pkg/setting"
34+
"github.com/koderover/zadig/v2/pkg/tool/log"
3435
mongotool "github.com/koderover/zadig/v2/pkg/tool/mongo"
3536
)
3637

@@ -265,6 +266,95 @@ func (c *WorkflowV4Coll) List(opt *ListWorkflowV4Option, pageNum, pageSize int64
265266
return resp, count, nil
266267
}
267268

269+
type ListWorkflowV4InGlobalOption struct {
270+
Keyword string
271+
ProjectName string
272+
ProjectNames []string
273+
FavoriteWorkflowNames []string
274+
CollModeWorkflowNames []string
275+
PageNum int64
276+
PageSize int64
277+
SortBy setting.ListWorkflowV4InGlobalSortBy
278+
OrderBy setting.ListWorkflowV4InGlobalOrderBy
279+
}
280+
281+
func (c *WorkflowV4Coll) ListInGlobal(opt *ListWorkflowV4InGlobalOption) ([]*models.WorkflowV4, int64, error) {
282+
resp := make([]*models.WorkflowV4, 0)
283+
query := bson.M{}
284+
285+
// 构建查询条件
286+
var conditions []bson.M
287+
288+
// 如果存在 FavoriteWorkflowNames,只查询这些工作流,忽略其他条件
289+
if len(opt.FavoriteWorkflowNames) > 0 {
290+
conditions = append(conditions, bson.M{"name": bson.M{"$in": opt.FavoriteWorkflowNames}})
291+
} else {
292+
// 项目条件
293+
if opt.ProjectName != "" {
294+
conditions = append(conditions, bson.M{"project": opt.ProjectName})
295+
} else if len(opt.ProjectNames) > 0 {
296+
conditions = append(conditions, bson.M{"project": bson.M{"$in": opt.ProjectNames}})
297+
}
298+
// 协作模式工作流条件
299+
if len(opt.CollModeWorkflowNames) > 0 {
300+
conditions = append(conditions, bson.M{"name": bson.M{"$in": opt.CollModeWorkflowNames}})
301+
}
302+
}
303+
304+
// 关键字搜索条件
305+
if opt.Keyword != "" {
306+
keywordRegex := bson.M{"$regex": opt.Keyword, "$options": "i"}
307+
conditions = append(conditions, bson.M{
308+
"$or": bson.A{
309+
bson.M{"name": keywordRegex},
310+
bson.M{"display_name": keywordRegex},
311+
},
312+
})
313+
}
314+
315+
// 构建最终查询
316+
if len(conditions) == 1 {
317+
query = conditions[0]
318+
} else if len(conditions) > 1 {
319+
query = bson.M{"$and": conditions}
320+
}
321+
322+
count, err := c.CountDocuments(context.TODO(), query)
323+
if err != nil {
324+
return nil, count, err
325+
}
326+
327+
var findOption *options.FindOptions
328+
if opt.PageSize == 0 {
329+
opt.PageSize = 10
330+
}
331+
if opt.PageNum == 0 {
332+
opt.PageNum = 1
333+
}
334+
335+
findOption = options.Find().
336+
SetSkip((opt.PageNum - 1) * opt.PageSize).
337+
SetLimit(opt.PageSize)
338+
339+
if opt.SortBy != "" && opt.OrderBy != 0 {
340+
findOption.SetSort(bson.D{
341+
bson.E{Key: string(opt.SortBy), Value: opt.OrderBy},
342+
})
343+
}
344+
345+
log.Debugf("query: %+v", query)
346+
347+
cursor, err := c.Collection.Find(context.TODO(), query, findOption)
348+
if err != nil {
349+
return nil, count, err
350+
}
351+
err = cursor.All(context.TODO(), &resp)
352+
if err != nil {
353+
return nil, count, err
354+
}
355+
return resp, count, nil
356+
}
357+
268358
func (c *WorkflowV4Coll) Find(name string) (*models.WorkflowV4, error) {
269359
resp := new(models.WorkflowV4)
270360
query := bson.M{"name": name}

pkg/microservice/aslan/core/workflow/handler/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (*Router) Inject(router *gin.RouterGroup) {
6868
workflowV4.POST("/workflowtask/:workflowName/field", SetWorkflowTasksCustomFields)
6969
workflowV4.GET("/workflowtask/:workflowName/field", GetWorkflowTasksCustomFields)
7070
workflowV4.GET("", ListWorkflowV4)
71+
workflowV4.GET("/global", ListGlobalWorkflowV4)
7172
workflowV4.POST("/auto", AutoCreateWorkflow)
7273
workflowV4.GET("/trigger", ListWorkflowV4CanTrigger)
7374
workflowV4.POST("/lint", LintWorkflowV4)

pkg/microservice/aslan/core/workflow/handler/workflow_v4.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
commonmodels "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models"
3434
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/workflow/service/workflow"
35+
"github.com/koderover/zadig/v2/pkg/shared/client/user"
3536
internalhandler "github.com/koderover/zadig/v2/pkg/shared/handler"
3637
"github.com/koderover/zadig/v2/pkg/tool/errors"
3738
e "github.com/koderover/zadig/v2/pkg/tool/errors"
@@ -312,6 +313,116 @@ func ListWorkflowV4(c *gin.Context) {
312313
ctx.RespErr = err
313314
}
314315

316+
type ListGlobalWorkflowV4Request struct {
317+
ProjectName string `json:"projectName" form:"projectName"`
318+
IsFavorite bool `json:"isFavorite" form:"isFavorite,default=false"`
319+
Keyword string `json:"keyword" form:"keyword"`
320+
PageSize int64 `json:"pageSize" form:"pageSize,default=10"`
321+
PageNum int64 `json:"pageNum" form:"pageNum,default=1"`
322+
SortBy setting.ListWorkflowV4InGlobalSortBy `json:"sortBy" form:"sortBy" binding:"omitempty,oneof=create_time name"`
323+
OrderBy setting.ListWorkflowV4InGlobalOrderBy `json:"orderBy" form:"orderBy" binding:"omitempty,oneof=1 -1"`
324+
}
325+
326+
// @summary 全局工作流列表
327+
// @description
328+
// @tags workflow
329+
// @accept json
330+
// @produce json
331+
// @Param projectName query string false "项目标识"
332+
// @Param isFavorite query bool false "是否是收藏"
333+
// @Param keyword query string false "关键字搜索"
334+
// @Param pageSize query int true "每页条数"
335+
// @Param pageNum query int true "页码"
336+
// @Param sortBy query setting.ListWorkflowV4InGlobalSortBy false "排序字段"
337+
// @Param orderBy query setting.ListWorkflowV4InGlobalOrderBy false "排序方式"
338+
// @success 200 {object} workflow.ListGlobalWorkflowV4Response
339+
// @router /api/aslan/workflow/v4/global [get]
340+
func ListGlobalWorkflowV4(c *gin.Context) {
341+
ctx, err := internalhandler.NewContextWithAuthorization(c)
342+
defer func() { internalhandler.JSONResponse(c, ctx) }()
343+
if err != nil {
344+
ctx.RespErr = fmt.Errorf("authorization Info Generation failed: err %s", err)
345+
ctx.UnAuthorized = true
346+
return
347+
}
348+
349+
args := &ListGlobalWorkflowV4Request{}
350+
if err := c.ShouldBindQuery(args); err != nil {
351+
ctx.RespErr = err
352+
return
353+
}
354+
355+
collModeWorkflowsWithVerb, err := internalhandler.ListAuthorizedWorkflowWithVerb(ctx.UserID, args.ProjectName)
356+
if err != nil {
357+
ctx.Logger.Errorf("failed to list collaboration mode authorized workflow resource, error: %s", err)
358+
ctx.RespErr = err
359+
return
360+
}
361+
362+
bytes, _ := json.Marshal(collModeWorkflowsWithVerb)
363+
log.Debugf("collModeWorkflowsWithVerb: %s", string(bytes))
364+
365+
query := &workflow.ListGlobalWorkflowV4Query{
366+
ProjectName: args.ProjectName,
367+
IsFavorite: args.IsFavorite,
368+
Keyword: args.Keyword,
369+
ProjectAuthMap: make(map[string]*workflow.ProjectAuthWorkflow),
370+
PageNum: args.PageNum,
371+
PageSize: args.PageSize,
372+
SortBy: args.SortBy,
373+
OrderBy: args.OrderBy,
374+
}
375+
376+
for projectName, project := range ctx.Resources.ProjectAuthInfo {
377+
if args.ProjectName != "" && projectName != args.ProjectName {
378+
continue
379+
}
380+
381+
var authWorkflow *workflow.ProjectAuthWorkflow
382+
if project.IsProjectAdmin || project.Workflow.View {
383+
authWorkflow = &workflow.ProjectAuthWorkflow{
384+
ProjectName: projectName,
385+
IsProjectAdmin: project.IsProjectAdmin,
386+
Actions: project.Workflow,
387+
CollModeWorkflowPermsMap: make(map[string]*workflow.WorkflowWithAction),
388+
}
389+
}
390+
391+
if collModeWorkflowsWithVerb.ProjectWorkflowActionsMap[projectName] != nil {
392+
if authWorkflow == nil {
393+
authWorkflow = &workflow.ProjectAuthWorkflow{
394+
IsProjectAdmin: false,
395+
Actions: &user.WorkflowActions{
396+
View: false,
397+
Edit: false,
398+
Create: false,
399+
Delete: false,
400+
Execute: false,
401+
},
402+
ProjectName: projectName,
403+
CollModeWorkflowPermsMap: make(map[string]*workflow.WorkflowWithAction),
404+
}
405+
}
406+
407+
for workflowName, workflowAction := range collModeWorkflowsWithVerb.ProjectWorkflowActionsMap[projectName] {
408+
authWorkflow.CollModeWorkflowPermsMap[workflowName] = &workflow.WorkflowWithAction{
409+
WorkflowName: workflowName,
410+
Action: *workflowAction,
411+
}
412+
}
413+
}
414+
415+
if authWorkflow != nil {
416+
query.ProjectAuthMap[projectName] = authWorkflow
417+
}
418+
}
419+
420+
bytes, _ = json.Marshal(query)
421+
log.Debugf("query: %s", string(bytes))
422+
423+
ctx.Resp, ctx.RespErr = workflow.ListWorkflowV4InGlobal(ctx, query)
424+
}
425+
315426
func ListWorkflowV4CanTrigger(c *gin.Context) {
316427
ctx, err := internalhandler.NewContextWithAuthorization(c)
317428
defer func() { internalhandler.JSONResponse(c, ctx) }()

0 commit comments

Comments
 (0)