多文件上传

在这里插入图片描述
一般的上传空间的原理都是使用input type='file’的h5元素实现的,那这个layui的原理也是如此。

每次点击选择文件按钮,控件自动生成一个input,将文件选择,选择后将其files中的属性提取出文件名,大小等信息,关于files可看这篇文章。选择的文件可以累加,文件的files都会保存在构造函数内部

https://blog.csdn.net/qq_41129811/article/details/87890242

上传时它将所有的files循环,每次上传时就给input赋值一个files[i],并请求,所以会出现多次请求。

将这些信息写入table中用户展示。删除按钮也只是对dom操作而已。

需要注意的是提交文件时,选中多少个文件他就会请求后台处理保存多少次,每次只提交一个文件,这是各个控件都没办法的事。
在这里插入图片描述
选择三个文件就请求三次,这样对于其他文本信息只需要传一次就极为不友好了。

解决办法是先传文本信息,保存文本信息后返回新建的id在回调触发文件上传

具体代码:

html:

<div class="row">
                            <div class="layui-upload-list col-sm-12">
                                <table class="layui-table">
                                    <thead>
                                    <tr>
                                        <th>文件名</th>
                                        <th>大小</th>
                                        <th>状态</th>
                                        <th>操作</th>
                                    </tr>
                                    </thead>
                                    <tbody id="demoList"></tbody>
                                </table>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal" onclick="window.location.reload()">关闭
                            </button>
                            <button type="button" class="btn btn-primary" id="testListAction" onclick="saveActivity()">
                                确定
                            </button>
                            <button type="button" class="btn btn-primary" id="testListAction1" style="display:none">
                                确定
                            </button>
                        </div>

先初始化upload控件

layui.use('upload', function () {
    var $ = layui.jquery
        , upload = layui.upload;
    //多文件列表示例
    var demoListView = $('#demoList')  //文件列表显示的元素
        , uploadListIns = upload.render({
        elem: '#testList'  //触发选择文件弹出的按钮
        , url: '/it/orderManage/saveActivityAttachment'
        , accept: 'file'   //后台接收的文件参数名
        , multiple: true   //是否可以上传多个文件
        , auto: false    //是否自动上传,一般是选false和bindAction配合使用
        , bindAction: '#testListAction1'   //触发上传文件的按钮
        ,number:0   //限制上传的个数,0为不限制
        , before: function (obj) { //obj参数包含的信息,跟 choose回调完全一致。其中输入向后台传输的参数
            this.data = {
                'TID': TID
            };
        }
        , choose: function (obj) {
            var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
            //读取本地文件
            obj.preview(function (index, file, result) {
                var tr = $(['<tr id="upload-' + index + '">'
                    , '<td>' + file.name + '</td>'
                    , '<td>' + (file.size / 1014).toFixed(1) + 'kb</td>'
                    , '<td>等待上传</td>'
                    , '<td>'
                    , '<button class="layui-btn layui-btn-mini demo-reload layui-hide">重传</button>'
                    , '<button class="layui-btn layui-btn-mini layui-btn-danger demo-delete">删除</button>'
                    , '</td>'
                    , '</tr>'].join(''));
 
                //单个重传
                tr.find('.demo-reload').on('click', function () {
                    obj.upload(index, file);
                });
 
                //删除
                tr.find('.demo-delete').on('click', function () {
                    delete files[index]; //删除对应的文件
                    tr.remove();
                    uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
                });
                demoListView.append(tr);
            });
        }
        , done: function (res, index, upload) {  //每个文件上传完成后的回调
            if (res.success) { //上传成功
             var tr = demoListView.find('tr#upload-' + index)
             , tds = tr.children();
             tds.eq(2).html('<span style="color: #5FB878;">上传成功</span>');
             tds.eq(3).html(''); //清空操作
             return delete this.files[index]; //删除文件队列已经上传成功的文件
 
             } else {
             layer.alert(res.msg);
             }
        },
        allDone: function (res, index, upload) {  //所有文件上传完成后的回调
            layer.alert("上传成功",function(){
                layer.closeAll()
                $("#trainInfoModal").modal("hide");
                $('#orderTable').bootstrapTable("refresh");
                $("#trainInfoModal input").val("");
                $("#trainInfoModal textarea").val("");
            })
            /*this.error(index, upload);*/
        }
        , error: function (index, upload) {
            var tr = demoListView.find('tr#upload-' + index)
                , tds = tr.children();
            tds.eq(2).html('<span style="color: #FF5722;">上传失败</span>');
            tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //显示重传
        }
    });
});

