'use strict'; const fs = require('fs'); const { extname, sep } = require('path'); const moment = require('moment'); const awaitWriteStream = require('await-stream-ready').write; const sendToWormhole = require('stream-wormhole'); const Service = require('egg').Service; class FilestoreService extends Service { constructor(ctx) { super(ctx); this.model = this.ctx.model.Filestore; } async upload({ app }) { const stream = await this.ctx.getFileStream(); const rootPath = `${this.app.config.repos_root_path}`; // 检查路径是否存在,不存在则创建 if (!fs.existsSync(`${rootPath}/${app}`)) { fs.mkdirSync(`${rootPath}/${app}`); } // 后缀名 const ext = extname(stream.filename).toLowerCase(); // 制作时间串 const name = moment().format('YYYYMMDDHHmmss'); // 定义文件名与路径 const fileName = `${name}${ext}`; const filePath = `${rootPath}${sep}${app}${sep}`; const writeStream = fs.createWriteStream(filePath + fileName); try { await awaitWriteStream(stream.pipe(writeStream)); if (this.app.config.data_save) { return await this.create({ fileName, filePath: `/upload/${app}/${fileName}`, name: stream.filename }); } const data = { fileName, filePath, name: stream.filename }; return { errcode: 0, errmsg: 'ok', data }; } catch (error) { await sendToWormhole(stream); throw error; } } async create({ fileName, filePath, name }) { try { const res = await this.model.create({ fileName, filePath, name }); return { errcode: 0, errmsg: 'ok', data: res }; } catch (error) { throw error; } } async delete({ fileName, filePath }) { try { const file = await fs.existsSync(`${filePath}${fileName}`, exists => { console.log(exists, 'exists'); if (!exists) throw { errcode: -1001, errmsg: '文件不存在' }; }); if (file) { fs.unlink(`${filePath}${fileName}`, err => { if (err) throw { errcode: -2001, errmsg: err }; }); await this.model.remove({ fileName }); return { errcode: 0, errmsg: 'ok' }; } return { errcode: -1001, errmsg: '文件不存在' }; } catch (error) { throw error; } } async query({ skip, limit, fileName, name }) { try { const filter = {}; if (name || fileName) filter.$or = []; if (fileName) filter.$or.push({ code: { $regex: fileName } }); if (name) filter.$or.push({ name: { $regex: name } }); let res; const total = await this.model.find({ ...filter }); if (skip && limit) { res = await this.model.find({ ...filter }).skip(Number(skip) * Number(limit)).limit(Number(limit)); } else { res = await this.model.find({ ...filter }); } return { errcode: 0, errmsg: 'ok', data: res, total: total.length }; } catch (error) { throw error; } } // 文件下载 async filesDownload({ filePath }) { const rootPath = `${this.app.config.root_path}`; const res = await this.model.findOne({ filePath }); const url = `${rootPath}${filePath}`; const postfix = url.split('.')[1]; this.ctx.attachment(`${res.name}.${postfix}`); // this.ctx.set('Content-Type', 'application/octet-stream'); return fs.createReadStream(url); } } module.exports = FilestoreService;