'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', '.gif', '.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(); } }; 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 = { realName: fileName, 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.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_); } };