file.js
5.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
'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 CDNCONFIG = require('../../config/cdn_config');
const qn = require('../../lib/qiniu')(CDNCONFIG.feature); // 活动上传
const FILE_SAVE_ROOT_PATH = './uploads'; // 上传到本地服务器的根目录
const SUPER_FILE_CHECK_PASS = 'yohowebtech.superfile'; // 存在此文件,直接上传到七牛
const BROADCAST_PATH = '/upload'; // ws 键
class FileApi {
/**
* 上传到服务器的文件处理
* @param {文件} file
* @param {路径} actPath
* @param {用户} user
*/
async upload(file, actPath, user) {
let fileName = _.get(file, 'name');
let fileNameWithoutType = _.split(fileName, '.')[0];
let fileSavePath = path.join(FILE_SAVE_ROOT_PATH, fileName); // 文件保存到服务器的路径
await new Promise((resolve, reject) => {
let readable = fs.createReadStream(file.path);
let writable = fs.createWriteStream(fileSavePath);
readable.pipe(writable);
readable.on('end', result => {
resolve(result);
});
});
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()
]
});
ws.broadcast(BROADCAST_PATH, {
state: '压缩包已经解压成功,开始校验文件...'
});
let fileList = rd.readSync(fileDistPath); // 读取待上传的文件列表
let testRes = this._testFiles(fileList); // 文件校验
if (testRes) {
ws.broadcast(BROADCAST_PATH, {
state: '校验文件通过,开始将文件上传到七牛...'
});
let fileModel = new FileModel();
let insertRes = await fileModel.insert({ // 上传记录写库
date: moment().format('YYYY-MM-DD HH:mm'),
fileName: fileName,
actPath: actPath,
username: user.username,
user_id: user._id
});
await this._uploadToQiniu(fileList, fileDistPath);
ws.broadcast(BROADCAST_PATH, {
state: '文件上传到七牛处理结束!'
});
} else {
ws.broadcast(BROADCAST_PATH, {
state: '校验文件失败,非法上传!'
});
}
return true;
}
/**
* 上传到七牛
* @param {待上传的文件列表} fileList
* @param {待上传的文件夹路径} fileDistPath
*/
async _uploadToQiniu(fileList, fileDistPath) {
_.remove(fileList, perFilePath => {
return !perFilePath || /__MACOSX/.test(perFilePath) || /.DS_Store/.test(perFilePath) || !fs.lstatSync(perFilePath).isFile();
});
let fileListPromises = _.map(fileList, filepath => {
let fileKey = path.relative(FILE_SAVE_ROOT_PATH, filepath);
return new Promise((resolve, reject) => {
qn.uploadFile(filepath, {key:fileKey}, (err, result) => {
if (err) {
ws.broadcast(BROADCAST_PATH, {
state: `${fileKey} 上传到七牛过程中出现错误`
});
reject(err);
} else {
if (result && result.url) {
ws.broadcast(BROADCAST_PATH, {
state: `${fileKey} 上传到七牛成功`
});
} else {
ws.broadcast(BROADCAST_PATH, {
state: `${fileKey} 上传到七牛失败`
});
}
resolve(result);
}
});
});
});
return Promise.all(fileListPromises);
}
/**
* 测试是否是可以上传的文件包
* @param {待上传的文件列表} fileDistPath
*/
_testFiles(fileList) {
let isSuperFile = false;
let isExistedHyperesources = false;
let isExistedHypeGenerated = false;
_.forEach(fileList, file => {
if (file.indexOf(SUPER_FILE_CHECK_PASS) > 0) {
isSuperFile = true;
return false;
}
if (/.hyperesources/.test(file)) {
isExistedHyperesources = true;
}
if (/_hype_generated_script/.test(file)) {
isExistedHypeGenerated = true;
}
if (isExistedHyperesources && isExistedHypeGenerated) {
return false;
}
});
return isSuperFile || (isExistedHyperesources && isExistedHypeGenerated);
}
/**
* 获取上传记录
*/
async getAllLogs(params) {
let page = _.parseInt(params.page);
let limit = 10;
let skip = page > 0? limit * (page - 1) : 0;
let result = await new FileModel().cfind({}).sort({
date: -1
}).skip(skip).limit(limit).exec();
_.forEach(result, perLog => {
perLog.link = _.get(CDNCONFIG, 'feature.origin') + perLog.actPath + '/index.html';
});
return result;
}
}
module.exports = FileApi;