Ver código fonte

添加服务器对服务器上传

ruifeng_liu 3 anos atrás
pai
commit
ab12f0e176
2 arquivos alterados com 221 adições e 169 exclusões
  1. 195 146
      app/controller/files.js
  2. 26 23
      app/router.js

+ 195 - 146
app/controller/files.js

@@ -1,146 +1,195 @@
-'use strict';
-
-const Controller = require('egg').Controller;
-const moment = require('moment');
-const { sep, extname } = require('path');
-const fs = require('fs');
-const awaitWriteStream = require('await-stream-ready').write;
-const sendToWormhole = require('stream-wormhole');
-const assert = require('assert');
-const wxstream = require('stream');
-const ffmpeg = require('fluent-ffmpeg');
-const { BusinessError, ErrorCode } = require('naf-core').Error;
-
-class FilesController extends Controller {
-
-  async upload() {
-    const { ctx, app } = this;
-    const { appid, catalog, item } = ctx.params;
-    assert(appid);
-    const stream = await ctx.getFileStream();
-    ctx.logger.debug(stream);
-
-    const rootPath = `${app.config.cdn.repos_root_path}`;
-    const rootUrl = `${app.config.cdn.repos_root_url}`;
-    const dirs = [ appid ];
-    if (catalog && catalog !== '_') {
-      const subs = catalog.split('_');
-      dirs.push(...subs);
-    }
-    const saved = await this.saveFile(rootPath, dirs, stream, item);
-    const uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
-    ctx.body = { errcode: 0, errmsg: 'ok', id: saved.id, name: saved.fileName, uri };
-  }
-
-  async saveFile(rootPath, dirs, stream, name) {
-    const ctx = this.ctx;
-    const ext = extname(stream.filename).toLowerCase();
-    // TODO: 指定文件名或者按时间生成文件名
-    // const name = moment().format('YYYYMMDDHHmmss');
-    if (!name) name = moment().format('YYYYMMDDHHmmss');
-
-    // TODO: 检查根路径是否存在,不存在则创建
-    ctx.logger.debug('rootPath: ', rootPath);
-    if (!fs.existsSync(rootPath)) {
-      ctx.logger.debug('create dir: ', rootPath);
-      fs.mkdirSync(rootPath);
-    }
-    // TODO: 检查分级目录是否存在,不存在则创建
-    for (let i = 0; i < dirs.length; i++) {
-      const p = `${rootPath}${sep}${dirs.slice(0, i + 1).join(sep)}`;
-      if (!fs.existsSync(p)) {
-        fs.mkdirSync(p);
-      }
-    }
-
-    const filePath = `${rootPath}${sep}${dirs.join(sep)}${sep}`;
-    const fileName = `${name}${ext}`;
-    const writeStream = fs.createWriteStream(filePath + fileName);
-    try {
-      await awaitWriteStream(stream.pipe(writeStream));
-    } catch (err) {
-      await sendToWormhole(stream);
-      throw err;
-    }
-
-    return { filePath, fileName, id: name };
-  }
-
-  async wxupload() {
-    const { serverid, type, appid } = this.ctx.request.body;
-    assert(serverid, 'serverid不允许为空');
-    assert(type, 'type不允许为空');
-    const { ctx, app } = this;
-    const url = app.config.wx.wxdown(appid, serverid);
-    const file = await this.ctx.curl(url);
-    console.log(url);
-    const stream = new wxstream.PassThrough();
-    stream.end(file.data);
-    const rootPath = `${app.config.cdn.repos_root_path}`;
-    const rootUrl = `${app.config.cdn.repos_root_url}`;
-    let uri;
-    // 判断类型 0、图片 1、音频 2、视频
-    if (type === '0') {
-      const dirs = [ 'wximage' ];
-      const saved = await this.wxsaveFile(rootPath, dirs, stream, '.jpg');
-      uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
-    } else if (type === '1') {
-      const dirs = [ 'wxadio' ];
-      const saved = await this.wxsaveFile(rootPath, dirs, stream, '.amr');
-      // 音频时如果需要使用转码,以下调用ffmpeg进行转码处理
-      // const hz = '.mp3';
-      const resultname = `${saved.id}.amr`;
-      // const ffurl = `${saved.filePath}${resultname}`;
-      // if (!ffmpeg) throw new BusinessError(ErrorCode.SERVICE_FAULT, '转换失败');
-      // new ffmpeg({ source: `${saved.filePath}${saved.fileName}` })
-      //   .saveToFile(ffurl, function(retcode, error) {
-      //   })
-      //   .on('end', function() {
-      //     // 在这里处理完成后的结果
-      //     console.log('Finished processing');
-      //   });
-      uri = `${rootUrl}/${dirs.join('/')}/${resultname}`;
-    } else if (type === '2') {
-      const dirs = [ 'wxvideo' ];
-      const saved = await this.wxsaveFile(rootPath, dirs, stream, '');
-      uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
-    }
-    ctx.body = { errcode: 0, errmsg: 'ok', uri };
-  }
-
-  async wxsaveFile(rootPath, dirs, stream, ext) {
-    const ctx = this.ctx;
-    // TODO: 指定文件名或者按时间生成文件名
-    const name = moment().format('YYYYMMDDHHmmss');
-
-    // TODO: 检查根路径是否存在,不存在则创建
-    ctx.logger.debug('rootPath: ', rootPath);
-    if (!fs.existsSync(rootPath)) {
-      ctx.logger.debug('create dir: ', rootPath);
-      fs.mkdirSync(rootPath);
-    }
-    // TODO: 检查分级目录是否存在,不存在则创建
-    for (let i = 0; i < dirs.length; i++) {
-      const p = `${rootPath}${sep}${dirs.slice(0, i + 1).join(sep)}`;
-      if (!fs.existsSync(p)) {
-        fs.mkdirSync(p);
-      }
-    }
-
-    const filePath = `${rootPath}${sep}${dirs.join(sep)}${sep}`;
-    const fileName = `${name}${ext}`;
-    console.log(filePath + fileName);
-    const writeStream = fs.createWriteStream(filePath + fileName);
-    try {
-      await awaitWriteStream(stream.pipe(writeStream));
-    } catch (err) {
-      await sendToWormhole(stream);
-      throw err;
-    }
-
-    return { filePath, fileName, id: name };
-  }
-
-}
-
-module.exports = FilesController;
+'use strict';
+
+const Controller = require('egg').Controller;
+const moment = require('moment');
+const { sep, extname } = require('path');
+const fs = require('fs');
+const awaitWriteStream = require('await-stream-ready').write;
+const sendToWormhole = require('stream-wormhole');
+const assert = require('assert');
+const wxstream = require('stream');
+const ffmpeg = require('fluent-ffmpeg');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+class FilesController extends Controller {
+
+  async upload() {
+    const { ctx, app } = this;
+    const { appid, catalog, item } = ctx.params;
+    assert(appid);
+    const stream = await ctx.getFileStream();
+    ctx.logger.debug(stream);
+
+    const rootPath = `${app.config.cdn.repos_root_path}`;
+    const rootUrl = `${app.config.cdn.repos_root_url}`;
+    const dirs = [ appid ];
+    if (catalog && catalog !== '_') {
+      const subs = catalog.split('_');
+      dirs.push(...subs);
+    }
+    const saved = await this.saveFile(rootPath, dirs, stream, item);
+    const uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
+    ctx.body = { errcode: 0, errmsg: 'ok', id: saved.id, name: saved.fileName, uri };
+  }
+
+  async saveFile(rootPath, dirs, stream, name) {
+    const ctx = this.ctx;
+    const ext = extname(stream.filename).toLowerCase();
+    // TODO: 指定文件名或者按时间生成文件名
+    // const name = moment().format('YYYYMMDDHHmmss');
+    if (!name) name = moment().format('YYYYMMDDHHmmss');
+
+    // TODO: 检查根路径是否存在,不存在则创建
+    ctx.logger.debug('rootPath: ', rootPath);
+    if (!fs.existsSync(rootPath)) {
+      ctx.logger.debug('create dir: ', rootPath);
+      fs.mkdirSync(rootPath);
+    }
+    // TODO: 检查分级目录是否存在,不存在则创建
+    for (let i = 0; i < dirs.length; i++) {
+      const p = `${rootPath}${sep}${dirs.slice(0, i + 1).join(sep)}`;
+      if (!fs.existsSync(p)) {
+        fs.mkdirSync(p);
+      }
+    }
+
+    const filePath = `${rootPath}${sep}${dirs.join(sep)}${sep}`;
+    const fileName = `${name}${ext}`;
+    const writeStream = fs.createWriteStream(filePath + fileName);
+    try {
+      await awaitWriteStream(stream.pipe(writeStream));
+    } catch (err) {
+      await sendToWormhole(stream);
+      throw err;
+    }
+
+    return { filePath, fileName, id: name };
+  }
+
+  async wxupload() {
+    const { serverid, type, appid } = this.ctx.request.body;
+    assert(serverid, 'serverid不允许为空');
+    assert(type, 'type不允许为空');
+    const { ctx, app } = this;
+    const url = app.config.wx.wxdown(appid, serverid);
+    const file = await this.ctx.curl(url);
+    const stream = new wxstream.PassThrough();
+    stream.end(file.data);
+    const rootPath = `${app.config.cdn.repos_root_path}`;
+    const rootUrl = `${app.config.cdn.repos_root_url}`;
+    let uri;
+    // 判断类型 0、图片 1、音频 2、视频
+    if (type === '0') {
+      const dirs = [ 'wximage' ];
+      const saved = await this.wxsaveFile(rootPath, dirs, stream, '.jpg');
+      uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
+    } else if (type === '1') {
+      const dirs = [ 'wxadio' ];
+      const saved = await this.wxsaveFile(rootPath, dirs, stream, '.amr');
+      // 音频时如果需要使用转码,以下调用ffmpeg进行转码处理
+      // const hz = '.mp3';
+      const resultname = `${saved.id}.amr`;
+      // const ffurl = `${saved.filePath}${resultname}`;
+      // if (!ffmpeg) throw new BusinessError(ErrorCode.SERVICE_FAULT, '转换失败');
+      // new ffmpeg({ source: `${saved.filePath}${saved.fileName}` })
+      //   .saveToFile(ffurl, function(retcode, error) {
+      //   })
+      //   .on('end', function() {
+      //     // 在这里处理完成后的结果
+      //     console.log('Finished processing');
+      //   });
+      uri = `${rootUrl}/${dirs.join('/')}/${resultname}`;
+    } else if (type === '2') {
+      const dirs = [ 'wxvideo' ];
+      const saved = await this.wxsaveFile(rootPath, dirs, stream, '');
+      uri = `${rootUrl}/${dirs.join('/')}/${saved.fileName}`;
+    }
+    ctx.body = { errcode: 0, errmsg: 'ok', uri };
+  }
+
+  async wxsaveFile(rootPath, dirs, stream, ext) {
+    const ctx = this.ctx;
+    // TODO: 指定文件名或者按时间生成文件名
+    const name = moment().format('YYYYMMDDHHmmss');
+
+    // TODO: 检查根路径是否存在,不存在则创建
+    ctx.logger.debug('rootPath: ', rootPath);
+    if (!fs.existsSync(rootPath)) {
+      ctx.logger.debug('create dir: ', rootPath);
+      fs.mkdirSync(rootPath);
+    }
+    // TODO: 检查分级目录是否存在,不存在则创建
+    for (let i = 0; i < dirs.length; i++) {
+      const p = `${rootPath}${sep}${dirs.slice(0, i + 1).join(sep)}`;
+      if (!fs.existsSync(p)) {
+        fs.mkdirSync(p);
+      }
+    }
+
+    const filePath = `${rootPath}${sep}${dirs.join(sep)}${sep}`;
+    const fileName = `${name}${ext}`;
+    const writeStream = fs.createWriteStream(filePath + fileName);
+    try {
+      await awaitWriteStream(stream.pipe(writeStream));
+    } catch (err) {
+      await sendToWormhole(stream);
+      throw err;
+    }
+
+    return { filePath, fileName, id: name };
+  }
+
+  async serverUpload() {
+    const { ctx, app } = this;
+    const body = ctx.request.body;
+    const { name, uri, extension, code } = body;
+    const path = uri;
+    if (!path) {
+      return this.getErrorReturn('缺少文件存储路径');
+    }
+    const rootPath = `${app.config.cdn.repos_root_path}`;
+    const rootUrl = `${app.config.cdn.repos_root_url}`;
+    if (!fs.existsSync(rootPath)) {
+      ctx.logger.debug('create dir: ', rootPath);
+      fs.mkdirSync(rootPath);
+    }
+    const dirs = path.split('/');
+    dirs.pop();
+    // 检查路径是否存在,不存在就创建
+    let realPath = rootPath;
+    const realPathArray = [];
+    for (const p of dirs) {
+      const children = p.split('_');
+      for (const c of children) {
+        realPath = `${realPath}${sep}${c}`;
+        if (!fs.existsSync(realPath)) {
+          fs.mkdirSync(realPath);
+        }
+        realPathArray.push(c);
+      }
+    }
+    const filePath = `${rootUrl}/${realPathArray.join('/')}`;
+    const fileName = `${name || new Date().getTime()}.${extension}`;
+    try {
+      const base64Data = code.replace(/^data:image\/\w+;base64,/, '');
+      const dataBuffer = Buffer(base64Data, 'base64');
+      await fs.writeFileSync(`${realPath}${sep}${fileName}`, Buffer(dataBuffer, 'base64'));
+    } catch (error) {
+      throw error;
+    }
+
+    const returnUri = `${filePath}/${fileName}`;
+    this.ctx.body = this.getSuccessReturn({ uri: returnUri, id: fileName });
+  }
+
+  getErrorReturn(message) {
+    return { errcode: -1, errmsg: message || '程序发生错误' };
+  }
+
+  getSuccessReturn(data) {
+    return { errcode: 0, errmsg: 'ok', data };
+  }
+
+}
+
+module.exports = FilesController;

