Authored by Targaryen

logs-save

'use strict';
const FileModel = require('../models/file');
const _ = require('lodash');
const shelljs = require('shelljs');
const decompress = require('decompress');
const decompressUnzip = require('decompress-unzip');
const moment = require('moment');
const path = require('path');
const fs = require('fs');
const rd = require('rd');
const ws = require('../../lib/ws');
const qn = require('../../lib/qiniu');
const QINIU_PREFIX = 'yoho';
const BROADCAST_PATH = '/upload';
const FILE_SAVE_ROOT_PATH = './uploads';
class FileApi {
/**
* 上传到服务器的文件处理
* @param {文件} file
* @param {路径} actPath
*/
async upload(file, actPath) {
let fileName = _.get(file, 'name');
let fileNameWithoutType = _.split(fileName, '.')[0];
let fileSavePath = path.join(FILE_SAVE_ROOT_PATH, fileName); // 文件保存到服务器的路径
let readable = await fs.createReadStream(file.path);
let writable = await fs.createWriteStream(fileSavePath);
await readable.pipe(writable);
await readable.on('end', () => {
ws.broadcast(BROADCAST_PATH, {
state: '压缩包已经上传到服务器,开始解压...'
});
});
let fileDistPath = path.join(FILE_SAVE_ROOT_PATH, actPath); // 文件解压的路径
shelljs.mkdir('-p', fileDistPath);
// 解压
await decompress(path.resolve(fileSavePath), path.resolve(fileDistPath), {
plugins: [
decompressUnzip()
]
}).then(() => {
ws.broadcast(BROADCAST_PATH, {
state: '压缩包已经解压成功,开始将文件上传到七牛...'
});
});
let upToQiniuResult = await this.uploadToQiniu(fileDistPath);
let fileModel = new FileModel();
let insertRes = await fileModel.insert({
date: moment().format('YYYY-MM-DD HH:mm'),
fileName: fileName,
actPath: actPath,
username: '' // TODO
});
return upToQiniuResult;
}
/**
* 上传到七牛
* @param {待上传的文件夹} fileDistPath
*/
async uploadToQiniu(fileDistPath) {
let fileList = rd.readSync(fileDistPath); // 读取待上传的文件列表
let hasError = false;
fileList = _.map(fileList, perFilePath => {
return fileDistPath + _.split(perFilePath, fileDistPath)[1];
}); // 处理待上传的文件列表
_.remove(fileList, perFilePath => {
return !perFilePath || /__MACOSX/.test(perFilePath) || !fs.lstatSync(perFilePath).isFile();
});
for(let i = 0; i < fileList.length; i++) {
let result = await qn.uploadFileAsync(fileList[i], {
key: path.join(QINIU_PREFIX, fileList[i])
});
if (result && result.url) {
ws.broadcast(BROADCAST_PATH, {
state: `${fileList[i]} 已经上传到七牛`
});
} else {
hasError = true;
}
}
return {
code: 200,
hasError: hasError
}
}
/**
* 获取上传记录
*/
async getAllLogs() {
let fileModel = new FileModel();
return await fileModel.findAll();
}
}
module.exports = FileApi;
... ...
'use strict';
const Model = require('./model');
class FileModel extends Model {
constructor() {
super('files');
}
}
module.exports = FileModel;
... ...
'use strict';
const _ = require('lodash');
const Router = require('koa-router');
const router = new Router();
const FileApi = require('../../ci/file');
const QINIU_PREFIX = 'yoho';
/**
* 处理列表数据
*/
const _handleListItems = items => {
_.forEach(items, perFile => {
perFile.fsizekb = (perFile.fsize / 1024).toFixed(2) + 'kb';
let dateTime = _.parseInt(perFile.putTime.toString().substring(0, 13));
perFile.putTimeFormat = moment(dateTime).format('YYYY-MM-DD HH:mm');
});
return items;
};
/**
* 校验是否是允许上传的文件包
*/
const _verifyFiles = filesList => {
return true;
};
const file = {
/**
* 文件管理页面
*/
page: async(ctx) => {
console.log(ctx.request.body.username);
await ctx.render('/action/file_page');
},
listLogs: async(ctx) => {
let fileApi = new FileApi();
let result = await fileApi.getAllLogs();
ctx.body = {
code: 200,
message: '',
data: result
}
},
listFiles: async(ctx) => {
let query = ctx.request.body;
let params = {
prefix: QINIU_PREFIX + query.actPath,
limit: 20
};
if (query.marker) {
params.marker = query.marker;
}
let result = await qn.listAsync(params);
let finalResult = {
items: _handleListItems(result.items)
};
if (result.marker) {
finalResult.marker = result.marker;
}
ctx.body = {
code: 200,
message: '',
data: finalResult
};
},
/**
* 上传处理
*/
upload: async(ctx, next) => {
if ('POST' !== ctx.method) return await next();
let file = _.get(ctx, 'request.body._files.file');
if (!file) {
return ctx.body = {
code: 400,
message: '没有接收到上传文件'
};
}
let actPath = _.get(ctx, 'request.body.actPath');
actPath = '/activity/2017/09/famous/007';
if (!actPath) {
return ctx.body = {
code: 400,
message: '请指定路径'
};
}
let fileApi = new FileApi();
let result = await fileApi.upload(file, actPath);
ctx.body = result;
}
}
router.get('/page', file.page);
router.get('/listlogs', file.listLogs);
router.get('/listfiles', file.listFiles);
router.post('/upload', file.upload);
module.exports = router;
... ...
const _ = require('lodash');
const moment = require('moment');
const path = require('path');
const fs = require('fs');
const rd = require('rd');
const shelljs = require('shelljs');
const decompress = require('decompress');
const decompressUnzip = require('decompress-unzip');
const ws = require('../../../lib/ws');
const qn = require('../../../lib/qiniu');
const Router = require('koa-router');
const router = new Router();
const QINIU_PREFIX = 'yoho';
const BROADCAST_PATH = '/upload';
const file = {
/**
* 文件管理页面
*/
page: async(ctx) => {
let result = await qn.listAsync('/yoho');
let resultArray = result.items;
_.forEach(resultArray, perFile => {
perFile.fsizekb = (perFile.fsize / 1024).toFixed(2) + 'kb';
let dateTime = _.parseInt(perFile.putTime.toString().substring(0, 13));
perFile.putTimeFormat = moment(dateTime).format('YYYY-MM-DD HH:mm');
});
await ctx.render('/action/file_page', {fileList: resultArray});
},
/**
* 上传处理
*/
upload: async(ctx, next) => {
if ('POST' !== ctx.method) return await next();
// 文件与路径处理
const file = _.get(ctx, 'request.body._files.file');
const fileName = _.get(file, 'name');
const fileNameWithoutType = _.split(fileName, '.')[0];
const fileSaveFolder = path.join('./uploads', moment().format('YYYYMMDD').toString()); // 以日期建的上传文件夹
const fileSavePath = path.join(fileSaveFolder, fileName); // 文件保存到服务器的路径
const fileDistPath = path.join(fileSaveFolder, 'dist', fileNameWithoutType); // 文件解压的路径
shelljs.mkdir('-p', fileSaveFolder);
shelljs.mkdir('-p', fileDistPath);
const readable = await fs.createReadStream(file.path);
const writable = await fs.createWriteStream(fileSavePath);
await readable.pipe(writable);
readable.on('end', () => {
ws.broadcast(BROADCAST_PATH, {
state: 'Zip file uploaded to Server!'
});
});
// 解压
await decompress(path.resolve(fileSavePath), fileDistPath, {
plugins: [
decompressUnzip()
]
}).then(() => {
ws.broadcast(BROADCAST_PATH, {
state: 'Zip file decompressed!'
});
});
// 上传到七牛处理
let fileList = rd.readSync(fileDistPath); // 读取待上传的文件列表
fileList = _.map(fileList, perFilePath => {
return fileDistPath + _.split(perFilePath, fileDistPath)[1];
}); // 处理待上传的文件列表
_.remove(fileList, perFilePath => {
return !perFilePath || /__MACOSX/.test(perFilePath) || !fs.lstatSync(perFilePath).isFile();
});
for(let i = 0; i < fileList.length; i++) {
let result = await qn.uploadFileAsync(fileList[i], {
key: path.join(QINIU_PREFIX, fileList[i])
});
ws.broadcast(BROADCAST_PATH, {
state: `SUCCESS! ${fileList[i]} Uploaded to Qiniu!`
});
}
ctx.body = {
code: 200,
message: ''
};
}
}
router.get('/page', file.page);
router.post('/upload', file.upload);
module.exports = router;
... ... @@ -25,7 +25,7 @@ const profile = require('./actions/profile');
const checkcode = require('./actions/checkcode').router;
const noAuth = new Router();
const base = new Router();
const files = require('./actions/files');
const file = require('./actions/file');
module.exports = function(app) {
... ... @@ -67,7 +67,7 @@ module.exports = function(app) {
base.use('/abuse_protection', abuseProtection.routes(), degrade.allowedMethods());
base.use('/seo', seo.routes(), seo.allowedMethods());
base.use('/files', files.routes(), files.allowedMethods());
base.use('/files', file.routes(), file.allowedMethods());
base.use('', index.routes(), index.allowedMethods());
... ...