chore: auto release commit (2026-09-15 01:02:50)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
All checks were successful
技能自动化发布 / release (push) Successful in 6s
This commit is contained in:
@@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
本文件对应技能市场 **「更新日志」** Tab。
|
本文件对应技能市场 **「更新日志」** Tab。
|
||||||
|
|
||||||
|
## 1.1.21
|
||||||
|
|
||||||
|
- **修复登录完成检测盲区**:`_wait_for_manual_login` 现在监听 3 个信号判断「登录已完成」,任一触发即继续
|
||||||
|
1. URL 含 `/app/` 且稳定 2 秒(v1.1.20 旧逻辑)
|
||||||
|
2. URL 已离开 `/login` / `/signin` / `/auth/` 等登录路径
|
||||||
|
3. 页面出现 sidebar 元素 `a[href$='/hr/contracts']`
|
||||||
|
- 解决「用户已经登录但脚本还在傻等」的回归:之前只判 URL 变化,cookie 已生效复用 profile 场景或 SPA 不跳 URL 的场景会卡 180 秒
|
||||||
|
|
||||||
## 1.1.20
|
## 1.1.20
|
||||||
|
|
||||||
- **登录流程重写**:第一跳改为 `https://sandbox.jc2009.com/`(根域,用户最初看到的页面),**不做任何操作**等 URL 稳定
|
- **登录流程重写**:第一跳改为 `https://sandbox.jc2009.com/`(根域,用户最初看到的页面),**不做任何操作**等 URL 稳定
|
||||||
|
|||||||
2
SKILL.md
2
SKILL.md
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: 合同到期智能预警与续聘辅助
|
name: 合同到期智能预警与续聘辅助
|
||||||
description: "当用户说要扫描即将到期的合同、查 90/60/30 天预警名单、给某位教师生成续聘任务书、下发单位版续聘清单、从 SmartCampus HR 平台抓合同数据、解析续聘材料 PDF/Word、查看本月合同到期人员清单时,加载本技能。支持定时扫描(每日凌晨)+ 数据管理 + Agent 三入口,覆盖合同到期智能预警与续聘辅助全流程。"
|
description: "当用户说要扫描即将到期的合同、查 90/60/30 天预警名单、给某位教师生成续聘任务书、下发单位版续聘清单、从 SmartCampus HR 平台抓合同数据、解析续聘材料 PDF/Word、查看本月合同到期人员清单时,加载本技能。支持定时扫描(每日凌晨)+ 数据管理 + Agent 三入口,覆盖合同到期智能预警与续聘辅助全流程。"
|
||||||
version: 1.1.20
|
version: 1.1.21
|
||||||
author: 深圳匠厂科技有限公司
|
author: 深圳匠厂科技有限公司
|
||||||
metadata:
|
metadata:
|
||||||
openclaw:
|
openclaw:
|
||||||
|
|||||||
@@ -168,15 +168,19 @@ def _is_logged_in(page) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def _wait_for_manual_login(page, wait_sec: int = HUMAN_WAIT_TIMEOUT) -> bool:
|
def _wait_for_manual_login(page, wait_sec: int = HUMAN_WAIT_TIMEOUT) -> bool:
|
||||||
"""手工登录 fallback(v1.1.19 重写):等用户在浏览器输完账号密码提交。
|
"""手工登录 fallback(v1.1.19 重写,v1.1.20 加强):等用户在浏览器完成登录。
|
||||||
|
|
||||||
|
判定「登录完成」的多个信号(满足任一即视为完成):
|
||||||
|
1. URL 含 `/app/` 且稳定 URL_STABLE_REQUIRED_S 秒(v1.1.19 旧逻辑)
|
||||||
|
2. URL 已离开 `/login` / `/signin` / `/auth/` 等登录路径(v1.1.20 新增)
|
||||||
|
—— 即便 sandbox 未跳到 /app/,只要离开登录页就认为登录成功
|
||||||
|
3. 页面出现 sidebar 元素 `a[href$='/hr/contracts']`(v1.1.20 新增)
|
||||||
|
—— 说明已加载到 SPA 主页
|
||||||
|
|
||||||
与之前轮询 _is_logged_in 不同的设计:
|
|
||||||
- **不做任何 goto / reload / click**,避免打断用户输入
|
- **不做任何 goto / reload / click**,避免打断用户输入
|
||||||
- 每 HUMAN_PROMPT_INTERVAL 秒打印一次剩余时间(默认 15s)
|
- 每 HUMAN_PROMPT_INTERVAL 秒打印一次剩余时间(默认 15s)
|
||||||
- 每 HUMAN_POLL_INTERVAL 秒(默认 5s)只检查 URL,不做任何操作
|
- 每 HUMAN_POLL_INTERVAL 秒检查一次(默认 5s)
|
||||||
- 用户完成登录(URL 跳到 /app/...)后 **等 URL 真正稳定**,再返回 True
|
- 超时抛 LoginTimeoutError。
|
||||||
|
|
||||||
超时抛 LoginTimeoutError。
|
|
||||||
"""
|
"""
|
||||||
print(
|
print(
|
||||||
f"[登录] 请在浏览器中完成登录"
|
f"[登录] 请在浏览器中完成登录"
|
||||||
@@ -187,12 +191,24 @@ def _wait_for_manual_login(page, wait_sec: int = HUMAN_WAIT_TIMEOUT) -> bool:
|
|||||||
last_url = page.url
|
last_url = page.url
|
||||||
last_url_change_at = time.monotonic()
|
last_url_change_at = time.monotonic()
|
||||||
|
|
||||||
|
def _is_login_page_url(url: str) -> bool:
|
||||||
|
u = url.lower()
|
||||||
|
return (
|
||||||
|
"/login" in u or "/signin" in u or "/auth/" in u
|
||||||
|
or u.rstrip("/").endswith("sandbox.jc2009.com")
|
||||||
|
)
|
||||||
|
|
||||||
|
def _sidebar_present() -> bool:
|
||||||
|
try:
|
||||||
|
return page.locator("a[href$='/hr/contracts']").count() > 0
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
remaining = deadline - time.monotonic()
|
remaining = deadline - time.monotonic()
|
||||||
if remaining <= 0:
|
if remaining <= 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
# 用户输入完提交后,URL 会从 /login 跳到 /app/...
|
|
||||||
cur_url = page.url
|
cur_url = page.url
|
||||||
if cur_url != last_url:
|
if cur_url != last_url:
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -201,16 +217,37 @@ def _wait_for_manual_login(page, wait_sec: int = HUMAN_WAIT_TIMEOUT) -> bool:
|
|||||||
last_url = cur_url
|
last_url = cur_url
|
||||||
last_url_change_at = time.monotonic()
|
last_url_change_at = time.monotonic()
|
||||||
|
|
||||||
|
# 信号 1:URL 跳到 /app/... 并稳定
|
||||||
if _is_logged_in(page):
|
if _is_logged_in(page):
|
||||||
# URL 已跳到 /app/...:等 URL 稳定 URL_STABLE_REQUIRED_S 秒再返回
|
|
||||||
stable_for = time.monotonic() - last_url_change_at
|
stable_for = time.monotonic() - last_url_change_at
|
||||||
if stable_for >= URL_STABLE_REQUIRED_S:
|
if stable_for >= URL_STABLE_REQUIRED_S:
|
||||||
print(f"[登录] ✅ 检测到登录完成(URL={cur_url}, 稳定 {stable_for:.1f}s)")
|
print(
|
||||||
|
f"[登录] ✅ 检测到登录完成(URL 含 /app/,稳定 {stable_for:.1f}s)"
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
logger.info(
|
logger.info(
|
||||||
"platform_collector: 登录后 URL 还在过渡,等稳定 "
|
"platform_collector: URL 含 /app/ 但还在过渡,等稳定 "
|
||||||
"(current=%s, stable_for=%.1fs)", cur_url, stable_for,
|
"(current=%s, stable_for=%.1fs)", cur_url, stable_for,
|
||||||
)
|
)
|
||||||
|
# 信号 2:URL 已离开登录页(即使不在 /app/,比如卡在中间过渡页也算)
|
||||||
|
elif not _is_login_page_url(cur_url):
|
||||||
|
stable_for = time.monotonic() - last_url_change_at
|
||||||
|
if stable_for >= URL_STABLE_REQUIRED_S:
|
||||||
|
print(
|
||||||
|
f"[登录] ✅ 检测到登录完成(URL 已离开登录页 → {cur_url},"
|
||||||
|
f"稳定 {stable_for:.1f}s)"
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
logger.info(
|
||||||
|
"platform_collector: URL 已离开登录页但还没稳定,等 "
|
||||||
|
"(current=%s, stable_for=%.1fs)", cur_url, stable_for,
|
||||||
|
)
|
||||||
|
# 信号 3:sidebar 已出现
|
||||||
|
elif _sidebar_present():
|
||||||
|
print(
|
||||||
|
f"[登录] ✅ 检测到登录完成(sidebar 已出现,URL={cur_url})"
|
||||||
|
)
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
# 还在登录页:每 HUMAN_PROMPT_INTERVAL 秒提醒用户一次
|
# 还在登录页:每 HUMAN_PROMPT_INTERVAL 秒提醒用户一次
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
@@ -225,6 +262,7 @@ def _wait_for_manual_login(page, wait_sec: int = HUMAN_WAIT_TIMEOUT) -> bool:
|
|||||||
|
|
||||||
raise LoginTimeoutError(
|
raise LoginTimeoutError(
|
||||||
f"自动登录失败,{wait_sec}s 内用户在浏览器中也未完成登录"
|
f"自动登录失败,{wait_sec}s 内用户在浏览器中也未完成登录"
|
||||||
|
f"(最后 URL={page.url})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
SKILL_SLUG = "alert-contract-expiring-hr"
|
SKILL_SLUG = "alert-contract-expiring-hr"
|
||||||
SKILL_VERSION = "1.1.20"
|
SKILL_VERSION = "1.1.21"
|
||||||
LOG_LOGGER_NAME = "openclaw.skill.alert_contract_expiring_hr"
|
LOG_LOGGER_NAME = "openclaw.skill.alert_contract_expiring_hr"
|
||||||
PLATFORM_KIT_MIN_VERSION = "1.2.11"
|
PLATFORM_KIT_MIN_VERSION = "1.2.11"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user