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="操作",