Files
bj_power/bj_power_mes/internal/handler/perm.go
T
SunYF e852c7cd37 chore: 批量完成项目多模块迭代优化
1. 废弃半成品库存表并统一库存主表
2. 修复列表排序与搜索大小写不敏感问题
3. 新增用户最近登录时间、工单BOM名称字段
4. 完善角色管理、工位选择器功能
5. 增加拧紧数据补录、成品自动回流WMS能力
6. 统一导出时间范围校验规则
7. 丰富物料/备料单筛选条件
8. 调整菜单与权限命名适配产品型号业务
2026-09-08 11:44:04 +08:00

104 lines
4.1 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/bom/item/delete": "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",
// 装机绑定(报工前扫料/撤销,属报工操作域)
"POST:/api/v1/binds": "produce.scan",
"POST:/api/v1/binds/remove": "produce.scan",
// 账号管理(拆分自原 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
}