支持创建周期验收项目并延迟首采
This commit is contained in:
@@ -996,17 +996,34 @@ def create_acceptance_task(data: dict[str, Any]) -> dict[str, Any]:
|
|||||||
422,
|
422,
|
||||||
)
|
)
|
||||||
name = str(data.get("name") or "").strip() or f"项目验收|{keywords[0] if keywords else '飞书资料'}"
|
name = str(data.get("name") or "").strip() or f"项目验收|{keywords[0] if keywords else '飞书资料'}"
|
||||||
|
schedule_requested = data.get("schedule_weekdays") not in (None, [], "")
|
||||||
|
schedule_weekdays = _normalize_schedule_weekdays(data.get("schedule_weekdays")) if schedule_requested else []
|
||||||
|
schedule_start = _normalize_schedule_time(data.get("schedule_start_time", "00:00"), "开始时间") if schedule_requested else "00:00"
|
||||||
|
schedule_end = _normalize_schedule_time(data.get("schedule_end_time", "23:59"), "结束时间") if schedule_requested else "23:59"
|
||||||
|
if schedule_requested and schedule_start > schedule_end:
|
||||||
|
raise TaskError("INVALID_SCHEDULE_RANGE", "开始时间不能晚于结束时间", 422)
|
||||||
|
defer_initial = data.get("defer_initial_collection") is True
|
||||||
|
initial_status = "completed" if defer_initial else "waiting"
|
||||||
|
initial_progress = 100 if defer_initial else 0
|
||||||
now = now_iso()
|
now = now_iso()
|
||||||
with connection() as conn:
|
with connection() as conn:
|
||||||
public_id = _public_id()
|
public_id = _public_id()
|
||||||
cursor = conn.execute(
|
cursor = conn.execute(
|
||||||
"""INSERT INTO acceptance_tasks
|
"""INSERT INTO acceptance_tasks
|
||||||
(public_task_id,name,acceptance_method,status,progress_percent,device_count,
|
(public_task_id,name,acceptance_method,status,progress_percent,device_count,
|
||||||
created_by_id,created_by_name,created_at,updated_at,trigger_source,cookie_count)
|
created_by_id,created_by_name,created_at,updated_at,trigger_source,cookie_count,
|
||||||
VALUES (?,?,?,'waiting',0,?,?,?,?,?,?,?)""",
|
schedule_enabled,schedule_weekday,schedule_weekdays,schedule_start_time,
|
||||||
(public_id, name, method, device_count, str(data.get("created_by_id") or "local-dev"),
|
schedule_end_time,next_run_at,use_all_devices)
|
||||||
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
|
||||||
|
(public_id, name, method, initial_status, initial_progress, device_count,
|
||||||
|
str(data.get("created_by_id") or "local-dev"),
|
||||||
str(data.get("created_by_name") or "本地开发用户"), now, now,
|
str(data.get("created_by_name") or "本地开发用户"), now, now,
|
||||||
str(data.get("trigger_source") or "acceptance"), cookie_count),
|
str(data.get("trigger_source") or "acceptance"), cookie_count,
|
||||||
|
1 if schedule_requested else 0, schedule_weekdays[0] if schedule_weekdays else None,
|
||||||
|
json.dumps(schedule_weekdays) if schedule_weekdays else None,
|
||||||
|
schedule_start, schedule_end,
|
||||||
|
_next_weekly_run(schedule_weekdays, schedule_start) if schedule_weekdays else None,
|
||||||
|
1 if method in {"screenshot", "combined"} else 0),
|
||||||
)
|
)
|
||||||
task_id = cursor.lastrowid
|
task_id = cursor.lastrowid
|
||||||
conn.executemany(
|
conn.executemany(
|
||||||
@@ -1046,6 +1063,7 @@ def create_acceptance_task(data: dict[str, Any]) -> dict[str, Any]:
|
|||||||
VALUES (?,?,?,?,'waiting',?,?)""",
|
VALUES (?,?,?,?,'waiting',?,?)""",
|
||||||
[(task_id, index, url, _source_type(url), now, now) for index, url in enumerate(links)],
|
[(task_id, index, url, _source_type(url), now, now) for index, url in enumerate(links)],
|
||||||
)
|
)
|
||||||
|
if not defer_initial:
|
||||||
threading.Thread(target=_fetch_sources, args=(public_id,), daemon=True, name=f"acceptance-{public_id}").start()
|
threading.Thread(target=_fetch_sources, args=(public_id,), daemon=True, name=f"acceptance-{public_id}").start()
|
||||||
return get_acceptance_task(public_id)
|
return get_acceptance_task(public_id)
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,11 @@
|
|||||||
"description": "仅用于笔记收录。填写后仅使用该 Cookie;留空时使用 Cookie 池全部可用凭据。不会在任务详情中返回。"
|
"description": "仅用于笔记收录。填写后仅使用该 Cookie;留空时使用 Cookie 池全部可用凭据。不会在任务详情中返回。"
|
||||||
},
|
},
|
||||||
"created_by_id": {"type": "string"},
|
"created_by_id": {"type": "string"},
|
||||||
"created_by_name": {"type": "string"}
|
"created_by_name": {"type": "string"},
|
||||||
|
"schedule_weekdays": {"type": "array", "items": {"type": "integer", "minimum": 1, "maximum": 7}},
|
||||||
|
"schedule_start_time": {"type": "string", "example": "20:00"},
|
||||||
|
"schedule_end_time": {"type": "string", "example": "22:00"},
|
||||||
|
"defer_initial_collection": {"type": "boolean", "description": "true 时只保存周期项目,不立即启动首批采集"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -62,6 +62,24 @@ class AcceptanceCreationTest(unittest.TestCase):
|
|||||||
self.assertEqual(task["keywords"], ["山姆特价"])
|
self.assertEqual(task["keywords"], ["山姆特价"])
|
||||||
self.assertEqual(task["feishu_links"], [])
|
self.assertEqual(task["feishu_links"], [])
|
||||||
|
|
||||||
|
@patch("acceptance_service.threading.Thread", _ThreadWithoutStart)
|
||||||
|
@patch("acceptance_service.get_wen_resources")
|
||||||
|
def test_create_can_save_schedule_without_starting_initial_collection(self, resources):
|
||||||
|
resources.return_value = {"cookie_count": 2, "device_count": 3, "credential_ids": ["c1", "c2"]}
|
||||||
|
task = create_acceptance_task({
|
||||||
|
"acceptance_method": "combined", "keywords": ["山姆会员卡"],
|
||||||
|
"match_keywords": ["民生"], "schedule_weekdays": [1, 4],
|
||||||
|
"schedule_start_time": "20:00", "schedule_end_time": "22:00",
|
||||||
|
"defer_initial_collection": True,
|
||||||
|
})
|
||||||
|
self.assertEqual(task["status"], "completed")
|
||||||
|
self.assertEqual(task["cookie_count"], 2)
|
||||||
|
self.assertEqual(task["device_count"], 3)
|
||||||
|
self.assertEqual(task["schedule_weekdays"], [1, 4])
|
||||||
|
self.assertEqual(task["schedule_start_time"], "20:00")
|
||||||
|
self.assertIsNotNone(task["next_run_at"])
|
||||||
|
self.assertEqual(task["keyword_runs"], [])
|
||||||
|
|
||||||
@patch("acceptance_service.threading.Thread", _ThreadWithoutStart)
|
@patch("acceptance_service.threading.Thread", _ThreadWithoutStart)
|
||||||
@patch("acceptance_service.get_wen_resources")
|
@patch("acceptance_service.get_wen_resources")
|
||||||
def test_active_acceptance_task_can_be_cancelled(self, resources):
|
def test_active_acceptance_task_can_be_cancelled(self, resources):
|
||||||
|
|||||||
Reference in New Issue
Block a user