1. 新增预警表添加工单号字段,支持按工单号检索预警 2. 添加工单过滤在制品/绩效报表/预警中心查询 3. 补全WMS台账字段口径与权限配置 4. 修复备料单与数量不符处理流程 5. 新增配送进度/库位联动/自动出库功能 6. 修复AGV配送状态更新逻辑 7. 优化退料与库存管理细节
118 lines
5.1 KiB
Go
118 lines
5.1 KiB
Go
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",
|
||
"POST:/api/v1/work-orders/auto-schedule": "produce.workorder:dailyplan",
|
||
"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/bom/import": "produce.bom:edit",
|
||
"POST:/api/v1/material-requests/generate": "produce.material:generate",
|
||
"POST:/api/v1/material-requests/auto-outbound": "produce.material:outbound",
|
||
// 数量不符处理(produce.qty 菜单下:补发/退库/调整关闭)
|
||
"POST:/api/v1/qty-reports/handle": "produce.qty:handle",
|
||
"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",
|
||
"DELETE:/api/v1/stations/*": "produce.station:delete",
|
||
// 过程巡检汇总生成《工序间检验记录》(巡检终端操作域)
|
||
"POST:/api/v1/inspections/generate-inter-process": "sys.inspect:process",
|
||
// 质量检验处置(过程检/完工检不合格处置 退货/返修/退换)
|
||
"POST:/api/v1/quality/disposal": "produce.quality:edit",
|
||
// 附件中心(sys.attachment 菜单下):删除 / 归档清理属管理动作;
|
||
// 列表/预览/下载不设按钮门槛(有菜单权限即可查阅)
|
||
"POST:/api/v1/attachment/delete": "sys.attachment:manage",
|
||
"POST:/api/v1/attachment/archive": "sys.attachment:manage",
|
||
// 装机绑定(报工前扫料/撤销,属报工操作域)
|
||
"POST:/api/v1/binds": "produce.scan",
|
||
"POST:/api/v1/binds/remove": "produce.scan",
|
||
// 账号管理(拆分自原 sys.rbac:user;sys.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/perm;sys.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
|
||
}
|