用途:在 Open edX Studio 的课程单元中内嵌 PDF 阅读器。pdf XBlock 属于高级模块,课程需先在 advanced_modules 中列出 pdf,Studio 才能创建,且其字段通过自身 handler 保存,而非通用 xblock 更新。流程为:每门课启用一次 → 上传文件 → 创建并保存。
前置条件:先运行 node .claude/skills/iblai-api-studio-auth/scripts/studio-login.mjs --check,需打印两个 ok,否则先执行 /iblai-api-studio-auth。需要单元 locator(来自 /iblai-api-studio-unit 或 /iblai-api-studio-outline;批量构建器无法创建 pdf 块,需事后单独添加),以及磁盘上的 PDF 文件(过大时先压缩)。
认证与约定:Base URL 为 $STUDIO_URL,会话 cookie 来自 studio.env(值为单引号包裹,解析时需去引号,否则 Studio 返回 500)。加载方式:set -a; . ./studio.env; set +a。请求需带 studio_session_id、csrftoken、X-CSRFToken、Origin、Referer、Accept 等头。块 locator 形如 …+type@pdf+block@<hex>。字段为 display_name(标题)与 href(PDF 的 URL,可为课程资产 /static/<file>.pdf 或绝对 https:// URL)。保存后单元处于草稿状态,需发布(/iblai-api-studio-publish)。DELETE 具破坏性,须先与用户确认。
读取:GET /settings/advanced/{COURSE} 查看 advanced_modules 是否含 pdf;GET /xblock/{pdf} 查看 display_name、category、metadata、published、has_changes(不含 href);href 需从 GET /xblock/{pdf}/studio_view 的 HTML 中用正则 id="edit_href"[^>]value="([^"])" 提取;GET /assets/{COURSE}/?asset_type=Documents&page_size=50 列出已上传 PDF,assets[].portable_url 即 /static/… 路径。
写入:启用模块(每课一次,需保留其他条目):POST /settings/advanced/{COURSE},body 为 {"advanced_modules":{"value":["pdf"]}},已有其他模块时先读取再合并。上传 PDF 用 multipart,字段名 file,不可带 JSON Content-Type:curl -s -b "studio_session_id=$STUDIO_SESSION; csrftoken=$STUDIO_CSRF" -H "X-CSRFToken: $STUDIO_CSRF" -H "Origin: $STUDIO_URL" -H "Referer: $STUDIO_URL/" -H "Accept: application/json" -X POST "$STUDIO_URL/assets/$COURSE/" -F "file=@syllabus.pdf",返回 asset.portable_url;同名重传会替换资产。创建块:POST /xblock/,body 含 parent_locator、category=pdf、display_name,返回 locator;此处 400/500 通常表示未启用模块。保存标题与文件:POST /xblock/{pdf}/handler/save_pdf,body 为 {"display_name":"Syllabus","href":"/static/syllabus.pdf"},这是唯一持久化 href 的调用。重命名用 POST /xblock/{pdf} 传 metadata.display_name;在 metadata 中传 href 或 url 会被忽略或返回 500,切勿用于文件。删除:DELETE /xblock/{pdf} 返回 204,须先确认。
限制:href 可用 /static/<name>(跨重跑与主机可移植)或绝对 URL,外部 URL 须允许嵌入(不能有 X-Frame-Options: DENY)。该块为内联阅读器,字段中没有下载开关;如需下载链接,可在 /iblai-api-studio-html 块中链接 external_url。保存后用 studio_view 正则验证,通用 GET /xblock/{pdf} 只显示 display_name。上传的 -F 请求不得携带 Content-Type: application/json。大 PDF 受部署上传上限限制(数十 MB),不确定时先压缩。