diff --git a/gm-server/app/controller/upload.ts b/gm-server/app/controller/upload.ts new file mode 100644 index 000000000..7c0f4325f --- /dev/null +++ b/gm-server/app/controller/upload.ts @@ -0,0 +1,127 @@ +import { Controller } from 'egg'; + const fs = require('fs'); +const unzip = require("unzip-stream"); +const awaitWriteStream = require('await-stream-ready').write; +const temp = require('temp'); +const compressing = require("compressing"); +const moment = require("moment"); + +const folderName = 'hot_update_files'; +const hotUpdateAddr = `/root/${folderName}`; +const publishPath = '/root/hot_update_backup'; + + +export default class UploadController extends Controller { + + private deleteFolder (path) { + let files = []; + if( fs.existsSync(path) ) { + files = fs.readdirSync(path); + files.forEach((file) =>{ + let curPath = path + "/" + file; + if(fs.statSync(curPath).isDirectory()) { + this.deleteFolder(curPath); + } else { + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(path); + } + } + private async readFileDir (dirPath) { + return new Promise((resolve:any, reject: any) => { + fs.readdir(dirPath, (err, files) => { + if(err) { + reject(err); + } else { + resolve(files); + } + }); + }); + } + + public async upload() { + const { ctx } = this; + const stream = await ctx.getFileStream(); + // const filename = stream.filename; + // const target = path.join(url, filename); + + // const writeStream = fs.createWriteStream(target); + if(stream.mimeType == 'application/zip') { + try { + + let dirPath = await temp.mkdir(folderName); // 临时文件夹 + + // 解压上传文件的stream + var unzipExtractor = unzip.Extract({ path: dirPath }); + await awaitWriteStream(stream.pipe(unzipExtractor)); // 异步写入文件 + + console.log('读取文件'); + let files:any = await this.readFileDir(dirPath); + + let index = files.indexOf(folderName); + if(index != -1) { + dirPath += '/' + folderName; + } + let arr = ['project.manifest', 'version.manifest', 'assets', 'src']; + for(let fileName of arr) { + console.log(dirPath + '/' + fileName) + let result = fs.existsSync(dirPath + '/' + fileName); + if(!result) throw new Error('缺少文件' + fileName); + } + + // 历史记录压缩移动 + console.log('历史记录压缩移动'); + let isEmpty = true; + try { + let oldFiles:any = await this.readFileDir(hotUpdateAddr); + console.log(oldFiles.length); + isEmpty = oldFiles.length <= 0; + } catch(e) { + isEmpty = true; + } + if(!isEmpty) { + await compressing.zip.compressDir(hotUpdateAddr, `${dirPath}/${folderName}.zip`); + if (!fs.existsSync(publishPath)) { + fs.mkdirSync(publishPath); + } + let versionManifest: string = ''; + try { + let version = JSON.parse(fs.readFileSync(`${hotUpdateAddr}/version.manifest`)); + versionManifest = version.version; + }catch(e) { + console.log(e); + } + fs.renameSync(`${dirPath}/${folderName}.zip`, `${publishPath}/${folderName}_${versionManifest}_${moment().format('YYMMDDHHmmss')}.zip`); + + // 删除原始文件 + this.deleteFolder(hotUpdateAddr); + } + + // 保存新文件 + console.log('保存至热更新地址'); + fs.renameSync(dirPath, hotUpdateAddr); + + temp.cleanupSync(); + return ctx.body = { + "status": "ok", + "data": "ok" + } + + } catch (err) { + console.log(err) + return ctx.body = { + "status": "error", + "data": err.message + } + } + + } else { + return ctx.body = { + "status": "error", + "data": "格式错误" + } + } + } + +} diff --git a/gm-server/app/router.ts b/gm-server/app/router.ts index 3f1a2f732..336c70aa4 100644 --- a/gm-server/app/router.ts +++ b/gm-server/app/router.ts @@ -9,6 +9,7 @@ export default (app: Application) => { router.post('/api/login/changeMyPass', tokenParser, controller.login.changeMyPass); router.post('/api/get_route', controller.login.getMenu); router.get('/api/currentUser', tokenParser, controller.login.currentUser); + router.post('/api/upload/hotupdate', controller.upload.upload); router.post('/api/gmaccount/getgmlist', tokenParser, controller.gmaccount.getGmList); router.post('/api/gmaccount/createaccount',tokenParser, controller.gmaccount.createGmAccount); diff --git a/gm-server/config/config.default.ts b/gm-server/config/config.default.ts index 4063fe193..2d10fdc0e 100644 --- a/gm-server/config/config.default.ts +++ b/gm-server/config/config.default.ts @@ -33,6 +33,13 @@ export default (appInfo: EggAppInfo) => { domainWhiteList: ['http://localhost:9000'] }; + // 配置上传 + config.multipart = { + fileSize: '50mb', + mode: 'stream', + fileExtensions: ['.zip', '.tar.gz'], // 扩展几种上传的文件格式 + }; + config.alinode = { appid: '86043', secret: '54ef0364995b0c4f2ab42150e29ad30df8327a3a', diff --git a/gm-server/config/config.local.ts b/gm-server/config/config.local.ts index 9086ec48f..a812b5d17 100644 --- a/gm-server/config/config.local.ts +++ b/gm-server/config/config.local.ts @@ -33,6 +33,13 @@ export default (appInfo: EggAppInfo) => { domainWhiteList: ['http://localhost:9000'] }; + // 配置上传 + config.multipart = { + fileSize: '100mb', + mode: 'stream', + fileExtensions: ['.zip', '.tar.gz'], // 扩展几种上传的文件格式 + }; + config.alinode = { appid: '86043', secret: '54ef0364995b0c4f2ab42150e29ad30df8327a3a', diff --git a/gm-server/package-lock.json b/gm-server/package-lock.json index 16fc1e50e..b0b2c6536 100644 --- a/gm-server/package-lock.json +++ b/gm-server/package-lock.json @@ -1099,6 +1099,11 @@ "ee-first": "^1.1.1" } }, + "await-stream-ready": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/await-stream-ready/-/await-stream-ready-1.0.1.tgz", + "integrity": "sha1-+jCMY/4UrHqQlmrXCCKqk2n4prs=" + }, "axe-core": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", @@ -2357,6 +2362,15 @@ "node-pre-gyp": "0.15.0" } }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -2373,6 +2387,44 @@ "file-uri-to-path": "1.0.0" } }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "black-hole-stream": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/black-hole-stream/-/black-hole-stream-0.0.1.tgz", @@ -2429,11 +2481,40 @@ "ieee754": "^1.1.4" } }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" + }, "busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -2556,6 +2637,21 @@ "utility": "^1.12.0" } }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "requires": { + "traverse": ">=0.3.0 <0.4" + }, + "dependencies": { + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + } + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2856,6 +2952,37 @@ "mime-db": ">= 1.43.0 < 2" } }, + "compressing": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/compressing/-/compressing-1.5.1.tgz", + "integrity": "sha512-1AGBR4Vh0/rpPKSXHoV9cerLo0CUlAhZ/xsJqU3a9+2cbSaFjWT3fk2MIGkCnbpk//DGWrcWw03rhKFQrA9RQw==", + "requires": { + "flushwritable": "^1.0.0", + "get-ready": "^1.0.0", + "iconv-lite": "^0.5.0", + "mkdirp": "^0.5.1", + "pump": "^3.0.0", + "streamifier": "^0.1.1", + "tar-stream": "^1.5.2", + "yauzl": "^2.7.0", + "yazl": "^2.4.2" + }, + "dependencies": { + "get-ready": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-ready/-/get-ready-1.0.0.tgz", + "integrity": "sha1-+RgX8emt7P6hOlYq38jeiDqzR4I=" + }, + "iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5160,6 +5287,14 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -5247,6 +5382,11 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "flushwritable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flushwritable/-/flushwritable-1.0.0.tgz", + "integrity": "sha1-PjKNj95BKtR+c44751C00pAENJg=" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -5297,6 +5437,11 @@ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", @@ -6913,9 +7058,9 @@ } }, "moment": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.28.0.tgz", - "integrity": "sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw==" + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz", + "integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA==" }, "moment-timezone": { "version": "0.5.31", @@ -8789,6 +8934,11 @@ "through": "~2.3" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -10015,6 +10165,11 @@ "resolved": "https://registry.npmjs.org/stream-wormhole/-/stream-wormhole-1.1.0.tgz", "integrity": "sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==" }, + "streamifier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", + "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=" + }, "streamsearch": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", @@ -10243,6 +10398,49 @@ "yallist": "^3.0.3" } }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "tcp-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tcp-base/-/tcp-base-3.1.0.tgz", @@ -10273,6 +10471,24 @@ } } }, + "temp": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz", + "integrity": "sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==", + "requires": { + "rimraf": "~2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", @@ -10387,6 +10603,11 @@ "os-tmpdir": "~1.0.2" } }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -10672,6 +10893,15 @@ } } }, + "unzip-stream": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.0.tgz", + "integrity": "sha512-NG1h/MdGIX3HzyqMjyj1laBCmlPYhcO4xEy7gEqqzGiSLw7XqDQCnY4nYSn5XSaH8mQ6TFkaujrO8d/PIZN85A==", + "requires": { + "binary": "^0.3.0", + "mkdirp": "^0.5.1" + } + }, "upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", @@ -11097,6 +11327,23 @@ } } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "requires": { + "buffer-crc32": "~0.2.3" + } + }, "ylru": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", diff --git a/gm-server/package.json b/gm-server/package.json index b4b6e39b9..3ef4d2cd8 100644 --- a/gm-server/package.json +++ b/gm-server/package.json @@ -24,13 +24,19 @@ "prod": "EGG_SERVER_ENV=prod npm run dev" }, "dependencies": { + "await-stream-ready": "^1.0.1", "bcrypt": "^5.0.0", + "compressing": "^1.5.1", "csprng": "^0.1.2", "egg": "^2.6.1", "egg-alinode": "^2.0.1", "egg-cors": "^2.2.3", "egg-scripts": "^2.6.0", - "reflect-metadata": "^0.1.13" + "moment": "^2.29.0", + "pump": "^3.0.0", + "reflect-metadata": "^0.1.13", + "temp": "^0.9.1", + "unzip-stream": "^0.3.0" }, "devDependencies": { "@types/mocha": "^2.2.40", diff --git a/gm-server/typings/app/controller/index.d.ts b/gm-server/typings/app/controller/index.d.ts index cc7db88b1..49e7c0f74 100644 --- a/gm-server/typings/app/controller/index.d.ts +++ b/gm-server/typings/app/controller/index.d.ts @@ -5,6 +5,7 @@ import 'egg'; import ExportGmaccount from '../../../app/controller/gmaccount'; import ExportHome from '../../../app/controller/home'; import ExportLogin from '../../../app/controller/login'; +import ExportUpload from '../../../app/controller/upload'; import ExportUsers from '../../../app/controller/users'; declare module 'egg' { @@ -12,6 +13,7 @@ declare module 'egg' { gmaccount: ExportGmaccount; home: ExportHome; login: ExportLogin; + upload: ExportUpload; users: ExportUsers; } }