Compare commits

...

18 Commits
v0.0.8 ... main

Author SHA1 Message Date
fcl 1056b4d222 update rest version 2025-08-01 18:33:07 +08:00
fcl 5d678e122a 添加多级组件定义 2025-07-30 13:51:51 +08:00
Yavolte 30a4143507 Merge branch 'main' of git.dialme.cn:golang/aeus-admin 2025-07-24 17:51:42 +08:00
Yavolte 300f600d66 添加文档说明 2025-07-24 17:51:09 +08:00
fcl 29fa44cb31 修复多域的处理 2025-07-23 18:46:14 +08:00
Yavolte 822603d14e 优化proto 2025-07-23 17:38:06 +08:00
Yavolte caf2ede72d update proto 2025-07-23 17:36:53 +08:00
Yavolte 016ae8a014 优化多租户的方案 2025-07-23 17:11:52 +08:00
Yavolte 9bbda7bfe3 优化多租户支持 2025-07-23 17:07:51 +08:00
Yavolte 556f7abf25 修复组件名称BUG 2025-07-23 15:32:57 +08:00
fcl 1214d3c6d4 fix refresh token not work 2025-07-23 11:23:27 +08:00
Yavolte 0de20d5ddf 添加支持refreshtoken的实现 2025-07-23 09:35:46 +08:00
Yavolte 13010ec1a4 实现刷新token机制 2025-07-22 19:05:57 +08:00
Yavolte d3e3a66eca add refresh token api 2025-07-22 18:44:30 +08:00
fcl ad43d206e1 update setting files 2025-07-22 18:28:40 +08:00
Yavolte aea76b919d 优化数据 2025-07-22 17:00:43 +08:00
Yavolte 74446b2e3f update pb files 2025-07-22 16:58:03 +08:00
fcl fde965bbd1 update system proto 2025-07-22 16:57:09 +08:00
32 changed files with 1124 additions and 239 deletions

View File

@ -1,2 +1,67 @@
# 权限配置
# 命名规则
## 模块命名
模块命名的话需要使用单个单词,不包含下划线,不用说驼峰命令
## 组件名称
1. 顶层组件
组件名称应该和模块名称和菜单层级保持一致, 比如`system`模块, 那么最顶级的组件名称应该为`System`
2. 子组件
子组件应该在父组件基础上加上自己的名称, 比如`System`模块下有一个`User`组件, 那么组件名称应该为`SystemUser`, 同时菜单也需要配置父组件为`System`
如果组件下面没有孙子组件, 那么视图为:
```
views/system/user/Index.vue
```
3. 孙子组件
孙子组件应该在父组件的基础上加上自己的名称, 比如`System`模块下有一个`User`组件, 那么组件名称应该为`SystemUser`, 同时自己的名称为`Login`, 那么组件名称应该为`SystemUserLogin`, 菜单的父组件为`SystemUser`, 生成对应的视图文件路径为:
```
views/system/user/login/Index.vue
```
# 子模块处理
处理子表的情况, 比如有一个菜单表和权限表, 权限隶属于菜单表下面, 那么在试图页面处理权限的的时候可以如下处理:
1. 菜单配置
这里需要手动指定下路由地址, 另外配置菜单为隐藏的菜单
``` go
func (m *AclRule) GetMenu() *types.Menu {
return &types.Menu{
Name: "SettingAclRule",
Parent: "Setting",
Label: "ACL规则",
Hidden: true,
Uri: "/setting/acl/rule/:acl",
}
}
```
2. 界面配置
需要配置组件`Viewer`的`knownColumns`属性, 表示这个是已知的字段值, 表现为不会再界面显示, 添加和更新的时候自动赋值, 查询的时候自动赋值
```vue
<viewer :known-columns="knownColumns"></viewer>
```
```js
onMounted(() => {
knownColumns.value['name'] = route.params['acl']
})
```

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

View File

