files.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. 'use strict';
  2. const Controller = require('egg').Controller;
  3. const moment = require('moment');
  4. const { sep, extname } = require('path');
  5. const fs = require('fs');
  6. const awaitWriteStream = require('await-stream-ready').write;
  7. const sendToWormhole = require('stream-wormhole');
  8. const assert = require('assert');
  9. const wxstream = require('stream');
  10. const ffmpeg = require('fluent-ffmpeg');
  11. // const sharp = require('sharp');
  12. class FilesController extends Controller {
  13. async upload() {
  14. const { ctx, app } = this;
  15. const { appid, catalog, item } = ctx.params;
  16. assert(appid);
  17. const stream = await ctx.getFileStream();
  18. ctx.logger.debug(stream);
  19. const rootPath = `${app.config.cdn.repos_root_path}`;
  20. const rootUrl = `${app.config.cdn.repos_root_url}`;
  21. const dirs = [ appid ];
  22. if (catalog && catalog !== '_') {
  23. const subs = catalog.split('_');
  24. dirs.push(...subs);
  25. }
  26. const saved = await this.saveFile(rootPath, dirs, stream, item);
  27. const uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
  28. ctx.body = { errcode: 0, errmsg: 'ok', id: saved.id, name: saved.fileName, uri };
  29. }
  30. async saveFile(rootPath, dirs, stream, name) {
  31. const ctx = this.ctx;
  32. const ext = extname(stream.filename).toLowerCase();
  33. // TODO: 指定文件名或者按时间生成文件名
  34. // const name = moment().format('YYYYMMDDHHmmss');
  35. if (!name) name = moment().format('YYYYMMDDHHmmss');
  36. // TODO: 检查根路径是否存在,不存在则创建
  37. ctx.logger.debug('rootPath: ', rootPath);
  38. if (!fs.existsSync(rootPath)) {
  39. ctx.logger.debug('create dir: ', rootPath);
  40. fs.mkdirSync(rootPath);
  41. }
  42. // TODO: 检查分级目录是否存在,不存在则创建
  43. for (let i = 0; i < dirs.length; i++) {
  44. const p = `${rootPath}${sep}${dirs.slice(0, i + 1).join(sep)}`;
  45. if (!fs.existsSync(p)) {
  46. fs.mkdirSync(p);
  47. }
  48. }
  49. const filePath = `${rootPath}${sep}${dirs.join(sep)}${sep}`;
  50. let fileName = `${name}${ext}`;
  51. const writeStream = fs.createWriteStream(filePath + fileName);
  52. try {
  53. await awaitWriteStream(stream.pipe(writeStream));
  54. } catch (err) {
  55. await sendToWormhole(stream);
  56. throw err;
  57. }
  58. // // 判断是不是作业的图片,是=>统一转换
  59. // const arr = fileName.split('.');
  60. // if (arr.length > 0 && filePath.includes('task')) {
  61. // const suffix = arr.find(
  62. // f =>
  63. // f.includes('jpg') ||
  64. // f.includes('jpeg') ||
  65. // f.includes('bmp') ||
  66. // f.includes('gif') ||
  67. // f.includes('png')
  68. // );
  69. // if (suffix) {
  70. // await sharp(`${filePath}${fileName}`)
  71. // .resize(1000)
  72. // .toFile(`${filePath}${name}_.jpg`)
  73. // .then(data => {
  74. // // 将转换之前的文件删除
  75. // fs.unlinkSync(`${filePath}${fileName}`);
  76. // fileName = `${name}_.jpg`;
  77. // name = `${name}_`;
  78. // });
  79. // }
  80. // }
  81. return { filePath, fileName, id: name };
  82. }
  83. async wxupload() {
  84. const { serverid, type } = this.ctx.request.body;
  85. assert(serverid, 'serverid不允许为空');
  86. assert(type, 'type不允许为空');
  87. const { ctx, app } = this;
  88. const url = app.config.wx.wxdown + serverid;
  89. console.log(url);
  90. console.log(type);
  91. const file = await this.ctx.curl(url);
  92. const stream = new wxstream.PassThrough();
  93. stream.end(file.data);
  94. const rootPath = `${app.config.cdn.repos_root_path}`;
  95. const rootUrl = `${app.config.cdn.repos_root_url}`;
  96. let uri;
  97. // 判断类型 0、图片 1、音频 2、视频
  98. if (type === '0') {
  99. const dirs = [ 'wximage' ];
  100. const saved = await this.wxsaveFile(rootPath, dirs, stream, '.jpg');
  101. uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
  102. } else if (type === '1') {
  103. const dirs = [ 'wxadio' ];
  104. const saved = await this.wxsaveFile(rootPath, dirs, stream, '.amr');
  105. // 音频时如果需要使用转码,以下调用ffmpeg进行转码处理
  106. const hz = '.mp3';
  107. const resultname = `${saved.id}${hz}`;
  108. const ffurl = `${saved.filePath}${resultname}`;
  109. new ffmpeg({ source: `${saved.filePath}${saved.fileName}` })
  110. .saveToFile(ffurl, function(retcode, error) {
  111. })
  112. .on('end', function() {
  113. // 在这里处理完成后的结果
  114. console.log('Finished processing');
  115. });
  116. uri = `${rootUrl}/${dirs.join('/')}/${resultname}`;
  117. } else if (type === '2') {
  118. const dirs = [ 'wxvideo' ];
  119. const saved = await this.wxsaveFile(rootPath, dirs, stream, '');
  120. uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
  121. }
  122. ctx.body = { errcode: 0, errmsg: 'ok', uri };
  123. }
  124. async wxsaveFile(rootPath, dirs, stream, ext) {
  125. const ctx = this.ctx;
  126. // TODO: 指定文件名或者按时间生成文件名
  127. const name = moment().format('YYYYMMDDHHmmss');
  128. // TODO: 检查根路径是否存在,不存在则创建
  129. ctx.logger.debug('rootPath: ', rootPath);
  130. if (!fs.existsSync(rootPath)) {
  131. ctx.logger.debug('create dir: ', rootPath);
  132. fs.mkdirSync(rootPath);
  133. }
  134. // TODO: 检查分级目录是否存在,不存在则创建
  135. for (let i = 0; i < dirs.length; i++) {
  136. const p = `${rootPath}${sep}${dirs.slice(0, i + 1).join(sep)}`;
  137. if (!fs.existsSync(p)) {
  138. fs.mkdirSync(p);
  139. }
  140. }
  141. const filePath = `${rootPath}${sep}${dirs.join(sep)}${sep}`;
  142. const fileName = `${name}${ext}`;
  143. console.log(filePath + fileName);
  144. const writeStream = fs.createWriteStream(filePath + fileName);
  145. try {
  146. await awaitWriteStream(stream.pipe(writeStream));
  147. } catch (err) {
  148. await sendToWormhole(stream);
  149. throw err;
  150. }
  151. return { filePath, fileName, id: name };
  152. }
  153. }
  154. module.exports = FilesController;