补充标签过滤 LIKE模式

This commit is contained in:
yumaojun03 2025-06-29 10:24:46 +08:00
parent 13ea1f2e04
commit 1b27d97f2a
5 changed files with 56 additions and 16 deletions

View File

@ -4,8 +4,10 @@ import (
"context"
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/label"
"github.com/infraboard/mcube/v2/exception"
"github.com/infraboard/mcube/v2/ioc/config/datasource"
"github.com/infraboard/mcube/v2/types"
"gorm.io/gorm"
)
// CreateLabel implements label.Service.
@ -46,13 +48,23 @@ func (i *LabelServiceImpl) QueryLabel(ctx context.Context, in *label.QueryLabelR
return set, nil
}
// DeleteLabel implements label.Service.
func (i *LabelServiceImpl) DeleteLabel(ctx context.Context, in *label.DeleteLabelRequest) (*label.Label, error) {
panic("unimplemented")
}
// DescribeLabel implements label.Service.
func (i *LabelServiceImpl) DescribeLabel(ctx context.Context, in *label.DescribeLabelRequest) (*label.Label, error) {
query := datasource.DBFromCtx(ctx)
ins := &label.Label{}
if err := query.Where("id = ?", in.Id).First(ins).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, exception.NewNotFound("label %s not found", in.Id)
}
return nil, err
}
return ins, nil
}
// DeleteLabel implements label.Service.
func (i *LabelServiceImpl) DeleteLabel(ctx context.Context, in *label.DeleteLabelRequest) (*label.Label, error) {
panic("unimplemented")
}

View File

@ -8,12 +8,16 @@ import (
func TestCreateLabel(t *testing.T) {
req := label.NewCreateLabelRequest()
req.Key = "tech"
req.KeyDesc = "技术部"
req.Key = "team"
req.KeyDesc = "小组"
req.ValueType = label.VALUE_TYPE_ENUM
req.AddEnumOption(&label.EnumOption{
Label: "开发一组",
Value: "dev01",
Children: []*label.EnumOption{
{Label: "后端开发", Value: "dev01.backend_developer"},
{Label: "前端开发", Value: "dev01.web_developer"},
},
})
ins, err := svc.CreateLabel(ctx, req)
@ -22,3 +26,12 @@ func TestCreateLabel(t *testing.T) {
}
t.Log(ins)
}
func TestQueryLabel(t *testing.T) {
req := label.NewQueryLabelRequest()
set, err := svc.QueryLabel(ctx, req)
if err != nil {
t.Fatal(err)
}
t.Log(set)
}

View File

@ -11,8 +11,8 @@ func NewLabel(spc *CreateLabelRequest) (*Label, error) {
return nil, err
}
return &Label{
ResourceMeta: *apps.NewResourceMeta(),
Spec: spc,
ResourceMeta: *apps.NewResourceMeta(),
CreateLabelRequest: *spc,
}, nil
}
@ -20,7 +20,7 @@ type Label struct {
// 基础数据
apps.ResourceMeta
// 空间定义
Spec *CreateLabelRequest `json:"spec" bson:",inline" gorm:"embedded"`
CreateLabelRequest `bson:",inline" gorm:"embedded"`
}
func (l *Label) TableName() string {
@ -65,13 +65,14 @@ type CreateCreateLabelSpec struct {
// 适用于那些资源
Resources []string `json:"resources" bson:"resources" gorm:"column:resources;type:json;serializer:json;" description:"适用于那些资源" optional:"true"`
// 标签的键, 标签的Key不允许修改, 带前缀的 tech.dev.frontend01 tech.dev.backend01
// 标签的键, 标签的Key不允许修改
Key string `json:"key" bson:"key" gorm:"column:key;type:varchar(255)" validate:"required"`
// 标签的键的描述
KeyDesc string `json:"key_desc" bson:"key_desc" gorm:"column:key_desc;type:varchar(255)" validate:"required"`
// 标签的颜色
Color string `json:"color" bson:"color" gorm:"column:color;type:varchar(100)"`
// 标签的值相关信息, tech.dev.frontend01 tech.dev.backend01
// 值类型
ValueType VALUE_TYPE `json:"value_type" gorm:"column:value_type;type:varchar(20)" bson:"value_type"`
// 标签默认值
@ -83,7 +84,7 @@ type CreateCreateLabelSpec struct {
// 枚举值的选项
EnumOptions []*EnumOption `json:"enum_options,omitempty" bson:"enum_options" gorm:"column:enum_options;type:json;serializer:json;"`
// 基于Http枚举的配置
HttpEnumConfig HttpEnumConfig `json:"http_enum_config,omitempty" gorm:"embedded" bson:"http_enum_config"`
HttpEnumConfig HttpEnumConfig `json:"http_enum_config" gorm:"embedded" bson:"http_enum_config"`
// 值的样例
Example string `json:"example" bson:"example" gorm:"column:example;type:text"`
@ -98,6 +99,8 @@ type EnumOption struct {
Input string `json:"input" bson:"input" validate:"required"`
// 选项的值, 根据parent.input + children.input 自动生成
Value string `json:"value" bson:"value"`
// 是否禁止选中, 和前端UI组件配合使用
Disabled bool `json:"disabled" bson:"disabled"`
// 标签的颜色
Color string `json:"color" bson:"color"`
// 是否废弃

View File

@ -1,6 +1,7 @@
package policy
import (
"strings"
"time"
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
@ -104,8 +105,18 @@ func (r ResourceScope) GormResourceFilter(query *gorm.DB) *gorm.DB {
// 构建"标签值匹配"条件
var valueMatches []clause.Expression
for _, val := range values {
valueMatches = append(valueMatches,
datatypes.JSONQuery("label").Equals(val, key))
if strings.Contains(val, "%") {
// 如果值包含通配符%使用LIKE条件
valueMatches = append(valueMatches,
clause.Expr{
SQL: "JSON_UNQUOTE(JSON_EXTRACT(label, ?)) LIKE ?",
Vars: []any{"$." + key, val},
})
} else {
// 否则使用精确匹配
valueMatches = append(valueMatches,
datatypes.JSONQuery("label").Equals(val, key))
}
}
// 组合条件:标签不存在 OR 标签值匹配

View File

@ -14,7 +14,7 @@ func TestCreateApplication(t *testing.T) {
req.CodeRepository = application.CodeRepository{
SshUrl: "git@122.51.31.227:go-course/go18.git",
}
req.SetLabel("team", "golang_dev_group_01")
req.SetLabel("team", "dev01.web_developer")
ins, err := svc.CreateApplication(ctx, req)
if err != nil {
t.Fatal(err)
@ -25,7 +25,8 @@ func TestCreateApplication(t *testing.T) {
// SELECT * FROM `applications` WHERE (NOT JSON_EXTRACT(`label`,'$.team') IS NOT NULL OR JSON_EXTRACT(`label`,'$.team') = 'golang_dev_group_01') ORDER BY created_at desc LIMIT 20
func TestQueryApplication(t *testing.T) {
req := application.NewQueryApplicationRequest()
req.SetScope("team", []string{"golang_dev_group_01"})
// dev01.%
req.SetScope("team", []string{"%"})
// req.SetScope("env", []string{"prod"})
ins, err := svc.QueryApplication(ctx, req)
if err != nil {