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 @@