Files
bj_power/bj_power_mes/CLAUDE.md
T

175 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
液压马达后盖(A6VM107/160/200CNC 产线管控系统。控制西门子 PLC 驱动的工业机器人 + 4台CNC + 清洗机 + 去毛刺机 + 检测设备 + 接驳台。
- **后端**: Go 1.25go-zero v1.8.3ent ORM v0.14.5PostgreSQLRedis(缓存辅助)
- **前端**: React 19 + Semi Design UI v2.94 + Zustand + Vite 7`frontend/`pnpm
- **PLC**: 西门子 S7 协议 + FANUC FOCAS + OKUMA OspDirect
- **数据采集**: `back_cover_dc/`(独立项目,Modbus/S7/Focas/OSP-MC/OSP-LATHE 多协议采集)
- **大屏看板**: `dashboard-server/` + `dashboard-client/`(4K 深色大屏,产线概览 + 设备监控 + OEE)
## 关联项目
本仓库位于 `F:\Workspace\Hardman\hougai\`,同级目录还有:
| 项目 | 说明 |
|------|------|
| `back_cover_dc/` | 多协议数据采集服务(Modbus/S7/Focas/OSP),独立 Go 项目,GORM + Fiber |
| `dashboard-server/` | 大屏看板后端,Go + Fiber + sqlx,直连 back_cover 数据库只读查询 |
| `dashboard-client/` | 大屏看板前端,React + TypeScript + ECharts + Semi Design4K 深色主题 |
| `okuma_dc/` | OKUMA 采集器(已废弃,功能已合并到 back_cover_dc 的 osp 协议) |
## 常用命令
```bash
# 后端
go run hougai.go -c etc/hougai-api.yaml # 开发运行
go run cmd/mockrun/main.go # Mock 模拟完整订单流程
go run cmd/debug/main.go -f etc/hougai-api.yaml # 调试面板(端口 8890
build.bat # 构建 bin/hougai.exe
# 前端
cd frontend && pnpm dev # Vite 开发服务器(5173 → 8888
cd frontend && pnpm build # 嵌入 Go 二进制
# 代码生成(修改 schema/api 后必须执行)
cd schema && go generate # ent ORM
cd apis && go generate # handler/logic/types
# 测试
go test ./internal/processor/... # 单包测试
go test -cover ./... # 覆盖率(Windows 上 -race 不可用)
go vet ./... # 静态分析
```
## 全局规则
- **禁止自动提交 git**
- handler 保持薄层,业务逻辑在 logic
- 不手动修改 `ent/``internal/handler/``internal/types/`(自动生成)
- 不用 `goctl`/`ent init`,用 `cd apis && go generate` / `cd schema && go generate`
- API 变更先改 `apis/*.api`schema 变更先改 `schema/*.go`,再生成
- **processor 包用 `log/slog`**,不用 `go-zero/core/logx`
- 所有命令加 `rtk` 前缀
## 编码准则
**先想后写**:不确定时停下来提问。有多种解读时列出选项,不要默默选择。有更简单方案时提出反对意见。
**简单优先**:用最少代码解决问题。不为单次使用创建抽象。不写不可能出现的错误处理。200 行能变 50 行就重写。
**精准改动**:只改必须改的部分。不改相邻代码、注释、格式。不改没坏的东西。风格匹配现有代码,即使你本会写成另一种风格。只清理你自己的改动产生的孤儿引用/import/变量。
**目标驱动**:把任务转化为可验证目标。"修 bug" → "先写能复现的测试,再修"。多步骤任务先列简明计划。让成功标准明确,才能独立推进。
## 架构
### 核心设计:DB SSOT + 单线程事件循环
PostgreSQL 是唯一运行时真相源。所有状态写入由 `ProductionEventLoop` 单线程串行处理。HTTP handler 直接查询 ent/PostgreSQL(读取无需经过 event loop)。
**状态写入路径**HTTP handler → EventLoopMessage → ProductionEventLoop → DBState 条件更新 → ent → PostgreSQLPLC 信号 → SignalRouter → Actor.signalCh → Actor 写 DB + 投递 MACHINE_DONE → EventLoop 推进步骤 + 调度。
### eventloop 包(`internal/processor/eventloop/`
- **`ProductionEventLoop`**`loop.go`)— 从 `msgCh`256)接收消息串行处理,`time.Timer`60s)触发 `trySchedule`。消息类型:CommandSTART_ORDER/PAUSE_ORDER/...)、ExternalEventMACHINE_DONE/INSPECTION_RESULT/STEP_TIMEOUT)、WorkerResult
- **`DBState`**`dbstate.go`)— ent 条件更新:`AdvanceStep`(链式跳步,上限 100 次防循环)、`CompleteStep``FinishJob``SetEquipmentSlot`Actor 独占调用)
- **`RecoverOnStartup`**`recovery.go`)— IN_PROGRESS→PAUSED + 校验 slot 一致性,不一致项创建 manual_action
- **`RuntimeSnapshot`** — DB 只读快照,替代旧 JobRuntime 状态机
### processor 包
- **`scheduler_bridge.go`** — RuntimeSnapshot→JobView→CandidateTask→RobotAction 映射。补料在调度管线**之前**处理。`prePairWasherLoads` 按 TargetID:Category 分组配对。`findExchangePair` 校验同 category
- **`Replenisher`** — 接驳台→暂存台补料。硬编码配额(8 槽位按活跃 category 分配:3类→3:3:22类→4:4/5:3,单类→8)。触发:占用 ≤ quota/2
- **`RobotWorker`** — 适配 `robot.Controller``action.HardwareWorker` 接口。通过 Actor 同步方法操作槽位,不直接写 DB。设备特定 PLC 操作(Load/Unload/Exchange)委托 Station 接口,不再包含 machineID 硬编码
- **`JobProcessor`** — 订单生命周期 + jobs map 跟踪
### 调度器(三层架构)
Generator(步骤→候选任务)→ Filter(链式约束:MachineBusy/TempSlotFull/OrderPaused/...)→ Policy8 条优先级规则)。`trySchedule` 触发。
### Actor 系统
每台设备一个 Actorgoroutine + channel),独占槽位状态和 equipment_slot DB 写入权。
**槽位状态机**`Empty → Occupied → Done → Empty`。外部组件无权直接写 equipment_slot。
**信号流**PLC → SignalRouter 轮询(上升沿,per-actor 通道容量 4)→ Actor.handleSignal → 标记 DONE + 写 DB → 投递 MACHINE_DONE → EventLoop
**通信模式**RobotWorker→Actor(同步),EventLoop→Actor(异步消息),Actor→EventLoop(异步事件)
**TempStoreActor**:暂存台槽位唯一写入口。`AllocateSlot`/`ReleaseSlot`(同步,补料器调用)、异步消息循环处理 ALLOCATE/RELEASE/RESTORE。
### Recipe Decision/Judge
4 种 `decisionType`:空(无条件设 key)、`negate_bool``scan_mismatch``signal_true`(需实时读 PLC,只能 in trySchedule 处理)。非 signal_true 由 AdvanceStep 内联链式推进。
### Category 活跃工单互斥
每个 category 最多一个活跃工单(IN_PROGRESS 或 PAUSED)。创建时后端强制校验 + 前端下拉过滤已占选项。
### 事件总线与 EventLog
`LocalBus`(进程内 channel)。EventLogWriter 订阅所有事件,批量写入 `event_log`batch 20/1s)。SSE Bridge 推送到前端。
**SSE vs HTTP API 格式差异**SSE 结构化字段在 `payload` 内,HTTP API 在顶层。前端 `normalizeEventLog()` 统一适配。
### 补料 & 废料搬运
补料:trySchedule 前检查 → BuildReplenishCandidate → 预分配暂存槽位 → RobotWorker 执行 replenish → EventLoop 处理结果。
扫码失败两条路径:补料扫码失败→保留槽位标记 WAITING_WASTE→ActionLoadWaste 搬运;标准扫码失败→工件直接放废料台→释放槽位+Scrap。ActionLoadWaste 豁免 OrderPaused/JobSuspended 约束。
### 恢复系统
启动时 `RecoverOnStartup` 将 IN_PROGRESS → PAUSED 并校验一致性(不一致项创建 ManualAction)。工单恢复由用户手动触发。
### 抽检台
machineID=9SAMPLING 类型,1槽位。OP100 Decision signal_true 读 SamplingRequest → 分支到 SAMPLING 步骤。onInspect 回调判定合格/不合格。
## 数据库
PostgreSQL `127.0.0.1:5432`,库 `back_cover`,用户 `postgres`。ent ORMschema 在 `schema/`,生成在 `ent/`,自动迁移。
核心表:work_orderfinishedNum/failNum 原子累加)、jobcurrent_step_id)、equipment/equipment_slotbatch 字段)、dock_slot、product_typecategory: A6VM107/160/200/recipe/recipe_stepstep_id: OP10-OP120next_step_default/branches)、signalPLC 地址映射)、alarm、manual_action、event_log/task_log。
## 前端
React 19 + Semi Design UI v2.94 + Zustand + HashRouter。SSE 实时更新。路由:`/dashboard`(主控面板)、`/work-order``/workpiece``/equipment``/alarm``/recipe``/system`。WorkOrderPanel 通过 SideSheet 弹窗展示详情。
## 配置
`etc/hougai-api.yaml` — 端口 8888。`Mock.Enable=true` 时使用 MockPLC/MockMarking 无硬件测试。Redis 仅用于缓存辅助。
## 架构概览
```
internal/
├── action/ # RobotAction + HardwareWorker 接口(独立包,避免循环依赖)
├── alarm/ # 报警服务
├── eventlog/ # EventLog 持久化(订阅 EventBus,批量写入)
├── processor/ # 核心引擎
│ ├── actor/ # Actor 模型(MachineActor + TempStoreActor + SignalRouter
│ ├── station/ # Station 接口(设备特定 PLC 操作:Load/Unload/Exchange + 扩展接口)
│ ├── tool/ # 手持工具(Scanner/LaserMarker
│ ├── scheduler/ # Generator/Filter/Policy 三层调度
│ ├── eventloop/ # DB SSOT 事件循环 + 调度桥接 + 恢复
│ ├── factory.go # BuildProductionLine 产线组装(Actor + Station
│ ├── job_processor.go / robot_worker.go / replenisher.go
│ └── interface.go
├── svc/ # DI 组装(ServiceContext
├── robot/ # PLC 机器人控制(dock/machine/temp_station/washer/...
├── sse/ # SSE 实时推送
└── preload/ # DB 数据内存缓存(PLC 信号映射 + Category 映射)
```
## 已知问题
- `internal/preload/``internal/robot/` 有构建失败的测试
- `internal/camera/` 测试需真实硬件
- Windows 上 `-race` 不可用