From f4b5316436629748ef18c79521a27f3edd9176ee Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Thu, 10 Sep 2026 21:50:18 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=8E=BB=E6=8E=89=20generic=5Fsteps?= =?UTF-8?q?=20=E7=9A=84=E9=BB=98=E8=AE=A4=E6=AD=A5=E9=AA=A4=20+=20?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E5=A4=B1=E8=B4=A5=E5=B8=A6=E4=B8=8A=E7=9C=9F?= =?UTF-8?q?=E5=AE=9E=E5=8E=9F=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tasks/generic/task.py:DEFAULT_PARAMS 只留 max_duration,**不再内置示例步骤** (步骤只能由前端编辑器产出;此前默认的"打开抖音→循环看视频"只有后端在用, 编辑器新建任务本来就是空的,等于埋了个和界面不一致的隐性默认值) - 空步骤不再静默空跑:worker 立即抛错「通用步骤任务没有可执行步骤…」, 设备表「最近错误」能看到(此前会走完 0 步当成功) - core/task_manager.py:重试耗尽的 last_error 现在带上最后一次的真实失败原因, 不再只有"重试N次失败"(用户看不到为什么失败);max_attempts=1 显示"执行失败" 而非费解的"重试1次失败";长度截断 200 字符 - 文档:TASK_DEV §2.10 说明无默认步骤 + 空步骤会报错;API.md 的 task_types 示例 改 default_params={"max_duration":0},POST /api/jobs 补「steps 要一起传」提示 自测(全通过):default_params 无 steps;无步骤任务真跑一次 → 设备错误信息完整含原因; 有步骤任务(wait 1s)真跑一次 → status=done 无错误;临时任务验完已删,任务集合复原 --- core/task_manager.py | 10 +++++++++- doc/API.md | 6 +++++- doc/TASK_DEV.md | 4 ++++ tasks/generic/task.py | 21 ++++++--------------- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/core/task_manager.py b/core/task_manager.py index 1f97b0e..1d398d5 100644 --- a/core/task_manager.py +++ b/core/task_manager.py @@ -757,7 +757,15 @@ class TaskManager: time.sleep(delay) _log.error(f"{serial} 任务 {job.name} 重试耗尽,放弃") - _update_status(serial, status="failed", last_error=f"{job.name} 重试{max_attempts}次失败") + # 带上最后一次的真实失败原因——只写"重试N次失败"会让用户看不到为什么失败 + # (worker 出错时已把原因写进 _WORKERS[serial]["last_error"]) + with _WORKERS_LOCK: + cause = (_WORKERS.get(serial, {}).get("last_error") or "").strip() + msg = (f"{job.name} 重试{max_attempts}次仍失败" if max_attempts > 1 + else f"{job.name} 执行失败") + if cause and cause != msg: + msg += f":{cause}" + _update_status(serial, status="failed", last_error=msg[:200]) finally: # 清除停止标志:整个重试循环结束(成功/失败/停止)后允许下次任务 with self._lock: diff --git a/doc/API.md b/doc/API.md index b38fb0e..3800da9 100644 --- a/doc/API.md +++ b/doc/API.md @@ -222,7 +222,7 @@ "task_type": "generic_steps", "name": "通用步骤", "description": "通过步骤编辑器编排...", - "default_params": {"steps": [...]} + "default_params": {"max_duration": 0} } ] } @@ -305,6 +305,10 @@ {"ok": true, "msg": "任务已创建", "job": {"id": "abc123", "...": "..."}} ``` +> **`params.steps` 要一起传**:`generic_steps` 的执行内容全在 `params.steps`,后端**不提供默认步骤**、 +> 也不做参数校验(编辑器是参数正确性的唯一关卡)。不传 steps 的任务能建成功,但执行时会立即报错 +> 「通用步骤任务没有可执行步骤」,请在「任务」页用步骤编辑器补步骤。 + `schedule` 字段格式: | 字段 | 说明 | |------|------| diff --git a/doc/TASK_DEV.md b/doc/TASK_DEV.md index d709102..c2114af 100644 --- a/doc/TASK_DEV.md +++ b/doc/TASK_DEV.md @@ -280,6 +280,10 @@ while not self.stopped(): - `max_duration` — 最大运行时长(秒),0=不限时 - `steps` — 步骤数组。每步 `{id, type, label, params}`;`id` 前端生成保证唯一 + +> **没有默认步骤**:`DEFAULT_PARAMS` 只含 `max_duration`,步骤只能由步骤编辑器产出 +> (新建任务时编辑器从零开始拖)。若任务的 `params.steps` 为空,worker 会**立即报错** +> (设备「最近错误」显示"通用步骤任务没有可执行步骤…"),不会静默空跑。 - **进度上报**:`done` = 累计已执行的**非容器**步骤数(loop/group/if_el 不计入,避免监控噪音)、`total=0`、`unit="操作"`(前端显示"已执行 N 次操作") - **公共参数**:每步都可有 `probability`(0-100,默认 100,<100 时按百分比概率决定本次是否执行该步) - **嵌套深度上限 5**:loop/group 的 `children`、if_el 的 `then/else` 递归嵌套超过 5 层会被跳过并告警 diff --git a/tasks/generic/task.py b/tasks/generic/task.py index f9dc50f..c859417 100644 --- a/tasks/generic/task.py +++ b/tasks/generic/task.py @@ -104,21 +104,8 @@ STEP_TYPES = [ DEFAULT_PARAMS = { "max_duration": 0, # 最大运行时长(秒),0=不限时 - "steps": [ # 默认示例:打开抖音→循环(看视频→滑动) - { - "id": "step_1", "type": "open_app", "label": "打开抖音", - "params": {"package": "com.ss.android.ugc.aweme", "wait_home": True, "home_feature": "拍摄"}, - }, - { - "id": "step_2", "type": "loop", "label": "循环看视频", - "params": {"max_iterations": 20, "children": [ - {"id": "step_2_1", "type": "wait", "label": "观看视频", - "params": {"min": 5.0, "max": 35.0}}, - {"id": "step_2_2", "type": "swipe", "label": "上滑下一个", - "params": {"direction": "up", "duration_min": 0.25, "duration_max": 0.50}}, - ]}, - }, - ], + # 注意:**没有默认 steps**。步骤由前端步骤编辑器编排产出,新建任务时从零开始拖; + # 缺 steps 的任务执行时会明确报错(见 run_task),不会静默空跑。 } @@ -157,6 +144,10 @@ class GenericStepsWorker(BaseWorker): def run_task(self, d): """按 steps 顺序执行。loop 步骤递归执行其 children。""" + if not self.steps: + # 任务没配步骤(DEFAULT_PARAMS 不含默认步骤,步骤只能由编辑器产出): + # 明确报错而不是"跑完 0 步"当成功——设备表/任务页会显示该错误 + raise ValueError("通用步骤任务没有可执行步骤:请在「任务」页编辑该任务并添加步骤") self._start_timer() self.set_action("开始执行步骤链") self.set_progress(done=0, total=0, unit="操作",