diff --git a/web/build/icons/1024x1024.png b/web/build/icons/1024x1024.png
new file mode 100644
index 00000000..9fc1c628
Binary files /dev/null and b/web/build/icons/1024x1024.png differ
diff --git a/web/build/icons/128x128.png b/web/build/icons/128x128.png
new file mode 100644
index 00000000..af6310e6
Binary files /dev/null and b/web/build/icons/128x128.png differ
diff --git a/web/build/icons/16x16.png b/web/build/icons/16x16.png
new file mode 100644
index 00000000..25e80fee
Binary files /dev/null and b/web/build/icons/16x16.png differ
diff --git a/web/build/icons/24x24.png b/web/build/icons/24x24.png
new file mode 100644
index 00000000..d8e4715d
Binary files /dev/null and b/web/build/icons/24x24.png differ
diff --git a/web/build/icons/256x256.png b/web/build/icons/256x256.png
new file mode 100644
index 00000000..c511962f
Binary files /dev/null and b/web/build/icons/256x256.png differ
diff --git a/web/build/icons/32x32.png b/web/build/icons/32x32.png
new file mode 100644
index 00000000..d70242bf
Binary files /dev/null and b/web/build/icons/32x32.png differ
diff --git a/web/build/icons/48x48.png b/web/build/icons/48x48.png
new file mode 100644
index 00000000..74fda199
Binary files /dev/null and b/web/build/icons/48x48.png differ
diff --git a/web/build/icons/512x512.png b/web/build/icons/512x512.png
new file mode 100644
index 00000000..c5cda241
Binary files /dev/null and b/web/build/icons/512x512.png differ
diff --git a/web/build/icons/64x64.png b/web/build/icons/64x64.png
new file mode 100644
index 00000000..5eee4182
Binary files /dev/null and b/web/build/icons/64x64.png differ
diff --git a/web/build/icons/icon.icns b/web/build/icons/icon.icns
new file mode 100644
index 00000000..9c2b3f34
Binary files /dev/null and b/web/build/icons/icon.icns differ
diff --git a/web/build/icons/icon.ico b/web/build/icons/icon.ico
new file mode 100644
index 00000000..c3daede2
Binary files /dev/null and b/web/build/icons/icon.ico differ
diff --git a/web/build/icons/icon.png b/web/build/icons/icon.png
new file mode 100644
index 00000000..23f64d25
Binary files /dev/null and b/web/build/icons/icon.png differ
diff --git a/web/build/icons/menu@88.png b/web/build/icons/menu@88.png
new file mode 100644
index 00000000..cc14a82d
Binary files /dev/null and b/web/build/icons/menu@88.png differ
diff --git a/web/dist_electron/index.js b/web/dist_electron/index.js
index dc14860d..bb282267 100644
--- a/web/dist_electron/index.js
+++ b/web/dist_electron/index.js
@@ -1804,7 +1804,7 @@ eval("/*\n Yaku v0.16.7\n (c) 2015 Yad Smood. http://ysmood.org\n License MIT\n*
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron */ \"electron\");\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue_cli_plugin_electron_builder_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue-cli-plugin-electron-builder/lib */ \"./node_modules/vue-cli-plugin-electron-builder/lib/index.js\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! path */ \"path\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _electron_fileHandle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./electron/fileHandle */ \"./src/electron/fileHandle.js\");\n/* harmony import */ var _electron_otherHandle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./electron/otherHandle */ \"./src/electron/otherHandle.js\");\n\n\n\n\n\n\n\n\nconst isDevelopment = \"development\" !== 'production'\n\n// Scheme must be registered before the app is ready\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"protocol\"].registerSchemesAsPrivileged([\n { scheme: 'app', privileges: { secure: true, standard: true } }\n])\n\n// 创建主页面\nlet mainWindow = null\nasync function createMainWindow() {\n mainWindow = new electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"]({\n width: 1200,\n height: 800,\n frame: false,\n titleBarStyle: 'hiddenInset',\n webPreferences: {\n webSecurity: false,\n nodeIntegration: true,\n enableRemoteModule: true,\n contextIsolation: true,\n preload: path__WEBPACK_IMPORTED_MODULE_2___default.a.join(__dirname, 'preload.js')\n }\n })\n\n if (true) {\n // Load the url of the dev server if in development mode\n await mainWindow.loadURL(\"http://localhost:8082\" + '/#/workbenche')\n // if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()\n } else {}\n}\n\n// 绑定事件\nconst bindEvent = () => {\n Object(_electron_fileHandle__WEBPACK_IMPORTED_MODULE_3__[\"bindFileHandleEvent\"])({ mainWindow })\n Object(_electron_otherHandle__WEBPACK_IMPORTED_MODULE_4__[\"bindOtherHandleEvent\"])()\n}\n\n// 关闭所有窗口后退出\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].on('window-all-closed', () => {\n // On macOS it is common for applications and their menu bar\n // to stay active until the user quits explicitly with Cmd + Q\n if (process.platform !== 'darwin') {\n electron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].quit()\n }\n})\n\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].on('activate', () => {\n // On macOS it's common to re-create a window in the app when the\n // dock icon is clicked and there are no other windows open.\n if (electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"].getAllWindows().length === 0) {\n createMainWindow()\n bindEvent()\n }\n})\n\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].on('ready', async () => {\n createMainWindow()\n bindEvent()\n})\n\n// Exit cleanly on request from parent process in development mode.\nif (isDevelopment) {\n if (process.platform === 'win32') {\n process.on('message', data => {\n if (data === 'graceful-exit') {\n electron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].quit()\n }\n })\n } else {\n process.on('SIGTERM', () => {\n electron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].quit()\n })\n }\n}\n\n\n//# sourceURL=webpack:///./src/background.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron */ \"electron\");\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue_cli_plugin_electron_builder_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue-cli-plugin-electron-builder/lib */ \"./node_modules/vue-cli-plugin-electron-builder/lib/index.js\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! path */ \"path\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _electron_fileHandle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./electron/fileHandle */ \"./src/electron/fileHandle.js\");\n/* harmony import */ var _electron_otherHandle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./electron/otherHandle */ \"./src/electron/otherHandle.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst isDevelopment = \"development\" !== 'production'\r\n\r\n// 在应用程序准备就绪之前,必须注册方案\r\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"protocol\"].registerSchemesAsPrivileged([\r\n { scheme: 'app', privileges: { secure: true, standard: true } }\r\n])\r\n\r\n// 创建主页面\r\nlet mainWindow = null\r\nasync function createMainWindow() {\r\n mainWindow = new electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"]({\r\n width: 1200,\r\n height: 800,\r\n frame: false,\r\n titleBarStyle: 'hiddenInset',\r\n webPreferences: {\r\n webSecurity: false,\r\n nodeIntegration: true,\r\n enableRemoteModule: true,\r\n contextIsolation: true,\r\n preload: path__WEBPACK_IMPORTED_MODULE_2___default.a.join(__dirname, 'preload.js')\r\n }\r\n })\r\n\r\n if (true) {\r\n // 如果处于开发模式,则加载开发服务器的url\r\n await mainWindow.loadURL(\r\n \"http://localhost:8080\" + '/#/workbenche'\r\n )\r\n if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()\r\n } else {}\r\n}\r\n\r\n// 绑定事件\r\nconst bindEvent = () => {\r\n Object(_electron_fileHandle__WEBPACK_IMPORTED_MODULE_3__[\"bindFileHandleEvent\"])({ mainWindow })\r\n Object(_electron_otherHandle__WEBPACK_IMPORTED_MODULE_4__[\"bindOtherHandleEvent\"])()\r\n}\r\n\r\n// 关闭所有窗口后退出\r\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].on('window-all-closed', () => {\r\n // 在macOS上,应用程序及其菜单栏通常保持活动状态,直到用户使用Cmd+Q明确退出\r\n if (process.platform !== 'darwin') {\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].quit()\r\n }\r\n})\r\n\r\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].on('activate', () => {\r\n // 在macOS上,当点击dock图标且没有其他窗口打开时,通常会在应用程序中重新创建一个窗口。\r\n if (electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"].getAllWindows().length === 0) {\r\n createMainWindow()\r\n // bindEvent()\r\n }\r\n})\r\n\r\nelectron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].on('ready', async () => {\r\n createMainWindow()\r\n bindEvent()\r\n})\r\n\r\n// 在开发模式下,应父进程的请求干净地退出。\r\nif (isDevelopment) {\r\n if (process.platform === 'win32') {\r\n process.on('message', data => {\r\n if (data === 'graceful-exit') {\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].quit()\r\n }\r\n })\r\n } else {\r\n process.on('SIGTERM', () => {\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"app\"].quit()\r\n })\r\n }\r\n}\r\n\n\n//# sourceURL=webpack:///./src/background.js?");
/***/ }),
@@ -1816,7 +1816,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var elec
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"bindFileHandleEvent\", function() { return bindFileHandleEvent; });\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron */ \"electron\");\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var fs_extra__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs-extra */ \"./node_modules/fs-extra/lib/index.js\");\n/* harmony import */ var fs_extra__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs_extra__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! path */ \"path\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./storage */ \"./src/electron/storage.js\");\n/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid */ \"./node_modules/uuid/index.js\");\n/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\n\nconst bindFileHandleEvent = ({ mainWindow }) => {\n // 通知主页面刷新最近文件列表\n const notifyMainWindowRefreshRecentFileList = () => {\n mainWindow.webContents.send('refreshRecentFileList')\n }\n\n // 新建编辑页面\n const openIds = []\n const createEditWindow = async (event, id) => {\n openIds.push(id)\n const win = new electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"]({\n width: 1200,\n height: 800,\n frame: false,\n titleBarStyle: 'hiddenInset',\n webPreferences: {\n webSecurity: false,\n nodeIntegration: true,\n enableRemoteModule: true,\n contextIsolation: true,\n preload: path__WEBPACK_IMPORTED_MODULE_2___default.a.join(__dirname, 'preload.js')\n }\n })\n win.on('closed', () => {\n let index = openIds.find(item => {\n return item === id\n })\n if (index !== -1) {\n openIds.splice(index, 1)\n }\n })\n if (true) {\n // Load the url of the dev server if in development mode\n win.loadURL(\n \"http://localhost:8082\" + '/#/workbenche/edit/' + id\n )\n if (!process.env.IS_TEST) win.webContents.openDevTools()\n } else {}\n }\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('create', createEditWindow)\n\n // 保存文件\n const idToFilePath = {}\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('save', async (event, id, data) => {\n if (!idToFilePath[id]) {\n const webContents = event.sender\n const win = electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"].fromWebContents(webContents)\n const res = electron__WEBPACK_IMPORTED_MODULE_0__[\"dialog\"].showSaveDialogSync(win, {\n title: '保存',\n defaultPath: '未命名.smm',\n filters: [{ name: '思维导图', extensions: ['smm'] }]\n })\n if (res) {\n idToFilePath[id] = res\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.writeFile(res, data)\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"saveToRecent\"])(res)\n .then(() => {\n notifyMainWindowRefreshRecentFileList()\n })\n return path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(idToFilePath[id]).name\n }\n } else {\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.writeFile(idToFilePath[id], data)\n }\n })\n\n // 打开文件\n const openFile = (event, file) => {\n let id = Object(uuid__WEBPACK_IMPORTED_MODULE_4__[\"v4\"])()\n idToFilePath[id] = file\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"saveToRecent\"])(file)\n .then(() => {\n notifyMainWindowRefreshRecentFileList()\n })\n createEditWindow(null, id)\n }\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('openFile', openFile)\n\n // 选择打开本地文件\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('selectOpenFile', (event) => {\n const res = electron__WEBPACK_IMPORTED_MODULE_0__[\"dialog\"].showOpenDialogSync({\n title: '选择',\n filters: [{ name: '思维导图', extensions: ['smm'] }],\n })\n if (res && res[0]) {\n openFile(null, res[0])\n }\n })\n\n // 获取文件内容\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('getFileContent', (event, id) => {\n return new Promise((resolve) => {\n let file = idToFilePath[id]\n if (!file) {\n resolve(null)\n return\n }\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.readFile(file, { encoding: 'utf-8' }, (err, data) => {\n resolve({\n name: path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(file).name,\n content: JSON.parse(data)\n })\n })\n })\n })\n\n // 重命名文件\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('rename', (event, id, name) => {\n return new Promise((resolve) => {\n if (!idToFilePath[id]) {\n resolve('文件不存在')\n return\n }\n let oldPath = idToFilePath[id]\n let { base, ...oldPathData } = path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(oldPath)\n oldPathData.name = name\n let newPath = path__WEBPACK_IMPORTED_MODULE_2___default.a.format(oldPathData)\n idToFilePath[id] = newPath\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.rename(oldPath, newPath, (err) => {\n if (err) {\n resolve('重命名失败')\n } else {\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"replaceFileInRecent\"])(oldPath, newPath).then(() => {\n notifyMainWindowRefreshRecentFileList()\n resolve()\n })\n }\n })\n })\n })\n\n // 获取最近文件列表\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('getRecentFileList', () => {\n return Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"getRecent\"])().map(item => {\n console.log(item);\n let data = path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(item)\n return {\n url: item,\n dir: data.dir,\n name: data.name\n }\n })\n })\n\n // 清空最近文件列表\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('clearRecentFileList', async () => {\n try {\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"clearRecent\"])()\n return ''\n } catch (error) {\n return '清空失败'\n }\n })\n\n // 打开指定目录\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('openFileInDir', (event, file) => {\n electron__WEBPACK_IMPORTED_MODULE_0__[\"shell\"].showItemInFolder(file)\n })\n\n // 删除指定文件\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('deleteFile', (event, file) => {\n let res = ''\n let id = Object.keys(idToFilePath).find(item => {\n return idToFilePath[item] === file\n })\n let index = -1\n if (id) {\n index = openIds.findIndex(item => {\n return item === id\n })\n }\n if (index === -1) {\n res = fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.rmSync(file)\n if (!res) {\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"removeFileInRecent\"])(file)\n }\n } else {\n res = '该文件正在编辑,请关闭后再试'\n }\n return res\n })\n}\n\n//# sourceURL=webpack:///./src/electron/fileHandle.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"bindFileHandleEvent\", function() { return bindFileHandleEvent; });\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron */ \"electron\");\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var fs_extra__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs-extra */ \"./node_modules/fs-extra/lib/index.js\");\n/* harmony import */ var fs_extra__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs_extra__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! path */ \"path\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./storage */ \"./src/electron/storage.js\");\n/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid */ \"./node_modules/uuid/index.js\");\n/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_4__);\n\r\n\r\n\r\n\r\n\r\n\r\nconst bindFileHandleEvent = ({ mainWindow }) => {\r\n // 通知主页面刷新最近文件列表\r\n const notifyMainWindowRefreshRecentFileList = () => {\r\n mainWindow.webContents.send('refreshRecentFileList')\r\n }\r\n\r\n // 新建编辑页面\r\n const openIds = []\r\n const createEditWindow = async (event, id) => {\r\n openIds.push(id)\r\n const win = new electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"]({\r\n width: 1200,\r\n height: 800,\r\n frame: false,\r\n titleBarStyle: 'hiddenInset',\r\n webPreferences: {\r\n webSecurity: false,\r\n nodeIntegration: true,\r\n enableRemoteModule: true,\r\n contextIsolation: true,\r\n preload: path__WEBPACK_IMPORTED_MODULE_2___default.a.join(__dirname, 'preload.js')\r\n }\r\n })\r\n win.on('closed', () => {\r\n // 从openIds数组中删除\r\n let index = openIds.find(item => {\r\n return item === id\r\n })\r\n if (index !== -1) {\r\n openIds.splice(index, 1)\r\n }\r\n // 从idToFilePath中删除\r\n delete idToFilePath[id]\r\n })\r\n if (true) {\r\n // Load the url of the dev server if in development mode\r\n win.loadURL(\r\n \"http://localhost:8080\" + '/#/workbenche/edit/' + id\r\n )\r\n if (!process.env.IS_TEST) win.webContents.openDevTools()\r\n } else {}\r\n }\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('create', createEditWindow)\r\n\r\n // 保存文件\r\n const idToFilePath = {}\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('save', async (event, id, data, fileName = '未命名') => {\r\n if (!idToFilePath[id]) {\r\n const webContents = event.sender\r\n const win = electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"].fromWebContents(webContents)\r\n const res = electron__WEBPACK_IMPORTED_MODULE_0__[\"dialog\"].showSaveDialogSync(win, {\r\n title: '保存',\r\n defaultPath: fileName + '.smm',\r\n filters: [{ name: '思维导图', extensions: ['smm'] }]\r\n })\r\n if (res) {\r\n idToFilePath[id] = res\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.writeFile(res, data)\r\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"saveToRecent\"])(res).then(() => {\r\n notifyMainWindowRefreshRecentFileList()\r\n })\r\n return path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(idToFilePath[id]).name\r\n }\r\n } else {\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.writeFile(idToFilePath[id], data)\r\n }\r\n })\r\n\r\n // 打开文件\r\n const openFile = (event, file) => {\r\n let id = Object(uuid__WEBPACK_IMPORTED_MODULE_4__[\"v4\"])()\r\n idToFilePath[id] = file\r\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"saveToRecent\"])(file).then(() => {\r\n notifyMainWindowRefreshRecentFileList()\r\n })\r\n createEditWindow(null, id)\r\n }\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('openFile', openFile)\r\n\r\n // 选择打开本地文件\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('selectOpenFile', event => {\r\n const res = electron__WEBPACK_IMPORTED_MODULE_0__[\"dialog\"].showOpenDialogSync({\r\n title: '选择',\r\n filters: [{ name: '思维导图', extensions: ['smm'] }]\r\n })\r\n if (res && res[0]) {\r\n openFile(null, res[0])\r\n }\r\n })\r\n\r\n // 获取文件内容\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('getFileContent', (event, id) => {\r\n return new Promise(resolve => {\r\n let file = idToFilePath[id]\r\n if (!file) {\r\n resolve(null)\r\n return\r\n }\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.readFile(file, { encoding: 'utf-8' }, (err, data) => {\r\n resolve({\r\n name: path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(file).name,\r\n content: JSON.parse(data)\r\n })\r\n })\r\n })\r\n })\r\n\r\n // 重命名文件\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('rename', (event, id, name) => {\r\n return new Promise(resolve => {\r\n if (!idToFilePath[id]) {\r\n resolve('文件不存在')\r\n return\r\n }\r\n let oldPath = idToFilePath[id]\r\n let { base, ...oldPathData } = path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(oldPath)\r\n oldPathData.name = name\r\n let newPath = path__WEBPACK_IMPORTED_MODULE_2___default.a.format(oldPathData)\r\n idToFilePath[id] = newPath\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.rename(oldPath, newPath, err => {\r\n if (err) {\r\n resolve('重命名失败')\r\n } else {\r\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"replaceFileInRecent\"])(oldPath, newPath).then(() => {\r\n notifyMainWindowRefreshRecentFileList()\r\n resolve()\r\n })\r\n }\r\n })\r\n })\r\n })\r\n\r\n // 获取最近文件列表\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('getRecentFileList', () => {\r\n return Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"getRecent\"])().map(item => {\r\n let data = path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(item)\r\n return {\r\n url: item,\r\n dir: data.dir,\r\n name: data.name\r\n }\r\n })\r\n })\r\n\r\n // 清空最近文件列表\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('clearRecentFileList', async () => {\r\n try {\r\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"clearRecent\"])()\r\n return ''\r\n } catch (error) {\r\n return '清空失败'\r\n }\r\n })\r\n\r\n // 添加到最近文件列表\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('addRecentFileList', async (event, fileList) => {\r\n try {\r\n console.log(fileList);\r\n await Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"saveFileListToRecent\"])(fileList)\r\n notifyMainWindowRefreshRecentFileList()\r\n } catch (error) {\r\n return error\r\n } \r\n })\r\n\r\n // 打开指定目录\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('openFileInDir', (event, file) => {\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"shell\"].showItemInFolder(file)\r\n })\r\n\r\n // 删除指定文件\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('deleteFile', (event, file) => {\r\n let res = ''\r\n let id = Object.keys(idToFilePath).find(item => {\r\n return idToFilePath[item] === file\r\n })\r\n let index = -1\r\n if (id) {\r\n index = openIds.findIndex(item => {\r\n return item === id\r\n })\r\n }\r\n if (index === -1) {\r\n try {\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.rmSync(file)\r\n } catch (error) {}\r\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"removeFileInRecent\"])(file)\r\n } else {\r\n res = '该文件正在编辑,请关闭后再试'\r\n }\r\n return res\r\n })\r\n\r\n // 复制文件\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].handle('copyFile', async (event, file) => {\r\n return new Promise((resolve, reject) => {\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.pathExists(file, (err, exists) => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n if (exists) {\r\n let { base, ...oldPathData } = path__WEBPACK_IMPORTED_MODULE_2___default.a.parse(file)\r\n let newName = oldPathData.name + '-复制'\r\n let index = 1\r\n oldPathData.name = newName\r\n let newPath = path__WEBPACK_IMPORTED_MODULE_2___default.a.format(oldPathData)\r\n // 检查新路径是否已存在\r\n while (fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.pathExistsSync(newPath)) {\r\n oldPathData.name = newName + index\r\n newPath = path__WEBPACK_IMPORTED_MODULE_2___default.a.format(oldPathData)\r\n index++\r\n }\r\n fs_extra__WEBPACK_IMPORTED_MODULE_1___default.a.copy(file, newPath, err => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n Object(_storage__WEBPACK_IMPORTED_MODULE_3__[\"saveToRecent\"])(newPath).then(() => {\r\n notifyMainWindowRefreshRecentFileList()\r\n })\r\n resolve()\r\n }\r\n })\r\n } else {\r\n reject('文件不存在')\r\n }\r\n }\r\n })\r\n })\r\n })\r\n}\r\n\n\n//# sourceURL=webpack:///./src/electron/fileHandle.js?");
/***/ }),
@@ -1828,7 +1828,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"bindOtherHandleEvent\", function() { return bindOtherHandleEvent; });\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron */ \"electron\");\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var open__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! open */ \"open\");\n/* harmony import */ var open__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(open__WEBPACK_IMPORTED_MODULE_1__);\n\n\n\nconst bindOtherHandleEvent = () => {\n // 处理缩放事件\n ;['minimize', 'maximize', 'unmaximize', 'close'].forEach(item => {\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on(item, event => {\n const webContents = event.sender\n const win = electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"].fromWebContents(webContents)\n win[item]()\n })\n })\n\n // 使用默认浏览器打开指定url\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('openUrl', (event, url) => {\n open__WEBPACK_IMPORTED_MODULE_1___default()(url)\n })\n}\n\n//# sourceURL=webpack:///./src/electron/otherHandle.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"bindOtherHandleEvent\", function() { return bindOtherHandleEvent; });\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron */ \"electron\");\n/* harmony import */ var electron__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var open__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! open */ \"open\");\n/* harmony import */ var open__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(open__WEBPACK_IMPORTED_MODULE_1__);\n\r\n\r\n\r\nconst bindOtherHandleEvent = () => {\r\n // 处理缩放事件\r\n ;['minimize', 'maximize', 'unmaximize', 'close', 'destroy'].forEach(item => {\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on(item, event => {\r\n const webContents = event.sender\r\n const win = electron__WEBPACK_IMPORTED_MODULE_0__[\"BrowserWindow\"].fromWebContents(webContents)\r\n win[item]()\r\n })\r\n })\r\n\r\n // 使用默认浏览器打开指定url\r\n electron__WEBPACK_IMPORTED_MODULE_0__[\"ipcMain\"].on('openUrl', (event, url) => {\r\n open__WEBPACK_IMPORTED_MODULE_1___default()(url)\r\n })\r\n}\r\n\n\n//# sourceURL=webpack:///./src/electron/otherHandle.js?");
/***/ }),
@@ -1836,11 +1836,11 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/*!*********************************!*\
!*** ./src/electron/storage.js ***!
\*********************************/
-/*! exports provided: RECENT_FILE_LIST, saveToRecent, getRecent, clearRecent, removeFileInRecent, replaceFileInRecent */
+/*! exports provided: RECENT_FILE_LIST, saveToRecent, saveFileListToRecent, getRecent, clearRecent, removeFileInRecent, replaceFileInRecent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"RECENT_FILE_LIST\", function() { return RECENT_FILE_LIST; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"saveToRecent\", function() { return saveToRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getRecent\", function() { return getRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"clearRecent\", function() { return clearRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"removeFileInRecent\", function() { return removeFileInRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"replaceFileInRecent\", function() { return replaceFileInRecent; });\n/* harmony import */ var electron_json_storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron-json-storage */ \"./node_modules/electron-json-storage/lib/storage.js\");\n/* harmony import */ var electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron_json_storage__WEBPACK_IMPORTED_MODULE_0__);\n\n\nconst RECENT_FILE_LIST = 'recentFileList'\n\n// 保存到最近文件\nconst saveToRecent = file => {\n return new Promise((resolve, reject) => {\n let list = getRecent()\n let index = list.findIndex(item => {\n return item === file\n })\n if (index !== -1) {\n list.splice(index, 1)\n }\n list.push(file)\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, (err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n}\n\n// 获取最近文件列表\nconst getRecent = () => {\n let res = electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.getSync(RECENT_FILE_LIST)\n return (Array.isArray(res) ? res : []).filter((item) => {\n return !!item\n })\n}\n\n// 清除最近文件列表\nconst clearRecent = () => {\n return new Promise((resolve, reject) => {\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.remove(RECENT_FILE_LIST, (err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n}\n\n// 从最近文件列表中移除指定文件\nconst removeFileInRecent = (file) => {\n return new Promise((resolve, reject) => {\n let list = getRecent()\n let index = list.findIndex(item => {\n return item === file\n })\n if (index !== -1) {\n list.splice(index, 1)\n }\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, (err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n}\n\n// 替换指定文件\nconst replaceFileInRecent = (oldFile, newFile) => {\n return new Promise((resolve, reject) => {\n let list = getRecent()\n let index = list.findIndex(item => {\n return item === oldFile\n })\n if (index !== -1) {\n list.splice(index, 1)\n }\n list.push(newFile)\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, (err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n}\n\n//# sourceURL=webpack:///./src/electron/storage.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"RECENT_FILE_LIST\", function() { return RECENT_FILE_LIST; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"saveToRecent\", function() { return saveToRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"saveFileListToRecent\", function() { return saveFileListToRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getRecent\", function() { return getRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"clearRecent\", function() { return clearRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"removeFileInRecent\", function() { return removeFileInRecent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"replaceFileInRecent\", function() { return replaceFileInRecent; });\n/* harmony import */ var electron_json_storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! electron-json-storage */ \"./node_modules/electron-json-storage/lib/storage.js\");\n/* harmony import */ var electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(electron_json_storage__WEBPACK_IMPORTED_MODULE_0__);\n\r\n\r\nconst RECENT_FILE_LIST = 'recentFileList'\r\n\r\n// 保存到最近文件\r\nconst saveToRecent = file => {\r\n return new Promise((resolve, reject) => {\r\n let list = getRecent()\r\n let index = list.findIndex(item => {\r\n return item === file\r\n })\r\n if (index !== -1) {\r\n list.splice(index, 1)\r\n }\r\n list.push(file)\r\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, err => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n })\r\n })\r\n}\r\n\r\n// 保存到最近文件\r\nconst saveFileListToRecent = fileList => {\r\n return new Promise((resolve, reject) => {\r\n let list = getRecent()\r\n fileList.forEach(file => {\r\n let index = list.findIndex(item => {\r\n return item === file\r\n })\r\n if (index !== -1) {\r\n list.splice(index, 1)\r\n }\r\n list.push(file)\r\n })\r\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, err => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n })\r\n })\r\n}\r\n\r\n// 获取最近文件列表\r\nconst getRecent = () => {\r\n let res = electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.getSync(RECENT_FILE_LIST)\r\n return (Array.isArray(res) ? res : []).filter(item => {\r\n return !!item\r\n })\r\n}\r\n\r\n// 清除最近文件列表\r\nconst clearRecent = () => {\r\n return new Promise((resolve, reject) => {\r\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.remove(RECENT_FILE_LIST, err => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n })\r\n })\r\n}\r\n\r\n// 从最近文件列表中移除指定文件\r\nconst removeFileInRecent = file => {\r\n return new Promise((resolve, reject) => {\r\n let list = getRecent()\r\n let index = list.findIndex(item => {\r\n return item === file\r\n })\r\n if (index !== -1) {\r\n list.splice(index, 1)\r\n }\r\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, err => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n })\r\n })\r\n}\r\n\r\n// 替换指定文件\r\nconst replaceFileInRecent = (oldFile, newFile) => {\r\n return new Promise((resolve, reject) => {\r\n let list = getRecent()\r\n let index = list.findIndex(item => {\r\n return item === oldFile\r\n })\r\n if (index !== -1) {\r\n list.splice(index, 1)\r\n }\r\n list.push(newFile)\r\n electron_json_storage__WEBPACK_IMPORTED_MODULE_0___default.a.set(RECENT_FILE_LIST, list, err => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n })\r\n })\r\n}\r\n\n\n//# sourceURL=webpack:///./src/electron/storage.js?");
/***/ }),
@@ -1851,7 +1851,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
-eval("module.exports = __webpack_require__(/*! /Users/lisa/wanglin/github/mind-map/web/src/background.js */\"./src/background.js\");\n\n\n//# sourceURL=webpack:///multi_./src/background.js?");
+eval("module.exports = __webpack_require__(/*! E:\\wanglin\\mind-map\\web\\src\\background.js */\"./src/background.js\");\n\n\n//# sourceURL=webpack:///multi_./src/background.js?");
/***/ }),
diff --git a/web/dist_electron/preload.js b/web/dist_electron/preload.js
index 53575a6b..c9ceb365 100644
--- a/web/dist_electron/preload.js
+++ b/web/dist_electron/preload.js
@@ -93,7 +93,7 @@
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
-eval("const { contextBridge, ipcRenderer } = __webpack_require__(/*! electron */ \"electron\")\n\ncontextBridge.exposeInMainWorld('platform', process.platform)\ncontextBridge.exposeInMainWorld('IS_ELECTRON', true)\n\ncontextBridge.exposeInMainWorld('electronAPI', {\n minimize: () => ipcRenderer.send('minimize'),\n maximize: () => ipcRenderer.send('maximize'),\n unmaximize: () => ipcRenderer.send('unmaximize'),\n close: () => ipcRenderer.send('close'),\n create: (id) => ipcRenderer.send('create', id),\n getFileContent: (id) => ipcRenderer.invoke('getFileContent', id),\n save: (id, data) => ipcRenderer.invoke('save', id, data),\n rename: (id, name) => ipcRenderer.invoke('rename', id, name),\n openUrl: (url) => ipcRenderer.send('openUrl', url),\n getRecentFileList: () => ipcRenderer.invoke('getRecentFileList'),\n clearRecentFileList: () => ipcRenderer.invoke('clearRecentFileList'),\n openFileInDir: (file) => ipcRenderer.send('openFileInDir', file),\n deleteFile: (file) => ipcRenderer.invoke('deleteFile', file),\n onRefreshRecentFileList: (callback) => ipcRenderer.on('refreshRecentFileList', callback),\n openFile: (file) => ipcRenderer.send('openFile', file),\n selectOpenFile: () => ipcRenderer.send('selectOpenFile'),\n})\n\n//# sourceURL=webpack:///./src/electron/preload.js?");
+eval("const { contextBridge, ipcRenderer } = __webpack_require__(/*! electron */ \"electron\")\r\n\r\ncontextBridge.exposeInMainWorld('platform', process.platform)\r\ncontextBridge.exposeInMainWorld('IS_ELECTRON', true)\r\n\r\ncontextBridge.exposeInMainWorld('electronAPI', {\r\n minimize: () => ipcRenderer.send('minimize'),\r\n maximize: () => ipcRenderer.send('maximize'),\r\n unmaximize: () => ipcRenderer.send('unmaximize'),\r\n close: () => ipcRenderer.send('close'),\r\n destroy: () => ipcRenderer.send('destroy'),\r\n create: id => ipcRenderer.send('create', id),\r\n getFileContent: id => ipcRenderer.invoke('getFileContent', id),\r\n save: (id, data, fileName) => ipcRenderer.invoke('save', id, data, fileName),\r\n rename: (id, name) => ipcRenderer.invoke('rename', id, name),\r\n openUrl: url => ipcRenderer.send('openUrl', url),\r\n addRecentFileList: (fileList) => ipcRenderer.invoke('addRecentFileList', fileList),\r\n getRecentFileList: () => ipcRenderer.invoke('getRecentFileList'),\r\n clearRecentFileList: () => ipcRenderer.invoke('clearRecentFileList'),\r\n openFileInDir: file => ipcRenderer.send('openFileInDir', file),\r\n deleteFile: file => ipcRenderer.invoke('deleteFile', file),\r\n onRefreshRecentFileList: callback =>\r\n ipcRenderer.on('refreshRecentFileList', callback),\r\n openFile: file => ipcRenderer.send('openFile', file),\r\n selectOpenFile: () => ipcRenderer.send('selectOpenFile'),\r\n copyFile: file => ipcRenderer.invoke('copyFile', file)\r\n})\r\n\n\n//# sourceURL=webpack:///./src/electron/preload.js?");
/***/ }),
@@ -104,7 +104,7 @@ eval("const { contextBridge, ipcRenderer } = __webpack_require__(/*! electron */
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
-eval("module.exports = __webpack_require__(/*! /Users/lisa/wanglin/github/mind-map/web/src/electron/preload.js */\"./src/electron/preload.js\");\n\n\n//# sourceURL=webpack:///multi_./src/electron/preload.js?");
+eval("module.exports = __webpack_require__(/*! E:\\wanglin\\mind-map\\web\\src\\electron\\preload.js */\"./src/electron/preload.js\");\n\n\n//# sourceURL=webpack:///multi_./src/electron/preload.js?");
/***/ }),
diff --git a/web/package.json b/web/package.json
index 15281f30..d5980fd2 100644
--- a/web/package.json
+++ b/web/package.json
@@ -15,6 +15,10 @@
"autoBuildDoc": "node ./scripts/autoBuildDoc.js",
"buildDoc": "node ./scripts/buildDoc.js",
"electron:build": "vue-cli-service electron:build",
+ "electron:build-all": "vue-cli-service electron:build -p never -mwl",
+ "electron:build-mac": "vue-cli-service electron:build -p never -m",
+ "electron:build-win": "vue-cli-service electron:build -p never -w",
+ "electron:build-linux": "vue-cli-service electron:build -p never -l",
"electron:serve": "vue-cli-service electron:serve",
"buildLibrary": "vue-cli-service build --target lib --name simpleMindMap ../simple-mind-map/full.js --dest ../simple-mind-map/dist && esbuild ../simple-mind-map/full.js --bundle --external:buffer --format=esm --outfile=../simple-mind-map/dist/simpleMindMap.esm.js",
"format": "prettier --write src/* src/*/* src/*/*/* src/*/*/*/*",
diff --git a/web/src/background.js b/web/src/background.js
index bfa792ed..1df80d95 100644
--- a/web/src/background.js
+++ b/web/src/background.js
@@ -1,18 +1,14 @@
'use strict'
-import {
- app,
- protocol,
- BrowserWindow,
-} from 'electron'
+import { app, protocol, BrowserWindow } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import path from 'path'
import { bindFileHandleEvent } from './electron/fileHandle'
-import { bindOtherHandleEvent } from './electron/otherHandle';
+import { bindOtherHandleEvent } from './electron/otherHandle'
const isDevelopment = process.env.NODE_ENV !== 'production'
-// Scheme must be registered before the app is ready
+// 在应用程序准备就绪之前,必须注册方案
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
@@ -35,12 +31,14 @@ async function createMainWindow() {
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
- // Load the url of the dev server if in development mode
- await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '/#/workbenche')
- // if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()
+ // 如果处于开发模式,则加载开发服务器的url
+ await mainWindow.loadURL(
+ process.env.WEBPACK_DEV_SERVER_URL + '/#/workbenche'
+ )
+ if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()
} else {
createProtocol('app')
- // Load the index.html when not in development
+ // 非开发环境时加载index.html
mainWindow.loadURL('app://./index.html/#/workbenche')
}
}
@@ -53,19 +51,17 @@ const bindEvent = () => {
// 关闭所有窗口后退出
app.on('window-all-closed', () => {
- // On macOS it is common for applications and their menu bar
- // to stay active until the user quits explicitly with Cmd + Q
+ // 在macOS上,应用程序及其菜单栏通常保持活动状态,直到用户使用Cmd+Q明确退出
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
- // On macOS it's common to re-create a window in the app when the
- // dock icon is clicked and there are no other windows open.
+ // 在macOS上,当点击dock图标且没有其他窗口打开时,通常会在应用程序中重新创建一个窗口。
if (BrowserWindow.getAllWindows().length === 0) {
createMainWindow()
- bindEvent()
+ // bindEvent()
}
})
@@ -74,7 +70,7 @@ app.on('ready', async () => {
bindEvent()
})
-// Exit cleanly on request from parent process in development mode.
+// 在开发模式下,应父进程的请求干净地退出。
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', data => {
diff --git a/web/src/electron/fileHandle.js b/web/src/electron/fileHandle.js
index 01528d48..102275eb 100644
--- a/web/src/electron/fileHandle.js
+++ b/web/src/electron/fileHandle.js
@@ -1,196 +1,246 @@
-import {
- BrowserWindow,
- ipcMain,
- dialog,
- shell
-} from 'electron'
+import { BrowserWindow, ipcMain, dialog, shell } from 'electron'
import fs from 'fs-extra'
import path from 'path'
-import { saveToRecent, clearRecent, removeFileInRecent, replaceFileInRecent, getRecent } from './storage'
+import {
+ saveToRecent,
+ clearRecent,
+ removeFileInRecent,
+ replaceFileInRecent,
+ getRecent,
+ saveFileListToRecent
+} from './storage'
import { v4 as uuid } from 'uuid'
export const bindFileHandleEvent = ({ mainWindow }) => {
- // 通知主页面刷新最近文件列表
- const notifyMainWindowRefreshRecentFileList = () => {
- mainWindow.webContents.send('refreshRecentFileList')
- }
+ // 通知主页面刷新最近文件列表
+ const notifyMainWindowRefreshRecentFileList = () => {
+ mainWindow.webContents.send('refreshRecentFileList')
+ }
- // 新建编辑页面
- const openIds = []
- const createEditWindow = async (event, id) => {
- openIds.push(id)
- const win = new BrowserWindow({
- width: 1200,
- height: 800,
- frame: false,
- titleBarStyle: 'hiddenInset',
- webPreferences: {
- webSecurity: false,
- nodeIntegration: true,
- enableRemoteModule: true,
- contextIsolation: true,
- preload: path.join(__dirname, 'preload.js')
- }
+ // 新建编辑页面
+ const openIds = []
+ const createEditWindow = async (event, id) => {
+ openIds.push(id)
+ const win = new BrowserWindow({
+ width: 1200,
+ height: 800,
+ frame: false,
+ titleBarStyle: 'hiddenInset',
+ webPreferences: {
+ webSecurity: false,
+ nodeIntegration: true,
+ enableRemoteModule: true,
+ contextIsolation: true,
+ preload: path.join(__dirname, 'preload.js')
+ }
+ })
+ win.on('closed', () => {
+ // 从openIds数组中删除
+ let index = openIds.find(item => {
+ return item === id
+ })
+ if (index !== -1) {
+ openIds.splice(index, 1)
+ }
+ // 从idToFilePath中删除
+ delete idToFilePath[id]
+ })
+ if (process.env.WEBPACK_DEV_SERVER_URL) {
+ // Load the url of the dev server if in development mode
+ win.loadURL(
+ process.env.WEBPACK_DEV_SERVER_URL + '/#/workbenche/edit/' + id
+ )
+ if (!process.env.IS_TEST) win.webContents.openDevTools()
+ } else {
+ // Load the index.html when not in development
+ win.loadURL('app://./index.html/#/workbenche/edit/' + id)
+ }
+ }
+ ipcMain.on('create', createEditWindow)
+
+ // 保存文件
+ const idToFilePath = {}
+ ipcMain.handle('save', async (event, id, data, fileName = '未命名') => {
+ if (!idToFilePath[id]) {
+ const webContents = event.sender
+ const win = BrowserWindow.fromWebContents(webContents)
+ const res = dialog.showSaveDialogSync(win, {
+ title: '保存',
+ defaultPath: fileName + '.smm',
+ filters: [{ name: '思维导图', extensions: ['smm'] }]
+ })
+ if (res) {
+ idToFilePath[id] = res
+ fs.writeFile(res, data)
+ saveToRecent(res).then(() => {
+ notifyMainWindowRefreshRecentFileList()
})
- win.on('closed', () => {
- let index = openIds.find(item => {
- return item === id
- })
- if (index !== -1) {
- openIds.splice(index, 1)
- }
+ return path.parse(idToFilePath[id]).name
+ }
+ } else {
+ fs.writeFile(idToFilePath[id], data)
+ }
+ })
+
+ // 打开文件
+ const openFile = (event, file) => {
+ let id = uuid()
+ idToFilePath[id] = file
+ saveToRecent(file).then(() => {
+ notifyMainWindowRefreshRecentFileList()
+ })
+ createEditWindow(null, id)
+ }
+ ipcMain.on('openFile', openFile)
+
+ // 选择打开本地文件
+ ipcMain.on('selectOpenFile', event => {
+ const res = dialog.showOpenDialogSync({
+ title: '选择',
+ filters: [{ name: '思维导图', extensions: ['smm'] }]
+ })
+ if (res && res[0]) {
+ openFile(null, res[0])
+ }
+ })
+
+ // 获取文件内容
+ ipcMain.handle('getFileContent', (event, id) => {
+ return new Promise(resolve => {
+ let file = idToFilePath[id]
+ if (!file) {
+ resolve(null)
+ return
+ }
+ fs.readFile(file, { encoding: 'utf-8' }, (err, data) => {
+ resolve({
+ name: path.parse(file).name,
+ content: JSON.parse(data)
})
- if (process.env.WEBPACK_DEV_SERVER_URL) {
- // Load the url of the dev server if in development mode
- win.loadURL(
- process.env.WEBPACK_DEV_SERVER_URL + '/#/workbenche/edit/' + id
- )
- if (!process.env.IS_TEST) win.webContents.openDevTools()
+ })
+ })
+ })
+
+ // 重命名文件
+ ipcMain.handle('rename', (event, id, name) => {
+ return new Promise(resolve => {
+ if (!idToFilePath[id]) {
+ resolve('文件不存在')
+ return
+ }
+ let oldPath = idToFilePath[id]
+ let { base, ...oldPathData } = path.parse(oldPath)
+ oldPathData.name = name
+ let newPath = path.format(oldPathData)
+ idToFilePath[id] = newPath
+ fs.rename(oldPath, newPath, err => {
+ if (err) {
+ resolve('重命名失败')
} else {
- // Load the index.html when not in development
- win.loadURL('app://./index.html/#/workbenche/edit/' + id)
+ replaceFileInRecent(oldPath, newPath).then(() => {
+ notifyMainWindowRefreshRecentFileList()
+ resolve()
+ })
}
- }
- ipcMain.on('create', createEditWindow)
+ })
+ })
+ })
- // 保存文件
- const idToFilePath = {}
- ipcMain.handle('save', async (event, id, data) => {
- if (!idToFilePath[id]) {
- const webContents = event.sender
- const win = BrowserWindow.fromWebContents(webContents)
- const res = dialog.showSaveDialogSync(win, {
- title: '保存',
- defaultPath: '未命名.smm',
- filters: [{ name: '思维导图', extensions: ['smm'] }]
- })
- if (res) {
- idToFilePath[id] = res
- fs.writeFile(res, data)
- saveToRecent(res)
- .then(() => {
- notifyMainWindowRefreshRecentFileList()
- })
- return path.parse(idToFilePath[id]).name
- }
+ // 获取最近文件列表
+ ipcMain.handle('getRecentFileList', () => {
+ return getRecent().map(item => {
+ let data = path.parse(item)
+ return {
+ url: item,
+ dir: data.dir,
+ name: data.name
+ }
+ })
+ })
+
+ // 清空最近文件列表
+ ipcMain.handle('clearRecentFileList', async () => {
+ try {
+ clearRecent()
+ return ''
+ } catch (error) {
+ return '清空失败'
+ }
+ })
+
+ // 添加到最近文件列表
+ ipcMain.handle('addRecentFileList', async (event, fileList) => {
+ try {
+ console.log(fileList);
+ await saveFileListToRecent(fileList)
+ notifyMainWindowRefreshRecentFileList()
+ } catch (error) {
+ return error
+ }
+ })
+
+ // 打开指定目录
+ ipcMain.on('openFileInDir', (event, file) => {
+ shell.showItemInFolder(file)
+ })
+
+ // 删除指定文件
+ ipcMain.handle('deleteFile', (event, file) => {
+ let res = ''
+ let id = Object.keys(idToFilePath).find(item => {
+ return idToFilePath[item] === file
+ })
+ let index = -1
+ if (id) {
+ index = openIds.findIndex(item => {
+ return item === id
+ })
+ }
+ if (index === -1) {
+ try {
+ fs.rmSync(file)
+ } catch (error) {}
+ removeFileInRecent(file)
+ } else {
+ res = '该文件正在编辑,请关闭后再试'
+ }
+ return res
+ })
+
+ // 复制文件
+ ipcMain.handle('copyFile', async (event, file) => {
+ return new Promise((resolve, reject) => {
+ fs.pathExists(file, (err, exists) => {
+ if (err) {
+ reject(err)
} else {
- fs.writeFile(idToFilePath[id], data)
- }
- })
-
- // 打开文件
- const openFile = (event, file) => {
- let id = uuid()
- idToFilePath[id] = file
- saveToRecent(file)
- .then(() => {
- notifyMainWindowRefreshRecentFileList()
- })
- createEditWindow(null, id)
- }
- ipcMain.on('openFile', openFile)
-
- // 选择打开本地文件
- ipcMain.on('selectOpenFile', (event) => {
- const res = dialog.showOpenDialogSync({
- title: '选择',
- filters: [{ name: '思维导图', extensions: ['smm'] }],
- })
- if (res && res[0]) {
- openFile(null, res[0])
- }
- })
-
- // 获取文件内容
- ipcMain.handle('getFileContent', (event, id) => {
- return new Promise((resolve) => {
- let file = idToFilePath[id]
- if (!file) {
- resolve(null)
- return
- }
- fs.readFile(file, { encoding: 'utf-8' }, (err, data) => {
- resolve({
- name: path.parse(file).name,
- content: JSON.parse(data)
- })
- })
- })
- })
-
- // 重命名文件
- ipcMain.handle('rename', (event, id, name) => {
- return new Promise((resolve) => {
- if (!idToFilePath[id]) {
- resolve('文件不存在')
- return
- }
- let oldPath = idToFilePath[id]
- let { base, ...oldPathData } = path.parse(oldPath)
- oldPathData.name = name
+ if (exists) {
+ let { base, ...oldPathData } = path.parse(file)
+ let newName = oldPathData.name + '-复制'
+ let index = 1
+ oldPathData.name = newName
let newPath = path.format(oldPathData)
- idToFilePath[id] = newPath
- fs.rename(oldPath, newPath, (err) => {
- if (err) {
- resolve('重命名失败')
- } else {
- replaceFileInRecent(oldPath, newPath).then(() => {
- notifyMainWindowRefreshRecentFileList()
- resolve()
- })
- }
- })
- })
- })
-
- // 获取最近文件列表
- ipcMain.handle('getRecentFileList', () => {
- return getRecent().map(item => {
- console.log(item);
- let data = path.parse(item)
- return {
- url: item,
- dir: data.dir,
- name: data.name
+ // 检查新路径是否已存在
+ while (fs.pathExistsSync(newPath)) {
+ oldPathData.name = newName + index
+ newPath = path.format(oldPathData)
+ index++
}
- })
- })
-
- // 清空最近文件列表
- ipcMain.handle('clearRecentFileList', async () => {
- try {
- clearRecent()
- return ''
- } catch (error) {
- return '清空失败'
- }
- })
-
- // 打开指定目录
- ipcMain.on('openFileInDir', (event, file) => {
- shell.showItemInFolder(file)
- })
-
- // 删除指定文件
- ipcMain.handle('deleteFile', (event, file) => {
- let res = ''
- let id = Object.keys(idToFilePath).find(item => {
- return idToFilePath[item] === file
- })
- let index = -1
- if (id) {
- index = openIds.findIndex(item => {
- return item === id
+ fs.copy(file, newPath, err => {
+ if (err) {
+ reject(err)
+ } else {
+ saveToRecent(newPath).then(() => {
+ notifyMainWindowRefreshRecentFileList()
+ })
+ resolve()
+ }
})
+ } else {
+ reject('文件不存在')
+ }
}
- if (index === -1) {
- res = fs.rmSync(file)
- if (!res) {
- removeFileInRecent(file)
- }
- } else {
- res = '该文件正在编辑,请关闭后再试'
- }
- return res
+ })
})
-}
\ No newline at end of file
+ })
+}
diff --git a/web/src/electron/otherHandle.js b/web/src/electron/otherHandle.js
index be87bc16..3869ac81 100644
--- a/web/src/electron/otherHandle.js
+++ b/web/src/electron/otherHandle.js
@@ -1,21 +1,18 @@
-import {
- BrowserWindow,
- ipcMain,
-} from 'electron'
+import { BrowserWindow, ipcMain } from 'electron'
import open from 'open'
export const bindOtherHandleEvent = () => {
- // 处理缩放事件
- ;['minimize', 'maximize', 'unmaximize', 'close'].forEach(item => {
- ipcMain.on(item, event => {
- const webContents = event.sender
- const win = BrowserWindow.fromWebContents(webContents)
- win[item]()
- })
+ // 处理缩放事件
+ ;['minimize', 'maximize', 'unmaximize', 'close', 'destroy'].forEach(item => {
+ ipcMain.on(item, event => {
+ const webContents = event.sender
+ const win = BrowserWindow.fromWebContents(webContents)
+ win[item]()
})
+ })
- // 使用默认浏览器打开指定url
- ipcMain.on('openUrl', (event, url) => {
- open(url)
- })
-}
\ No newline at end of file
+ // 使用默认浏览器打开指定url
+ ipcMain.on('openUrl', (event, url) => {
+ open(url)
+ })
+}
diff --git a/web/src/electron/preload.js b/web/src/electron/preload.js
index ae058c3e..d4f5eee5 100644
--- a/web/src/electron/preload.js
+++ b/web/src/electron/preload.js
@@ -4,20 +4,24 @@ contextBridge.exposeInMainWorld('platform', process.platform)
contextBridge.exposeInMainWorld('IS_ELECTRON', true)
contextBridge.exposeInMainWorld('electronAPI', {
- minimize: () => ipcRenderer.send('minimize'),
- maximize: () => ipcRenderer.send('maximize'),
- unmaximize: () => ipcRenderer.send('unmaximize'),
- close: () => ipcRenderer.send('close'),
- create: (id) => ipcRenderer.send('create', id),
- getFileContent: (id) => ipcRenderer.invoke('getFileContent', id),
- save: (id, data) => ipcRenderer.invoke('save', id, data),
- rename: (id, name) => ipcRenderer.invoke('rename', id, name),
- openUrl: (url) => ipcRenderer.send('openUrl', url),
- getRecentFileList: () => ipcRenderer.invoke('getRecentFileList'),
- clearRecentFileList: () => ipcRenderer.invoke('clearRecentFileList'),
- openFileInDir: (file) => ipcRenderer.send('openFileInDir', file),
- deleteFile: (file) => ipcRenderer.invoke('deleteFile', file),
- onRefreshRecentFileList: (callback) => ipcRenderer.on('refreshRecentFileList', callback),
- openFile: (file) => ipcRenderer.send('openFile', file),
- selectOpenFile: () => ipcRenderer.send('selectOpenFile'),
-})
\ No newline at end of file
+ minimize: () => ipcRenderer.send('minimize'),
+ maximize: () => ipcRenderer.send('maximize'),
+ unmaximize: () => ipcRenderer.send('unmaximize'),
+ close: () => ipcRenderer.send('close'),
+ destroy: () => ipcRenderer.send('destroy'),
+ create: id => ipcRenderer.send('create', id),
+ getFileContent: id => ipcRenderer.invoke('getFileContent', id),
+ save: (id, data, fileName) => ipcRenderer.invoke('save', id, data, fileName),
+ rename: (id, name) => ipcRenderer.invoke('rename', id, name),
+ openUrl: url => ipcRenderer.send('openUrl', url),
+ addRecentFileList: (fileList) => ipcRenderer.invoke('addRecentFileList', fileList),
+ getRecentFileList: () => ipcRenderer.invoke('getRecentFileList'),
+ clearRecentFileList: () => ipcRenderer.invoke('clearRecentFileList'),
+ openFileInDir: file => ipcRenderer.send('openFileInDir', file),
+ deleteFile: file => ipcRenderer.invoke('deleteFile', file),
+ onRefreshRecentFileList: callback =>
+ ipcRenderer.on('refreshRecentFileList', callback),
+ openFile: file => ipcRenderer.send('openFile', file),
+ selectOpenFile: () => ipcRenderer.send('selectOpenFile'),
+ copyFile: file => ipcRenderer.invoke('copyFile', file)
+})
diff --git a/web/src/electron/storage.js b/web/src/electron/storage.js
index 67eba367..fe42683d 100644
--- a/web/src/electron/storage.js
+++ b/web/src/electron/storage.js
@@ -13,7 +13,30 @@ export const saveToRecent = file => {
list.splice(index, 1)
}
list.push(file)
- storage.set(RECENT_FILE_LIST, list, (err) => {
+ storage.set(RECENT_FILE_LIST, list, err => {
+ if (err) {
+ reject(err)
+ } else {
+ resolve()
+ }
+ })
+ })
+}
+
+// 保存到最近文件
+export const saveFileListToRecent = fileList => {
+ return new Promise((resolve, reject) => {
+ let list = getRecent()
+ fileList.forEach(file => {
+ let index = list.findIndex(item => {
+ return item === file
+ })
+ if (index !== -1) {
+ list.splice(index, 1)
+ }
+ list.push(file)
+ })
+ storage.set(RECENT_FILE_LIST, list, err => {
if (err) {
reject(err)
} else {
@@ -26,7 +49,7 @@ export const saveToRecent = file => {
// 获取最近文件列表
export const getRecent = () => {
let res = storage.getSync(RECENT_FILE_LIST)
- return (Array.isArray(res) ? res : []).filter((item) => {
+ return (Array.isArray(res) ? res : []).filter(item => {
return !!item
})
}
@@ -34,7 +57,7 @@ export const getRecent = () => {
// 清除最近文件列表
export const clearRecent = () => {
return new Promise((resolve, reject) => {
- storage.remove(RECENT_FILE_LIST, (err) => {
+ storage.remove(RECENT_FILE_LIST, err => {
if (err) {
reject(err)
} else {
@@ -45,7 +68,7 @@ export const clearRecent = () => {
}
// 从最近文件列表中移除指定文件
-export const removeFileInRecent = (file) => {
+export const removeFileInRecent = file => {
return new Promise((resolve, reject) => {
let list = getRecent()
let index = list.findIndex(item => {
@@ -54,7 +77,7 @@ export const removeFileInRecent = (file) => {
if (index !== -1) {
list.splice(index, 1)
}
- storage.set(RECENT_FILE_LIST, list, (err) => {
+ storage.set(RECENT_FILE_LIST, list, err => {
if (err) {
reject(err)
} else {
@@ -75,7 +98,7 @@ export const replaceFileInRecent = (oldFile, newFile) => {
list.splice(index, 1)
}
list.push(newFile)
- storage.set(RECENT_FILE_LIST, list, (err) => {
+ storage.set(RECENT_FILE_LIST, list, err => {
if (err) {
reject(err)
} else {
@@ -83,4 +106,4 @@ export const replaceFileInRecent = (oldFile, newFile) => {
}
})
})
-}
\ No newline at end of file
+}
diff --git a/web/src/pages/Edit/components/Edit.vue b/web/src/pages/Edit/components/Edit.vue
index aa559551..862e2d77 100644
--- a/web/src/pages/Edit/components/Edit.vue
+++ b/web/src/pages/Edit/components/Edit.vue
@@ -241,6 +241,7 @@ export default {
this.setFileName(data.name)
storeData = data.content
} else {
+ this.setFileName('未命名')
storeData = getData()
}
this.mindMapData = storeData
@@ -264,7 +265,6 @@ export default {
storeData(data)
})
this.$bus.$on('view_data_change', data => {
- console.log(2);
this.setIsUnSave(true)
storeConfig({
view: data
@@ -437,7 +437,7 @@ export default {
let id = this.$route.params.id
let data = this.mindMap.getData(true)
console.log('保存', id, data)
- let res = await window.electronAPI.save(id, JSON.stringify(data))
+ let res = await window.electronAPI.save(id, JSON.stringify(data), this.fileName)
if (res) {
this.setFileName(res)
}
diff --git a/web/src/pages/Workbenche/components/FileList.vue b/web/src/pages/Workbenche/components/FileList.vue
index 6da3c927..ef50ab83 100644
--- a/web/src/pages/Workbenche/components/FileList.vue
+++ b/web/src/pages/Workbenche/components/FileList.vue
@@ -11,11 +11,31 @@