WEUI文件上传详解

本文通过我个人设计的系统为案例来教会读者使用weui的uploader,先来看看效果图:

图片上传框

PC端

移动端

首先,微信的官方文档不会一步一步教会你怎么用,但是在其中能发现很多使用的细节,推荐看一下,遇到问题可以找到解决方法:

微信weui官方文档

下面,通过我系统的案例让大家一步步了解如何使用weui的uploader:

1、编写文件上传框Html

商品图片上传

图片列表

0/4

    把div块放到你想要的位置,着重关注带id的标签,之后的上传相关的js代码中都会有使用到!!!

    2、编写图片上传的js代码

    /* *
     * 图片上传
     * */
    var uploadCount = 0,  //上传图片的数量
        uploadList = [],  //上传的图片
        uploadSuccessCount = 0;  //上传成功的数量
    var uploadCountDom = document.getElementById("uploadCount");
    weui.uploader('#uploader', {
        url: 'img-api/upload_imgs',  //你要上传的url地址
        auto: true,
        type: 'file',
        fileVal: 'fileVal',  //文件上传域的name,后台通过该name拿到传输的文件
        compress: {
            width: 1600,
            height: 1600,
            quality: .8
        },
        onBeforeQueued: function onBeforeQueued(files) {
            //上传前,对上传的情况做以下多个判断,保证合法性,可自行删改
            if (["image/jpg", "image/jpeg", "image/png", "image/gif"].indexOf(this.type) < 0) {
                weui.alert('请上传图片');
                return false;
            }
            if (this.size > 5 * 1024 * 1024) {
                weui.alert('请上传不超过5M的图片');
                return false;
            }
            if (files.length > 4) {
                //防止一下子选中过多文件
                weui.alert('最多只能上传4张图片,请重新选择');
                return false;
            }
            if (uploadCount + 1 > 4) {
                weui.alert('最多只能上传4张图片');
                return false;
            }
            if (localStorage.userId == undefined) {
                weui.alert('请先登录!');
                return false;
            }
    
            ++uploadCount;
            uploadCountDom.innerHTML = uploadCount;
        },
        onQueued: function onQueued() {
            uploadList.push(this);
            //手动上传,如果不想选择完图片自动上传可以通过此方法改为手动不过上面的auto要改为false
            /*var self = this;
            $('#preview_confirm').on('click',function(){
                self.upload();
            });*/
        },
        onBeforeSend: function onBeforeSend(data, headers) {
            $("#submit_order").addClass("weui-btn_disabled");
            //return false; //阻止文件上传
        },
        onProgress: function onProgress(procent) {
            //console.log(this, procent);
        },
        onSuccess: function onSuccess(ret) {
            if (ret.result == true) {
                uploadSuccessCount++;
                if (uploadSuccessCount == uploadCount) {
                    //判断上传是否全部成功
                    $("#submit_order").removeClass("weui-btn_disabled");
                }
            }
            var uploadID = this.id;
            $("#uploaderFiles li").each(function () {
                if ($(this).attr("data-id") == uploadID) {
                    $(this).attr("DB-id", ret.DBId);  //图片后台对应的唯一编号
                    $(this).attr("url", ret.url);  //图片存放地址
                }
            });
            //console.log(this, ret);
        },
        onError: function onError(err) {
            console.log(this, err);
        }
    });
    

    关键的地方我都通过注释标注了出来,上面的重点就是在从id为uploaderFiles的ul标签中找到新加入的li标签,这里面存放着上传的图片信息,给其加上编号和地址两个属性方便后续预览或删除

    3、编写缩略图预览js代码

    /* *
     * 缩略图预览
     * */
    document.querySelector('#uploaderFiles').addEventListener('click', function (e) {
        var target = e.target;
    
        while (!target.classList.contains('weui-uploader__file') && target) {
            target = target.parentNode;
        }
        if (!target) return;
    
        //从图片对应的li标签中获得所需属性
        var url = target.getAttribute('url');  //图片存放地址
        var DBId = target.getAttribute('db-id');  //图片唯一编号
        var id = target.getAttribute('data-id');  //点击图片对应的id
    
        var gallery = weui.gallery(url, {
            className: 'custom-name',
            onDelete: function () {
                //删除图片的回调
                var isDelete = confirm('确定删除该图片?');
                if (isDelete) {
                    --uploadCount;
                    uploadCountDom.innerHTML = uploadCount;  //处理角标
                    for (var i = 0, len = uploadList.length; i < len; ++i) {
                        var file = uploadList[i];
                        if (file.id == id) {
                            $("#uploaderFiles li").each(function () {
                                //找到对应的li标签,请求后台删除文件
                                if ($(this).attr("data-id") == id) {
                                    var param = {};
                                    param.DBId = DBId;
                                    param.imgUrl = url;
                                    $.ajax({
                                        url: "img-api/delete_imgs",
                                        type: "delete",
                                        contentType: "application/json;charset=UTF-8",
                                        dataType: "json",
                                        data: JSON.stringify(param),
                                        success: function (msg) {
                                            console.log(msg);
                                        },
                                        error: function (xhr, textstatus, thrown) {
    
                                        }
                                    });
                                }
                            });
                            file.stop();
                            break;
                        }
                    }
                    target.remove();
                    gallery.hide();
                }
            }
        });
    });
    

    这部分代码比较统一,需要修改的可能就是请求后台删除图片部分

    4、引用的第三方文件

    
    
    
    
    
    
    
    

    5、后台图片文件操作

    我使用flask编写的项目,但是大致思路是一样的,放出来大家参考一下:

    class uploadImgs(Resource):
        def post(self):
            if request.method == 'POST':
                # 获得post过来的图片
                file = request.files['fileVal']
                # 判断是否是图片
                if file and file.filename.rsplit('.', 1)[1] in config.ALLOWED_EXTENSIONS:
                    # 将名字命名为唯一的
                    DBId = self.create_uid()
                    filename = secure_filename(file.filename)
                    filename = DBId + "." + filename.split(".")[1]
                    # 将文件存储到指定位置
                    base_path = path.abspath(path.dirname(__file__))
                    upload_path = path.join(base_path, config.UPLOAD_FOLDER)
                    file.save(upload_path + filename)
                    # 定时4个小时后清除没有下单但上传的图片
                    Timer(14400, self.operateImgs, (base_path, upload_path, filename)).start()
    
                    res_data = {'result': True, 'url': config.UPLOAD_FOLDER + filename,
                                'DBId': DBId}
                    return res_data
    
        def create_uid(self):
            return str(uuid.uuid1())
        
        # 这部分仅仅是一个初步的思路,还没进行优化,不建议参考
        def operateImgs(self, basePath, uploadPath, fileName):
            # 删除上传的文件
            os.remove(uploadPath + fileName)
            # 如果成功下单了,去临时文件夹拷贝图片回来,并删除临时图片
            if (os.path.exists(path.join(basePath, TEMP_UPLOAD_FOLDER + fileName))):
                shutil.copyfile(path.join(basePath, TEMP_UPLOAD_FOLDER + fileName), uploadPath + fileName)
                os.remove(path.join(basePath, TEMP_UPLOAD_FOLDER + fileName))
                return
    
    
    class getImgs(Resource):
        def get(self, filename):
            base_path = path.abspath(path.dirname(__file__))
            upload_path = path.join(base_path, config.UPLOAD_FOLDER)
            return send_from_directory(upload_path,
                                       filename)
    
    
    class deleteImgs(Resource):
        def delete(self):
            data = request.get_json()
            base_path = path.abspath(path.dirname(__file__))
            upload_file = path.join(base_path, data['imgUrl'])
            if os.path.exists(upload_file):
                os.remove(upload_file)
                return True
            else:
                return False
    

    上传图片的方法中,通过唯一的编号给图片文件命名,存放在指定的目录中,这样子无论是在删除还是预览中都比较方便。但是这里有个问题,由于是自动上传,图片会一直自动累积在后台中,包括一些无效的图片,所以采用定时的方法检测无效的图片并删除(无效是相对的,具体看你项目里怎么定义,我的项目里就是没下单的但上传的图片),方法比较粗暴,望各位指导。

    图片预览和删除就比较简单了,不在赘述。

    至此weui的uploader讲解完毕。

    github传送地址:https://github.com/JunJieDing666/YouZhiGou

    若有错误烦请指出,有地方不理解欢迎讨论。

    你可能感兴趣的:(WEUI文件上传详解)