mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-25 04:17:42 +08:00
更新
This commit is contained in:
commit
c2c9de1c03
File diff suppressed because one or more lines are too long
@ -20,6 +20,7 @@
|
||||
"@toast-ui/editor": "^3.1.5",
|
||||
"core-js": "^3.6.5",
|
||||
"element-ui": "^2.15.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"highlight.js": "^10.7.3",
|
||||
"uuid": "^3.4.0",
|
||||
"v-viewer": "^1.6.4",
|
||||
|
||||
122
web/dist_electron/preload.js
Normal file
122
web/dist_electron/preload.js
Normal file
@ -0,0 +1,122 @@
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ "./src/electron/preload.js":
|
||||
/*!*********************************!*\
|
||||
!*** ./src/electron/preload.js ***!
|
||||
\*********************************/
|
||||
/*! 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 save: (id, data) => ipcRenderer.send('save', id, data),\n})\n\n//# sourceURL=webpack:///./src/electron/preload.js?");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 0:
|
||||
/*!***************************************!*\
|
||||
!*** multi ./src/electron/preload.js ***!
|
||||
\***************************************/
|
||||
/*! 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?");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "electron":
|
||||
/*!***************************!*\
|
||||
!*** external "electron" ***!
|
||||
\***************************/
|
||||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
eval("module.exports = require(\"electron\");\n\n//# sourceURL=webpack:///external_%22electron%22?");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
32
web/package-lock.json
generated
32
web/package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"@toast-ui/editor": "^3.1.5",
|
||||
"core-js": "^3.6.5",
|
||||
"element-ui": "^2.15.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"highlight.js": "^10.7.3",
|
||||
"uuid": "^3.4.0",
|
||||
"v-viewer": "^1.6.4",
|
||||
@ -9162,7 +9163,6 @@
|
||||
"node_modules/fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
@ -9512,8 +9512,8 @@
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.10",
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
|
||||
},
|
||||
"node_modules/graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
@ -11237,7 +11237,6 @@
|
||||
"node_modules/jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"dev": true,
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@ -16879,7 +16878,6 @@
|
||||
"node_modules/universalify": {
|
||||
"version": "0.1.2",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
@ -20916,7 +20914,6 @@
|
||||
"version": "4.5.19",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.11.0",
|
||||
"@babel/helper-compilation-targets": "^7.9.6",
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
@ -20929,7 +20926,6 @@
|
||||
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||
"@vue/babel-preset-jsx": "^1.2.4",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js-compat": "^3.6.5",
|
||||
"semver": "^6.1.0"
|
||||
}
|
||||
@ -21051,6 +21047,8 @@
|
||||
},
|
||||
"@vue/cli-plugin-vuex": {
|
||||
"version": "4.5.19",
|
||||
"resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.19.tgz",
|
||||
"integrity": "sha512-DUmfdkG3pCdkP7Iznd87RfE9Qm42mgp2hcrNcYQYSru1W1gX2dG/JcW8bxmeGSa06lsxi9LEIc/QD1yPajSCZw==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
@ -21190,6 +21188,8 @@
|
||||
},
|
||||
"@vue/preload-webpack-plugin": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz",
|
||||
"integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
@ -21364,6 +21364,8 @@
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
@ -21409,11 +21411,15 @@
|
||||
},
|
||||
"ajv-errors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
|
||||
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
@ -25546,6 +25552,8 @@
|
||||
"fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"dev": true,
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
@ -25788,6 +25796,8 @@
|
||||
"graceful-fs": {
|
||||
"version": "4.2.10",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
|
||||
},
|
||||
"graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
@ -26900,6 +26910,8 @@
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"dev": true,
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@ -30980,7 +30992,9 @@
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
@ -31839,6 +31853,8 @@
|
||||
},
|
||||
"vuex": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
|
||||
"integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
|
||||
"requires": {}
|
||||
},
|
||||
"w3c-keyname": {
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
"@toast-ui/editor": "^3.1.5",
|
||||
"core-js": "^3.6.5",
|
||||
"element-ui": "^2.15.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"highlight.js": "^10.7.3",
|
||||
"uuid": "^3.4.0",
|
||||
"v-viewer": "^1.6.4",
|
||||
|
||||
@ -34,7 +34,17 @@ export const getData = () => {
|
||||
return simpleDeepClone(exampleData)
|
||||
} else {
|
||||
try {
|
||||
return JSON.parse(store)
|
||||
let parsedData = JSON.parse(store)
|
||||
if (window.IS_ELECTRON) {
|
||||
return simpleDeepClone(exampleData)
|
||||
let { root, ...rest } = parsedData
|
||||
return {
|
||||
...rest,
|
||||
root: simpleDeepClone(exampleData).root
|
||||
}
|
||||
} else {
|
||||
return parsedData
|
||||
}
|
||||
} catch (error) {
|
||||
return simpleDeepClone(exampleData)
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1679621707211') format('woff2'),
|
||||
url('iconfont.woff?t=1679621707211') format('woff'),
|
||||
url('iconfont.ttf?t=1679621707211') format('truetype');
|
||||
src: url('iconfont.woff2?t=1678265970945') format('woff2'),
|
||||
url('iconfont.woff?t=1678265970945') format('woff'),
|
||||
url('iconfont.ttf?t=1678265970945') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
import { app, protocol, BrowserWindow } from 'electron'
|
||||
import { app, protocol, BrowserWindow, ipcMain, BrowserView, dialog } from 'electron'
|
||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
|
||||
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
|
||||
import path from 'path'
|
||||
const fs = require('fs-extra')
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||
|
||||
// Scheme must be registered before the app is ready
|
||||
@ -18,22 +20,77 @@ async function createWindow() {
|
||||
frame: false,
|
||||
titleBarStyle: 'hiddenInset',
|
||||
webPreferences: {
|
||||
|
||||
// Use pluginOptions.nodeIntegration, leave this alone
|
||||
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
|
||||
webSecurity: false,
|
||||
nodeIntegration: true,
|
||||
enableRemoteModule: true,
|
||||
contextIsolation: true,
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
|
||||
// 新建编辑页面
|
||||
ipcMain.on('create', async (event, 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')
|
||||
}
|
||||
})
|
||||
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)
|
||||
}
|
||||
})
|
||||
// 保存
|
||||
const idToFilePath = {}
|
||||
ipcMain.on('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)
|
||||
}
|
||||
return
|
||||
}
|
||||
fs.writeFile(idToFilePath[id], data)
|
||||
})
|
||||
;['minimize', 'maximize', 'unmaximize', 'close'].forEach(item => {
|
||||
ipcMain.on(item, event => {
|
||||
const webContents = event.sender
|
||||
const win = BrowserWindow.fromWebContents(webContents)
|
||||
win[item]()
|
||||
})
|
||||
})
|
||||
|
||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
// Load the url of the dev server if in development mode
|
||||
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
|
||||
if (!process.env.IS_TEST) win.webContents.openDevTools()
|
||||
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '/#/workbenche')
|
||||
// if (!process.env.IS_TEST) win.webContents.openDevTools()
|
||||
} else {
|
||||
createProtocol('app')
|
||||
// Load the index.html when not in development
|
||||
win.loadURL('app://./index.html')
|
||||
win.loadURL('app://./index.html/#/workbenche')
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,25 +109,14 @@ app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', async () => {
|
||||
// if (isDevelopment && !process.env.IS_TEST) {
|
||||
// // Install Vue Devtools
|
||||
// try {
|
||||
// await installExtension(VUEJS_DEVTOOLS)
|
||||
// } catch (e) {
|
||||
// console.error('Vue Devtools failed to install:', e.toString())
|
||||
// }
|
||||
// }
|
||||
createWindow()
|
||||
})
|
||||
|
||||
// Exit cleanly on request from parent process in development mode.
|
||||
if (isDevelopment) {
|
||||
if (process.platform === 'win32') {
|
||||
process.on('message', (data) => {
|
||||
process.on('message', data => {
|
||||
if (data === 'graceful-exit') {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
13
web/src/electron/preload.js
Normal file
13
web/src/electron/preload.js
Normal file
@ -0,0 +1,13 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
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),
|
||||
save: (id, data) => ipcRenderer.send('save', id, data),
|
||||
})
|
||||
@ -14,6 +14,15 @@ Vue.config.productionTip = false
|
||||
Vue.prototype.$bus = new Vue()
|
||||
Vue.use(ElementUI)
|
||||
Vue.use(VueViewer)
|
||||
Vue.mixin({
|
||||
data () {
|
||||
return {
|
||||
IS_ELECTRON: window.IS_ELECTRON,
|
||||
IS_MAC: window.platform === 'darwin',
|
||||
IS_WIN: window.platform === 'win32'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="editContainer">
|
||||
<div class="editContainer" :style="{top: IS_ELECTRON ? '40px' : 0}">
|
||||
<div class="mindMapContainer" ref="mindMapContainer"></div>
|
||||
<Count v-if="!isZenMode"></Count>
|
||||
<Navigator :mindMap="mindMap"></Navigator>
|
||||
@ -136,6 +136,9 @@ export default {
|
||||
this.test()
|
||||
}, 5000)
|
||||
}
|
||||
if (window.IS_ELECTRON) {
|
||||
this.mindMap.keyCommand.addShortcut('Control+s', this.saveToLocal)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
@ -409,6 +412,13 @@ export default {
|
||||
// 移除节点富文本编辑插件
|
||||
removeRichTextPlugin() {
|
||||
this.mindMap.removePlugin(RichText)
|
||||
},
|
||||
|
||||
saveToLocal() {
|
||||
let id = this.$route.params.id
|
||||
let data = this.mindMap.getData(true)
|
||||
console.log('保存', id, data)
|
||||
window.electronAPI.save(id, JSON.stringify(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="toolbarContainer">
|
||||
<div class="toolbar">
|
||||
<div class="toolbar" :style="{top: IS_ELECTRON ? '40px' : 0}">
|
||||
<!-- 节点操作 -->
|
||||
<div class="toolbarBlock">
|
||||
<div
|
||||
@ -126,15 +126,15 @@
|
||||
</div>
|
||||
<!-- 导出 -->
|
||||
<div class="toolbarBlock">
|
||||
<div class="toolbarBtn" @click="createNewLocalFile">
|
||||
<div class="toolbarBtn" @click="createNewLocalFile" v-if="!IS_ELECTRON">
|
||||
<span class="icon iconfont iconxinjian"></span>
|
||||
<span class="text">{{ $t('toolbar.newFile') }}</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="openLocalFile">
|
||||
<div class="toolbarBtn" @click="openLocalFile" v-if="!IS_ELECTRON">
|
||||
<span class="icon iconfont icondakai"></span>
|
||||
<span class="text">{{ $t('toolbar.openFile') }}</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="saveLocalFile">
|
||||
<div class="toolbarBtn" @click="saveLocalFile" v-if="!IS_ELECTRON">
|
||||
<span class="icon iconfont iconlingcunwei"></span>
|
||||
<span class="text">{{ $t('toolbar.saveAs') }}</span>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div class="workbencheContainer">
|
||||
<Header></Header>
|
||||
<div class="workbencheContent">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
@ -8,13 +7,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Header from './components/Header.vue';
|
||||
|
||||
export default {
|
||||
name: 'Workbenche',
|
||||
components: {
|
||||
Header
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
62
web/src/pages/Workbenche/components/Empty.vue
Normal file
62
web/src/pages/Workbenche/components/Empty.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="workbencheEmptyContainer">
|
||||
<div class="icon iconfont iconwushuju"></div>
|
||||
<div class="tip">暂时没有内容</div>
|
||||
<div class="desc">没有最近使用的文件记录</div>
|
||||
<div class="createBtn" @click="create">立即创建</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { create } from '../utils'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
create
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheEmptyContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.icon {
|
||||
font-size: 100px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 12px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.createBtn {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #409eff;
|
||||
color: #409eff;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
45
web/src/pages/Workbenche/components/FileList.vue
Normal file
45
web/src/pages/Workbenche/components/FileList.vue
Normal file
@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div class="workbencheFileListContainer">
|
||||
<div class="title">最近</div>
|
||||
<div class="fileListBox">
|
||||
<Empty></Empty>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Empty from '../components/Empty.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheFileListContainer {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
height: 65px;
|
||||
line-height: 65px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.fileListBox {
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<div class="workbencheHeaderContainer">
|
||||
<div class="placeholder"></div>
|
||||
<div class="home noDrag" :class="{active: isInHome}">
|
||||
<span class="icon iconfont iconzhuye"></span>
|
||||
<span class="text">主页</span>
|
||||
</div>
|
||||
<ScrollTab></ScrollTab>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ScrollTab from './ScrollTab.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ScrollTab
|
||||
},
|
||||
computed: {
|
||||
isInHome() {
|
||||
return this.$route.path.includes('home')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheHeaderContainer {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background-color: #ebeef1;
|
||||
-webkit-app-region: drag;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
.placeholder {
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.home {
|
||||
padding: 0 10px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
background-color: #e3e6e9;
|
||||
flex-shrink: 0;
|
||||
font-size: 14px;
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
15
web/src/pages/Workbenche/components/MacControl.vue
Normal file
15
web/src/pages/Workbenche/components/MacControl.vue
Normal file
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div class="macControl" v-if="IS_MAC"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.macControl {
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
@ -1,227 +0,0 @@
|
||||
<template>
|
||||
<div class="workbencheScrollTabContainer" ref="container">
|
||||
<div class="workbencheScrollTabBox noDrag">
|
||||
<div class="workbencheScrollTabList" ref="list" :style="{ transform: `translateX(${listTranslateX}px)` }">
|
||||
<div class="workbencheScrollTabItem" v-for="(item, index) in localEditList" :key="item.id"
|
||||
:style="{ width: tabWidth + 'px' }" :class="{ active: $route.params.id === item.id }"
|
||||
@click="openTab(item)">
|
||||
<span class="icon iconfont icondiannao"></span>
|
||||
<span class="text">{{ item.name }}</span>
|
||||
<span class="mask"></span>
|
||||
<span class="icon closeIcon el-icon-close" @click="deleteFile(index)"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="workbencheScrollTabControl noDrag" ref="control">
|
||||
<div class="workbencheScrollTabBtn el-icon-plus" @click="addFile"></div>
|
||||
<div class="workbencheScrollTabBtn el-icon-arrow-left" @click="scrollLeft"></div>
|
||||
<div class="workbencheScrollTabBtn el-icon-arrow-right" @click="scrollRight"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
const MIN_TAB_WIDTH = 100
|
||||
const MAX_TAB_WIDTH = 220
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabWidth: 0,
|
||||
tabTotalWidth: 0,
|
||||
listTranslateX: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['localEditList']),
|
||||
},
|
||||
mounted() {
|
||||
this.computeTabWidth()
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setLocalEditList']),
|
||||
|
||||
addFile() {
|
||||
let item = {
|
||||
id: uuidv4(),
|
||||
name: '新建文件',
|
||||
path: ''
|
||||
}
|
||||
this.setLocalEditList([...this.localEditList, item])
|
||||
this.$nextTick(() => {
|
||||
this.openTab(item)
|
||||
this.computeTabWidth()
|
||||
this.scrollToEnd()
|
||||
})
|
||||
},
|
||||
|
||||
deleteFile(index) {
|
||||
let arr = [...this.localEditList]
|
||||
arr.splice(index, 1)
|
||||
this.setLocalEditList(arr)
|
||||
this.$nextTick(() => {
|
||||
this.computeTabWidth()
|
||||
})
|
||||
},
|
||||
|
||||
computeTabWidth() {
|
||||
let containerWidth = this.$refs.container.getBoundingClientRect().width
|
||||
let controlWidth = this.$refs.control.getBoundingClientRect().width
|
||||
this.tabTotalWidth = containerWidth - controlWidth
|
||||
let length = this.localEditList.length
|
||||
let tabWidth = Math.floor(this.tabTotalWidth / length)
|
||||
if (tabWidth >= MAX_TAB_WIDTH) {
|
||||
this.tabWidth = MAX_TAB_WIDTH
|
||||
} else if (tabWidth <= MIN_TAB_WIDTH) {
|
||||
this.tabWidth = MIN_TAB_WIDTH
|
||||
} else {
|
||||
this.tabWidth = tabWidth
|
||||
}
|
||||
},
|
||||
|
||||
scrollLeft() {
|
||||
if (this.listTranslateX + this.tabWidth < 0) {
|
||||
this.listTranslateX += this.tabWidth
|
||||
} else {
|
||||
this.listTranslateX = 0
|
||||
}
|
||||
},
|
||||
|
||||
scrollRight() {
|
||||
let maxScroll = this.tabTotalWidth - this.localEditList.length * this.tabWidth
|
||||
if (this.listTranslateX - this.tabWidth > maxScroll) {
|
||||
this.listTranslateX -= this.tabWidth
|
||||
} else {
|
||||
this.listTranslateX = maxScroll
|
||||
}
|
||||
},
|
||||
|
||||
scrollToEnd() {
|
||||
if (this.localEditList.length * this.tabWidth <= this.tabTotalWidth) {
|
||||
return
|
||||
}
|
||||
this.listTranslateX = this.tabTotalWidth - this.localEditList.length * this.tabWidth
|
||||
},
|
||||
|
||||
openTab(item) {
|
||||
this.$router.push({
|
||||
name: 'WorkbencheEdit',
|
||||
params: {
|
||||
id: item.id
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheScrollTabContainer {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
|
||||
.workbencheScrollTabBox {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
|
||||
.workbencheScrollTabList {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
height: 100%;
|
||||
transition: all 0.3s;
|
||||
|
||||
.workbencheScrollTabItem {
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
font-size: 12px;
|
||||
padding: 0 10px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
.icon {
|
||||
|
||||
&.closeIcon {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 20px;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
box-shadow: -10px 0 10px #fff;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #fff;
|
||||
|
||||
.mask {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.closeIcon {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 10px;
|
||||
background-color: #999;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.text {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.workbencheScrollTabControl {
|
||||
flex-shrink: 0;
|
||||
padding: 0 10px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
.workbencheScrollTabBtn {
|
||||
width: 20px;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
margin: 0 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,75 +1,86 @@
|
||||
|
||||
<template>
|
||||
<div class="workbencheHomeSidebarContainer">
|
||||
<div class="workbencheMenuList">
|
||||
<div class="workbencheMenuItem" v-for="item in menuList" :key="item.name"
|
||||
:class="{ active: $route.name === item.routerName }" @click="toMenu(item.rou
|
||||
)">
|
||||
<span class="icon iconfont" :class="[item.icon]"></span>
|
||||
<span class="text">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="workbencheSidebarContainer">
|
||||
<div class="createBtn" @click="create">开始新建</div>
|
||||
<div class="line"></div>
|
||||
<div class="btn">
|
||||
<span class="icon iconfont icondakai"></span>
|
||||
<span class="text">打开本地文件</span>
|
||||
</div>
|
||||
<div class="btn active">
|
||||
<span class="icon iconfont iconzuijinliulan"></span>
|
||||
<span class="text">最近文件</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { create } from '../utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
menuList: [
|
||||
{
|
||||
name: '本地',
|
||||
icon: 'iconbendi1x',
|
||||
routerName: 'WorkbencheHomeLocal'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toMenu(routerName) {
|
||||
this.$router.push(routerName)
|
||||
}
|
||||
}
|
||||
methods: {
|
||||
create
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheHomeSidebarContainer {
|
||||
width: 80px;
|
||||
background-color: #fff;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
padding: 20px 0;
|
||||
.workbencheSidebarContainer {
|
||||
flex-shrink: 0;
|
||||
width: 200px;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
margin-right: 20px;
|
||||
padding: 15px 20px;
|
||||
|
||||
.workbencheMenuList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.createBtn {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: #409eff;
|
||||
border-radius: 5px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
|
||||
.workbencheMenuItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #000;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background-color: #f3fbf4;
|
||||
color: #56b74b;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #e4e7ed;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
color: #000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
padding: 0 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: rgba(64, 158, 255, 0.3);
|
||||
color: rgba(64, 158, 255, 1);
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
68
web/src/pages/Workbenche/components/WinControl.vue
Normal file
68
web/src/pages/Workbenche/components/WinControl.vue
Normal file
@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="winControl noDrag" v-if="IS_WIN">
|
||||
<div class="winControlBtn iconfont iconzuixiaohua" @click="minimize"></div>
|
||||
<div
|
||||
class="winControlBtn iconfont"
|
||||
:class="[isMaximize ? 'icon3zuidahua-3' : 'iconzuidahua']"
|
||||
@click="toggleMaximize"
|
||||
></div>
|
||||
<div class="winControlBtn iconfont iconguanbi" @click="close"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isMaximize: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
minimize() {
|
||||
window.electronAPI.minimize()
|
||||
},
|
||||
|
||||
toggleMaximize() {
|
||||
if (this.isMaximize) {
|
||||
this.isMaximize = false
|
||||
window.electronAPI.unmaximize()
|
||||
} else {
|
||||
this.isMaximize = true
|
||||
window.electronAPI.maximize()
|
||||
}
|
||||
},
|
||||
|
||||
close() {
|
||||
window.electronAPI.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.winControl {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
.winControlBtn {
|
||||
width: 40px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #ccced1;
|
||||
}
|
||||
|
||||
&.iconguanbi {
|
||||
&:hover {
|
||||
background-color: #e81123;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
6
web/src/pages/Workbenche/utils.js
Normal file
6
web/src/pages/Workbenche/utils.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { v4 as uuid } from 'uuid'
|
||||
|
||||
// 打开新的编辑窗口
|
||||
export const create = () => {
|
||||
window.electronAPI.create(uuid())
|
||||
}
|
||||
@ -1,21 +1,37 @@
|
||||
<template>
|
||||
<div class="workbencheHeaderContainer">
|
||||
<Edit :key="$route.params.id"></Edit>
|
||||
<div class="workbencheEditContainer">
|
||||
<div class="workbencheEditHeader">
|
||||
<MacControl></MacControl>
|
||||
<WinControl></WinControl>
|
||||
</div>
|
||||
<Edit></Edit>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Edit from '../../Edit/Index.vue';
|
||||
import Edit from '../../Edit/Index.vue'
|
||||
import WinControl from '../components/WinControl.vue'
|
||||
import MacControl from '../components/MacControl.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Edit
|
||||
}
|
||||
components: {
|
||||
Edit,
|
||||
MacControl,
|
||||
WinControl
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheHeaderContainer {
|
||||
|
||||
.workbencheEditContainer {
|
||||
.workbencheEditHeader {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background-color: #ebeef1;
|
||||
-webkit-app-region: drag;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -1,32 +1,55 @@
|
||||
<template>
|
||||
<div class="workbencheHomeContainer">
|
||||
<Sidebar></Sidebar>
|
||||
<div class="workbencheHomeContent">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<div class="workbencheHomeContainer">
|
||||
<div class="workbencheHomeHeader">
|
||||
<MacControl></MacControl>
|
||||
<WinControl></WinControl>
|
||||
</div>
|
||||
<div class="workbencheHomeContent">
|
||||
<Sidebar></Sidebar>
|
||||
<FileList></FileList>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WinControl from '../components/WinControl.vue'
|
||||
import MacControl from '../components/MacControl.vue'
|
||||
import Sidebar from '../components/Sidebar.vue'
|
||||
import FileList from '../components/FileList.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar
|
||||
}
|
||||
components: {
|
||||
WinControl,
|
||||
MacControl,
|
||||
Sidebar,
|
||||
FileList
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheHomeContainer {
|
||||
background-color: #f6f8f9;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
background-color: #f6f8f9;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.workbencheHomeContent {
|
||||
flex-grow: 1;
|
||||
padding: 20px;
|
||||
}
|
||||
.workbencheHomeHeader {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background-color: #ebeef1;
|
||||
-webkit-app-region: drag;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.workbencheHomeContent {
|
||||
flex-grow: 1;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div class="workbencheLocalContainer">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.workbencheLocalContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
@ -6,7 +6,6 @@ import routerList from '@/pages/Doc/routerList'
|
||||
import WorkbenchePage from '@/pages/Workbenche/Index'
|
||||
import WorkbencheHomePage from '@/pages/Workbenche/views/Home'
|
||||
import WorkbencheEditPage from '@/pages/Workbenche/views/Edit'
|
||||
import WorkbencheHomeLocalPage from '@/pages/Workbenche/views/Local'
|
||||
|
||||
// 处理没有翻译的章节路由
|
||||
const handleRouterList = () => {
|
||||
@ -39,19 +38,12 @@ const routes = [
|
||||
path: '/workbenche',
|
||||
name: 'Workbenche',
|
||||
component: WorkbenchePage,
|
||||
redirect: '/workbenche/home/local',
|
||||
redirect: '/workbenche/home',
|
||||
children: [
|
||||
{
|
||||
path: 'home',
|
||||
name: 'WorkbencheHome',
|
||||
component: WorkbencheHomePage,
|
||||
children: [
|
||||
{
|
||||
path: 'local',
|
||||
name: 'WorkbencheHomeLocal',
|
||||
component: WorkbencheHomeLocalPage,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'edit/:id',
|
||||
|
||||
@ -1,16 +1,110 @@
|
||||
const path = require('path');
|
||||
const path = require('path')
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
module.exports = {
|
||||
publicPath: isDev ? '' : './dist',
|
||||
outputDir: '../dist',
|
||||
lintOnSave: false,
|
||||
productionSourceMap: false,
|
||||
configureWebpack: {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src/')
|
||||
}
|
||||
}
|
||||
publicPath: isDev ? '' : './dist',
|
||||
outputDir: '../dist',
|
||||
lintOnSave: false,
|
||||
productionSourceMap: false,
|
||||
configureWebpack: {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src/')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
pluginOptions: {
|
||||
electronBuilder: {
|
||||
preload: 'src/electron/preload.js',
|
||||
builderOptions: {
|
||||
productName: 'SimpleMindMap',
|
||||
copyright: 'Copyright © SimpleMindMap',
|
||||
// compression: "maximum", // 机器好的可以打开,配置压缩,开启后会让 .AppImage 格式的客户端启动缓慢
|
||||
asar: true,
|
||||
publish: [
|
||||
{
|
||||
provider: 'github',
|
||||
owner: 'wanglin2',
|
||||
repo: 'mind-map',
|
||||
vPrefixedTagName: true,
|
||||
releaseType: 'draft',
|
||||
},
|
||||
],
|
||||
directories: {
|
||||
output: 'dist_electron',
|
||||
},
|
||||
mac: {
|
||||
target: [
|
||||
{
|
||||
target: 'dmg',
|
||||
arch: ['x64', 'arm64', 'universal'],
|
||||
},
|
||||
],
|
||||
artifactName: '${productName}-${os}-${version}-${arch}.${ext}',
|
||||
category: 'public.app-category.utilities',
|
||||
darkModeSupport: true,
|
||||
},
|
||||
win: {
|
||||
target: [
|
||||
{
|
||||
target: 'portable',
|
||||
arch: ['x64'],
|
||||
},
|
||||
{
|
||||
target: 'nsis',
|
||||
arch: ['x64'],
|
||||
},
|
||||
],
|
||||
publisherName: 'SimpleMindMap',
|
||||
icon: 'build/icons/icon.ico',
|
||||
publish: ['github'],
|
||||
},
|
||||
linux: {
|
||||
target: [
|
||||
{
|
||||
target: 'AppImage',
|
||||
arch: ['x64'],
|
||||
},
|
||||
{
|
||||
target: 'tar.gz',
|
||||
arch: ['x64', 'arm64'],
|
||||
},
|
||||
{
|
||||
target: 'deb',
|
||||
arch: ['x64', 'armv7l', 'arm64'],
|
||||
},
|
||||
{
|
||||
target: 'rpm',
|
||||
arch: ['x64'],
|
||||
},
|
||||
{
|
||||
target: 'snap',
|
||||
arch: ['x64'],
|
||||
},
|
||||
{
|
||||
target: 'pacman',
|
||||
arch: ['x64'],
|
||||
},
|
||||
],
|
||||
category: 'Utilities',
|
||||
icon: './build/icon.icns',
|
||||
},
|
||||
dmg: {
|
||||
icon: 'build/icons/icon.icns',
|
||||
},
|
||||
nsis: {
|
||||
oneClick: true,
|
||||
perMachine: true,
|
||||
deleteAppDataOnUninstall: true,
|
||||
},
|
||||
},
|
||||
// 渲染线程的配置文件
|
||||
chainWebpackRendererProcess: config => {
|
||||
config.plugin('define').tap(args => {
|
||||
args[0]['IS_ELECTRON'] = true
|
||||
return args
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user