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

  • LayUI多文件上传,支持历史上传预览已关闭评论
  • 91 次浏览
  • A+
所属分类:Web前端
摘要

记录一次项目开发中,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移除即可。

提交表单

 

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