import { useState } from "react"; import styles from "../styles/Builder.module.css"; interface IMap { [key: string]: boolean; } const pluginList = ["Sort", "Filter", "Comment", "Alternating Colors"]; // TODO 选项匹配插件名称 // TODO 代码包含一个完整的运行案例,直接运行,或者npm i 后运行,README.md引导 // TODO 下载代码压缩文件 // TODO 下载完成之后,服务器新复制的项目清除掉 // TODO 测试并发能力 function Builder() { const pluginMap: IMap = {}; const [msgList, setMsgList] = useState([]); const [progressValue, setProgressValue] = useState(0); const [buildId, setBuildId] = useState(""); // const const check = (e: React.ChangeEvent) => { pluginMap[e.target.value] = e.target.checked; }; const build = () => { const buildList = []; for (const plugin in pluginMap) { if (pluginMap[plugin] === true) { buildList.push(plugin); } } postData("/api/build", { buildList }).then((data) => { setBuildId(data.buildId); startBuild(data.buildId); }); }; const download = () => { fetch("/api/download?buildId=" + buildId, { method: "GET", // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, *cors, same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, *same-origin, omit headers: { "Content-Type": "application/octet-stream", // 'Content-Type': 'application/x-www-form-urlencoded', }, redirect: "follow", // manual, *follow, error referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url }).then ((res) => res.blob()).then((blob)=>{ downloadFile(blob,'luckysheet-custom-build.zip') }) }; /** * reference: https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch * @param url * @param data * @returns */ async function postData(url = "", data = {}) { // Default options are marked with * const response = await fetch(url, { method: "POST", // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, *cors, same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, *same-origin, omit headers: { "Content-Type": "application/json", // 'Content-Type': 'application/x-www-form-urlencoded', }, redirect: "follow", // manual, *follow, error referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url body: JSON.stringify(data), // body data type must match "Content-Type" header }); return response.json(); // parses JSON response into native JavaScript objects } async function getFile(url = "") { // Default options are marked with * const response = await fetch(url, { method: "GET", // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, *cors, same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, *same-origin, omit headers: { "Content-Type": "application/octet-stream", // 'Content-Type': 'application/x-www-form-urlencoded', }, redirect: "follow", // manual, *follow, error referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url }); return response; // parses JSON response into native JavaScript objects } function startBuild(buildId: string) { // when "Start" button pressed if (!window.EventSource) { // IE or an old browser alert("The browser doesn't support EventSource."); return; } const eventSource = new EventSource("/api/progress?buildId=" + buildId); let retryCount = 0; eventSource.onopen = function (e) { console.log("Event: open"); }; eventSource.onerror = function (this: EventSource) { console.log(`Event: readyState=${this.readyState})`); if (this.readyState == EventSource.CLOSED) { console.log("Event: Connection was closed."); } else if (this.readyState == EventSource.CONNECTING) { eventSource.close(); console.log("Event: Connection was closed."); // if (++retryCount === 5) { // eventSource.close(); // } } else { console.log("Event: Error has occured."); } }; eventSource.addEventListener("progress", function (e) { const dataList = e.data.split("-"); const msg = dataList[0]; const progress = dataList[1]; setMsgList((msgList) => [...msgList, msg]); setProgressValue(progress * 100); if (msg === "Success" || msg === "Fail") { eventSource.close(); } }); } /** * 下载文件 * @param content 文件流 * @param fileName 文件名称 */ function downloadFile(blob: any, fileName: string) { // const blob = new Blob([content], { // type: 'application/octet-stream' // }); const a = document.createElement("a"); const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox a.click(); window.URL.revokeObjectURL(url); a.remove(); //afterwards we remove the element again } return (

Luckysheet Custom Builder

Choose plugins

{pluginList.map((plugin) => { return (

); })}
{progressValue === 0 ? ( "" ) : (
{progressValue}%
)}

Build Log

    {msgList.map((msg, i) => (
  • {msg}
  • ))}
{/* */} {progressValue === 100 ? ( ) : ( "" )}
); } export default Builder;