feat(qoder): 适配国际版每日签到 — UMID 设备风控身份 + 国际版活动 schema
核心发现(实测): - Qoder 国际版服务端只对带 Cosy-MachineToken/Code/Type 的请求下发签到活动, 否则 campaigns 返回空数组(国内版无此限制) - 国际版活动 actionType=VIEW_DETAILS(国内版 CLAIM_BENEFIT),claimStatus 一致 - 活动窗口 2026-09-01~10-31,每日 10:00 (UTC+8) 刷新,领取后 30 天有效 实现: - 新增 umid.py:从官方 npm 包 @qoder-ai/qodercli 下载并提取内嵌 UMID 二进制 (x86_64/arm64 ELF),试跑校验后缓存到 @appdata/AgentCheckin/umid/ - qoder.py:签到前自动确保风控身份,支持国际版/国内版双 schema 活动解析 - API:/api/umid/status、/api/umid/install、/api/accounts/refresh_risk - 前端:设置页风控身份面板(下载/状态)、账号列表「刷新风控」按钮 - 诊断:测连接返回 risk_identity / campaigns_debug(原始字段) 验证:NAS 实测 Qoder 国际版从「活动列表为空」变为「今日已领取(75 积分)」 测试:37 后端 + 25 E2E + 9 前端,全部通过
This commit is contained in:
@@ -203,6 +203,37 @@ def h_fix_qoder_domain(_params, body):
|
||||
return {"ok": False, "probe": probe,
|
||||
"error": "两个站点均无法认证(Token 可能已过期),请重新获取 Token"}
|
||||
|
||||
|
||||
def h_umid_status(_params, _body):
|
||||
"""Qoder 风控身份(UMID runtime-info)安装状态。"""
|
||||
import umid as _u
|
||||
return _u.status()
|
||||
|
||||
|
||||
def h_umid_install(_params, _body):
|
||||
"""下载官方 qodercli 并提取 runtime-info(约 30MB,耗时 1-3 分钟)。"""
|
||||
import umid as _u
|
||||
ok, msg = _u.install(force=bool((_body or {}).get("force")))
|
||||
return {"ok": ok, "message": msg, "status": _u.status()}
|
||||
|
||||
|
||||
def h_qoder_refresh_risk(_params, body):
|
||||
"""为某个 Qoder 账号重新生成风控身份。"""
|
||||
acc_id = body.get("id")
|
||||
if not acc_id:
|
||||
return ("error", "缺少 id")
|
||||
accounts = load_accounts()
|
||||
acc = engine.find_account(accounts, acc_id)
|
||||
if not acc or acc.get("platform") != "qoder":
|
||||
return ("error", "账号不存在或不是 Qoder 账号")
|
||||
import qoder as _q
|
||||
tok, code, mtype, err = _q.risk_identity(acc, force=True)
|
||||
if err:
|
||||
return {"ok": False, "error": err}
|
||||
engine.save_accounts([acc if a.get("id") == acc_id else a for a in accounts])
|
||||
return {"ok": True, "machineToken": tok[:12] + "…", "machineCode": code, "machineType": mtype}
|
||||
|
||||
|
||||
def h_delete_account(_params, body):
|
||||
acc_id = body.get("id")
|
||||
if not acc_id:
|
||||
@@ -356,6 +387,9 @@ ROUTES = {
|
||||
("POST", "/api/accounts/test"): h_test_account,
|
||||
("POST", "/api/wb_oauth_begin"): h_wb_oauth_begin,
|
||||
("GET", "/api/wb_oauth_poll"): h_wb_oauth_poll,
|
||||
("GET", "/api/umid/status"): h_umid_status,
|
||||
("POST", "/api/umid/install"): h_umid_install,
|
||||
("POST", "/api/accounts/refresh_risk"): h_qoder_refresh_risk,
|
||||
("GET", "/api/settings"): h_settings_get,
|
||||
("POST", "/api/settings"): h_settings_post,
|
||||
("GET", "/api/logs"): h_logs,
|
||||
|
||||
Reference in New Issue
Block a user