美文网首页程序员
WEUI文件上传详解

WEUI文件上传详解

作者: 丁俊杰_ | 来源:发表于2017-12-27 21:15 被阅读408次

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

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

微信weui官方文档

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

1、编写文件上传框Html

<div class="weui-cells__title">商品图片上传</div>
<div class="weui-cells weui-cells_form" id="uploader">
    <div class="weui-cell">
        <div class="weui-cell__bd">
            <div class="weui-uploader">
                <div class="weui-uploader__hd">
                    <p class="weui-uploader__title">图片列表</p>
                    <div class="weui-uploader__info">
                        <span id="uploadCount">0</span>/4
                    </div>
                </div>
                <div class="weui-uploader__bd">
                    <ul class="weui-uploader__files" id="uploaderFiles"></ul>
                    <div class="weui-uploader__input-box">
                        <input id="uploaderInput" class="weui-uploader__input" type="file"
                               accept="image/*" multiple="">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

把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、引用的第三方文件

<!--微信ui-->
<link rel="stylesheet" href="../static/lib/css/weui.min.css"/>
<link rel="stylesheet" href="../static/lib/css/jquery-weui.min.css"/>
<!--第三方库-->
<script type="text/javascript" src="../static/lib/weui.min.js"></script>
<script type="text/javascript" src="../static/lib/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="../static/lib/jquery-weui.min.js"></script>

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文件上传详解

    本文链接:https://www.haomeiwen.com/subject/ojdpgxtx.html