filestore.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. 'use strict';
  2. const fs = require('fs');
  3. const { extname, sep } = require('path');
  4. const moment = require('moment');
  5. const awaitWriteStream = require('await-stream-ready').write;
  6. const sendToWormhole = require('stream-wormhole');
  7. const Service = require('egg').Service;
  8. class FilestoreService extends Service {
  9. constructor(ctx) {
  10. super(ctx);
  11. this.model = this.ctx.model.Filestore;
  12. }
  13. async upload({ app }) {
  14. const stream = await this.ctx.getFileStream();
  15. const rootPath = `${this.app.config.repos_root_path}`;
  16. // 检查路径是否存在,不存在则创建
  17. if (!fs.existsSync(`${rootPath}/${app}`)) {
  18. fs.mkdirSync(`${rootPath}/${app}`);
  19. }
  20. // 后缀名
  21. const ext = extname(stream.filename).toLowerCase();
  22. // 制作时间串
  23. const name = moment().format('YYYYMMDDHHmmss');
  24. // 定义文件名与路径
  25. const fileName = `${name}${ext}`;
  26. const filePath = `${rootPath}${sep}${app}${sep}`;
  27. const writeStream = fs.createWriteStream(filePath + fileName);
  28. try {
  29. await awaitWriteStream(stream.pipe(writeStream));
  30. if (this.app.config.data_save) {
  31. return await this.create({ fileName, filePath: `/upload/${app}/${fileName}`, name: stream.filename });
  32. }
  33. const data = { fileName, filePath, name: stream.filename };
  34. return { errcode: 0, errmsg: 'ok', data };
  35. } catch (error) {
  36. await sendToWormhole(stream);
  37. throw error;
  38. }
  39. }
  40. async create({ fileName, filePath, name }) {
  41. try {
  42. const res = await this.model.create({ fileName, filePath, name });
  43. return { errcode: 0, errmsg: 'ok', data: res };
  44. } catch (error) {
  45. throw error;
  46. }
  47. }
  48. async delete({ fileName, filePath }) {
  49. try {
  50. const file = await fs.existsSync(`${filePath}${fileName}`, exists => {
  51. console.log(exists, 'exists');
  52. if (!exists) throw { errcode: -1001, errmsg: '文件不存在' };
  53. });
  54. if (file) {
  55. fs.unlink(`${filePath}${fileName}`, err => {
  56. if (err) throw { errcode: -2001, errmsg: err };
  57. });
  58. await this.model.remove({ fileName });
  59. return { errcode: 0, errmsg: 'ok' };
  60. }
  61. return { errcode: -1001, errmsg: '文件不存在' };
  62. } catch (error) {
  63. throw error;
  64. }
  65. }
  66. async query({ skip, limit, fileName, name }) {
  67. try {
  68. const filter = {};
  69. if (name || fileName) filter.$or = [];
  70. if (fileName) filter.$or.push({ code: { $regex: fileName } });
  71. if (name) filter.$or.push({ name: { $regex: name } });
  72. let res;
  73. const total = await this.model.find({ ...filter });
  74. if (skip && limit) {
  75. res = await this.model.find({ ...filter }).skip(Number(skip) * Number(limit)).limit(Number(limit));
  76. } else {
  77. res = await this.model.find({ ...filter });
  78. }
  79. return { errcode: 0, errmsg: 'ok', data: res, total: total.length };
  80. } catch (error) {
  81. throw error;
  82. }
  83. }
  84. // 文件下载
  85. async filesDownload({ filePath }) {
  86. const rootPath = `${this.app.config.root_path}`;
  87. const res = await this.model.findOne({ filePath });
  88. const url = `${rootPath}${filePath}`;
  89. const postfix = url.split('.')[1];
  90. this.ctx.attachment(`${res.name}.${postfix}`);
  91. // this.ctx.set('Content-Type', 'application/octet-stream');
  92. return fs.createReadStream(url);
  93. }
  94. }
  95. module.exports = FilestoreService;