add logic and menu service
This commit is contained in:
parent
ef4ad92e35
commit
79a9746447
|
@ -0,0 +1,80 @@
|
||||||
|
package aeusadmin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/internal/logic"
|
||||||
|
"git.nobla.cn/golang/rest"
|
||||||
|
"git.nobla.cn/golang/rest/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Formatter struct {
|
||||||
|
db *gorm.DB
|
||||||
|
user *logic.User
|
||||||
|
department *logic.Department
|
||||||
|
role *logic.Role
|
||||||
|
menu *logic.Menu
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Formatter) FormatUser(ctx context.Context, value, model any, scm *types.Schema) any {
|
||||||
|
if values, err := f.user.GetLabels(ctx); err == nil {
|
||||||
|
for _, row := range values {
|
||||||
|
if row.Value == value {
|
||||||
|
return fmt.Sprintf("%s(%s)", row.Label, row.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Formatter) FormatDepartment(ctx context.Context, value, model any, scm *types.Schema) any {
|
||||||
|
if values, err := f.department.GetLabels(ctx); err == nil {
|
||||||
|
for _, row := range values {
|
||||||
|
if row.Value == value {
|
||||||
|
return row.Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Formatter) FormatRole(ctx context.Context, value, model any, scm *types.Schema) any {
|
||||||
|
if values, err := f.role.GetLabels(ctx); err == nil {
|
||||||
|
for _, row := range values {
|
||||||
|
if row.Value == value {
|
||||||
|
return row.Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Formatter) FormatMenu(ctx context.Context, value, model any, scm *types.Schema) any {
|
||||||
|
if values, err := f.menu.GetLabels(ctx); err == nil {
|
||||||
|
for _, row := range values {
|
||||||
|
if row.Value == value {
|
||||||
|
return row.Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Formatter) Register() {
|
||||||
|
rest.DefaultFormatter.Register("user", f.FormatUser)
|
||||||
|
rest.DefaultFormatter.Register("department", f.FormatDepartment)
|
||||||
|
rest.DefaultFormatter.Register("role", f.FormatRole)
|
||||||
|
rest.DefaultFormatter.Register("menu", f.FormatMenu)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFormatter(db *gorm.DB) *Formatter {
|
||||||
|
return &Formatter{
|
||||||
|
db: db,
|
||||||
|
user: logic.NewUserLogic(db),
|
||||||
|
department: logic.NewDepartmentLogic(db),
|
||||||
|
role: logic.NewRoleLogic(db),
|
||||||
|
menu: logic.NewMenuLogic(db),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
||||||
|
"git.nobla.cn/golang/rest"
|
||||||
|
"git.nobla.cn/golang/rest/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Department struct {
|
||||||
|
db *gorm.DB
|
||||||
|
sqlDependency *dbcache.SqlDependency
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Department) RecursiveDepartment(ctx context.Context, parent int64, level int, departments []*models.Department) []*types.TypeValue[int64] {
|
||||||
|
var (
|
||||||
|
child []*types.TypeValue[int64]
|
||||||
|
)
|
||||||
|
values := make([]*types.TypeValue[int64], 0, len(departments))
|
||||||
|
for _, dept := range departments {
|
||||||
|
if dept.ParentId == parent {
|
||||||
|
if level == 0 {
|
||||||
|
values = append(values, &types.TypeValue[int64]{
|
||||||
|
Label: dept.Name,
|
||||||
|
Value: dept.Id,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
values = append(values, &types.TypeValue[int64]{
|
||||||
|
Label: strings.Repeat("--", level) + dept.Name,
|
||||||
|
Value: dept.Id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
child = u.RecursiveDepartment(ctx, dept.Id, level+1, departments)
|
||||||
|
if len(child) > 0 {
|
||||||
|
for _, row := range child {
|
||||||
|
values = append(values, row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
var values []*models.Department
|
||||||
|
if err = tx.Find(&values).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return u.RecursiveDepartment(ctx, 0, 0, values), nil
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
var items []*models.Department
|
||||||
|
err = tx.Find(&items).Error
|
||||||
|
return items, err
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDepartmentLogic(db *gorm.DB) *Department {
|
||||||
|
return &Department{
|
||||||
|
db: db,
|
||||||
|
sqlDependency: dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM departments"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
||||||
|
"git.nobla.cn/golang/rest"
|
||||||
|
"git.nobla.cn/golang/rest/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Menu struct {
|
||||||
|
db *gorm.DB
|
||||||
|
sqlDependency *dbcache.SqlDependency
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Menu) GetMenus(ctx context.Context) (values []*models.Menu, err error) {
|
||||||
|
return dbcache.TryCache(ctx, "menus", func(tx *gorm.DB) ([]*models.Menu, error) {
|
||||||
|
var items []*models.Menu
|
||||||
|
err = tx.Order("`position`,`id` ASC").Find(&items).Error
|
||||||
|
return items, err
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Menu) GetLabels(ctx context.Context) (values []*types.TypeValue[string], err error) {
|
||||||
|
return dbcache.TryCache(ctx, fmt.Sprintf("menu:labels"), func(tx *gorm.DB) ([]*types.TypeValue[string], error) {
|
||||||
|
return rest.ModelTypes[string](ctx, tx, &models.Menu{}, "", "label", "name")
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMenuLogic(db *gorm.DB) *Menu {
|
||||||
|
return &Menu{
|
||||||
|
db: db,
|
||||||
|
sqlDependency: dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM menus"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
||||||
|
"git.nobla.cn/golang/rest"
|
||||||
|
"git.nobla.cn/golang/rest/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Role struct {
|
||||||
|
db *gorm.DB
|
||||||
|
sqlDependency *dbcache.SqlDependency
|
||||||
|
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")
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Role) GetPermissions(ctx context.Context, role string) (values []*models.Permission, err error) {
|
||||||
|
values, err = dbcache.TryCache(ctx, fmt.Sprintf("role:permissions-items:%s", role), func(tx *gorm.DB) ([]*models.Permission, error) {
|
||||||
|
var items []*models.Permission
|
||||||
|
if role == "" {
|
||||||
|
err = tx.Find(&items).Error
|
||||||
|
} else {
|
||||||
|
err = tx.
|
||||||
|
Where("`permission` IN (SELECT `permission` FROM role_permissions WHERE `role` = ?)", role).
|
||||||
|
Find(&items).Error
|
||||||
|
}
|
||||||
|
return items, err
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.permissionSqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleLogic(db *gorm.DB) *Role {
|
||||||
|
return &Role{
|
||||||
|
db: db,
|
||||||
|
sqlDependency: dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM roles"),
|
||||||
|
permissionSqlDependency: dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM permissions"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
||||||
|
"git.nobla.cn/golang/rest"
|
||||||
|
"git.nobla.cn/golang/rest/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
db *gorm.DB
|
||||||
|
sqlDependency *dbcache.SqlDependency
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPermissions 获取用户权限
|
||||||
|
func (u *User) GetPermissions(ctx context.Context, uid string) (permissions []string, err error) {
|
||||||
|
permissions, err = dbcache.TryCache(ctx, fmt.Sprintf("user:permissions:%s", uid), func(tx *gorm.DB) ([]string, error) {
|
||||||
|
var ss []string
|
||||||
|
err = tx.Select("permission").Model(&models.RolePermission{}).
|
||||||
|
Joins("LEFT JOIN users on users.role = role_permissions.role").
|
||||||
|
Where("users.uid = ?", uid).
|
||||||
|
Pluck("permission", &ss).
|
||||||
|
Error
|
||||||
|
return ss, err
|
||||||
|
}, dbcache.WithCacheDuration(time.Minute), dbcache.WithDB(u.db))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
var items []*models.User
|
||||||
|
err = tx.Find(&items).Error
|
||||||
|
return items, err
|
||||||
|
},
|
||||||
|
dbcache.WithDB(u.db),
|
||||||
|
dbcache.WithDependency(u.sqlDependency),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserLogic(db *gorm.DB) *User {
|
||||||
|
return &User{
|
||||||
|
db: db,
|
||||||
|
sqlDependency: dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM users"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
package defaults
|
package migrate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -84,46 +81,3 @@ func init() {
|
||||||
systemDepartment.Description = ""
|
systemDepartment.Description = ""
|
||||||
defaultDepartments = append(defaultDepartments, systemDepartment)
|
defaultDepartments = append(defaultDepartments, systemDepartment)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MergeMenu(db *gorm.DB, model *models.Menu) (err error) {
|
|
||||||
if err = db.Where("name = ?", model.Name).First(model).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
err = db.Create(model).Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Generate(db *gorm.DB) (err error) {
|
|
||||||
var (
|
|
||||||
n int64
|
|
||||||
)
|
|
||||||
for _, row := range defaultMenus {
|
|
||||||
if err = MergeMenu(db, row); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if db.Model(&models.Role{}).Count(&n); n == 0 {
|
|
||||||
db.Create(defaultRoles)
|
|
||||||
permissions := make([]*models.Permission, 0)
|
|
||||||
db.Find(&permissions)
|
|
||||||
for _, row := range defaultRoles {
|
|
||||||
items := make([]*models.RolePermission, 0)
|
|
||||||
for _, perm := range permissions {
|
|
||||||
item := &models.RolePermission{}
|
|
||||||
item.Role = row.Name
|
|
||||||
item.Permission = perm.Permission
|
|
||||||
items = append(items, item)
|
|
||||||
}
|
|
||||||
db.Save(items)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if db.Model(&models.Department{}).Count(&n); n == 0 {
|
|
||||||
db.Create(defaultDepartments)
|
|
||||||
}
|
|
||||||
if db.Model(&models.User{}).Count(&n); n == 0 {
|
|
||||||
db.Create(defaultUsers)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package migrate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Menu 合并菜单
|
||||||
|
func Menu(db *gorm.DB, model *models.Menu) (err error) {
|
||||||
|
if err = db.Where("name = ?", model.Name).First(model).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
err = db.Create(model).Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission 合并权限数据
|
||||||
|
func Permission(db *gorm.DB, menuName string, permission string, label string) (permissionModel *models.Permission, err error) {
|
||||||
|
permissionModel = &models.Permission{}
|
||||||
|
if err = db.Where("permission = ? AND menu = ?", permission, menuName).First(permissionModel).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
permissionModel.Menu = menuName
|
||||||
|
permissionModel.Label = label
|
||||||
|
permissionModel.Permission = permission
|
||||||
|
err = db.Create(permissionModel).Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default 合并初始化数据集
|
||||||
|
func Default(db *gorm.DB) (err error) {
|
||||||
|
var (
|
||||||
|
n int64
|
||||||
|
)
|
||||||
|
for _, row := range defaultMenus {
|
||||||
|
if err = Menu(db, row); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if db.Model(&models.Role{}).Count(&n); n == 0 {
|
||||||
|
db.Create(defaultRoles)
|
||||||
|
permissions := make([]*models.Permission, 0)
|
||||||
|
db.Find(&permissions)
|
||||||
|
for _, row := range defaultRoles {
|
||||||
|
items := make([]*models.RolePermission, 0)
|
||||||
|
for _, perm := range permissions {
|
||||||
|
item := &models.RolePermission{}
|
||||||
|
item.Role = row.Name
|
||||||
|
item.Permission = perm.Permission
|
||||||
|
items = append(items, item)
|
||||||
|
}
|
||||||
|
db.Save(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if db.Model(&models.Department{}).Count(&n); n == 0 {
|
||||||
|
db.Create(defaultDepartments)
|
||||||
|
}
|
||||||
|
if db.Model(&models.User{}).Count(&n); n == 0 {
|
||||||
|
db.Create(defaultUsers)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@ message Menu {
|
||||||
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"菜单ID"}];
|
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"菜单ID"}];
|
||||||
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
|
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
|
||||||
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
|
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
|
||||||
string parent = 4 [(aeus.field)={gorm:"index;size:60",props:"readonly:update",comment:"父级菜单"}];
|
string parent = 4 [(aeus.field)={gorm:"index;size:60",props:"readonly:update",live:"type:dropdown;url:/menu/level-labels",format:"menu",comment:"父级菜单"}];
|
||||||
string name = 5 [(aeus.field)={gorm:"index;size:60",props:"readonly:update",rule:"unique;required",comment: "组件名称"},(validate.rules).string = {max_len: 60}];
|
string name = 5 [(aeus.field)={gorm:"index;size:60",props:"readonly:update",rule:"unique;required",comment: "组件名称"},(validate.rules).string = {max_len: 60}];
|
||||||
string label = 6 [(aeus.field)={gorm:"size:120",rule:"required",comment: "菜单标题"},(validate.rules).string = {max_len: 120}];
|
string label = 6 [(aeus.field)={gorm:"size:120",rule:"required",comment: "菜单标题"},(validate.rules).string = {max_len: 120}];
|
||||||
string uri = 7 [(aeus.field)={gorm:"size:512",rule:"required",scenarios:"create;update;view;export",comment: "菜单链接"},(validate.rules).string = {max_len: 512}];
|
string uri = 7 [(aeus.field)={gorm:"size:512",rule:"required",scenarios:"create;update;view;export",comment: "菜单链接"},(validate.rules).string = {max_len: 512}];
|
||||||
|
@ -26,6 +26,7 @@ message Menu {
|
||||||
bool hidden = 10 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否隐藏"}];
|
bool hidden = 10 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否隐藏"}];
|
||||||
bool public = 11 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否公开"}];
|
bool public = 11 [(aeus.field)={scenarios:"create;update;view;export",comment:"是否公开"}];
|
||||||
string description = 12 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export;list",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
|
string description = 12 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export;list",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
|
||||||
|
int64 position = 13 [(aeus.field)={comment:"排序",scenarios:"create;update"}];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Role 角色模型定义
|
// Role 角色模型定义
|
||||||
|
@ -47,9 +48,11 @@ message Permission {
|
||||||
table: "permissions"
|
table: "permissions"
|
||||||
};
|
};
|
||||||
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment: "权限ID"}];
|
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment: "权限ID"}];
|
||||||
string menu = 2 [(aeus.field)={gorm:"index;size:60",rule:"required",comment: "所属菜单"}];
|
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
|
||||||
string permission = 3 [(aeus.field)={gorm:"index;size:60",rule:"required",comment: "权限名称"},(validate.rules).string = {max_len: 60}];
|
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
|
||||||
string label = 4 [(aeus.field)={gorm:"size:60",rule:"required",comment: "权限标题"},(validate.rules).string = {max_len: 60}];
|
string menu = 4 [(aeus.field)={gorm:"index;size:60",format:"menu",rule:"required",comment: "所属菜单"}];
|
||||||
|
string permission = 5 [(aeus.field)={gorm:"index;size:60",rule:"required",comment: "权限名称"},(validate.rules).string = {max_len: 60}];
|
||||||
|
string label = 6 [(aeus.field)={gorm:"size:60",rule:"required",comment: "权限标题"},(validate.rules).string = {max_len: 60}];
|
||||||
}
|
}
|
||||||
|
|
||||||
// RolePermission 角色权限关联表
|
// RolePermission 角色权限关联表
|
||||||
|
@ -92,7 +95,7 @@ message Department {
|
||||||
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
|
int64 id = 1 [(aeus.field) = {gorm:"primaryKey",comment:"ID"}];
|
||||||
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
|
int64 created_at = 2 [(aeus.field)={scenarios:"view;export",comment:"创建时间"}];
|
||||||
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
|
int64 updated_at = 3 [(aeus.field)={gorm:"index",scenarios:"view;export",comment:"更新时间"}];
|
||||||
int64 parent_id = 4 [(aeus.field)={format:"department",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 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 description = 6 [(aeus.field)={gorm:"size:1024",scenarios:"create;update;view;export;list",format:"textarea",comment: "备注说明"},(validate.rules).string = {max_len: 1024}];
|
||||||
}
|
}
|
||||||
|
@ -289,6 +292,13 @@ message DepartmentLabelValue {
|
||||||
int64 value = 2;
|
int64 value = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message DepartmentUserValue {
|
||||||
|
string label = 1;
|
||||||
|
string value = 2;
|
||||||
|
bool isuser = 3;
|
||||||
|
repeated DepartmentUserValue children = 4;
|
||||||
|
}
|
||||||
|
|
||||||
message GetDepartmentLabelRequest {
|
message GetDepartmentLabelRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +306,26 @@ message GetDepartmentLabelResponse {
|
||||||
repeated DepartmentLabelValue data = 1;
|
repeated DepartmentLabelValue data = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetDepartmentUserRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDepartmentUserResponse {
|
||||||
|
repeated DepartmentUserValue data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DepartmentLevelValue {
|
||||||
|
string label = 1;
|
||||||
|
int64 value = 2;
|
||||||
|
repeated DepartmentLevelValue children = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDepartmentLevelLabelsRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDepartmentLevelLabelsResponse {
|
||||||
|
repeated DepartmentLevelValue data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
service DepartmentService {
|
service DepartmentService {
|
||||||
// 获取部门标签
|
// 获取部门标签
|
||||||
rpc GetDepartmentLabels(GetDepartmentLabelRequest) returns (GetDepartmentLabelResponse) {
|
rpc GetDepartmentLabels(GetDepartmentLabelRequest) returns (GetDepartmentLabelResponse) {
|
||||||
|
@ -303,6 +333,16 @@ service DepartmentService {
|
||||||
get: "/department/labels"
|
get: "/department/labels"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
rpc GetDepartmentUsers(GetDepartmentUserRequest) returns (GetDepartmentUserResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/department/users"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc GetDepartmentLevelLabels(GetDepartmentLevelLabelsRequest) returns (GetDepartmentLevelLabelsResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/department/level-labels"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRoleLabelRequest {
|
message GetRoleLabelRequest {
|
||||||
|
@ -352,6 +392,27 @@ service RoleService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message MenuLevelValue {
|
||||||
|
string label = 1;
|
||||||
|
string value = 2;
|
||||||
|
repeated MenuLevelValue children = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetMenuLevelLabelsRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetMenuLevelLabelsResponse {
|
||||||
|
repeated MenuLevelValue data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
service MenuService {
|
||||||
|
rpc GetMenuLevelLabels(GetMenuLevelLabelsRequest) returns (GetMenuLevelLabelsResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/menu/level-labels"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
message LoginRequest {
|
message LoginRequest {
|
||||||
string username = 1;
|
string username = 1;
|
||||||
|
|
|
@ -368,6 +368,8 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DepartmentService_GetDepartmentLabels_FullMethodName = "/organize.DepartmentService/GetDepartmentLabels"
|
DepartmentService_GetDepartmentLabels_FullMethodName = "/organize.DepartmentService/GetDepartmentLabels"
|
||||||
|
DepartmentService_GetDepartmentUsers_FullMethodName = "/organize.DepartmentService/GetDepartmentUsers"
|
||||||
|
DepartmentService_GetDepartmentLevelLabels_FullMethodName = "/organize.DepartmentService/GetDepartmentLevelLabels"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DepartmentServiceClient is the client API for DepartmentService service.
|
// DepartmentServiceClient is the client API for DepartmentService service.
|
||||||
|
@ -376,6 +378,8 @@ const (
|
||||||
type DepartmentServiceClient interface {
|
type DepartmentServiceClient interface {
|
||||||
// 获取部门标签
|
// 获取部门标签
|
||||||
GetDepartmentLabels(ctx context.Context, in *GetDepartmentLabelRequest, opts ...grpc.CallOption) (*GetDepartmentLabelResponse, error)
|
GetDepartmentLabels(ctx context.Context, in *GetDepartmentLabelRequest, opts ...grpc.CallOption) (*GetDepartmentLabelResponse, error)
|
||||||
|
GetDepartmentUsers(ctx context.Context, in *GetDepartmentUserRequest, opts ...grpc.CallOption) (*GetDepartmentUserResponse, error)
|
||||||
|
GetDepartmentLevelLabels(ctx context.Context, in *GetDepartmentLevelLabelsRequest, opts ...grpc.CallOption) (*GetDepartmentLevelLabelsResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type departmentServiceClient struct {
|
type departmentServiceClient struct {
|
||||||
|
@ -396,12 +400,34 @@ func (c *departmentServiceClient) GetDepartmentLabels(ctx context.Context, in *G
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *departmentServiceClient) GetDepartmentUsers(ctx context.Context, in *GetDepartmentUserRequest, opts ...grpc.CallOption) (*GetDepartmentUserResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(GetDepartmentUserResponse)
|
||||||
|
err := c.cc.Invoke(ctx, DepartmentService_GetDepartmentUsers_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *departmentServiceClient) GetDepartmentLevelLabels(ctx context.Context, in *GetDepartmentLevelLabelsRequest, opts ...grpc.CallOption) (*GetDepartmentLevelLabelsResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(GetDepartmentLevelLabelsResponse)
|
||||||
|
err := c.cc.Invoke(ctx, DepartmentService_GetDepartmentLevelLabels_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DepartmentServiceServer is the server API for DepartmentService service.
|
// DepartmentServiceServer is the server API for DepartmentService service.
|
||||||
// All implementations must embed UnimplementedDepartmentServiceServer
|
// All implementations must embed UnimplementedDepartmentServiceServer
|
||||||
// for forward compatibility.
|
// for forward compatibility.
|
||||||
type DepartmentServiceServer interface {
|
type DepartmentServiceServer interface {
|
||||||
// 获取部门标签
|
// 获取部门标签
|
||||||
GetDepartmentLabels(context.Context, *GetDepartmentLabelRequest) (*GetDepartmentLabelResponse, error)
|
GetDepartmentLabels(context.Context, *GetDepartmentLabelRequest) (*GetDepartmentLabelResponse, error)
|
||||||
|
GetDepartmentUsers(context.Context, *GetDepartmentUserRequest) (*GetDepartmentUserResponse, error)
|
||||||
|
GetDepartmentLevelLabels(context.Context, *GetDepartmentLevelLabelsRequest) (*GetDepartmentLevelLabelsResponse, error)
|
||||||
mustEmbedUnimplementedDepartmentServiceServer()
|
mustEmbedUnimplementedDepartmentServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,6 +441,12 @@ type UnimplementedDepartmentServiceServer struct{}
|
||||||
func (UnimplementedDepartmentServiceServer) GetDepartmentLabels(context.Context, *GetDepartmentLabelRequest) (*GetDepartmentLabelResponse, error) {
|
func (UnimplementedDepartmentServiceServer) GetDepartmentLabels(context.Context, *GetDepartmentLabelRequest) (*GetDepartmentLabelResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetDepartmentLabels not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GetDepartmentLabels not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedDepartmentServiceServer) GetDepartmentUsers(context.Context, *GetDepartmentUserRequest) (*GetDepartmentUserResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetDepartmentUsers not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedDepartmentServiceServer) GetDepartmentLevelLabels(context.Context, *GetDepartmentLevelLabelsRequest) (*GetDepartmentLevelLabelsResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetDepartmentLevelLabels not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedDepartmentServiceServer) mustEmbedUnimplementedDepartmentServiceServer() {}
|
func (UnimplementedDepartmentServiceServer) mustEmbedUnimplementedDepartmentServiceServer() {}
|
||||||
func (UnimplementedDepartmentServiceServer) testEmbeddedByValue() {}
|
func (UnimplementedDepartmentServiceServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
|
@ -454,6 +486,42 @@ func _DepartmentService_GetDepartmentLabels_Handler(srv interface{}, ctx context
|
||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _DepartmentService_GetDepartmentUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetDepartmentUserRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(DepartmentServiceServer).GetDepartmentUsers(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: DepartmentService_GetDepartmentUsers_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(DepartmentServiceServer).GetDepartmentUsers(ctx, req.(*GetDepartmentUserRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _DepartmentService_GetDepartmentLevelLabels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetDepartmentLevelLabelsRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(DepartmentServiceServer).GetDepartmentLevelLabels(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: DepartmentService_GetDepartmentLevelLabels_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(DepartmentServiceServer).GetDepartmentLevelLabels(ctx, req.(*GetDepartmentLevelLabelsRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// DepartmentService_ServiceDesc is the grpc.ServiceDesc for DepartmentService service.
|
// DepartmentService_ServiceDesc is the grpc.ServiceDesc for DepartmentService service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
|
@ -465,6 +533,14 @@ var DepartmentService_ServiceDesc = grpc.ServiceDesc{
|
||||||
MethodName: "GetDepartmentLabels",
|
MethodName: "GetDepartmentLabels",
|
||||||
Handler: _DepartmentService_GetDepartmentLabels_Handler,
|
Handler: _DepartmentService_GetDepartmentLabels_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetDepartmentUsers",
|
||||||
|
Handler: _DepartmentService_GetDepartmentUsers_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetDepartmentLevelLabels",
|
||||||
|
Handler: _DepartmentService_GetDepartmentLevelLabels_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "organize.proto",
|
Metadata: "organize.proto",
|
||||||
|
@ -652,6 +728,108 @@ var RoleService_ServiceDesc = grpc.ServiceDesc{
|
||||||
Metadata: "organize.proto",
|
Metadata: "organize.proto",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
MenuService_GetMenuLevelLabels_FullMethodName = "/organize.MenuService/GetMenuLevelLabels"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MenuServiceClient is the client API for MenuService service.
|
||||||
|
//
|
||||||
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||||
|
type MenuServiceClient interface {
|
||||||
|
GetMenuLevelLabels(ctx context.Context, in *GetMenuLevelLabelsRequest, opts ...grpc.CallOption) (*GetMenuLevelLabelsResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type menuServiceClient struct {
|
||||||
|
cc grpc.ClientConnInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMenuServiceClient(cc grpc.ClientConnInterface) MenuServiceClient {
|
||||||
|
return &menuServiceClient{cc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *menuServiceClient) GetMenuLevelLabels(ctx context.Context, in *GetMenuLevelLabelsRequest, opts ...grpc.CallOption) (*GetMenuLevelLabelsResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(GetMenuLevelLabelsResponse)
|
||||||
|
err := c.cc.Invoke(ctx, MenuService_GetMenuLevelLabels_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MenuServiceServer is the server API for MenuService service.
|
||||||
|
// All implementations must embed UnimplementedMenuServiceServer
|
||||||
|
// for forward compatibility.
|
||||||
|
type MenuServiceServer interface {
|
||||||
|
GetMenuLevelLabels(context.Context, *GetMenuLevelLabelsRequest) (*GetMenuLevelLabelsResponse, error)
|
||||||
|
mustEmbedUnimplementedMenuServiceServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnimplementedMenuServiceServer must be embedded to have
|
||||||
|
// forward compatible implementations.
|
||||||
|
//
|
||||||
|
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||||
|
// pointer dereference when methods are called.
|
||||||
|
type UnimplementedMenuServiceServer struct{}
|
||||||
|
|
||||||
|
func (UnimplementedMenuServiceServer) GetMenuLevelLabels(context.Context, *GetMenuLevelLabelsRequest) (*GetMenuLevelLabelsResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetMenuLevelLabels not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedMenuServiceServer) mustEmbedUnimplementedMenuServiceServer() {}
|
||||||
|
func (UnimplementedMenuServiceServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
|
// UnsafeMenuServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||||
|
// Use of this interface is not recommended, as added methods to MenuServiceServer will
|
||||||
|
// result in compilation errors.
|
||||||
|
type UnsafeMenuServiceServer interface {
|
||||||
|
mustEmbedUnimplementedMenuServiceServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterMenuServiceServer(s grpc.ServiceRegistrar, srv MenuServiceServer) {
|
||||||
|
// If the following call pancis, it indicates UnimplementedMenuServiceServer was
|
||||||
|
// embedded by pointer and is nil. This will cause panics if an
|
||||||
|
// unimplemented method is ever invoked, so we test this at initialization
|
||||||
|
// time to prevent it from happening at runtime later due to I/O.
|
||||||
|
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||||
|
t.testEmbeddedByValue()
|
||||||
|
}
|
||||||
|
s.RegisterService(&MenuService_ServiceDesc, srv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _MenuService_GetMenuLevelLabels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetMenuLevelLabelsRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(MenuServiceServer).GetMenuLevelLabels(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: MenuService_GetMenuLevelLabels_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(MenuServiceServer).GetMenuLevelLabels(ctx, req.(*GetMenuLevelLabelsRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MenuService_ServiceDesc is the grpc.ServiceDesc for MenuService service.
|
||||||
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
|
// and not to be introspected or modified (even as a copy)
|
||||||
|
var MenuService_ServiceDesc = grpc.ServiceDesc{
|
||||||
|
ServiceName: "organize.MenuService",
|
||||||
|
HandlerType: (*MenuServiceServer)(nil),
|
||||||
|
Methods: []grpc.MethodDesc{
|
||||||
|
{
|
||||||
|
MethodName: "GetMenuLevelLabels",
|
||||||
|
Handler: _MenuService_GetMenuLevelLabels_Handler,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Streams: []grpc.StreamDesc{},
|
||||||
|
Metadata: "organize.proto",
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AuthService_Login_FullMethodName = "/organize.AuthService/Login"
|
AuthService_Login_FullMethodName = "/organize.AuthService/Login"
|
||||||
AuthService_Logout_FullMethodName = "/organize.AuthService/Logout"
|
AuthService_Logout_FullMethodName = "/organize.AuthService/Logout"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
|
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
|
||||||
// source: organize.proto
|
// source: organize.proto
|
||||||
// date: 2025-06-17 18:12:28
|
// date: 2025-06-18 14:37:24
|
||||||
|
|
||||||
package pb
|
package pb
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ type UserServiceHttpServer interface {
|
||||||
|
|
||||||
type DepartmentServiceHttpServer interface {
|
type DepartmentServiceHttpServer interface {
|
||||||
GetDepartmentLabels(context.Context, *GetDepartmentLabelRequest) (*GetDepartmentLabelResponse, error)
|
GetDepartmentLabels(context.Context, *GetDepartmentLabelRequest) (*GetDepartmentLabelResponse, error)
|
||||||
|
|
||||||
|
GetDepartmentUsers(context.Context, *GetDepartmentUserRequest) (*GetDepartmentUserResponse, error)
|
||||||
|
|
||||||
|
GetDepartmentLevelLabels(context.Context, *GetDepartmentLevelLabelsRequest) (*GetDepartmentLevelLabelsResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RoleServiceHttpServer interface {
|
type RoleServiceHttpServer interface {
|
||||||
|
@ -38,6 +42,10 @@ type RoleServiceHttpServer interface {
|
||||||
SaveRolePermission(context.Context, *SaveRolePermissionRequest) (*SaveRolePermissionResponse, error)
|
SaveRolePermission(context.Context, *SaveRolePermissionRequest) (*SaveRolePermissionResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MenuServiceHttpServer interface {
|
||||||
|
GetMenuLevelLabels(context.Context, *GetMenuLevelLabelsRequest) (*GetMenuLevelLabelsResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
type AuthServiceHttpServer interface {
|
type AuthServiceHttpServer interface {
|
||||||
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
||||||
|
|
||||||
|
@ -212,6 +220,38 @@ func handleDepartmentServiceGetDepartmentLabels(s DepartmentServiceHttpServer) h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleDepartmentServiceGetDepartmentUsers(s DepartmentServiceHttpServer) http.HandleFunc {
|
||||||
|
return func(ctx *http.Context) (err error) {
|
||||||
|
req := &GetDepartmentUserRequest{}
|
||||||
|
|
||||||
|
if res, err := s.GetDepartmentUsers(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 handleDepartmentServiceGetDepartmentLevelLabels(s DepartmentServiceHttpServer) http.HandleFunc {
|
||||||
|
return func(ctx *http.Context) (err error) {
|
||||||
|
req := &GetDepartmentLevelLabelsRequest{}
|
||||||
|
|
||||||
|
if res, err := s.GetDepartmentLevelLabels(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 handleRoleServiceGetRoleLabels(s RoleServiceHttpServer) http.HandleFunc {
|
func handleRoleServiceGetRoleLabels(s RoleServiceHttpServer) http.HandleFunc {
|
||||||
|
@ -272,6 +312,22 @@ func handleRoleServiceSaveRolePermission(s RoleServiceHttpServer) http.HandleFun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleMenuServiceGetMenuLevelLabels(s MenuServiceHttpServer) http.HandleFunc {
|
||||||
|
return func(ctx *http.Context) (err error) {
|
||||||
|
req := &GetMenuLevelLabelsRequest{}
|
||||||
|
|
||||||
|
if res, err := s.GetMenuLevelLabels(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 handleAuthServiceLogin(s AuthServiceHttpServer) http.HandleFunc {
|
func handleAuthServiceLogin(s AuthServiceHttpServer) http.HandleFunc {
|
||||||
return func(ctx *http.Context) (err error) {
|
return func(ctx *http.Context) (err error) {
|
||||||
req := &LoginRequest{}
|
req := &LoginRequest{}
|
||||||
|
@ -358,6 +414,12 @@ func RegisterDepartmentServiceRouter(hs *http.Server, s DepartmentServiceHttpSer
|
||||||
// Register handle GetDepartmentLabels route
|
// Register handle GetDepartmentLabels route
|
||||||
hs.GET("/department/labels", handleDepartmentServiceGetDepartmentLabels(s))
|
hs.GET("/department/labels", handleDepartmentServiceGetDepartmentLabels(s))
|
||||||
|
|
||||||
|
// Register handle GetDepartmentUsers route
|
||||||
|
hs.GET("/department/users", handleDepartmentServiceGetDepartmentUsers(s))
|
||||||
|
|
||||||
|
// Register handle GetDepartmentLevelLabels route
|
||||||
|
hs.GET("/department/level-labels", handleDepartmentServiceGetDepartmentLevelLabels(s))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterRoleServiceRouter(hs *http.Server, s RoleServiceHttpServer) {
|
func RegisterRoleServiceRouter(hs *http.Server, s RoleServiceHttpServer) {
|
||||||
|
@ -373,6 +435,13 @@ func RegisterRoleServiceRouter(hs *http.Server, s RoleServiceHttpServer) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RegisterMenuServiceRouter(hs *http.Server, s MenuServiceHttpServer) {
|
||||||
|
|
||||||
|
// Register handle GetMenuLevelLabels route
|
||||||
|
hs.GET("/menu/level-labels", handleMenuServiceGetMenuLevelLabels(s))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func RegisterAuthServiceRouter(hs *http.Server, s AuthServiceHttpServer) {
|
func RegisterAuthServiceRouter(hs *http.Server, s AuthServiceHttpServer) {
|
||||||
|
|
||||||
// Register handle Login route
|
// Register handle Login route
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
|
// Code generated by protoc-gen-go-aeus. DO NOT EDIT.
|
||||||
// source: organize.proto
|
// source: organize.proto
|
||||||
// date: 2025-06-17 18:12:28
|
// date: 2025-06-18 14:37:24
|
||||||
|
|
||||||
package pb
|
package pb
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ type MenuModel struct {
|
||||||
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey" comment:"菜单ID"`
|
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey" comment:"菜单ID"`
|
||||||
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" comment:"创建时间" scenarios:"view;export"`
|
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" comment:"创建时间" scenarios:"view;export"`
|
||||||
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index" comment:"更新时间" scenarios:"view;export"`
|
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index" comment:"更新时间" scenarios:"view;export"`
|
||||||
Parent string `json:"parent" yaml:"parent" xml:"parent" gorm:"index;size:60" comment:"父级菜单" props:"readonly:update"`
|
Parent string `json:"parent" yaml:"parent" xml:"parent" gorm:"index;size:60" comment:"父级菜单" format:"menu" props:"readonly:update" live:"type:dropdown;url:/menu/level-labels"`
|
||||||
Name string `json:"name" yaml:"name" xml:"name" gorm:"index;size:60" comment:"组件名称" props:"readonly:update" rule:"unique;required"`
|
Name string `json:"name" yaml:"name" xml:"name" gorm:"index;size:60" comment:"组件名称" props:"readonly:update" rule:"unique;required"`
|
||||||
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:120" comment:"菜单标题" rule:"required"`
|
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:120" comment:"菜单标题" rule:"required"`
|
||||||
Uri string `json:"uri" yaml:"uri" xml:"uri" gorm:"size:512" comment:"菜单链接" scenarios:"create;update;view;export" rule:"required"`
|
Uri string `json:"uri" yaml:"uri" xml:"uri" gorm:"size:512" comment:"菜单链接" scenarios:"create;update;view;export" rule:"required"`
|
||||||
|
@ -21,6 +21,7 @@ type MenuModel struct {
|
||||||
Hidden bool `json:"hidden" yaml:"hidden" xml:"hidden" comment:"是否隐藏" scenarios:"create;update;view;export"`
|
Hidden bool `json:"hidden" yaml:"hidden" xml:"hidden" comment:"是否隐藏" scenarios:"create;update;view;export"`
|
||||||
Public bool `json:"public" yaml:"public" xml:"public" comment:"是否公开" scenarios:"create;update;view;export"`
|
Public bool `json:"public" yaml:"public" xml:"public" comment:"是否公开" scenarios:"create;update;view;export"`
|
||||||
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024" comment:"备注说明" scenarios:"create;update;view;export;list" format:"textarea"`
|
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024" comment:"备注说明" scenarios:"create;update;view;export;list" format:"textarea"`
|
||||||
|
Position int64 `json:"position" yaml:"position" xml:"position" comment:"排序" scenarios:"create;update"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MenuModel) TableName() string {
|
func (m *MenuModel) TableName() string {
|
||||||
|
@ -40,6 +41,7 @@ func (m *MenuModel) FromValue(x *Menu) {
|
||||||
m.Hidden = x.Hidden
|
m.Hidden = x.Hidden
|
||||||
m.Public = x.Public
|
m.Public = x.Public
|
||||||
m.Description = x.Description
|
m.Description = x.Description
|
||||||
|
m.Position = x.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MenuModel) ToValue() (x *Menu) {
|
func (m *MenuModel) ToValue() (x *Menu) {
|
||||||
|
@ -56,6 +58,7 @@ func (m *MenuModel) ToValue() (x *Menu) {
|
||||||
x.Hidden = m.Hidden
|
x.Hidden = m.Hidden
|
||||||
x.Public = m.Public
|
x.Public = m.Public
|
||||||
x.Description = m.Description
|
x.Description = m.Description
|
||||||
|
x.Position = m.Position
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +79,7 @@ func (m *MenuModel) Delete(db *gorm.DB) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MenuModel) Find(db *gorm.DB, pk any) (err error) {
|
func (m *MenuModel) Find(db *gorm.DB, pk any) (err error) {
|
||||||
return db.Where("description=?", pk).First(m).Error
|
return db.Where("position=?", pk).First(m).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MenuModel) FindOne(db *gorm.DB, query any, args ...any) (err error) {
|
func (m *MenuModel) FindOne(db *gorm.DB, query any, args ...any) (err error) {
|
||||||
|
@ -158,7 +161,9 @@ func NewRoleModel() *RoleModel {
|
||||||
|
|
||||||
type PermissionModel struct {
|
type PermissionModel struct {
|
||||||
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey" comment:"权限ID"`
|
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey" comment:"权限ID"`
|
||||||
Menu string `json:"menu" yaml:"menu" xml:"menu" gorm:"index;size:60" comment:"所属菜单" rule:"required"`
|
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" comment:"创建时间" scenarios:"view;export"`
|
||||||
|
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index" comment:"更新时间" scenarios:"view;export"`
|
||||||
|
Menu string `json:"menu" yaml:"menu" xml:"menu" gorm:"index;size:60" comment:"所属菜单" format:"menu" rule:"required"`
|
||||||
Permission string `json:"permission" yaml:"permission" xml:"permission" gorm:"index;size:60" comment:"权限名称" rule:"required"`
|
Permission string `json:"permission" yaml:"permission" xml:"permission" gorm:"index;size:60" comment:"权限名称" rule:"required"`
|
||||||
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:60" comment:"权限标题" rule:"required"`
|
Label string `json:"label" yaml:"label" xml:"label" gorm:"size:60" comment:"权限标题" rule:"required"`
|
||||||
}
|
}
|
||||||
|
@ -169,6 +174,8 @@ func (m *PermissionModel) TableName() string {
|
||||||
|
|
||||||
func (m *PermissionModel) FromValue(x *Permission) {
|
func (m *PermissionModel) FromValue(x *Permission) {
|
||||||
m.Id = x.Id
|
m.Id = x.Id
|
||||||
|
m.CreatedAt = x.CreatedAt
|
||||||
|
m.UpdatedAt = x.UpdatedAt
|
||||||
m.Menu = x.Menu
|
m.Menu = x.Menu
|
||||||
m.Permission = x.Permission
|
m.Permission = x.Permission
|
||||||
m.Label = x.Label
|
m.Label = x.Label
|
||||||
|
@ -177,6 +184,8 @@ func (m *PermissionModel) FromValue(x *Permission) {
|
||||||
func (m *PermissionModel) ToValue() (x *Permission) {
|
func (m *PermissionModel) ToValue() (x *Permission) {
|
||||||
x = &Permission{}
|
x = &Permission{}
|
||||||
x.Id = m.Id
|
x.Id = m.Id
|
||||||
|
x.CreatedAt = m.CreatedAt
|
||||||
|
x.UpdatedAt = m.UpdatedAt
|
||||||
x.Menu = m.Menu
|
x.Menu = m.Menu
|
||||||
x.Permission = m.Permission
|
x.Permission = m.Permission
|
||||||
x.Label = m.Label
|
x.Label = m.Label
|
||||||
|
@ -367,7 +376,7 @@ type DepartmentModel struct {
|
||||||
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey" comment:"ID"`
|
Id int64 `json:"id" yaml:"id" xml:"id" gorm:"primaryKey" comment:"ID"`
|
||||||
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" comment:"创建时间" scenarios:"view;export"`
|
CreatedAt int64 `json:"created_at" yaml:"createdAt" xml:"createdAt" comment:"创建时间" scenarios:"view;export"`
|
||||||
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index" comment:"更新时间" scenarios:"view;export"`
|
UpdatedAt int64 `json:"updated_at" yaml:"updatedAt" xml:"updatedAt" gorm:"index" comment:"更新时间" scenarios:"view;export"`
|
||||||
ParentId int64 `json:"parent_id" yaml:"parentId" xml:"parentId" comment:"父级部门" format:"department"`
|
ParentId int64 `json:"parent_id" yaml:"parentId" xml:"parentId" comment:"父级部门" format:"department" live:"type:dropdown;url:/department/level-labels"`
|
||||||
Name string `json:"name" yaml:"name" xml:"name" gorm:"size:20" comment:"部门名称" rule:"required"`
|
Name string `json:"name" yaml:"name" xml:"name" gorm:"size:20" comment:"部门名称" rule:"required"`
|
||||||
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024" comment:"备注说明" scenarios:"create;update;view;export;list" format:"textarea"`
|
Description string `json:"description" yaml:"description" xml:"description" gorm:"size:1024" comment:"备注说明" scenarios:"create;update;view;export;list" format:"textarea"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,9 @@ package aeusadmin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/internal/logic"
|
||||||
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
|
||||||
"git.nobla.cn/golang/aeus/middleware/auth"
|
"git.nobla.cn/golang/aeus/middleware/auth"
|
||||||
"git.nobla.cn/golang/aeus/pkg/errors"
|
"git.nobla.cn/golang/aeus/pkg/errors"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
@ -15,22 +12,9 @@ import (
|
||||||
|
|
||||||
type PermissionChecker struct {
|
type PermissionChecker struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
logic *logic.User
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PermissionChecker) getUserPermissions(ctx context.Context, uid string) (permissions []string, err error) {
|
|
||||||
permissions, err = dbcache.TryCache(ctx, fmt.Sprintf("user:permissions:%s", uid), func(tx *gorm.DB) ([]string, error) {
|
|
||||||
var ss []string
|
|
||||||
err = tx.Select("permission").Model(&models.RolePermission{}).
|
|
||||||
Joins("LEFT JOIN users on users.role = role_permissions.role").
|
|
||||||
Where("users.uid = ?", uid).
|
|
||||||
Pluck("permission", &ss).
|
|
||||||
Error
|
|
||||||
return ss, err
|
|
||||||
}, dbcache.WithCacheDuration(time.Minute), dbcache.WithDB(p.db))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func (p *PermissionChecker) CheckPermission(ctx context.Context, permission string) (err error) {
|
func (p *PermissionChecker) CheckPermission(ctx context.Context, permission string) (err error) {
|
||||||
var (
|
var (
|
||||||
uid string
|
uid string
|
||||||
|
@ -43,7 +27,7 @@ func (p *PermissionChecker) CheckPermission(ctx context.Context, permission stri
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ps, err = p.getUserPermissions(ctx, uid); err != nil {
|
if ps, err = p.logic.GetPermissions(ctx, uid); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !slices.Contains(ps, permission) {
|
if !slices.Contains(ps, permission) {
|
||||||
|
@ -55,5 +39,6 @@ func (p *PermissionChecker) CheckPermission(ctx context.Context, permission stri
|
||||||
func NewPermissionChecker(db *gorm.DB) *PermissionChecker {
|
func NewPermissionChecker(db *gorm.DB) *PermissionChecker {
|
||||||
return &PermissionChecker{
|
return &PermissionChecker{
|
||||||
db: db,
|
db: db,
|
||||||
|
logic: logic.NewUserLogic(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
server.go
35
server.go
|
@ -11,7 +11,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.nobla.cn/golang/aeus-admin/defaults"
|
"git.nobla.cn/golang/aeus-admin/migrate"
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
||||||
adminTypes "git.nobla.cn/golang/aeus-admin/types"
|
adminTypes "git.nobla.cn/golang/aeus-admin/types"
|
||||||
|
@ -100,30 +100,11 @@ func checkModelMenu(db *gorm.DB, viewPath string, apiPrefix string, model *rest.
|
||||||
func checkModelPermission(db *gorm.DB, menuName string, scene string, model *rest.Model, translate Translate) (permissionModel *models.Permission, err error) {
|
func checkModelPermission(db *gorm.DB, menuName string, scene string, model *rest.Model, translate Translate) (permissionModel *models.Permission, err error) {
|
||||||
permissionModel = &models.Permission{}
|
permissionModel = &models.Permission{}
|
||||||
permission := model.Permission(scene)
|
permission := model.Permission(scene)
|
||||||
if err = db.Where("permission = ? AND menu = ?", permission, menuName).First(permissionModel).Error; err != nil {
|
label := scene
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
permissionModel.Menu = menuName
|
|
||||||
permissionModel.Label = scene
|
|
||||||
if translate != nil {
|
if translate != nil {
|
||||||
permissionModel.Label = translate.Permission(model, scene, permissionModel.Label)
|
label = translate.Permission(model, scene, label)
|
||||||
}
|
|
||||||
permissionModel.Permission = permission
|
|
||||||
err = db.Create(permissionModel).Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func replaceModelPermission(db *gorm.DB, menuName string, permission string, label string) (permissionModel *models.Permission, err error) {
|
|
||||||
permissionModel = &models.Permission{}
|
|
||||||
if err = db.Where("permission = ? AND menu = ?", permission, menuName).First(permissionModel).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
permissionModel.Menu = menuName
|
|
||||||
permissionModel.Label = label
|
|
||||||
permissionModel.Permission = permission
|
|
||||||
err = db.Create(permissionModel).Error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
permissionModel, err = migrate.Permission(db, menuName, permission, label)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +129,7 @@ func checkModel(opts *options, model *rest.Model) (err error) {
|
||||||
modelValue := reflect.New(model.Value().Type()).Interface()
|
modelValue := reflect.New(model.Value().Type()).Interface()
|
||||||
if v, ok := modelValue.(adminTypes.PerrmissionModule); ok {
|
if v, ok := modelValue.(adminTypes.PerrmissionModule); ok {
|
||||||
for k, v := range v.ModelPermissions() {
|
for k, v := range v.ModelPermissions() {
|
||||||
if _, err = replaceModelPermission(tx, menuModel.Name, k, v); err != nil {
|
if _, err = migrate.Permission(tx, menuModel.Name, k, v); err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -287,7 +268,6 @@ func AutoMigrate(ctx context.Context, db *gorm.DB, model any, cbs ...Option) (er
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
|
func registerRESTRoute(domain string, db *gorm.DB, hs *http.Server) {
|
||||||
|
|
||||||
handleListSchemas := func(ctx *http.Context) (err error) {
|
handleListSchemas := func(ctx *http.Context) (err error) {
|
||||||
var (
|
var (
|
||||||
schemas []*restTypes.Schema
|
schemas []*restTypes.Schema
|
||||||
|
@ -390,7 +370,7 @@ func Init(ctx context.Context, cbs ...Option) (err error) {
|
||||||
registerRESTRoute(opts.domain, opts.db, opts.httpServer)
|
registerRESTRoute(opts.domain, opts.db, opts.httpServer)
|
||||||
}
|
}
|
||||||
if !opts.disableDefault {
|
if !opts.disableDefault {
|
||||||
if err = defaults.Generate(opts.db); err != nil {
|
if err = migrate.Default(opts.db); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,5 +378,8 @@ func Init(ctx context.Context, cbs ...Option) (err error) {
|
||||||
//启用操作记录
|
//启用操作记录
|
||||||
NewActivityRecorder(ctx, opts.db).Recoder()
|
NewActivityRecorder(ctx, opts.db).Recoder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//注册渲染器
|
||||||
|
NewFormatter(opts.db).Register()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
@ -20,6 +23,19 @@ type (
|
||||||
secret []byte
|
secret []byte
|
||||||
method string
|
method string
|
||||||
ttl int64
|
ttl int64
|
||||||
|
turnstileValidateUrl string
|
||||||
|
turnstileSiteKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
turnstileRequest struct {
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
Response string `json:"response"`
|
||||||
|
}
|
||||||
|
turnstileResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
ErrorCodes []string `json:"error-codes"`
|
||||||
|
Action string `json:"action"`
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthOption func(o *authOptions)
|
AuthOption func(o *authOptions)
|
||||||
|
@ -41,6 +57,16 @@ func WithAuthSecret(secret []byte) AuthOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithAuthTranslate(key, url string) AuthOption {
|
||||||
|
return func(o *authOptions) {
|
||||||
|
o.turnstileSiteKey = key
|
||||||
|
if url == "" {
|
||||||
|
url = "https://challenges.cloudflare.com/turnstile/v0/siteverify"
|
||||||
|
}
|
||||||
|
o.turnstileValidateUrl = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithAuthMethod(method string) AuthOption {
|
func WithAuthMethod(method string) AuthOption {
|
||||||
return func(o *authOptions) {
|
return func(o *authOptions) {
|
||||||
o.method = method
|
o.method = method
|
||||||
|
@ -53,12 +79,56 @@ func WithAuthTTL(ttl int64) AuthOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *AuthService) turnstileValidate(ctx context.Context, token string) (err error) {
|
||||||
|
var (
|
||||||
|
buf []byte
|
||||||
|
req *http.Request
|
||||||
|
res *http.Response
|
||||||
|
)
|
||||||
|
if s.opts.turnstileSiteKey == "" || s.opts.turnstileValidateUrl == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
payload := &turnstileRequest{
|
||||||
|
Secret: s.opts.turnstileSiteKey,
|
||||||
|
Response: token,
|
||||||
|
}
|
||||||
|
if buf, err = json.Marshal(payload); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req, err = http.NewRequestWithContext(ctx, http.MethodPost, s.opts.turnstileValidateUrl, bytes.NewReader(buf)); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
if res, err = http.DefaultClient.Do(req); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return errors.Format(errors.Unavailable, "turnstile validate failed")
|
||||||
|
}
|
||||||
|
result := &turnstileResponse{}
|
||||||
|
if err = json.NewDecoder(res.Body).Decode(result); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !result.Success {
|
||||||
|
if len(result.ErrorCodes) == 0 {
|
||||||
|
err = errors.Format(errors.Unavailable, "turnstile validate failed")
|
||||||
|
} else {
|
||||||
|
err = errors.Format(errors.Unavailable, result.ErrorCodes[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.LoginResponse, err error) {
|
func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.LoginResponse, err error) {
|
||||||
model := &models.User{}
|
model := &models.User{}
|
||||||
tx := s.opts.db.WithContext(ctx)
|
tx := s.opts.db.WithContext(ctx)
|
||||||
if err = req.Validate(); err != nil {
|
if err = req.Validate(); err != nil {
|
||||||
return nil, errors.Format(errors.Invalid, err.Error())
|
return nil, errors.Format(errors.Invalid, err.Error())
|
||||||
}
|
}
|
||||||
|
if err = s.turnstileValidate(ctx, req.Token); err != nil {
|
||||||
|
return nil, errors.Format(errors.Invalid, err.Error())
|
||||||
|
}
|
||||||
if err = model.FindOne(tx, "uid=?", req.Username); err != nil {
|
if err = model.FindOne(tx, "uid=?", req.Username); err != nil {
|
||||||
return nil, errors.ErrAccessDenied
|
return nil, errors.ErrAccessDenied
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,12 @@ package service
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/internal/logic"
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
"git.nobla.cn/golang/aeus-admin/pb"
|
"git.nobla.cn/golang/aeus-admin/pb"
|
||||||
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
"git.nobla.cn/golang/rest/types"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,6 +20,8 @@ type (
|
||||||
|
|
||||||
DepartmentService struct {
|
DepartmentService struct {
|
||||||
opts *departmentOptions
|
opts *departmentOptions
|
||||||
|
logic *logic.Department
|
||||||
|
user *logic.User
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,24 +33,87 @@ func WithDepartmentDB(db *gorm.DB) DepartmentOption {
|
||||||
|
|
||||||
func (s *DepartmentService) GetDepartmentLabels(ctx context.Context, req *pb.GetDepartmentLabelRequest) (res *pb.GetDepartmentLabelResponse, err error) {
|
func (s *DepartmentService) GetDepartmentLabels(ctx context.Context, req *pb.GetDepartmentLabelRequest) (res *pb.GetDepartmentLabelResponse, err error) {
|
||||||
res = &pb.GetDepartmentLabelResponse{}
|
res = &pb.GetDepartmentLabelResponse{}
|
||||||
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("department:labels"), func(tx *gorm.DB) ([]*pb.DepartmentLabelValue, error) {
|
var values []*types.TypeValue[int64]
|
||||||
values := make([]*models.Department, 0)
|
if values, err = s.logic.GetLabels(ctx); err == nil {
|
||||||
if err = tx.Find(&values).Error; err == nil {
|
res.Data = make([]*pb.DepartmentLabelValue, 0, len(values))
|
||||||
items := make([]*pb.DepartmentLabelValue, 0, len(values))
|
for _, row := range values {
|
||||||
for _, v := range values {
|
res.Data = append(res.Data, &pb.DepartmentLabelValue{
|
||||||
items = append(items, &pb.DepartmentLabelValue{
|
Label: row.Label,
|
||||||
Label: v.Name,
|
Value: row.Value,
|
||||||
Value: v.Id,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return items, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
},
|
return
|
||||||
dbcache.WithDB(s.opts.db),
|
}
|
||||||
dbcache.WithDependency(dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM departments")),
|
|
||||||
|
func (s *DepartmentService) recursiveDepartmentUser(parent int64, departments []*models.Department, users []*models.User) []*pb.DepartmentUserValue {
|
||||||
|
values := make([]*pb.DepartmentUserValue, 0, len(departments))
|
||||||
|
for _, row := range departments {
|
||||||
|
if row.ParentId == parent {
|
||||||
|
item := &pb.DepartmentUserValue{
|
||||||
|
Label: row.Name,
|
||||||
|
Value: strconv.FormatInt(row.Id, 10),
|
||||||
|
Children: make([]*pb.DepartmentUserValue, 0),
|
||||||
|
}
|
||||||
|
item.Children = append(item.Children, s.recursiveDepartmentUser(row.Id, departments, users)...)
|
||||||
|
for _, v := range users {
|
||||||
|
if v.DeptId == row.Id {
|
||||||
|
item.Children = append(item.Children, &pb.DepartmentUserValue{
|
||||||
|
Label: fmt.Sprintf("%s(%s)", v.Username, v.Uid),
|
||||||
|
Value: v.Uid,
|
||||||
|
Isuser: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values = append(values, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DepartmentService) recursiveDepartmentLevel(parent int64, departments []*models.Department) []*pb.DepartmentLevelValue {
|
||||||
|
values := make([]*pb.DepartmentLevelValue, 0, len(departments))
|
||||||
|
for _, row := range departments {
|
||||||
|
if row.ParentId == parent {
|
||||||
|
item := &pb.DepartmentLevelValue{
|
||||||
|
Label: row.Name,
|
||||||
|
Value: row.Id,
|
||||||
|
Children: make([]*pb.DepartmentLevelValue, 0),
|
||||||
|
}
|
||||||
|
item.Children = append(item.Children, s.recursiveDepartmentLevel(row.Id, departments)...)
|
||||||
|
values = append(values, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DepartmentService) GetDepartmentUsers(ctx context.Context, req *pb.GetDepartmentUserRequest) (res *pb.GetDepartmentUserResponse, err error) {
|
||||||
|
var (
|
||||||
|
users []*models.User
|
||||||
|
departments []*models.Department
|
||||||
)
|
)
|
||||||
|
if departments, err = s.logic.GetDepartments(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if users, err = s.user.GeUsers(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res = &pb.GetDepartmentUserResponse{
|
||||||
|
Data: s.recursiveDepartmentUser(0, departments, users),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DepartmentService) GetDepartmentLevelLabels(ctx context.Context, req *pb.GetDepartmentLevelLabelsRequest) (res *pb.GetDepartmentLevelLabelsResponse, err error) {
|
||||||
|
var (
|
||||||
|
departments []*models.Department
|
||||||
|
)
|
||||||
|
if departments, err = s.logic.GetDepartments(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res = &pb.GetDepartmentLevelLabelsResponse{
|
||||||
|
Data: s.recursiveDepartmentLevel(0, departments),
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,5 +124,7 @@ func NewDepartmentService(cbs ...DepartmentOption) *DepartmentService {
|
||||||
}
|
}
|
||||||
return &DepartmentService{
|
return &DepartmentService{
|
||||||
opts: opts,
|
opts: opts,
|
||||||
|
user: logic.NewUserLogic(opts.db),
|
||||||
|
logic: logic.NewDepartmentLogic(opts.db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/internal/logic"
|
||||||
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
|
"git.nobla.cn/golang/aeus-admin/pb"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
menuOptions struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
MenuOption func(o *menuOptions)
|
||||||
|
|
||||||
|
MenuService struct {
|
||||||
|
opts *menuOptions
|
||||||
|
logic *logic.Menu
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithMenuDB(db *gorm.DB) MenuOption {
|
||||||
|
return func(o *menuOptions) {
|
||||||
|
o.db = db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MenuService) recursiveMenuLevel(parent string, items []*models.Menu) []*pb.MenuLevelValue {
|
||||||
|
values := make([]*pb.MenuLevelValue, 0, len(items))
|
||||||
|
for _, row := range items {
|
||||||
|
if row.Parent == parent {
|
||||||
|
item := &pb.MenuLevelValue{
|
||||||
|
Label: row.Label,
|
||||||
|
Value: row.Name,
|
||||||
|
Children: make([]*pb.MenuLevelValue, 0),
|
||||||
|
}
|
||||||
|
item.Children = append(item.Children, s.recursiveMenuLevel(row.Name, items)...)
|
||||||
|
values = append(values, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MenuService) GetMenuLevelLabels(ctx context.Context, req *pb.GetMenuLevelLabelsRequest) (res *pb.GetMenuLevelLabelsResponse, err error) {
|
||||||
|
var (
|
||||||
|
items []*models.Menu
|
||||||
|
)
|
||||||
|
if items, err = s.logic.GetMenus(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res = &pb.GetMenuLevelLabelsResponse{
|
||||||
|
Data: s.recursiveMenuLevel("", items),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMenuService(cbs ...MenuOption) *MenuService {
|
||||||
|
opts := &menuOptions{}
|
||||||
|
for _, cb := range cbs {
|
||||||
|
cb(opts)
|
||||||
|
}
|
||||||
|
return &MenuService{
|
||||||
|
opts: opts,
|
||||||
|
logic: logic.NewMenuLogic(opts.db),
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,11 +2,11 @@ package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/internal/logic"
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
"git.nobla.cn/golang/aeus-admin/pb"
|
"git.nobla.cn/golang/aeus-admin/pb"
|
||||||
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
"git.nobla.cn/golang/rest/types"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ type (
|
||||||
|
|
||||||
RoleService struct {
|
RoleService struct {
|
||||||
opts *roleOptions
|
opts *roleOptions
|
||||||
|
logic *logic.Role
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,24 +30,16 @@ func WithRoleDB(db *gorm.DB) RoleOption {
|
||||||
|
|
||||||
func (s *RoleService) GetRoleLabels(ctx context.Context, req *pb.GetRoleLabelRequest) (res *pb.GetRoleLabelResponse, err error) {
|
func (s *RoleService) GetRoleLabels(ctx context.Context, req *pb.GetRoleLabelRequest) (res *pb.GetRoleLabelResponse, err error) {
|
||||||
res = &pb.GetRoleLabelResponse{}
|
res = &pb.GetRoleLabelResponse{}
|
||||||
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("role:labels"), func(tx *gorm.DB) ([]*pb.LabelValue, error) {
|
var values []*types.TypeValue[string]
|
||||||
values := make([]*models.Role, 0)
|
if values, err = s.logic.GetLabels(ctx); err == nil {
|
||||||
if err = tx.Find(&values).Error; err == nil {
|
res.Data = make([]*pb.LabelValue, 0, len(values))
|
||||||
items := make([]*pb.LabelValue, 0, len(values))
|
for _, row := range values {
|
||||||
for _, v := range values {
|
res.Data = append(res.Data, &pb.LabelValue{
|
||||||
items = append(items, &pb.LabelValue{
|
Label: row.Label,
|
||||||
Label: v.Label,
|
Value: row.Value,
|
||||||
Value: v.Name,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return items, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
dbcache.WithDB(s.opts.db),
|
|
||||||
dbcache.WithDependency(dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM roles")),
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,5 +83,6 @@ func NewRoleService(cbs ...RoleOption) *RoleService {
|
||||||
}
|
}
|
||||||
return &RoleService{
|
return &RoleService{
|
||||||
opts: opts,
|
opts: opts,
|
||||||
|
logic: logic.NewRoleLogic(opts.db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
108
service/user.go
108
service/user.go
|
@ -3,13 +3,16 @@ package service
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.nobla.cn/golang/aeus-admin/internal/logic"
|
||||||
"git.nobla.cn/golang/aeus-admin/models"
|
"git.nobla.cn/golang/aeus-admin/models"
|
||||||
"git.nobla.cn/golang/aeus-admin/pb"
|
"git.nobla.cn/golang/aeus-admin/pb"
|
||||||
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
||||||
"git.nobla.cn/golang/aeus/middleware/auth"
|
"git.nobla.cn/golang/aeus/middleware/auth"
|
||||||
"git.nobla.cn/golang/aeus/pkg/errors"
|
"git.nobla.cn/golang/aeus/pkg/errors"
|
||||||
|
"git.nobla.cn/golang/rest/types"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +24,10 @@ type (
|
||||||
UserOption func(o *userOptions)
|
UserOption func(o *userOptions)
|
||||||
|
|
||||||
UserService struct {
|
UserService struct {
|
||||||
|
user *logic.User
|
||||||
|
menu *logic.Menu
|
||||||
|
role *logic.Role
|
||||||
|
department *logic.Department
|
||||||
opts *userOptions
|
opts *userOptions
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -87,12 +94,6 @@ func (s *UserService) recursiveNestedMenu(ctx context.Context, parent string, pe
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserService) getRolePermissions(db *gorm.DB, role string) (permissions []*models.Permission, err error) {
|
|
||||||
permissions = make([]*models.Permission, 0)
|
|
||||||
err = db.Where("permission IN (SELECT permission FROM role_permissions WHERE role = ?)", role).Find(&permissions).Error
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *UserService) GetMenus(ctx context.Context, req *pb.GetMenuRequest) (res *pb.GetMenuResponse, err error) {
|
func (s *UserService) GetMenus(ctx context.Context, req *pb.GetMenuRequest) (res *pb.GetMenuResponse, err error) {
|
||||||
var (
|
var (
|
||||||
uid string
|
uid string
|
||||||
|
@ -103,28 +104,28 @@ func (s *UserService) GetMenus(ctx context.Context, req *pb.GetMenuRequest) (res
|
||||||
}
|
}
|
||||||
res = &pb.GetMenuResponse{}
|
res = &pb.GetMenuResponse{}
|
||||||
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:%v", uid, req.Permission), func(tx *gorm.DB) ([]*pb.MenuItem, error) {
|
||||||
userModel := &models.User{}
|
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=?", uid).First(userModel).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
items := make([]*models.Menu, 0)
|
if menus, err = s.menu.GetMenus(ctx); err != nil {
|
||||||
if err = tx.Find(&items).Error; err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
roleName := userModel.Role
|
||||||
if userModel.Admin {
|
if userModel.Admin {
|
||||||
permissions = make([]*models.Permission, 0)
|
roleName = ""
|
||||||
if err = tx.Find(&permissions).Error; err != nil {
|
}
|
||||||
|
if permissions, err = s.role.GetPermissions(ctx, roleName); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
return s.recursiveNestedMenu(ctx, "", req.Permission, menus, permissions), nil
|
||||||
if permissions, err = s.getRolePermissions(tx, userModel.Role); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s.recursiveNestedMenu(ctx, "", req.Permission, items, permissions), nil
|
|
||||||
},
|
},
|
||||||
dbcache.WithDB(s.opts.db),
|
dbcache.WithDB(s.opts.db),
|
||||||
dbcache.WithDependency(dbcache.NewSqlDependency("SELECT `updated_at` FROM users WHERE `uid`=?", uid)),
|
dbcache.WithCacheDuration(time.Second*10),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -145,7 +146,6 @@ func (s *UserService) GetProfile(ctx context.Context, req *pb.GetProfileRequest)
|
||||||
},
|
},
|
||||||
dbcache.WithDB(s.opts.db),
|
dbcache.WithDB(s.opts.db),
|
||||||
dbcache.WithDependency(dbcache.NewSqlDependency("SELECT `updated_at` FROM users WHERE `uid`=?", req.Uid)),
|
dbcache.WithDependency(dbcache.NewSqlDependency("SELECT `updated_at` FROM users WHERE `uid`=?", req.Uid)),
|
||||||
// dbcache.WithDepend("SELECT `updated_at` FROM users WHERE `uid`=?", req.Uid),
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -213,41 +213,59 @@ func (s *UserService) GetPermissions(ctx context.Context, req *pb.GetPermissionR
|
||||||
res = &pb.GetPermissionResponse{
|
res = &pb.GetPermissionResponse{
|
||||||
Uid: req.Uid,
|
Uid: req.Uid,
|
||||||
}
|
}
|
||||||
res.Permissions, err = dbcache.TryCache(ctx, fmt.Sprintf("user:permissions:%s", req.Uid), func(tx *gorm.DB) ([]string, error) {
|
res.Permissions, err = s.user.GetPermissions(ctx, req.Uid)
|
||||||
var ss []string
|
|
||||||
err = tx.Select("permission").Model(&models.RolePermission{}).
|
|
||||||
Joins("LEFT JOIN users on users.role = role_permissions.role").
|
|
||||||
Where("users.uid = ?", req.Uid).
|
|
||||||
Pluck("permission", &ss).
|
|
||||||
Error
|
|
||||||
return ss, err
|
|
||||||
}, dbcache.WithCacheDuration(time.Minute), dbcache.WithDB(s.opts.db))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserService) GetUserLabels(ctx context.Context, req *pb.GetUserLabelRequest) (res *pb.GetUserLabelResponse, err error) {
|
func (s *UserService) GetUserLabels(ctx context.Context, req *pb.GetUserLabelRequest) (res *pb.GetUserLabelResponse, err error) {
|
||||||
res = &pb.GetUserLabelResponse{}
|
res = &pb.GetUserLabelResponse{}
|
||||||
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:labels"), func(tx *gorm.DB) ([]*pb.LabelValue, error) {
|
var values []*types.TypeValue[string]
|
||||||
values := make([]*models.User, 0)
|
if values, err = s.user.GetLabels(ctx); err == nil {
|
||||||
if err = tx.Find(&values).Error; err == nil {
|
res.Data = make([]*pb.LabelValue, 0, len(values))
|
||||||
items := make([]*pb.LabelValue, 0, len(values))
|
for _, row := range values {
|
||||||
for _, v := range values {
|
res.Data = append(res.Data, &pb.LabelValue{
|
||||||
items = append(items, &pb.LabelValue{
|
Label: row.Label,
|
||||||
Label: v.Username,
|
Value: row.Value,
|
||||||
Value: v.Uid,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return items, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
dbcache.WithDB(s.opts.db),
|
|
||||||
dbcache.WithDependency(dbcache.NewSqlDependency("SELECT MAX(`updated_at`) FROM users")),
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *UserService) DepartmentUserNested(ctx context.Context) []*types.NestedValue[string] {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
users []*models.User
|
||||||
|
departments []*models.Department
|
||||||
|
)
|
||||||
|
|
||||||
|
if departments, err = s.department.GetDepartments(ctx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if users, err = s.user.GeUsers(ctx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
depts := s.department.RecursiveDepartment(ctx, 0, 0, departments)
|
||||||
|
values := make([]*types.NestedValue[string], 0)
|
||||||
|
for _, dept := range depts {
|
||||||
|
v := &types.NestedValue[string]{
|
||||||
|
Label: dept.Label,
|
||||||
|
Value: strconv.FormatInt(dept.Value, 10),
|
||||||
|
Children: make([]*types.NestedValue[string], 0),
|
||||||
|
}
|
||||||
|
for _, user := range users {
|
||||||
|
if strconv.FormatInt(user.DeptId, 10) == v.Value {
|
||||||
|
v.Children = append(v.Children, &types.NestedValue[string]{
|
||||||
|
Label: fmt.Sprintf("%s(%s)", user.Username, user.Uid),
|
||||||
|
Value: user.Uid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values = append(values, v)
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
func (s *UserService) GetUserTags(ctx context.Context, req *pb.GetUserTagRequest) (res *pb.GetUserTagResponse, err error) {
|
func (s *UserService) GetUserTags(ctx context.Context, req *pb.GetUserTagRequest) (res *pb.GetUserTagResponse, err error) {
|
||||||
res = &pb.GetUserTagResponse{}
|
res = &pb.GetUserTagResponse{}
|
||||||
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:tags"), func(tx *gorm.DB) ([]*pb.LabelValue, error) {
|
res.Data, err = dbcache.TryCache(ctx, fmt.Sprintf("user:tags"), func(tx *gorm.DB) ([]*pb.LabelValue, error) {
|
||||||
|
@ -281,5 +299,9 @@ func NewUserService(cbs ...UserOption) *UserService {
|
||||||
}
|
}
|
||||||
return &UserService{
|
return &UserService{
|
||||||
opts: opts,
|
opts: opts,
|
||||||
|
user: logic.NewUserLogic(opts.db),
|
||||||
|
role: logic.NewRoleLogic(opts.db),
|
||||||
|
menu: logic.NewMenuLogic(opts.db),
|
||||||
|
department: logic.NewDepartmentLogic(opts.db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue