Files
bj_power/bj_power_mes/internal/handler/auth_handlers.go
T
SunYF 0ab21b1234 feat&refactor: 完成多模块功能迭代与配置优化
本次提交覆盖多个业务模块的功能完善与体验优化:
1.  **鉴权与配置调整**:
    - 统一JWT滑动续签逻辑,简化Token存储,移除RefreshToken相关冗余代码
    - 调整多项目配置文件中JWT过期时间为3600秒,统一会话闲置窗口
    - 工位配置放开1~12限制,改为仅校验大于0
2.  **术语统一替换**:全链路将"精密件"替换为"电气件",修正物料管理描述
3.  **功能新增**:
    - 新增工位类型、工艺路线与产线点位台账模块
    - 添加工艺PDF预览面板、工位终端代理转发接口
    - 新增操作日志按操作人列表筛选、工位登出日志记录
    - 新增PLC移料指令与产线点位状态管理
4.  **业务流程优化**:
    - 调整BOM物料删除校验逻辑,优化工单备料计算
    - 补充物料图号、检测单号等追溯字段
    - 完善工艺流程图与工位绑定关系说明
    - 优化前端页面文案与交互细节
5.  **代码规范与维护**:
    - 新增通用工具函数与前端静态资源
    - 整理路由权限与中间件逻辑
    - 修复部分接口与配置的不兼容问题
2026-09-10 16:59:15 +08:00

