122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
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
|
||
}
|