Files
bj_power/bj_power_mes/CLAUDE.md
T

162 lines
7.4 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.
## 项目概述
磨床自动化单元管控系统。控制西门子 PLC 驱动的工业机器人串联 6 台设备完成毛坯到成品的全流程加工。
- **后端**: Go 1.25go-zero v1.8.3ent ORM v0.14.5PostgreSQL
- **前端**: React 19 + Semi Design UI v2.94 + Zustand + Vite 7`frontend/`pnpm
- **PLC**: 西门子 S7 协议(Snap7
## 常用命令
```bash
# 后端
go run . -f etc/spherical-api.yaml # 开发运行
go run cmd/mockrun/main.go -debug -jobs 3 # Mock 全流程模拟
go run cmd/debug/main.go -f etc/spherical-api.yaml -p 8890 # 调试面板
# 前端
cd frontend && pnpm dev # Vite 开发服务器
cd frontend && pnpm build # 构建,输出到 public/
# 构建
./build.sh # macOS/Linux 构建脚本
# 代码生成(修改 schema/api 后必须执行)
cd schema && go generate # ent ORM
cd apis && go generate # handler/logic/types
# 数据库初始化
go run schema/tools/migrate.go # 建表
go run schema/tools/data.go seed signals # 导入种子数据 + 信号
# 测试
go test ./internal/processor/... # 单包测试
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`
## 编码准则
**先想后写**:不确定时停下来提问。有多种解读时列出选项,不要默默选择。有更简单方案时提出反对意见。
**简单优先**:用最少代码解决问题。不为单次使用创建抽象。不写不可能出现的错误处理。
**精准改动**:只改必须改的部分。不改相邻代码、注释、格式。不改没坏的东西。风格匹配现有代码。
**防御式编程**:所有函数返回 error 不许直接 `_` 忽略,必须日志告警或向上抛出。禁止隐性失败。
## 架构
### 核心设计:DB SSOT + 单线程事件循环
PostgreSQL 是唯一运行时真相源。所有状态写入由 `ProductionEventLoop` 单线程串行处理。HTTP handler 直接查询 ent/PostgreSQL(读取无需经过 event loop)。
**状态写入路径**HTTP handler → EventLoopMessage → ProductionEventLoop → DBState 条件更新 → ent → PostgreSQLPLC 信号 → SignalRouter → EventLoop 投递 → handleMachineSignal → Actor 标记槽位 → trySchedule。
### eventloop 包(`internal/processor/eventloop/`
- **`ProductionEventLoop`**`loop.go`)— 从 `msgCh`256)接收消息串行处理,`time.Timer`60s)触发 `trySchedule`。消息类型:CommandSTART_ORDER/PAUSE_ORDER/...)、ExternalEventMACHINE_DONE/MACHINE_SIGNAL/SCHEDULE_TICK)、WorkerResult
- **`DBState`**`dbstate.go`)— ent 条件更新:`AdvanceStep`(链式跳步)、`CompleteStep``FinishJob``SetEquipmentSlot`
- **`RecoverOnStartup`**`recovery.go`)— 启动恢复未完成工单
- **`RuntimeSnapshot`** — DB 只读快照,缓存工件当前步骤信息
### 调度器(三层架构)
Generator(步骤→候选动作)→ Filter(链式约束:MachineBusy/MachineEmpty/CacheSlotFull/OrderPaused/JobSuspended/ExchangePair/MachineWait)→ Policy(优先级规则)。`trySchedule` 触发。
一次调度只派遣一个 Worker 动作,确保机器人串行执行。
### Actor 系统
每台设备一个 MachineActor(mutex 保护的状态结构体),负责槽位状态管理。不写 DB,不操作 PLC。
**槽位状态机**`Empty → Occupied → Done → Empty`
**信号流**PLC → SignalRouter 轮询(上升沿检测)→ EventLoop.handleMachineSignal → Actor.MarkSlotDone → 投递 MACHINE_DONE → trySchedule。
### 设备类型
| 设备 | 槽位数 | 支持 Exchange |
|------|--------|--------------|
| GRINDER 磨床 | 1 | 是 |
| TURN_TABLE 转台 | 1 | 是 |
| AIR_BLOW 气吹 | 1 | 否 |
| FULL_CHECK 全检台 | 2 | 否 |
| CACHE 缓存台 | 1 | 否 |
| DOCK 接驳台 | 84 | 否 |
### 事件总线与 EventLog
`LocalBus`(进程内 channel)。EventLogWriter 订阅所有事件,批量写入 `event_log`。SSE Bridge 推送到前端。
### 恢复系统
启动时 `RecoverOnStartup` 恢复未完成工单,校验一致性。工单恢复由用户手动触发。
## 数据库
PostgreSQLent ORMschema 在 `schema/`,生成在 `ent/`,自动迁移。
核心表:work_order、job、equipment、equipment_slot、recipe、recipe_step、signal、alarm、event_log。
## 前端
React 19 + Semi Design UI v2.94 + Zustand + HashRouter。SSE 实时更新。
## 配置
`etc/spherical-api.yaml` — 端口 8888。`Mock.Enable=true` 时使用 MockPLC 无硬件测试。
## 架构概览
```
internal/
├── action/ # 动作定义(RobotAction 结构体 + 校验方法)
├── alarm/ # 报警服务
├── engine/ # 全配置化流程引擎(ACQUIRE→EXECUTE→WAIT→COMPLETE
│ ├── engine.go # 核心引擎,TryAdvanceJob 主循环,AlarmService 接口
│ ├── acquirer.go # 资源获取,SELECT FOR UPDATE 事务,死循环检测+报警
│ ├── executor.go # 信号发送,按 sort_order 写入 PLC,失败报警
│ ├── completer.go # 后置操作+Done 信号匹配,资源释放/状态设置/跳转
│ ├── decision.go # 决策步骤处理,按 priority 匹配条件分支
│ ├── db_ops.go # 数据库操作封装,加载配置、读写资源
│ ├── adapter.go # I/O 层适配器,桥接引擎与 SignalRouter/PLC
│ └── types.go # 类型定义,Job/JobStep/StepSignal/StepAction
├── eventlog/ # EventLog 持久化
├── processor/ # 核心引擎(旧架构,仍运行中)
│ ├── actor/ # MachineActor + SignalRouter
│ ├── eventloop/ # ProductionEventLoop + DBState + 调度桥接 + 恢复
│ ├── scheduler/ # Generator/Filter/Policy 三层调度(将被 engine 替代)
│ ├── plcactions/ # PlcExecutorPLC 信号握手)
│ ├── steplog/ # 步骤日志
│ ├── factory.go # BuildProductionLine 产线组装
│ ├── job_processor.go / plc_worker.go
│ └── recipe_loader.go
├── svc/ # ServiceContext 根容器
├── robot/ # 机器人控制器
├── sse/ # SSE 实时推送
├── plc/ # PLC 连接管理
└── preload/ # 信号地址/产品类型内存缓存
```
### engine 包(新架构)vs processor 包(旧架构)
| 维度 | engine(新) | processor(旧,仍运行) |
|------|------------|----------------------|
| 定位 | 纯执行器,零业务知识 | 包含业务逻辑(if磨床/接驳台) |
| 触发 | 事件驱动(EventLoop 调用) | 消息驱动(msgCh channel |
| 调度 | 资源-based,按 job_step 推进 | 过滤器链 + 候选动作生成 |
| 并发 | SELECT FOR UPDATE 事务 | 单 goroutine 串行 + atomic.Bool |
| 配置 | 全部 DB 子表配置 | 代码硬编码 + 部分 DB |