200 lines
6.6 KiB
TypeScript
200 lines
6.6 KiB
TypeScript
import { Controller } from 'egg';
|
|
import { Stream } from 'stream';
|
|
import { STATUS } from '@consts/statusCode';
|
|
const fs = require('fs');
|
|
const unzip = require("unzip-stream");
|
|
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 getFileList (p: string, resultArr: Array<{path:string,name:string}>) {
|
|
console.log(p, fs.existsSync(p))
|
|
if( fs.existsSync(p) ) {
|
|
let files = fs.readdirSync(p);
|
|
console.log(p, files, resultArr);
|
|
files.forEach((file) =>{
|
|
let curPath = p + "/" + file;
|
|
// console.log(curPath, fs.statSync(curPath).isDirectory())
|
|
if(fs.statSync(curPath).isDirectory()) {
|
|
this.getFileList(curPath, resultArr);
|
|
} else {
|
|
resultArr.push({
|
|
path: curPath,
|
|
name: file
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
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
|
|
await this.doUnzipExtra(stream, dirPath);
|
|
|
|
console.log('读取文件');
|
|
let files:any = fs.readdirSync(dirPath);
|
|
let msg = '', result = '';
|
|
for(let file of files) {
|
|
let flag = false;
|
|
|
|
let arr = ['project.manifest', 'version.manifest', 'assets', 'src'];
|
|
for(let fileName of arr) {
|
|
console.log(`${dirPath}/${file}/${fileName}`);
|
|
let result = fs.existsSync(`${dirPath}/${file}/${fileName}`);
|
|
if(!result) {
|
|
msg = '缺少文件' + fileName;
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
if(flag) {
|
|
continue;
|
|
} else {
|
|
result = file;
|
|
dirPath += `/${file}`;
|
|
};
|
|
}
|
|
if(!result) {
|
|
throw new Error(msg);
|
|
}
|
|
|
|
// 历史记录压缩移动
|
|
console.log('历史记录压缩移动');
|
|
let isEmpty = true;
|
|
try {
|
|
let oldFiles:any = fs.readdirSync(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 = ctx.service.utils.resResult(STATUS.SUCCESS);
|
|
|
|
} catch (err) {
|
|
console.log(err)
|
|
return ctx.body = ctx.service.utils.resResult(STATUS.GM_UPLOAD_FORMAT_ERR, null, err.message);
|
|
}
|
|
|
|
} else {
|
|
return ctx.body = ctx.service.utils.resResult(STATUS.GM_UPLOAD_FORMAT_ERR);
|
|
}
|
|
}
|
|
|
|
private async doUnzipExtra(stream: Stream, dirPath: string) {
|
|
return new Promise((resolve, reject) => {
|
|
// 解压上传文件的stream
|
|
var unzipExtractor = unzip.Extract({ path: dirPath });
|
|
unzipExtractor.on('close', function() {
|
|
resolve();
|
|
});
|
|
|
|
unzipExtractor.on('close', function(e) {
|
|
reject(e);
|
|
});
|
|
|
|
stream.pipe(unzipExtractor); // 异步写入文件
|
|
})
|
|
}
|
|
|
|
private jsonFolderName = 'resource';
|
|
private jsonFolderPath = `/root/zyz/shared/${this.jsonFolderName}`;
|
|
|
|
public async uploadJson() {
|
|
const { ctx } = this;
|
|
const stream = await ctx.getFileStream();
|
|
// const filename = stream.filename;
|
|
// const target = path.join(url, filename);
|
|
|
|
if(stream.mimeType == 'application/zip') {
|
|
try {
|
|
let dirPath = await temp.mkdir(this.jsonFolderName); // 临时文件夹
|
|
|
|
console.log('读取文件');
|
|
await this.doUnzipExtra(stream, dirPath);
|
|
let files = new Array<{path:string,name:string}>();
|
|
this.getFileList(dirPath, files);
|
|
console.log(files);
|
|
|
|
console.log('保存文件');
|
|
if (!fs.existsSync(this.jsonFolderPath)) {
|
|
fs.mkdirSync(this.jsonFolderPath);
|
|
}
|
|
for (let {path, name} of files) {
|
|
console.log(`${this.jsonFolderPath}/${name}`);
|
|
fs.renameSync(path, `${this.jsonFolderPath}/${name}`);
|
|
}
|
|
|
|
temp.cleanupSync();
|
|
return ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, {
|
|
"files": JSON.stringify(files)
|
|
});
|
|
} catch (err) {
|
|
console.log(err)
|
|
return ctx.body = ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
|
|
}
|
|
|
|
} else {
|
|
return ctx.body = ctx.service.utils.resResult(STATUS.GM_UPLOAD_FORMAT_ERR);
|
|
}
|
|
}
|
|
|
|
}
|