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="' + index + '">',
 '<td>'
 + '<img src=\'' + result + '\' class=\'tdPreImg\'>'
 + '</td>',
 '<td>'
 + '<i class="del-img" id="'+index+'" data-src=""></i>'
 + file.name + '</td>',
 '<td>' + (file.size / 1024).toFixed(1) + 'kb</td>',
 '<td><div class="layui-progress" lay-filter="progress-' + 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#' + index);
 var tds = tr.children();
 if (res.result) { //上传成功
 $('#' + 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#' + index);
 //console.log(that);
 that.find(".demo-reload").removeClass('layui-hide');
 },
 progress: function (n, elem, e, index) {
 element.progress('progress-' + 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移除即可。

提交表单

 

 

作者:打不死的小强^_^原文地址:https://www.cnblogs.com/youyoufei/p/17503694.html

%s 个评论

要回复文章请先登录注册