432 lines
19 KiB
Go
432 lines
19 KiB
Go
package data
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
|
|
"kra/internal/biz"
|
|
|
|
"github.com/google/uuid"
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type userPO struct {
|
|
ID uint `gorm:"primaryKey"`
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
UUID string `gorm:"type:char(36);uniqueIndex"`
|
|
Username string `gorm:"index;uniqueIndex"`
|
|
Password string
|
|
NickName string `gorm:"column:nick_name"`
|
|
HeaderImg string `gorm:"column:header_img"`
|
|
AuthorityID uint `gorm:"column:authority_id"`
|
|
DeptID uint `gorm:"column:dept_id"`
|
|
Phone string
|
|
Email string
|
|
Enable int `gorm:"default:1"`
|
|
OriginSetting string `gorm:"type:text"`
|
|
PasswordUpdatedAt *time.Time
|
|
MustChangePassword bool
|
|
}
|
|
|
|
func (userPO) TableName() string { return "sys_users" }
|
|
|
|
type authorityPO struct {
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
AuthorityID uint `gorm:"primaryKey;column:authority_id"`
|
|
AuthorityName string
|
|
ParentID *uint
|
|
DataScope int `gorm:"default:1"`
|
|
DefaultRouter string `gorm:"default:dashboard"`
|
|
}
|
|
|
|
func (authorityPO) TableName() string { return "sys_authorities" }
|
|
|
|
type menuPO struct {
|
|
ID uint `gorm:"primaryKey"`
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
MenuLevel uint
|
|
ParentID uint `gorm:"column:parent_id"`
|
|
Path string
|
|
Name string
|
|
Hidden bool
|
|
Component string
|
|
Sort int
|
|
ActiveName string
|
|
KeepAlive bool
|
|
DefaultMenu bool
|
|
Title string
|
|
Icon string
|
|
CloseTab bool
|
|
TransitionType string
|
|
}
|
|
|
|
func (menuPO) TableName() string { return "sys_base_menus" }
|
|
|
|
type userAuthorityPO struct {
|
|
SysUserID uint `gorm:"primaryKey;column:sys_user_id"`
|
|
SysAuthorityAuthorityID uint `gorm:"primaryKey;column:sys_authority_authority_id"`
|
|
}
|
|
|
|
func (userAuthorityPO) TableName() string { return "sys_user_authority" }
|
|
|
|
type authorityMenuPO struct {
|
|
SysAuthorityAuthorityID uint `gorm:"primaryKey;column:sys_authority_authority_id"`
|
|
SysBaseMenuID uint `gorm:"primaryKey;column:sys_base_menu_id"`
|
|
}
|
|
|
|
func (authorityMenuPO) TableName() string { return "sys_authority_menus" }
|
|
|
|
type systemRepo struct{ data *Data }
|
|
|
|
func NewSystemRepo(data *Data) biz.SystemRepo { return &systemRepo{data: data} }
|
|
|
|
func (r *systemRepo) IsInitialized(ctx context.Context) (bool, error) {
|
|
return r.data.gormDB.WithContext(ctx).Migrator().HasTable(&userPO{}), nil
|
|
}
|
|
|
|
func (r *systemRepo) Initialize(ctx context.Context) error {
|
|
db := r.data.gormDB.WithContext(ctx)
|
|
if err := db.AutoMigrate(&userPO{}, &authorityPO{}, &menuPO{}, &userAuthorityPO{}, &authorityMenuPO{}, &apiPO{}, &ignoredAPIPO{}, &authorityAPIPO{}, &menuButtonPO{}, &authorityButtonPO{}, &departmentPO{}, &positionPO{}, &userDepartmentPO{}, &userPositionPO{}, &authorityDepartmentPO{}, &dictionaryPO{}, &dictionaryDetailPO{}, ¶meterPO{}, &apiTokenPO{}, &securityConfigPO{}, &versionPO{}, &exportTemplatePO{}, &exportConditionPO{}, &exportJoinPO{}, &operationPO{}, &loginLogPO{}, &dataAccessLogPO{}, &errorRecordPO{}, &taskPO{}, &taskLogPO{}, &mediaPO{}, &categoryPO{}, &uploadSessionPO{}, &uploadChunkPO{}, &announcementPO{}); err != nil {
|
|
return err
|
|
}
|
|
return db.Transaction(func(tx *gorm.DB) error {
|
|
authority := authorityPO{AuthorityID: 888, AuthorityName: "超级管理员", DataScope: 1, DefaultRouter: "dashboard"}
|
|
if err := tx.FirstOrCreate(&authority, authorityPO{AuthorityID: 888}).Error; err != nil {
|
|
return err
|
|
}
|
|
menus := defaultMenus()
|
|
for i := range menus {
|
|
if err := tx.Where("name = ?", menus[i].Name).FirstOrCreate(&menus[i]).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
var persisted []menuPO
|
|
if err := tx.Order("sort asc, id asc").Find(&persisted).Error; err != nil {
|
|
return err
|
|
}
|
|
nameID := make(map[string]uint, len(persisted))
|
|
for _, menu := range persisted {
|
|
nameID[menu.Name] = menu.ID
|
|
}
|
|
for i := range menus {
|
|
if menus[i].ParentID == 0 || menus[i].ActiveName == "" {
|
|
continue
|
|
}
|
|
_ = tx.Model(&menuPO{}).Where("name = ?", menus[i].Name).Updates(map[string]any{"parent_id": nameID[menus[i].ActiveName], "active_name": ""}).Error
|
|
}
|
|
if err := tx.Where("sys_authority_authority_id = ?", 888).Delete(&authorityMenuPO{}).Error; err != nil {
|
|
return err
|
|
}
|
|
links := make([]authorityMenuPO, 0, len(persisted))
|
|
for _, menu := range persisted {
|
|
links = append(links, authorityMenuPO{SysAuthorityAuthorityID: 888, SysBaseMenuID: menu.ID})
|
|
}
|
|
if len(links) > 0 {
|
|
if err := tx.Create(&links).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
var count int64
|
|
if err := tx.Model(&userPO{}).Where("username = ?", "admin").Count(&count).Error; err != nil {
|
|
return err
|
|
}
|
|
if count == 0 {
|
|
hash, err := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
now := time.Now()
|
|
user := userPO{UUID: uuid.NewString(), Username: "admin", Password: string(hash), NickName: "超级管理员", AuthorityID: 888, Enable: 1, PasswordUpdatedAt: &now}
|
|
if err := tx.Create(&user).Error; err != nil {
|
|
return err
|
|
}
|
|
if err := tx.Create(&userAuthorityPO{SysUserID: user.ID, SysAuthorityAuthorityID: 888}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *systemRepo) FindUserByUsername(ctx context.Context, username string) (*biz.User, error) {
|
|
var po userPO
|
|
if err := r.data.gormDB.WithContext(ctx).Where("username = ?", username).First(&po).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, biz.ErrAdminNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return r.toBizUser(ctx, &po)
|
|
}
|
|
|
|
func (r *systemRepo) FindUserByID(ctx context.Context, id uint) (*biz.User, error) {
|
|
var po userPO
|
|
if err := r.data.gormDB.WithContext(ctx).First(&po, id).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, biz.ErrAdminNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return r.toBizUser(ctx, &po)
|
|
}
|
|
|
|
func (r *systemRepo) toBizUser(ctx context.Context, po *userPO) (*biz.User, error) {
|
|
var authority authorityPO
|
|
if err := r.data.gormDB.WithContext(ctx).First(&authority, "authority_id = ?", po.AuthorityID).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
var authorityPOs []authorityPO
|
|
if err := r.data.gormDB.WithContext(ctx).Table("sys_authorities").Joins("JOIN sys_user_authority ON sys_user_authority.sys_authority_authority_id = sys_authorities.authority_id").Where("sys_user_authority.sys_user_id = ? AND sys_authorities.deleted_at IS NULL", po.ID).Find(&authorityPOs).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
authorities := make([]biz.Authority, 0, len(authorityPOs))
|
|
for _, item := range authorityPOs {
|
|
authorities = append(authorities, toBizAuthority(item))
|
|
}
|
|
setting := map[string]any(nil)
|
|
if po.OriginSetting != "" {
|
|
_ = json.Unmarshal([]byte(po.OriginSetting), &setting)
|
|
}
|
|
var departmentPOs []departmentPO
|
|
if err := r.data.gormDB.WithContext(ctx).Table("sys_departments").Joins("JOIN sys_user_departments ON sys_user_departments.sys_department_id = sys_departments.id").Where("sys_user_departments.sys_user_id = ? AND sys_departments.deleted_at IS NULL", po.ID).Find(&departmentPOs).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
departments := make([]biz.Department, 0, len(departmentPOs))
|
|
var primary *biz.Department
|
|
for _, item := range departmentPOs {
|
|
value := deptFromPO(item)
|
|
departments = append(departments, *value)
|
|
if item.ID == po.DeptID {
|
|
copy := *value
|
|
primary = ©
|
|
}
|
|
}
|
|
var positionPOs []positionPO
|
|
if err := r.data.gormDB.WithContext(ctx).Table("sys_positions").Joins("JOIN sys_user_positions ON sys_user_positions.sys_position_id = sys_positions.id").Where("sys_user_positions.sys_user_id = ? AND sys_positions.deleted_at IS NULL", po.ID).Find(&positionPOs).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
positions := make([]biz.Position, 0, len(positionPOs))
|
|
for _, item := range positionPOs {
|
|
positions = append(positions, *posFromPO(item))
|
|
}
|
|
return &biz.User{ID: po.ID, CreatedAt: po.CreatedAt, UpdatedAt: po.UpdatedAt, UUID: po.UUID, Username: po.Username, Password: po.Password, NickName: po.NickName, HeaderImg: po.HeaderImg, AuthorityID: po.AuthorityID, Authority: toBizAuthority(authority), Authorities: authorities, DeptID: po.DeptID, Department: primary, Departments: departments, Positions: positions, Phone: po.Phone, Email: po.Email, Enable: po.Enable, OriginSetting: setting, MustChangePassword: po.MustChangePassword, PasswordUpdatedAt: po.PasswordUpdatedAt}, nil
|
|
}
|
|
|
|
func toBizAuthority(po authorityPO) biz.Authority {
|
|
return biz.Authority{AuthorityID: po.AuthorityID, AuthorityName: po.AuthorityName, ParentID: po.ParentID, DataScope: po.DataScope, DefaultRouter: po.DefaultRouter}
|
|
}
|
|
|
|
func (r *systemRepo) MenusByAuthority(ctx context.Context, authorityID uint) ([]*biz.Menu, error) {
|
|
var pos []menuPO
|
|
err := r.data.gormDB.WithContext(ctx).Table("sys_base_menus").
|
|
Joins("JOIN sys_authority_menus ON sys_authority_menus.sys_base_menu_id = sys_base_menus.id").
|
|
Where("sys_authority_menus.sys_authority_authority_id = ? AND sys_base_menus.deleted_at IS NULL", authorityID).
|
|
Order("sys_base_menus.sort asc, sys_base_menus.id asc").Scan(&pos).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
byID := make(map[uint]*biz.Menu, len(pos))
|
|
for _, po := range pos {
|
|
byID[po.ID] = &biz.Menu{ID: po.ID, ParentID: po.ParentID, Path: po.Path, Name: po.Name, Hidden: po.Hidden, Component: po.Component, Sort: po.Sort, ActiveName: po.ActiveName, KeepAlive: po.KeepAlive, DefaultMenu: po.DefaultMenu, Title: po.Title, Icon: po.Icon, CloseTab: po.CloseTab, TransitionType: po.TransitionType, Children: []*biz.Menu{}}
|
|
}
|
|
roots := make([]*biz.Menu, 0)
|
|
for _, po := range pos {
|
|
menu := byID[po.ID]
|
|
if parent := byID[po.ParentID]; parent != nil {
|
|
parent.Children = append(parent.Children, menu)
|
|
} else {
|
|
roots = append(roots, menu)
|
|
}
|
|
}
|
|
return roots, nil
|
|
}
|
|
|
|
func (r *systemRepo) ListUsers(ctx context.Context, page, pageSize int, filter *biz.UserListFilter) ([]*biz.User, int64, error) {
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if pageSize < 1 {
|
|
pageSize = 10
|
|
}
|
|
db := r.data.gormDB.WithContext(ctx).Model(&userPO{})
|
|
if scope, ok := biz.DataScopeFromContext(ctx); ok && !scope.All {
|
|
if scope.OwnerUserID != 0 {
|
|
db = db.Where("sys_users.id = ?", scope.OwnerUserID)
|
|
} else if len(scope.DepartmentIDs) > 0 {
|
|
db = db.Joins("JOIN sys_user_departments ON sys_user_departments.sys_user_id = sys_users.id").Where("sys_user_departments.sys_department_id IN ?", scope.DepartmentIDs).Distinct("sys_users.id")
|
|
} else {
|
|
db = db.Where("1 = 0")
|
|
}
|
|
}
|
|
order := "id desc"
|
|
if filter != nil {
|
|
if filter.Username != "" {
|
|
db = db.Where("username LIKE ?", "%"+filter.Username+"%")
|
|
}
|
|
if filter.NickName != "" {
|
|
db = db.Where("nick_name LIKE ?", "%"+filter.NickName+"%")
|
|
}
|
|
if filter.Phone != "" {
|
|
db = db.Where("phone LIKE ?", "%"+filter.Phone+"%")
|
|
}
|
|
if filter.Email != "" {
|
|
db = db.Where("email LIKE ?", "%"+filter.Email+"%")
|
|
}
|
|
allowed := map[string]bool{"id": true, "username": true, "nick_name": true, "phone": true, "email": true, "created_at": true}
|
|
if allowed[filter.OrderKey] {
|
|
order = filter.OrderKey
|
|
if filter.Desc {
|
|
order += " desc"
|
|
}
|
|
}
|
|
}
|
|
var total int64
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
var pos []userPO
|
|
if err := db.Order(order).Offset((page - 1) * pageSize).Limit(pageSize).Find(&pos).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
users := make([]*biz.User, 0, len(pos))
|
|
for i := range pos {
|
|
user, err := r.toBizUser(ctx, &pos[i])
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
users = append(users, user)
|
|
}
|
|
return users, total, nil
|
|
}
|
|
|
|
func (r *systemRepo) CreateUser(ctx context.Context, user *biz.User) (*biz.User, error) {
|
|
if user.UUID == "" {
|
|
user.UUID = uuid.NewString()
|
|
}
|
|
if user.Enable == 0 {
|
|
user.Enable = 1
|
|
}
|
|
if user.AuthorityID == 0 {
|
|
user.AuthorityID = 888
|
|
}
|
|
if user.NickName == "" {
|
|
user.NickName = "系统用户"
|
|
}
|
|
now := time.Now()
|
|
po := userPO{UUID: user.UUID, Username: user.Username, Password: user.Password, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Phone: user.Phone, Email: user.Email, Enable: user.Enable, PasswordUpdatedAt: &now, MustChangePassword: user.MustChangePassword}
|
|
if err := r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Create(&po).Error; err != nil {
|
|
return err
|
|
}
|
|
return tx.Create(&userAuthorityPO{SysUserID: po.ID, SysAuthorityAuthorityID: po.AuthorityID}).Error
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
return r.FindUserByID(ctx, po.ID)
|
|
}
|
|
|
|
func (r *systemRepo) UpdateUser(ctx context.Context, user *biz.User) error {
|
|
updates := map[string]any{"nick_name": user.NickName, "header_img": user.HeaderImg, "phone": user.Phone, "email": user.Email, "enable": user.Enable}
|
|
if user.AuthorityID != 0 {
|
|
updates["authority_id"] = user.AuthorityID
|
|
}
|
|
return r.data.gormDB.WithContext(ctx).Model(&userPO{}).Where("id = ?", user.ID).Updates(updates).Error
|
|
}
|
|
func (r *systemRepo) DeleteUser(ctx context.Context, id uint) error {
|
|
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Where("sys_user_id = ?", id).Delete(&userAuthorityPO{}).Error; err != nil {
|
|
return err
|
|
}
|
|
return tx.Delete(&userPO{}, id).Error
|
|
})
|
|
}
|
|
func (r *systemRepo) UpdatePassword(ctx context.Context, id uint, password string) error {
|
|
now := time.Now()
|
|
return r.data.gormDB.WithContext(ctx).Model(&userPO{}).Where("id = ?", id).Updates(map[string]any{"password": password, "password_updated_at": now, "must_change_password": false}).Error
|
|
}
|
|
func (r *systemRepo) ListAuthorities(ctx context.Context) ([]*biz.Authority, error) {
|
|
var pos []authorityPO
|
|
if err := r.data.gormDB.WithContext(ctx).Order("authority_id").Find(&pos).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
result := make([]*biz.Authority, 0, len(pos))
|
|
for _, po := range pos {
|
|
a := toBizAuthority(po)
|
|
result = append(result, &a)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (r *systemRepo) SetUserAuthorities(ctx context.Context, id uint, authorityIDs []uint) error {
|
|
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Where("sys_user_id = ?", id).Delete(&userAuthorityPO{}).Error; err != nil {
|
|
return err
|
|
}
|
|
links := make([]userAuthorityPO, 0, len(authorityIDs))
|
|
for _, authorityID := range authorityIDs {
|
|
var count int64
|
|
if err := tx.Model(&authorityPO{}).Where("authority_id = ?", authorityID).Count(&count).Error; err != nil || count == 0 {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return errors.New("角色不存在")
|
|
}
|
|
links = append(links, userAuthorityPO{SysUserID: id, SysAuthorityAuthorityID: authorityID})
|
|
}
|
|
if err := tx.Create(&links).Error; err != nil {
|
|
return err
|
|
}
|
|
return tx.Model(&userPO{}).Where("id = ?", id).Update("authority_id", authorityIDs[0]).Error
|
|
})
|
|
}
|
|
|
|
func (r *systemRepo) SetUserAuthority(ctx context.Context, id, authorityID uint) error {
|
|
var count int64
|
|
if err := r.data.gormDB.WithContext(ctx).Model(&userAuthorityPO{}).Where("sys_user_id = ? AND sys_authority_authority_id = ?", id, authorityID).Count(&count).Error; err != nil {
|
|
return err
|
|
}
|
|
if count == 0 {
|
|
return errors.New("该用户无此角色")
|
|
}
|
|
return r.data.gormDB.WithContext(ctx).Model(&userPO{}).Where("id = ?", id).Update("authority_id", authorityID).Error
|
|
}
|
|
|
|
func (r *systemRepo) SetUserSetting(ctx context.Context, id uint, setting map[string]any) error {
|
|
value, err := json.Marshal(setting)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return r.data.gormDB.WithContext(ctx).Model(&userPO{}).Where("id = ?", id).Update("origin_setting", string(value)).Error
|
|
}
|
|
|
|
// ActiveName temporarily carries the parent menu name during seeding. It is
|
|
// cleared from responses by the service for these records.
|
|
func defaultMenus() []menuPO {
|
|
root := func(path, name, title, icon string, sort int) menuPO {
|
|
return menuPO{Path: path, Name: name, Component: "view/routerHolder.vue", Title: title, Icon: icon, Sort: sort}
|
|
}
|
|
child := func(parent, path, name, component, title, icon string, sort int) menuPO {
|
|
return menuPO{MenuLevel: 1, Path: path, Name: name, Component: component, Title: title, Icon: icon, Sort: sort, ActiveName: parent}
|
|
}
|
|
return []menuPO{
|
|
{Path: "dashboard", Name: "dashboard", Component: "view/dashboard/index.vue", Title: "仪表盘", Icon: "odometer", Sort: 1},
|
|
root("permission", "permission", "权限管理", "perm-gva", 2), root("org", "org", "组织管理", "share", 3), root("systemConfig", "systemConfig", "系统设置", "config-gva", 4), root("monitor", "monitor", "运维监控", "monitor-gva", 5), root("media", "media", "媒体管理", "folder-opened", 6), root("plugin", "plugin", "插件系统", "cherry", 10),
|
|
{Path: "person", Name: "person", Component: "view/person/person.vue", Title: "个人信息", Icon: "postcard", Hidden: true, Sort: 13},
|
|
child("permission", "authority", "authority", "view/superAdmin/authority/authority.vue", "角色管理", "role-gva", 1), child("permission", "menu", "menu", "view/superAdmin/menu/menu.vue", "菜单管理", "tickets", 2), child("permission", "api", "api", "view/superAdmin/api/api.vue", "api管理", "api-gva", 3), child("permission", "apiToken", "apiToken", "view/systemTools/apiToken/index.vue", "API Token", "key", 4),
|
|
child("org", "user", "user", "view/superAdmin/user/user.vue", "用户管理", "user", 1), child("org", "department", "department", "view/superAdmin/department/department.vue", "部门管理", "office-building", 2), child("org", "position", "position", "view/superAdmin/position/position.vue", "岗位管理", "postcard", 3),
|
|
child("systemConfig", "system", "system", "view/systemTools/system/system.vue", "配置文件", "config-file-gva", 1), child("systemConfig", "dictionary", "dictionary", "view/superAdmin/dictionary/sysDictionary.vue", "字典管理", "notebook", 2), child("systemConfig", "sysParams", "sysParams", "view/superAdmin/params/sysParams.vue", "参数管理", "set-up", 3), child("systemConfig", "security", "security", "view/system/security/index.vue", "安全配置", "security-gva", 4),
|
|
child("monitor", "operation", "operation", "view/superAdmin/operation/sysOperationRecord.vue", "操作历史", "document", 1), child("monitor", "loginLog", "loginLog", "view/systemTools/loginLog/index.vue", "登录日志", "clock", 2), child("monitor", "sysError", "sysError", "view/systemTools/sysError/sysError.vue", "错误日志", "error-gva", 3), child("monitor", "sysVersion", "sysVersion", "view/systemTools/version/version.vue", "版本管理", "version-gva", 4), child("monitor", "state", "state", "view/system/state.vue", "服务器状态", "server", 5), child("monitor", "dataAccessLog", "dataAccessLog", "view/superAdmin/dataAccessLog/dataAccessLog.vue", "数据权限审计", "warning", 6), child("monitor", "timedTask", "timedTask", "view/systemTools/timedTask/index.vue", "定时任务", "timer", 7), child("monitor", "logViewer", "logViewer", "view/systemTools/logViewer/index.vue", "文件日志", "document", 8),
|
|
child("media", "upload", "upload", "view/media/upload.vue", "媒体库(上传下载)", "upload", 1), child("media", "chunkUpload", "chunkUpload", "view/media/chunkUpload.vue", "大文件上传", "folder-add", 2),
|
|
child("plugin", "plugin-email", "plugin-email", "plugin/email/view/index.vue", "邮件插件", "message", 4), child("plugin", "anInfo", "anInfo", "plugin/announcement/view/info.vue", "公告管理[示例]", "bell", 5),
|
|
}
|
|
}
|