然后先上传其他信息,再通过js控制按钮触发的方式回调传文件

function saveActivity(){
    var flag=true;
    $('#form1 .form-control:not(".banner,#file1")').each(function () {
        //console.log($(this).attr("id"))
        if($(this).val()==""||$(this).val()==null){
            layer.alert("请填写完整信息");
            flag=false;
        }
        if($("#endtime").val()<$("#starttime").val()){
            layer.alert("结束时间未大于开始时间");
            flag=false;
        }
    })
    if($(".layui-table tbody").html()==""){
        layer.alert("请选择附件");
        flag=false;
    }
    if(flag){
        var formData = new FormData($("#form1")[0]);
        $.ajax({
            url : "/it/orderManage/saveActivity",
            type : 'POST',
            data : formData,
            // 告诉jQuery不要去处理发送的数据
            processData : false,
            // 告诉jQuery不要去设置Content-Type请求头
            contentType : false,
            async : true,
            success : function(ret) {
                //alert("上传成功")
                TID=ret
                $("#testListAction1").trigger("click");  //触发上传文件
            }
        });
    }
}

java部分

//保存文字信息并返回创建的id
    @RequestMapping(value = "/saveActivity", method = RequestMethod.POST, produces = "text/html;charset=utf-8")
    @ResponseBody
    public String saveActivity(@RequestParam Map<String,String> param,
                               String TID,
                               HttpServletRequest req) {
        RetBase ret = new RetBase();
        Map<String, String> p = new HashMap<String, String>();
        try {
           
                orderManageService.updateTrainActivity(param);
                param.put("T_PACKAGE_CODE", TID);
                p.put("TID", TID);
                return TID;
              
           
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSON.toJSONString(ret);
    }
 
    //保存文件
    @RequestMapping(value = "/saveActivityAttachment", method = RequestMethod.POST, produces = "text/html;charset=utf-8")
    @ResponseBody
    public String saveActivityAttachment(@RequestParam Map<String,String> param,
                                         MultipartFile file,
                                         String TID,
                                         HttpServletRequest req) {
        RetBase ret = new RetBase();
        // String path = orderManageService.getPath("banner");
        String path1 = orderManageService.getPath("attachmentPath");
        Map<String, String> p = new HashMap<String, String>();
        p.put("descript", "");
        try {
            if (TID != null && !TID.equals("")) {
                p.put("TID",TID);
                // orderManageService.removeAttachment(param);
                Map<String, String> name = uploadFile(file, path1, req);
                p.put("attachmentUrl", path1 + name.get("saveName"));
                p.put("attachmentName", name.get("oriName"));
                p.put("fileType", name.get("fileType"));
                orderManageService.saveTrainAttachment(p);
                ret.setSuccess(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
            ret.setSuccess(false);
        }
        return JSON.toJSONString(ret);
    }
 
 
public Map<String, String> uploadFile(MultipartFile file, String path, HttpServletRequest request) throws IOException {
        String fileName = file.getOriginalFilename();
        //  String basepath=request.getSession().getServletContext().getRealPath("/");
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
//        File tempFile = new File(path, new Date().getTime() + String.valueOf(fileName));
        String saveName = String.valueOf((new Date()).getTime()) + String.valueOf((int) (Math.random() * 9 + 1) * 1000) + '.' + fileType;
        File tempFile = new File(path, String.valueOf(saveName));
        if (!tempFile.getParentFile().exists()) {
            tempFile.getParentFile().mkdir();
        }
        if (!tempFile.exists()) {
            tempFile.createNewFile();
        }
        file.transferTo(tempFile);
        Map<String, String> map = new HashMap<String, String>();
        map.put("oriName", fileName);
        map.put("saveName", saveName);
        map.put("fileType", fileType);
        // return tempFile.getName();
        return map;
    }

关于在mybatis中怎么将刚插入创建生成的新id返回,可以参考这篇博文

总之后台最好把其他信息还文件信息分开接收,接收文件不需要使用MultipartFile数组,因为一次只传一个