Exemple #1
0
export function* uploadReplacingIcon(next) {
  const { userId } = this.state.user;
  invariant(
    this.req.file,
    '未获取上传的图标文件,请检查 formdata 的 icon 字段'
  );
  const { originalname, buffer } = this.req.file;
  const name = getFileName(originalname);
  const param = {
    icons: [{ name, buffer }],
    writeFiles: false
  };
  let icons;
  try {
    icons = yield fontBuilder(param);
  } catch (e) {
    invariant(false, '读取 svg 文件内容有误,请检查文件');
  }
  const icon = icons[0];

  let iconData = {};

  yield seq.transaction(transaction =>
    Icon.create(
      {
        name: icon.name,
        path: icon.d,
        status: iconStatus.REPLACING,
        uploader: userId
      },
      { transaction }
    ).then(addedIcon => {
      iconData = addedIcon;
      const svg = (buffer && buffer.toString()) || null;
      return Cache.create(
        { iconId: addedIcon && addedIcon.id, svg },
        { transaction }
      );
    })
  );

  this.state.respond = {
    replaceId: iconData.id
  };

  yield next;
}
Exemple #2
0
export function* downloadFont(next) {
  const { type, id, icons } = this.param;
  let { version } = this.param;
  let { fontName, isNeedNewFontFamily } = this.param;
  let iconData;
  let foldName;
  let lastModify = null;
  let baselineShouldBeAdjusted = true;

  const isRepo = type === 'repo';
  if (Array.isArray(icons) && icons.length) {
    iconData = yield Icon.findAll({
      where: { id: { $in: icons }, status: iconStatus.RESOLVED },
      attributes: [['fontClass', 'name'], ['code', 'codepoint'], ['path', 'd']],
      raw: true
    });
    foldName = `temporary_${+new Date()}`;
    fontName = fontName || 'iconfont';
  } else {
    const model = isRepo ? Repo : Project;
    const throughModel = isRepo ? RepoVersion : ProjectVersion;
    const instance = yield model.findOne({ where: { id } });

    // 仅对项目进行处理,迫使每次下载都是最新版本
    if (!isRepo) {
      const getVersion = version
        ? Promise.resolve(version)
        : ProjectVersion.max('version', { where: { projectId: id } });
      version = yield getVersion;
      baselineShouldBeAdjusted = !!instance.baseline;
    } else {
      version = 0;
    }

    invariant(instance, `不存在 id 为 ${id} 的 ${isRepo ? '大库' : '项目'}`);

    // 检查项目中是否存在系统占用的图标,若存在则阻止下载
    if (type === 'project') {
      const icon = yield instance.getIcons({
        attributes: ['name'],
        where: { status: iconStatus.DISABLED },
        through: {
          model: ProjectVersion,
          where: { version: 0 }
        },
        raw: true
      });
      invariant(
        !icon.length,
        `项目中的 ${icon
          .map(item => item.name)
          .join('、')} 等图标被系统占用,请先删除,再下载或同步`
      );
    }

    iconData = yield instance.getIcons({
      attributes: [['fontClass', 'name'], ['code', 'codepoint'], ['path', 'd']],
      through: {
        model: throughModel,
        where: { version }
      },
      where: { status: iconStatus.RESOLVED },
      raw: true
    });
    foldName = `${type}-${
      isRepo ? instance.id : instance.name
    }-${versionTools.n2v(version)}`;
    fontName = fontName || (isRepo ? `iconfont${instance.id}` : instance.name);
    if (isRepo) {
      lastModify = +new Date(instance.updatedAt);
    }
  }

  // font-family增加版本号
  let originFontName = '';
  if (isNeedNewFontFamily) {
    originFontName = fontName;
    fontName += '-' + versionTools.n2v(version);
  }

  const fontDest = yield ensureCachesExist(foldName, 'font');
  let needReBuild = true;
  // 如果是大库则检查一下当前文件是否过期
  if (isRepo) {
    const modifyTime = yield getModifyTime(foldName, 'font', 'zip');
    needReBuild = !modifyTime || modifyTime < lastModify;
  }

  // 除了大库已存在副本之外,项目和单独下载都需要 rebuild
  if (needReBuild) {
    const zipDest = `${fontDest}.zip`;
    yield fontBuilder({
      icons: iconData,
      readFiles: false,
      dest: fontDest,
      descent: baselineShouldBeAdjusted ? 128 : 0,
      fontName,
      translate: baselineShouldBeAdjusted ? -128 : 0
    });

    // font-name 是否需要加版本号
    if (isNeedNewFontFamily) {
      // 处理文件名 改回原来的
      fs.readdirSync(fontDest).forEach(fileName => {
        const path = fontDest + '/' + fileName;

        let fileExt = fileName.replace(/.+\./, '');

        // 处理html 删除带版本号的后缀
        if (fileExt === 'html') {
          let htmlContent = fs.readFileSync(path, 'utf8');
          let arr = htmlContent.split(fontName + '.');
          htmlContent = arr.join(originFontName + '.');

          fs.writeFileSync(path, htmlContent);
        }

        const oldPath = path;
        const newPath =
          fontDest + '/' + fileName.replace(/.+\./, originFontName + '.');

        // 替换回原文件名
        fs.renameSync(oldPath, newPath);
      });

      let fileCc = fs.readdirSync(fontDest).length;

      invariant(fileCc >= 5, '文件缺失, 请重试');
    }

    yield Q.nfcall(zip, fontDest, { saveTo: zipDest });
  }
  this.state.respond = {
    foldName: `${foldName}.zip`,
    fontDest: `${fontDest}.zip`
  };
  yield next;
}
Exemple #3
0
export function* uploadIcons(next) {
  const { userId } = this.state.user;
  invariant(
    this.req.files && this.req.files.length,
    '未获取上传的图标文件,请检查 formdata 的 icon 字段'
  );
  // 处理传入文件
  const param = {
    icons: this.req.files.map(file => {
      const { originalname } = file;
      console.log(file);
      let buffer = file.buffer;
      buffer = replaceDefs(buffer, originalname);
      const name = getFileName(originalname);
      return { name, buffer };
    }),
    // 标记只返回图标信息数据
    writeFiles: false
  };

  yield saveOriginalSVG(param.icons);

  let icons;
  try {
    icons = yield fontBuilder(param);
  } catch (e) {
    invariant(false, '读取 svg 文件内容有误,请检查文件');
  }

  const data = icons.map(icon => {
    invariant(
      ICON_NAME.reg.test(icon.name),
      '文件名称长度为 1-20,支持中文、英文、数字、连字符和下划线等,不能含有其他非法字符,请修改后重新上传'
    );
    return {
      name: icon.name,
      tags: icon.name,
      path: icon.d,
      status: iconStatus.UPLOADED,
      uploader: userId
    };
  });

  yield seq.transaction(transaction =>
    Icon.bulkCreate(data, { individualHooks: true, transaction }).then(
      addedIcons => {
        const cacheIcons = [];
        addedIcons.forEach((icon, index) => {
          const { id, name } = icon || {};
          const originalIcons = param.icons;
          if (
            originalIcons &&
            originalIcons[index] &&
            name === originalIcons[index].name
          ) {
            // 将 icon id 和 对应的 svg 插入 cache 表
            const svg =
              (originalIcons[index].buffer &&
                originalIcons[index].buffer.toString()) ||
              null;
            cacheIcons.push({ iconId: id, svg });
          }
        });
        return Cache.bulkCreate(cacheIcons, { transaction });
      }
    )
  );
  // TODO: 看一下上传失败是否会直接抛出异常
  this.state.respond = '图标上传成功';

  yield next;
}