任务三
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/data/model"
|
||||
"kra/internal/data/query"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type apiRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewApiRepo 创建API仓储
|
||||
func NewApiRepo(db *gorm.DB) system.ApiRepo {
|
||||
return &apiRepo{db: db}
|
||||
}
|
||||
|
||||
func (r *apiRepo) Create(ctx context.Context, api *system.Api) error {
|
||||
_, err := query.SysAPI.WithContext(ctx).Where(
|
||||
query.SysAPI.Path.Eq(api.Path),
|
||||
query.SysAPI.Method.Eq(api.Method),
|
||||
).First()
|
||||
if err == nil {
|
||||
return errors.New("存在相同api")
|
||||
}
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
m := toModelAPI(api)
|
||||
return query.SysAPI.WithContext(ctx).Create(m)
|
||||
}
|
||||
|
||||
func (r *apiRepo) Update(ctx context.Context, api *system.Api) error {
|
||||
old, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(api.ID))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if safeString(old.Path) != api.Path || safeString(old.Method) != api.Method {
|
||||
dup, ferr := query.SysAPI.WithContext(ctx).Where(
|
||||
query.SysAPI.Path.Eq(api.Path),
|
||||
query.SysAPI.Method.Eq(api.Method),
|
||||
).First()
|
||||
if ferr == nil && dup.ID != int64(api.ID) {
|
||||
return errors.New("存在相同api路径")
|
||||
}
|
||||
if ferr != nil && !errors.Is(ferr, gorm.ErrRecordNotFound) {
|
||||
return ferr
|
||||
}
|
||||
}
|
||||
m := toModelAPI(api)
|
||||
_, err = query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(api.ID))).Updates(m)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *apiRepo) Delete(ctx context.Context, id uint) error {
|
||||
_, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(id))).Delete()
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *apiRepo) DeleteByIds(ctx context.Context, ids []uint) error {
|
||||
int64Ids := make([]int64, len(ids))
|
||||
for i, id := range ids {
|
||||
int64Ids[i] = int64(id)
|
||||
}
|
||||
_, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.In(int64Ids...)).Delete()
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *apiRepo) FindByID(ctx context.Context, id uint) (*system.Api, error) {
|
||||
m, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(id))).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toBizAPI(m), nil
|
||||
}
|
||||
|
||||
func (r *apiRepo) FindByPathMethod(ctx context.Context, path, method string) (*system.Api, error) {
|
||||
m, err := query.SysAPI.WithContext(ctx).Where(
|
||||
query.SysAPI.Path.Eq(path),
|
||||
query.SysAPI.Method.Eq(method),
|
||||
).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toBizAPI(m), nil
|
||||
}
|
||||
|
||||
func (r *apiRepo) List(ctx context.Context, page, pageSize int, filters map[string]string, orderKey string, desc bool) ([]*system.Api, int64, error) {
|
||||
q := query.SysAPI.WithContext(ctx)
|
||||
if v, ok := filters["path"]; ok && v != "" {
|
||||
q = q.Where(query.SysAPI.Path.Like("%" + v + "%"))
|
||||
}
|
||||
if v, ok := filters["description"]; ok && v != "" {
|
||||
q = q.Where(query.SysAPI.Description.Like("%" + v + "%"))
|
||||
}
|
||||
if v, ok := filters["method"]; ok && v != "" {
|
||||
q = q.Where(query.SysAPI.Method.Eq(v))
|
||||
}
|
||||
if v, ok := filters["api_group"]; ok && v != "" {
|
||||
q = q.Where(query.SysAPI.APIGroup.Eq(v))
|
||||
}
|
||||
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
orderMap := map[string]bool{"id": true, "path": true, "api_group": true, "description": true, "method": true}
|
||||
if orderKey != "" && orderMap[orderKey] {
|
||||
switch orderKey {
|
||||
case "id":
|
||||
if desc {
|
||||
q = q.Order(query.SysAPI.ID.Desc())
|
||||
} else {
|
||||
q = q.Order(query.SysAPI.ID)
|
||||
}
|
||||
case "path":
|
||||
if desc {
|
||||
q = q.Order(query.SysAPI.Path.Desc())
|
||||
} else {
|
||||
q = q.Order(query.SysAPI.Path)
|
||||
}
|
||||
case "api_group":
|
||||
if desc {
|
||||
q = q.Order(query.SysAPI.APIGroup.Desc())
|
||||
} else {
|
||||
q = q.Order(query.SysAPI.APIGroup)
|
||||
}
|
||||
case "description":
|
||||
if desc {
|
||||
q = q.Order(query.SysAPI.Description.Desc())
|
||||
} else {
|
||||
q = q.Order(query.SysAPI.Description)
|
||||
}
|
||||
case "method":
|
||||
if desc {
|
||||
q = q.Order(query.SysAPI.Method.Desc())
|
||||
} else {
|
||||
q = q.Order(query.SysAPI.Method)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
q = q.Order(query.SysAPI.ID.Desc())
|
||||
}
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
list, err := q.Offset(offset).Limit(pageSize).Find()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
apis := make([]*system.Api, len(list))
|
||||
for i, m := range list {
|
||||
apis[i] = toBizAPI(m)
|
||||
}
|
||||
return apis, total, nil
|
||||
}
|
||||
|
||||
func (r *apiRepo) FindAll(ctx context.Context) ([]*system.Api, error) {
|
||||
list, err := query.SysAPI.WithContext(ctx).Order(query.SysAPI.ID.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apis := make([]*system.Api, len(list))
|
||||
for i, m := range list {
|
||||
apis[i] = toBizAPI(m)
|
||||
}
|
||||
return apis, nil
|
||||
}
|
||||
|
||||
func (r *apiRepo) FindByIds(ctx context.Context, ids []uint) ([]*system.Api, error) {
|
||||
int64Ids := make([]int64, len(ids))
|
||||
for i, id := range ids {
|
||||
int64Ids[i] = int64(id)
|
||||
}
|
||||
list, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.In(int64Ids...)).Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apis := make([]*system.Api, len(list))
|
||||
for i, m := range list {
|
||||
apis[i] = toBizAPI(m)
|
||||
}
|
||||
return apis, nil
|
||||
}
|
||||
|
||||
func (r *apiRepo) GetApiGroups(ctx context.Context) ([]string, map[string]string, error) {
|
||||
list, err := query.SysAPI.WithContext(ctx).Find()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
groupMap := make(map[string]bool)
|
||||
apiGroupMap := make(map[string]string)
|
||||
var groups []string
|
||||
|
||||
for _, m := range list {
|
||||
path := safeString(m.Path)
|
||||
apiGroup := safeString(m.APIGroup)
|
||||
|
||||
if !groupMap[apiGroup] {
|
||||
groupMap[apiGroup] = true
|
||||
groups = append(groups, apiGroup)
|
||||
}
|
||||
|
||||
if len(path) > 1 {
|
||||
parts := strings.Split(path, "/")
|
||||
if len(parts) > 1 {
|
||||
apiGroupMap[parts[1]] = apiGroup
|
||||
}
|
||||
}
|
||||
}
|
||||
return groups, apiGroupMap, nil
|
||||
}
|
||||
|
||||
func (r *apiRepo) CreateIgnoreApi(ctx context.Context, path, method string) error {
|
||||
m := &model.SysIgnoreAPI{
|
||||
Path: &path,
|
||||
Method: &method,
|
||||
}
|
||||
return r.db.WithContext(ctx).Create(m).Error
|
||||
}
|
||||
|
||||
func (r *apiRepo) DeleteIgnoreApi(ctx context.Context, path, method string) error {
|
||||
return r.db.WithContext(ctx).Unscoped().Where("path = ? AND method = ?", path, method).Delete(&model.SysIgnoreAPI{}).Error
|
||||
}
|
||||
|
||||
func (r *apiRepo) FindAllIgnoreApis(ctx context.Context) ([]*system.IgnoreApi, error) {
|
||||
var list []model.SysIgnoreAPI
|
||||
if err := r.db.WithContext(ctx).Find(&list).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]*system.IgnoreApi, len(list))
|
||||
for i, m := range list {
|
||||
result[i] = &system.IgnoreApi{
|
||||
Path: safeString(m.Path),
|
||||
Method: safeString(m.Method),
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 转换函数
|
||||
func toModelAPI(a *system.Api) *model.SysAPI {
|
||||
return &model.SysAPI{
|
||||
ID: int64(a.ID),
|
||||
Path: &a.Path,
|
||||
Description: &a.Description,
|
||||
APIGroup: &a.ApiGroup,
|
||||
Method: &a.Method,
|
||||
}
|
||||
}
|
||||
|
||||
func toBizAPI(m *model.SysAPI) *system.Api {
|
||||
return &system.Api{
|
||||
ID: uint(m.ID),
|
||||
Path: safeString(m.Path),
|
||||
Description: safeString(m.Description),
|
||||
ApiGroup: safeString(m.APIGroup),
|
||||
Method: safeString(m.Method),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,485 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/data/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type menuRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewMenuRepo 创建菜单仓储
|
||||
func NewMenuRepo(db *gorm.DB) system.MenuRepo {
|
||||
return &menuRepo{db: db}
|
||||
}
|
||||
|
||||
// CreateBaseMenu 创建基础菜单
|
||||
func (r *menuRepo) CreateBaseMenu(ctx context.Context, menu *system.BaseMenu) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 检查name是否重复
|
||||
var count int64
|
||||
if err := tx.Model(&model.SysBaseMenu{}).Where("name = ?", menu.Name).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在重复name,请修改name")
|
||||
}
|
||||
|
||||
if menu.ParentId != 0 {
|
||||
// 检查父菜单是否存在
|
||||
var parentMenu model.SysBaseMenu
|
||||
if err := tx.First(&parentMenu, menu.ParentId).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("父菜单不存在")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查父菜单下现有子菜单数量
|
||||
var existingChildrenCount int64
|
||||
if err := tx.Model(&model.SysBaseMenu{}).Where("parent_id = ?", menu.ParentId).Count(&existingChildrenCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 如果父菜单原本是叶子菜单,需要清空其权限分配
|
||||
if existingChildrenCount == 0 {
|
||||
// 检查父菜单是否被其他角色设置为首页
|
||||
var defaultRouterCount int64
|
||||
if err := tx.Model(&model.SysAuthority{}).Where("default_router = ?", parentMenu.Name).Count(&defaultRouterCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if defaultRouterCount > 0 {
|
||||
return errors.New("父菜单已被其他角色的首页占用,请先释放父菜单的首页权限")
|
||||
}
|
||||
|
||||
// 清空父菜单的所有权限分配
|
||||
if err := tx.Where("sys_base_menu_id = ?", menu.ParentId).Delete(&model.SysAuthorityMenu{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建菜单
|
||||
m := toModelBaseMenu(menu)
|
||||
if err := tx.Create(m).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建参数
|
||||
if len(menu.Parameters) > 0 {
|
||||
for _, p := range menu.Parameters {
|
||||
param := &model.SysBaseMenuParameter{
|
||||
SysBaseMenuID: ptrInt64(int64(m.ID)),
|
||||
Type: &p.Type,
|
||||
Key: &p.Key,
|
||||
Value: &p.Value,
|
||||
}
|
||||
if err := tx.Create(param).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建按钮
|
||||
if len(menu.MenuBtn) > 0 {
|
||||
for _, b := range menu.MenuBtn {
|
||||
btn := &model.SysBaseMenuBtn{
|
||||
SysBaseMenuID: ptrInt64(int64(m.ID)),
|
||||
Name: &b.Name,
|
||||
Desc: &b.Desc,
|
||||
}
|
||||
if err := tx.Create(btn).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.ID = uint(m.ID)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateBaseMenu 更新基础菜单
|
||||
func (r *menuRepo) UpdateBaseMenu(ctx context.Context, menu *system.BaseMenu) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var oldMenu model.SysBaseMenu
|
||||
if err := tx.Where("id = ?", menu.ID).First(&oldMenu).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查name是否重复
|
||||
if safeString(oldMenu.Name) != menu.Name {
|
||||
var count int64
|
||||
if err := tx.Model(&model.SysBaseMenu{}).Where("id <> ? AND name = ?", menu.ID, menu.Name).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在相同name修改失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 删除旧参数和按钮
|
||||
if err := tx.Unscoped().Where("sys_base_menu_id = ?", menu.ID).Delete(&model.SysBaseMenuParameter{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Where("sys_base_menu_id = ?", menu.ID).Delete(&model.SysBaseMenuBtn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建新参数
|
||||
if len(menu.Parameters) > 0 {
|
||||
for _, p := range menu.Parameters {
|
||||
param := &model.SysBaseMenuParameter{
|
||||
SysBaseMenuID: ptrInt64(int64(menu.ID)),
|
||||
Type: &p.Type,
|
||||
Key: &p.Key,
|
||||
Value: &p.Value,
|
||||
}
|
||||
if err := tx.Create(param).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新按钮
|
||||
if len(menu.MenuBtn) > 0 {
|
||||
for _, b := range menu.MenuBtn {
|
||||
btn := &model.SysBaseMenuBtn{
|
||||
SysBaseMenuID: ptrInt64(int64(menu.ID)),
|
||||
Name: &b.Name,
|
||||
Desc: &b.Desc,
|
||||
}
|
||||
if err := tx.Create(btn).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新菜单
|
||||
updates := map[string]any{
|
||||
"keep_alive": menu.KeepAlive,
|
||||
"close_tab": menu.CloseTab,
|
||||
"default_menu": menu.DefaultMenu,
|
||||
"parent_id": menu.ParentId,
|
||||
"path": menu.Path,
|
||||
"name": menu.Name,
|
||||
"hidden": menu.Hidden,
|
||||
"component": menu.Component,
|
||||
"title": menu.Title,
|
||||
"active_name": menu.ActiveName,
|
||||
"icon": menu.Icon,
|
||||
"sort": menu.Sort,
|
||||
"transition_type": menu.TransitionType,
|
||||
}
|
||||
return tx.Model(&oldMenu).Updates(updates).Error
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteBaseMenu 删除基础菜单
|
||||
func (r *menuRepo) DeleteBaseMenu(ctx context.Context, id uint) error {
|
||||
// 检查是否有子菜单
|
||||
var childCount int64
|
||||
if err := r.db.WithContext(ctx).Model(&model.SysBaseMenu{}).Where("parent_id = ?", id).Count(&childCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if childCount > 0 {
|
||||
return errors.New("此菜单存在子菜单不可删除")
|
||||
}
|
||||
|
||||
// 获取菜单信息
|
||||
var menu model.SysBaseMenu
|
||||
if err := r.db.WithContext(ctx).First(&menu, id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("记录不存在")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查是否有角色将此菜单作为首页
|
||||
var defaultRouterCount int64
|
||||
if err := r.db.WithContext(ctx).Model(&model.SysAuthority{}).Where("default_router = ?", menu.Name).Count(&defaultRouterCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if defaultRouterCount > 0 {
|
||||
return errors.New("此菜单有角色正在作为首页,不可删除")
|
||||
}
|
||||
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Delete(&model.SysBaseMenu{}, "id = ?", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(&model.SysBaseMenuParameter{}, "sys_base_menu_id = ?", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(&model.SysBaseMenuBtn{}, "sys_base_menu_id = ?", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(&model.SysAuthorityBtn{}, "sys_menu_id = ?", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(&model.SysAuthorityMenu{}, "sys_base_menu_id = ?", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// FindBaseMenuByID 根据ID获取基础菜单
|
||||
func (r *menuRepo) FindBaseMenuByID(ctx context.Context, id uint) (*system.BaseMenu, error) {
|
||||
var menu model.SysBaseMenu
|
||||
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&menu).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取参数
|
||||
var params []model.SysBaseMenuParameter
|
||||
r.db.WithContext(ctx).Where("sys_base_menu_id = ?", id).Find(¶ms)
|
||||
|
||||
// 获取按钮
|
||||
var btns []model.SysBaseMenuBtn
|
||||
r.db.WithContext(ctx).Where("sys_base_menu_id = ?", id).Find(&btns)
|
||||
|
||||
return toBizBaseMenu(&menu, params, btns), nil
|
||||
}
|
||||
|
||||
// FindAllBaseMenus 获取所有基础菜单
|
||||
func (r *menuRepo) FindAllBaseMenus(ctx context.Context) ([]*system.BaseMenu, error) {
|
||||
var menus []model.SysBaseMenu
|
||||
if err := r.db.WithContext(ctx).Order("sort").Find(&menus).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取所有参数
|
||||
var allParams []model.SysBaseMenuParameter
|
||||
r.db.WithContext(ctx).Find(&allParams)
|
||||
paramMap := make(map[int64][]model.SysBaseMenuParameter)
|
||||
for _, p := range allParams {
|
||||
if p.SysBaseMenuID != nil {
|
||||
paramMap[*p.SysBaseMenuID] = append(paramMap[*p.SysBaseMenuID], p)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有按钮
|
||||
var allBtns []model.SysBaseMenuBtn
|
||||
r.db.WithContext(ctx).Find(&allBtns)
|
||||
btnMap := make(map[int64][]model.SysBaseMenuBtn)
|
||||
for _, b := range allBtns {
|
||||
if b.SysBaseMenuID != nil {
|
||||
btnMap[*b.SysBaseMenuID] = append(btnMap[*b.SysBaseMenuID], b)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]*system.BaseMenu, len(menus))
|
||||
for i, m := range menus {
|
||||
result[i] = toBizBaseMenu(&m, paramMap[m.ID], btnMap[m.ID])
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindBaseMenusByIds 根据ID列表获取基础菜单
|
||||
func (r *menuRepo) FindBaseMenusByIds(ctx context.Context, ids []string) ([]*system.BaseMenu, error) {
|
||||
var menus []model.SysBaseMenu
|
||||
if err := r.db.WithContext(ctx).Where("id in (?)", ids).Order("sort").Find(&menus).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取参数
|
||||
var allParams []model.SysBaseMenuParameter
|
||||
r.db.WithContext(ctx).Where("sys_base_menu_id in (?)", ids).Find(&allParams)
|
||||
paramMap := make(map[int64][]model.SysBaseMenuParameter)
|
||||
for _, p := range allParams {
|
||||
if p.SysBaseMenuID != nil {
|
||||
paramMap[*p.SysBaseMenuID] = append(paramMap[*p.SysBaseMenuID], p)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取按钮
|
||||
var allBtns []model.SysBaseMenuBtn
|
||||
r.db.WithContext(ctx).Where("sys_base_menu_id in (?)", ids).Find(&allBtns)
|
||||
btnMap := make(map[int64][]model.SysBaseMenuBtn)
|
||||
for _, b := range allBtns {
|
||||
if b.SysBaseMenuID != nil {
|
||||
btnMap[*b.SysBaseMenuID] = append(btnMap[*b.SysBaseMenuID], b)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]*system.BaseMenu, len(menus))
|
||||
for i, m := range menus {
|
||||
result[i] = toBizBaseMenu(&m, paramMap[m.ID], btnMap[m.ID])
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindAuthorityMenuIds 获取角色的菜单ID列表
|
||||
func (r *menuRepo) FindAuthorityMenuIds(ctx context.Context, authorityId uint) ([]string, error) {
|
||||
var authorityMenus []model.SysAuthorityMenu
|
||||
if err := r.db.WithContext(ctx).Where("sys_authority_authority_id = ?", authorityId).Find(&authorityMenus).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
menuIds := make([]string, len(authorityMenus))
|
||||
for i, am := range authorityMenus {
|
||||
menuIds[i] = strconv.FormatInt(am.SysBaseMenuID, 10)
|
||||
}
|
||||
return menuIds, nil
|
||||
}
|
||||
|
||||
// FindAuthorityBtns 获取角色的按钮权限
|
||||
func (r *menuRepo) FindAuthorityBtns(ctx context.Context, authorityId uint) ([]*system.AuthorityBtn, error) {
|
||||
var btns []model.SysAuthorityBtn
|
||||
if err := r.db.WithContext(ctx).Where("authority_id = ?", authorityId).Find(&btns).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取按钮名称
|
||||
var btnIds []int64
|
||||
for _, b := range btns {
|
||||
if b.SysBaseMenuBtnID != nil {
|
||||
btnIds = append(btnIds, *b.SysBaseMenuBtnID)
|
||||
}
|
||||
}
|
||||
|
||||
btnNameMap := make(map[int64]string)
|
||||
if len(btnIds) > 0 {
|
||||
var menuBtns []model.SysBaseMenuBtn
|
||||
r.db.WithContext(ctx).Where("id in (?)", btnIds).Find(&menuBtns)
|
||||
for _, mb := range menuBtns {
|
||||
btnNameMap[mb.ID] = safeString(mb.Name)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]*system.AuthorityBtn, len(btns))
|
||||
for i, b := range btns {
|
||||
result[i] = &system.AuthorityBtn{}
|
||||
if b.AuthorityID != nil {
|
||||
result[i].AuthorityId = uint(*b.AuthorityID)
|
||||
}
|
||||
if b.SysMenuID != nil {
|
||||
result[i].SysMenuID = uint(*b.SysMenuID)
|
||||
}
|
||||
if b.SysBaseMenuBtnID != nil {
|
||||
result[i].SysBaseMenuBtnID = uint(*b.SysBaseMenuBtnID)
|
||||
result[i].BtnName = btnNameMap[*b.SysBaseMenuBtnID]
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SetMenuAuthority 设置角色菜单权限
|
||||
func (r *menuRepo) SetMenuAuthority(ctx context.Context, authorityId uint, menuIds []uint) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 删除旧权限
|
||||
if err := tx.Where("sys_authority_authority_id = ?", authorityId).Delete(&model.SysAuthorityMenu{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建新权限
|
||||
for _, menuId := range menuIds {
|
||||
am := &model.SysAuthorityMenu{
|
||||
SysAuthorityAuthorityID: int64(authorityId),
|
||||
SysBaseMenuID: int64(menuId),
|
||||
}
|
||||
if err := tx.Create(am).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// 转换函数
|
||||
func toModelBaseMenu(m *system.BaseMenu) *model.SysBaseMenu {
|
||||
parentId := int64(m.ParentId)
|
||||
sort := int64(m.Sort)
|
||||
|
||||
return &model.SysBaseMenu{
|
||||
ID: int64(m.ID),
|
||||
ParentID: &parentId,
|
||||
Path: &m.Path,
|
||||
Name: &m.Name,
|
||||
Hidden: &m.Hidden,
|
||||
Component: &m.Component,
|
||||
Sort: &sort,
|
||||
ActiveName: &m.ActiveName,
|
||||
KeepAlive: &m.KeepAlive,
|
||||
DefaultMenu: &m.DefaultMenu,
|
||||
Title: &m.Title,
|
||||
Icon: &m.Icon,
|
||||
CloseTab: &m.CloseTab,
|
||||
TransitionType: &m.TransitionType,
|
||||
}
|
||||
}
|
||||
|
||||
func toBizBaseMenu(m *model.SysBaseMenu, params []model.SysBaseMenuParameter, btns []model.SysBaseMenuBtn) *system.BaseMenu {
|
||||
menu := &system.BaseMenu{
|
||||
ID: uint(m.ID),
|
||||
Path: safeString(m.Path),
|
||||
Name: safeString(m.Name),
|
||||
Component: safeString(m.Component),
|
||||
ActiveName: safeString(m.ActiveName),
|
||||
Title: safeString(m.Title),
|
||||
Icon: safeString(m.Icon),
|
||||
TransitionType: safeString(m.TransitionType),
|
||||
}
|
||||
if m.ParentID != nil {
|
||||
menu.ParentId = uint(*m.ParentID)
|
||||
}
|
||||
if m.Sort != nil {
|
||||
menu.Sort = int(*m.Sort)
|
||||
}
|
||||
if m.Hidden != nil {
|
||||
menu.Hidden = *m.Hidden
|
||||
}
|
||||
if m.KeepAlive != nil {
|
||||
menu.KeepAlive = *m.KeepAlive
|
||||
}
|
||||
if m.DefaultMenu != nil {
|
||||
menu.DefaultMenu = *m.DefaultMenu
|
||||
}
|
||||
if m.CloseTab != nil {
|
||||
menu.CloseTab = *m.CloseTab
|
||||
}
|
||||
|
||||
// 转换参数
|
||||
if len(params) > 0 {
|
||||
menu.Parameters = make([]*system.MenuParameter, len(params))
|
||||
for i, p := range params {
|
||||
menu.Parameters[i] = &system.MenuParameter{
|
||||
ID: uint(p.ID),
|
||||
Type: safeString(p.Type),
|
||||
Key: safeString(p.Key),
|
||||
Value: safeString(p.Value),
|
||||
}
|
||||
if p.SysBaseMenuID != nil {
|
||||
menu.Parameters[i].SysBaseMenuID = uint(*p.SysBaseMenuID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 转换按钮
|
||||
if len(btns) > 0 {
|
||||
menu.MenuBtn = make([]*system.MenuBtn, len(btns))
|
||||
for i, b := range btns {
|
||||
menu.MenuBtn[i] = &system.MenuBtn{
|
||||
ID: uint(b.ID),
|
||||
Name: safeString(b.Name),
|
||||
Desc: safeString(b.Desc),
|
||||
}
|
||||
if b.SysBaseMenuID != nil {
|
||||
menu.MenuBtn[i].SysBaseMenuID = uint(*b.SysBaseMenuID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return menu
|
||||
}
|
||||
|
||||
func ptrInt64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
Reference in New Issue
Block a user