Skip to content

iframe 导入

对接流程

  1. 通过 iframe 加载导入页面
html
<iframe src="${domain_name}/app/import"></iframe>
  1. 通过 OpenAPI 生成文件 file_key(详见文档), 将数据给到 Pixso

  2. 通过 postMessage 消息调用 Pixso

js
iframe.contentWindow.postMessage({
    name: "/file/convert";
    type: "msg-api";
    data: {
        files: [{
            fileKey: string,
            name: "pixso.pix",
            buffer: ArrayBuffer,
            isHtml: true // 是否将 axure 文件当成 html 文件导入
	}],
    };
}, *);
  1. 监听文件导入的状态变化,当对应 file_key 状态为 success 时,导入成功
js
window.addEventListener("message", (event) => {
  if (event.data.name === "/file/convert") {
    const {
      data: { status, message, progress },
    } = event.data;
    // do something
  }
});

接口类型定义

ts
// 外部发送 文件信息 给到 Pixso
interface FileConvertReqMsg {
  name: "/file/convert";
  type: "msg-api";
  data: {
    files: {
      fileKey: string; // 后端创建的文件fileKey
      name: string; // 导入的文件名,必须带文件后缀名
      buffer: ArrayBuffer; // 导入的文件数据
      isHtml?: boolean; // 导入Axure文件时,是否作为html导入(该选项对其他文件类型无效)
      libraryType?: "library" | "design" | "normal"; // 导入的文件类型,默认是 normal ,library 是资源库,design 是设计稿 (仅对 sketch 文件生效, file_key 需要符合规范)
    }[];
  };
}

// Pixso 将文件导入状态返回给 外部 (每个文件状态改变都会通知)
interface FileConvertResMsg {
  name: "/file/convert";
  type: "msg-event";
  data: {
    fileKey: string;
    status: "loading" | "success" | "error";
    // status 为 loading 时, message 为进度枚举值
    // status 为 error 时,message 为报错的原因
    message?: ProgreesMessage | string;
    progress?: string; // 进度,状态为 loading 时返回
  };
}

ProgreesMessage 枚举值说明

枚举值说明进度格式
NONE
DECOMPRESS解压百分比
PARSE_FILE解析百分比
UPLOAD_PREVIEW上传封面图百分比
UPLOAD_FILE上传文件百分比
UPLOAD_IMAGES上传图片进度(1/n)

进度整合说明

将进度整合成一个进度条,可以参考以下代码

ts
const progressMap = new Map<string, string>();
const updateProgress = (
  fileKey: string,
  message: ProgreesMessage,
  progress: string
) => {
  // 预设各个阶段进度占比
  const ratio = {
    DECOMPRESS: 0.1,
    PARSE_FILE: 0.5,
    UPLOAD_PREVIEW: 0.1,
    UPLOAD_FILE: 0.1,
    UPLOAD_IMAGES: 0.2,
  };

  switch (message) {
    // 解压
    case "DECOMPRESS":
      const cur = ratio.DECOMPRESS * parseFloat(progress);
      progressMap.set(fileKey, cur.toFixed(2) + "%");
      break;
    // 解析
    case "PARSE_FILE":
      const cur = ratio.DECOMPRESS + ratio.PARSE_FILE * parseFloat(progress);
      progressMap.set(fileKey, cur.toFixed(2) + "%");
      break;
    // 上传封面图
    case "UPLOAD_PREVIEW":
      const cur =
        ratio.DECOMPRESS +
        ratio.PARSE_FILE +
        ratio.UPLOAD_PREVIEW * parseFloat(progress);
      progressMap.set(fileKey, cur.toFixed(2) + "%");
      break;
    // 上传文件
    case "UPLOAD_FILE":
      const cur =
        ratio.DECOMPRESS +
        ratio.PARSE_FILE +
        ratio.UPLOAD_PREVIEW +
        ratio.UPLOAD_FILE * parseFloat(progress);
      progressMap.set(fileKey, cur.toFixed(2) + "%");
      break;
    // 上传图片
    case "UPLOAD_IMAGES":
      const [_, total] = progress.split("/");
      const cur =
        ratio.DECOMPRESS +
        ratio.PARSE_FILE +
        ratio.UPLOAD_PREVIEW +
        ratio.UPLOAD_FILE +
        ratio.UPLOAD_IMAGES * (1 / total) * 100;
      progressMap.set(fileKey, cur.toFixed(2) + "%");
      break;
    default:
      break;
  }
};

window.addEventListener("message", (event) => {
  if (event.data.name === "/file/convert") {
    const {
      data: { fileKey, status, message, progress },
    } = event.data;
    if (status === "loading") {
      updateProgress(fileKey, message, progress);
    }
  }
});

Sketch 导入

Sketch 普通导入

1、通过 OpenAPI 生成文件 file_key(详见文档),后导入

ts
postMessage({
    name: "/file/convert";
    type: "msg-api";
    data: {
        files: [{
            fileKey: string,
            name: "normal.sketch", // 文件名后缀必须为 .sketch
            buffer: ArrayBuffer,
	}],
    };
}, *);

Sketch 设计稿导入

1、通过 OpenAPI 生成文件 file_key(详见文档),与普通导入的区别是保留实例的关联关系

ts
postMessage({
    name: "/file/convert";
    type: "msg-api";
    data: {
        files: [{
            fileKey: string,
            name: "design.sketch", // 文件名后缀必须为 .sketch
            buffer: ArrayBuffer,
			libraryType: "design"
	}],
    };
}, *);

Sketch 资源库导入

1、解析 Sketch 资源库,获取资源库唯一 file_key 和 该库是否已存在标识 isExists

ts

postMessage({
    name: "/file/parse";
    type: "msg-api";
    data: {
       name: "library.sketch",  // 文件名后缀必须为 .sketch
       buffer: ArrayBuffer,
    };
}, *);


window.addEventListener("message", (event) => {
  if (event.data.name === "/file/parse") {
    const { data: { status, message, fileKey, isExists }} = event.data;
	if(status === "success") {
		// 解析成功
		console.log("资源库 file_key", fileKey, "资源库是否已存在:", isExists)
	}
	if (status === "error") {
		// 解析失败, 打印错误信息
		console.error(message)
	}
});

2.1 如果 isExists 为 true ,说明资源库已存在,往下执行会覆盖该资源库

2.2 如果 isExists 为 false ,则需要通过 OpenAPI 创建由步骤 1 中解析出来的 file_key

3、 将 Sketch 作为资源库导入,libraryType 需要指定为 library

ts
postMessage({
    name: "/file/convert";
    type: "msg-api";
    data: {
        files: [{
            fileKey: string,
            name: "library.sketch",
            buffer: ArrayBuffer,
			libraryType: "library"
	}],
    };
}, *);