package organize import ( "context" "fmt" "git.nobla.cn/golang/moto/common/db" "git.nobla.cn/golang/moto/models" "git.nobla.cn/golang/rest/types" "gorm.io/gorm" "strings" ) func RecursiveDepartment(ctx context.Context, parent string, level int, departments []*models.Department) []*types.TypeValue { var ( child []*types.TypeValue ) values := make([]*types.TypeValue, 0) for _, dept := range departments { if dept.Parent == parent { values = append(values, &types.TypeValue{ Label: "|-" + strings.Repeat("--", level) + dept.Name, Value: dept.ID, }) child = RecursiveDepartment(ctx, dept.ID, level+1, departments) if len(child) > 0 { for _, row := range child { values = append(values, row) } } } } return values } func RecursiveNestedDepartment(ctx context.Context, parent string, level int, departments []*models.Department) []*types.NestedValue { values := make([]*types.NestedValue, 0) for _, dept := range departments { if dept.Parent == parent { v := &types.NestedValue{ Label: dept.Name, Value: dept.ID, Children: RecursiveNestedDepartment(ctx, dept.ID, level+1, departments), } values = append(values, v) } } return values } func DepartmentUserNested(ctx context.Context, domainName string) []*types.NestedValue { var ( err error value any users []*models.User departments []*models.Department ) if value, err = db.TryCache(ctx, fmt.Sprintf("domain:%s:departments", domainName), func(tx *gorm.DB) (any, error) { departments = make([]*models.Department, 0) err = tx.Where("domain=?", domainName).Order("created_at ASC").Find(&departments).Error return departments, err }, db.WithDepend("SELECT max(`updated_at`) FROM `departments` WHERE `domain`=?", domainName)); err == nil { departments = value.([]*models.Department) } else { return nil } if value, err = db.TryCache(ctx, fmt.Sprintf("domain:%s:users", domainName), func(tx *gorm.DB) (any, error) { users = make([]*models.User, 0) err = tx.Where("domain=?", domainName).Order("uid ASC").Find(&users).Error return users, err }, db.WithDepend("SELECT max(`updated_at`) FROM `users` WHERE `domain`=?", domainName)); err == nil { users = value.([]*models.User) } else { return nil } depts := RecursiveDepartment(ctx, "", 0, departments) values := make([]*types.NestedValue, 0) for _, dept := range depts { v := &types.NestedValue{ Label: dept.Label, Value: dept.Value, Children: make([]*types.NestedValue, 0), } for _, user := range users { if user.Department == v.Value { v.Children = append(v.Children, &types.NestedValue{ Label: fmt.Sprintf("%s(%s)", user.Username, user.UID), Value: user.UID, }) } } values = append(values, v) } return values } func DepartmentTypes(ctx context.Context, domainName string) []*types.TypeValue { result, err := db.TryCache(ctx, fmt.Sprintf("domain:%s:department:types", domainName), func(tx *gorm.DB) (any, error) { values := make([]*models.Department, 0) if err := db.WithContext(ctx).Where("domain=?", domainName).Find(&values).Error; err == nil { return RecursiveDepartment(ctx, "", 0, values), nil } else { return nil, err } }, db.WithDepend("SELECT max(`updated_at`) FROM `departments` WHERE `domain`=?", domainName)) if err == nil { return result.([]*types.TypeValue) } return nil }