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

24 KiB
Raw Blame History

订单模式工作模式与工作规则说明

文档用途:说明当前生产扫码 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 路由。控制器实际执行逻辑位于:

backend/plugin/produce/app/api/controller/DataEntryController.php

APP API 控制器为委托层,复用上述逻辑。

2.2 页面加载后的准备流程

订单模式页面加载时,按当前本地登录用户初始化并请求以下数据:

  1. 从本地缓存 scanapp_user 读取用户编码;
    • 取值优先级:username → nickname → 默认值 U001。
  2. 获取启用的工序列表;
  3. 获取当前用户的订单模式统计;
  4. 获取当前用户的最近订单扫码记录;
  5. 根据已保存的个人选择恢复工序与步骤;
  6. 获取当前工序的启用步骤;
  7. 获取当前工序/步骤对应的录入配置和特定规则。

用户的工序、步骤选择会保存到本地存储,键名格式为:

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 订单号录入方式

订单号支持两种录入方式:

  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 字符

当前订单模式前端固定提交:

{
  "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 最近记录

订单模式调用:

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. 当前实现的已知边界与风险

以下内容是当前代码已确认的边界,后续若要以“已完成订单”为核心建设功能,应优先统一定义。

  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