Files
bj_power/bj_power_mes/internal/handler/perm.go
T
SunYF b6799c9de4 feat: 完成产线与仓储系统多模块迭代升级
本次迭代覆盖MES与WMS核心业务:
1. 新增接驳台托盘传感器读取与AGV对接能力
2. 完善工单排产、备料流程与权限体系拆分
3. 优化看板接口与前端路由、样式
4. 新增操作日志、库存盘点与角色保护逻辑
5. 修复代理地址、BOM保存等已知问题
2026-09-04 14:18:53 +08:00

100 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"net/http"
"strings"
"bj_power_mes/common/httpx"
"bj_power_mes/internal/svc"
)
// pathPermMap 请求方法+路径 → 所需按钮级权限码(块2:后端接口兜底校验)。
// 路径中的 :id 统一以 * 结尾匹配。
var pathPermMap = map[string]string{
"POST:/api/v1/product-types": "produce.product:add",
"PUT:/api/v1/product-types": "produce.product:edit",
"DELETE:/api/v1/product-types/*": "produce.product:delete",
"POST:/api/v1/work-orders": "produce.workorder:add",
"PUT:/api/v1/work-orders": "produce.workorder:edit",
"POST:/api/v1/work-orders/status": "produce.workorder:edit",
"DELETE:/api/v1/work-orders/*": "produce.workorder:delete",
"POST:/api/v1/daily-plans": "produce.workorder:dailyplan",
"PUT:/api/v1/bom": "produce.bom:edit",
"POST:/api/v1/material-requests/generate": "produce.material:generate",
"POST:/api/v1/plc/send-process": "produce.plc:send",
"POST:/api/v1/process-flows": "produce.processflow:add",
"POST:/api/v1/process-flows/status": "produce.processflow:edit",
"DELETE:/api/v1/process-flows/*": "produce.processflow:delete",
"POST:/api/v1/process-flows/upload": "produce.processflow:upload",
"POST:/api/v1/process-steps": "produce.processflow:edit",
"POST:/api/v1/stations": "produce.station:edit",
// 账号管理(拆分自原 sys.rbac:usersys.account 菜单下增/改/删)
"POST:/api/v1/users": "sys.account:add",
"PUT:/api/v1/users": "sys.account:edit",
"DELETE:/api/v1/users/*": "sys.account:delete",
// 角色管理(拆分自原 sys.rbac:role/permsys.role 菜单下增/改/删)
"POST:/api/v1/roles": "sys.role:add",
"PUT:/api/v1/roles": "sys.role:edit",
"DELETE:/api/v1/roles/*": "sys.role:delete",
"POST:/api/v1/permissions": "sys.role:perm",
"PUT:/api/v1/permissions": "sys.role:perm",
"DELETE:/api/v1/permissions/*": "sys.role:perm",
}
// userHasPerm 校验当前登录用户是否拥有某权限码(SUPER_ADMIN 或 * 放行)。
// 用户ID 使用 uidFromRequest:优先取 context,缺失时回退解析 Authorization token。
func userHasPerm(r *http.Request, svcCtx *svc.ServiceContext, code string) bool {
if code == "" {
return true
}
userId := uidFromRequest(r, svcCtx)
if userId <= 0 {
return false
}
usr, err := svcCtx.EntClient.User.Get(r.Context(), userId)
if err != nil {
return false
}
role, err := svcCtx.EntClient.Role.Get(r.Context(), usr.RoleId)
if err != nil {
return false
}
if role.Code == "SUPER_ADMIN" {
return true
}
for _, c := range role.PermissionCodes {
if c == "*" || c == code {
return true
}
}
return false
}
// permissionGuard 按钮级权限后端兜底中间件(仅对写操作映射表内的路径生效)
func permissionGuard(svcCtx *svc.ServiceContext) func(http.HandlerFunc) http.HandlerFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
code, ok := pathPerm(r.Method, r.URL.Path)
if ok && !userHasPerm(r, svcCtx, code) {
httpx.FailHTTP(w, http.StatusForbidden, "无操作权限:"+code)
return
}
next(w, r)
}
}
}
// pathPerm 先按完整路径精确匹配;未命中时把末段替换为 * 再匹配(用于 :id 结尾的路径)。
func pathPerm(method, path string) (string, bool) {
key := method + ":" + strings.TrimSuffix(path, "/")
if code, ok := pathPermMap[key]; ok {
return code, true
}
segs := strings.Split(key, "/")
if len(segs) > 0 {
segs[len(segs)-1] = "*"
}
code, ok := pathPermMap[strings.Join(segs, "/")]
return code, ok
}