fix: rebuild MES as compilable go-zero+ent backend (renamed bj_power_mes), restore 3 workstation projects from pristine original, align naming; all Go projects go build clean

This commit is contained in:
SunYF
2026-08-27 10:56:41 +08:00
parent 380715f8a9
commit 371b494c54
523 changed files with 67923 additions and 24758 deletions
+213 -4
View File
@@ -1,5 +1,214 @@
下面我进行球面膜项目的流程场景演示 。现在全检台是两个插位,暂存台是一个插位。我新建一个工单,是7个工件。我从第一步开始说,每一步说清楚它的状态、信号等。现在开始,我先在接驳台上。1号槽放job1。 接驳台台这时候没有其他工件,紧接着触发最小执行单元,转向台最小执行单元,包括软件向Plc发送转向台放料信号PLc回复转向台放料完成,软件发送转向台取料信号,Plc转向台回复取料完成,。磨床收到软件的放料信号,回复放料完成。
磨床触发 M3600 完成信号。
软件发送取料信号,收到取料完成气吹机构收到软件信号,占用机器人进行气吹。气吹完成后回复“吹完”,接驳台收到软件放料信号,软件收到接驳台放料完成,第一个工具走完流程,接下来进行第二个,接下来我再接驳台234567全部加上工件,触发第二个工件也就是job 2 然后也是执行转向台最小执行单元,然后上磨床,磨床加工完回复m3600信号,这个时候执行的是换料,也就是说,软件没有去罗床取下去,而是发送了一个接驳台取料信号,取走了job 3,经过转向台,然后给然后给模长发送了一个换料信号,这个时候,机械臂因为有两个爪子,他就把磨床上面的工件二拿起来,把刚才从接驳台取的工件三放进去,紧接着,他去气吹机构持有料操作,气吹完成以后工件又运到了全检台上面,这个时候,工件二,工件一都在全检台,工件三在磨床,因为全检台满了,所以全剪裁收到了,软件发给他的已满,待检查,待人工检查信号,接着,人工检查马上人工检查完成,软件收到了,完成信号,开始把全剪裁的工件搬运到接驳台,当他正在搬运第一个的工具时,收到了,磨床的m3600完成信号,因为磨床优先级比较高,所以机器人把全剪裁的一个工件搬运完,也就是执行完一个最小操作单元以后马上,进行磨床换料操作,也就是说机器人先到接驳台取料,然后是转向台,然后是磨床换料操作,这一步完成以后,磨床上面放的是工件4,工件三在气吹机构,因为气吹机构占用机器人,所以全检台未完成的工作也无法继续,等气吹机构完成以后,机器人去全检台换料,这时候,他拿起了全剪裁的工件二,并把工件四放到了二的位置上,然后机器人把工件二放回接驳台,到这一步,两个完成检查的工件一和二全部到接驳台,并且是在原来的槽位一和槽位二上面,磨床工件是在加工工件三在全检台,因为全检台只有一个工件,所以也不需要人工检查,紧接着,工件4加工完成软件,收到m3600信号。上面的流程里面有几件事情,第一件事情,刚才的磨床优先是要把转向台给捎带上去的,因为他们俩是一个整体,第二件事情转向台和磨床是一个整体,没有哪个工件会在转向台待着,它不停留,第三个事情,气吹机构是持料气吹占用机器人。第四个内容全检台放满以后,而且是未检查的工件,才会请求人工检查。关于全检台露出了一种场景,那就是如果全检台两个已完成工件,一个也没有回到接驳台,这个时候机器人操作一个模模完的工件去全检台由于是换料操作这个时候全检台会存在一个检查完成,一个没有检查完成的,因为不是全部检查完成的工件,虽然槽位满了,全检才槽位满了,但是也不能收到,也软件也不能给PRC发送,请求检查的信号。
# 高压清洗机 FANUC 宏变量控制方案(待确定)
继续,弓箭是走流程,走到了全检台,弓箭五也是换料的方式,走到了磨床工件五加工完成工件六以换料的方式到磨床工件五到缓存台,这个时候缓存台一个全检台两个满,全检台收到等待人工检查信号。此时人工没有检查,机器人全检台,缓存台都是满的。这里有一个事情要说,转线台不是空的吗?是空的,但是也不需要把接驳台的工件7放到机构台,不需要。这时候收到磨床加工完成信号,由于没有地方放了,管理后台页面收到警告,会问为什么不把光件七去汽车台先吹着?因为气吹台会占用机器人所以不要吹,否则等其他地方如果是非全检材,需要操作的时候机器人被占用。紧接着,人工开始检查,并且检查完,软件收到检查完成信号,这个时候因为魔床优先,所以如果接驳台还有工件机器人会接驳台取货,然后磨床换料,然后把工件漆拿到全检台换料,并把从全检台换料下来的已检查完成的工件放到接驳台原来的位置然后机器人会把全检台剩下的另一个检查完成的工件放回到接驳台,注意全前台有空位,并且暂存台有工件,所以进行回流,把缓存站站台的工件放到全检台放满为止,或者缓存台没有货,没有工件为止,这时候如果是全检台放满了,就要发等待人工检查信号给plc。你流程收尾最后一个工作流程收尾你做的已经比较好了,就不再描述,简单提一下,收尾第一种说法接驳台没货了这时候磨床是取料操作,不是换料,接驳台有货时,工单继续进行。第二种情况,收尾是工单的最后一个件,同样,磨床也是取料操作,全检台还是换换料操作,这时候全检台如果没有满,软件应该让PRC把缓存台的工件回流到全检台,如果有的话,即便是全检台,没有板也要收到人工检查,再检查信号,等人工去检查。人工检查完,回到接驳台。如果接驳台有位置。理论上,接驳台应该有位置,因为工件是从哪取,从哪放,放回了哪。关于接驳台收尾工单完成或者接驳台满了,都应该向agv或M0m发送报工
## 一、业务背景
高压清洗机(设备ID=5)的加工程序按零件号分成 **9 组**,通过 FANUC(发那科)CNC 宏变量 `#666`(左工位)和 `#888`(右工位)的值来调用对应的子程序(O1001~O1018)。
当前软件只发送 `workpieceType`(毛坯号,即 product_type 主键ID)给 PLC**没有**发送零件号和 FANUC 宏变量的功能,需要新增。
## 二、业务规则
### 1. 零件号 → 组号映射(9组,共19个零件号)
| 组号 | #666(左) | #888(右) | 种类 | 毛坯号 | 零件号 |
|---|---|---|---|---|---|
| 1 | 1 | 1 | A6VM107 | B99414 | B02858、B20044、B20223、B20480 |
| 2 | 2 | 2 | A6VM107 | B99414 | B20177、B20248、B20538 |
| 3 | 3 | 3 | A6VM107 | B99487 | B20227、B20257 |
| 4 | 4 | 4 | A6VM160 | B99464 | B20141 |
| 5 | 5 | 5 | A6VM160 | B99464 | B20061、B20235 |
| 6 | 6 | 6 | A6VM160 | B99464 | B02943 |
| 7 | 7 | 7 | A6VM160 | B99464 | B20149 |
| 8 | 8 | 8 | A6VM160 | B99488 | B20240 |
| 9 | 9 | 9 | A6VM200 | B99259 | B02533、B02681、B20102、B20144 |
> 注:第9组零件号以你核对过的 `临时.txt` 为准(B02533);手写稿中记为 B20533,旧Excel图片中亦为 B02533。
### 2. 高压清洗机运行流程(新)
```
放料前:
1. 从工单取出零件号(新建工单时用户选择,存入子表)
2. 根据零件号查映射表,得到组号(1~9)
3. 通过 FANUCgofocas 库)写入宏变量:
左工位 → #666 = 组号
右工位 → #888 = 组号
4. 通过 PLC 发送放料命令(M1040,现有逻辑不变)
5. 通过 PLC 发送启动命令(M1144.2,现有逻辑不变)
清洗完成后:
6. 两个槽位都必须完成,才能取料
7. 禁止换料(exchange),先全部取下,再单独放入
```
## 三、改动清单(按模块)
### 1. 数据库(新增2张表 + 1个字段)
**新表 `part_no`(零件号表)**:存零件号、所属毛坯号、清洗机组号
| 字段 | 说明 |
|---|---|
| id | 主键,自增 |
| code | 零件号(如 B02858),全局唯一,工单选择零件号时显示的选项值 |
| productTypeId | 所属毛坯号(关联 product_type.id),与现有工件分类体系保持一致,**此主键ID是所有其他设备(CNC、去毛刺等)识别工件类型的依据,不可改变** |
| washerGroupNo | 高压清洗机组号(1~9),即写入 FANUC 宏变量 #666/#888 的值;仅高压清洗机使用,其他设备忽略 |
| remark | 备注(可选) |
| createdAt | 创建时间 |
**新表 `work_order_part`(工单零件号表)**:存工单选了哪个零件号
| 字段 | 说明 |
|---|---|
| id | 主键 |
| workOrderId | 工单ID(关联 work_order.id |
| partNoId | 零件号ID(关联 part_no.id |
**equipment 表**:高压清洗机记录(ID=5)的 `ipAddress` 字段值 = FANUC 连接地址,格式 **`IP:端口`**(如 `192.168.x.x:8193`),**不写死端口**,生产提供后整串填入;端口默认 8193,但以数据库实际配置为准。
### 2. 前端(新建工单弹窗)
现有选择是两级:`种类 → 毛坯号`[work-order-editor/index.tsx](frontend/src/components/work-order-editor/index.tsx) 的 Select 分组)。
改为三级:`种类 → 毛坯号 → 零件号`,样式不变,多一层显示,用户选择零件号后随工单一起提交。
### 3. 后端
**新增 FANUC 通讯模块**(替换现有 `internal/cnc/` 的 stub):
- 使用公用库 `bjhardman.cn/bjhardman/gofocas`(与 goplc 同仓库,已有权限)
- 连接地址从 equipment 表 `ipAddress` 字段读取(格式 `IP:端口`,如 `192.168.x.x:8193`
- 提供写宏变量方法:`SetMacroVar(addr, macroNo, value)`,即写 #666/#888
**清洗机调度流程修改**[washer_orchestrator.go](internal/processor/eventloop/washer_orchestrator.go)):
- 放料动作前插入"查零件号 → FANUC 写 #666/#888"
- 卸载逻辑取消换料(exchange),改为两个槽位都完成后再逐个取出
**新建工单逻辑修改**[create_work_order_logic.go](internal/logic/workorder/create_work_order_logic.go)):
- 接收并保存零件号到 `work_order_part`
### 4. 种子数据(追加到 doc/data.sql
19 条 `part_no` 记录(映射关系见第二节表格,数据已核对)。
## 四、实施顺序(确认后按此执行)
1. 拉取 gofocas 库,确认其 API(写宏变量的方法签名)
2. 数据库:新增 part_no、work_order_part 表 + 种子数据
3. 后端:FANUC 通讯模块封装
4. 前端:工单选择增加零件号层级
5. 后端:清洗机流程接入 FANUC 写入 + 取消换料
6. mockrun 验证(gofocas 用 mock 模拟)
## 五、待确认事项
1.**gofocas 库**:与 goplc 同仓库,有权限可拉取,实施时直接 `go get`
2. **FANUC 连接地址**:生产提供高压清洗机 CNC 的 `IP:端口`(端口默认 8193),填入 equipment.ip_address,先留空
3.**一个工单只选一个零件号**:已确认,工单内所有工件同一零件号
4. **说明**:本方案只**追加**新表/新数据,不修改 signals.sql 及现有信号(StartMeasure 等在 signals.sql 中保持不变)
---
## 六、代码示例(放文档底部,仅供确认,不直接改代码)
### 1. 种子数据 SQL(追加到 doc/data.sql
```sql
-- 零件号表(含清洗机组号)
CREATE TABLE IF NOT EXISTS part_no (
id SERIAL PRIMARY KEY,
code VARCHAR(20) NOT NULL UNIQUE,
product_type_id INT NOT NULL REFERENCES product_type(id),
washer_group_no INT NOT NULL,
remark VARCHAR(255) DEFAULT '',
created_at TIMESTAMPTZ DEFAULT now()
);
COMMENT ON TABLE part_no IS '零件号表(高压清洗机按零件号分9组程序)';
COMMENT ON COLUMN part_no.id IS '主键,自增';
COMMENT ON COLUMN part_no.code IS '零件号(如 B02858),全局唯一,工单选择零件号时的选项值';
COMMENT ON COLUMN part_no.product_type_id IS '所属毛坯号(关联 product_type.id),与现有工件分类体系一致,此主键ID是所有设备(CNC、去毛刺等)识别工件类型的依据,不可改变';
COMMENT ON COLUMN part_no.washer_group_no IS '高压清洗机组号(1~9),即写入 FANUC 宏变量 #666/#888 的值;仅高压清洗机使用,其他设备忽略';
COMMENT ON COLUMN part_no.remark IS '备注(可选)';
COMMENT ON COLUMN part_no.created_at IS '创建时间';
-- 工单零件号关联表
CREATE TABLE IF NOT EXISTS work_order_part (
id SERIAL PRIMARY KEY,
work_order_id INT NOT NULL REFERENCES work_order(id),
part_no_id INT NOT NULL REFERENCES part_no(id),
created_at TIMESTAMPTZ DEFAULT now()
);
COMMENT ON TABLE work_order_part IS '工单零件号关联表(一个工单只选一个零件号)';
COMMENT ON COLUMN work_order_part.id IS '主键,自增';
COMMENT ON COLUMN work_order_part.work_order_id IS '工单ID(关联 work_order.id),一个工单只对应一个零件号';
COMMENT ON COLUMN work_order_part.part_no_id IS '零件号ID(关联 part_no.id';
COMMENT ON COLUMN work_order_part.created_at IS '创建时间';
-- 种子数据(19个零件号,对应9组)
INSERT INTO part_no (code, product_type_id, washer_group_no) VALUES
('B02858', 1, 1), ('B20044', 1, 1), ('B20223', 1, 1), ('B20480', 1, 1),
('B20177', 1, 2), ('B20248', 1, 2), ('B20538', 1, 2),
('B20227', 2, 3), ('B20257', 2, 3),
('B20141', 3, 4),
('B20061', 3, 5), ('B20235', 3, 5),
('B02943', 3, 6),
('B20149', 3, 7),
('B20240', 4, 8),
('B02533', 5, 9), ('B02681', 5, 9), ('B20102', 5, 9), ('B20144', 5, 9);
-- 高压清洗机 FANUC 连接地址(格式 IP:端口,如 192.168.x.x:8193;待生产提供,先留空)
UPDATE equipment SET ip_address = '' WHERE id = 5;
```
### 2. FANUC 通讯模块(internal/cnc/ 替换 stub
```go
package cnc
// 写 FANUC 宏变量(如 #666、#888
// gofocas 库 API 以实际拉取到的版本为准,这里先画结构
// 连接地址从 equipment.ip_address 读取,格式 "IP:端口"(如 192.168.x.x:8193),端口不写死
type Client struct {
addr string // equipment.ipAddress,格式 "IP:端口"
}
func NewClient(addr string) *Client {
return &Client{addr: addr}
}
// WriteMacro 写宏变量,如 WriteMacro(666, 1)
func (c *Client) WriteMacro(ctx context.Context, macroNo int, value int) error {
// 解析 addr 为 host:port,调用 gofocas 库:连接 → 写宏变量 → 断开
return nil
}
```
### 3. 清洗机放料流程(washer_orchestrator.go 改动点)
```go
// 放料动作前:写 FANUC 宏变量
// 伪代码,具体以现有 buildWasherLoadActions 结构为准
for _, act := range actions {
if act.Kind == "load_to_machine" && act.MachineID == WASHER_HP {
// 1. 查零件号
partNo := queryWorkOrderPart(act.JobID)
// 2. 查组号
groupNo := partNo.washerGroupNo
// 3. FANUC 写宏变量(slotNo=1 写 #666slotNo=2 写 #888
fanuc.WriteMacro(ctx, 666, groupNo) // 左
fanuc.WriteMacro(ctx, 888, groupNo) // 右
// 4. 再走现有 PLC 放料
}
}
```
### 4. 前端三级选择(work-order-editor/index.tsx 改动点)
```tsx
// 现有:种类 → 毛坯号(两级)
// 新增:毛坯号 children 下再加零件号一层
// 数据来源:listProductTypes 接口扩展返回 partNos 数组
// 提交时:productTypeId + partNoId 一起传给 createWorkOrder
```