material_file.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. 'use strict';
  2. const archiver = require('archiver');
  3. const path = require('path');
  4. const fs = require('fs');
  5. /**
  6. * 附件表 数据模型
  7. * @author LanJianRong
  8. * @date 2020/6/30
  9. * @version
  10. */
  11. module.exports = app => {
  12. class MaterialFile extends app.BaseService {
  13. /**
  14. * 构造函数
  15. *
  16. * @param {Object} ctx - egg全局变量
  17. * @return {void}
  18. */
  19. constructor(ctx) {
  20. super(ctx);
  21. this.tableName = 'material_file';
  22. }
  23. /**
  24. * 获取当前标段(期)所有上传的附件
  25. * @param {Number} tid 标段id
  26. * @param {Number?} mid 期id
  27. * @return {Promise<void>} 数据库查询实例
  28. */
  29. async getAllMaterialFiles(tid, mid) {
  30. const { ctx } = this;
  31. const where = { tid };
  32. if (mid) where.mid = mid;
  33. const result = await this.db.select(this.tableName, {
  34. where,
  35. orders: [['upload_time', 'desc']],
  36. });
  37. return result.map(item => {
  38. item.orginpath = this.ctx.app.config.fujianOssPath + item.filepath;
  39. if (!ctx.helper.canPreview(item.fileext)) {
  40. item.filepath = `/tender/${ctx.tender.id}/measure/material/${item.s_order}/file/${item.id}/download`;
  41. } else {
  42. item.filepath = this.ctx.app.config.fujianOssPath + item.filepath;
  43. }
  44. return item;
  45. });
  46. }
  47. /**
  48. * 存储上传的文件信息至数据库
  49. * @param {Array} payload 载荷
  50. * @return {Promise<void>} 数据库插入执行实例
  51. */
  52. async saveFileMsgToDb(payload) {
  53. return await this.db.insert(this.tableName, payload);
  54. }
  55. /**
  56. * 获取单个文件信息
  57. * @param {Number} id 文件id
  58. * @return {Promise<void>} 数据库查询实例
  59. */
  60. async getMaterialFileById(id) {
  61. return await this.getDataByCondition({ id });
  62. }
  63. /**
  64. * 删除附件
  65. * @param {Number} id - 附件id
  66. * @return {void}
  67. */
  68. async delete(id) {
  69. return await this.deleteById(id);
  70. }
  71. /**
  72. * 将文件压缩成zip,并返回zip文件的路径
  73. * @param {array} fileIds - 文件数组id
  74. * @param {string} zipPath - 压缩文件存储路径
  75. * @return {string} 压缩后的zip文件路径
  76. */
  77. async compressedFile(fileIds, zipPath) {
  78. this.initSqlBuilder();
  79. this.sqlBuilder.setAndWhere('id', {
  80. value: fileIds,
  81. operate: 'in',
  82. });
  83. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  84. const files = await this.db.query(sql, sqlParam);
  85. // const paths = files.map(item => {
  86. // return { name: item.filename + item.fileext, path: item.filepath }
  87. // })
  88. return new Promise((resolve, reject) => {
  89. // 每次开一个新的archiver
  90. const ziparchiver = archiver('zip');
  91. const outputPath = fs.createWriteStream(path.resolve(this.app.baseDir, zipPath));
  92. outputPath.on('error', err => {
  93. return reject(err);
  94. });
  95. ziparchiver.pipe(outputPath);
  96. files.forEach(item => {
  97. ziparchiver.file(path.resolve(this.app.baseDir, 'app', item.filepath), { name: item.file_name });
  98. });
  99. // 存档警告
  100. ziparchiver.on('warning', function(err) {
  101. // if (err.code === 'ENOENT') {
  102. // console.warn('stat故障和其他非阻塞错误');
  103. // }
  104. return reject(err);
  105. });
  106. // 存档出错
  107. ziparchiver.on('error', function(err) {
  108. // console.log(err);
  109. return reject(err);
  110. });
  111. ziparchiver.finalize();
  112. outputPath.on('close', () => {
  113. return resolve(ziparchiver.pointer());
  114. });
  115. });
  116. }
  117. }
  118. return MaterialFile;
  119. };