嵌入编辑器与通知事件
父页面只需嵌入 iframe 并监听通知事件。平台不负责接入方数据存储,也不会向接入方服务器主动回调。
嵌入 iframe
<iframe
id="qm-resume-editor"
src="创建会话返回的 editorUrl"
style="width: 100%; height: 100vh; border: 0;"
></iframe>安全监听模板
var editorFrame = document.getElementById("qm-resume-editor");
window.addEventListener("message", function (event) {
// 校验发送域
if (event.origin !== "https://www.qmjianli.com") return;
// 校验确实来自当前 iframe,而不是页面里其他窗口
if (event.source !== editorFrame.contentWindow) return;
var message = event.data;
if (!message || message.source !== "QM_RESUME_EDITOR") return;
switch (message.event) {
case "ready":
console.log("编辑器已就绪");
break;
case "saved":
// 自动保存成功后即返回完整 JSON,接入方应同步保存草稿
saveResumeDraft(message.externalResumeId, message.resumeData);
break;
case "exported":
console.log("本次 PDF 地址", message.downloadUrl);
break;
case "diagnosed":
console.log("诊断报告 PDF 地址", message.downloadUrl);
break;
case "billing_consumed":
console.log("扣费成功,会话剩余(分)", message.sessionBalanceCents);
break;
case "session_balance_insufficient":
showUserPayment(message.requiredAmountCents);
break;
case "developer_balance_insufficient":
alert("开发者账户余额不足,请联系管理员充值");
break;
}
});事件字段
| event | 触发时机 | 主要字段 |
|---|---|---|
| ready | 编辑器加载完成 | sessionId, externalResumeId |
| saved | 草稿自动保存成功 | resumeData, sessionId, externalResumeId, version |
| exported | PDF 同步生成成功 | downloadUrl, expiresAt, externalResumeId |
| diagnosed | AI 诊断报告生成成功 | downloadUrl, expiresAt, externalResumeId |
| billing_consumed | 一次收费操作成功并确认双扣 | action, requestId, amountCents, sessionBalanceCents, developerBalanceCents |
| session_balance_insufficient | 当前会话额度不足 | action, requiredAmountCents, sessionBalanceCents |
| developer_balance_insufficient | 开发者账户余额不足 | action, requiredAmountCents, developerBalanceCents |
| photo_created | AI 证件照生成成功 | photoUrl, expiresAt, temporary |
saved 事件示例
{
"source": "QM_RESUME_EDITOR",
"event": "saved",
"sessionId": "S...",
"externalResumeId": "R10001",
"version": 5,
"resumeData": {
"setData": { "tplId": 1013 },
"basicInfo": { "name": "张三" },
"moduleData": []
}
}saved 表示平台临时草稿保存成功,并把同一份完整 JSON 通知给父页面;不表示接入方已经保存成功。接入方应自行处理保存状态和失败重试。
若
resumeData.basicInfo.photo 是 https://www.qmjianli.com/api_open/v1/id-photo-files/... 这类平台临时地址,接入方应立即下载并转存到自己的对象存储,再把该字段替换成自己的照片 URL 后入库。下次创建会话时传入替换后的地址。增加额度后通知 iframe
服务端调用会话充值接口成功后,父页面通知 iframe 重新拉取余额:
editorFrame.contentWindow.postMessage({
source: "QM_RESUME_HOST",
event: "balance_updated"
}, "https://www.qmjianli.com");iframe 会校验父页面 Origin 是否等于创建会话时的 parentOrigin。即使没有发送该通知,下一次收费操作也会以服务端余额为准;该消息主要用于立即刷新编辑器里的额度展示。
自动保存说明
编辑器约 1 秒防抖后,把草稿临时放在平台 Redis,并通过 saved 携带完整 JSON 给父页面。接入方应以此事件实时保存草稿;平台不会替接入方永久保存。
Origin 约束
iframe 只向会话中的 parentOrigin 发送消息。该值在创建会话时已经与应用白名单比对。若实际嵌入页面换了协议、域名或端口,父页面将收不到通知。