LayUI多文件上传,支持历史上传预览

记录一次项目开发中,LayUI多个图片进行优化,需要支持多个图片上传、可删除某一个图片、支持加载上次上次图片。

页面代码:

复制代码
   <div class="layui-upload">
                    <button type="button" class="layui-btn layui-btn-normal" id="ID-upload-demo-files">选择多文件</button>

                    <div class="layui-upload-list">
                        <table class="layui-table">
                            <colgroup>
                                <col style="min-width: 100px;">
                                <col width="100">
                                <col width="150">
                                <col width="260">
                                <col width="100">
                            </colgroup>
                            <thead>
                            <th>图片</th>
                            <th>文件名</th>
                            <th>大小</th>
                            <th>上传进度</th>
                            <th>操作</th>
                            </thead>
                            @*历史数据*@
                            <tbody id="ID-upload-pre-files-list">
                                @{
                                    var filelist = ViewData["UploadedList"] as List<MultiPics>;
                                    if (filelist != null && filelist.Count > 0)
                                    {
                                        foreach (var file in filelist)
                                        {
                                            <tr id="fileList@((filelist.IndexOf(file)+1).ToString())">
                                                <td>
                                                    <img src="@file.Content" class="tdPreImg">
                                                </td>
                                                <td>
                                                    <i class="del-img" id="@((filelist.IndexOf(file)+1).ToString())" data-src="@file.FilePath"></i>@file.FileName
                                                </td>
                                                <td>@file.FileSize KB</td>
                                                <td>已上传</td>
                                                <td>
                                                    @*因为layui按钮会提交,此处后台加载的图片,不用layui按钮*@
                                                    <input type="button" value="删除" class="btn_del" id="btn_del@((filelist.IndexOf(file)+1).ToString())" data-index="@((filelist.IndexOf(file)+1).ToString())" />
                                                </td>
                                            </tr>
                                        }
                                    }
                                }
                            </tbody>
                            @*当前上传*@
                            <tbody id="ID-upload-demo-files-list">
                            </tbody>
                        </table>
                    </div>

                    <button type="button" class="layui-btn" id="ID-upload-demo-files-action">开始上传</button>
                </div>

LayUI js 代码:

复制代码
 layui.use(function () {
            var upload = layui.upload;
            var element = layui.element;
            var $ = layui.$;
            var deliveryId = $("#LogID").val();

            // 制作多文件上传表格
            var uploadListIns = upload.render({
                elem: '#ID-upload-demo-files',
                elemList: $('#ID-upload-demo-files-list'), // 列表元素对象
                url: '/Ship/OrderInfo/UploadImages?id=' + deliveryId,
                accept: 'images',
                multiple: true,
                number: 10,
                exts: "png|jpg|jpeg",
                auto: false,
                bindAction: '#ID-upload-demo-files-action',
                choose: function (obj) {
                    var that = this;
                    // 将每次选择的文件追加到文件队列
                    var files = this.files = obj.pushFile();
                    // 读取本地文件
                    obj.preview(function (index, file, result) {
                        //console.log('choose' + index)
                        var tr = $(['<tr id="upload-' + index + '">',
                            '<td>'
                                + '<img src=\'' + result + '\' class=\'tdPreImg\'>'
                            + '</td>',

                            '<td>'
                            + '<i class="del-img" id="del-'+index+'" data-src=""></i>'
                            + file.name + '</td>',
                            '<td>' + (file.size / 1024).toFixed(1) + 'kb</td>',
                            '<td><div class="layui-progress" lay-filter="progress-demo-' + index + '">'
                            + '<div class="layui-progress-bar" lay-percent=""></div></div>'
                            + '</td>',

                            '<td>',

                            '<button class="layui-btn layui-btn-xs demo-reload layui-hide">重传</button>',
                            '<button class="layui-btn layui-btn-xs 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(); // 删除表格行
                            // 清空 input file 值,以免删除后出现同名文件不可选
                            uploadListIns.config.elem.next()[0].value = '';
                        });

                        that.elemList.append(tr);
                        element.render('progress'); // 渲染新加的进度条组件
                    });
                },
                done: function (res, index, upload) { // 成功的回调
                    //console.log('done' + index)

                    // 删除文件队列已经上传成功的文件【很重要防止之前的图片重复上传】
                    delete this.files[index];
                    var that = this;

                    var tr = that.elemList.find('tr#upload-' + index);
                    var tds = tr.children();
                    if (res.result) { //上传成功
                        $('#del-' + index).attr('data-src', res.data)

                        //清空操作
                        tds.eq(3).html('');
                        tds.eq(3).html('上传成功!');
                    }
                    else {
                        this.error(index, upload);
                        tds.eq(3).html('上传失败!');
                        //弹框显示错误信息
                        layer.msg("上传失败!" + res.msg);
                        //调试人员查看,暂时保留
                        console.log("上传失败!" + res.msg + "#" + res.data);
                    }
                },
                allDone: function (obj) { // 多文件上传完毕后的状态回调
                    console.log(obj);
                },
                error: function (index, upload) { // 错误回调

                    var that = this.elemList.find('tr#upload-' + index);
                    //console.log(that);
                    that.find(".demo-reload").removeClass('layui-hide');
                },
                progress: function (n, elem, e, index) {
                    element.progress('progress-demo-' + index, n + '%'); // 执行进度条。n 即为返回的进度百分比
                }
            });
        });

