package handler import ( "net/http" "strconv" "bj_power_mes/common/httpx" "bj_power_mes/internal/logic" "bj_power_mes/internal/svc" ) // atoiDefault 解析整型字符串,非法返回默认值 func atoiDefault(s string, def int) int { if s == "" { return def } if n, err := strconv.Atoi(s); err == nil { return n } return def } // operator 从 JWT 上下文取操作人,取不到回退 fallback func operator(r *http.Request, fallback string) 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 } if fallback != "" { return fallback } return "system" } // StationLoginInternalHandler 工位终端登录(内部接口,X-API-TOKEN 保护) // 校验 用户名 + 工位终端密码 + 工位权限,签发与 MES 同密钥 JWT func StationLoginInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req logic.StationLoginReq if err := httpx.ParseJSON(r, &req); err != nil { httpx.BadRequest(w, "请求体解析失败") return } data, err := logic.New(svcCtx).StationLogin(r.Context(), req) if err != nil { httpx.Fail(w, 2101, err.Error()) return } httpx.Ok(w, data) } } // StationChangePasswordInternalHandler 工位终端修改自己的工位终端密码 func StationChangePasswordInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req struct { UserId int `json:"userId"` OldPassword string `json:"oldPassword"` NewPassword string `json:"newPassword"` } if err := httpx.ParseJSON(r, &req); err != nil { httpx.BadRequest(w, "请求体解析失败") return } if err := logic.New(svcCtx).StationChangePassword(r.Context(), req.UserId, req.OldPassword, req.NewPassword); err != nil { httpx.Fail(w, 2102, err.Error()) return } httpx.OkMessage(w, "工位终端密码修改成功", nil) } } // StationTaskInternalHandler 工位终端拉取当前任务(工位/流程/步骤/活跃工单) func StationTaskInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { stationNo := atoiDefault(r.URL.Query().Get("stationNo"), 0) if stationNo <= 0 { httpx.BadRequest(w, "缺少 stationNo 参数") return } data, err := logic.New(svcCtx).StationTask(r.Context(), stationNo) if err != nil { httpx.Fail(w, 2103, err.Error()) return } httpx.Ok(w, data) } } // StationReportInternalHandler 工位终端工序报工(写工序实绩 + 步骤考核) func StationReportInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req logic.ReportProcessReq if err := httpx.ParseJSON(r, &req); err != nil { httpx.BadRequest(w, "请求体解析失败") return } if err := logic.New(svcCtx).ReportProcess(r.Context(), req, operator(r, "")); err != nil { httpx.Fail(w, 2104, err.Error()) return } httpx.OkMessage(w, "报工成功", nil) } } // WorkloadInternalHandler 工作量/绩效报表(工位终端"我的工作量" + MES 绩效报表共用) // operator=操作人、stationNo=工位号(空=全部工位)、from/to=日期范围 func WorkloadInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() data, err := logic.New(svcCtx).Workload(r.Context(), q.Get("operator"), q.Get("stationNo"), q.Get("from"), q.Get("to")) if err != nil { httpx.Fail(w, 2105, err.Error()) return } httpx.Ok(w, data) } } // FileDownloadInternalHandler 内部文件下载(工艺图纸 PDF,供工位终端代理) func FileDownloadInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { serveUploadFile(w, r, svcCtx.Config.Upload.Dir, r.URL.Query().Get("name")) } } // StationCheckinInternalHandler 工位终端暂存退库(半成品入库,块4/5) // 记录已完成工序后按半成品 INBOUND 流转,并通知 WMS 入库。 func StationCheckinInternalHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req struct { Sn string `json:"sn"` OrderNo string `json:"orderNo"` StationNo int `json:"stationNo"` ProcessCode int `json:"processCode"` Operator string `json:"operator"` } if err := httpx.ParseJSON(r, &req); err != nil { httpx.BadRequest(w, "请求体解析失败") return } if req.Sn == "" { httpx.BadRequest(w, "缺少 sn") return } doneCodes := []int{} if req.ProcessCode > 0 { doneCodes = append(doneCodes, req.ProcessCode) } op := req.Operator if op == "" { op = operator(r, "") } if err := logic.New(svcCtx).SemiFlow(r.Context(), logic.SemiReq{ Sn: req.Sn, OrderNo: req.OrderNo, DoneProcessCodes: doneCodes, Action: "INBOUND", }, op); err != nil { httpx.Fail(w, 2106, err.Error()) return } httpx.OkMessage(w, "暂存退库已登记", nil) } }