文章分类

首页 / 文章分类 / 正文

Image

antDesign eggjs资源上传,并基于md5进行资源是否重复校验

1、UploadController

'use strict';  const Controller = require('egg').Controller;  class UploadController extends Controller {     async index() {         const {ctx} = this;         ctx.body = await ctx.service.upload.upload();     } }  module.exports = UploadController;

2、UploadService

'use strict';  const Service = require('egg').Service; const path = require('path'); const fs = require('fs'); const crypto = require('crypto');  class UploadService extends Service {     /**      * 上传入口      * @returns {Promise.<*>}      */     async upload() {         const {ctx} = this;         // 获取 steam         const stream = await ctx.getFileStream();         /**          * 文件路径          */         const {uplaodBasePath, filename, filePath, name} = this.setFlieByStream(stream);         /**          * 检验md5          */         const {status, flieBuffer, data} = await this.checkMd5(stream, {filePath, name});         /**          * 如果找到md5 则直接将信息返回 不再重新生成资源          */         if (status === 'found') {             return this.createResponse(stream, data.path);         } else {             /**              * 生成文件目录              */             const {targetPath} = this.createUploadPath({uplaodBasePath, filename});             /**              * 图片信息写入              */             await this.writeFile({path: targetPath, file: flieBuffer});             /**              * 数据插入数据库              */             await this.createMD5(data);             return this.createResponse(stream, data.path);         }     }      /**      * 文件写入      * @param path      * @param file      * @returns {Promise}      */     async writeFile({path, file}) {         return new Promise((resolve, reject) => {             fs.writeFile(path, file, function (err) {                 if (err) reject(err);                 resolve('successed')             });         })     }      /**      * 创建响应      * @param stream      * @param filePath      * @returns {*}      */     createResponse(stream, filePath) {         return {path: filePath};     }      /**      * 检验md5      * @param stream      * @param fileInfo      * @returns {Promise}      */     async checkMd5(stream, fileInfo) {         const {ctx} = this;         const {filePath, name} = fileInfo;         /**          * 生成md5 然后先查询根据md5查询数据库          * 如果数据库存在 将值拿到直接返回 不在创建文件          * 如果值不存在 则创建文件后 再把路径返回          */         return new Promise((resolve, reject) => {             const fsHash = crypto.createHash('md5');             /**              * 保存流数据 后续用于写入              */             let flieBuffer;             stream.on('data', function (d) {                 flieBuffer ? flieBuffer = Buffer.concat([flieBuffer, d]) : flieBuffer = d;                 fsHash.update(d);             });             stream.on('end', function () {                 const md5 = fsHash.digest('hex');                 // 根据md5查询 是否存在                 ctx.connector.upload.fetchByMd5(md5).then(res => {                     // 存在该资源 编辑状态为found 然后返回                     if (res.dataValues) {                         resolve({                             data: res.dataValues,                             status: 'found'                         })                         //  不存在 则在数据库中创建该条资源 并将资源写入 标记状态为create                     } else {                         resolve({                             status: 'create',                             flieBuffer: flieBuffer,                             data: {                                 md5,                                 name,                                 path: filePath                             }                         })                     }                 })             });         });     }      /**      * 生成md5      */     async createMD5(data) {         const {ctx} = this;         /**          * 生成md5 然后先查询根据md5查询数据库          * 如果数据库存在 将值拿到直接返回 不在创建文件          * 如果值不存在 则创建文件后 再把路径返回          */         return new Promise((resolve, reject) => {             ctx.connector.upload.createMd5(data).then(res => {                 resolve({                     status: data                 })             });         });     }      /***      * 创建最终的文件夹 及文件名称      * @param filename      * @param uplaodBasePath      * @returns {{target: string}}      */     createUploadPath({filename, uplaodBasePath}) {         // 没有文件则创建文件目录         const filePath = path.join(this.config.baseDir, uplaodBasePath);         if (!fs.existsSync(filePath)) fs.mkdirSync(filePath);         // 生成写入路径         const targetPath = path.join(this.config.baseDir, uplaodBasePath, filename);         return {             targetPath         }     }      /**      * 设置文件路径和文件名称      * @param stream      * @returns {{uplaodBasePath: string, filename: string}}      */     setFlieByStream(stream) {         // 额外的路径         const _path = stream.fields.path || '';         const actionPath = _path ? _path + '/' : 'upload/';         // 上传基础目录         const uplaodBasePath = ('upload/' + actionPath).replace(/\/\//g, '/');         // 生成文件名         const filename = Date.now() + '_' + stream.filename;         // 返回文件路径         const filePath = `/${uplaodBasePath}${filename}`.replace(/\\/g, '/');         return {             uplaodBasePath,             filename,             filePath,             name: stream.filename         }     } }  module.exports = UploadService;

3、ant

 <Upload name="logo"                         {...upload}                         onChange={uploadOnChange}                         method="POST"                         multiple={false}                         action="/upload"                         data={UploadData}                         accept=".png,.jpg,.jpeg,.svg"                         listType="picture">                     {                         hasFileList ? '' :                             <Button>                                 <UploadOutlined/> 请选择背景图片                             </Button>                     }                 </Upload>