页面加载数据和提交表单js

复制代码
    var main = {
            @*初始化,静态js*@
            Init: function () {
                $(document).ready(function () {
                    @* Layui自带图片删除,历史图片的删除需特殊处理 *@
                    $(".btn_del").click(function () {
                        var _index = this.getAttribute("data-index");
                        var _tr = $("#fileList" + _index);
                        $("#ID-upload-pre-files-list")[0].removeChild(_tr[0]);
                    })
                });
            },
            @* 获取参数,前台不提交文件,后台绑定 *@
            SaveSignBack: function () {
                @*图片地址列表*@
                var _BackImage = "";
                @*发货日志*@
                var _ID = $("#LogID").val();
var _Note= $("#Note").val();

                //图片提取并限制数量
                var images_ids = $('.del-img');
                @*限制上传图片数量*@
                if (images_ids.length > 10) {
                    layer.msg("图片最多选择10张");
                    return false;
                }

                @*以|竖线分割,拼接字符串*@
                if (images_ids.length) {
                    var images = '';
                    $.each(images_ids, function (index, val) {
                        if (images == '') {
                            images += $(val).attr('data-src')
                        } else {
                            images += '|' + $(val).attr('data-src')
                        }
                    });
                    //$(data.form).append('<input name="images" type="hidden" value="' + images + '">');//插入表单

                    //图片参数赋值
                    _BackImage= images;
                }

                @*获取表单内容序列化*@
                //var fileForm = $("#form1").serialize();

                //上传了图片,直接修改
                if (_BackImage.length) {
                    main.FormSubmit(_LogID, _Note, _BackImage);
                }
                //未上传图片,弹框提示
                else {
                    $.messager.confirm("提示", "您未上传图片,确定提交吗?", function (data) {
                        //确定
                        if (data) {
                            main.FormSubmit(_LogID, _Note, _BackImage);
                            return;
                        }
                        //修改,不处理
                        else { }
                    });
                }
             },
            @* 提交后台 *@
            FormSubmit: function (_LogID, _Note, _BackImage) {
                $.post("/ControllerName/OrderInfo/BackSubmit",
                        {
                            LogID: _LogID,
                            Note: _Note,
                            Images: _BackImage
                        },
                        function (obj) {
                            if (obj.result) {
                                layer.msg(obj.msg);
                                //parent.refresh();
                                parent.location.reload();
                                parent.CloseWin();
                            }
                            else {
                                $.messager.alert('Info', obj.msg, 'info');
                            }
                        }
                    );
            },
        }

        $(function () {
            main.Init();
        })

后台C#上传代码,表单提交后台代码就不贴了