+ 26 - 23
app/router.js

@@ -1,23 +1,26 @@
-'use strict';
-
-/**
- * @param {Egg.Application} app - egg application
- */
-module.exports = app => {
-  const { router, controller } = app;
-  router.get('/', controller.home.index);
-  router.post('/wechat/upload', controller.files.wxupload);
-  router.post('/:appid/upload', controller.files.upload);
-  router.post('/:appid/:catalog/upload', controller.files.upload);
-  router.post('/:appid/:catalog/:item/upload', controller.files.upload);
-
-  // 视频转码
-  router.post('/:appid/scale', controller.scale.scale);
-  // 缩略图
-  router.post('/:appid/takeshots', controller.scale.takeshots);
-  // 视频剪辑
-  router.post('/:appid/clip', controller.scale.clip);
-  // 获取视频信息
-  router.post('/:appid/metainfo', controller.scale.metainfo);
-
-};
+'use strict';
+
+/**
+ * @param {Egg.Application} app - egg application
+ */
+module.exports = app => {
+  const { router, controller } = app;
+  router.get('/', controller.home.index);
+  // 服务端上传
+  router.post('/server/upload', controller.files.serverUpload);
+  router.post('/wechat/upload', controller.files.wxupload);
+  router.post('/:appid/upload', controller.files.upload);
+  router.post('/:appid/:catalog/upload', controller.files.upload);
+  router.post('/:appid/:catalog/:item/upload', controller.files.upload);
+
+  // 视频转码
+  router.post('/:appid/scale', controller.scale.scale);
+  // 缩略图
+  router.post('/:appid/takeshots', controller.scale.takeshots);
+  // 视频剪辑
+  router.post('/:appid/clip', controller.scale.clip);
+  // 获取视频信息
+  router.post('/:appid/metainfo', controller.scale.metainfo);
+
+
+};