You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
10 KiB
252 lines
10 KiB
'use strict';
|
|
const request = require('superagent');
|
|
const parse = require('async-busboy');
|
|
const path = require('path')
|
|
const fs = require('fs');
|
|
const OSS = require('ali-oss');
|
|
const uuid = require('uuid');
|
|
|
|
const UploadPath = {
|
|
project: ['.txt', '.dwg', '.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf', '.pptx', '.png', '.jpg', '.svg', '.rar', '.zip', '.jpeg', '.mp4'],
|
|
report: ['.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf'],
|
|
data: ['.txt', '.xls', '.xlsx', ".csv"],
|
|
image: ['.png', '.jpg', '.svg'],
|
|
three: ['.js'],
|
|
video: ['.mp4']
|
|
};
|
|
const ext = {
|
|
project: ['.txt', '.dwg', '.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf', '.pptx', '.png', '.jpg', '.svg', '.rar', '.zip', '.jpeg', '.mp4'],
|
|
report: [".doc", ".docx", ".xls", ".xlsx", ".pdf"],
|
|
data: [".txt", ".xls", ".xlsx"],
|
|
image: [".png", ".jpg", ".svg"],
|
|
three: [".js"],
|
|
video: [".mp4"],
|
|
bpmn: [".bpmn", ".bpmn20.xml", ".zip", ".bar"],
|
|
app: [".apk"]
|
|
}
|
|
|
|
module.exports = {
|
|
entry: function (app, router, opts) {
|
|
let download_ = async function (ctx, next) {
|
|
const { fetchUrl } = opts.qiniu;
|
|
const { fetchUrl: aliFetchUrl, bucket, region } = opts.aliOss
|
|
if (ctx.path && ctx.path.includes(fetchUrl)) {
|
|
try {
|
|
const { filename } = ctx.request.query;
|
|
const fkey = decodeURI(ctx.path.slice(fetchUrl.length + 1)).replace(/\.json$/, '.js');
|
|
if (ctx.path) {
|
|
const extNames = ctx.path.split('.');
|
|
app.fs.logger.log('info', 'extNames', extNames);
|
|
if (extNames.length > 0) {
|
|
let fileType = extNames[extNames.length - 1].toLowerCase();
|
|
if (fileType === 'pdf') {
|
|
ctx.type = 'application/pdf';
|
|
app.fs.logger.log('info', 'application/pdf', fileType);
|
|
}
|
|
}
|
|
}
|
|
const publicDownloadUrl = await app.fs.attachment.download(fkey);
|
|
ctx.status = 200;
|
|
if (filename) ctx.attachment(filename);
|
|
ctx.body = request.get(publicDownloadUrl);
|
|
} catch (err) {
|
|
ctx.fs.logger.error(err);
|
|
ctx.status = 404;
|
|
ctx.body = { error: 'file not found.' };
|
|
}
|
|
} else if (ctx.path && ctx.path.includes(aliFetchUrl)) {
|
|
const { filename } = ctx.request.query;
|
|
const fkey = decodeURI(ctx.path.slice(aliFetchUrl.length + 1)).replace(/\.json$/, '.js');
|
|
if (ctx.path) {
|
|
const extNames = ctx.path.split('.');
|
|
app.fs.logger.log('info', 'extNames', extNames);
|
|
if (extNames.length > 0) {
|
|
let fileType = extNames[extNames.length - 1].toLowerCase();
|
|
if (fileType === 'pdf') {
|
|
ctx.type = 'application/pdf';
|
|
app.fs.logger.log('info', 'application/pdf', fileType);
|
|
}
|
|
}
|
|
}
|
|
const publicDownloadUrl = `http://${bucket}.${region}.aliyuncs.com/${encodeURIComponent(fkey)}`
|
|
ctx.status = 200;
|
|
ctx.body = request.get(publicDownloadUrl);
|
|
} else {
|
|
await next();
|
|
}
|
|
};
|
|
const getApiRoot = async function (ctx) {
|
|
const { apiUrl, qiniu, webScreen } = opts;
|
|
const { bucket, region } = opts.aliOss
|
|
|
|
ctx.status = 200;
|
|
ctx.body = {
|
|
root: apiUrl,
|
|
qiniu: qiniu.domain,
|
|
aliAdmin: `http://${bucket}.${region}.aliyuncs.com`,
|
|
webScreen,
|
|
};
|
|
};
|
|
|
|
let upload = async function (ctx, next) {
|
|
try {
|
|
const { files } = await parse(ctx.req);
|
|
const file = files[0];
|
|
const extname = path.extname(file.filename).toLowerCase();
|
|
const fileType = ctx.query.type || "image";
|
|
const fileFolder = ctx.query.fileFolder || 'common';
|
|
if (ext[fileType].indexOf(extname) < 0) {
|
|
ctx.status = 400;
|
|
ctx.body = JSON.stringify({ name: 'UploadFailed', message: '文件格式无效' });
|
|
return;
|
|
}
|
|
const date = new Date().toLocaleDateString();
|
|
const time = new Date().getTime();
|
|
let fileName = time + '_' + file.filename;
|
|
let saveFile = path.join(__dirname, '../../', `/client/assets/files/${fileFolder}`, fileName);
|
|
const pathUrl = `./client/assets/files/${fileFolder}`;
|
|
|
|
const res1 = fs.existsSync(`./client/assets/files/${fileFolder}`);
|
|
!res1 && fs.mkdirSync(`./client/assets/files/${fileFolder}`);
|
|
const res = fs.existsSync(pathUrl);
|
|
!res && fs.mkdirSync(pathUrl);
|
|
let stream = fs.createWriteStream(saveFile);
|
|
fs.createReadStream(file.path).pipe(stream);
|
|
stream.on('error', function (err) {
|
|
app.fs.logger.log('error', '[Upload Heatmap]', err);
|
|
});
|
|
ctx.status = 200;
|
|
ctx.body = { filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' };
|
|
} catch (err) {
|
|
ctx.status = 500;
|
|
ctx.fs.logger.error(err);
|
|
ctx.body = { err: 'upload error.' };
|
|
}
|
|
}
|
|
|
|
let remove = async function (ctx, next) {
|
|
try {
|
|
const fkeys = ctx.request.body;
|
|
let removeUrl = path.join(__dirname, '../../', './client', fkeys.url);
|
|
const res = fs.existsSync(removeUrl);
|
|
if (!res) {
|
|
ctx.status = 400;
|
|
ctx.body = JSON.stringify({ name: 'DeleteFailed', message: '文件地址不存在' });
|
|
return;
|
|
}
|
|
fs.unlink(removeUrl, function (error) {
|
|
if (error) {
|
|
console.log(error);
|
|
}
|
|
})
|
|
ctx.status = 200;
|
|
ctx.body = { name: 'DeleteSuccess.', message: '删除成功' };
|
|
} catch (err) {
|
|
ctx.status = 500;
|
|
ctx.fs.logger.error(err);
|
|
ctx.body = { err: 'upload cleanup error.' };
|
|
}
|
|
}
|
|
let upload_ = async function (ctx, next) {
|
|
let fkey = null;
|
|
try {
|
|
const { p } = ctx.params;
|
|
const { files } = await parse(ctx.req);
|
|
const file = files[0];
|
|
const extname = path.extname(file.filename).toLowerCase();
|
|
if (!UploadPath[p]) {
|
|
ctx.status = 400;
|
|
ctx.body = JSON.stringify({ error: '附件存放的文件夹名称无效' });
|
|
return;
|
|
} else if (UploadPath[p].indexOf(extname) < 0) {
|
|
ctx.status = 400;
|
|
ctx.body = JSON.stringify({ error: '文件格式无效' });
|
|
return;
|
|
} else {
|
|
const fileInfo = await ctx.app.fs.attachment.upload(file, { uploadPath: p });
|
|
fkey = fileInfo.key;
|
|
ctx.body = { uploaded: fkey };
|
|
}
|
|
} catch (err) {
|
|
ctx.status = 500;
|
|
ctx.fs.logger.error(err);
|
|
ctx.body = { err: 'upload error.' };
|
|
}
|
|
}
|
|
|
|
const uploadAliOSS = async (ctx,) => {
|
|
// 这个是上传到阿里
|
|
try {
|
|
const { aliOss } = opts
|
|
const { p = 'default' } = ctx.params;
|
|
const { files } = await parse(ctx.req);
|
|
const file = files[0];
|
|
const filename = file.filename || path.basename(file);
|
|
|
|
const client = new OSS({
|
|
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
|
region: aliOss.region,
|
|
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
|
|
accessKeyId: aliOss.accessKey,
|
|
accessKeySecret: aliOss.secretKey,
|
|
// 填写Bucket名称,例如examplebucket。
|
|
bucket: aliOss.bucket,
|
|
});
|
|
|
|
let uploadPath = path.posix.join(p, uuid.v4(), filename);
|
|
let result = await client.putStream(
|
|
uploadPath,
|
|
file,
|
|
// { contentLength: size }
|
|
);
|
|
|
|
ctx.status = 200;
|
|
ctx.body = {
|
|
key: result.name,
|
|
uploaded: result.name,
|
|
url: result.url,
|
|
};
|
|
} catch (error) {
|
|
ctx.status = 400;
|
|
ctx.fs.logger.error(error);
|
|
ctx.body = { err: 'upload error.' };
|
|
}
|
|
}
|
|
|
|
const downloadFromAli = async (ctx) => {
|
|
try {
|
|
const { aliOss } = opts
|
|
const { path, filename } = ctx.query
|
|
const client = new OSS({
|
|
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
|
region: aliOss.region,
|
|
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
|
|
accessKeyId: aliOss.accessKey,
|
|
accessKeySecret: aliOss.secretKey,
|
|
// 填写Bucket名称,例如examplebucket。
|
|
bucket: aliOss.bucket,
|
|
});
|
|
|
|
const filename_ = filename || path.split('/').pop()
|
|
|
|
const result = await client.get(path);
|
|
ctx.status = 200;
|
|
ctx.set('Content-Type', 'application/x-xls');
|
|
ctx.set('Content-disposition', 'attachment; filename=' + filename_);
|
|
ctx.body = result.content;
|
|
} catch (error) {
|
|
ctx.status = 400;
|
|
ctx.fs.logger.error(error);
|
|
ctx.body = { err: 'download error.' };
|
|
}
|
|
}
|
|
|
|
router.use(download_);
|
|
router.get('/api/root', getApiRoot);
|
|
router.post('/_upload/new', upload);
|
|
router.delete('/_upload/cleanup', remove);
|
|
router.post('/_upload/attachments/ali/:p', uploadAliOSS);
|
|
router.get('/_download/attachments/ali', downloadFromAli);
|
|
router.post('/_upload/attachments/:p', upload_);
|
|
}
|
|
};
|
|
|