前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Egg中使用DiyUpload实现图片批量上传

Egg中使用DiyUpload实现图片批量上传

作者头像
越陌度阡
发布2020-11-26 11:33:10
1.3K0
发布2020-11-26 11:33:10
举报

1. 在HTML文件中引入需要的文件。

代码语言:javascript
复制
<!-- 引入批量上传的插件 -->
<link href="/public/admin/diyUpload/css/webuploader.css" rel="stylesheet" type="text/css" />
<link href="/public/admin/diyUpload/css/diyUpload.css" rel="stylesheet" type="text/css" />

<!-- 依赖于Jquery,如果在头文件中已经引入,此处可注释 -->
<!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> -->

<script src="/public/admin/diyUpload/js/webuploader.html5only.min.js" type="text/javascript"></script>
<script src="/public/admin/diyUpload/js/diyUpload.js" type="text/javascript"></script>

2. 在HTML文件中定义一个标签,指定插件要加载的位置,另外定义一个隐藏表单域,用于上传成功后保存返回的地址。

代码语言:javascript
复制
<div>
    <!-- 加载批量上传插件 -->
    <div id="photoLibrary"></div>
    <!-- 用隐藏表单域保存上传成功的图片地址,以便与其它数据一起提交 -->
    <div id="photoList"></div>
</div>

3. 在HTML文件中加载插件。

代码语言:javascript
复制
<script>

// 初始化批量上传插件
$(function () {
    let photoStr = "";
    $('#photoLibrary').diyUpload({
        // 上传的路由器地址
        url: '/admin/goods/goodsUploadPhoto',
        success: function (response) {
            // 将上传的址址放到临时的隐藏表单域中,与其它字段一起提交
            photoStr = '<input type="hidden" name="goods_image_list[]"  value="' + response.link + '"></input>';
            $('#photoList').append(photoStr);
        },
        error: function (data) {
            console.log(data);
        }
    })
})

</script>

4. 配置初始化插件中上传图片的地址。

代码语言:javascript
复制
// router.js

'use strict';

module.exports = app => {
    const { router, controller } = app;

    router.post('/admin/goods/goodsUploadPhoto',controller.admin.goods.goodsUploadPhoto);

};

5. 为插件上传图片的路由编写控制器。

代码语言:javascript
复制
// app/controller/admin/goods.js

'use strict';

const Fs = require('fs');
// cnpm i mz-modules --save
// 此模块解决上传卡死
const Pump = require('mz-modules/pump');

const Controller = require('egg').Controller;
class GoodsController extends Controller {

    // 编辑器的图片批量上传
    async goodsUploadPhoto() {
        // autoFields: true 表示除了文件的其它字段
        let parts = this.ctx.multipart({ autoFields: true });
        let files = {}, stream;
        // 循环获取数据流
        while ((stream = await parts()) != null) {
            if (!stream.filename) {
                // 多文件上传时,只能break,不能return
                break;
            }
            // 文件表单的name
            let fieldname = stream.fieldname;

            // 获取上传文件路径与入库保存路径
            let dir = await this.service.tools.getUploadFile(stream.filename);
            // 上传路径
            let target = dir.uploadDir;

            // 写入上传文件
            let writeStream = Fs.createWriteStream(target);
            await Pump(stream, writeStream);

            // 将多个上传图片统一拼接为一个对象,便于访问
            files = Object.assign(files, {
                [fieldname]: dir.saveDir
            });

            // 生成缩略图 target为图片地址
            this.service.tools.jimpImg(target);
        }

        // 返回的格式要按编辑器约定的格式
        this.ctx.body = {
            link: files.file
        }
    }


}
module.exports = GoodsController;

6. 控制器中调用服务中的getUploadFile方法。

代码语言:javascript
复制
// app/service/tools.js
'use strict';
const Path = require('path');
const Service = require('egg').Service;
 
 
// 引入格式化时间模块
// cnpm i silly-datetime --save
const Sd = require('silly-datetime');
 
// 引入模块智能生成上传文件夹
// cnpm i mz-modules --save
const Mkdirp = require('mz-modules/mkdirp');
 
 
// 引入生成缩略图的模块
// cnpm install jimp --save
// https://github.com/oliver-moran/jimp/tree/master/packages/jimp
const Jimp = require('jimp');
 
 
class ToolService extends Service {
 
    // 获取当前时间戳
    async getTime(){
        let now = new Date();
        return now.getTime();
    }
 
    // 处理要上传的文件名
    async getUploadFile(filename){
        // 获取当前日期
        let now = Sd.format(new Date(),'YYYYMMDD');
        // 创建文件目录(将存放地址与日期进行拼接);
        let dir = Path.join(this.config.uploadDir,now);
        // 按dir去创建文件夹,如果没有则生成,如果有则忽略
        await Mkdirp(dir);
 
        // 以时间戳命名文件
        let timestamp = await this.getTime();
 
        // 图片的保存路径(文件夹 + 时间戳 + 后辍名)
        let uploadDir = Path.join(dir,timestamp + Path.extname(filename));
 
        return{
            // 上传的地址
            uploadDir:uploadDir,
            // 保存在数据库的地址
            saveDir:uploadDir.slice(3).replace(/\\/g,'/')
        }
    }
 
 
    // 生成缩略图方法
    async jimpImg(target){
        Jimp.read(target, (err, lenna) => {
            if (err) throw err;
            // 生成200乘以200大小,品质为90,并重命名文件
            lenna.resize(200,200).quality(90).write(target+'_200x200'+Path.extname(target)); 
        })
 
    }
 
}
 
module.exports = ToolService;

7. 处理上传图片时,由于Egg安全验证机制导致无法上传的问题。

代码语言:javascript
复制
// config/config.default.js
'use strict';
module.exports = appInfo => {
    const config = exports = {};
    config.keys = appInfo.name + '_1585450669767_9677';
    config.session = {
        key: 'SESSION_ID',
        maxAge: 8640000,
        httpOnly: true,
        encrypt: true,
        renew: true
    }

    // 上传文件存放的全局地址
    config.uploadDir = 'app/public/admin/upload';

    // 上传文件的配置
    // https://github.com/eggjs/egg-multipart
    config.multipart = {
        // 允许上传的图片格式
        whitelist: ['.png', '.jpg', '.jpeg'],
        // 文件允许大小
        fileSize: '50mb',
        // 上传字段的数量
        fields: '50'
    }


    // 处理编辑器上传图片的安全验证机制
    exports.security = {
        csrf: {
            // 为指定的URL忽略csrf验证
            ignore: ctx => { 
                if ( ctx.request.url == '/admin/goods/goodsUploadPhoto') { 
                    return true; 
                } 
                return false; 
            },
        }
    }

    return config

};

8. 解决上传按钮无法点击的问题

代码语言:javascript
复制
#photoLibrary div:nth-child(2) {
    width: 100%!important;
    height: 100%!important;
}

注意:#photoLibrary即为载插件标签的ID。

9. 上传效果图

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档