package logic import ( "context" "errors" "time" "bj_power_mes/ent" "bj_power_mes/ent/dailyplan" "bj_power_mes/ent/scanrecord" "bj_power_mes/ent/workorder" "bj_power_mes/ent/workpiece" ) type ScanReq struct { Station string `json:"station"` Sn string `json:"sn"` OrderNo string `json:"orderNo"` Type string `json:"type"` // ONLINE / PROCESS / DONE / TEMP_STORE ProcessCode int `json:"processCode"` Operator string `json:"operator"` } // ReportScan 扫码报工:记录 scan_record,并更新工单进度 func (s *Service) ReportScan(ctx context.Context, req ScanReq, operator string) error { if req.Sn == "" { return errors.New("sn 不能为空") } scanType := req.Type if scanType == "" { scanType = "PROCESS" } if req.Operator == "" { req.Operator = operator } _, err := s.ctx.EntClient.ScanRecord.Create(). SetStation(req.Station).SetSn(req.Sn).SetOrderNo(req.OrderNo). SetType(scanType).SetProcessCode(req.ProcessCode).SetOperator(req.Operator). SetTime(time.Now()).Save(ctx) if err != nil { return err } s.ctx.EventLog.Write(ctx, "scan.report", req.OrderNo, operator, "scan_record", req.Sn, "扫码报工", map[string]any{"station": req.Station, "type": scanType, "processCode": req.ProcessCode}) // 更新工单进度:调高 finished 进度(去重按 sn+工序) wp, err := s.ctx.EntClient.Workpiece.Query().Where(workpiece.Sn(req.Sn)).First(ctx) if err == nil && wp != nil && wp.WorkOrderId > 0 { s.bumpWorkOrderProgress(ctx, wp.OrderNo, wp.Sn) } s.notifyDashboard() return nil } // bumpWorkOrderProgress 增加工单已完成数量(由完工动作驱动;扫码报工仅流转状态不重复计数) func (s *Service) bumpWorkOrderProgress(ctx context.Context, orderNo, sn string) { wo, err := s.ctx.EntClient.WorkOrder.Query().Where(workorder.WorkOrderNo(orderNo)).First(ctx) if err != nil || wo == nil { return } if wo.FinishedNum >= wo.Quantity { return } _, _ = s.ctx.EntClient.WorkOrder.UpdateOneID(wo.ID). SetFinishedNum(wo.FinishedNum + 1). SetStatus("IN_PROGRESS").Save(ctx) } // bumpDailyPlanCompleted 工单完工联动当日排产:completedQty+1,达到 planQty 置 DONE。 // 当天没有匹配排产则跳过(不做自动建单)。仅由真正的完工事件调用。 func (s *Service) bumpDailyPlanCompleted(ctx context.Context, orderNo string, t time.Time) { date := t.Format("2006-01-02") plans, err := s.ctx.EntClient.DailyPlan.Query(). Where(dailyplan.OrderNo(orderNo), dailyplan.PlanDate(date)). Where(dailyplan.StatusIn("PENDING", "PROCESSING", "DONE")).All(ctx) if err != nil || len(plans) == 0 { return } for _, p := range plans { if p.CompletedQty >= p.PlanQty { continue } newQty := p.CompletedQty + 1 st := p.Status if newQty >= p.PlanQty { st = "DONE" } else if st == "PENDING" { st = "PROCESSING" } _, _ = s.ctx.EntClient.DailyPlan.UpdateOneID(p.ID). SetCompletedQty(newQty).SetStatus(st).Save(ctx) } } // ListScanRecords 查询扫码报工记录 func (s *Service) ListScanRecords(ctx context.Context, sn, orderNo string, page, pageSize int) ([]*ent.ScanRecord, int, error) { q := s.ctx.EntClient.ScanRecord.Query() if sn != "" { q = q.Where(scanrecord.Sn(sn)) } if orderNo != "" { q = q.Where(scanrecord.OrderNoEqualFold(orderNo)) } if sn != "" { q = q.Where(scanrecord.SnEqualFold(sn)) } total, err := q.Count(ctx) if err != nil { return nil, 0, err } rows, err := q.Order(ent.Desc(scanrecord.FieldID)). Offset((page - 1) * pageSize).Limit(pageSize).All(ctx) return rows, total, err }