feat: 新增产线看板功能并优化多端系统体验
1. 新增SSE看板广播机制,业务操作后主动推送刷新事件 2. 新增产线工序横道图与工位状态展示面板 3. 移除dashboard无用的three.js依赖 4. 重构WMS客户端布局与WMS前端资源哈希 5. 新增工位终端时钟图标与大屏自适应布局 6. 新增系统截图脚本与说明书生成工具 7. 修复多处代码细节与空值处理逻辑
This commit is contained in:
@@ -97,6 +97,7 @@ func (s *Service) SaveDailyPlan(ctx context.Context, req DailyPlanReq, operator
|
||||
s.rememberOrderDocks(ctx, req.OrderNo, dockCodes(req.DockCodes))
|
||||
}
|
||||
s.ctx.EventLog.Write(ctx, "daily.plan.save", req.OrderNo, operator, "daily_plan", req.OrderNo, "保存日排产", map[string]any{"planDate": req.PlanDate, "planQty": req.PlanQty, "dockCodes": req.DockCodes})
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ func (s *Service) CreateInspection(ctx context.Context, req InspectionReq, opera
|
||||
_, _ = s.ctx.RedisClient.Del("dashboard:alarms")
|
||||
}
|
||||
}
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,15 @@ func New(s *svc.ServiceContext) *Service {
|
||||
return &Service{ctx: s}
|
||||
}
|
||||
|
||||
// notifyDashboard 生产业务数据落库成功后广播看板刷新事件。
|
||||
// SSE 事件只做"数据变了"的通知(空载荷),大屏收到后自行拉取最新快照,
|
||||
// 避免把整份快照塞进事件流。无订阅客户端时 Publish 为空操作,零开销。
|
||||
func (s *Service) notifyDashboard() {
|
||||
if s.ctx.SSE != nil {
|
||||
s.ctx.SSE.Publish("dashboard.updated", "{}")
|
||||
}
|
||||
}
|
||||
|
||||
// cachedTyped 泛型版缓存:与 cached 同为 TTL + SETNX 防击穿,
|
||||
// 区别是返回强类型,调用方不必再做类型断言(看板快照等结构化数据用这个)。
|
||||
func cachedTyped[T any](ctx context.Context, s *Service, key string, ttl int, build func() (T, error)) (T, error) {
|
||||
|
||||
@@ -97,6 +97,7 @@ func (s *Service) GenerateMaterialRequest(ctx context.Context, planDate string,
|
||||
}
|
||||
}
|
||||
s.ctx.EventLog.Write(ctx, "material.request.generate", "", operator, "material_request", planDate, "按日排产自动生成备料单", map[string]any{"planDate": planDate, "count": created})
|
||||
s.notifyDashboard()
|
||||
return created, nil, nil
|
||||
}
|
||||
|
||||
@@ -127,5 +128,6 @@ func (s *Service) SetMaterialRequestStatus(ctx context.Context, requestNo, statu
|
||||
if n == 0 {
|
||||
return errors.New("备料单不存在")
|
||||
}
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ func (s *Service) ReportScan(ctx context.Context, req ScanReq, operator string)
|
||||
if err == nil && wp != nil && wp.WorkOrderId > 0 {
|
||||
s.bumpWorkOrderProgress(ctx, wp.OrderNo, wp.Sn)
|
||||
}
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ func (s *Service) ReportTorque(ctx context.Context, req TorqueReq, operator stri
|
||||
}
|
||||
s.ctx.EventLog.Write(ctx, "torque.report", workOrderNo, operator, "torque_record", req.Sn, "接收拧紧数据上报", map[string]any{"strain": req.Strain, "angle": req.Angle, "result": result})
|
||||
s.evaluateTorqueCriterion(ctx, req.Sn, req.StationNo, req.Strain, req.Angle, operator)
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ func (s *Service) CreateWorkOrder(ctx context.Context, req WorkOrderReq, operato
|
||||
return err
|
||||
}
|
||||
s.ctx.EventLog.Write(ctx, "work.order.create", req.WorkOrderNo, operator, "work_order", req.WorkOrderNo, "创建工单", map[string]any{"quantity": req.Quantity})
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -120,6 +121,7 @@ func (s *Service) UpdateWorkOrder(ctx context.Context, req WorkOrderReq, operato
|
||||
if err == nil {
|
||||
s.ctx.EventLog.Write(ctx, "work.order.update", wo.WorkOrderNo, operator, "work_order", wo.WorkOrderNo, "更新工单", nil)
|
||||
}
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -201,6 +203,7 @@ func (s *Service) SetWorkOrderStatus(ctx context.Context, id int, status, reason
|
||||
map[string]any{"from": wo.Status, "to": status, "reason": reason})
|
||||
// 联动:DONE/CANCELLED → 该工单未完成排产批量取消;IN_PROGRESS → 排产置执行中
|
||||
s.syncPlansByOrderStatus(ctx, wo.WorkOrderNo, status, operator)
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -244,4 +247,4 @@ func (s *Service) DeleteWorkOrder(ctx context.Context, id int, operator string)
|
||||
}
|
||||
s.ctx.EventLog.Write(ctx, "work.order.delete", wo.WorkOrderNo, operator, "work_order", wo.WorkOrderNo, "删除工单", map[string]any{"status": wo.Status})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ func (s *Service) OnlineWorkpiece(ctx context.Context, req OnlineReq, operator s
|
||||
return err
|
||||
}
|
||||
s.ctx.EventLog.Write(ctx, "workpiece.online", req.OrderNo, operator, "workpiece", req.Sn, "工件进线登记", nil)
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -141,6 +142,7 @@ func (s *Service) ReportProcess(ctx context.Context, req ReportProcessReq, opera
|
||||
|
||||
s.ctx.EventLog.Write(ctx, "workpiece.process.report", wp.OrderNo, operator, "workpiece", req.Sn,
|
||||
"工位报工", map[string]any{"processCode": req.ProcessCode, "result": result})
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -202,6 +204,7 @@ func (s *Service) DoneWorkpiece(ctx context.Context, req DoneReq, operator strin
|
||||
s.bumpWorkOrderProgress(ctx, wp.OrderNo, req.Sn)
|
||||
s.bumpDailyPlanCompleted(ctx, wp.OrderNo, now)
|
||||
s.ctx.EventLog.Write(ctx, "workpiece.done", wp.OrderNo, operator, "workpiece", req.Sn, "完工+关联追溯", map[string]any{"batchItems": req.BatchItems, "serialItems": req.SerialItems})
|
||||
s.notifyDashboard()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -78,4 +78,4 @@ func (h *Hub) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user