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": "格式错误" } } } }