复制代码
    public ActionResult UploadImages(int ID = 0)
    {
            ////防止异常加载图片覆盖,延时半秒 SaveAs
            //System.Threading.Thread.Sleep(500);

            try
            {
                #region 数据校验
                //登录状态校验
                if (CurrentUser.Id == 0)
                {
                    return Json(new { result = false, msg = "登录失效!", data = "" });
                }

                //获取回签单图片列表
                HttpFileCollectionBase files = HttpContext.Request.Files;
                //图片非空校验
                if (files.Count == 0)
                {
                    return Json(new { result = false, msg = "上传失败!请上传回签单图片!", data = "" });
                }

                //单个图片轮询上传,只能单张上传
                if (files.Count > 1)
                {
                    return Json(new { result = false, msg = "参数错误!", data = "" });
                }
                #endregion

                //上传文件计数
                var successCount = 0;
                //图片相对路径(用于数据库保存)
                string FilePath = string.Empty;
                //循环保存图片,实际单个图片上传
                for (int i = 0; i < files.Count; i++)
                {
                    #region 拼接文件名(不含路径)
                    //文件类型
                    var fileType = string.Empty;
                    //获取文件类型
                    if (files[i].ContentType == "image/jpeg" || files[i].ContentType == "image/jpg")
                    {
                        fileType = ".jpg";
                    }
                    else if (files[i].ContentType == "image/png")
                    {
                        fileType = ".png";
                    }

                    // 生成随机4位数字
                    var rand = (new Random()).Next(1000, 10000).ToString();
                    //文件名
                    var _name = ID + "_" + CurrentUser.Id + "_" + DateTime.Now.ToString("yyMMddHHmmsss") + "_" + rand;
                    //拼接文件名 回签图片名称格式:发货日志Id_上传人_年月日_4位随机数
                    var book = _name + fileType;
                    #endregion

                    //获取配置文件的回签单保存路径 SignBackUrl
                    string savePath = System.Configuration.ConfigurationManager.AppSettings["FileUrl"];
                    //按月分文件夹
                    FilePath = DateTime.Now.ToString("yyyyMM") + "/" + book;
                    //文件完整路径
                    string fileFullPath = savePath + "/" + FilePath;

                    //没有文件夹则创建
                    if (!Directory.Exists(savePath + "/" + DateTime.Now.ToString("yyyyMM")))
                    {
                        Directory.CreateDirectory(savePath + "/" + DateTime.Now.ToString("yyyyMM"));
                    }

                    #region 文件大小校验
                    //保存图片到服务器上
                    files[i].SaveAs(fileFullPath);

                    //创建文件 获取文件大小
                    var fileInfo = new FileInfo(fileFullPath);
                    //获取文件大小,单位KB  1KB=1024byte(字节)
                    decimal fileSize = (decimal)(fileInfo.Length > 0 ? (fileInfo.Length / 1024) : 0);
                    //2MB转成KB
                    var _2mb = (decimal)2 * 1024;
                    //获取大小异常
                    if (fileSize == 0)
                    {
                        //计算文件大小异常
                        return Json(new { result = false, msg = "计算文件大小异常 !", data = FilePath });
                    }
                    else if (fileSize != 0 && fileSize > _2mb)
                    {
                        //文件大小超出2MB
                        return Json(new { result = false, msg = "文件大小超出2MB,请修改后重试 !", data = FilePath });
                    }
                    #endregion//累计成功计数
                    successCount++;
                }

                if (successCount == files.Count)
                {
                    //成功返回,回调图片地址列表(相对地址)
                    return Json(new { result = true, msg = "上传成功 !", data = FilePath });
                }
                else
                {
                    //失败
                    return Json(new { result = false, msg = "上传失败 !", data = "[上传文件数: " + successCount + "]" });
                }
            }
            catch (Exception ex)
            {
                //抛出异常
                return Json(new { result = false, msg = "上传异常,请重试 !", data = "[Exception: " + ex.Message + "]" });
            }
        }

上传图片时,出现上传图片名称和图片不能对应,数据串了问题。但是能想到可能是前一张图片没有保存,后面一张图片已经执行到保存方法,导致覆盖了。尝试了增加延时、后台记录id等一系列操作后,才发现是生成图片名称只到天。

后加了到秒并加了四位随机数,才得以解决。

Layui实际上是每上传一次图片,调用一次后台上传方法。

这里表格id " ID-upload-demo-files-list"是layui指定表格Id。已经上传的历史数据,不能用这个Id显示,单独加了一个tbody id="ID-upload-pre-files-list"用于显示已上传图片。需要删除,找到这行Dom移除即可。

提交表单

相关推荐
猫猫不是喵喵.3 天前
layui表单项次大数据量导入并提交
前端·javascript·layui
医疗信息化王工8 天前
基于ASP.NET Core的住院日志统计系统设计与实现
后端·layui·asp.net core·npoi·dapper
Purgatory00117 天前
layui select重新渲染
前端·layui
滴滴答答哒1 个月前
layui表格头部按钮 加入下拉选项
前端·javascript·layui
滴滴答答哒1 个月前
layui响应式表单上下结构
前端·javascript·layui
djk88881 个月前
支持手机屏幕的layui后台html模板
前端·html·layui
EQ-雪梨蛋花汤2 个月前
【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题
unity·layui·webgl
Southern Wind3 个月前
从零封装一套企业级表格组件库 - 基于 Layui 的实战教程
前端·javascript·layui·jquery
obDLaSfLKr3 个月前
探索之旅:基于.net 6 的多功能自用工具开发
layui
Southern Wind3 个月前
从零开始封装一个优雅的图片上传组件 - 二次改装 Layui-Upload 的教程(附完整封装代码)
前端·javascript·html·layui·css3