iaaing / RAP文档导出工具

// ==UserScript==
// @name         RAP文档导出工具
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  为轻量化 RAP 而生
// @author       iaaiNG
// @match        *://rap.eoms.phone580.com/workspace/myWorkspace.do*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// @license      MIT
// ==/UserScript==

function parseModuleList(moduleList, space = "") {
  let string = "";
  moduleList.forEach((module) => {
    string += `\n${space}"${module.name}": {`;
    string += parsePageList(module.pageList, space + "    ");
    string += `\n${space}},`;
  });
  return string;
}

function parsePageList(pageList, space = "") {
  let string = "";
  pageList.forEach((pageItem) => {
    string += `\n${space}"${pageItem.name}": {`;
    string += parseActionList(pageItem.actionList, space + "    ");
    string += `\n${space}},`;
  });
  return string;
}

function parseActionList(actionList, space = "") {
  let string = "";
  actionList._apiNameList = []
  actionList.forEach((actionItem) => {
    string += parseActionItem(actionItem, actionList, space + "    ");
  });
  return string;
}

function parseActionItem(actionItem, actionList, space = "") {
  let string = "";
  let apiName = getNameByUrl(actionItem.requestUrl, 2);
  if (actionList._apiNameList.indexOf(apiName) > -1) {
    apiName += actionItem.id;
  }
  actionList._apiNameList.push(apiName); // 储存

  string += `\n${space}/**`;
  string += `\n${space} * ${
        ["GET", "POST"][actionItem.requestType - 1]
} | ${actionItem.name} `;
  string += `\n${space} *`;
  string += `\n${space} * [Request]`;
  string += parseParameterList(actionItem.requestParameterList, space);
  string += `\n${space} *`;
  string += `\n${space} * [Response]`;
  string += parseParameterList(actionItem.responseParameterList, space);
  string += `\n${space} */`;
  string += `\n${space}"${apiName}": "${actionItem.requestUrl}",\n`;
  return string;
}

function parseParameterList(parameterList, space, deepSpace = "") {
  let string = "";

  // 找出最长那个字符串
  const maxLengthIdentifierItem = parameterList.sort(
    (a, b) => b.identifier.length - a.identifier.length
  )[0];
  const maxLengthDataTypeItem = parameterList.sort(
    (a, b) => b.dataType.length - a.dataType.length
  )[0];

  // 字母顺序排序
  parameterList.sort((a, b) => {
    if (a.identifier < b.identifier) {
      return -1;
    }
    if (a.identifier > b.identifier) {
      return 1;
    }
    return 0;
  });
  parameterList.forEach((item) => {
    const identifierSpace = createSpace(
      maxLengthIdentifierItem.identifier.length - item.identifier.length
    );
    const dataTypeSpace = createSpace(
      (maxLengthDataTypeItem.dataType.length - item.dataType.length) * 2
    );
    string += `\n${space} *${deepSpace} ${item.identifier}${identifierSpace} | ${item.dataType}${dataTypeSpace} | ${item.name} | ${item.remark}`;
    if (item.parameterList) {
      string += parseParameterList(
        item.parameterList,
        space,
        deepSpace + "    "
      );
    }
  });
  return string;
}

function createSpace(length) {
  let space = "";
  while (length > 0) {
    length--;
    space += " ";
  }
  return space;
}

function getNameByUrl(api, deep) {
  return api
    .replace(/\/\{\w+\}/, "")
    .split("/")
    .filter((e) => e)
    .filter((e, i, a) => i >= a.length - deep)
    .join("-")
    .replace(/-(\w)/g, (w, $1) => $1.toUpperCase());
}

function exportApi(content) {
  let string = `const apiList = {`;
  string += content;
  string += `\n}`;
  console.log(string)
  navigator.clipboard.writeText(string).then(() => {
    alert('已复制到剪贴板');
    /* Resolved - 文本被成功复制到剪贴板 */
  }, () => {
    alert('复制失败');
    /* Rejected - 文本未被复制到剪贴板 */
  });
  return string
}

(function () {
  'use strict';

  let projectId = location.href.match(/projectId=(\d+)/)
  if (projectId) {
    console.log("projectId: " + projectId[1])
  }
  else {
    console.log("找不到projectId")
  }
  let data = new FormData()
  data.append('projectId', projectId[1])
  let xhr = new XMLHttpRequest();
  // 第二步: 调用open函数
  xhr.open('POST', 'https://rap.eoms.phone580.com/workspace/loadWorkspace.do')
  // 第三步: 设置Content-Type属性 (这一步是固定的写法)
  xhr.setRequestHeader('Conten-Type', 'application/x-www-form-urlencoded')
  // 第四步: 调用send()函数,同时将数据以查询字符串的形式,提交给服务器
  xhr.send(data)
  // 第五步:监听onreadystatechange事件
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      eval('window.ss = ' + xhr.responseText)

      var btn = document.createElement("button")
      btn.innerText = "导出JOSN"
      btn.setAttribute('class', 'btn btn-default btn-sm')
      btn.onclick = function () {
        exportApi(parseModuleList(window.ss.projectData.moduleList))
      }
      document.querySelector("#div-control-panel > div.btn-group").appendChild(btn)

      let container = document.createElement("div")
      container.setAttribute("class", "insert_body")
      container.onclick = function (event) {
        const pageIndex = parseInt(event.target.getAttribute("data-pageIndex"))
        const moduleIndex = parseInt(event.target.getAttribute("data-moduleIndex"))
        const pageList = window.ss.projectData.moduleList[moduleIndex].pageList
        if (pageIndex > -1) {
          exportApi(parseActionList(pageList[pageIndex].actionList))
        }
        else {
          exportApi(parsePageList(pageList))
        }
      }
      document.querySelector('#div-w').insertBefore(container, document.querySelector('#div-m-list'))

      const list = document.querySelector("#div-mt-list")
      list.addEventListener("click", findIdRenderContent)
      findIdRenderContent()

      function findIdRenderContent() {
        const item = list.querySelector('.cur')
        if (item) {
          const id = parseInt(item.id.split('-')[2])
          if (!id) {
            console.log("找不到 module ID")
            return
          }
          let content = ""
          window.ss.projectData.moduleList.forEach((module, moduleIndex) => {
            if (module.id === id) {
              content += `<div style="margin-bottom:10px"><h4 data-moduleIndex="${moduleIndex}" style="cursor: pointer;">${module.name}</h4>`
              module.pageList.forEach((page, pageIndex) => {
                content += `<button class="btn btn-default btn-sm" data-pageIndex="${pageIndex}" data-moduleIndex="${moduleIndex}">${page.name}</button>`
              })
              content += '</div>'
            }
          })
          container.innerHTML = content
        }
      }
    }
  }

})();