2026-08-27 10:09:54 +08:00
|
|
|
|
# 前端 API 文档(基于《系统设计方案.md》)
|
|
|
|
|
|
|
|
|
|
|
|
> 版本依据:`系统设计方案.md` V2.4(2026-05-01,最终生产版·固定槽位与批量补料)
|
|
|
|
|
|
> 适用对象:React 前端、API 对接、联调、后续接口生成
|
|
|
|
|
|
> 说明:本文描述目标设计契约,不以当前过渡期 `apis/*.api` 的实现为准。若当前实现与本文不一致,应以本文作为后续对齐目标。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 通用约定
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 Base URL
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
/api/v1
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 鉴权
|
|
|
|
|
|
|
|
|
|
|
|
除登录、刷新 token 外,所有接口默认需要登录态。
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
Authorization: <accessToken>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 1.3 时间格式
|
|
|
|
|
|
|
|
|
|
|
|
前端统一按 ISO 8601 字符串处理时间。
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type ISODateTime = string // 例:2026-05-01T10:30:00+08:00
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 1.4 分页参数
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface PageReq {
|
|
|
|
|
|
page?: number // 默认 1
|
|
|
|
|
|
limit?: number // 默认 10,最大 100
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface PageReply {
|
|
|
|
|
|
page: number
|
|
|
|
|
|
limit: number
|
|
|
|
|
|
total: number
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 1.5 排序参数
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface SortReq {
|
|
|
|
|
|
sort?: string
|
|
|
|
|
|
order?: 'asc' | 'desc' | 'ascend' | 'descend'
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 1.6 通用响应 envelope
|
|
|
|
|
|
|
|
|
|
|
|
目标设计建议前端统一按如下响应格式接入;如果后端某些接口仍返回裸数据,需要在请求封装层兼容。
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ApiResponse<T> {
|
|
|
|
|
|
code: number
|
|
|
|
|
|
message: string
|
|
|
|
|
|
data: T
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
成功:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"code": 0,
|
|
|
|
|
|
"message": "ok",
|
|
|
|
|
|
"data": {}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
失败:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"code": 40001,
|
|
|
|
|
|
"message": "工件状态不允许执行该操作",
|
|
|
|
|
|
"data": null
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 核心枚举
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 工单状态 `WorkOrderStatus`
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type WorkOrderStatus =
|
|
|
|
|
|
| 'CREATED'
|
|
|
|
|
|
| 'IN_PROGRESS'
|
|
|
|
|
|
| 'PAUSED'
|
|
|
|
|
|
| 'COMPLETED'
|
|
|
|
|
|
| 'CANCELLED'
|
|
|
|
|
|
| 'ERROR'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 工件状态 `JobStatus`
|
|
|
|
|
|
|
|
|
|
|
|
来自设计第 7.1 节。
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type JobStatus =
|
|
|
|
|
|
| 'CREATED'
|
|
|
|
|
|
| 'IN_HANDLING'
|
|
|
|
|
|
| 'PROCESSING'
|
|
|
|
|
|
| 'WAITING_UNLOAD'
|
|
|
|
|
|
| 'ON_BUFFER'
|
|
|
|
|
|
| 'WAITING_DECISION'
|
|
|
|
|
|
| 'COMPLETED'
|
|
|
|
|
|
| 'SCRAPPED'
|
|
|
|
|
|
| 'SUSPENDED'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 工件位置类型 `PositionType`
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type PositionType = 'ON_EQUIPMENT' | 'ON_BUFFER' | 'IN_HAND'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.4 设备状态 `StationStatus`
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type StationStatus = 'IDLE' | 'BUSY' | 'WAITING' | 'FAULT' | 'OFFLINE'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.5 任务状态 `TaskStatus`
|
|
|
|
|
|
|
|
|
|
|
|
来自设计第 9 节。
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type TaskStatus =
|
|
|
|
|
|
| 'CREATED'
|
|
|
|
|
|
| 'DISPATCHED'
|
|
|
|
|
|
| 'RUNNING'
|
|
|
|
|
|
| 'SUCCESS'
|
|
|
|
|
|
| 'FAILED'
|
|
|
|
|
|
| 'TIMEOUT'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.6 工序类型 `RecipeStepType`
|
|
|
|
|
|
|
|
|
|
|
|
来自设计第 5.1 节。
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
type RecipeStepType =
|
|
|
|
|
|
| 'LOAD'
|
|
|
|
|
|
| 'BUFFER_STAGE'
|
|
|
|
|
|
| 'MACHINING'
|
|
|
|
|
|
| 'UNLOAD'
|
|
|
|
|
|
| 'WASH'
|
|
|
|
|
|
| 'INSPECTION'
|
|
|
|
|
|
| 'JUDGE'
|
|
|
|
|
|
| 'DEBURR'
|
|
|
|
|
|
| 'RUST_WASH'
|
|
|
|
|
|
| 'FINAL_SCAN'
|
|
|
|
|
|
| 'LASER_MARK'
|
|
|
|
|
|
| 'DECISION'
|
|
|
|
|
|
| 'PLACE_SAMPLING'
|
|
|
|
|
|
| 'PLACE_AGV'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 登录与当前用户
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 登录
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/login
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface LoginReq {
|
|
|
|
|
|
username: string
|
|
|
|
|
|
password: string
|
|
|
|
|
|
captchaId?: string
|
|
|
|
|
|
captchaCode?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface TokenReply {
|
|
|
|
|
|
accessToken: string
|
|
|
|
|
|
accessExpire: number
|
|
|
|
|
|
refreshToken: string
|
|
|
|
|
|
refreshExpire: number
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 刷新 token
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/refreshToken
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface RefreshTokenReq {
|
|
|
|
|
|
refreshToken: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`TokenReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 当前用户信息
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/userinfo
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface UserInfoReply {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
name: string
|
|
|
|
|
|
username: string
|
|
|
|
|
|
mobile: string
|
|
|
|
|
|
gender: number
|
|
|
|
|
|
roleId: number
|
|
|
|
|
|
roleName: string
|
|
|
|
|
|
deptId: number
|
|
|
|
|
|
deptName: string
|
|
|
|
|
|
position: string
|
|
|
|
|
|
status: number
|
|
|
|
|
|
createdAt: number
|
|
|
|
|
|
updatedAt: number
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 产品类型与工艺路线
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 1.1 节机床绑定关系、第 5 节工艺路线定义、第 6.1 节 `product_type/recipe/recipe_step`。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 产品类型列表
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/product-types/list
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ListProductTypesReq {
|
|
|
|
|
|
keyword?: string
|
|
|
|
|
|
activeOnly?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ProductTypeReply {
|
|
|
|
|
|
id: string // 例:A6VM107
|
|
|
|
|
|
code: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
recipeId: string
|
|
|
|
|
|
cncMachineIds: string[] // 例:['CNC_3', 'CNC_4']
|
|
|
|
|
|
isActive: boolean
|
|
|
|
|
|
remark: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 产品类型详情
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/product-types/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`ProductTypeReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 工艺路线详情
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/recipes/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface RecipeReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
version: number
|
|
|
|
|
|
steps: RecipeStepReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface RecipeStepReply {
|
|
|
|
|
|
stepId: string
|
|
|
|
|
|
stepName: string
|
|
|
|
|
|
stepType: RecipeStepType
|
|
|
|
|
|
resourceType?: string
|
|
|
|
|
|
toolType?: 'SCANNER' | 'LASER'
|
|
|
|
|
|
allowedResources?: string[]
|
|
|
|
|
|
processingParams?: Record<string, unknown>
|
|
|
|
|
|
nextStepDefault?: string
|
|
|
|
|
|
nextStepBranches?: Record<string, string>
|
|
|
|
|
|
stepTimeout?: number
|
|
|
|
|
|
description?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 工单管理
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 10 节。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 工单分页列表
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/work-orders
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryWorkOrdersReq extends PageReq, SortReq {
|
|
|
|
|
|
keyword?: string
|
|
|
|
|
|
statuses?: WorkOrderStatus[]
|
|
|
|
|
|
productTypeId?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryWorkOrdersReply extends PageReply {
|
|
|
|
|
|
data: WorkOrderReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface WorkOrderReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
no: string
|
|
|
|
|
|
productTypeId: string
|
|
|
|
|
|
quantity: number
|
|
|
|
|
|
finishedNum: number
|
|
|
|
|
|
failNum: number
|
|
|
|
|
|
status: WorkOrderStatus
|
|
|
|
|
|
sourceBaySlotId?: string
|
|
|
|
|
|
context?: Record<string, unknown>
|
|
|
|
|
|
createdTime: ISODateTime
|
|
|
|
|
|
updatedTime: ISODateTime
|
|
|
|
|
|
completedTime?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.2 工单详情
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/work-orders/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`WorkOrderReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 创建工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/work-orders
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface CreateWorkOrderReq {
|
|
|
|
|
|
productTypeId: string
|
|
|
|
|
|
quantity: number
|
|
|
|
|
|
dockSlots: string[] // 格式:dockNo.slotNo,例如 '1.3'
|
|
|
|
|
|
context?: Record<string, unknown>
|
|
|
|
|
|
remark?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface CreateWorkOrderReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.4 更新工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
PUT /api/v1/work-orders/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface UpdateWorkOrderReq {
|
|
|
|
|
|
productTypeId?: string
|
|
|
|
|
|
quantity?: number
|
|
|
|
|
|
remark?: string
|
|
|
|
|
|
context?: Record<string, unknown>
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5 开始工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/work-orders/:id/start
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:工单进入 `IN_PROGRESS`,触发初始补料/调度。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.6 暂停工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/work-orders/:id/pause
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:只修改工单为 `PAUSED`,调度过滤层排除该工单,不污染工件状态。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.7 恢复工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/work-orders/:id/resume
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:工单从 `PAUSED` 回到 `IN_PROGRESS`,调度重新纳入。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.8 断电恢复工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/work-orders/:id/restore
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:按设计第 15 节恢复等级执行恢复。
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface RestoreWorkOrderReply {
|
|
|
|
|
|
orderId: string
|
|
|
|
|
|
restoredJobs: number
|
|
|
|
|
|
level: 'L1' | 'L2' | 'L3'
|
|
|
|
|
|
manualRequired: boolean
|
|
|
|
|
|
message?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.9 取消工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/work-orders/:id/cancel
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:终止未完成工件,释放可释放资源。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.10 删除工单
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
DELETE /api/v1/work-orders/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
约束:仅允许删除未运行或已终态工单。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 工件 / Job 管理
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 6.2 节 `job`,第 7 节工件生命周期。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.1 工件分页列表
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/jobs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryJobsReq extends PageReq, SortReq {
|
|
|
|
|
|
keyword?: string
|
|
|
|
|
|
workOrderId?: string
|
|
|
|
|
|
productTypeId?: string
|
|
|
|
|
|
statuses?: JobStatus[]
|
|
|
|
|
|
positionType?: PositionType
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryJobsReply extends PageReply {
|
|
|
|
|
|
data: JobReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface JobReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
workOrderId: string
|
|
|
|
|
|
workpieceNo: string
|
|
|
|
|
|
productTypeId: string
|
|
|
|
|
|
recipeId: string
|
|
|
|
|
|
currentStepId: string
|
|
|
|
|
|
currentStepName: string
|
|
|
|
|
|
status: JobStatus
|
|
|
|
|
|
positionType: PositionType
|
|
|
|
|
|
positionRefId: string
|
|
|
|
|
|
priority: number
|
|
|
|
|
|
suspendedReason?: string
|
|
|
|
|
|
context?: Record<string, unknown>
|
|
|
|
|
|
version: number
|
|
|
|
|
|
createdTime: ISODateTime
|
|
|
|
|
|
lastUpdated: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 工单下工件分页
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/work-orders/:id/jobs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryJobsOfWorkOrderReq extends PageReq, SortReq {
|
|
|
|
|
|
statuses?: JobStatus[]
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`QueryJobsReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 6.3 工件详情
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/jobs/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`JobReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 6.4 挂起工件
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/jobs/:id/suspend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface SuspendJobReq {
|
|
|
|
|
|
reason?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:工件进入 `SUSPENDED`。如果当前 `IN_HANDLING` 或设备处理中,按后端策略延迟挂起或要求人工确认。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.5 恢复工件
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/jobs/:id/resume
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:从 `SUSPENDED` 恢复到可调度状态。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.6 返工工件
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/jobs/:id/rework
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ReworkJobReq {
|
|
|
|
|
|
targetStepId: string
|
|
|
|
|
|
reason?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:修改 `current_step_id`,新增 `job_step_instance`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 看板 / 监控 API
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 3 节人工终端、第 7 节状态管理、第 11 节工站接口、第 16 节 Redis SSOT。
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 生产线总览
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/dashboard/overview
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface DashboardOverviewReply {
|
|
|
|
|
|
activeOrderCount: number
|
|
|
|
|
|
activeJobCount: number
|
|
|
|
|
|
completedToday: number
|
|
|
|
|
|
scrappedToday: number
|
|
|
|
|
|
stationFaultCount: number
|
|
|
|
|
|
buffer: BufferSummary
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface BufferSummary {
|
|
|
|
|
|
total: number
|
|
|
|
|
|
occupied: number
|
|
|
|
|
|
free: number
|
|
|
|
|
|
needRefill: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 7.2 工站监控
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/stations/monitor
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface StationMonitorReply {
|
|
|
|
|
|
stations: StationMonitorItem[]
|
|
|
|
|
|
activeOrders: ActiveOrderSummary[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface StationMonitorItem {
|
|
|
|
|
|
id: string // 例:CNC_1、WASHER_1、BUFFER、SAMPLING_1
|
|
|
|
|
|
type: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
status: StationStatus
|
|
|
|
|
|
heartbeatOnline: boolean
|
|
|
|
|
|
currentJobs: StationJobBrief[]
|
|
|
|
|
|
waitingUnloadJobs: StationJobBrief[]
|
|
|
|
|
|
updatedAt: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface StationJobBrief {
|
|
|
|
|
|
jobId: string
|
|
|
|
|
|
workOrderId: string
|
|
|
|
|
|
productTypeId: string
|
|
|
|
|
|
status: JobStatus
|
|
|
|
|
|
positionRefId: string
|
|
|
|
|
|
currentStepId: string
|
|
|
|
|
|
currentStepName: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ActiveOrderSummary {
|
|
|
|
|
|
orderId: string
|
|
|
|
|
|
orderNo: string
|
|
|
|
|
|
status: WorkOrderStatus
|
|
|
|
|
|
productTypeId: string
|
|
|
|
|
|
totalJobs: number
|
|
|
|
|
|
completedJobs: number
|
|
|
|
|
|
scrappedJobs: number
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> 设计说明:工站对外不暴露内部槽位写接口;前端仅展示 Redis 推导出的当前工件、等待下料工件和设备状态。设备槽位属于后端工站内部实现细节,不作为前端操作入口。
|
|
|
|
|
|
|
|
|
|
|
|
### 7.3 暂存台槽位监控
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/buffer/slots
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface BufferSlotsReply {
|
|
|
|
|
|
slots: BufferSlotReply[]
|
|
|
|
|
|
occupied: number
|
|
|
|
|
|
free: number
|
|
|
|
|
|
total: 8
|
|
|
|
|
|
refillThreshold: 4
|
|
|
|
|
|
needRefill: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface BufferSlotReply {
|
|
|
|
|
|
slotNo: number // 1~8
|
|
|
|
|
|
occupied: boolean
|
|
|
|
|
|
job?: JobBrief
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface JobBrief {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
workOrderId: string
|
|
|
|
|
|
workpieceNo: string
|
|
|
|
|
|
productTypeId: string
|
|
|
|
|
|
status: JobStatus
|
|
|
|
|
|
currentStepId: string
|
|
|
|
|
|
currentStepName: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 7.4 接驳台槽位监控
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/docks/loading/slots
|
|
|
|
|
|
GET /api/v1/docks/unloading/slots
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface DockSlotsReply {
|
|
|
|
|
|
docks: DockReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface DockReply {
|
|
|
|
|
|
dockNo: number
|
|
|
|
|
|
type: 'LOADING' | 'UNLOADING'
|
|
|
|
|
|
slots: DockSlotReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface DockSlotReply {
|
|
|
|
|
|
slotNo: number
|
|
|
|
|
|
status: 'EMPTY' | 'UNPUBLISHED' | 'PUBLISHED' | 'SCAN_FAILED' | 'PROCESSING' | 'COMPLETED'
|
|
|
|
|
|
job?: JobBrief
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 调度与任务 API
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 8 节调度器三层架构、第 9 节任务状态机。
|
|
|
|
|
|
|
|
|
|
|
|
### 8.1 当前调度队列
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/scheduler/ready-jobs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ReadyJobsReply {
|
|
|
|
|
|
jobs: ReadyJobReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ReadyJobReply {
|
|
|
|
|
|
jobId: string
|
|
|
|
|
|
workOrderId: string
|
|
|
|
|
|
status: JobStatus
|
|
|
|
|
|
priority: number
|
|
|
|
|
|
reason: string
|
|
|
|
|
|
queuedAt: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 8.2 当前任务列表
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/tasks
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryTasksReq extends PageReq, SortReq {
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
workOrderId?: string
|
|
|
|
|
|
statuses?: TaskStatus[]
|
|
|
|
|
|
type?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryTasksReply extends PageReply {
|
|
|
|
|
|
data: TaskReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface TaskReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
jobId: string
|
|
|
|
|
|
type: string
|
|
|
|
|
|
status: TaskStatus
|
|
|
|
|
|
fromPos?: PositionRef
|
|
|
|
|
|
toPos?: PositionRef
|
|
|
|
|
|
assignedRobot?: string
|
|
|
|
|
|
startedTime?: ISODateTime
|
|
|
|
|
|
completedTime?: ISODateTime
|
|
|
|
|
|
result?: Record<string, unknown>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface PositionRef {
|
|
|
|
|
|
type: PositionType | 'DOCK' | 'AGV' | 'SAMPLING'
|
|
|
|
|
|
refId: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 8.3 任务详情
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/tasks/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`TaskReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 8.4 任务日志
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/work-orders/:id/task-logs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryTaskLogsReq extends PageReq, SortReq {
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
status?: TaskStatus
|
|
|
|
|
|
taskKind?: string
|
|
|
|
|
|
startTime?: ISODateTime
|
|
|
|
|
|
endTime?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryTaskLogsReply extends PageReply {
|
|
|
|
|
|
data: TaskLogReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface TaskLogReply {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
workOrderId: string
|
|
|
|
|
|
jobId: string
|
|
|
|
|
|
stepId: string
|
|
|
|
|
|
stepName: string
|
|
|
|
|
|
taskKind: string
|
|
|
|
|
|
status: TaskStatus
|
|
|
|
|
|
content: string
|
|
|
|
|
|
durationMs: number
|
|
|
|
|
|
createdAt: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 人工交互 API
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 10 节单工件暂存/返工、第 15 节 L3 人工恢复、第 18 节人工终端。
|
|
|
|
|
|
|
|
|
|
|
|
### 9.1 待人工处理事项
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/manual-actions
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryManualActionsReq extends PageReq, SortReq {
|
|
|
|
|
|
type?: string
|
|
|
|
|
|
resolved?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryManualActionsReply extends PageReply {
|
|
|
|
|
|
data: ManualActionReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ManualActionReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
type: 'SCAN_FAILED' | 'RECOVERY_REQUIRED' | 'INSPECTION_DECISION' | 'FAULT_CONFIRM'
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
workOrderId?: string
|
|
|
|
|
|
message: string
|
|
|
|
|
|
payload?: Record<string, unknown>
|
|
|
|
|
|
resolved: boolean
|
|
|
|
|
|
createdAt: ISODateTime
|
|
|
|
|
|
resolvedAt?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-27 10:56:41 +08:00
|
|
|
|
### 9.2 确认扫码失败处理
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/manual-actions/:id/resolve-scan-failed
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ResolveScanFailedReq {
|
|
|
|
|
|
action: 'RETRY_SCAN' | 'RETURN_BAY' | 'SCRAP'
|
|
|
|
|
|
remark?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 9.3 检测结果人工判定
|
2026-08-27 10:09:54 +08:00
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/jobs/:id/inspection-decision
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface InspectionDecisionReq {
|
|
|
|
|
|
result: 'PASS' | 'FAIL'
|
|
|
|
|
|
needSampling?: boolean
|
|
|
|
|
|
remark?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 9.4 L3 断电恢复人工确认
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/recovery/actions/:id/confirm
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ConfirmRecoveryReq {
|
|
|
|
|
|
decision: 'RESUME' | 'WAIT_UNLOAD' | 'SUSPEND' | 'SCRAP'
|
|
|
|
|
|
confirmedPosition?: PositionRef
|
|
|
|
|
|
remark?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 设备与心跳 API
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 6.1 节 `equipment`、第 13 节心跳。
|
|
|
|
|
|
|
|
|
|
|
|
### 10.1 设备列表
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/equipments
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryEquipmentsReq extends PageReq, SortReq {
|
|
|
|
|
|
keyword?: string
|
|
|
|
|
|
typeCode?: string
|
|
|
|
|
|
status?: StationStatus
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryEquipmentsReply extends PageReply {
|
|
|
|
|
|
data: EquipmentReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface EquipmentReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
typeCode: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
status: StationStatus
|
|
|
|
|
|
slotCount: number
|
|
|
|
|
|
ipAddress?: string
|
|
|
|
|
|
location?: string
|
|
|
|
|
|
heartbeatOnline: boolean
|
|
|
|
|
|
lastHeartbeatAt?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 10.2 设备详情
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/equipments/:id
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:`EquipmentReply`
|
|
|
|
|
|
|
|
|
|
|
|
### 10.3 设备心跳状态
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/equipments/:id/heartbeat
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface EquipmentHeartbeatReply {
|
|
|
|
|
|
equipmentId: string
|
|
|
|
|
|
online: boolean
|
|
|
|
|
|
ttlMs: number
|
|
|
|
|
|
lastHeartbeatAt?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 11. 报警与运行校验
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 14 节运行期状态校验、附录 PLC 错误码。
|
|
|
|
|
|
|
|
|
|
|
|
### 11.1 报警分页列表
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/alarms
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
查询:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryAlarmsReq extends PageReq, SortReq {
|
|
|
|
|
|
equipmentId?: string
|
|
|
|
|
|
level?: 'INFO' | 'WARN' | 'ERROR' | 'CRITICAL'
|
|
|
|
|
|
resolved?: boolean
|
|
|
|
|
|
startTime?: ISODateTime
|
|
|
|
|
|
endTime?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface QueryAlarmsReply extends PageReply {
|
|
|
|
|
|
data: AlarmReply[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface AlarmReply {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
alarmCode: string
|
|
|
|
|
|
alarmMessage: string
|
|
|
|
|
|
level: 'INFO' | 'WARN' | 'ERROR' | 'CRITICAL'
|
|
|
|
|
|
equipmentId?: string
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
resolved: boolean
|
|
|
|
|
|
createdAt: ISODateTime
|
|
|
|
|
|
resolvedAt?: ISODateTime
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 11.2 确认报警
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/alarms/:id/ack
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface AckAlarmReq {
|
|
|
|
|
|
remark?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 11.3 状态一致性校验结果
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/state-checks/latest
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface StateCheckReply {
|
|
|
|
|
|
checkedAt: ISODateTime
|
|
|
|
|
|
ok: boolean
|
|
|
|
|
|
issues: StateCheckIssue[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface StateCheckIssue {
|
|
|
|
|
|
type: 'PLC_REDIS_MISMATCH' | 'MISSING_HEARTBEAT' | 'UNKNOWN_POSITION'
|
|
|
|
|
|
equipmentId?: string
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
message: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 12. 事件流 API
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 3 节 WebSocket/HTTP、第 4 节事件总线、第 16 节 Redis Stream。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.1 WebSocket 实时事件
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
WS /api/v1/events/ws
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
前端连接后接收统一事件:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface RealtimeEvent<T = unknown> {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
entityId: string
|
|
|
|
|
|
entityVersion: number
|
|
|
|
|
|
type: RealtimeEventType
|
|
|
|
|
|
source: string
|
|
|
|
|
|
timestamp: ISODateTime
|
|
|
|
|
|
payload: T
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type RealtimeEventType =
|
|
|
|
|
|
| 'PALLET_ARRIVED'
|
|
|
|
|
|
| 'PALLET_REMOVED'
|
|
|
|
|
|
| 'MACHINE_TASK_COMPLETE'
|
|
|
|
|
|
| 'ROBOT_ACTION_DONE'
|
|
|
|
|
|
| 'SCAN_RESULT'
|
|
|
|
|
|
| 'JOB_STATUS_CHANGED'
|
|
|
|
|
|
| 'STATION_READY'
|
|
|
|
|
|
| 'STATION_REQUEST_LOAD'
|
|
|
|
|
|
| 'INSPECTION_PASS'
|
|
|
|
|
|
| 'INSPECTION_FAIL'
|
|
|
|
|
|
| 'SAMPLING_REQUEST'
|
|
|
|
|
|
| 'SAMPLING_COMPLETE_OK'
|
|
|
|
|
|
| 'SAMPLING_COMPLETE_NG'
|
|
|
|
|
|
| 'ROBOT_ERROR'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
常用 payload:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface JobStatusChangedPayload {
|
|
|
|
|
|
jobId: string
|
|
|
|
|
|
workOrderId: string
|
|
|
|
|
|
fromStatus: JobStatus
|
|
|
|
|
|
toStatus: JobStatus
|
|
|
|
|
|
positionType: PositionType
|
|
|
|
|
|
positionRefId: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface MachineTaskCompletePayload {
|
|
|
|
|
|
equipmentId: string
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
slotNo?: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ScanResultPayload {
|
|
|
|
|
|
jobId: string
|
|
|
|
|
|
success: boolean
|
|
|
|
|
|
scanCode?: string
|
|
|
|
|
|
reason?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 12.2 SSE 兼容事件流(可选)
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/v1/events/sse
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
返回格式:标准 `text/event-stream`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 13. 断电恢复 API
|
|
|
|
|
|
|
|
|
|
|
|
设计依据:第 15 节。
|
|
|
|
|
|
|
|
|
|
|
|
### 13.1 恢复扫描
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/recovery/scan
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
效果:扫描 Redis/PG/PLC 状态,生成恢复建议。
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface RecoveryScanReply {
|
|
|
|
|
|
items: RecoveryItem[]
|
|
|
|
|
|
summary: {
|
|
|
|
|
|
l1: number
|
|
|
|
|
|
l2: number
|
|
|
|
|
|
l3: number
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface RecoveryItem {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
level: 'L1' | 'L2' | 'L3'
|
|
|
|
|
|
jobId?: string
|
|
|
|
|
|
workOrderId?: string
|
|
|
|
|
|
equipmentId?: string
|
|
|
|
|
|
currentStatus?: JobStatus
|
|
|
|
|
|
suggestedAction: string
|
|
|
|
|
|
manualRequired: boolean
|
|
|
|
|
|
message: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 13.2 执行自动恢复
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/recovery/auto-restore
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface AutoRestoreReq {
|
|
|
|
|
|
levels?: Array<'L1' | 'L2'>
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface AutoRestoreReply {
|
|
|
|
|
|
restoredCount: number
|
|
|
|
|
|
skippedCount: number
|
|
|
|
|
|
failedItems: Array<{
|
|
|
|
|
|
id: string
|
|
|
|
|
|
message: string
|
|
|
|
|
|
}>
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 13.3 事件重放
|
|
|
|
|
|
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/v1/recovery/replay-events
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
请求:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ReplayEventsReq {
|
|
|
|
|
|
afterEventId?: string
|
|
|
|
|
|
dryRun?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ReplayEventsReply {
|
|
|
|
|
|
applied: number
|
|
|
|
|
|
skipped: number
|
|
|
|
|
|
lastEventId?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 14. 前端模块建议
|
|
|
|
|
|
|
|
|
|
|
|
建议前端按以下 client 模块组织:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
frontend/src/api/auth.ts
|
|
|
|
|
|
frontend/src/api/product-type.ts
|
|
|
|
|
|
frontend/src/api/recipe.ts
|
|
|
|
|
|
frontend/src/api/work-order.ts
|
|
|
|
|
|
frontend/src/api/job.ts
|
|
|
|
|
|
frontend/src/api/dashboard.ts
|
|
|
|
|
|
frontend/src/api/station-monitor.ts
|
|
|
|
|
|
frontend/src/api/buffer.ts
|
|
|
|
|
|
frontend/src/api/dock.ts
|
|
|
|
|
|
frontend/src/api/task.ts
|
|
|
|
|
|
frontend/src/api/manual-action.ts
|
|
|
|
|
|
frontend/src/api/equipment.ts
|
|
|
|
|
|
frontend/src/api/alarm.ts
|
|
|
|
|
|
frontend/src/api/recovery.ts
|
|
|
|
|
|
frontend/src/api/events.ts
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 15. 与当前实现的主要差异提示
|
|
|
|
|
|
|
|
|
|
|
|
以下是前端联调时需要注意的目标差异:
|
|
|
|
|
|
|
|
|
|
|
|
1. **工件资源命名**:目标设计使用 `job` 作为运行时工件实体;当前实现部分接口仍使用 `workpiece` 命名。
|
|
|
|
|
|
2. **ID 类型**:目标设计中 `product_type/equipment/work_order/job` 更偏向字符串业务 ID;当前实现大量使用 int ID。前端新契约应优先按本文类型建模。
|
|
|
|
|
|
3. **工站监控**:目标契约不要求前端直接操作或依赖工站内部槽位写方法;监控数据应来自 Redis SSOT 推导结果。
|
|
|
|
|
|
4. **暂存台**:目标设计明确为 8 个固定槽位,工件全周期独占槽位,接口应体现 `slotNo 1~8` 和 `needRefill`。
|
|
|
|
|
|
5. **事件流**:目标架构要求 WebSocket/SSE 实时推送;仅轮询 `/stations/monitor` 不能满足最终生产版看板体验。
|
|
|
|
|
|
6. **恢复 API**:目标设计需要 L1/L2/L3 分级恢复接口;当前实现如果只有单个 restore endpoint,应继续补齐扫描、自动恢复和人工确认能力。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 16. 最小前端接入优先级
|
|
|
|
|
|
|
|
|
|
|
|
建议按以下顺序落地:
|
|
|
|
|
|
|
|
|
|
|
|
1. `auth`:登录、刷新 token、当前用户。
|
|
|
|
|
|
2. `product-type/recipe`:产品与工艺路线展示。
|
|
|
|
|
|
3. `work-order/job`:工单创建、启动、暂停、恢复、工件列表。
|
|
|
|
|
|
4. `buffer/dock/station-monitor`:生产线看板。
|
|
|
|
|
|
5. `events`:实时事件流。
|
|
|
|
|
|
6. `manual-action/recovery`:异常处理和断电恢复。
|
|
|
|
|
|
7. `task/alarm/equipment`:任务追踪、报警、设备运维。
|