优化多租户支持

This commit is contained in:
Yavolte 2025-07-23 17:07:51 +08:00
parent 556f7abf25
commit 9bbda7bfe3
26 changed files with 430 additions and 215 deletions

View File

@ -42,6 +42,7 @@ func (s *ActivityRecorder) onAfterCreate(ctx context.Context, tx *gorm.DB, model
}
data := &models.Activity{}
data.Uid = runtimeScope.User
data.Domain = runtimeScope.Domain
data.Module = runtimeScope.ModuleName
data.Table = runtimeScope.TableName
data.Action = types.ScenarioCreate
@ -65,6 +66,7 @@ func (s *ActivityRecorder) onAfterUpdate(ctx context.Context, tx *gorm.DB, model
}
data := &models.Activity{}
data.Uid = runtimeScope.User
data.Domain = runtimeScope.Domain
data.Module = runtimeScope.ModuleName
data.Table = runtimeScope.TableName
data.Action = types.ScenarioUpdate
@ -95,6 +97,7 @@ func (s *ActivityRecorder) onAfterDelete(ctx context.Context, tx *gorm.DB, model
}
data := &models.Activity{}
data.Uid = runtimeScope.User
data.Domain = runtimeScope.Domain
data.Module = runtimeScope.ModuleName
data.Table = runtimeScope.TableName
data.Action = types.ScenarioDelete

2
go.mod
View File

