影刀RPA 状态机模式在流程中的实现:订单从待处理到完成的状态流转
影刀RPA 状态机模式按数据状态调度不同处理逻辑很多RPA流程本质上是检查数据的状态 → 决定做什么的循环。订单待付款要催付、已付款要发货、已发货要跟踪物流——每个状态对应不同的操作。这种场景天然适合用状态机模式来设计流程。这篇文章讲怎么在影刀里实现。什么是状态机状态机三要素状态数据当前处于什么阶段。比如订单的待付款“已付款”“已发货”“已完成”“已取消”。事件触发状态变化的原因。比如用户付款“超时自动取消”。动作状态变化时做什么。比如已付款→扣库存通知仓库。在RPA中你通常不需要自己写状态机引擎。你只需要以状态为中心来组织流程逻辑而不是以操作步骤为中心。店群矩阵自动化突破运营极限以状态为中心的流程设计传统写法按步骤 1. 从数据库取所有订单 2. 对每条订单判断状态 3. IF 待付款 → 发催付短信 4. ELIF 已付款 → 通知仓库 5. ELIF 已发货 → 更新物流 ...  状态机写法按状态 状态A待付款 → 超时30分钟→ 发催付短信 → 待付款 状态B已付款 → 推送到WMS → 已发货 状态C已发货 → 查物流 → 已签收→ 已完成状态机写法的好处每个状态的处理逻辑是独立的加一个状态不影响其他状态。改已付款的处理逻辑不用担心误伤待付款的处理。实现订单状态处理器classOrderStateHandler:def__init__(self):self.handlers{待付款:self.handle_pending_payment,已付款:self.handle_paid,已发货:self.handle_shipped,已完成:self.handle_completed,已取消:self.handle_cancelled,}defprocess_order(self,order):statusorder[status]handlerself.handlers.get(status)ifhandler:print(f订单{order[id]}状态{status}开始处理)new_statushandler(order)ifnew_statusandnew_status!status:order[status]new_statusprint(f → 状态更新{status}→{new_status})else:print(f警告未知状态{status})defhandle_pending_payment(self,order):待付款检查是否超时fromdatetimeimportdatetime createddatetime.strptime(order[created_time],%Y-%m-%d %H:%M:%S)elapsed(datetime.now()-created).total_seconds()ifelapsed1800:# 30分钟还没付款# 发催付通知print(f 发催付短信给{order[phone]})return待付款# 状态不变只是催付elifelapsed3600:# 1小时自动取消# 取消订单释放库存print(f 自动取消订单释放库存)return已取消returnNone# 不需要变更状态defhandle_paid(self,order):已付款推送到仓库系统print(f 推送订单到WMS{order[id]})# 调用WMS API...return已发货defhandle_shipped(self,order):已发货查物流判断是否签收# 查物流APIlogisticsself.query_logistics(order[tracking_no])iflogistics.get(status)签收:print(f 已签收订单完成)return已完成else:print(f 物流状态{logistics.get(status)})returnNone# 状态不变defhandle_completed(self,order):已完成什么也不做returnNonedefhandle_cancelled(self,order):已取消什么也不做returnNonedefquery_logistics(self,tracking_no):# 模拟物流查询return{status:运输中}# 使用handlerOrderStateHandler()orders[{id:1,status:待付款,phone:138xxx,created_time:2026-07-01 13:00:00},{id:2,status:已付款,phone:139xxx,created_time:2026-07-01 12:00:00},{id:3,status:已完成,phone:137xxx,created_time:2026-07-01 10:00:00},]fororderinorders:handler.process_order(order)在影刀中的实现状态机模式在影刀中可以这样落地主流程状态扫描器 1. 【读取数据库】→ 获取所有非终态的订单 终态 [已完成, 已取消] 2. FOR EACH order IN orders: 【日志输出】f处理订单 {order.id}状态{order.status} IF order.status 待付款: 【运行子流程】handle_pending.flow ELIF order.status 已付款: 【运行子流程】handle_paid.flow ELIF order.status 已发货: 【运行子流程】handle_shipped.flow # 每个子流程可能更新状态返回new_status IF new_status 和原状态不同: 【更新数据库】→ UPDATE order.status END FOR每个子流程只干一件事handle_pending.flow 1. 检查创建时间 2. 如果超时30分钟 → 发催付短信 3. 如果超时60分钟 → 取消订单返回已取消 4. 否则 → 返回None不更新状态 handle_paid.flow 1. 调用WMS API推送订单 2. 推送成功 → 返回已发货 3. 推送失败 → 记录错误返回None状态转换图怎么画设计状态机前先画出状态转换图。不需要专业工具在纸上画几个方框和箭头待付款 ──(超时)──→ 已取消 待付款 ──(付款)──→ 已付款 已付款 ──(推仓)──→ 已发货 已发货 ──(签收)──→ 已完成 已发货 ──(拒收)──→ 已取消画完以后每个箭头对应一个子流程。新增一个状态或转换只需要加一个箭头子流程不影响现有的。temu店群自动化报活动案例状态机的边界条件做状态机最容易漏的是边界条件1. 并发修改。A流程和B流程同时读到同一条订单都判断为待付款都去发催付短信。客户连收两条一样的短信。解决处理前加乐观锁。# 更新时检查状态是否还是原来的cursor.execute(UPDATE orders SET status %s WHERE id %s AND status %s,(new_status,order_id,original_status))ifcursor.rowcount0:print(状态已被其他流程修改跳过)2. 死循环。状态从A→B→A→B循环流程一直跑停不下来。解决加处理次数上限。每条记录每次扫描最多处理一次。3. 终态节点。“已完成”已取消这些状态不会再变化应该从扫描范围里排除。否则你的流程每次都在扫描已完成的订单白白浪费计算资源。总结状态机模式的核心是把检查状态→执行动作→更新状态这个循环标准化。每个状态的处理逻辑独立成子流程加新状态不影响老状态。状态转换图画清楚再写代码避免死循环和并发冲突。作者林焱