Files
MrleeAdmin/doc/订单模式工作模式与工作规则说明.md
T
2026-08-31 11:33:59 +08:00

595 lines
24 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.
# 订单模式工作模式与工作规则说明
> 文档用途:说明当前生产扫码 APP 中“订单模式”的实际工作方式、数据规则、校验规则、状态流转与边界。本文仅基于当前项目已实现代码梳理;对尚未实现或未被调用的配置能力,会明确标注,避免将规划误认为现行规则。
>
> 适用范围:`frontend/scanapp` 移动端订单模式、`backend/plugin/produce` 的 APP API 及其生产记录数据。
---
## 1. 概述
订单模式用于生产人员在指定的**工序**和**步骤**下,对单个订单号进行扫码或手工录入,并生成一条订单扫码记录。
一次成功提交的核心结果是:
1. 生成一条 `produce_scan_data` 订单扫码记录;
2. 将当前登录用户映射为记录的操作人员;
3. 为记录写入当前步骤的初始状态;
4. 对满足条件的上游步骤,尝试执行“下一步骤扫码”自动状态转换;
5. 更新移动端的最近记录与统计数据。
订单模式是**单订单、单次记录**的录入模式。它记录订单在某工序步骤的作业动作,不等同于订单主档,也不会在当前实现中直接维护“整张订单已完成”的全局终态。
---
## 2. 现行工作模式
### 2.1 操作入口与页面
| 项目 | 当前实现 |
| --- | --- |
| 页面 | `frontend/scanapp/pages/entry/order.vue` |
| 页面名称 | 订单模式 |
| 主要用途 | 扫描订单号并按当前工序、步骤提交生产扫码记录 |
| 提交接口 | `POST /appapi/produce/scan-data/record` |
| 最近记录接口 | `GET /appapi/produce/scan-data` |
| 统计接口 | `GET /appapi/produce/scan-data/statistics` |
| 配置接口 | `GET /appapi/produce/config/data-entry` |
APP 请求基础前缀为 `/appapi`;生产插件通过 Swagger 注解注册 APP API 路由。控制器实际执行逻辑位于:
```text
backend/plugin/produce/app/api/controller/DataEntryController.php
```
APP API 控制器为委托层,复用上述逻辑。
### 2.2 页面加载后的准备流程
订单模式页面加载时,按当前本地登录用户初始化并请求以下数据:
1. 从本地缓存 `scanapp_user` 读取用户编码;
- 取值优先级:`username` → `nickname` → 默认值 `U001`。
2. 获取启用的工序列表;
3. 获取当前用户的订单模式统计;
4. 获取当前用户的最近订单扫码记录;
5. 根据已保存的个人选择恢复工序与步骤;
6. 获取当前工序的启用步骤;
7. 获取当前工序/步骤对应的录入配置和特定规则。
用户的工序、步骤选择会保存到本地存储,键名格式为:
```text
scanapp_entry_order_selection_<用户编码>
```
保存字段为:
```json
{
"processId": "工序ID",
"stepId": "步骤ID"
}
```
因此,同一用户再次进入订单模式时,会优先恢复上一次选择的工序与步骤;不同用户的选择互不覆盖。
### 2.3 工序和步骤选择规则
#### 工序
- 数据源:`produce_process`。
- 仅返回 `status = 1` 的启用工序。
- 排序:先按 `sort` 升序,再按 `id` 升序。
- 操作人员可在页面中切换工序。
#### 步骤
- 数据源:`produce_process_step`。
- 仅返回 `status = 1` 的启用步骤。
- 仅返回当前选中工序下的步骤。
- 排序:先按 `sort` 升序,再按 `id` 升序。
- 切换工序后,页面会重新加载步骤、录入配置,并保存当前选择。
### 2.4 订单号录入方式
订单号支持两种录入方式:
1. **手工输入**:在订单号输入框直接录入;
2. **相机扫码**:调用 `uni.scanCode`,仅允许通过相机扫码,支持:
- 一维条码:`barCode`
- 二维码:`qrCode`
扫码成功后,系统将结果转为字符串并去除首尾空格,再回填订单号字段。扫码取消或失败时,页面提示“未完成扫码”。
### 2.5 连续扫码
页面提供“连续扫码”开关,默认关闭。
- 关闭:提交成功后清空订单号,等待下一次手工输入或主动扫码。
- 开启:提交成功后清空订单号、刷新页面数据,并在约 350 毫秒后自动再次唤起相机扫码。
连续扫码只影响前端扫码动作,不改变后端校验、记录创建或状态流转规则。
---
## 3. 提交前校验规则
订单模式采取“前端预校验 + 后端强制校验”的方式。前端用于及时提示,后端是最终准入边界。
### 3.1 页面级必填校验
提交前必须满足:
| 校验项 | 规则 | 失败提示 |
| --- | --- | --- |
| 订单号 | 去除首尾空格后不能为空 | 请输入订单号 |
| 工序 | 当前必须存在有效选中项 | 请选择工序 |
| 步骤 | 当前必须存在有效选中项 | 请选择步骤 |
### 3.2 基础配置校验
配置来源为 `produce_config` 表中 `group_code = basic_setting` 的配置项。当前订单模式实际使用以下字段:
| 配置代码 | 当前作用 |
| --- | --- |
| `order_no_min_length` | 大于 0 时,订单号长度不得小于该值 |
| `order_no_regex` | 配置非空时,订单号必须匹配该正则表达式 |
| `global_allow_repeat` | 步骤未覆盖时,作为全局重复扫码默认开关 |
| `repeat_scan_interval` | 重复扫码最短间隔,单位秒 |
| `recent_records_today_only` | 控制最近记录和统计在无订单号筛选时是否仅统计当天 |
规则说明:
- 未配置 `order_no_min_length` 或值小于等于 0:不做最小长度限制;
- 未配置 `order_no_regex`:不做格式正则校验;
- 正则配置格式异常时,前端会记录错误日志,但不会因该错误阻塞用户提交;后端的特定规则匹配会将无法匹配的规则视为不命中。
### 3.3 特定规则(订单命中规则)
特定规则来源:`produce_specific_rule`,仅查询 `is_enabled = 1` 的规则,并按 `sort`、`id` 升序处理。
规则可按以下维度限制:
| 字段 | 说明 |
| --- | --- |
| `apply_mode` | 生效模式:`order` 表示订单模式,`both` 表示订单和整机模式均生效 |
| `match_field` | 用于匹配的字段;订单模式默认是 `order_no` |
| `rule_pattern` | 正则表达式内容 |
| `step_ids` | 可选的步骤 ID 范围;为空表示不限制步骤 |
| `rule_type` | 当前实现中 `2` 表示命中后禁止提交;`1` 在重复扫码策略中表示允许重复 |
订单模式页面会在提交前检查:若存在一个满足模式、步骤范围和正则条件的 `rule_type = 2` 规则,则拒绝提交,并提示规则名称;规则未命名时提示“当前订单命中特定规则,禁止提交”。
> 注意:前端会先加载规则并做预拦截;后端 `record` 提交接口当前没有再次执行“订单号长度、订单号正则、禁止型特定规则”的完整校验。因此,客户端校验不能替代服务端校验。现行系统中,前置步骤、重复扫码、用户编码和请求字段校验由后端强制执行。
### 3.4 后端请求字段校验
接口 `POST /produce/scan-data/record` 使用 `ScanDataValidate` 的 `store` 场景校验,要求:
| 字段 | 规则 |
| --- | --- |
| `order_no` | 必填,最长 100 字符 |
| `user_code` | 必填,最长 50 字符 |
| `process_id` | 必填,整数 |
| `step_id` | 必填,整数 |
| `status_id` | 可选,整数 |
| `scan_result` | 必填,只允许 `0` 或 `1` |
| `remark` | 可选,最长 65535 字符 |
当前订单模式前端固定提交:
```json
{
"order_no": "订单号",
"user_code": "当前用户编码",
"process_id": "当前工序ID",
"step_id": "当前步骤ID",
"scan_result": 1
}
```
即订单模式正常提交默认写入成功结果 `scan_result = 1`,页面没有提供失败结果或备注的录入控件。
### 3.5 操作人员校验与归属
后端以 `user_code` 查询会员表 `member` 的 `username`:
- 用户不存在:拒绝提交,返回“用户编码不存在”;
- 用户存在:后端以会员真实信息写入操作人员信息;
- `user_code`:请求中的用户编码;
- `operator`:优先会员昵称,否则使用会员用户名;
- `operator_id`:会员 ID。
前端传入的 `operator` 不作为最终可信操作人员来源,服务端会重新从会员数据生成操作人快照。
---
## 4. 前置步骤与重复扫码规则
### 4.1 前置步骤规则
每个步骤可以配置前置步骤,配置字段属于 `produce_process_step`:
| 字段 | 含义 |
| --- | --- |
| `prerequisite_steps` | 前置步骤 ID 数组 |
| `prerequisite_mode` | 验证模式:`all`、`any`、`none` |
| `prerequisite_require_final` | 是否要求前置步骤已进入终态:`1` 是,`0` 否 |
后端在创建当前步骤记录前执行校验。
#### 验证模式
| 模式 | 含义 | 不满足时的结果 |
| --- | --- | --- |
| `none` | 不校验前置步骤,或未配置前置步骤 | 允许提交 |
| `all` | 所有前置步骤都要满足 | 返回“前置步骤未完成:步骤A、步骤B” |
| `any` | 至少一个前置步骤满足 | 返回“前置步骤未满足,至少需要完成一个前置步骤” |
#### 前置步骤满足条件
系统以“同一订单号 + 指定前置步骤”查询历史订单扫码记录:
- `prerequisite_require_final = 0`:只要存在任意历史记录,即视为满足;
- `prerequisite_require_final = 1`:必须存在关联步骤状态为 `is_final = 1` 的历史记录,才视为满足。
因此,是否称得上“完成”,在当前订单流程中取决于**步骤状态是否是终态**,而不是仅仅存在过扫码记录。
### 4.2 重复扫码规则
后端以“同订单号 + 同工序 + 同步骤”查询最新扫码记录。若不存在历史记录,允许直接提交;若存在,则按下列优先级计算重复扫码策略:
1. 全局基础配置 `global_allow_repeat`、`repeat_scan_interval`;
2. 当前步骤配置覆盖全局是否允许重复及允许的状态;
3. 命中的特定规则可最终覆盖“是否允许重复”。
#### 默认与覆盖逻辑
| 配置来源 | 影响 |
| --- | --- |
| `global_allow_repeat` | 未配置步骤规则时的默认允许重复开关 |
| `repeat_scan_interval` | 最短重复扫码间隔(秒) |
| `allow_repeat_scan` | 步骤级允许重复开关,会覆盖全局开关 |
| `repeat_scan_statuses` | 限制仅在指定状态下允许重复;空数组表示不额外限制状态 |
| 命中特定规则且 `rule_type = 1` | 允许重复 |
| 命中特定规则且 `rule_type != 1` | 不允许重复 |
当存在历史记录时,以下任一条件不满足都会拒绝提交:
1. 当前策略未允许重复:提示“当前配置不允许重复扫码”;
2. 配置了允许重复状态,且最近记录的状态不在范围内:提示“当前状态不允许重复扫码”;
3. 配置了最短间隔,且距离最近一次扫码不足该秒数:提示“重复扫码间隔不能小于 N 秒”。
> 实现细节:重复扫描校验只检查同工序、同步骤下的最新记录,不会因其他步骤或其他工序的记录直接阻止当前提交。
---
## 5. 状态与工作流规则
### 5.1 订单扫码记录的初始状态
提交接口收到 `status_id` 时会优先使用该值;订单模式页面当前不传 `status_id`,因此后端会自动查询当前步骤 `is_initial = 1` 的状态并写入记录。
相关状态配置表为 `produce_step_status`:
| 字段 | 说明 |
| --- | --- |
| `step_id` | 所属步骤 |
| `status_code` / `status_name` | 状态编码与显示名称 |
| `is_initial` | 是否初始状态 |
| `is_final` | 是否终态 |
| `status` | 是否启用 |
当前实现没有在记录创建时显式校验“初始状态是否唯一、是否启用”;管理端配置时应保证每个可用步骤存在明确且唯一的初始状态,避免记录没有状态或状态语义不确定。
### 5.2 下一步骤扫码触发上游状态转换
提交当前步骤订单记录后,后端在同一数据库事务中处理“下一步骤扫码自动触发状态转换”。该机制含义是:当前步骤扫码可以推动与它相连的**前置步骤记录**切换状态。
触发过程如下:
1. 找到所有已启用、且目标步骤等于当前步骤的步骤关系:`produce_step_relation.to_step_id = 当前 step_id`;
2. 按 `priority`、`sort`、`id` 升序逐项处理;
3. 对每个关系,取同一订单在源步骤(`from_step_id`)的最新扫码记录;
4. 若源记录不存在或没有状态,则跳过;
5. 查找源步骤上已启用、自动触发的状态转换:
- `trigger_event = next_step_scan`
- `auto_trigger = 1`
- 当前源记录状态等于 `from_status_id`
6. 若存在多条可用转换,按以下顺序取第一条:
- `priority` 降序;
- `sort` 升序;
- `id` 升序;
7. 将源记录 `status_id` 更新为转换目标状态 `to_status_id`;
8. 无论成功或失败,均写入一条 `produce_transition_log` 流转日志。
### 5.3 “已完成”的系统含义
当前代码中没有独立的“订单完成表”或统一的订单全局完成字段。订单层面的“已完成”主要通过以下事实判断:
1. 某步骤的订单扫码记录关联的状态配置为 `is_final = 1`;
2. 在后续步骤校验前置条件时,该步骤可被视为已完成(当 `prerequisite_require_final = 1`);
3. 当前流程末端步骤是否代表整张订单完成,取决于管理端为该步骤配置的终态及步骤关系。
因此,**订单是否已完成是流程配置驱动的结果,不是当前订单模式页面上的固定布尔状态。**
### 5.4 状态转换日志
自动状态转换会创建 `produce_transition_log`,记录:
- 被转换的源订单记录 ID 和订单号;
- 源步骤和状态、目标状态;
- 触发事件 `next_step_scan`;
- 当前扫码记录、用户、工序及关系等触发快照;
- 触发人员、IP、耗时;
- 自动触发标识;
- 成功/失败结果和异常信息。
日志用于追溯“为什么某一步状态被改动”,不直接替代订单扫码记录。
---
## 6. 数据模型与数据口径
### 6.1 主记录:`produce_scan_data`
订单模式的每次提交生成一行记录,核心字段如下:
| 字段 | 说明 |
| --- | --- |
| `id` | 记录主键 |
| `order_no` | 订单号 |
| `user_code` | 操作用户编码 |
| `operator` / `operator_id` | 操作人员快照及会员 ID |
| `process_id` / `step_id` | 执行的工序和步骤 |
| `status_id` | 当前步骤状态 |
| `scan_result` | 扫码结果:`0` 失败,`1` 成功 |
| `scan_time` | 业务扫码时间 |
| `remark` | 备注 |
| `created_at` / `updated_at` / `deleted_at` | 创建、更新、软删除时间 |
每次提交均写入当前服务器时间作为 `scan_time`。模型创建钩子也会在 `scan_time` 为空时补写当前时间,避免出现空扫码时间。
### 6.2 与整机模式的边界
整机模式写入的是 `produce_product_record`,主要字段为工序订单号、商品编码、数量、工序步骤、状态和扫码结果。
订单模式与整机模式的差异:
| 对比项 | 订单模式 | 整机模式 |
| --- | --- | --- |
| 主表 | `produce_scan_data` | `produce_product_record` |
| 主识别字段 | `order_no` | `process_order_no` + `product_code` |
| 记录粒度 | 单个订单号 | 整机/物料及数量 |
| 前置步骤校验 | 已实现 | 当前提交接口未调用同等校验 |
| 重复扫码校验 | 已实现 | 当前提交接口未调用同等校验 |
| 下一步自动状态转换 | 已实现 | 当前提交接口未触发 |
### 6.3 与异常和维修模块的边界
异常记录位于 `produce_exception_record`,维修记录位于 `produce_repair_record`。它们可按订单号与订单扫码数据建立业务关联,但当前订单模式提交成功不会自动创建异常或维修记录。
异常处理目前使用独立状态:
| 异常状态值 | 含义 |
| --- | --- |
| `0` | 待处理 |
| `1` | 处理中/待复核(不同展示位置的命名存在差异) |
| `2` | 已处理 |
维修任务列表仅筛选异常状态为 `0` 的记录,并按异常提报时间升序展示,用于优先处理较早提报的异常。该规则不等同于订单模式的步骤完成规则。
---
## 7. 最近记录与统计规则
### 7.1 最近记录
订单模式调用:
```text
GET /appapi/produce/scan-data?user_code=<当前用户>&limit=5
```
后端行为:
- 支持按订单号、工序、步骤、状态、扫码结果过滤;
- 订单模式页面实际传入用户编码和数量限制,但当前后端订单扫码过滤函数**没有使用 `user_code` 条件**;
- 记录按 `scan_time` 降序、`id` 降序返回;
- 支持分页,默认每页 10 条,单页最大 50 条;
- 返回结构包含:`items`、`total`。
> 现状说明:页面文案为“当前登录用户的最近记录”,但接口实现尚未按 `user_code` 过滤。因此,在当前实现中,该列表实际可能包含其他用户的订单扫码记录。此为文档记录的现行行为,不应被误解为已完成个人隔离。
### 7.2 统计
订单模式调用:
```text
GET /appapi/produce/scan-data/statistics?user_code=<当前用户>
```
返回字段:
| 字段 | 含义 |
| --- | --- |
| `today_total` | 查询范围内记录总数 |
| `success_total` | `scan_result = 1` 的记录数 |
| `failed_total` | `scan_result = 0` 的记录数 |
当前统计实现同样没有在订单扫码过滤函数中应用 `user_code`,因此页面虽然传入用户编码,统计口径实际并非严格的个人统计。
此外,`today_total` 这个字段名称不必然代表“今日”:
- 当基础配置 `recent_records_today_only = 1` 且未传 `order_no` 时,只计算当天 00:00:00 至 23:59:59 的记录;
- 当该配置不是 `1` 时,统计全部历史记录。
页面中“今日统计”“当前工序/步骤扫码量”的文案与当前接口传参及过滤实现并不完全一致:页面未传当前工序、步骤,接口未按用户编码过滤。实际数据范围应以服务端查询规则为准。
---
## 8. 当前端到端流程
```text
进入订单模式
↓
读取当前用户和已保存的工序/步骤选择
↓
加载启用工序、当前用户参数下的记录/统计、当前工序步骤和规则配置
↓
选择工序与步骤(可切换并保存)
↓
输入或扫描订单号
↓
加载当前上下文的配置与特定规则
↓
前端校验:订单号/工序/步骤/长度/正则/禁止型规则
↓
提交 POST /produce/scan-data/record(scan_result 固定为 1)
↓
后端校验:请求字段、会员用户、前置步骤、重复扫码
↓
创建订单扫码记录,并赋予步骤初始状态
↓
按步骤关系尝试自动推进上游步骤状态,记录流转日志
↓
返回录入成功
↓
前端提示成功,清空订单号,刷新页面数据
↓
若开启连续扫码,则自动再次发起相机扫码
```
---
## 9. 管理配置对订单模式的影响
订单模式的实际行为高度依赖管理端配置。上线或调整流程前,应至少检查下列内容。
### 9.1 工序与步骤
- 工序、步骤是否启用;
- 工序和步骤的 `sort` 是否符合现场操作顺序;
- 每一步是否正确配置前置步骤;
- `prerequisite_mode` 是否符合“全部完成”或“任意完成”的业务要求;
- 是否必须要求前置步骤终态。
### 9.2 步骤状态
- 每个可使用步骤是否配置了初始状态;
- 初始状态是否唯一、名称是否清晰;
- 哪些状态是终态(`is_final = 1`);
- 终态是否与“可进入下步”“该步骤结束”等业务语义一致;
- 状态是否启用。
### 9.3 步骤关系和状态转换
- 是否建立从上游步骤到下游步骤的关系;
- 关系是否启用;
- 当前下游步骤扫码时,是否需要自动更新上游步骤状态;
- 状态转换是否设置:
- 源步骤;
- 源状态;
- 目标状态;
- 触发事件 `next_step_scan`;
- `auto_trigger = 1`;
- 启用状态;
- 多条转换并存时,优先级是否正确。
### 9.4 订单校验与重复策略
- 最小订单号长度是否符合现场编码;
- 正则表达式是否已在真实订单样本上验证;
- 是否允许同订单、同工序、同步骤重复扫码;
- 如允许,最短间隔是否合理;
- 是否限制只能在指定状态下重复;
- 特定规则是否正确设置应用模式、匹配字段、步骤范围和规则类型。
---
## 10. 当前实现的已知边界与风险
以下内容是当前代码已确认的边界,后续若要以“已完成订单”为核心建设功能,应优先统一定义。
1. **没有独立的全局订单完成状态。**
- 当前“完成”依赖步骤状态 `is_final` 与流程配置。
- 若需要“已完成订单列表”,需要明确:是最后一步进入终态即完成,还是所有必经步骤进入终态即完成。
2. **订单模式前端的部分校验没有在后端重复执行。**
- 最小长度、订单正则、禁止型特定规则主要在前端执行。
- 直接调用接口的客户端理论上可以绕过这些规则。
- 后续需将关键业务准入规则统一收敛至后端,前端只保留体验层预校验。
3. **最近记录与统计未实际按 `user_code` 过滤。**
- 页面传递用户编码,但服务端 `applyScanDataFilter` 未处理该字段。
- 当前页面“当前用户”相关文案与真实数据范围可能不一致。
4. **统计字段命名与口径依赖配置。**
- `today_total` 是否仅统计当日由 `recent_records_today_only` 决定。
- 页面未传工序和步骤,所以“当前工序/步骤扫码量”文案不能保证与实际查询范围一致。
5. **初始状态存在性由配置保证。**
- 若当前步骤未配置初始状态,记录可能以空状态创建,影响后续前置完成判定和自动流转。
6. **自动流转只由订单模式提交触发。**
- 整机模式当前不会执行相同的前置步骤、重复扫码和下一步骤自动流转逻辑。
7. **当前订单模式默认只提交成功结果。**
- 页面固定 `scan_result = 1`,失败记录、备注等需要通过其他页面或接口能力处理。
---
## 11. 后续建设“已完成订单”功能前的统一规则建议
若后续要增加“已完成订单”列表、详情、查询或统计,建议先由业务方确认以下定义,再实施接口和页面:
1. **完成判定对象**:
- 指定末端步骤进入终态;
- 所有必经步骤进入终态;
- 指定末端步骤成功扫码即可;
- 是否还要排除未关闭的异常或维修任务。
2. **完成时间**:
- 最后一步进入终态的时间;
- 最后一次成功扫码时间;
- 所有必经步骤均完成时的最大完成时间。
3. **同订单重工/返工**:
- 完成后是否允许再次扫码;
- 再次扫码是否撤销完成状态;
- 应使用订单维度快照还是按最新步骤记录实时计算。
4. **异常和维修的影响**:
- 待处理异常是否阻止进入已完成列表;
- 已维修但未复核的订单是否算完成;
- 维修完成后是否要回写生产步骤或重新进入某一工序。
5. **列表数据模型**:
- 运行时按 `produce_scan_data` 聚合计算;
- 或建立订单流程汇总表,以提高查询性能、固化完成时间并支持审计。
在这些规则统一前,不建议将“存在终态扫码记录”简单等同于“整张订单完成”,以免与返工、异常、维修等现场业务冲突。
---
## 12. 代码与配置定位清单
| 类型 | 位置 |
| --- | --- |
| 订单模式页面 | `frontend/scanapp/pages/entry/order.vue` |
| APP 请求封装 | `frontend/scanapp/api/produce/data-entry.js` |
| 请求基础前缀 | `frontend/scanapp/config/index.js` |
| 生产数据入口控制器 | `backend/plugin/produce/app/api/controller/DataEntryController.php` |
| APP 委托控制器 | `backend/plugin/produce/app/appapi/controller/DataEntryController.php` |
| 订单扫码模型 | `backend/plugin/produce/app/model/ScanData.php` |
| 订单扫码校验器 | `backend/plugin/produce/app/validate/ScanDataValidate.php` |
| 步骤模型 | `backend/plugin/produce/app/model/ProcessStep.php` |
| 步骤状态模型 | `backend/plugin/produce/app/model/StepStatus.php` |
| 步骤关系模型 | `backend/plugin/produce/app/model/StepRelation.php` |
| 状态转换模型 | `backend/plugin/produce/app/model/StatusTransition.php` |
| 流转日志模型 | `backend/plugin/produce/app/model/TransitionLog.php` |
| 基础表迁移 | `backend/plugin/produce/resource/database/migrations/2026_07_30_000001_create_produce_basic_tables.php` |
| 扫码记录迁移 | `backend/plugin/produce/resource/database/migrations/2026_07_31_000003_create_produce_config_and_scan_data_tables.php` |
| 插件路由配置 | `backend/plugin/produce/config/route.php` |