diff --git a/src/components/scEditor/UploadAdapter.js b/src/components/scEditor/UploadAdapter.js new file mode 100644 index 0000000..f689603 --- /dev/null +++ b/src/components/scEditor/UploadAdapter.js @@ -0,0 +1,144 @@ +export default class UploadAdapter { + constructor(loader, options) { + this.loader = loader; + this.options = options; + this.timeout = 60000; // 60秒超时 + } + + upload() { + return this.loader.file.then( + (file) => + new Promise((resolve, reject) => { + this._initRequest(); + this._initListeners(resolve, reject, file); + this._sendRequest(file); + this._initTimeout(reject); + }), + ); + } + + abort() { + if (this.xhr) { + this.xhr.abort(); + } + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + } + + _initRequest() { + const xhr = (this.xhr = new XMLHttpRequest()); + + xhr.open("POST", this.options.upload.uploadUrl, true); + xhr.responseType = "json"; + } + + _initListeners(resolve, reject, file) { + const xhr = this.xhr; + const loader = this.loader; + const genericErrorText = `Couldn't upload file: ${file.name}.`; + + xhr.addEventListener("error", () => { + console.error("[UploadAdapter] Upload error for file:", file.name); + reject(genericErrorText); + }); + + xhr.addEventListener("abort", () => { + console.warn("[UploadAdapter] Upload aborted for file:", file.name); + reject(); + }); + + xhr.addEventListener("timeout", () => { + console.error("[UploadAdapter] Upload timeout for file:", file.name); + reject(`Upload timeout: ${file.name}. Please try again.`); + }); + + xhr.addEventListener("load", () => { + const response = xhr.response; + + // 检查响应状态码 + if (xhr.status >= 200 && xhr.status < 300) { + if (!response) { + console.error("[UploadAdapter] Empty response for file:", file.name); + reject(genericErrorText); + return; + } + + // 检查业务状态码(假设 code=1 表示成功) + if (response.code == 1 || response.code == undefined) { + const url = response.data?.url || response.data?.src; + if (!url) { + console.error("[UploadAdapter] No URL in response for file:", file.name, response); + reject("Upload succeeded but no URL returned"); + return; + } + resolve({ default: url }); + } else { + const errorMessage = response.message || genericErrorText; + console.error("[UploadAdapter] Upload failed for file:", file.name, "Error:", errorMessage); + reject(errorMessage); + } + } else { + console.error("[UploadAdapter] HTTP error for file:", file.name, "Status:", xhr.status); + reject(`Server error (${xhr.status}): ${file.name}`); + } + }); + + // 上传进度监听 + if (xhr.upload) { + xhr.upload.addEventListener("progress", (evt) => { + if (evt.lengthComputable) { + loader.uploadTotal = evt.total; + loader.uploaded = evt.loaded; + } + }); + } + } + + _initTimeout(reject) { + // 清除之前的超时定时器(如果有) + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + + // 设置新的超时定时器 + this.timeoutId = setTimeout(() => { + if (this.xhr) { + this.xhr.abort(); + reject(new Error("Upload timeout")); + } + }, this.timeout); + } + + _sendRequest(file) { + // 设置请求超时 + this.xhr.timeout = this.timeout; + + // Set headers if specified. + const headers = this.options.upload.headers || {}; + const extendData = this.options.upload.extendData || {}; + // Use the withCredentials flag if specified. + const withCredentials = this.options.upload.withCredentials || false; + const uploadName = this.options.upload.uploadName || "file"; + + for (const headerName of Object.keys(headers)) { + this.xhr.setRequestHeader(headerName, headers[headerName]); + } + + this.xhr.withCredentials = withCredentials; + + const data = new FormData(); + for (const key of Object.keys(extendData)) { + data.append(key, extendData[key]); + } + data.append(uploadName, file); + + this.xhr.send(data); + } +} + +export function UploadAdapterPlugin(editor) { + editor.plugins.get("FileRepository").createUploadAdapter = (loader) => { + return new UploadAdapter(loader, editor.config._config); + }; +} diff --git a/src/components/scEditor/index.vue b/src/components/scEditor/index.vue new file mode 100644 index 0000000..8be1b79 --- /dev/null +++ b/src/components/scEditor/index.vue @@ -0,0 +1,389 @@ + + + + + diff --git a/src/config/index.js b/src/config/index.js index ab4e9b0..66eba26 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -30,6 +30,14 @@ export default { //语言 LANG: 'zh-cn', + DASHBOARD_LAYOUT: 'widgets', //控制台首页默认布局 + DEFAULT_GRID: { + //默认分栏数量和宽度 例如 [24] [18,6] [8,8,8] [6,12,6] + layout: [24, 12, 12], + //小组件分布,com取值:pages/home/components 文件名 + compsList: [["welcome"], ["info"], ["ver"]], + }, + //是否加密localStorage, 为空不加密 //支持多种加密方式: 'AES', 'BASE64', 'DES' LS_ENCRYPTION: '', diff --git a/src/pages/home/index.vue b/src/pages/home/index.vue index c07343a..e3dd744 100644 --- a/src/pages/home/index.vue +++ b/src/pages/home/index.vue @@ -6,8 +6,8 @@