package handler import ( "encoding/json" "fmt" "io" "net/http" "strconv" "strings" "bj_power_workstation/internal/store" "bj_power_workstation/internal/svc" ) // tighteningListHandler GET /api/tightening/list?sn=&only_pending=true&limit=100 // 查询本地 torque_results(最新优先)。 func tighteningListHandler(ctx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() sn := q.Get("sn") onlyPending := false if v, err := strconv.ParseBool(q.Get("only_pending")); err == nil { onlyPending = v } limit := atoi(q.Get("limit"), 100) if limit <= 0 || limit > 500 { limit = 500 } list, err := ctx.Store.ListTorqueResults(sn, onlyPending, limit) if err != nil { fail(w, http.StatusInternalServerError, "查询拧紧结果失败:"+err.Error()) return } ok(w, map[string]any{ "total": len(list), "list": list, }) } } // tighteningRecordHandler POST /api/tightening/record —— 录入一条拧紧数据。 // 真实场景:工件走到「需要拧紧枪」的工艺步骤时界面聚焦拧紧输入框,人工操作拧紧枪把采集到的 // 扭矩值打入输入框回车 → 本接口按当前工件 SN + 工艺步骤落本地库,再由后台同步器上报 MES。 // 入参 {sn, workOrderNo, stepId, stepName, screwNo, torque, angle, result, operator}; // result 由前端按该步骤考核标准(扭矩 RANGE)判定后传入,非 NG 一律记 OK。 func tighteningRecordHandler(ctx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { payload, err := io.ReadAll(r.Body) if err != nil { fail(w, http.StatusBadRequest, "请求体读取失败") return } var req struct { Sn string `json:"sn"` WorkOrderNo string `json:"workOrderNo"` StepId string `json:"stepId"` StepName string `json:"stepName"` ScrewNo string `json:"screwNo"` Torque float64 `json:"torque"` Angle float64 `json:"angle"` Result string `json:"result"` Operator string `json:"operator"` } if err := json.Unmarshal(payload, &req); err != nil { fail(w, http.StatusBadRequest, "请求体解析失败") return } if strings.TrimSpace(req.Sn) == "" { fail(w, http.StatusBadRequest, "缺少工件 SN,请先上料") return } if strings.TrimSpace(req.StepId) == "" { fail(w, http.StatusBadRequest, "缺少拧紧工艺步骤") return } if req.Result != "NG" { req.Result = "OK" } dockCode := fmt.Sprintf("DOCK%02d", ctx.Config.Station.StationNo) id, err := ctx.Store.InsertTorqueResult(store.TorqueResult{ WorkOrderNo: req.WorkOrderNo, Sn: req.Sn, DockCode: dockCode, ScrewNo: req.ScrewNo, StepId: req.StepId, StepName: req.StepName, Torque: req.Torque, Angle: req.Angle, Result: req.Result, Operator: req.Operator, }) if err != nil { fail(w, http.StatusInternalServerError, "拧紧数据入库失败:"+err.Error()) return } ctx.Store.AddEventLog(req.WorkOrderNo, req.Operator, "torque_record", fmt.Sprintf("拧紧录入 sn=%s 步骤=%s 扭矩=%.1f 结果=%s", req.Sn, req.StepName, req.Torque, req.Result)) ok(w, map[string]any{"id": id, "result": req.Result}) } }