24 KiB
订单模式工作模式与工作规则说明
文档用途:说明当前生产扫码 APP 中“订单模式”的实际工作方式、数据规则、校验规则、状态流转与边界。本文仅基于当前项目已实现代码梳理;对尚未实现或未被调用的配置能力,会明确标注,避免将规划误认为现行规则。
适用范围:
frontend/scanapp移动端订单模式、backend/plugin/produce的 APP API 及其生产记录数据。
1. 概述
订单模式用于生产人员在指定的工序和步骤下,对单个订单号进行扫码或手工录入,并生成一条订单扫码记录。
一次成功提交的核心结果是:
- 生成一条
produce_scan_data订单扫码记录; - 将当前登录用户映射为记录的操作人员;
- 为记录写入当前步骤的初始状态;
- 对满足条件的上游步骤,尝试执行“下一步骤扫码”自动状态转换;
- 更新移动端的最近记录与统计数据。
订单模式是单订单、单次记录的录入模式。它记录订单在某工序步骤的作业动作,不等同于订单主档,也不会在当前实现中直接维护“整张订单已完成”的全局终态。
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 路由。控制器实际执行逻辑位于:
backend/plugin/produce/app/api/controller/DataEntryController.php
APP API 控制器为委托层,复用上述逻辑。
2.2 页面加载后的准备流程
订单模式页面加载时,按当前本地登录用户初始化并请求以下数据:
- 从本地缓存
scanapp_user读取用户编码;- 取值优先级:
username→nickname→ 默认值U001。
- 取值优先级:
- 获取启用的工序列表;
- 获取当前用户的订单模式统计;
- 获取当前用户的最近订单扫码记录;
- 根据已保存的个人选择恢复工序与步骤;
- 获取当前工序的启用步骤;
- 获取当前工序/步骤对应的录入配置和特定规则。
用户的工序、步骤选择会保存到本地存储,键名格式为:
scanapp_entry_order_selection_<用户编码>
保存字段为:
{
"processId": "工序ID",
"stepId": "步骤ID"
}
因此,同一用户再次进入订单模式时,会优先恢复上一次选择的工序与步骤;不同用户的选择互不覆盖。
2.3 工序和步骤选择规则
工序
- 数据源:
produce_process。 - 仅返回
status = 1的启用工序。 - 排序:先按
sort升序,再按id升序。 - 操作人员可在页面中切换工序。
步骤
- 数据源:
produce_process_step。 - 仅返回
status = 1的启用步骤。 - 仅返回当前选中工序下的步骤。
- 排序:先按
sort升序,再按id升序。 - 切换工序后,页面会重新加载步骤、录入配置,并保存当前选择。
2.4 订单号录入方式
订单号支持两种录入方式:
- 手工输入:在订单号输入框直接录入;
- 相机扫码:调用
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 字符 |
当前订单模式前端固定提交:
{
"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 重复扫码规则
后端以“同订单号 + 同工序 + 同步骤”查询最新扫码记录。若不存在历史记录,允许直接提交;若存在,则按下列优先级计算重复扫码策略:
- 全局基础配置
global_allow_repeat、repeat_scan_interval; - 当前步骤配置覆盖全局是否允许重复及允许的状态;
- 命中的特定规则可最终覆盖“是否允许重复”。
默认与覆盖逻辑
| 配置来源 | 影响 |
|---|---|
global_allow_repeat |
未配置步骤规则时的默认允许重复开关 |
repeat_scan_interval |
最短重复扫码间隔(秒) |
allow_repeat_scan |
步骤级允许重复开关,会覆盖全局开关 |
repeat_scan_statuses |
限制仅在指定状态下允许重复;空数组表示不额外限制状态 |
命中特定规则且 rule_type = 1 |
允许重复 |
命中特定规则且 rule_type != 1 |
不允许重复 |
当存在历史记录时,以下任一条件不满足都会拒绝提交:
- 当前策略未允许重复:提示“当前配置不允许重复扫码”;
- 配置了允许重复状态,且最近记录的状态不在范围内:提示“当前状态不允许重复扫码”;
- 配置了最短间隔,且距离最近一次扫码不足该秒数:提示“重复扫码间隔不能小于 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 下一步骤扫码触发上游状态转换
提交当前步骤订单记录后,后端在同一数据库事务中处理“下一步骤扫码自动触发状态转换”。该机制含义是:当前步骤扫码可以推动与它相连的前置步骤记录切换状态。
触发过程如下:
- 找到所有已启用、且目标步骤等于当前步骤的步骤关系:
produce_step_relation.to_step_id = 当前 step_id; - 按
priority、sort、id升序逐项处理; - 对每个关系,取同一订单在源步骤(
from_step_id)的最新扫码记录; - 若源记录不存在或没有状态,则跳过;
- 查找源步骤上已启用、自动触发的状态转换:
trigger_event = next_step_scanauto_trigger = 1- 当前源记录状态等于
from_status_id
- 若存在多条可用转换,按以下顺序取第一条:
priority降序;sort升序;id升序;
- 将源记录
status_id更新为转换目标状态to_status_id; - 无论成功或失败,均写入一条
produce_transition_log流转日志。
5.3 “已完成”的系统含义
当前代码中没有独立的“订单完成表”或统一的订单全局完成字段。订单层面的“已完成”主要通过以下事实判断:
- 某步骤的订单扫码记录关联的状态配置为
is_final = 1; - 在后续步骤校验前置条件时,该步骤可被视为已完成(当
prerequisite_require_final = 1); - 当前流程末端步骤是否代表整张订单完成,取决于管理端为该步骤配置的终态及步骤关系。
因此,订单是否已完成是流程配置驱动的结果,不是当前订单模式页面上的固定布尔状态。
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 最近记录
订单模式调用:
GET /appapi/produce/scan-data?user_code=<当前用户>&limit=5
后端行为:
- 支持按订单号、工序、步骤、状态、扫码结果过滤;
- 订单模式页面实际传入用户编码和数量限制,但当前后端订单扫码过滤函数没有使用
user_code条件; - 记录按
scan_time降序、id降序返回; - 支持分页,默认每页 10 条,单页最大 50 条;
- 返回结构包含:
items、total。
现状说明:页面文案为“当前登录用户的最近记录”,但接口实现尚未按
user_code过滤。因此,在当前实现中,该列表实际可能包含其他用户的订单扫码记录。此为文档记录的现行行为,不应被误解为已完成个人隔离。
7.2 统计
订单模式调用:
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. 当前端到端流程
进入订单模式
↓
读取当前用户和已保存的工序/步骤选择
↓
加载启用工序、当前用户参数下的记录/统计、当前工序步骤和规则配置
↓
选择工序与步骤(可切换并保存)
↓
输入或扫描订单号
↓
加载当前上下文的配置与特定规则
↓
前端校验:订单号/工序/步骤/长度/正则/禁止型规则
↓
提交 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. 当前实现的已知边界与风险
以下内容是当前代码已确认的边界,后续若要以“已完成订单”为核心建设功能,应优先统一定义。
-
没有独立的全局订单完成状态。
- 当前“完成”依赖步骤状态
is_final与流程配置。 - 若需要“已完成订单列表”,需要明确:是最后一步进入终态即完成,还是所有必经步骤进入终态即完成。
- 当前“完成”依赖步骤状态
-
订单模式前端的部分校验没有在后端重复执行。
- 最小长度、订单正则、禁止型特定规则主要在前端执行。
- 直接调用接口的客户端理论上可以绕过这些规则。
- 后续需将关键业务准入规则统一收敛至后端,前端只保留体验层预校验。
-
最近记录与统计未实际按
user_code过滤。- 页面传递用户编码,但服务端
applyScanDataFilter未处理该字段。 - 当前页面“当前用户”相关文案与真实数据范围可能不一致。
- 页面传递用户编码,但服务端
-
统计字段命名与口径依赖配置。
today_total是否仅统计当日由recent_records_today_only决定。- 页面未传工序和步骤,所以“当前工序/步骤扫码量”文案不能保证与实际查询范围一致。
-
初始状态存在性由配置保证。
- 若当前步骤未配置初始状态,记录可能以空状态创建,影响后续前置完成判定和自动流转。
-
自动流转只由订单模式提交触发。
- 整机模式当前不会执行相同的前置步骤、重复扫码和下一步骤自动流转逻辑。
-
当前订单模式默认只提交成功结果。
- 页面固定
scan_result = 1,失败记录、备注等需要通过其他页面或接口能力处理。
- 页面固定
11. 后续建设“已完成订单”功能前的统一规则建议
若后续要增加“已完成订单”列表、详情、查询或统计,建议先由业务方确认以下定义,再实施接口和页面:
-
完成判定对象:
- 指定末端步骤进入终态;
- 所有必经步骤进入终态;
- 指定末端步骤成功扫码即可;
- 是否还要排除未关闭的异常或维修任务。
-
完成时间:
- 最后一步进入终态的时间;
- 最后一次成功扫码时间;
- 所有必经步骤均完成时的最大完成时间。
-
同订单重工/返工:
- 完成后是否允许再次扫码;
- 再次扫码是否撤销完成状态;
- 应使用订单维度快照还是按最新步骤记录实时计算。
-
异常和维修的影响:
- 待处理异常是否阻止进入已完成列表;
- 已维修但未复核的订单是否算完成;
- 维修完成后是否要回写生产步骤或重新进入某一工序。
-
列表数据模型:
- 运行时按
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 |