324 lines
8.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"
"strconv"
"strings"
"bj_power_mes/common/httpx"
tokenx "bj_power_mes/common/token"
"bj_power_mes/internal/logic"
"bj_power_mes/internal/svc"
"github.com/zeromicro/go-zero/rest/pathvar"
)
// ctxUserId 从 JWT 上下文取用户IDgo-zero 将自定义 claim 放入 context
func ctxUserId(r *http.Request) int {
switch v := r.Context().Value("userId").(type) {
case float64:
return int(v)
case int:
return v
case int64:
return int(v)
case string:
n, _ := strconv.Atoi(v)
return n
}
return 0
}
// uidFromRequest 取当前登录用户ID:优先 context,缺失时回退解析 Authorization Bearer token(更稳健)
func uidFromRequest(r *http.Request, svcCtx *svc.ServiceContext) int {
if uid := ctxUserId(r); uid > 0 {
return uid
}
auth := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
if auth == "" || auth == r.Header.Get("Authorization") {
return 0
}
claims, err := tokenx.Parse(svcCtx.Config.Auth.AccessSecret, auth)
if err == nil && claims.UserId > 0 {
return claims.UserId
}
return 0
}
// ctxOperator 当前操作人:优先取 name,其次 username
func ctxOperator(r *http.Request) string {
if v, ok := r.Context().Value("name").(string); ok && v != "" {
return v
}
if v, ok := r.Context().Value("username").(string); ok && v != "" {
return v
}
return "system"
}
// pathId 读取路由参数 :id
func pathId(r *http.Request) int {
vars := pathvar.Vars(r)
if vars == nil {
return 0
}
n, _ := strconv.Atoi(vars["id"])
return n
}
func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.LoginReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
data, err := logic.New(svcCtx).Login(r.Context(), req)
if err != nil {
httpx.Fail(w, 1001, err.Error())
return
}
// 操作日志:登录成功(写失败不阻断登录)
svcCtx.EventLog.Write(r.Context(), "auth.login", "", req.Username, "auth", req.Username,
"登录成功", map[string]any{"ip": clientIP(r)})
httpx.Ok(w, data)
}
}
// clientIP 取客户端 IP(优先代理头,兜底 RemoteAddr)
func clientIP(r *http.Request) string {
if v := r.Header.Get("X-Real-IP"); v != "" {
return v
}
if v := r.Header.Get("X-Forwarded-For"); v != "" {
for i := 0; i < len(v); i++ {
if v[i] == ',' {
return strings.TrimSpace(v[:i])
}
}
return strings.TrimSpace(v)
}
if host := r.RemoteAddr; host != "" {
if i := strings.LastIndex(host, ":"); i > 0 {
return host[:i]
}
return host
}
return ""
}
// LogoutHandler POST /api/v1/logout 退出登录(需登录 JWT
// 记录退出日志;登录态清除由前端完成(无状态 JWT 无服务端会话)。
func LogoutHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
username, _ := r.Context().Value("username").(string)
if username == "" {
if u, err := svcCtx.EntClient.User.Get(r.Context(), uidFromRequest(r, svcCtx)); err == nil {
username = u.Username
}
}
if username != "" {
svcCtx.EventLog.Write(r.Context(), "auth.logout", "", username, "auth", username,
"退出登录", map[string]any{"ip": clientIP(r)})
}
httpx.OkMessage(w, "已退出", nil)
}
}
func UserInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
data, err := logic.New(svcCtx).UserInfo(r.Context(), uidFromRequest(r, svcCtx))
if err != nil {
httpx.Fail(w, 1003, err.Error())
return
}
httpx.Ok(w, data)
}
}
func SeedHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := logic.New(svcCtx).Seed(r.Context()); err != nil {
httpx.Fail(w, 1004, err.Error())
return
}
httpx.OkMessage(w, "初始化完成", nil)
}
}
// ---------- 用户管理 ----------
func ListUsersHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
data, err := logic.New(svcCtx).ListUsers(r.Context())
if err != nil {
httpx.Fail(w, 1005, err.Error())
return
}
httpx.Ok(w, data)
}
}
func CreateUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.UserReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).CreateUser(r.Context(), req); err != nil {
httpx.Fail(w, 1006, err.Error())
return
}
httpx.OkMessage(w, "创建成功", nil)
}
}
func UpdateUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.UserReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).UpdateUser(r.Context(), req); err != nil {
httpx.Fail(w, 1007, err.Error())
return
}
httpx.OkMessage(w, "更新成功", nil)
}
}
func DeleteUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := logic.New(svcCtx).DeleteUser(r.Context(), pathId(r)); err != nil {
httpx.Fail(w, 1008, err.Error())
return
}
httpx.OkMessage(w, "删除成功", nil)
}
}
// ---------- 修改自己的密码 ----------
func ChangePasswordHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.ChangePasswordReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).ChangePassword(r.Context(), uidFromRequest(r, svcCtx), req); err != nil {
httpx.Fail(w, 1017, err.Error())
return
}
httpx.OkMessage(w, "密码修改成功", nil)
}
}
// ---------- 角色管理 ----------
func ListRolesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
data, err := logic.New(svcCtx).ListRoles(r.Context())
if err != nil {
httpx.Fail(w, 1009, err.Error())
return
}
httpx.Ok(w, data)
}
}
func CreateRoleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.RoleReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).CreateRole(r.Context(), req); err != nil {
httpx.Fail(w, 1010, err.Error())
return
}
httpx.OkMessage(w, "创建成功", nil)
}
}
func UpdateRoleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.RoleReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).UpdateRole(r.Context(), req); err != nil {
httpx.Fail(w, 1011, err.Error())
return
}
httpx.OkMessage(w, "更新成功", nil)
}
}
func DeleteRoleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := logic.New(svcCtx).DeleteRole(r.Context(), pathId(r)); err != nil {
httpx.Fail(w, 1012, err.Error())
return
}
httpx.OkMessage(w, "删除成功", nil)
}
}
// ---------- 权限管理 ----------
func ListPermissionsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
data, err := logic.New(svcCtx).ListPermissions(r.Context())
if err != nil {
httpx.Fail(w, 1013, err.Error())
return
}
httpx.Ok(w, data)
}
}
func CreatePermissionHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.PermissionReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).CreatePermission(r.Context(), req); err != nil {
httpx.Fail(w, 1014, err.Error())
return
}
httpx.OkMessage(w, "创建成功", nil)
}
}
func UpdatePermissionHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req logic.PermissionReq
if err := httpx.ParseJSON(r, &req); err != nil {
httpx.BadRequest(w, "请求体解析失败")
return
}
if err := logic.New(svcCtx).UpdatePermission(r.Context(), req); err != nil {
httpx.Fail(w, 1015, err.Error())
return
}
httpx.OkMessage(w, "更新成功", nil)
}
}
func DeletePermissionHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := logic.New(svcCtx).DeletePermission(r.Context(), pathId(r)); err != nil {
httpx.Fail(w, 1016, err.Error())
return
}
httpx.OkMessage(w, "删除成功", nil)
}
}