/** * iframe 与宿主页通信消息类型常量 * * 消息格式:{ type: MESSAGE_TYPE, ...其他字段 } * 发送方式:window.parent.postMessage(message, "*") */ // 发送给宿主页的消息类型 export const POST_MESSAGE_TYPES = { // 全屏切换 FULLSCREEN: "fullscreen", // 会话是否处于聊天态 IS_CHATTING: "isChatting", // 请求宿主页执行复制 COPY_TO_CLIPBOARD: "copyToClipboard", // 选择预定义 skill SELECT_SKILLS: "selectedSkills", // 打开 skill 选择对话框 OPEN_SKILL_DIALOG: "openSkillDialog", } as const; // 接收来自宿主页的消息类型 export const RECEIVE_MESSAGE_TYPES = { // 选中的 skill 数据 SELECTED_SKILL: "selectedSkill", // 选中的 skills 数据(数组) SELECTED_SKILLS: "selectedSkills", } as const; // 消息类型 export type PostMessageType = (typeof POST_MESSAGE_TYPES)[keyof typeof POST_MESSAGE_TYPES]; export type ReceiveMessageType = (typeof RECEIVE_MESSAGE_TYPES)[keyof typeof RECEIVE_MESSAGE_TYPES]; // 消息数据类型 export interface FullscreenMessage { type: typeof POST_MESSAGE_TYPES.FULLSCREEN; fullscreen: boolean; } export interface IsChattingMessage { type: typeof POST_MESSAGE_TYPES.IS_CHATTING; isChatting: boolean; } export interface CopyToClipboardMessage { type: typeof POST_MESSAGE_TYPES.COPY_TO_CLIPBOARD; text: string; } export interface SelectSkillMessage { type: typeof POST_MESSAGE_TYPES.SELECT_SKILLS; selectedSkills: SelectedSkillPayloadItem[]; } export interface OpenSkillDialogMessage { type: typeof POST_MESSAGE_TYPES.OPEN_SKILL_DIALOG; openSkillDialog: true; } export interface SelectedSkillMessage { type: typeof RECEIVE_MESSAGE_TYPES.SELECTED_SKILL; id: string | number; title: string; } export interface SelectedSkillPayloadItem { id: string | number; name: string; } type UnknownRecord = Record; function asRecord(value: unknown): UnknownRecord | null { if (typeof value !== "object" || value === null) { return null; } return value as UnknownRecord; } export function isSelectedSkillMessage( value: unknown, ): value is SelectedSkillMessage { const record = asRecord(value); if (record?.type !== RECEIVE_MESSAGE_TYPES.SELECTED_SKILL) { return false; } const { id, title } = record; const isValidId = typeof id === "string" || typeof id === "number"; return isValidId && typeof title === "string" && title.trim().length > 0; } export function isSelectedSkillsMessage( value: unknown, ): value is SelectSkillMessage { const record = asRecord(value); if (record?.type !== RECEIVE_MESSAGE_TYPES.SELECTED_SKILLS) { return false; } const selectedSkills = record.selectedSkills; if (!Array.isArray(selectedSkills)) { return false; } return selectedSkills.every((item) => { const skill = asRecord(item); if (!skill) return false; const id = skill.id; const name = skill.name; const isValidId = typeof id === "string" || typeof id === "number"; return isValidId && typeof name === "string" && name.trim().length > 0; }); } // 发送消息的辅助函数 export function sendToParent( message: | FullscreenMessage | IsChattingMessage | CopyToClipboardMessage | SelectSkillMessage | OpenSkillDialogMessage, ): void { console.log("[iframe] sendToParent:", message); if (window.parent !== window) { window.parent.postMessage(message, "*"); } }