chore: auto release commit (2026-09-15 01:10:24)
Some checks failed
技能自动化发布 / release (push) Failing after 6s
Some checks failed
技能自动化发布 / release (push) Failing after 6s
This commit is contained in:
@@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
本文件对应技能市场 **「更新日志」** Tab。
|
本文件对应技能市场 **「更新日志」** Tab。
|
||||||
|
|
||||||
|
## 1.1.23
|
||||||
|
|
||||||
|
- **修复登录后跳 /app/home 的流程**:
|
||||||
|
- `_wait_for_url_stable` 支持 tuple targets(任一匹配即稳定)
|
||||||
|
- 登录后等 URL 稳定到 `/app/` 或 `/select`(sandbox 中间页)
|
||||||
|
- 显式 `goto SPA_HOME_URL` (/app/home) → 等 sidebar link 出现 → click `<a href="/industries/campus/smartcampus/app/hr/contracts">合同到期续聘</a>`
|
||||||
|
- 删掉重复的 # 4 块(之前手抖复制粘贴的 bug)
|
||||||
|
|
||||||
## 1.1.22
|
## 1.1.22
|
||||||
|
|
||||||
- **登录流程接入 sandbox 自动登录**:root 登录页(https://sandbox.jc2009.com/)的 #jc-user / #jc-pass 默认有 demo/123456 预填
|
- **登录流程接入 sandbox 自动登录**:root 登录页(https://sandbox.jc2009.com/)的 #jc-user / #jc-pass 默认有 demo/123456 预填
|
||||||
|
|||||||
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.22
|
version: 1.1.23
|
||||||
author: 深圳匠厂科技有限公司
|
author: 深圳匠厂科技有限公司
|
||||||
metadata:
|
metadata:
|
||||||
openclaw:
|
openclaw:
|
||||||
|
|||||||
@@ -167,6 +167,16 @@ def _is_logged_in(page) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_spa_routed(page) -> bool:
|
||||||
|
"""v1.1.22:检测 sandbox SPA 是否已路由到 SPA 页面(含 /select /app/)。"""
|
||||||
|
url_lower = page.url.lower()
|
||||||
|
return (
|
||||||
|
("/app/" in url_lower or "/select" in url_lower)
|
||||||
|
and "/login" not in url_lower
|
||||||
|
and "/signin" not in url_lower
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _try_auto_sign_in(page, wait_input_sec: int = 2) -> bool:
|
def _try_auto_sign_in(page, wait_input_sec: int = 2) -> bool:
|
||||||
"""v1.1.21:检测登录页 demo/123456 是否已预填,有则自动点 Sign in。
|
"""v1.1.21:检测登录页 demo/123456 是否已预填,有则自动点 Sign in。
|
||||||
|
|
||||||
@@ -386,16 +396,23 @@ def _wait_for_manual_login(page, wait_sec: int = HUMAN_WAIT_TIMEOUT) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def _wait_for_url_stable(
|
def _wait_for_url_stable(
|
||||||
page, target_substr: str, max_wait_sec: int = 30,
|
page, target_substr: str | tuple[str, ...], max_wait_sec: int = 30,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""v1.1.19:等 URL 含 target_substr,且连续 URL_STABLE_REQUIRED_S 秒不变。
|
"""v1.1.19:等 URL 含 target_substr,且连续 URL_STABLE_REQUIRED_S 秒不变。
|
||||||
|
|
||||||
|
v1.1.22:target_substr 支持 tuple(任一匹配即视为稳定)。
|
||||||
|
|
||||||
用于「已登录态直接跳到目标页面」后等待 SPA 路由稳定。
|
用于「已登录态直接跳到目标页面」后等待 SPA 路由稳定。
|
||||||
**不做任何 goto / reload**,只 listen URL 变化。
|
**不做任何 goto / reload**,只 listen URL 变化。
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True = URL 已稳定到目标;False = 超时。
|
True = URL 已稳定到任一目标;False = 超时。
|
||||||
"""
|
"""
|
||||||
|
if isinstance(target_substr, str):
|
||||||
|
targets = (target_substr,)
|
||||||
|
else:
|
||||||
|
targets = target_substr
|
||||||
|
|
||||||
deadline = time.monotonic() + max_wait_sec
|
deadline = time.monotonic() + max_wait_sec
|
||||||
last_url = page.url
|
last_url = page.url
|
||||||
last_url_change_at = time.monotonic()
|
last_url_change_at = time.monotonic()
|
||||||
@@ -410,7 +427,8 @@ def _wait_for_url_stable(
|
|||||||
last_url = cur_url
|
last_url = cur_url
|
||||||
last_url_change_at = time.monotonic()
|
last_url_change_at = time.monotonic()
|
||||||
|
|
||||||
if target_substr in cur_url.lower():
|
cur_lower = cur_url.lower()
|
||||||
|
if any(t.lower() in cur_lower for t in targets):
|
||||||
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:
|
||||||
return True
|
return True
|
||||||
@@ -653,32 +671,39 @@ def collect_all(
|
|||||||
f"(请用 --show-browser 重试)"
|
f"(请用 --show-browser 重试)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 4. 登录完成 → 等 URL 真正稳定到 /app/(最多 30s,**不做任何操作**)
|
# 4. 登录完成 → 等 URL 真正稳定到 /app/ 或 /select(最多 30s,**不做任何操作**)
|
||||||
# 之前 retry loop 会强制 goto home / fill login,**打断用户刚登录态**。
|
# v1.1.22:sandbox 登录后会先跳 /select,再自动跳 /app/home,
|
||||||
if not _wait_for_url_stable(page, "/app/", max_wait_sec=30):
|
# 所以两个 URL 都算"SPA 已路由"
|
||||||
|
if not _wait_for_url_stable(page, ("/app/", "/select"), max_wait_sec=30):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"platform_collector: 登录后 30s 内 URL 未稳定到 /app/(当前 URL=%s)",
|
"platform_collector: 登录后 30s 内 URL 未稳定到 /app/或 /select(当前 URL=%s)",
|
||||||
page.url,
|
page.url,
|
||||||
)
|
)
|
||||||
# 不强行 reload —— 让用户决定是否手工刷新
|
# 不强行 reload —— 让用户决定是否手工刷新
|
||||||
|
|
||||||
# 5. 登录完成 → 等 URL 真正稳定到 /app/(最多 30s,**不做任何操作**)
|
# 5. v1.1.22:显式跳到 SPA_HOME_URL(/app/home),等侧边栏 link 出现
|
||||||
# 之前 retry loop 会强制 goto home / fill login,**打断用户刚登录态**。
|
# 避免 sandbox 在 /select 中间页时直接找 sidebar link 找不到
|
||||||
if not _wait_for_url_stable(page, "/app/", max_wait_sec=30):
|
if "/app/home" not in page.url.lower():
|
||||||
|
logger.info(
|
||||||
|
"platform_collector: 当前 URL=%s,跳到 SPA_HOME_URL=%s",
|
||||||
|
page.url, SPA_HOME_URL,
|
||||||
|
)
|
||||||
|
_goto(page, SPA_HOME_URL)
|
||||||
|
page.wait_for_timeout(SPA_HYDRATION_MS)
|
||||||
|
# 等 URL 稳定到 /app/home(最多 15s,**不做任何操作**)
|
||||||
|
if not _wait_for_url_stable(page, "/app/home", max_wait_sec=15):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"platform_collector: 登录后 30s 内 URL 未稳定到 /app/(当前 URL=%s)",
|
"platform_collector: 15s 内未稳定到 /app/home(当前 URL=%s)",
|
||||||
page.url,
|
page.url,
|
||||||
)
|
)
|
||||||
# 不强行 reload —— 让用户决定是否手工刷新
|
|
||||||
|
|
||||||
# 5. 等 SPA 渲染 + click 侧边栏 hr/contracts(SPA 路由,避免 goto 触发整页 reload 丢 session)
|
# 6. 等 SPA 渲染 + click 侧边栏 hr/contracts(SPA 路由,避免 goto 触发整页 reload 丢 session)
|
||||||
try:
|
try:
|
||||||
# dump SPA home 一次(用于调试 selector)
|
# dump SPA home 一次(用于调试 selector)
|
||||||
page.wait_for_timeout(POST_LOGIN_SETTLE_MS)
|
page.wait_for_timeout(POST_LOGIN_SETTLE_MS)
|
||||||
_dump_page(page, download_dir.parent / "spa_home_dump.html", "SPA home")
|
_dump_page(page, download_dir.parent / "spa_home_dump.html", "SPA home")
|
||||||
|
|
||||||
# 等 SPA 真正加载完(侧边栏 link 出现,最长 SIDEBAR_LINK_TIMEOUT_MS)
|
# 等 SPA 真正加载完(侧边栏 link 出现,最长 SIDEBAR_LINK_TIMEOUT_MS)
|
||||||
# 修复:之前 15s 太短,sandbox mock 加载慢时直接 fallback 到 pushState → 表格加载不出来
|
|
||||||
try:
|
try:
|
||||||
page.wait_for_selector(
|
page.wait_for_selector(
|
||||||
"a[href$='/hr/contracts']",
|
"a[href$='/hr/contracts']",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
SKILL_SLUG = "alert-contract-expiring-hr"
|
SKILL_SLUG = "alert-contract-expiring-hr"
|
||||||
SKILL_VERSION = "1.1.22"
|
SKILL_VERSION = "1.1.23"
|
||||||
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