@ -5,6 +5,7 @@ import (
"fmt"
"git.nobla.cn/golang/aeus-admin/internal/logic"
"git.nobla.cn/golang/aeus-admin/utils"
"git.nobla.cn/golang/aeus/pkg/cache"
"git.nobla.cn/golang/rest"
"git.nobla.cn/golang/rest/types"
@ -20,7 +21,7 @@ type Formatter struct {
}
func (f *Formatter) FormatUser(ctx context.Context, value, model any, scm *types.Schema) any {
if values, err := f.user.GetLabels(ctx); err == nil {
if values, err := f.user.GetLabels(ctx, utils.GetDomainFromContext(ctx)); err == nil {
for _, row := range values {
if row.Value == value {
return fmt.Sprintf("%s(%s)", row.Label, row.Value)
@ -31,7 +32,7 @@ func (f *Formatter) FormatUser(ctx context.Context, value, model any, scm *types
}
func (f *Formatter) FormatDepartment(ctx context.Context, value, model any, scm *types.Schema) any {
if values, err := f.department.GetLabels(ctx); err == nil {
if values, err := f.department.GetLabels(ctx, utils.GetDomainFromContext(ctx)); err == nil {
for _, row := range values {
if row.Value == value {
return row.Label
@ -42,7 +43,7 @@ func (f *Formatter) FormatDepartment(ctx context.Context, value, model any, scm
}
func (f *Formatter) FormatRole(ctx context.Context, value, model any, scm *types.Schema) any {
if values, err := f.role.GetLabels(ctx); err == nil {
if values, err := f.role.GetLabels(ctx, utils.GetDomainFromContext(ctx)); err == nil {
for _, row := range values {
if row.Value == value {
return row.Label

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.9
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.9 h1:oI57jWoaJ98rRQyjH5EPoe7TYGs4MzLZ2zVRfUB0sS4=
git.nobla.cn/golang/rest v0.1.9/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
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

@ -2,7 +2,6 @@ package logic
import (
"context"
"fmt"
"git.nobla.cn/golang/aeus-admin/models"
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
@ -31,7 +30,7 @@ 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 dbcache.TryCache(ctx, "menu:labels", func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
return rest.ModelTypes[string](ctx, tx, &models.Menu{}, "", "label", "name")
},
dbcache.WithDB(u.db),

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
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

@ -11,7 +11,7 @@ import (
func Menu(db *gorm.DB, datas ...*models.Menu) (err error) {
tx := db.Begin()
for _, model := range datas {
if err = tx.Where("name = ?", model.Name).First(model).Error; err != nil {
if err = tx.Where("`name` = ?", model.Name).First(model).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
if err = tx.Create(model).Error; err != nil {
tx.Rollback()
@ -39,7 +39,7 @@ func Permission(db *gorm.DB, menuName string, permission string, label string) (
}
// Default 合并初始化数据集
func Default(db *gorm.DB) (err error) {
func Default(db *gorm.DB, domain string) (err error) {
var (
n int64
)
@ -49,6 +49,9 @@ func Default(db *gorm.DB) (err error) {
}
}
if db.Model(&models.Role{}).Count(&n); n == 0 {
for i := range defaultRoles {
defaultRoles[i].Domain = domain
}
db.Create(defaultRoles)
permissions := make([]*models.Permission, 0)
db.Find(&permissions)
@ -65,9 +68,15 @@ func Default(db *gorm.DB) (err error) {
}
if db.Model(&models.Department{}).Count(&n); n == 0 {
for i := range defaultDepartments {
defaultDepartments[i].Domain = domain
}
db.Create(defaultDepartments)
}
if db.Model(&models.User{}).Count(&n); n == 0 {
for i := range defaultUsers {
defaultUsers[i].Domain = domain
}
db.Create(defaultUsers)
}
return

View File

@ -172,9 +172,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 +231,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
@ -403,18 +411,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 +479,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 +576,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 +635,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 +667,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 +723,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
@ -2722,6 +2754,7 @@ type LoginResponse struct {
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"`
Expires int64 `protobuf:"varint,4,opt,name=expires,proto3" json:"expires,omitempty"`
RefreshToken string `protobuf:"bytes,5,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -2784,6 +2817,133 @@ func (x *LoginResponse) GetExpires() int64 {
return 0
}
func (x *LoginResponse) GetRefreshToken() string {
if x != nil {
return x.RefreshToken
}
return ""
}
type RefreshTokenRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
RefreshToken string `protobuf:"bytes,1,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RefreshTokenRequest) Reset() {
*x = RefreshTokenRequest{}
mi := &file_organize_proto_msgTypes[47]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RefreshTokenRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RefreshTokenRequest) ProtoMessage() {}
func (x *RefreshTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_organize_proto_msgTypes[47]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RefreshTokenRequest.ProtoReflect.Descriptor instead.
func (*RefreshTokenRequest) Descriptor() ([]byte, []int) {
return file_organize_proto_rawDescGZIP(), []int{47}
}
func (x *RefreshTokenRequest) GetRefreshToken() string {
if x != nil {
return x.RefreshToken
}
return ""
}
type RefreshTokenResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"`
Expires int64 `protobuf:"varint,4,opt,name=expires,proto3" json:"expires,omitempty"`
RefreshToken string `protobuf:"bytes,5,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RefreshTokenResponse) Reset() {
*x = RefreshTokenResponse{}
mi := &file_organize_proto_msgTypes[48]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RefreshTokenResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RefreshTokenResponse) ProtoMessage() {}
func (x *RefreshTokenResponse) ProtoReflect() protoreflect.Message {
mi := &file_organize_proto_msgTypes[48]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RefreshTokenResponse.ProtoReflect.Descriptor instead.
func (*RefreshTokenResponse) Descriptor() ([]byte, []int) {
return file_organize_proto_rawDescGZIP(), []int{48}
}
func (x *RefreshTokenResponse) GetUid() string {
if x != nil {
return x.Uid
}
return ""
}
func (x *RefreshTokenResponse) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *RefreshTokenResponse) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *RefreshTokenResponse) GetExpires() int64 {
if x != nil {
return x.Expires
}
return 0
}
func (x *RefreshTokenResponse) GetRefreshToken() string {
if x != nil {
return x.RefreshToken
}
return ""
}
type LogoutRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
@ -2793,7 +2953,7 @@ type LogoutRequest struct {
func (x *LogoutRequest) Reset() {
*x = LogoutRequest{}
mi := &file_organize_proto_msgTypes[47]
mi := &file_organize_proto_msgTypes[49]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2805,7 +2965,7 @@ func (x *LogoutRequest) String() string {
func (*LogoutRequest) ProtoMessage() {}
func (x *LogoutRequest) ProtoReflect() protoreflect.Message {
mi := &file_organize_proto_msgTypes[47]
mi := &file_organize_proto_msgTypes[49]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2818,7 +2978,7 @@ func (x *LogoutRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead.
func (*LogoutRequest) Descriptor() ([]byte, []int) {
return file_organize_proto_rawDescGZIP(), []int{47}
return file_organize_proto_rawDescGZIP(), []int{49}
}
func (x *LogoutRequest) GetToken() string {
@ -2837,7 +2997,7 @@ type LogoutResponse struct {
func (x *LogoutResponse) Reset() {
*x = LogoutResponse{}
mi := &file_organize_proto_msgTypes[48]
mi := &file_organize_proto_msgTypes[50]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2849,7 +3009,7 @@ func (x *LogoutResponse) String() string {
func (*LogoutResponse) ProtoMessage() {}
func (x *LogoutResponse) ProtoReflect() protoreflect.Message {
mi := &file_organize_proto_msgTypes[48]
mi := &file_organize_proto_msgTypes[50]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2862,7 +3022,7 @@ func (x *LogoutResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead.
func (*LogoutResponse) Descriptor() ([]byte, []int) {
return file_organize_proto_rawDescGZIP(), []int{48}
return file_organize_proto_rawDescGZIP(), []int{50}
}
func (x *LogoutResponse) GetUid() string {
@ -2904,7 +3064,7 @@ const file_organize_proto_rawDesc = "" +
"\vdescription\x18\f \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" +
"\x05menus\"\x9f\x04\n" +
"\x04Role\x12*\n" +
"\x02id\x18\x01 \x01(\x03B\x1a\xb2\xb9\x19\x16\n" +
"\n" +
@ -2913,12 +3073,14 @@ 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" +
"\n" +
@ -2950,7 +3112,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" +
@ -2959,33 +3121,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" +
@ -2995,35 +3159,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" +
@ -3137,12 +3305,21 @@ const file_organize_proto_rawDesc = "" +
"\fLoginRequest\x12\x1a\n" +
"\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" +
"\bpassword\x18\x02 \x01(\tR\bpassword\x12\x14\n" +
"\x05token\x18\x03 \x01(\tR\x05token\"m\n" +
"\x05token\x18\x03 \x01(\tR\x05token\"\x92\x01\n" +
"\rLoginResponse\x12\x10\n" +
"\x03uid\x18\x01 \x01(\tR\x03uid\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12\x14\n" +
"\x05token\x18\x03 \x01(\tR\x05token\x12\x18\n" +
"\aexpires\x18\x04 \x01(\x03R\aexpires\"%\n" +
"\aexpires\x18\x04 \x01(\x03R\aexpires\x12#\n" +
"\rrefresh_token\x18\x05 \x01(\tR\frefreshToken\":\n" +
"\x13RefreshTokenRequest\x12#\n" +
"\rrefresh_token\x18\x01 \x01(\tR\frefreshToken\"\x99\x01\n" +
"\x14RefreshTokenResponse\x12\x10\n" +
"\x03uid\x18\x01 \x01(\tR\x03uid\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12\x14\n" +
"\x05token\x18\x03 \x01(\tR\x05token\x12\x18\n" +
"\aexpires\x18\x04 \x01(\x03R\aexpires\x12#\n" +
"\rrefresh_token\x18\x05 \x01(\tR\frefreshToken\"%\n" +
"\rLogoutRequest\x12\x14\n" +
"\x05token\x18\x01 \x01(\tR\x05token\"\"\n" +
"\x0eLogoutResponse\x12\x10\n" +
@ -3168,10 +3345,11 @@ const file_organize_proto_rawDesc = "" +
"\vMenuService\x12S\n" +
"\bGetMenus\x12\x18.organize.GetMenuRequest\x1a\x19.organize.GetMenuResponse\"\x12\x82\xd3\xe4\x93\x02\f\x12\n" +
"/menu/list\x12{\n" +
"\x12GetMenuLevelLabels\x12#.organize.GetMenuLevelLabelsRequest\x1a$.organize.GetMenuLevelLabelsResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\x12\x12/menu/level-labels2\xbd\x01\n" +
"\x12GetMenuLevelLabels\x12#.organize.GetMenuLevelLabelsRequest\x1a$.organize.GetMenuLevelLabelsResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\x12\x12/menu/level-labels2\xb0\x02\n" +
"\vAuthService\x12T\n" +
"\x05Login\x12\x16.organize.LoginRequest\x1a\x17.organize.LoginResponse\"\x1a\x82\xd3\xe4\x93\x02\x14:\x01*\"\x0f/passport/login\x12X\n" +
"\x06Logout\x12\x17.organize.LogoutRequest\x1a\x18.organize.LogoutResponse\"\x1b\x82\xd3\xe4\x93\x02\x15:\x01*\"\x10/passport/logoutB&Z$git.nobla.cn/golang/aeis-admin/pb;pbb\x06proto3"
"\x06Logout\x12\x17.organize.LogoutRequest\x1a\x18.organize.LogoutResponse\"\x1b\x82\xd3\xe4\x93\x02\x15:\x01*\"\x10/passport/logout\x12q\n" +
"\fRefreshToken\x12\x1d.organize.RefreshTokenRequest\x1a\x1e.organize.RefreshTokenResponse\"\"\x82\xd3\xe4\x93\x02\x1c:\x01*\"\x17/passport/refresh-tokenB&Z$git.nobla.cn/golang/aeis-admin/pb;pbb\x06proto3"
var (
file_organize_proto_rawDescOnce sync.Once
@ -3185,7 +3363,7 @@ func file_organize_proto_rawDescGZIP() []byte {
return file_organize_proto_rawDescData
}
var file_organize_proto_msgTypes = make([]protoimpl.MessageInfo, 49)
var file_organize_proto_msgTypes = make([]protoimpl.MessageInfo, 51)
var file_organize_proto_goTypes = []any{
(*Menu)(nil), // 0: organize.Menu
(*Role)(nil), // 1: organize.Role
@ -3234,8 +3412,10 @@ var file_organize_proto_goTypes = []any{
(*GetMenuResponse)(nil), // 44: organize.GetMenuResponse
(*LoginRequest)(nil), // 45: organize.LoginRequest
(*LoginResponse)(nil), // 46: organize.LoginResponse
(*LogoutRequest)(nil), // 47: organize.LogoutRequest
(*LogoutResponse)(nil), // 48: organize.LogoutResponse
(*RefreshTokenRequest)(nil), // 47: organize.RefreshTokenRequest
(*RefreshTokenResponse)(nil), // 48: organize.RefreshTokenResponse
(*LogoutRequest)(nil), // 49: organize.LogoutRequest
(*LogoutResponse)(nil), // 50: organize.LogoutResponse
}
var file_organize_proto_depIdxs = []int32{
8, // 0: organize.MenuItem.permissions:type_name -> organize.PermissionItem
@ -3269,26 +3449,28 @@ var file_organize_proto_depIdxs = []int32{
43, // 28: organize.MenuService.GetMenus:input_type -> organize.GetMenuRequest
40, // 29: organize.MenuService.GetMenuLevelLabels:input_type -> organize.GetMenuLevelLabelsRequest
45, // 30: organize.AuthService.Login:input_type -> organize.LoginRequest
47, // 31: organize.AuthService.Logout:input_type -> organize.LogoutRequest
11, // 32: organize.UserService.GetMenus:output_type -> organize.GetUserMenuResponse
13, // 33: organize.UserService.GetProfile:output_type -> organize.GetProfileResponse
17, // 34: organize.UserService.UpdateProfile:output_type -> organize.UpdateProfileResponse
15, // 35: organize.UserService.ResetPassword:output_type -> organize.ResetPasswordResponse
19, // 36: organize.UserService.GetPermissions:output_type -> organize.GetPermissionResponse
21, // 37: organize.UserService.GetUserLabels:output_type -> organize.GetUserLabelResponse
23, // 38: organize.UserService.GetUserTags:output_type -> organize.GetUserTagResponse
27, // 39: organize.DepartmentService.GetDepartmentLabels:output_type -> organize.GetDepartmentLabelResponse
29, // 40: organize.DepartmentService.GetDepartmentUsers:output_type -> organize.GetDepartmentUserResponse
32, // 41: organize.DepartmentService.GetDepartmentLevelLabels:output_type -> organize.GetDepartmentLevelLabelsResponse
34, // 42: organize.RoleService.GetRoleLabels:output_type -> organize.GetRoleLabelResponse
36, // 43: organize.RoleService.GetRolePermissions:output_type -> organize.GetRolePermissionResponse
38, // 44: organize.RoleService.SaveRolePermission:output_type -> organize.SaveRolePermissionResponse
44, // 45: organize.MenuService.GetMenus:output_type -> organize.GetMenuResponse
41, // 46: organize.MenuService.GetMenuLevelLabels:output_type -> organize.GetMenuLevelLabelsResponse
46, // 47: organize.AuthService.Login:output_type -> organize.LoginResponse
48, // 48: organize.AuthService.Logout:output_type -> organize.LogoutResponse
32, // [32:49] is the sub-list for method output_type
15, // [15:32] is the sub-list for method input_type
49, // 31: organize.AuthService.Logout:input_type -> organize.LogoutRequest
47, // 32: organize.AuthService.RefreshToken:input_type -> organize.RefreshTokenRequest
11, // 33: organize.UserService.GetMenus:output_type -> organize.GetUserMenuResponse
13, // 34: organize.UserService.GetProfile:output_type -> organize.GetProfileResponse
17, // 35: organize.UserService.UpdateProfile:output_type -> organize.UpdateProfileResponse
15, // 36: organize.UserService.ResetPassword:output_type -> organize.ResetPasswordResponse
19, // 37: organize.UserService.GetPermissions:output_type -> organize.GetPermissionResponse
21, // 38: organize.UserService.GetUserLabels:output_type -> organize.GetUserLabelResponse
23, // 39: organize.UserService.GetUserTags:output_type -> organize.GetUserTagResponse
27, // 40: organize.DepartmentService.GetDepartmentLabels:output_type -> organize.GetDepartmentLabelResponse
29, // 41: organize.DepartmentService.GetDepartmentUsers:output_type -> organize.GetDepartmentUserResponse
32, // 42: organize.DepartmentService.GetDepartmentLevelLabels:output_type -> organize.GetDepartmentLevelLabelsResponse
34, // 43: organize.RoleService.GetRoleLabels:output_type -> organize.GetRoleLabelResponse
36, // 44: organize.RoleService.GetRolePermissions:output_type -> organize.GetRolePermissionResponse
38, // 45: organize.RoleService.SaveRolePermission:output_type -> organize.SaveRolePermissionResponse
44, // 46: organize.MenuService.GetMenus:output_type -> organize.GetMenuResponse
41, // 47: organize.MenuService.GetMenuLevelLabels:output_type -> organize.GetMenuLevelLabelsResponse
46, // 48: organize.AuthService.Login:output_type -> organize.LoginResponse
50, // 49: organize.AuthService.Logout:output_type -> organize.LogoutResponse
48, // 50: organize.AuthService.RefreshToken:output_type -> organize.RefreshTokenResponse
33, // [33:51] is the sub-list for method output_type
15, // [15:33] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
@ -3305,7 +3487,7 @@ func file_organize_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_organize_proto_rawDesc), len(file_organize_proto_rawDesc)),
NumEnums: 0,
NumMessages: 49,
NumMessages: 51,
NumExtensions: 0,
NumServices: 5,
},

View File

@ -240,6 +240,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",
@ -621,6 +623,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 +835,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 +963,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",
@ -5663,6 +5671,8 @@ func (m *LoginResponse) validate(all bool) error {
// no validation rules for Expires
// no validation rules for RefreshToken
if len(errors) > 0 {
return LoginResponseMultiError(errors)
}
@ -5741,6 +5751,222 @@ var _ interface {
ErrorName() string
} = LoginResponseValidationError{}
// Validate checks the field values on RefreshTokenRequest with the rules
// defined in the proto definition for this message. If any rules are
// violated, the first error encountered is returned, or nil if there are no violations.
func (m *RefreshTokenRequest) Validate() error {
return m.validate(false)
}
// ValidateAll checks the field values on RefreshTokenRequest with the rules
// defined in the proto definition for this message. If any rules are
// violated, the result is a list of violation errors wrapped in
// RefreshTokenRequestMultiError, or nil if none found.
func (m *RefreshTokenRequest) ValidateAll() error {
return m.validate(true)
}
func (m *RefreshTokenRequest) validate(all bool) error {
if m == nil {
return nil
}
var errors []error
// no validation rules for RefreshToken
if len(errors) > 0 {
return RefreshTokenRequestMultiError(errors)
}
return nil
}
// RefreshTokenRequestMultiError is an error wrapping multiple validation
// errors returned by RefreshTokenRequest.ValidateAll() if the designated
// constraints aren't met.
type RefreshTokenRequestMultiError []error
// Error returns a concatenation of all the error messages it wraps.
func (m RefreshTokenRequestMultiError) Error() string {
msgs := make([]string, 0, len(m))
for _, err := range m {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "; ")
}
// AllErrors returns a list of validation violation errors.
func (m RefreshTokenRequestMultiError) AllErrors() []error { return m }
// RefreshTokenRequestValidationError is the validation error returned by
// RefreshTokenRequest.Validate if the designated constraints aren't met.
type RefreshTokenRequestValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e RefreshTokenRequestValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e RefreshTokenRequestValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e RefreshTokenRequestValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e RefreshTokenRequestValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e RefreshTokenRequestValidationError) ErrorName() string {
return "RefreshTokenRequestValidationError"
}
// Error satisfies the builtin error interface
func (e RefreshTokenRequestValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sRefreshTokenRequest.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = RefreshTokenRequestValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = RefreshTokenRequestValidationError{}
// Validate checks the field values on RefreshTokenResponse with the rules
// defined in the proto definition for this message. If any rules are
// violated, the first error encountered is returned, or nil if there are no violations.
func (m *RefreshTokenResponse) Validate() error {
return m.validate(false)
}
// ValidateAll checks the field values on RefreshTokenResponse with the rules
// defined in the proto definition for this message. If any rules are
// violated, the result is a list of violation errors wrapped in
// RefreshTokenResponseMultiError, or nil if none found.
func (m *RefreshTokenResponse) ValidateAll() error {
return m.validate(true)
}
func (m *RefreshTokenResponse) validate(all bool) error {
if m == nil {
return nil
}
var errors []error
// no validation rules for Uid
// no validation rules for Username
// no validation rules for Token
// no validation rules for Expires
// no validation rules for RefreshToken
if len(errors) > 0 {
return RefreshTokenResponseMultiError(errors)
}
return nil
}
// RefreshTokenResponseMultiError is an error wrapping multiple validation
// errors returned by RefreshTokenResponse.ValidateAll() if the designated
// constraints aren't met.
type RefreshTokenResponseMultiError []error
// Error returns a concatenation of all the error messages it wraps.
func (m RefreshTokenResponseMultiError) Error() string {
msgs := make([]string, 0, len(m))
for _, err := range m {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "; ")
}
// AllErrors returns a list of validation violation errors.
func (m RefreshTokenResponseMultiError) AllErrors() []error { return m }
// RefreshTokenResponseValidationError is the validation error returned by
// RefreshTokenResponse.Validate if the designated constraints aren't met.
type RefreshTokenResponseValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e RefreshTokenResponseValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e RefreshTokenResponseValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e RefreshTokenResponseValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e RefreshTokenResponseValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e RefreshTokenResponseValidationError) ErrorName() string {
return "RefreshTokenResponseValidationError"
}
// Error satisfies the builtin error interface
func (e RefreshTokenResponseValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sRefreshTokenResponse.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = RefreshTokenResponseValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = RefreshTokenResponseValidationError{}
// Validate checks the field values on LogoutRequest with the rules defined in
// the proto definition for this message. If any rules are violated, the first
// error encountered is returned, or nil if there are no violations.

View File

@ -37,9 +37,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
@ -73,18 +74,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 +97,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 +109,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 {
@ -418,6 +422,19 @@ message LoginResponse {
string username = 2;
string token = 3;
int64 expires = 4;
string refresh_token = 5;
}
message RefreshTokenRequest {
string refresh_token = 1;
}
message RefreshTokenResponse {
string uid = 1;
string username = 2;
string token = 3;
int64 expires = 4;
string refresh_token = 5;
}
message LogoutRequest {
@ -442,4 +459,10 @@ service AuthService {
body: "*"
};
}
rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse) {
option (google.api.http) = {
post: "/passport/refresh-token"
body: "*"
};
}
}

View File

@ -871,6 +871,7 @@ var MenuService_ServiceDesc = grpc.ServiceDesc{
const (
AuthService_Login_FullMethodName = "/organize.AuthService/Login"
AuthService_Logout_FullMethodName = "/organize.AuthService/Logout"
AuthService_RefreshToken_FullMethodName = "/organize.AuthService/RefreshToken"
)
// AuthServiceClient is the client API for AuthService service.
@ -881,6 +882,7 @@ const (
type AuthServiceClient interface {
Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error)
Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error)
RefreshToken(ctx context.Context, in *RefreshTokenRequest, opts ...grpc.CallOption) (*RefreshTokenResponse, error)
}
type authServiceClient struct {
@ -911,6 +913,16 @@ func (c *authServiceClient) Logout(ctx context.Context, in *LogoutRequest, opts
return out, nil
}
func (c *authServiceClient) RefreshToken(ctx context.Context, in *RefreshTokenRequest, opts ...grpc.CallOption) (*RefreshTokenResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RefreshTokenResponse)
err := c.cc.Invoke(ctx, AuthService_RefreshToken_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthServiceServer is the server API for AuthService service.
// All implementations must embed UnimplementedAuthServiceServer
// for forward compatibility.
@ -919,6 +931,7 @@ func (c *authServiceClient) Logout(ctx context.Context, in *LogoutRequest, opts
type AuthServiceServer interface {
Login(context.Context, *LoginRequest) (*LoginResponse, error)
Logout(context.Context, *LogoutRequest) (*LogoutResponse, error)
RefreshToken(context.Context, *RefreshTokenRequest) (*RefreshTokenResponse, error)
mustEmbedUnimplementedAuthServiceServer()
}
@ -935,6 +948,9 @@ func (UnimplementedAuthServiceServer) Login(context.Context, *LoginRequest) (*Lo
func (UnimplementedAuthServiceServer) Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Logout not implemented")
}
func (UnimplementedAuthServiceServer) RefreshToken(context.Context, *RefreshTokenRequest) (*RefreshTokenResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RefreshToken not implemented")
}
func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {}
func (UnimplementedAuthServiceServer) testEmbeddedByValue() {}
@ -992,6 +1008,24 @@ func _AuthService_Logout_Handler(srv interface{}, ctx context.Context, dec func(
return interceptor(ctx, in, info, handler)
}
func _AuthService_RefreshToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RefreshTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).RefreshToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AuthService_RefreshToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).RefreshToken(ctx, req.(*RefreshTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -1007,6 +1041,10 @@ var AuthService_ServiceDesc = grpc.ServiceDesc{
MethodName: "Logout",
Handler: _AuthService_Logout_Handler,
},
{
MethodName: "RefreshToken",
Handler: _AuthService_RefreshToken_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "organize.proto",

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: organize.proto
// date: 2025-06-22 11:09:05
// date: 2025-07-23 17:37:42
package pb
@ -65,6 +65,8 @@ type AuthServiceHttpServer interface {
Login(ctx context.Context, req *LoginRequest) (res *LoginResponse, err error)
Logout(ctx context.Context, req *LogoutRequest) (res *LogoutResponse, err error)
RefreshToken(ctx context.Context, req *RefreshTokenRequest) (res *RefreshTokenResponse, err error)
}
// 获取用户菜单
@ -367,6 +369,24 @@ func handleAuthServiceLogout(s AuthServiceHttpServer) http.HandleFunc {
}
}
func handleAuthServiceRefreshToken(s AuthServiceHttpServer) http.HandleFunc {
return func(ctx *http.Context) (err error) {
req := &RefreshTokenRequest{}
if err := ctx.Bind(req); err != nil {
return ctx.Error(errors.Invalid, err.Error())
}
if res, err := s.RefreshToken(ctx.Context(), req); err != nil {
if er, ok := err.(*errors.Error); ok {
return ctx.Error(er.Code, er.Message)
} else {
return ctx.Error(errors.Unavailable, err.Error())
}
} else {
return ctx.Success(res)
}
}
}
func RegisterUserServiceRouter(hs *http.Server, s UserServiceHttpServer) {
// Register handle GetMenus route
@ -436,4 +456,7 @@ func RegisterAuthServiceRouter(hs *http.Server, s AuthServiceHttpServer) {
// Register handle Logout route
hs.POST("/passport/logout", handleAuthServiceLogout(s))
// Register handle RefreshToken route
hs.POST("/passport/refresh-token", handleAuthServiceRefreshToken(s))
}

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: organize.proto
// date: 2025-06-22 11:09:05
// date: 2025-07-23 17:37:42
package pb
@ -98,6 +98,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 +112,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 +123,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
@ -284,6 +287,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 +310,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 +330,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 +382,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 +396,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 +407,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 +449,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 +466,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 +480,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,9 +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"`
Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,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"`
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
}
@ -89,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
@ -96,6 +105,13 @@ func (x *Setting) GetName() string {
return ""
}
func (x *Setting) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Setting) GetValue() string {
if x != nil {
return x.Value
@ -115,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
}
@ -168,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
@ -206,7 +230,8 @@ func (x *Activity) GetData() string {
type SettingItem struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -248,6 +273,13 @@ func (x *SettingItem) GetName() string {
return ""
}
func (x *SettingItem) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *SettingItem) GetValue() string {
if x != nil {
return x.Value
@ -339,44 +371,51 @@ 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\"\xd8\x03\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" +
"primaryKey\x12\x02IDR\x02id\x12E\n" +
"primaryKey\x12\x02IDR\x02id\x12>\n" +
"\n" +
"created_at\x18\x02 \x01(\x03B&\xb2\xb9\x19\"\x12\f创建时间\x1a\x12search;view;exportR\tcreatedAt\x12E\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&\xb2\xb9\x19\"\x12\f更新时间\x1a\x12search;view;exportR\tupdatedAt\x12N\n" +
"\x04name\x18\x04 \x01(\tB:\xfaB\x04r\x02\x18\x14\xb2\xb9\x19/\n" +
"\asize:60\x12\t配置项2\x0freadonly:update:\brequiredR\x04name\x12K\n" +
"\x05value\x18\x05 \x01(\tB5\xfaB\x05r\x03\x18\x80\x04\xb2\xb9\x19)\n" +
"\bsize:512\x12\t配置值*\btextarea:\brequiredR\x05value\x12l\n" +
"\vdescription\x18\x06 \x01(\tBJ\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19>\n" +
"\tsize:1024\x12\f备注说明\x1a\x19create;update;view;export*\btextareaR\vdescription:\x0e\xba\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\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\a \x01(\tB6\xfaB\x05r\x03\x18\x80\b\xb2\xb9\x19*\n" +
"\tsize:1024\x12\t配置值*\btextarea:\brequiredR\x05value\x12q\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\"7\n" +
"activities\"K\n" +
"\vSettingItem\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" +
"\x05value\x18\x02 \x01(\tR\x05value\"\x13\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" +
"\x04type\x18\x02 \x01(\tR\x04type\x12\x14\n" +
"\x05value\x18\x03 \x01(\tR\x05value\"\x13\n" +
"\x11GetSettingRequest\"=\n" +
"\x12GetSettingResponse\x12'\n" +
"\x04data\x18\x01 \x03(\v2\x13.system.SettingItemR\x04data2n\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",
@ -73,10 +75,21 @@ func (m *Setting) validate(all bool) error {
errors = append(errors, err)
}
if utf8.RuneCountInString(m.GetValue()) > 512 {
if utf8.RuneCountInString(m.GetType()) > 20 {
err := SettingValidationError{
field: "Type",
reason: "value length must be at most 20 runes",
}
if !all {
return err
}
errors = append(errors, err)
}
if utf8.RuneCountInString(m.GetValue()) > 1024 {
err := SettingValidationError{
field: "Value",
reason: "value length must be at most 512 runes",
reason: "value length must be at most 1024 runes",
}
if !all {
return err
@ -198,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",
@ -318,6 +333,8 @@ func (m *SettingItem) validate(all bool) error {
// no validation rules for Name
// no validation rules for Type
// no validation rules for Value
if len(errors) > 0 {

View File

@ -16,11 +16,13 @@ message Setting {
table: "settings"
};
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
int64 created_at = 2 [(aeus.field)={scenarios:"search;view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={scenarios:"search;view;export",comment:"更新时间"}];
string name = 4 [(aeus.field)={gorm:"size:60",rule:"required",props:"readonly:update",comment: "配置项"},(validate.rules).string = {max_len: 20}];
string value = 5 [(aeus.field)={gorm:"size:512",rule:"required",format:"textarea",comment: "配置值"},(validate.rules).string = {max_len: 512}];
string description = 6 [(aeus.field)={gorm:"size:1024",format:"textarea",scenarios:"create;update;view;export",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
int64 updated_at = 3 [(aeus.field)={scenarios:"view;export",comment:"更新时间"}];
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}];
}
@ -31,17 +33,19 @@ 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"}];
}
message SettingItem {
string name = 1;
string value = 2;
string type = 2;
string value = 3;
}
message GetSettingRequest{}

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: system.proto
// date: 2025-06-22 11:09:05
// date: 2025-07-23 17:37:42
package pb

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
// source: system.proto
// date: 2025-06-22 11:09:05
// date: 2025-07-23 17:37:42
package pb
@ -10,11 +10,13 @@ import (
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:"search;view;export"`
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"column:updated_at" comment:"更新时间" scenarios:"search;view;export"`
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"`
Value string `json:"value" yaml:"value" xml:"value" gorm:"size:512;column:value" comment:"配置值" format:"textarea" rule:"required"`
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024;column:description" comment:"备注说明" scenarios:"create;update;view;export" format:"textarea"`
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"`
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024;column:description" comment:"备注说明" scenarios:"list;create;update;view;export" format:"textarea"`
}
func (m *SettingModel) TableName() string {
@ -25,7 +27,9 @@ 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
m.Description = x.Description
}
@ -35,7 +39,9 @@ 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
x.Description = m.Description
return x
@ -76,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"`
@ -90,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
@ -101,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

@ -42,6 +42,31 @@ func getModels() []any {
}
}
func getViewPath(prefix string, model *rest.Model) string {
viewPath := path.Join(prefix, model.Naming().ModuleName, model.Naming().Singular, "Index.vue")
refVal := reflect.New(model.Value().Type()).Interface()
if v, ok := refVal.(adminTypes.MenuModel); ok {
instance := v.GetMenu()
if instance == nil {
return viewPath
}
// 多级别的定义, 比如 CallcenterRoute -> callcenter/route
if instance.Parent != "" {
words := strings.Split(inflector.Camel2id(instance.Parent), "_")
names := []string{prefix}
for _, word := range words {
word = strings.TrimSpace(word)
if word != "" {
names = append(names, strings.ToLower(word))
}
}
names = append(names, model.Naming().Singular, "Index.vue")
viewPath = path.Join(names...)
}
}
return viewPath
}
// checkModelMenu 检查模型菜单
func checkModelMenu(db *gorm.DB, viewPath string, apiPrefix string, model *rest.Model, translate Translate) (value *models.Menu, err error) {
refVal := reflect.New(model.Value().Type()).Interface()
@ -72,7 +97,7 @@ func checkModelMenu(db *gorm.DB, viewPath string, apiPrefix string, model *rest.
value.Uri = strings.TrimPrefix(model.Uri(types.ScenarioList), apiPrefix)
}
if value.ViewPath == "" {
value.ViewPath = path.Join(viewPath, model.ModuleName(), model.Naming().Singular, "Index.vue")
value.ViewPath = getViewPath(viewPath, model)
}
err = db.Create(value).Error
}
@ -142,20 +167,11 @@ func checkModel(opts *options, model *rest.Model) (err error) {
// generateVueFile 生成Vue文件
func generateVueFile(prefix string, apiPrefix string, mv *rest.Model) (err error) {
refVal := reflect.New(mv.Value().Type()).Interface()
if v, ok := refVal.(adminTypes.MenuModel); ok {
instance := v.GetMenu()
if instance != nil {
if instance.Hidden {
viewPath := getViewPath(prefix, mv)
if _, err = os.Stat(viewPath); err == nil {
return
}
}
}
filename := path.Join(prefix, mv.Naming().ModuleName, mv.Naming().Singular, "Index.vue")
if _, err = os.Stat(filename); err == nil {
return
}
dirname := path.Dir(filename)
dirname := path.Dir(viewPath)
if _, err = os.Stat(dirname); err != nil {
if err = os.MkdirAll(dirname, os.ModePerm); err != nil {
return
@ -178,29 +194,44 @@ func generateVueFile(prefix string, apiPrefix string, mv *rest.Model) (err error
}
}
data := &vueTemplateData{
Component: inflector.Camelize(mv.Naming().ModuleName) + inflector.Camelize(mv.Naming().Singular),
ModuleName: mv.ModuleName(),
TableName: mv.TableName(),
Permissions: permissions,
Readonly: !editable,
ApiPrefix: strings.TrimPrefix(apiPrefix, "/"),
}
//调整组件名称
refVal := reflect.New(mv.Value().Type()).Interface()
if v, ok := refVal.(adminTypes.MenuModel); ok {
if v.GetMenu().Name != "" {
data.Component = v.GetMenu().Name
}
}
writer := pool.GetBuffer()
defer pool.PutBuffer(writer)
if err = temp.Execute(writer, data); err != nil {
return
}
return os.WriteFile(filename, writer.Bytes(), 0644)
return os.WriteFile(viewPath, writer.Bytes(), 0644)
}
// 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)
}
@ -218,10 +249,13 @@ func initREST(ctx context.Context, o *options) (err error) {
if o.apiPrefix != "" {
opts = append(opts, rest.WithUriPrefix(o.apiPrefix))
}
if !o.enableDomain {
opts = append(opts, rest.WithoutDomain())
}
if err = rest.Init(opts...); err != nil {
return
}
if !o.disableModel {
if !o.disableModels {
if err = tx.AutoMigrate(getModels()...); err != nil {
return
}
@ -259,6 +293,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(),
@ -267,7 +302,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"),
)
@ -283,7 +318,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,
@ -371,8 +406,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 {
@ -419,8 +455,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 {
@ -467,8 +504,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 {
@ -525,7 +563,7 @@ func Init(ctx context.Context, cbs ...Option) (err error) {
registerRESTRoute(opts.domain, opts.db, opts.httpServer)
}
if !opts.disableDefault {
if err = migrate.Default(opts.db); err != nil {
if err = migrate.Default(opts.db, opts.domain); err != nil {
return
}
}

View File

@ -27,6 +27,8 @@ type (
tokenStore TokenStore
turnstileValidateUrl string
turnstileSiteKey string
enableRefreshToken bool
enableDomain bool
}
turnstileRequest struct {
@ -59,12 +61,24 @@ func WithAuthDB(db *gorm.DB) AuthOption {
}
}
func WithAuthDomain() AuthOption {
return func(o *authOptions) {
o.enableDomain = true
}
}
func WithAuthCache(cache cache.Cache) AuthOption {
return func(o *authOptions) {
o.cache = cache
}
}
func WithAuthRefreshToken() AuthOption {
return func(o *authOptions) {
o.enableRefreshToken = true
}
}
func WithTokenStore(store TokenStore) AuthOption {
return func(o *authOptions) {
o.tokenStore = store
@ -152,16 +166,34 @@ 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.enableDomain {
claims.Domain = model.Domain
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
res = &pb.LoginResponse{}
if res.Token, err = token.SignedString(s.opts.secret); err == nil {
res.Uid = model.Uid
res.Username = model.Username
res.Expires = s.opts.ttl
}
if s.opts.enableRefreshToken {
refreshClaims := types.Claims{
Uid: model.Uid,
Role: model.Role,
Admin: model.Admin,
IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Hour * 48).Unix(),
}
if s.opts.enableDomain {
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 {
@ -186,6 +218,43 @@ func (s *AuthService) Logout(ctx context.Context, req *pb.LogoutRequest) (res *p
return
}
func (s *AuthService) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequest) (res *pb.RefreshTokenResponse, err error) {
var (
refreshToken *jwt.Token
)
if !s.opts.enableRefreshToken {
err = errors.ErrAccessDenied
return
}
if refreshToken, err = jwt.ParseWithClaims(req.RefreshToken, &types.Claims{}, func(token *jwt.Token) (interface{}, error) {
return s.opts.secret, nil
}); err != nil {
return
}
refreshClaims, ok := refreshToken.Claims.(*types.Claims)
if !ok {
err = errors.ErrIncompatible
}
tokenClaims := types.Claims{
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(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, tokenClaims)
res = &pb.RefreshTokenResponse{}
if res.Token, err = token.SignedString(s.opts.secret); err == nil {
res.Uid = refreshClaims.Uid
res.Expires = s.opts.ttl
if s.opts.tokenStore != nil {
s.opts.tokenStore.Put(ctx, res.Token, s.opts.ttl)
}
}
return
}
func NewAuthService(cbs ...AuthOption) *AuthService {
opts := &authOptions{
ttl: 7200,

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"
"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

@ -46,15 +46,19 @@ func (s *SettingService) GetSetting(ctx context.Context, req *pb.GetSettingReque
for _, v := range values {
res.Data = append(res.Data, &pb.SettingItem{
Name: v.Name,
Type: v.Type,
Value: v.Value,
})
}
return
}
func NewSettingService(cbs ...SettingOption) *SettingService {
opts := &settingOptions{}
for _, cb := range cbs {
cb(opts)
}
return &SettingService{}
return &SettingService{
opts: opts,
}
}

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,19 +106,21 @@ 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 {
@ -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)
@ -276,9 +280,15 @@ func (s *UserService) DepartmentUserNested(ctx context.Context) []*types.NestedV
func (s *UserService) GetUserTags(ctx context.Context, req *pb.GetUserTagRequest) (res *pb.GetUserTagResponse, err error) {
res = &pb.GetUserTagResponse{}
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:tags"), func(tx *gorm.DB) ([]*pb.LabelValue, error) {
domainName := utils.GetDomainFromContext(ctx)
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:tags:%s", domainName), func(tx *gorm.DB) ([]*pb.LabelValue, error) {
values := make([]*models.User, 0)
if err = tx.Select("DISTINCT(`tag`) AS `tag`").Find(&values).Error; err == nil {
if domainName == "" {
err = tx.Select("DISTINCT(`tag`) AS `tag`").Find(&values).Error
} else {
err = tx.Select("DISTINCT(`tag`) AS `tag`").Where("`domain`=?", domainName).Find(&values).Error
}
if err == nil {
items := make([]*pb.LabelValue, 0, len(values))
for _, v := range values {
if v.Tag == "" {

View File

@ -20,6 +20,10 @@ var (
import Viewer from '@/components/fragment/Viewer.vue';
import { computed } from 'vue';
defineOptions({
name: '{{.Component}}'
})
const props = defineProps({
title: {
type: String,

View File

@ -34,6 +34,7 @@ type (
disableModels bool
httpServer *http.Server
restOpts []rest.Option
enableDomain bool
}
Option func(*options)
@ -52,6 +53,7 @@ type (
}
vueTemplateData struct {
Component string //组件名称
ModuleName string
TableName string
ApiPrefix string
@ -72,6 +74,13 @@ func WithCache(cache cache.Cache) Option {
}
}
func WithDomain(domain string) Option {
return func(o *options) {
o.enableDomain = true
o.domain = domain
}
}
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"`
}

64
utils.go 100644
View File

@ -0,0 +1,64 @@
package aeusadmin
import "git.nobla.cn/golang/aeus-admin/models"
type (
menuOptions struct {
icon string
position int
public bool
hidden bool
description string
}
MenuOption func(o *menuOptions)
)
func WithMenuIcon(icon string) MenuOption {
return func(o *menuOptions) {
o.icon = icon
}
}
func WithMenuPosition(position int) MenuOption {
return func(o *menuOptions) {
o.position = position
}
}
func WithMenuPublic(public bool) MenuOption {
return func(o *menuOptions) {
o.public = public
}
}
func WithMenuHidden(hidden bool) MenuOption {
return func(o *menuOptions) {
o.hidden = hidden
}
}
func WithMenuDescription(description string) MenuOption {
return func(o *menuOptions) {
o.description = description
}
}
func NewMenu(label string, name string, parent string, uri string, viewPath string, cbs ...MenuOption) *models.Menu {
opts := &menuOptions{}
for _, cb := range cbs {
cb(opts)
}
model := &models.Menu{}
model.Name = name
model.Label = label
model.Parent = parent
model.Uri = uri
model.ViewPath = viewPath
model.Public = opts.public
model.Position = int64(opts.position)
model.Icon = opts.icon
model.Hidden = opts.hidden
model.Description = opts.description
return model
}

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 ""
}