167 lines
5.0 KiB
Go
167 lines
5.0 KiB
Go
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 绩效报表共用)
|
||
|
|
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("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)
|
||
|
|
}
|
||
|
|
}
|