diff --git a/backend/file.js b/backend/file.js index 29153cc4..d3ca61fe 100644 --- a/backend/file.js +++ b/backend/file.js @@ -98,6 +98,10 @@ exports.mv = (oldPath, newPath) => { } } +exports.upload = (file, path) => { + exports.write(path, fs.readFileSync(file.path)) +} + exports.tree = () => { return [{ name: '/', diff --git a/backend/main.js b/backend/main.js index 5e8035f9..326f9af3 100644 --- a/backend/main.js +++ b/backend/main.js @@ -1,13 +1,14 @@ const Koa = require('koa') +const bodyParser = require('koa-body') +const mime = require('mime') const file = require('./file') -const bodyParser = require('koa-bodyparser') const result = (status = 'ok', message = '操作成功', data = null) => { return { status, message, data } } -const fileContent = ctx => { +const fileContent = (ctx, next) => { if (ctx.path === '/api/file') { if (ctx.method === 'GET') { ctx.body = result('ok', '获取成功', file.read(ctx.query.path).toString()) @@ -23,12 +24,30 @@ const fileContent = ctx => { } } else if (ctx.path === '/api/tree') { ctx.body = result('ok', '获取成功', file.tree()) + } else { + next() + } +} + +const attachment = (ctx, next) => { + if (ctx.path.startsWith('/api/attachment')) { + if (ctx.method === 'POST') { + const path = ctx.request.body.fields.path + file.upload(ctx.request.body.files.attachment, path) + ctx.body = result('ok', '上传成功', path) + } else if (ctx.method === 'GET') { + ctx.type = mime.getType(ctx.query.path) + ctx.body = file.read(ctx.query.path) + } + } else { + next() } } const app = new Koa() -app.use(bodyParser()) -app.use(async ctx => fileContent(ctx)) +app.use(bodyParser({multipart: true})) +app.use(async (ctx, next) => fileContent(ctx, next)) +app.use(async (ctx, next) => attachment(ctx, next)) app.listen(3000) diff --git a/backend/package.json b/backend/package.json index df0a6a0d..12fd08f4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,7 @@ { "dependencies": { "koa": "^2.4.1", - "koa-bodyparser": "^4.2.0" + "koa-body": "^2.5.0", + "mime": "^2.2.0" } } diff --git a/backend/yarn.lock b/backend/yarn.lock index b8b1aa05..c969fba2 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -17,7 +17,7 @@ bytes@3.0.0: version "3.0.0" resolved "http://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" -co-body@^5.1.0: +co-body@^5.1.1: version "5.1.1" resolved "http://registry.npm.taobao.org/co-body/download/co-body-5.1.1.tgz#d97781d1e3344ba4a820fd1806bddf8341505236" dependencies: @@ -45,10 +45,6 @@ cookies@~0.7.0: depd "~1.1.1" keygrip "~1.0.2" -copy-to@^2.0.1: - version "2.0.1" - resolved "http://registry.npm.taobao.org/copy-to/download/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" - debug@*: version "3.1.0" resolved "http://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -87,6 +83,10 @@ escape-html@~1.0.1: version "1.0.3" resolved "http://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" +formidable@^1.1.1: + version "1.1.1" + resolved "http://registry.npm.taobao.org/formidable/download/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" + fresh@^0.5.2: version "0.5.2" resolved "http://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -127,12 +127,12 @@ keygrip@~1.0.2: version "1.0.2" resolved "http://registry.npm.taobao.org/keygrip/download/keygrip-1.0.2.tgz#ad3297c557069dea8bcfe7a4fa491b75c5ddeb91" -koa-bodyparser@^4.2.0: - version "4.2.0" - resolved "http://registry.npm.taobao.org/koa-bodyparser/download/koa-bodyparser-4.2.0.tgz#bce6e08bc65f8709b6d1faa9411c7f0d8938aa54" +koa-body@^2.5.0: + version "2.5.0" + resolved "http://registry.npm.taobao.org/koa-body/download/koa-body-2.5.0.tgz#84e8fcd8d5229a8cc1cb98a926e939069e716915" dependencies: - co-body "^5.1.0" - copy-to "^2.0.1" + co-body "^5.1.1" + formidable "^1.1.1" koa-compose@^3.0.0: version "3.2.1" @@ -198,6 +198,10 @@ mime-types@^2.0.7, mime-types@~2.1.15, mime-types@~2.1.16: dependencies: mime-db "~1.30.0" +mime@^2.2.0: + version "2.2.0" + resolved "http://registry.npm.taobao.org/mime/download/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" + ms@2.0.0: version "2.0.0" resolved "http://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" diff --git a/frontend/src/components/Editor.vue b/frontend/src/components/Editor.vue index 47fe9c9f..61165777 100644 --- a/frontend/src/components/Editor.vue +++ b/frontend/src/components/Editor.vue @@ -25,6 +25,9 @@ export default { this.onGotAmdLoader() } }, + beforeDestroy () { + window.removeEventListener('paste', this.paste) + }, methods: { onGotAmdLoader () { window.require(['vs/editor/editor.main'], () => { @@ -44,6 +47,7 @@ export default { }) this.keyBind() + window.addEventListener('paste', this.paste) }, keyBind () { const KM = window.monaco.KeyMod @@ -85,6 +89,27 @@ export default { // console.log(this.editor.getModel().getLineContent(this.editor.getPosition().lineNumber)) // }) }, + paste (e) { + if (this.editor.isFocused()) { + const items = e.clipboardData.items + for (let i = 0; i < items.length; i++) { + let matches = items[i].type.match(/^image\/(png|jpg|jpeg|gif)$/i) + if (matches) { + this.$emit('paste-img', items[i].getAsFile()) + } + } + } + }, + insert (text) { + const selection = this.editor.getSelection() + this.editor.executeEdits('', [ + { + range: new window.monaco.Range(selection.endLineNumber, selection.endColumn, selection.endLineNumber, selection.endColumn), + text, + forceMoveMarkers: true + } + ]) + }, setValue (val) { this.editor.getModel().setValue(val) } diff --git a/frontend/src/components/TreeNode.vue b/frontend/src/components/TreeNode.vue index 2dbc6b0e..8efce527 100644 --- a/frontend/src/components/TreeNode.vue +++ b/frontend/src/components/TreeNode.vue @@ -1,6 +1,6 @@