This commit is contained in:
2025-06-13 17:37:30 +08:00
parent 1b72f51e4a
commit 3bd4c5d672
5 changed files with 380 additions and 122 deletions

View File

@@ -1,121 +1,121 @@
package mid
import (
"fmt"
"log"
"net/http"
"time"
"management/internal/erpserver/model/dto"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/know"
"management/internal/pkg/session"
"github.com/patrickmn/go-cache"
)
var publicRoutes = map[string]bool{
"/home.html": true,
"/dashboard": true,
"/system/menus": true,
"/upload/img": true,
"/upload/file": true,
"/upload/multi_files": true,
"/pear.json": true,
"/logout": true,
}
// 定义一个全局的go-cache实例
var menuCache *cache.Cache
func init() {
// 初始化go-cache设置默认过期时间为5分钟每10分钟清理一次过期项
menuCache = cache.New(5*time.Minute, 10*time.Minute)
}
func Authorize(
sess session.Manager,
menuService v1.MenuService,
) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
path := r.URL.Path
// 登陆检查
user, err := sess.GetUser(ctx, know.StoreName)
if err != nil || user.ID == 0 {
http.Redirect(w, r, "/", http.StatusFound)
return
}
// 公共路由放行
if publicRoutes[path] {
ctx = setUser(ctx, user)
next.ServeHTTP(w, r.WithContext(ctx))
return
}
n1 := time.Now()
// 权限检查
var menus map[string]*dto.OwnerMenuDto
cacheKey := fmt.Sprintf("user_menus:%d", user.RoleID) // 使用用户RoleID作为缓存key
// 尝试从内存缓存中获取菜单数据
if cachedMenus, found := menuCache.Get(cacheKey); found {
menus = cachedMenus.(map[string]*dto.OwnerMenuDto)
log.Printf("listByRoleIDToMap (from cache): %s", time.Since(n1).String())
} else {
// 内存缓存未命中从menuService获取并存入内存缓存
menus, err = menuService.ListByRoleIDToMap(ctx, user.RoleID)
if err != nil {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
menuCache.Set(cacheKey, menus, cache.DefaultExpiration) // 使用默认过期时间
log.Printf("listByRoleIDToMap (from service, then cached): %s", time.Since(n1).String())
}
if !hasPermission(menus, path) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
cur := getCurrentMenus(menus, path)
ctx = setUser(ctx, user)
ctx = setCurMenus(ctx, cur)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
func hasPermission(menus map[string]*dto.OwnerMenuDto, path string) bool {
_, ok := menus[path]
return ok
}
func getCurrentMenus(data map[string]*dto.OwnerMenuDto, path string) []dto.OwnerMenuDto {
var res []dto.OwnerMenuDto
menu, ok := data[path]
if !ok {
return res
}
for _, item := range data {
if menu.IsList {
if item.ParentID == menu.ID || item.ID == menu.ID {
res = append(res, *item)
}
} else {
if item.ParentID == menu.ParentID {
res = append(res, *item)
}
}
}
return res
}
//import (
// "fmt"
// "log"
// "net/http"
// "time"
//
// "management/internal/erpserver/model/dto"
// v1 "management/internal/erpserver/service/v1"
// "management/internal/pkg/know"
// "management/internal/pkg/session"
//
// "github.com/patrickmn/go-cache"
//)
//
//var publicRoutes = map[string]bool{
// "/home.html": true,
// "/dashboard": true,
// "/system/menus": true,
// "/upload/img": true,
// "/upload/file": true,
// "/upload/multi_files": true,
// "/pear.json": true,
// "/logout": true,
//}
//
//// 定义一个全局的go-cache实例
//var menuCache *cache.Cache
//
//func init() {
// // 初始化go-cache设置默认过期时间为5分钟每10分钟清理一次过期项
// menuCache = cache.New(5*time.Minute, 10*time.Minute)
//}
//
//func Authorize(
// sess session.Manager,
// menuService v1.MenuService,
//) func(http.Handler) http.Handler {
// return func(next http.Handler) http.Handler {
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// ctx := r.Context()
// path := r.URL.Path
//
// // 登陆检查
// user, err := sess.GetUser(ctx, know.StoreName)
// if err != nil || user.ID == 0 {
// http.Redirect(w, r, "/", http.StatusFound)
// return
// }
//
// // 公共路由放行
// if publicRoutes[path] {
// ctx = setUser(ctx, user)
// next.ServeHTTP(w, r.WithContext(ctx))
// return
// }
//
// n1 := time.Now()
// // 权限检查
// var menus map[string]*dto.OwnerMenuDto
// cacheKey := fmt.Sprintf("user_menus:%d", user.RoleID) // 使用用户RoleID作为缓存key
//
// // 尝试从内存缓存中获取菜单数据
// if cachedMenus, found := menuCache.Get(cacheKey); found {
// menus = cachedMenus.(map[string]*dto.OwnerMenuDto)
// log.Printf("listByRoleIDToMap (from cache): %s", time.Since(n1).String())
//
// } else {
// // 内存缓存未命中从menuService获取并存入内存缓存
// menus, err = menuService.ListByRoleIDToMap(ctx, user.RoleID)
// if err != nil {
// http.Error(w, "Forbidden", http.StatusForbidden)
// return
// }
// menuCache.Set(cacheKey, menus, cache.DefaultExpiration) // 使用默认过期时间
// log.Printf("listByRoleIDToMap (from service, then cached): %s", time.Since(n1).String())
// }
//
// if !hasPermission(menus, path) {
// http.Error(w, "Forbidden", http.StatusForbidden)
// return
// }
//
// cur := getCurrentMenus(menus, path)
//
// ctx = setUser(ctx, user)
// ctx = setCurMenus(ctx, cur)
//
// next.ServeHTTP(w, r.WithContext(ctx))
// })
// }
//}
//
//func hasPermission(menus map[string]*dto.OwnerMenuDto, path string) bool {
// _, ok := menus[path]
// return ok
//}
//
//func getCurrentMenus(data map[string]*dto.OwnerMenuDto, path string) []dto.OwnerMenuDto {
// var res []dto.OwnerMenuDto
//
// menu, ok := data[path]
// if !ok {
// return res
// }
//
// for _, item := range data {
// if menu.IsList {
// if item.ParentID == menu.ID || item.ID == menu.ID {
// res = append(res, *item)
// }
// } else {
// if item.ParentID == menu.ParentID {
// res = append(res, *item)
// }
// }
// }
//
// return res
//}