This commit is contained in:
ddrwode
2026-03-02 00:56:09 +08:00
parent e9b359b4fb
commit 71061dc12a
3 changed files with 62 additions and 8 deletions

View File

@@ -549,7 +549,22 @@ Set-Cookie: auth_token=a1b2c3d4e5f6...; HttpOnly; Max-Age=31536000; SameSite=Lax
| task_type | 说明 | 必要参数 | 返回 result | | task_type | 说明 | 必要参数 | 返回 result |
|-----------|------|---------|-------------| |-----------|------|---------|-------------|
| `check_login` | 检测浏览器环境中 BOSS 账号是否已登录 | `account_name`(环境名) | `{ "browser_id", "browser_name", "boss_username", "is_logged_in" }` | | `check_login` | 检测浏览器环境中 BOSS 账号是否已登录 | `account_name`(环境名) | `{ "browser_id", "browser_name", "boss_username", "is_logged_in" }` |
| `boss_recruit` | 执行 BOSS 直聘自动招聘流程 | `worker_id` + `params` | 根据任务定义返回 | | `boss_recruit` | 执行 BOSS 直聘自动招聘流程 | `worker_id` + `params` | `{ "job_title", "total_processed", "wechat_collected", "phone_collected", "details", "error_count" }` |
`boss_recruit``details` 项示例:
```json
{
"name": "候选人A",
"job": "Python开发",
"wechat": "wxid_xxx",
"phone": "13800138000"
}
```
说明:
- 若自动化流程发生报错,任务状态会标记为 `failed`(不再显示为 `success`)。
- 失败任务也会保留 `result`,便于在任务列表查看已采集到的微信号/手机号数量。
--- ---

View File

@@ -144,6 +144,7 @@ class TaskDispatcher:
if failure_reason: if failure_reason:
task.status = TaskStatus.FAILED task.status = TaskStatus.FAILED
task.error = failure_reason task.error = failure_reason
task.result = result
else: else:
task.status = TaskStatus.SUCCESS task.status = TaskStatus.SUCCESS
task.result = result task.result = result

View File

@@ -95,26 +95,41 @@ class BossRecruitHandler(BaseTaskHandler):
human_delay(2.5, 4.0) human_delay(2.5, 4.0)
# 4. 执行招聘流程 # 4. 执行招聘流程
collected = self._recruit_flow(tab, job_title, max_greet) flow_result = self._recruit_flow(tab, job_title, max_greet)
collected = flow_result["details"]
errors = flow_result["errors"]
return { wechat_set = {str(c.get("wechat", "")).strip() for c in collected if str(c.get("wechat", "")).strip()}
phone_set = {str(c.get("phone", "")).strip() for c in collected if str(c.get("phone", "")).strip()}
has_errors = bool(errors)
result = {
"job_title": job_title, "job_title": job_title,
"total_processed": len(collected), "total_processed": len(collected),
"wechat_collected": sum(1 for c in collected if c.get("wechat")), "wechat_collected": len(wechat_set),
"phone_collected": len(phone_set),
"details": collected, "details": collected,
"error_count": len(errors),
"errors": errors[:20],
"success": not has_errors,
} }
if has_errors:
result["error"] = f"招聘流程出现 {len(errors)} 处错误"
def _recruit_flow(self, tab, job_title: str, max_greet: int) -> List[dict]: return result
def _recruit_flow(self, tab, job_title: str, max_greet: int) -> dict:
"""核心招聘流程:遍历聊天列表,打招呼、询问微信号、收集结果。""" """核心招聘流程:遍历聊天列表,打招呼、询问微信号、收集结果。"""
greeting = f"您好,我们正在招【{job_title}】,看到您的经历比较匹配,方便简单聊聊吗?" greeting = f"您好,我们正在招【{job_title}】,看到您的经历比较匹配,方便简单聊聊吗?"
ask_wechat = "后续沟通会更及时,您方便留一下您的微信号吗?我这边加您。" ask_wechat = "后续沟通会更及时,您方便留一下您的微信号吗?我这边加您。"
collected = [] collected = []
errors = []
# 获取左侧会话列表 # 获取左侧会话列表
items = self._get_conversation_items(tab) items = self._get_conversation_items(tab)
if not items: if not items:
self.logger.warning("未找到会话列表元素") self.logger.warning("未找到会话列表元素")
return collected return {"details": collected, "errors": ["未找到会话列表元素"]}
total = min(len(items), max_greet) total = min(len(items), max_greet)
self.logger.info("会话数约 %d,本次处理前 %d", len(items), total) self.logger.info("会话数约 %d,本次处理前 %d", len(items), total)
@@ -164,18 +179,22 @@ class BossRecruitHandler(BaseTaskHandler):
messages = self._get_chat_messages(tab) messages = self._get_chat_messages(tab)
ctx = self._analyze_context(messages, job_title) ctx = self._analyze_context(messages, job_title)
wechats = ctx["wechats"][:2] wechats = ctx["wechats"][:2]
phones = ctx["phones"][:2]
collected.append({ collected.append({
"name": name, "name": name,
"job": job_title, "job": job_title,
"wechat": wechats[0] if wechats else "", "wechat": wechats[0] if wechats else "",
"phone": phones[0] if phones else "",
}) })
except Exception as e: except Exception as e:
self.logger.error("处理第 %d 个会话出错: %s", i + 1, e) err_msg = f"处理第 {i + 1} 个会话出错: {e}"
self.logger.error(err_msg)
errors.append(err_msg)
continue continue
return collected return {"details": collected, "errors": errors}
# ─── 辅助方法 ─── # ─── 辅助方法 ───
@@ -305,14 +324,18 @@ class BossRecruitHandler(BaseTaskHandler):
full_boss = " ".join(boss_texts) full_boss = " ".join(boss_texts)
wechats = [] wechats = []
phones = []
for t in friend_texts: for t in friend_texts:
wechats.extend(self._extract_wechat(t)) wechats.extend(self._extract_wechat(t))
phones.extend(self._extract_phone(t))
wechats = list(dict.fromkeys(wechats))[:3] wechats = list(dict.fromkeys(wechats))[:3]
phones = list(dict.fromkeys(phones))[:3]
return { return {
"already_greeting": job_title in full_boss or "" in full_boss, "already_greeting": job_title in full_boss or "" in full_boss,
"already_asked_wechat": "微信" in full_boss or "微信号" in full_boss, "already_asked_wechat": "微信" in full_boss or "微信号" in full_boss,
"wechats": wechats, "wechats": wechats,
"phones": phones,
} }
@staticmethod @staticmethod
@@ -333,3 +356,18 @@ class BossRecruitHandler(BaseTaskHandler):
if s and s not in found and len(s) >= 6: if s and s not in found and len(s) >= 6:
found.append(s) found.append(s)
return found[:3] return found[:3]
@staticmethod
def _extract_phone(text: str) -> list:
"""提取手机号(仅保留 11 位中国大陆手机号)。"""
if not text or not text.strip():
return []
found = []
# 支持 13800138000 / 138-0013-8000 / 138 0013 8000 等格式
raw_candidates = re.findall(r"1[3-9][\d\-\s]{9,15}", text)
for raw in raw_candidates:
digits = re.sub(r"\D", "", raw)
if len(digits) == 11 and digits.startswith("1") and digits not in found:
found.append(digits)
return found[:3]