@ -6,7 +6,7 @@ toolchain go1.23.10
require (
git.nobla.cn/golang/aeus v0.0.11
git.nobla.cn/golang/rest v0.1.4
git.nobla.cn/golang/rest v0.1.7
github.com/envoyproxy/protoc-gen-validate v1.2.1
golang.org/x/text v0.23.0 // indirect
google.golang.org/protobuf v1.36.6

4
go.sum
View File

@ -4,8 +4,8 @@ git.nobla.cn/golang/aeus v0.0.11 h1:gbXIOVOQRDTIQTjw9wPVfNC9nXBaTJCABeDYmrHW2Oc=
git.nobla.cn/golang/aeus v0.0.11/go.mod h1:oOEwqIp6AhKKqj6sLFO8x7IycOROYHCb/2/CjF4+9CU=
git.nobla.cn/golang/kos v0.1.32 h1:sFVCA7vKc8dPUd0cxzwExOSPX2mmMh2IuwL6cYS1pBc=
git.nobla.cn/golang/kos v0.1.32/go.mod h1:35Z070+5oB39WcVrh5DDlnVeftL/Ccmscw2MZFe9fUg=
git.nobla.cn/golang/rest v0.1.4 h1:9/XscfNXI3aPESpy8CPtVl17VSMxU9BihhedeG+h8YY=
git.nobla.cn/golang/rest v0.1.4/go.mod h1:4viDk7VujDokpUeHQGbnSp2bkkVZEoIkWQIs/l/TTPQ=
git.nobla.cn/golang/rest v0.1.7 h1:VLBTfuEbjLGM8RwtrFo+d9W5eaMasbkHWfLjWgi+isQ=
git.nobla.cn/golang/rest v0.1.7/go.mod h1:4viDk7VujDokpUeHQGbnSp2bkkVZEoIkWQIs/l/TTPQ=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=

View File

@ -49,10 +49,15 @@ func (u *Department) RecursiveDepartment(ctx context.Context, parent int64, leve
}
// GetLevelLabels 获取层级标签
func (u *Department) GetLevelLabels(ctx context.Context) (values []*types.TypeValue[int64], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("department:level:labels"), func(tx *gorm.DB) ([]*types.TypeValue[int64], error) {
func (u *Department) GetLevelLabels(ctx context.Context, domainName string) (values []*types.TypeValue[int64], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("department:level:labels:%s", domainName), func(tx *gorm.DB) ([]*types.TypeValue[int64], error) {
var values []*models.Department
if err = tx.Find(&values).Error; err != nil {
if domainName == "" {
err = tx.Find(&values).Error
} else {
err = tx.Where("`domain` = ?", domainName).Find(&values).Error
}
if err != nil {
return nil, err
}
return u.RecursiveDepartment(ctx, 0, 0, values), nil
@ -65,9 +70,9 @@ func (u *Department) GetLevelLabels(ctx context.Context) (values []*types.TypeVa
}
// GetLabels 获取用户标签
func (u *Department) GetLabels(ctx context.Context) (values []*types.TypeValue[int64], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("department:labels"), func(tx *gorm.DB) ([]*types.TypeValue[int64], error) {
return rest.ModelTypes[int64](ctx, tx, &models.Department{}, "", "name", "id")
func (u *Department) GetLabels(ctx context.Context, domainName string) (values []*types.TypeValue[int64], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("department:labels:%s", domainName), func(tx *gorm.DB) ([]*types.TypeValue[int64], error) {
return rest.ModelTypes[int64](ctx, tx, &models.Department{}, domainName, "name", "id")
},
dbcache.WithDB(u.db),
dbcache.WithCache(u.cache),
@ -77,10 +82,14 @@ func (u *Department) GetLabels(ctx context.Context) (values []*types.TypeValue[i
}
// GetDepartments 获取部门列表
func (u *Department) GetDepartments(ctx context.Context) (values []*models.Department, err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("department:list"), func(tx *gorm.DB) ([]*models.Department, error) {
func (u *Department) GetDepartments(ctx context.Context, domainName string) (values []*models.Department, err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("department:list:%s", domainName), func(tx *gorm.DB) ([]*models.Department, error) {
var items []*models.Department
err = tx.Find(&items).Error
if domainName == "" {
err = tx.Find(&items).Error
} else {
err = tx.Where("`domain` = ?", domainName).Find(&items).Error
}
return items, err
},
dbcache.WithDB(u.db),

View File

@ -18,10 +18,14 @@ type Menu struct {
sqlDependency *dbcache.SqlDependency
}
func (u *Menu) GetMenus(ctx context.Context) (values []*models.Menu, err error) {
return dbcache.TryCache(ctx, "menus", func(tx *gorm.DB) ([]*models.Menu, error) {
func (u *Menu) GetMenus(ctx context.Context, domainName string) (values []*models.Menu, err error) {
return dbcache.TryCache(ctx, fmt.Sprintf("menus:%s", domainName), func(tx *gorm.DB) ([]*models.Menu, error) {
var items []*models.Menu
err = tx.Order("`position`,`id` ASC").Find(&items).Error
if domainName == "" {
err = tx.Order("`position`,`id` ASC").Find(&items).Error
} else {
err = tx.Where("`domain`=?", domainName).Order("`position`,`id` ASC").Find(&items).Error
}
return items, err
},
dbcache.WithDB(u.db),
@ -30,9 +34,9 @@ func (u *Menu) GetMenus(ctx context.Context) (values []*models.Menu, err error)
)
}
func (u *Menu) GetLabels(ctx context.Context) (values []*types.TypeValue[string], err error) {
return dbcache.TryCache(ctx, fmt.Sprintf("menu:labels"), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.Menu{}, "", "label", "name")
func (u *Menu) GetLabels(ctx context.Context, domainName string) (values []*types.TypeValue[string], err error) {
return dbcache.TryCache(ctx, fmt.Sprintf("menu:labels:%s", domainName), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.Menu{}, domainName, "label", "name")
},
dbcache.WithDB(u.db),
dbcache.WithCache(u.cache),

View File

@ -19,9 +19,9 @@ type Role struct {
permissionSqlDependency *dbcache.SqlDependency
}
func (u *Role) GetLabels(ctx context.Context) (values []*types.TypeValue[string], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("role:labels"), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.Role{}, "", "label", "name")
func (u *Role) GetLabels(ctx context.Context, domainName string) (values []*types.TypeValue[string], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("role:labels:%s", domainName), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.Role{}, domainName, "label", "name")
},
dbcache.WithDB(u.db),
dbcache.WithCache(u.cache),

View File

@ -40,9 +40,9 @@ func (u *User) GetPermissions(ctx context.Context, uid string) (permissions []st
}
// GetLabels 获取用户标签
func (u *User) GetLabels(ctx context.Context) (values []*types.TypeValue[string], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("user:labels"), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.User{}, "", "username", "uid")
func (u *User) GetLabels(ctx context.Context, domainName string) (values []*types.TypeValue[string], err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("user:labels:%s", domainName), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.User{}, domainName, "username", "uid")
},
dbcache.WithDB(u.db),
dbcache.WithCache(u.cache),
@ -52,10 +52,14 @@ func (u *User) GetLabels(ctx context.Context) (values []*types.TypeValue[string]
}
// GeUsers 获取部门列表
func (u *User) GeUsers(ctx context.Context) (values []*models.User, err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("user:list"), func(tx *gorm.DB) ([]*models.User, error) {
func (u *User) GeUsers(ctx context.Context, domainName string) (values []*models.User, err error) {
values, err = dbcache.TryCache(ctx, fmt.Sprintf("user:list:%s", domainName), func(tx *gorm.DB) ([]*models.User, error) {
var items []*models.User
err = tx.Find(&items).Error
if domainName != "" {
err = tx.Where("`domain` = ?", domainName).Find(&items).Error
} else {
err = tx.Find(&items).Error
}
return items, err
},
dbcache.WithDB(u.db),

View File

@ -31,16 +31,17 @@ type Menu struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt int64 `protobuf:"varint,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Parent string `protobuf:"bytes,4,opt,name=parent,proto3" json:"parent,omitempty"`
Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
Label string `protobuf:"bytes,6,opt,name=label,proto3" json:"label,omitempty"`
Uri string `protobuf:"bytes,7,opt,name=uri,proto3" json:"uri,omitempty"`
ViewPath string `protobuf:"bytes,8,opt,name=view_path,json=viewPath,proto3" json:"view_path,omitempty"`
Icon string `protobuf:"bytes,9,opt,name=icon,proto3" json:"icon,omitempty"`
Hidden bool `protobuf:"varint,10,opt,name=hidden,proto3" json:"hidden,omitempty"`
Public bool `protobuf:"varint,11,opt,name=public,proto3" json:"public,omitempty"`
Description string `protobuf:"bytes,12,opt,name=description,proto3" json:"description,omitempty"`
Position int64 `protobuf:"varint,13,opt,name=position,proto3" json:"position,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
Parent string `protobuf:"bytes,5,opt,name=parent,proto3" json:"parent,omitempty"`
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
Label string `protobuf:"bytes,7,opt,name=label,proto3" json:"label,omitempty"`
Uri string `protobuf:"bytes,8,opt,name=uri,proto3" json:"uri,omitempty"`
ViewPath string `protobuf:"bytes,9,opt,name=view_path,json=viewPath,proto3" json:"view_path,omitempty"`
Icon string `protobuf:"bytes,10,opt,name=icon,proto3" json:"icon,omitempty"`
Hidden bool `protobuf:"varint,11,opt,name=hidden,proto3" json:"hidden,omitempty"`
Public bool `protobuf:"varint,12,opt,name=public,proto3" json:"public,omitempty"`
Description string `protobuf:"bytes,13,opt,name=description,proto3" json:"description,omitempty"`
Position int64 `protobuf:"varint,14,opt,name=position,proto3" json:"position,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -96,6 +97,13 @@ func (x *Menu) GetUpdatedAt() int64 {
return 0
}
func (x *Menu) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Menu) GetParent() string {
if x != nil {
return x.Parent
@ -172,9 +180,10 @@ type Role struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt int64 `protobuf:"varint,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
Label string `protobuf:"bytes,5,opt,name=label,proto3" json:"label,omitempty"`
Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
Label string `protobuf:"bytes,6,opt,name=label,proto3" json:"label,omitempty"`
Description string `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -230,6 +239,13 @@ func (x *Role) GetUpdatedAt() int64 {
return 0
}
func (x *Role) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Role) GetName() string {
if x != nil {
return x.Name
@ -257,9 +273,10 @@ type Permission struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt int64 `protobuf:"varint,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Menu string `protobuf:"bytes,4,opt,name=menu,proto3" json:"menu,omitempty"`
Permission string `protobuf:"bytes,5,opt,name=permission,proto3" json:"permission,omitempty"`
Label string `protobuf:"bytes,6,opt,name=label,proto3" json:"label,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
Menu string `protobuf:"bytes,5,opt,name=menu,proto3" json:"menu,omitempty"`
Permission string `protobuf:"bytes,6,opt,name=permission,proto3" json:"permission,omitempty"`
Label string `protobuf:"bytes,7,opt,name=label,proto3" json:"label,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -315,6 +332,13 @@ func (x *Permission) GetUpdatedAt() int64 {
return 0
}
func (x *Permission) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Permission) GetMenu() string {
if x != nil {
return x.Menu
@ -403,18 +427,19 @@ type User struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt int64 `protobuf:"varint,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Uid string `protobuf:"bytes,4,opt,name=uid,proto3" json:"uid,omitempty"`
Username string `protobuf:"bytes,5,opt,name=username,proto3" json:"username,omitempty"`
Role string `protobuf:"bytes,6,opt,name=role,proto3" json:"role,omitempty"`
Admin bool `protobuf:"varint,7,opt,name=admin,proto3" json:"admin,omitempty"`
Status string `protobuf:"bytes,8,opt,name=status,proto3" json:"status,omitempty"`
DeptId int64 `protobuf:"varint,9,opt,name=dept_id,json=deptId,proto3" json:"dept_id,omitempty"`
Tag string `protobuf:"bytes,10,opt,name=tag,proto3" json:"tag,omitempty"`
Password string `protobuf:"bytes,11,opt,name=password,proto3" json:"password,omitempty"`
Email string `protobuf:"bytes,12,opt,name=email,proto3" json:"email,omitempty"`
Avatar string `protobuf:"bytes,13,opt,name=avatar,proto3" json:"avatar,omitempty"`
Gender string `protobuf:"bytes,14,opt,name=gender,proto3" json:"gender,omitempty"`
Description string `protobuf:"bytes,15,opt,name=description,proto3" json:"description,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
Uid string `protobuf:"bytes,5,opt,name=uid,proto3" json:"uid,omitempty"`
Username string `protobuf:"bytes,6,opt,name=username,proto3" json:"username,omitempty"`
Role string `protobuf:"bytes,7,opt,name=role,proto3" json:"role,omitempty"`
Admin bool `protobuf:"varint,8,opt,name=admin,proto3" json:"admin,omitempty"`
Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"`
DeptId int64 `protobuf:"varint,10,opt,name=dept_id,json=deptId,proto3" json:"dept_id,omitempty"`
Tag string `protobuf:"bytes,11,opt,name=tag,proto3" json:"tag,omitempty"`
Password string `protobuf:"bytes,12,opt,name=password,proto3" json:"password,omitempty"`
Email string `protobuf:"bytes,13,opt,name=email,proto3" json:"email,omitempty"`
Avatar string `protobuf:"bytes,14,opt,name=avatar,proto3" json:"avatar,omitempty"`
Gender string `protobuf:"bytes,15,opt,name=gender,proto3" json:"gender,omitempty"`
Description string `protobuf:"bytes,16,opt,name=description,proto3" json:"description,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -470,6 +495,13 @@ func (x *User) GetUpdatedAt() int64 {
return 0
}
func (x *User) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *User) GetUid() string {
if x != nil {
return x.Uid
@ -560,9 +592,10 @@ type Department struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt int64 `protobuf:"varint,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
ParentId int64 `protobuf:"varint,4,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"`
Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
ParentId int64 `protobuf:"varint,5,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"`
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
Description string `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -618,6 +651,13 @@ func (x *Department) GetUpdatedAt() int64 {
return 0
}
func (x *Department) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Department) GetParentId() int64 {
if x != nil {
return x.ParentId
@ -643,13 +683,14 @@ type Login struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
Uid string `protobuf:"bytes,4,opt,name=uid,proto3" json:"uid,omitempty"`
Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"`
Browser string `protobuf:"bytes,6,opt,name=browser,proto3" json:"browser,omitempty"`
Os string `protobuf:"bytes,7,opt,name=os,proto3" json:"os,omitempty"`
Platform string `protobuf:"bytes,8,opt,name=platform,proto3" json:"platform,omitempty"`
AccessToken string `protobuf:"bytes,9,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
UserAgent string `protobuf:"bytes,10,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
Uid string `protobuf:"bytes,5,opt,name=uid,proto3" json:"uid,omitempty"`
Ip string `protobuf:"bytes,6,opt,name=ip,proto3" json:"ip,omitempty"`
Browser string `protobuf:"bytes,7,opt,name=browser,proto3" json:"browser,omitempty"`
Os string `protobuf:"bytes,8,opt,name=os,proto3" json:"os,omitempty"`
Platform string `protobuf:"bytes,9,opt,name=platform,proto3" json:"platform,omitempty"`
AccessToken string `protobuf:"bytes,10,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
UserAgent string `protobuf:"bytes,11,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -698,6 +739,13 @@ func (x *Login) GetCreatedAt() int64 {
return 0
}
func (x *Login) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Login) GetUid() string {
if x != nil {
return x.Uid
@ -3004,7 +3052,7 @@ var File_organize_proto protoreflect.FileDescriptor
const file_organize_proto_rawDesc = "" +
"\n" +
"\x0eorganize.proto\x12\borganize\x1a\x0faeus/rest.proto\x1a\x17validate/validate.proto\x1a google/protobuf/descriptor.proto\x1a\x1cgoogle/api/annotations.proto\"\xc2\b\n" +
"\x0eorganize.proto\x12\borganize\x1a\x0faeus/rest.proto\x1a\x17validate/validate.proto\x1a google/protobuf/descriptor.proto\x1a\x1cgoogle/api/annotations.proto\"\x90\t\n" +
"\x04Menu\x12*\n" +
"\x02id\x18\x01 \x01(\x03B\x1a\xb2\xb9\x19\x16\n" +
"\n" +
@ -3013,26 +3061,28 @@ const file_organize_proto_rawDesc = "" +
"created_at\x18\x02 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f创建时间\x1a\vview;exportR\tcreatedAt\x12E\n" +
"\n" +
"updated_at\x18\x03 \x01(\x03B&\xb2\xb9\x19\"\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12\x91\x01\n" +
"\x06parent\x18\x04 \x01(\tBy\xb2\xb9\x19u\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12\x91\x01\n" +
"\x06parent\x18\x05 \x01(\tBy\xb2\xb9\x19u\n" +
"\rindex;size:60\x12\f父级菜单\x1a\x19create;update;view;export*\x04menu2\x0freadonly:updateB$type:dropdown;url:/menu/level-labelsR\x06parent\x12^\n" +
"\x04name\x18\x05 \x01(\tBJ\xfaB\x04r\x02\x18<\xb2\xb9\x19?\n" +
"\x04name\x18\x06 \x01(\tBJ\xfaB\x04r\x02\x18<\xb2\xb9\x19?\n" +
"\rindex;size:60\x12\f组件名称2\x0freadonly:update:\x0funique;requiredR\x04name\x12C\n" +
"\x05label\x18\x06 \x01(\tB-\xfaB\x04r\x02\x18x\xb2\xb9\x19\"\n" +
"\x05label\x18\a \x01(\tB-\xfaB\x04r\x02\x18x\xb2\xb9\x19\"\n" +
"\bsize:120\x12\f菜单标题:\brequiredR\x05label\x12[\n" +
"\x03uri\x18\a \x01(\tBI\xfaB\x05r\x03\x18\x80\x04\xb2\xb9\x19=\n" +
"\x03uri\x18\b \x01(\tBI\xfaB\x05r\x03\x18\x80\x04\xb2\xb9\x19=\n" +
"\bsize:512\x12\f菜单链接\x1a\x19create;update;view;export:\brequiredR\x03uri\x12\\\n" +
"\tview_path\x18\b \x01(\tB?\xfaB\x05r\x03\x18\x80\x04\xb2\xb9\x193\n" +
"\tview_path\x18\t \x01(\tB?\xfaB\x05r\x03\x18\x80\x04\xb2\xb9\x193\n" +
"\bsize:512\x12\f视图路径\x1a\x19create;update;view;exportR\bviewPath\x12Q\n" +
"\x04icon\x18\t \x01(\tB=\xfaB\x04r\x02\x18<\xb2\xb9\x192\n" +
"\x04icon\x18\n" +
" \x01(\tB=\xfaB\x04r\x02\x18<\xb2\xb9\x192\n" +
"\asize:60\x12\f菜单图标\x1a\x19create;update;view;exportR\x04icon\x12E\n" +
"\x06hidden\x18\n" +
" \x01(\bB-\xb2\xb9\x19)\x12\f是否隐藏\x1a\x19create;update;view;exportR\x06hidden\x12E\n" +
"\x06public\x18\v \x01(\bB-\xb2\xb9\x19)\x12\f是否公开\x1a\x19create;update;view;exportR\x06public\x12l\n" +
"\vdescription\x18\f \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\x06hidden\x18\v \x01(\bB-\xb2\xb9\x19)\x12\f是否隐藏\x1a\x19create;update;view;exportR\x06hidden\x12E\n" +
"\x06public\x18\f \x01(\bB-\xb2\xb9\x19)\x12\f是否公开\x1a\x19create;update;view;exportR\x06public\x12l\n" +
"\vdescription\x18\r \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\tsize:1024\x12\f备注说明\x1a\x19create;update;view;export*\btextareaR\vdescription\x127\n" +
"\bposition\x18\r \x01(\x03B\x1b\xb2\xb9\x19\x17\x12\x06排序\x1a\rcreate;updateR\bposition:\v\xba\xb9\x19\a\n" +
"\x05menus\"\xd1\x03\n" +
"\bposition\x18\x0e \x01(\x03B\x1b\xb2\xb9\x19\x17\x12\x06排序\x1a\rcreate;updateR\bposition:\v\xba\xb9\x19\a\n" +
"\x05menus\"\x9f\x04\n" +
"\x04Role\x12*\n" +
"\x02id\x18\x01 \x01(\x03B\x1a\xb2\xb9\x19\x16\n" +
"\n" +
@ -3041,14 +3091,16 @@ const file_organize_proto_rawDesc = "" +
"created_at\x18\x02 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f创建时间\x1a\vview;exportR\tcreatedAt\x12E\n" +
"\n" +
"updated_at\x18\x03 \x01(\x03B&\xb2\xb9\x19\"\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12W\n" +
"\x04name\x18\x04 \x01(\tBC\xfaB\x04r\x02\x18<\xb2\xb9\x198\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12W\n" +
"\x04name\x18\x05 \x01(\tBC\xfaB\x04r\x02\x18<\xb2\xb9\x198\n" +
"\rindex;size:60\x12\f角色名称2\x0freadonly:update:\brequiredR\x04name\x12B\n" +
"\x05label\x18\x05 \x01(\tB,\xfaB\x04r\x02\x18<\xb2\xb9\x19!\n" +
"\x05label\x18\x06 \x01(\tB,\xfaB\x04r\x02\x18<\xb2\xb9\x19!\n" +
"\asize:60\x12\f角色标题:\brequiredR\x05label\x12l\n" +
"\vdescription\x18\x06 \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\vdescription\x18\a \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\tsize:1024\x12\f备注说明\x1a\x19list;create;update;export*\btextareaR\vdescription:\v\xba\xb9\x19\a\n" +
"\x05roles\"\xb1\x03\n" +
"\x05roles\"\xff\x03\n" +
"\n" +
"Permission\x12*\n" +
"\x02id\x18\x01 \x01(\x03B\x1a\xb2\xb9\x19\x16\n" +
@ -3058,14 +3110,16 @@ const file_organize_proto_rawDesc = "" +
"created_at\x18\x02 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f创建时间\x1a\vview;exportR\tcreatedAt\x12E\n" +
"\n" +
"updated_at\x18\x03 \x01(\x03B&\xb2\xb9\x19\"\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12E\n" +
"\x04menu\x18\x04 \x01(\tB1\xb2\xb9\x19-\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12E\n" +
"\x04menu\x18\x05 \x01(\tB1\xb2\xb9\x19-\n" +
"\rindex;size:60\x12\f所属菜单*\x04menu:\brequiredR\x04menu\x12R\n" +
"\n" +
"permission\x18\x05 \x01(\tB2\xfaB\x04r\x02\x18<\xb2\xb9\x19'\n" +
"permission\x18\x06 \x01(\tB2\xfaB\x04r\x02\x18<\xb2\xb9\x19'\n" +
"\rindex;size:60\x12\f权限名称:\brequiredR\n" +
"permission\x12B\n" +
"\x05label\x18\x06 \x01(\tB,\xfaB\x04r\x02\x18<\xb2\xb9\x19!\n" +
"\x05label\x18\a \x01(\tB,\xfaB\x04r\x02\x18<\xb2\xb9\x19!\n" +
"\asize:60\x12\f权限标题:\brequiredR\x05label:\x11\xba\xb9\x19\r\n" +
"\vpermissions\"\xd1\x01\n" +
"\x0eRolePermission\x12$\n" +
@ -3078,7 +3132,7 @@ const file_organize_proto_rawDesc = "" +
"permission\x18\x03 \x01(\tB\x1f\xb2\xb9\x19\x1b\n" +
"\asize:60\x12\x06权限:\brequiredR\n" +
"permission:\x16\xba\xb9\x19\x12\n" +
"\x10role_permissions\"\xa2\v\n" +
"\x10role_permissions\"\xf0\v\n" +
"\x04User\x12$\n" +
"\x02id\x18\x01 \x01(\x03B\x14\xb2\xb9\x19\x10\n" +
"\n" +
@ -3087,33 +3141,35 @@ const file_organize_proto_rawDesc = "" +
"created_at\x18\x02 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f创建时间\x1a\vview;exportR\tcreatedAt\x12E\n" +
"\n" +
"updated_at\x18\x03 \x01(\x03B&\xb2\xb9\x19\"\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12x\n" +
"\x03uid\x18\x04 \x01(\tBf\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x19Y\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12x\n" +
"\x03uid\x18\x05 \x01(\tBf\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x19Y\n" +
"\rindex;size:20\x12\f用户工号2\x0freadonly:update:)required;unique;regexp:^[a-zA-Z0-9]{3,8}$R\x03uid\x12J\n" +
"\busername\x18\x05 \x01(\tB.\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x19!\n" +
"\busername\x18\x06 \x01(\tB.\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x19!\n" +
"\asize:20\x12\f用户名称:\brequiredR\busername\x12z\n" +
"\x04role\x18\x06 \x01(\tBf\xfaB\x04r\x02\x18<\xb2\xb9\x19[\n" +
"\x04role\x18\a \x01(\tBf\xfaB\x04r\x02\x18<\xb2\xb9\x19[\n" +
"\x1bsize:60;not null;default:''\x12\f所属角色*\x04role:\brequiredB\x1etype:dropdown;url:/role/labelsR\x04role\x12-\n" +
"\x05admin\x18\a \x01(\bB\x17\xb2\xb9\x19\x13\x12\t管理员\x1a\x06createR\x05admin\x12u\n" +
"\x06status\x18\b \x01(\tB]\xb2\xb9\x19Y\n" +
"\x05admin\x18\b \x01(\bB\x17\xb2\xb9\x19\x13\x12\t管理员\x1a\x06createR\x05admin\x12u\n" +
"\x06status\x18\t \x01(\tB]\xb2\xb9\x19Y\n" +
"\x16size:20;default:normal\x12\x06状态\x1a\x19create,update,list,searchR\x1cnormal:正常;disable:禁用R\x06status\x12{\n" +
"\adept_id\x18\t \x01(\x03Bb\xb2\xb9\x19^\n" +
"\adept_id\x18\n" +
" \x01(\x03Bb\xb2\xb9\x19^\n" +
"\x12not null;default:0\x12\f所属部门*\n" +
"department:\brequiredB$type:dropdown;url:/department/labelsR\x06deptId\x12\x88\x01\n" +
"\x03tag\x18\n" +
" \x01(\tBv\xfaB\x04r\x02\x18<\xb2\xb9\x19k\n" +
"\x03tag\x18\v \x01(\tBv\xfaB\x04r\x02\x18<\xb2\xb9\x19k\n" +
"\asize:60\x12\f用户标签\x1a\x12list;create;updateB\x1ctype:dropdown;url:/user/tagsJ created;filterable;default_firstR\x03tag\x12P\n" +
"\bpassword\x18\v \x01(\tB4\xfaB\x04r\x02\x18<\xb2\xb9\x19)\n" +
"\bpassword\x18\f \x01(\tB4\xfaB\x04r\x02\x18<\xb2\xb9\x19)\n" +
"\asize:60\x12\f用户密码\x1a\x06create:\brequiredR\bpassword\x12X\n" +
"\x05email\x18\f \x01(\tBB\xfaB\x04r\x02\x18<\xb2\xb9\x197\n" +
"\x05email\x18\r \x01(\tBB\xfaB\x04r\x02\x18<\xb2\xb9\x197\n" +
"\asize:60\x12\f用户邮箱\x1a\x1ecreate;update;view;list;exportR\x05email\x12C\n" +
"\x06avatar\x18\r \x01(\tB+\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19\x1f\n" +
"\x06avatar\x18\x0e \x01(\tB+\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19\x1f\n" +
"\tsize:1024\x12\f用户头像\x1a\x04viewR\x06avatar\x12\x90\x01\n" +
"\x06gender\x18\x0e \x01(\tBx\xfaB\x04r\x02\x18\x14\xb2\xb9\x19m\n" +
"\x06gender\x18\x0f \x01(\tBx\xfaB\x04r\x02\x18\x14\xb2\xb9\x19m\n" +
"\x13size:20;default:man\x12\f用户性别\x1a\x1elist;create;update;view;export:\brequiredR\x1eman:男;woman:女;other:其他R\x06gender\x12l\n" +
"\vdescription\x18\x0f \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\vdescription\x18\x10 \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\tsize:1024\x12\f备注说明\x1a\x19create;update;view;export*\btextareaR\vdescription:\v\xba\xb9\x19\a\n" +
"\x05users\"\xea\x03\n" +
"\x05users\"\xb8\x04\n" +
"\n" +
"Department\x12$\n" +
"\x02id\x18\x01 \x01(\x03B\x14\xb2\xb9\x19\x10\n" +
@ -3123,35 +3179,39 @@ const file_organize_proto_rawDesc = "" +
"created_at\x18\x02 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f创建时间\x1a\vview;exportR\tcreatedAt\x12E\n" +
"\n" +
"updated_at\x18\x03 \x01(\x03B&\xb2\xb9\x19\"\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12g\n" +
"\tparent_id\x18\x04 \x01(\x03BJ\xb2\xb9\x19F\x12\f父级部门*\n" +
"\x05index\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12g\n" +
"\tparent_id\x18\x05 \x01(\x03BJ\xb2\xb9\x19F\x12\f父级部门*\n" +
"departmentB*type:dropdown;url:/department/level-labelsR\bparentId\x12@\n" +
"\x04name\x18\x05 \x01(\tB,\xfaB\x04r\x02\x18\x14\xb2\xb9\x19!\n" +
"\x04name\x18\x06 \x01(\tB,\xfaB\x04r\x02\x18\x14\xb2\xb9\x19!\n" +
"\asize:20\x12\f部门名称:\brequiredR\x04name\x12q\n" +
"\vdescription\x18\x06 \x01(\tBO\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19C\n" +
"\vdescription\x18\a \x01(\tBO\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19C\n" +
"\tsize:1024\x12\f备注说明\x1a\x1ecreate;update;view;export;list*\btextareaR\vdescription:\x11\xba\xb9\x19\r\n" +
"\vdepartments\"\x9e\x05\n" +
"\vdepartments\"\xec\x05\n" +
"\x05Login\x12$\n" +
"\x02id\x18\x01 \x01(\x03B\x14\xb2\xb9\x19\x10\n" +
"\n" +
"primaryKey\x12\x02IDR\x02id\x12J\n" +
"\n" +
"created_at\x18\x02 \x01(\x03B+\xb2\xb9\x19'\x12\f登录时间\x1a\x17list;search;view;exportR\tcreatedAt\x12W\n" +
"\x03uid\x18\x04 \x01(\tBE\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x198\n" +
"created_at\x18\x02 \x01(\x03B+\xb2\xb9\x19'\x12\f登录时间\x1a\x17list;search;view;exportR\tcreatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12W\n" +
"\x03uid\x18\x05 \x01(\tBE\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x198\n" +
"\rindex;size:20\x12\x06用户*\x04user2\x0freadonly:update:\brequiredR\x03uid\x12E\n" +
"\x02ip\x18\x05 \x01(\tB5\xb2\xb9\x191\n" +
"\x02ip\x18\x06 \x01(\tB5\xb2\xb9\x191\n" +
"\bsize:128\x12\f登录地址\x1a\x17list;search;view;exportR\x02ip\x12E\n" +
"\abrowser\x18\x06 \x01(\tB+\xb2\xb9\x19'\n" +
"\abrowser\x18\a \x01(\tB+\xb2\xb9\x19'\n" +
"\bsize:128\x12\t浏览器\x1a\x10list;view;exportR\abrowser\x12>\n" +
"\x02os\x18\a \x01(\tB.\xb2\xb9\x19*\n" +
"\x02os\x18\b \x01(\tB.\xb2\xb9\x19*\n" +
"\bsize:128\x12\f操作系统\x1a\x10list;view;exportR\x02os\x12J\n" +
"\bplatform\x18\b \x01(\tB.\xb2\xb9\x19*\n" +
"\bplatform\x18\t \x01(\tB.\xb2\xb9\x19*\n" +
"\bsize:128\x12\f系统平台\x1a\x10list;view;exportR\bplatform\x12R\n" +
"\faccess_token\x18\t \x01(\tB/\xb2\xb9\x19+\n" +
"\faccess_token\x18\n" +
" \x01(\tB/\xb2\xb9\x19+\n" +
"\tsize:1024\x12\f访问令牌\x1a\x10list;view;exportR\vaccessToken\x12N\n" +
"\n" +
"user_agent\x18\n" +
" \x01(\tB/\xb2\xb9\x19+\n" +
"user_agent\x18\v \x01(\tB/\xb2\xb9\x19+\n" +
"\tsize:1024\x12\f用户代理\x1a\x10list;view;exportR\tuserAgent:\f\xba\xb9\x19\b\n" +
"\x06logins\"8\n" +
"\n" +

View File

@ -62,6 +62,8 @@ func (m *Menu) validate(all bool) error {
// no validation rules for UpdatedAt
// no validation rules for Domain
// no validation rules for Parent
if utf8.RuneCountInString(m.GetName()) > 60 {
@ -240,6 +242,8 @@ func (m *Role) validate(all bool) error {
// no validation rules for UpdatedAt
// no validation rules for Domain
if utf8.RuneCountInString(m.GetName()) > 60 {
err := RoleValidationError{
field: "Name",
@ -378,6 +382,8 @@ func (m *Permission) validate(all bool) error {
// no validation rules for UpdatedAt
// no validation rules for Domain
// no validation rules for Menu
if utf8.RuneCountInString(m.GetPermission()) > 60 {
@ -621,6 +627,8 @@ func (m *User) validate(all bool) error {
// no validation rules for UpdatedAt
// no validation rules for Domain
if l := utf8.RuneCountInString(m.GetUid()); l < 5 || l > 20 {
err := UserValidationError{
field: "Uid",
@ -831,6 +839,8 @@ func (m *Department) validate(all bool) error {
// no validation rules for UpdatedAt
// no validation rules for Domain
// no validation rules for ParentId
if utf8.RuneCountInString(m.GetName()) > 20 {
@ -957,6 +967,8 @@ func (m *Login) validate(all bool) error {
// no validation rules for CreatedAt
// no validation rules for Domain
if l := utf8.RuneCountInString(m.GetUid()); l < 5 || l > 20 {
err := LoginValidationError{
field: "Uid",

View File

@ -17,16 +17,17 @@ message Menu {
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"菜单ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
string parent = 4 [(aeus.field)={gorm:"index;size:60",scenarios:"create;update;view;export",props:"readonly:update",live:"type:dropdown;url:/menu/level-labels",format:"menu",comment:"父级菜单"}];
string name = 5 [(aeus.field)={gorm:"index;size:60",props:"readonly:update",rule:"unique;required",comment: "组件名称"},(validate.rules).string = {max_len: 60}];
string label = 6 [(aeus.field)={gorm:"size:120",rule:"required",comment: "菜单标题"},(validate.rules).string = {max_len: 120}];
string uri = 7 [(aeus.field)={gorm:"size:512",rule:"required",scenarios:"create;update;view;export",comment: "菜单链接"},(validate.rules).string = {max_len: 512}];
string view_path = 8 [(aeus.field)={gorm:"size:512",scenarios:"create;update;view;export",comment: "视图路径"},(validate.rules).string = {max_len: 512}];
string icon = 9 [(aeus.field)={gorm:"size:60",scenarios:"create;update;view;export",comment: "菜单图标"},(validate.rules).string = {max_len: 60}];
bool hidden = 10 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否隐藏"}];
bool public = 11 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否公开"}];
string description = 12 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
int64 position = 13 [(aeus.field)={comment:"排序",scenarios:"create;update"}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string parent = 5 [(aeus.field)={gorm:"index;size:60",scenarios:"create;update;view;export",props:"readonly:update",live:"type:dropdown;url:/menu/level-labels",format:"menu",comment:"父级菜单"}];
string name = 6 [(aeus.field)={gorm:"index;size:60",props:"readonly:update",rule:"unique;required",comment: "组件名称"},(validate.rules).string = {max_len: 60}];
string label = 7 [(aeus.field)={gorm:"size:120",rule:"required",comment: "菜单标题"},(validate.rules).string = {max_len: 120}];
string uri = 8 [(aeus.field)={gorm:"size:512",rule:"required",scenarios:"create;update;view;export",comment: "菜单链接"},(validate.rules).string = {max_len: 512}];
string view_path = 9 [(aeus.field)={gorm:"size:512",scenarios:"create;update;view;export",comment: "视图路径"},(validate.rules).string = {max_len: 512}];
string icon = 10 [(aeus.field)={gorm:"size:60",scenarios:"create;update;view;export",comment: "菜单图标"},(validate.rules).string = {max_len: 60}];
bool hidden = 11 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否隐藏"}];
bool public = 12 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否公开"}];
string description = 13 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
int64 position = 14 [(aeus.field)={comment:"排序",scenarios:"create;update"}];
}
// Role
@ -37,9 +38,10 @@ message Role {
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment: "角色ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
string name = 4 [(aeus.field)={gorm:"index;size:60",rule:"required",props:"readonly:update",comment: "角色名称"},(validate.rules).string = {max_len: 60}];
string label = 5 [(aeus.field)={gorm:"size:60",rule:"required",comment: "角色标题"},(validate.rules).string = {max_len: 60}];
string description = 6 [(aeus.field)={gorm:"size:1024",scenarios:"list;create;update;export",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string name = 5 [(aeus.field)={gorm:"index;size:60",rule:"required",props:"readonly:update",comment: "角色名称"},(validate.rules).string = {max_len: 60}];
string label = 6 [(aeus.field)={gorm:"size:60",rule:"required",comment: "角色标题"},(validate.rules).string = {max_len: 60}];
string description = 7 [(aeus.field)={gorm:"size:1024",scenarios:"list;create;update;export",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
}
// Permission
@ -50,9 +52,10 @@ message Permission {
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment: "权限ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
string menu = 4 [(aeus.field)={gorm:"index;size:60",format:"menu",rule:"required",comment: "所属菜单"}];
string permission = 5 [(aeus.field)={gorm:"index;size:60",rule:"required",comment: "权限名称"},(validate.rules).string = {max_len: 60}];
string label = 6 [(aeus.field)={gorm:"size:60",rule:"required",comment: "权限标题"},(validate.rules).string = {max_len: 60}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string menu = 5 [(aeus.field)={gorm:"index;size:60",format:"menu",rule:"required",comment: "所属菜单"}];
string permission = 6 [(aeus.field)={gorm:"index;size:60",rule:"required",comment: "权限名称"},(validate.rules).string = {max_len: 60}];
string label = 7 [(aeus.field)={gorm:"size:60",rule:"required",comment: "权限标题"},(validate.rules).string = {max_len: 60}];
}
// RolePermission
@ -73,18 +76,19 @@ message User {
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment: "ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
string uid = 4 [(aeus.field) = {gorm:"index;size:20",rule:"required;unique;regexp:^[a-zA-Z0-9]{3,8}$",props:"readonly:update",comment: "用户工号"},(validate.rules).string = {min_len: 5, max_len: 20}];
string username = 5 [(aeus.field)={gorm:"size:20",rule:"required",comment: "用户名称"},(validate.rules).string = {min_len: 5, max_len: 20}];
string role = 6 [(aeus.field)={gorm:"size:60;not null;default:''",rule:"required",format:"role",live:"type:dropdown;url:/role/labels",comment: "所属角色"},(validate.rules).string = {max_len: 60}];
bool admin = 7 [(aeus.field)={scenarios:"create",comment:"管理员"}];
string status = 8 [(aeus.field)={scenarios:"create,update,list,search",gorm:"size:20;default:normal",enum:"normal:正常;disable:禁用",comment:"状态"}];
int64 dept_id = 9 [(aeus.field) = {gorm:"not null;default:0",rule:"required",live:"type:dropdown;url:/department/labels",format:"department",comment: "所属部门"}];
string tag = 10 [ (aeus.field)={gorm:"size:60",scenarios:"list;create;update",dropdown:"created;filterable;default_first",live:"type:dropdown;url:/user/tags",comment: "用户标签"},(validate.rules).string = {max_len: 60}];
string password = 11 [(aeus.field)={gorm:"size:60",rule:"required",scenarios:"create",comment: "用户密码"},(validate.rules).string = {max_len: 60}];
string email = 12 [(aeus.field)={gorm:"size:60",scenarios:"create;update;view;list;export",comment: "用户邮箱"},(validate.rules).string = {max_len: 60}];
string avatar = 13 [(aeus.field)={gorm:"size:1024",scenarios:"view",comment: "用户头像"},(validate.rules).string = {max_len: 1024}];
string gender = 14 [(aeus.field)={gorm:"size:20;default:man",rule:"required",scenarios:"list;create;update;view;export",enum:"man:男;woman:女;other:其他",comment: "用户性别"},(validate.rules).string = {max_len: 20}];
string description = 15 [(aeus.field)={gorm:"size:1024",format:"textarea",scenarios:"create;update;view;export",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string uid = 5 [(aeus.field) = {gorm:"index;size:20",rule:"required;unique;regexp:^[a-zA-Z0-9]{3,8}$",props:"readonly:update",comment: "用户工号"},(validate.rules).string = {min_len: 5, max_len: 20}];
string username = 6 [(aeus.field)={gorm:"size:20",rule:"required",comment: "用户名称"},(validate.rules).string = {min_len: 5, max_len: 20}];
string role = 7 [(aeus.field)={gorm:"size:60;not null;default:''",rule:"required",format:"role",live:"type:dropdown;url:/role/labels",comment: "所属角色"},(validate.rules).string = {max_len: 60}];
bool admin = 8 [(aeus.field)={scenarios:"create",comment:"管理员"}];
string status = 9 [(aeus.field)={scenarios:"create,update,list,search",gorm:"size:20;default:normal",enum:"normal:正常;disable:禁用",comment:"状态"}];
int64 dept_id = 10 [(aeus.field) = {gorm:"not null;default:0",rule:"required",live:"type:dropdown;url:/department/labels",format:"department",comment: "所属部门"}];
string tag = 11 [ (aeus.field)={gorm:"size:60",scenarios:"list;create;update",dropdown:"created;filterable;default_first",live:"type:dropdown;url:/user/tags",comment: "用户标签"},(validate.rules).string = {max_len: 60}];
string password = 12 [(aeus.field)={gorm:"size:60",rule:"required",scenarios:"create",comment: "用户密码"},(validate.rules).string = {max_len: 60}];
string email = 13 [(aeus.field)={gorm:"size:60",scenarios:"create;update;view;list;export",comment: "用户邮箱"},(validate.rules).string = {max_len: 60}];
string avatar = 14 [(aeus.field)={gorm:"size:1024",scenarios:"view",comment: "用户头像"},(validate.rules).string = {max_len: 1024}];
string gender = 15 [(aeus.field)={gorm:"size:20;default:man",rule:"required",scenarios:"list;create;update;view;export",enum:"man:男;woman:女;other:其他",comment: "用户性别"},(validate.rules).string = {max_len: 20}];
string description = 16 [(aeus.field)={gorm:"size:1024",format:"textarea",scenarios:"create;update;view;export",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
}
// Department
@ -95,9 +99,10 @@ message Department {
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
int64 parent_id = 4 [(aeus.field)={live:"type:dropdown;url:/department/level-labels",format:"department",comment:"父级部门"}];
string name = 5 [(aeus.field)={gorm:"size:20",rule:"required",comment: "部门名称"},(validate.rules).string = {max_len: 20}];
string description = 6 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export;list",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
int64 parent_id = 5 [(aeus.field)={live:"type:dropdown;url:/department/level-labels",format:"department",comment:"父级部门"}];
string name = 6 [(aeus.field)={gorm:"size:20",rule:"required",comment: "部门名称"},(validate.rules).string = {max_len: 20}];
string description = 7 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export;list",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
}
message Login {
@ -106,13 +111,14 @@ message Login {
};
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"list;search;view;export",comment:"登录时间"}];
string uid = 4 [(aeus.field)={gorm:"index;size:20",rule:"required",props:"readonly:update",format:"user",comment: "用户"},(validate.rules).string = {min_len: 5, max_len: 20}];
string ip = 5 [(aeus.field)={gorm:"size:128",scenarios:"list;search;view;export",comment: "登录地址"}];
string browser = 6 [(aeus.field)={gorm:"size:128",scenarios:"list;view;export",comment: "浏览器"}];
string os = 7 [(aeus.field)={gorm:"size:128",scenarios:"list;view;export",comment: "操作系统"}];
string platform = 8 [(aeus.field)={gorm:"size:128",scenarios:"list;view;export",comment: "系统平台"}];
string access_token = 9 [(aeus.field)={gorm:"size:1024",scenarios:"list;view;export",comment: "访问令牌"}];
string user_agent = 10 [(aeus.field)={gorm:"size:1024",scenarios:"list;view;export",comment: "用户代理"}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string uid = 5 [(aeus.field)={gorm:"index;size:20",rule:"required",props:"readonly:update",format:"user",comment: "用户"},(validate.rules).string = {min_len: 5, max_len: 20}];
string ip = 6 [(aeus.field)={gorm:"size:128",scenarios:"list;search;view;export",comment: "登录地址"}];
string browser = 7 [(aeus.field)={gorm:"size:128",scenarios:"list;view;export",comment: "浏览器"}];
string os = 8 [(aeus.field)={gorm:"size:128",scenarios:"list;view;export",comment: "操作系统"}];
string platform = 9 [(aeus.field)={gorm:"size:128",scenarios:"list;view;export",comment: "系统平台"}];
string access_token = 10 [(aeus.field)={gorm:"size:1024",scenarios:"list;view;export",comment: "访问令牌"}];
string user_agent = 11 [(aeus.field)={gorm:"size:1024",scenarios:"list;view;export",comment: "用户代理"}];
}
message LabelValue {

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: organize.proto
// date: 2025-07-22 18:30:59
// date: 2025-07-23 17:06:59
package pb

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: organize.proto
// date: 2025-07-22 18:30:59
// date: 2025-07-23 17:06:59
package pb
@ -12,6 +12,7 @@ type MenuModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"菜单ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index;column:updated_at" comment:"更新时间" scenarios:"view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Parent string `json:"parent" yaml:"parent" xml:"parent" gorm:"index;size:60;column:parent" comment:"父级菜单" scenarios:"create;update;view;export" format:"menu" props:"readonly:update" live:"type:dropdown;url:/menu/level-labels"`
Name string `json:"name" yaml:"name" xml:"name" gorm:"index;size:60;column:name" comment:"组件名称" props:"readonly:update" rule:"unique;required"`
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:120;column:label" comment:"菜单标题" rule:"required"`
@ -32,6 +33,7 @@ func (m *MenuModel) FromValue(x *Menu) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.UpdatedAt = x.UpdatedAt
m.Domain = x.Domain
m.Parent = x.Parent
m.Name = x.Name
m.Label = x.Label
@ -49,6 +51,7 @@ func (m *MenuModel) ToValue() (x *Menu) {
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.UpdatedAt = m.UpdatedAt
x.Domain = m.Domain
x.Parent = m.Parent
x.Name = m.Name
x.Label = m.Label
@ -98,6 +101,7 @@ type RoleModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"角色ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index;column:updated_at" comment:"更新时间" scenarios:"view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Name string `json:"name" yaml:"name" xml:"name" gorm:"index;size:60;column:name" comment:"角色名称" props:"readonly:update" rule:"required"`
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:60;column:label" comment:"角色标题" rule:"required"`
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024;column:description" comment:"备注说明" scenarios:"list;create;update;export" format:"textarea"`
@ -111,6 +115,7 @@ func (m *RoleModel) FromValue(x *Role) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.UpdatedAt = x.UpdatedAt
m.Domain = x.Domain
m.Name = x.Name
m.Label = x.Label
m.Description = x.Description
@ -121,6 +126,7 @@ func (m *RoleModel) ToValue() (x *Role) {
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.UpdatedAt = m.UpdatedAt
x.Domain = m.Domain
x.Name = m.Name
x.Label = m.Label
x.Description = m.Description
@ -163,6 +169,7 @@ type PermissionModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"权限ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index;column:updated_at" comment:"更新时间" scenarios:"view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Menu string `json:"menu" yaml:"menu" xml:"menu" gorm:"index;size:60;column:menu" comment:"所属菜单" format:"menu" rule:"required"`
Permission string `json:"permission" yaml:"permission" xml:"permission" gorm:"index;size:60;column:permission" comment:"权限名称" rule:"required"`
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:60;column:label" comment:"权限标题" rule:"required"`
@ -176,6 +183,7 @@ func (m *PermissionModel) FromValue(x *Permission) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.UpdatedAt = x.UpdatedAt
m.Domain = x.Domain
m.Menu = x.Menu
m.Permission = x.Permission
m.Label = x.Label
@ -186,6 +194,7 @@ func (m *PermissionModel) ToValue() (x *Permission) {
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.UpdatedAt = m.UpdatedAt
x.Domain = m.Domain
x.Menu = m.Menu
x.Permission = m.Permission
x.Label = m.Label
@ -284,6 +293,7 @@ type UserModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index;column:updated_at" comment:"更新时间" scenarios:"view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Uid string `json:"uid" yaml:"uid" xml:"uid" gorm:"index;size:20;column:uid" comment:"用户工号" props:"readonly:update" rule:"required;unique;regexp:^[a-zA-Z0-9]{3,8}$"`
Username string `json:"username" yaml:"username" xml:"username" gorm:"size:20;column:username" comment:"用户名称" rule:"required"`
Role string `json:"role" yaml:"role" xml:"role" gorm:"size:60;not null;default:'';column:role" comment:"所属角色" format:"role" rule:"required" live:"type:dropdown;url:/role/labels"`
@ -306,6 +316,7 @@ func (m *UserModel) FromValue(x *User) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.UpdatedAt = x.UpdatedAt
m.Domain = x.Domain
m.Uid = x.Uid
m.Username = x.Username
m.Role = x.Role
@ -325,6 +336,7 @@ func (m *UserModel) ToValue() (x *User) {
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.UpdatedAt = m.UpdatedAt
x.Domain = m.Domain
x.Uid = m.Uid
x.Username = m.Username
x.Role = m.Role
@ -376,6 +388,7 @@ type DepartmentModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index;column:updated_at" comment:"更新时间" scenarios:"view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
ParentId int64 `json:"parent_id" yaml:"parentId" xml:"parentId" gorm:"column:parent_id" comment:"父级部门" format:"department" live:"type:dropdown;url:/department/level-labels"`
Name string `json:"name" yaml:"name" xml:"name" gorm:"size:20;column:name" comment:"部门名称" rule:"required"`
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024;column:description" comment:"备注说明" scenarios:"create;update;view;export;list" format:"textarea"`
@ -389,6 +402,7 @@ func (m *DepartmentModel) FromValue(x *Department) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.UpdatedAt = x.UpdatedAt
m.Domain = x.Domain
m.ParentId = x.ParentId
m.Name = x.Name
m.Description = x.Description
@ -399,6 +413,7 @@ func (m *DepartmentModel) ToValue() (x *Department) {
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.UpdatedAt = m.UpdatedAt
x.Domain = m.Domain
x.ParentId = m.ParentId
x.Name = m.Name
x.Description = m.Description
@ -440,6 +455,7 @@ func NewDepartmentModel() *DepartmentModel {
type LoginModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"登录时间" scenarios:"list;search;view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Uid string `json:"uid" yaml:"uid" xml:"uid" gorm:"index;size:20;column:uid" comment:"用户" format:"user" props:"readonly:update" rule:"required"`
Ip string `json:"ip" yaml:"ip" xml:"ip" gorm:"size:128;column:ip" comment:"登录地址" scenarios:"list;search;view;export"`
Browser string `json:"browser" yaml:"browser" xml:"browser" gorm:"size:128;column:browser" comment:"浏览器" scenarios:"list;view;export"`
@ -456,6 +472,7 @@ func (m *LoginModel) TableName() string {
func (m *LoginModel) FromValue(x *Login) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.Domain = x.Domain
m.Uid = x.Uid
m.Ip = x.Ip
m.Browser = x.Browser
@ -469,6 +486,7 @@ func (m *LoginModel) ToValue() (x *Login) {
x = &Login{}
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.Domain = m.Domain
x.Uid = m.Uid
x.Ip = m.Ip
x.Browser = m.Browser

View File

@ -31,10 +31,11 @@ type Setting struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt int64 `protobuf:"varint,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
Type string `protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"`
Value string `protobuf:"bytes,6,opt,name=value,proto3" json:"value,omitempty"`
Description string `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"`
Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"`
Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
Type string `protobuf:"bytes,6,opt,name=type,proto3" json:"type,omitempty"`
Value string `protobuf:"bytes,7,opt,name=value,proto3" json:"value,omitempty"`
Description string `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -90,6 +91,13 @@ func (x *Setting) GetUpdatedAt() int64 {
return 0
}
func (x *Setting) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Setting) GetName() string {
if x != nil {
return x.Name
@ -123,11 +131,12 @@ type Activity struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
Uid string `protobuf:"bytes,3,opt,name=uid,proto3" json:"uid,omitempty"`
Action string `protobuf:"bytes,4,opt,name=action,proto3" json:"action,omitempty"`
Module string `protobuf:"bytes,5,opt,name=module,proto3" json:"module,omitempty"`
Table string `protobuf:"bytes,6,opt,name=table,proto3" json:"table,omitempty"`
Data string `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty"`
Domain string `protobuf:"bytes,3,opt,name=domain,proto3" json:"domain,omitempty"`
Uid string `protobuf:"bytes,4,opt,name=uid,proto3" json:"uid,omitempty"`
Action string `protobuf:"bytes,5,opt,name=action,proto3" json:"action,omitempty"`
Module string `protobuf:"bytes,6,opt,name=module,proto3" json:"module,omitempty"`
Table string `protobuf:"bytes,7,opt,name=table,proto3" json:"table,omitempty"`
Data string `protobuf:"bytes,8,opt,name=data,proto3" json:"data,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -176,6 +185,13 @@ func (x *Activity) GetCreatedAt() int64 {
return 0
}
func (x *Activity) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *Activity) GetUid() string {
if x != nil {
return x.Uid
@ -355,7 +371,7 @@ var File_system_proto protoreflect.FileDescriptor
const file_system_proto_rawDesc = "" +
"\n" +
"\fsystem.proto\x12\x06system\x1a\x0faeus/rest.proto\x1a\x17validate/validate.proto\x1a google/protobuf/descriptor.proto\x1a\x1cgoogle/api/annotations.proto\"\xb7\x04\n" +
"\fsystem.proto\x12\x06system\x1a\x0faeus/rest.proto\x1a\x17validate/validate.proto\x1a google/protobuf/descriptor.proto\x1a\x1cgoogle/api/annotations.proto\"\x85\x05\n" +
"\aSetting\x12$\n" +
"\x02id\x18\x01 \x01(\x03B\x14\xb2\xb9\x19\x10\n" +
"\n" +
@ -363,32 +379,36 @@ const file_system_proto_rawDesc = "" +
"\n" +
"created_at\x18\x02 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f创建时间\x1a\vview;exportR\tcreatedAt\x12>\n" +
"\n" +
"updated_at\x18\x03 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12N\n" +
"\x04name\x18\x04 \x01(\tB:\xfaB\x04r\x02\x18\x14\xb2\xb9\x19/\n" +
"updated_at\x18\x03 \x01(\x03B\x1f\xb2\xb9\x19\x1b\x12\f更新时间\x1a\vview;exportR\tupdatedAt\x12L\n" +
"\x06domain\x18\x04 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12N\n" +
"\x04name\x18\x05 \x01(\tB:\xfaB\x04r\x02\x18\x14\xb2\xb9\x19/\n" +
"\asize:60\x12\t配置项2\x0freadonly:update:\brequiredR\x04name\x12e\n" +
"\x04type\x18\x05 \x01(\tBQ\xfaB\x04r\x02\x18\x14\xb2\xb9\x19F\n" +
"\x04type\x18\x06 \x01(\tBQ\xfaB\x04r\x02\x18\x14\xb2\xb9\x19F\n" +
"\asize:20\x12\f数据类型:\brequiredR#text:文本;number:数字;json:JSONR\x04type\x12L\n" +
"\x05value\x18\x06 \x01(\tB6\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19*\n" +
"\x05value\x18\a \x01(\tB6\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19*\n" +
"\tsize:1024\x12\t配置值*\btextarea:\brequiredR\x05value\x12q\n" +
"\vdescription\x18\a \x01(\tBO\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19C\n" +
"\vdescription\x18\b \x01(\tBO\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19C\n" +
"\tsize:1024\x12\f备注说明\x1a\x1elist;create;update;view;export*\btextareaR\vdescription:\x0e\xba\xb9\x19\n" +
"\n" +
"\bsettings\"\xe2\x05\n" +
"\bsettings\"\xb0\x06\n" +
"\bActivity\x12$\n" +
"\x02id\x18\x01 \x01(\x03B\x14\xb2\xb9\x19\x10\n" +
"\n" +
"primaryKey\x12\x02IDR\x02id\x12L\n" +
"\n" +
"created_at\x18\x02 \x01(\x03B-\xb2\xb9\x19)\x12\f创建时间\x1a\x19search;search;view;exportR\tcreatedAt\x12W\n" +
"\x03uid\x18\x03 \x01(\tBE\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x198\n" +
"created_at\x18\x02 \x01(\x03B-\xb2\xb9\x19)\x12\f创建时间\x1a\x19search;search;view;exportR\tcreatedAt\x12L\n" +
"\x06domain\x18\x03 \x01(\tB4\xb2\xb9\x190\n" +
"!index;size:60;not null;default:''\x12\x03域\x1a\x06exportR\x06domain\x12W\n" +
"\x03uid\x18\x04 \x01(\tBE\xfaB\x06r\x04\x10\x05\x18\x14\xb2\xb9\x198\n" +
"\rindex;size:20\x12\x06用户*\x04user2\x0freadonly:update:\brequiredR\x03uid\x12\xc9\x01\n" +
"\x06action\x18\x04 \x01(\tB\xb0\x01\xb2\xb9\x19\xab\x01\n" +
"\x06action\x18\x05 \x01(\tB\xb0\x01\xb2\xb9\x19\xab\x01\n" +
"!index;size:20;not null;default:''\x12\x06行为\x1a%search;list;create;update;view;export2\rmatch:exactly:\brequiredR>create:新建#198754;update:更新#f09d00;delete:删除#e63757R\x06action\x12h\n" +
"\x06module\x18\x05 \x01(\tBP\xb2\xb9\x19L\n" +
"\x06module\x18\x06 \x01(\tBP\xb2\xb9\x19L\n" +
"\x1bsize:60;not null;default:''\x12\x06模块\x1a%search;list;create;update;view;exportR\x06module\x12_\n" +
"\x05table\x18\x06 \x01(\tBI\xb2\xb9\x19E\n" +
"\x05table\x18\a \x01(\tBI\xb2\xb9\x19E\n" +
"\x1bsize:60;not null;default:''\x12\x06模型\x1a\x1elist;create;update;view;exportR\x05table\x12`\n" +
"\x04data\x18\a \x01(\tBL\xb2\xb9\x19H\n" +
"\x04data\x18\b \x01(\tBL\xb2\xb9\x19H\n" +
"\x1esize:10240;not null;default:''\x12\x06内容\x1a\x1elist;create;update;view;exportR\x04data:\x10\xba\xb9\x19\f\n" +
"\n" +
"activities\"K\n" +

View File

@ -62,6 +62,8 @@ func (m *Setting) validate(all bool) error {
// no validation rules for UpdatedAt
// no validation rules for Domain
if utf8.RuneCountInString(m.GetName()) > 20 {
err := SettingValidationError{
field: "Name",
@ -209,6 +211,8 @@ func (m *Activity) validate(all bool) error {
// no validation rules for CreatedAt
// no validation rules for Domain
if l := utf8.RuneCountInString(m.GetUid()); l < 5 || l > 20 {
err := ActivityValidationError{
field: "Uid",

View File

@ -18,10 +18,11 @@ message Setting {
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={scenarios:"view;export",comment:"更新时间"}];
string name = 4 [(aeus.field)={gorm:"size:60",rule:"required",props:"readonly:update",comment: "配置项"},(validate.rules).string = {max_len: 20}];
string type = 5 [(aeus.field)={gorm:"size:20",rule:"required",enum:"text:文本;number:数字;json:JSON",comment: "数据类型"},(validate.rules).string = {max_len: 20}];
string value = 6 [(aeus.field)={gorm:"size:1024",rule:"required",format:"textarea",comment: "配置值"},(validate.rules).string = {max_len: 1024}];
string description = 7 [(aeus.field)={gorm:"size:1024",format:"textarea",scenarios:"list;create;update;view;export",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
string domain = 4 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string name = 5 [(aeus.field)={gorm:"size:60",rule:"required",props:"readonly:update",comment: "配置项"},(validate.rules).string = {max_len: 20}];
string type = 6 [(aeus.field)={gorm:"size:20",rule:"required",enum:"text:文本;number:数字;json:JSON",comment: "数据类型"},(validate.rules).string = {max_len: 20}];
string value = 7 [(aeus.field)={gorm:"size:1024",rule:"required",format:"textarea",comment: "配置值"},(validate.rules).string = {max_len: 1024}];
string description = 8 [(aeus.field)={gorm:"size:1024",format:"textarea",scenarios:"list;create;update;view;export",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
}
@ -32,11 +33,12 @@ message Activity {
};
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"search;search;view;export",comment:"创建时间"}];
string uid = 3 [(aeus.field)={gorm:"index;size:20",rule:"required",props:"readonly:update",format:"user",comment: "用户"},(validate.rules).string = {min_len: 5, max_len: 20}];
string action = 4 [(aeus.field)={props:"match:exactly",rule:"required",gorm:"index;size:20;not null;default:''",comment:"行为",enum:"create:新建#198754;update:更新#f09d00;delete:删除#e63757",scenarios:"search;list;create;update;view;export"}];
string module = 5 [(aeus.field)={gorm:"size:60;not null;default:''",comment:"模块",scenarios:"search;list;create;update;view;export"}];
string table = 6 [(aeus.field)={gorm:"size:60;not null;default:''",comment:"模型",scenarios:"list;create;update;view;export"}];
string data = 7 [(aeus.field)={gorm:"size:10240;not null;default:''",comment:"内容",scenarios:"list;create;update;view;export"}];
string domain = 3 [(aeus.field)={gorm:"index;size:60;not null;default:''",comment:"域",scenarios:"export"}];
string uid = 4 [(aeus.field)={gorm:"index;size:20",rule:"required",props:"readonly:update",format:"user",comment: "用户"},(validate.rules).string = {min_len: 5, max_len: 20}];
string action = 5 [(aeus.field)={props:"match:exactly",rule:"required",gorm:"index;size:20;not null;default:''",comment:"行为",enum:"create:新建#198754;update:更新#f09d00;delete:删除#e63757",scenarios:"search;list;create;update;view;export"}];
string module = 6 [(aeus.field)={gorm:"size:60;not null;default:''",comment:"模块",scenarios:"search;list;create;update;view;export"}];
string table = 7 [(aeus.field)={gorm:"size:60;not null;default:''",comment:"模型",scenarios:"list;create;update;view;export"}];
string data = 8 [(aeus.field)={gorm:"size:10240;not null;default:''",comment:"内容",scenarios:"list;create;update;view;export"}];
}

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: system.proto
// date: 2025-07-22 18:30:59
// date: 2025-07-23 17:06:59
package pb

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: system.proto
// date: 2025-07-22 18:30:59
// date: 2025-07-23 17:06:59
package pb
@ -12,6 +12,7 @@ type SettingModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"column:updated_at" comment:"更新时间" scenarios:"view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Name string `json:"name" yaml:"name" xml:"name" gorm:"size:60;column:name" comment:"配置项" props:"readonly:update" rule:"required"`
Type string `json:"type" yaml:"type" xml:"type" gorm:"size:20;column:type" comment:"数据类型" rule:"required" enum:"text:文本;number:数字;json:JSON"`
Value string `json:"value" yaml:"value" xml:"value" gorm:"size:1024;column:value" comment:"配置值" format:"textarea" rule:"required"`
@ -26,6 +27,7 @@ func (m *SettingModel) FromValue(x *Setting) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.UpdatedAt = x.UpdatedAt
m.Domain = x.Domain
m.Name = x.Name
m.Type = x.Type
m.Value = x.Value
@ -37,6 +39,7 @@ func (m *SettingModel) ToValue() (x *Setting) {
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.UpdatedAt = m.UpdatedAt
x.Domain = m.Domain
x.Name = m.Name
x.Type = m.Type
x.Value = m.Value
@ -79,6 +82,7 @@ func NewSettingModel() *SettingModel {
type ActivityModel struct {
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey;column:id" comment:"ID"`
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" gorm:"column:created_at" comment:"创建时间" scenarios:"search;search;view;export"`
Domain string `json:"domain" yaml:"domain" xml:"domain" gorm:"index;size:60;not null;default:'';column:domain" comment:"域" scenarios:"export"`
Uid string `json:"uid" yaml:"uid" xml:"uid" gorm:"index;size:20;column:uid" comment:"用户" format:"user" props:"readonly:update" rule:"required"`
Action string `json:"action" yaml:"action" xml:"action" gorm:"index;size:20;not null;default:'';column:action" comment:"行为" scenarios:"search;list;create;update;view;export" props:"match:exactly" rule:"required" enum:"create:新建#198754;update:更新#f09d00;delete:删除#e63757"`
Module string `json:"module" yaml:"module" xml:"module" gorm:"size:60;not null;default:'';column:module" comment:"模块" scenarios:"search;list;create;update;view;export"`
@ -93,6 +97,7 @@ func (m *ActivityModel) TableName() string {
func (m *ActivityModel) FromValue(x *Activity) {
m.Id = x.Id
m.CreatedAt = x.CreatedAt
m.Domain = x.Domain
m.Uid = x.Uid
m.Action = x.Action
m.Module = x.Module
@ -104,6 +109,7 @@ func (m *ActivityModel) ToValue() (x *Activity) {
x = &Activity{}
x.Id = m.Id
x.CreatedAt = m.CreatedAt
x.Domain = m.Domain
x.Uid = m.Uid
x.Action = m.Action
x.Module = m.Module

View File

@ -196,12 +196,19 @@ func generateVueFile(prefix string, apiPrefix string, mv *rest.Model) (err error
// restValueLookup 特殊字段获取方式
func restValueLookup(column string, w httpkg.ResponseWriter, r *httpkg.Request) string {
switch column {
case "user":
case types.FieldUser:
// 从授权信息里面获取用户的ID
if t, ok := auth.FromContext(r.Context()); ok {
uid, _ := t.GetSubject()
return uid
}
case types.FieldDomain:
// 从授权信息里面获取用户的domain
if t, ok := auth.FromContext(r.Context()); ok {
if v, ok := t.(*adminTypes.Claims); ok {
return v.Domain
}
}
}
return r.Header.Get(column)
}
@ -219,6 +226,9 @@ func initREST(ctx context.Context, o *options) (err error) {
if o.apiPrefix != "" {
opts = append(opts, rest.WithUriPrefix(o.apiPrefix))
}
if o.disableDomain {
opts = append(opts, rest.WithoutDomain())
}
if err = rest.Init(opts...); err != nil {
return
}
@ -260,6 +270,7 @@ func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
schemas []*restTypes.Schema
)
scenario := ctx.Request().URL.Query().Get("scenario")
domainName := restValueLookup(types.FieldDomain, ctx.Response(), ctx.Request())
if scenario == "" {
schemas, err = dbcache.TryCache(
ctx.Request().Context(),
@ -268,7 +279,7 @@ func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
return rest.GetSchemas(
ctx.Request().Context(),
tx,
"",
domainName,
ctx.Param("module"),
ctx.Param("table"),
)
@ -284,7 +295,7 @@ func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
return rest.VisibleSchemas(
ctx.Request().Context(),
db.WithContext(ctx.Request().Context()),
"",
domainName,
ctx.Param("module"),
ctx.Param("table"),
scenario,
@ -372,8 +383,9 @@ func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
} else {
opts = append(opts, dbcache.WithCacheDuration(time.Minute))
}
if pairs, err = dbcache.TryCache(ctx.Context(), fmt.Sprintf("rest:kvpairs:%s:%s:%s:%s", moduleName, tableName, labelColumn, valueColumn), func(tx *gorm.DB) ([]*restTypes.TypeValue[any], error) {
return rest.ModelTypes[any](ctx.Context(), db, modelValue, "", labelColumn, valueColumn)
domainName := restValueLookup(types.FieldDomain, ctx.Response(), ctx.Request())
if pairs, err = dbcache.TryCache(ctx.Context(), fmt.Sprintf("rest:kvpairs:%s:%s:%s:%s:%s", domainName, moduleName, tableName, labelColumn, valueColumn), func(tx *gorm.DB) ([]*restTypes.TypeValue[any], error) {
return rest.ModelTypes[any](ctx.Context(), db, modelValue, domainName, labelColumn, valueColumn)
}, opts...); err == nil {
return ctx.Success(pairs)
} else {
@ -420,8 +432,9 @@ func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
} else {
opts = append(opts, dbcache.WithCacheDuration(time.Minute))
}
if pairs, err = dbcache.TryCache(ctx.Context(), fmt.Sprintf("rest:tierpairs:%s:%s:%s:%s", moduleName, tableName, labelColumn, valueColumn), func(tx *gorm.DB) ([]*restTypes.TierValue[string], error) {
return rest.ModelTiers[string](ctx.Context(), db, modelValue, "", parentColumn, labelColumn, valueColumn)
domainName := restValueLookup(types.FieldDomain, ctx.Response(), ctx.Request())
if pairs, err = dbcache.TryCache(ctx.Context(), fmt.Sprintf("rest:tierpairs:%s:%s:%s:%s:%s", domainName, moduleName, tableName, labelColumn, valueColumn), func(tx *gorm.DB) ([]*restTypes.TierValue[string], error) {
return rest.ModelTiers[string](ctx.Context(), db, modelValue, domainName, parentColumn, labelColumn, valueColumn)
}, opts...); err == nil {
return ctx.Success(pairs)
} else {
@ -468,8 +481,9 @@ func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
} else {
opts = append(opts, dbcache.WithCacheDuration(time.Minute))
}
if pairs, err = dbcache.TryCache(ctx.Context(), fmt.Sprintf("rest:tierpairs:%s:%s:%s:%s", moduleName, tableName, labelColumn, valueColumn), func(tx *gorm.DB) ([]*restTypes.TierValue[int64], error) {
return rest.ModelTiers[int64](ctx.Context(), db, modelValue, "", parentColumn, labelColumn, valueColumn)
domainName := restValueLookup(types.FieldDomain, ctx.Response(), ctx.Request())
if pairs, err = dbcache.TryCache(ctx.Context(), fmt.Sprintf("rest:tierpairs:%s:%s:%s:%s:%s", domainName, moduleName, tableName, labelColumn, valueColumn), func(tx *gorm.DB) ([]*restTypes.TierValue[int64], error) {
return rest.ModelTiers[int64](ctx.Context(), db, modelValue, domainName, parentColumn, labelColumn, valueColumn)
}, opts...); err == nil {
return ctx.Success(pairs)
} else {

View File

@ -28,6 +28,7 @@ type (
turnstileValidateUrl string
turnstileSiteKey string
enableRefreshToken bool
disableDomain bool
}
turnstileRequest struct {
@ -60,6 +61,12 @@ func WithAuthDB(db *gorm.DB) AuthOption {
}
}
func WithoutDomain() AuthOption {
return func(o *authOptions) {
o.disableDomain = true
}
}
func WithAuthCache(cache cache.Cache) AuthOption {
return func(o *authOptions) {
o.cache = cache
@ -159,7 +166,9 @@ func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.
IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(),
}
if !s.opts.disableDomain {
claims.Domain = model.Domain
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
res = &pb.LoginResponse{}
if res.Token, err = token.SignedString(s.opts.secret); err == nil {
@ -167,6 +176,7 @@ func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.
res.Username = model.Username
res.Expires = s.opts.ttl
}
if s.opts.enableRefreshToken {
refreshClaims := types.Claims{
Uid: model.Uid,
@ -175,11 +185,15 @@ func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.
IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Hour * 48).Unix(),
}
if !s.opts.disableDomain {
refreshClaims.Domain = model.Domain
}
refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims)
res.RefreshToken, err = refreshToken.SignedString(s.opts.secret)
}
loginModel := &models.Login{}
loginModel.Uid = model.Uid
loginModel.Domain = model.Domain
loginModel.AccessToken = res.Token
md := metadata.FromContext(ctx)
if s.opts.tokenStore != nil {
@ -225,6 +239,7 @@ func (s *AuthService) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequ
Uid: refreshClaims.Uid,
Role: refreshClaims.Role,
Admin: refreshClaims.Admin,
Domain: refreshClaims.Domain,
IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(),
}

View File

@ -8,6 +8,7 @@ import (
"git.nobla.cn/golang/aeus-admin/internal/logic"
"git.nobla.cn/golang/aeus-admin/models"
"git.nobla.cn/golang/aeus-admin/pb"
"git.nobla.cn/golang/aeus-admin/utils"
"git.nobla.cn/golang/aeus/pkg/cache"
"git.nobla.cn/golang/rest/types"
"gorm.io/gorm"
@ -42,7 +43,8 @@ func WithDepartmentDB(db *gorm.DB) DepartmentOption {
func (s *DepartmentService) GetDepartmentLabels(ctx context.Context, req *pb.GetDepartmentLabelRequest) (res *pb.GetDepartmentLabelResponse, err error) {
res = &pb.GetDepartmentLabelResponse{}
var values []*types.TypeValue[int64]
if values, err = s.logic.GetLabels(ctx); err == nil {
domainName := utils.GetDomainFromContext(ctx)
if values, err = s.logic.GetLabels(ctx, domainName); err == nil {
res.Data = make([]*pb.DepartmentLabelValue, 0, len(values))
for _, row := range values {
res.Data = append(res.Data, &pb.DepartmentLabelValue{
@ -100,10 +102,11 @@ func (s *DepartmentService) GetDepartmentUsers(ctx context.Context, req *pb.GetD
users []*models.User
departments []*models.Department
)
if departments, err = s.logic.GetDepartments(ctx); err != nil {
domainName := utils.GetDomainFromContext(ctx)
if departments, err = s.logic.GetDepartments(ctx, domainName); err != nil {
return
}
if users, err = s.user.GeUsers(ctx); err != nil {
if users, err = s.user.GeUsers(ctx, domainName); err != nil {
return
}
res = &pb.GetDepartmentUserResponse{
@ -116,7 +119,8 @@ func (s *DepartmentService) GetDepartmentLevelLabels(ctx context.Context, req *p
var (
departments []*models.Department
)
if departments, err = s.logic.GetDepartments(ctx); err != nil {
domainName := utils.GetDomainFromContext(ctx)
if departments, err = s.logic.GetDepartments(ctx, domainName); err != nil {
return
}
res = &pb.GetDepartmentLevelLabelsResponse{

View File

@ -6,6 +6,7 @@ import (
"git.nobla.cn/golang/aeus-admin/internal/logic"
"git.nobla.cn/golang/aeus-admin/models"
"git.nobla.cn/golang/aeus-admin/pb"
"git.nobla.cn/golang/aeus-admin/utils"
"git.nobla.cn/golang/aeus/pkg/cache"
"gorm.io/gorm"
)
@ -73,7 +74,8 @@ func (s *MenuService) GetMenus(ctx context.Context, req *pb.GetMenuRequest) (res
var (
items []*models.Menu
)
if items, err = s.logic.GetMenus(ctx); err != nil {
domainName := utils.GetDomainFromContext(ctx)
if items, err = s.logic.GetMenus(ctx, domainName); err != nil {
return
}
res = &pb.GetMenuResponse{
@ -86,7 +88,8 @@ func (s *MenuService) GetMenuLevelLabels(ctx context.Context, req *pb.GetMenuLev
var (
items []*models.Menu
)
if items, err = s.logic.GetMenus(ctx); err != nil {
domainName := utils.GetDomainFromContext(ctx)
if items, err = s.logic.GetMenus(ctx, domainName); err != nil {
return
}
res = &pb.GetMenuLevelLabelsResponse{

View File

@ -6,6 +6,7 @@ import (
"git.nobla.cn/golang/aeus-admin/internal/logic"
"git.nobla.cn/golang/aeus-admin/models"
"git.nobla.cn/golang/aeus-admin/pb"
"git.nobla.cn/golang/aeus-admin/utils"
"git.nobla.cn/golang/aeus/pkg/cache"
"git.nobla.cn/golang/rest/types"
"gorm.io/gorm"
@ -39,7 +40,8 @@ func WithRoleDB(db *gorm.DB) RoleOption {
func (s *RoleService) GetRoleLabels(ctx context.Context, req *pb.GetRoleLabelRequest) (res *pb.GetRoleLabelResponse, err error) {
res = &pb.GetRoleLabelResponse{}
var values []*types.TypeValue[string]
if values, err = s.logic.GetLabels(ctx); err == nil {
domainName := utils.GetDomainFromContext(ctx)
if values, err = s.logic.GetLabels(ctx, domainName); err == nil {
res.Data = make([]*pb.LabelValue, 0, len(values))
for _, row := range values {
res.Data = append(res.Data, &pb.LabelValue{

View File

@ -10,6 +10,7 @@ import (
"git.nobla.cn/golang/aeus-admin/models"
"git.nobla.cn/golang/aeus-admin/pb"
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
"git.nobla.cn/golang/aeus-admin/utils"
"git.nobla.cn/golang/aeus/middleware/auth"
"git.nobla.cn/golang/aeus/pkg/cache"
"git.nobla.cn/golang/aeus/pkg/errors"
@ -105,22 +106,24 @@ func (s *UserService) recursiveNestedMenu(ctx context.Context, parent string, pe
func (s *UserService) GetMenus(ctx context.Context, req *pb.GetUserMenuRequest) (res *pb.GetUserMenuResponse, err error) {
var (
uid string
domainName string
permissions []*models.Permission
)
if uid, err = s.getUidFromContext(ctx); err != nil {
return
}
domainName = utils.GetDomainFromContext(ctx)
res = &pb.GetUserMenuResponse{}
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:menu:%s:%v", uid, req.Permission), func(tx *gorm.DB) ([]*pb.MenuItem, error) {
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:menu:%s:%s:%v", domainName, uid, req.Permission), func(tx *gorm.DB) ([]*pb.MenuItem, error) {
var (
userModel *models.User
menus []*models.Menu
)
userModel = &models.User{}
if err = tx.Where("`uid`=?", uid).First(userModel).Error; err != nil {
if err = tx.Where("`uid`=? AND `domain`=?", uid, domainName).First(userModel).Error; err != nil {
return nil, err
}
if menus, err = s.menu.GetMenus(ctx); err != nil {
if menus, err = s.menu.GetMenus(ctx, domainName); err != nil {
return nil, err
}
roleName := userModel.Role
@ -228,7 +231,8 @@ func (s *UserService) GetPermissions(ctx context.Context, req *pb.GetPermissionR
func (s *UserService) GetUserLabels(ctx context.Context, req *pb.GetUserLabelRequest) (res *pb.GetUserLabelResponse, err error) {
res = &pb.GetUserLabelResponse{}
var values []*types.TypeValue[string]
if values, err = s.user.GetLabels(ctx); err == nil {
domainName := utils.GetDomainFromContext(ctx)
if values, err = s.user.GetLabels(ctx, domainName); err == nil {
res.Data = make([]*pb.LabelValue, 0, len(values))
for _, row := range values {
res.Data = append(res.Data, &pb.LabelValue{
@ -246,11 +250,11 @@ func (s *UserService) DepartmentUserNested(ctx context.Context) []*types.NestedV
users []*models.User
departments []*models.Department
)
if departments, err = s.department.GetDepartments(ctx); err != nil {
domainName := utils.GetDomainFromContext(ctx)
if departments, err = s.department.GetDepartments(ctx, domainName); err != nil {
return nil
}
if users, err = s.user.GeUsers(ctx); err != nil {
if users, err = s.user.GeUsers(ctx, domainName); err != nil {
return nil
}
depts := s.department.RecursiveDepartment(ctx, 0, 0, departments)

View File

@ -34,6 +34,7 @@ type (
disableModels bool
httpServer *http.Server
restOpts []rest.Option
disableDomain bool
}
Option func(*options)
@ -73,6 +74,12 @@ func WithCache(cache cache.Cache) Option {
}
}
func WithoutDomain() Option {
return func(o *options) {
o.disableDomain = true
}
}
func WithoutDefault() Option {
return func(o *options) {
o.disableDefault = true

View File

@ -13,6 +13,7 @@ type Claims struct {
Issuer string `json:"iss"`
IssuedAt int64 `json:"iat"`
ExpirationAt int64 `json:"exp"`
Domain string `json:"dom,omitempty"`
Audience []string `json:"aud,omitempty"`
}

17
utils/domain.go 100644
View File

@ -0,0 +1,17 @@
package utils
import (
"context"
"git.nobla.cn/golang/aeus-admin/types"
"git.nobla.cn/golang/aeus/middleware/auth"
)
func GetDomainFromContext(ctx context.Context) string {
if claims, ok := auth.FromContext(ctx); ok {
if v, ok := claims.(*types.Claims); ok {
return v.Domain
}
}
return ""
}