图片上传组件webuploader

前端组件webuploader

 

当时也是搞了很久参考这种demo,但是没记、现在事后大致总结下。直接上大概代码(我使用asp.net  MVC来做的):

执行顺序:(get)Record/Add——Add.cshtml页面,点击确认上传执行上传图片,可多选——(post)Photo/UploadPhotos,完成图片上传。多图分别执行post接口上传、1张图失败可能不会有提示;返回图片url保存在页面的隐藏字段内——(post)Record/Add保存整个实体信息,图片url解析(用|或;)保存

 1    public ActionResult Add()
 2         {
 3             return View();
 4         }
 5 
 6         [HttpPost]
 7         public JsonResult Add(string key1, string key2, string photoUrlSplits, int typeId = 1, string remark = "")
 8         {
 9             if (key1.IsNullOrWhiteSpace() || photoUrlSplits.IsNullOrWhiteSpace() || photoUrlSplits.Length < 3)
10                 return Json(new BaseResponse(ApiCodeEnum.ParamError.GetHashCode(), "参数错误"));
11 
12             var photoUrls = photoUrlSplits.Trim(';').Split(';').ToList();
13             _service.SaveRecord(CurrentUser, key1, key2, photoUrls, typeId, remark);
14             return Json(new BaseResponse());
15         }
View Code
 1 public class PhotoController : BaseControllerWithUser
 2     {
 3         private readonly PhotoService _service = new PhotoService();
 4         
 5         static string urlPath = string.Empty;
 6 
 7         public PhotoController() 
 8         {
 9             var applicationPath = VirtualPathUtility.ToAbsolute("~") == "/" ? "" : VirtualPathUtility.ToAbsolute("~");
10             urlPath = applicationPath + "/Upload";
11         }
12 
13         public JsonResult UploadPhotos(string id, string name, string type, string lastModifiedDate, int size, HttpPostedFileBase file)
14         {
15             string filePathName = string.Empty;
16 
17             string localPath = Path.Combine(HttpRuntime.AppDomainAppPath, "Upload");
18             if (Request.Files.Count == 0)
19             {
20                 return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" });
21             }
22 
23             string ex = Path.GetExtension(file.FileName);
24             filePathName = Guid.NewGuid().ToString("N") + ex;
25             if (!System.IO.Directory.Exists(localPath))
26             {
27                 System.IO.Directory.CreateDirectory(localPath);
28             }
29             file.SaveAs(Path.Combine(localPath, filePathName));
30 
31             return Json(new
32             {
33                 jsonrpc = "2.0",
34                 id = id,
35                 filePath = urlPath + "/" + filePathName
36             });
37 
38             //_service.UploadPhotos();
39             //return Json("");
40         }
41 
42     }
View Code

前端页面代码:

  1 @using OuymxPhotoRecordSystem.Web.Service
  2 @{
  3     Layout = null;
  4 }
  5 
  6 <!DOCTYPE html>
  7 <html>
  8 <head>
  9     <meta name="viewport" content="width=device-width" />
 10     <title>上传图片数据</title>
 11     @*<script src="../../js/plugins/jQuery/jquery-2.2.3.min.js"></script>*@
 12     <script src="/Scripts/jquery-1.8.2.min.js"></script>
 13     <link href="/CSS/webuploader.css" rel="stylesheet" />
 14     <script src="/Scripts/webuploader.js"></script>
 15     <link href="/CSS/bootstrap.min.css" rel="stylesheet" />
 16     <link href="/CSS/style.css" rel="stylesheet" />
 17     <link href="/CSS/demo.css" rel="stylesheet" />
 18     <link href="/CSS/font-awesome.css" rel="stylesheet" />
 19 
 20     <script src="/js/plugins/layer/layer.js"></script>
 21 </head>
 22 <body>
 23     @using (Html.BeginForm("Add", "Record", FormMethod.Post))
 24     {
 25     <table class="tc_table_cp" border="0">
 26         <tr>
 27             <td width="104">图片上传</td>
 28             <td colspan="3">
 29                 <div id="fileList">
 30                     
 31                 </div>
 32                 <div class="cp_img_jia" id="filePicker"></div>
 33                 <input id="photoUrlSplits" name="photoUrlSplits" type="hidden" value="" />
 34                 <button id="ctlBtn" class="btn btn-default">开始上传</button>
 35             </td>
 36         </tr>
 37         @*空的行,主要为了显示上传失败的文字提醒*@
 38         <tr>
 39             <td width="104"></td>
 40             <td colspan="3">
 41             </td>
 42         </tr>
 43         @*上传按钮和隐藏控件移到前面去了*@
 44         @*<tr>
 45             <td width="104"></td>
 46             <td colspan="3">
 47                 <input id="photoUrlSplits" name="photoUrlSplits" type="hidden" value="" />
 48                 <button id="ctlBtn" class="btn btn-default">开始上传</button>
 49             </td>
 50         </tr>*@
 51         <tr>
 52             <td>主键1</td>
 53             <td>@Html.TextBox("key1")</td>
 54         </tr>
 55         <tr>
 56             <td>主键2</td>
 57             <td>@Html.TextBox("key2")</td>
 58         </tr>
 59         <tr>
 60             <td>类型</td>
 61             <td>@Html.DropDownList("typeId", WebMvcHelper.GetPhotoTypes())</td>
 62         </tr>
 63         <tr>
 64             <td>备注</td>
 65             <td>@Html.TextBox("remark")</td>
 66         </tr>
 67         <tr>
 68             <td></td>
 69             <td>
 70                 <input id="btnSubmit" type="submit" style="width: 120px;" value="提交保存" disabled="disabled" title="先上传图片后才能提交保存"/>
 71             </td>
 72         </tr>
 73     </table>
 74     }
 75 </body>
 76 </html>
 77 
 78 <script type="text/javascript">
 79 
 80     $("#btnSubmit").click(function (event) {
 81         event.preventDefault();
 82 
 83         var photoUrlSplits = $('#photoUrlSplits').val();
 84         var key1 = $('#key1').val();
 85         if (photoUrlSplits == null || photoUrlSplits.length <= 3 || key1 == null || key1 == '') {
 86             layer.msg('保存失败,原因:主键不得为空,待上传图片不得为空', { icon: 2, time: 0, closeBtn: 1 }, function () {
 87                 //no-op
 88             });
 89             return;
 90         }
 91         $.ajax({
 92             type: 'POST',
 93             url: '@Url.Action("Add")',
 94             data: { 'photoUrlSplits': photoUrlSplits, 'key1': key1, 'key2': $('#key2').val(), 'typeId': $("#typeId").val(), 'remark': $('#remark').val(), },
 95                 success: function (data) {
 96                     if (data.code == 0) {
 97                         layer.msg('保存成功', { icon: 1, time: 1000 }, function () {
 98                             parent.layer.closeAll();    //成功则关闭自身layer
 99                             //window.parent.location.reload();  //无需执行,因为Index父页面已定义关闭本layer时自动执行
100                         });
101                     }
102                     else {
103                         layer.msg('保存失败,原因:' + data.message, { icon: 2, time: 0, closeBtn: 1 }, function () {
104                             //no-op
105                         });
106                     }
107                 },
108                 dataType: 'json'
109          });
110     });
111 
112     var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../";
113     $(function () {
114         var $ = jQuery,
115         $list = $('#fileList'),
116         // 优化retina, 在retina下这个值是2
117         ratio = window.devicePixelRatio || 1,
118         // 缩略图大小
119         thumbnailWidth = 90 * ratio,
120         thumbnailHeight = 90 * ratio,
121         // Web Uploader实例
122         uploader;
123         uploader = WebUploader.create({
124             // 选完文件后,是否自动上传。
125             auto: false,
126             disableGlobalDnd: true,
127             // swf文件路径
128             swf: applicationPath + '/Script/Uploader.swf',
129             // 文件接收服务端。
130             server: applicationPath + '/Photo/UploadPhotos',
131             // 选择文件的按钮。可选。
132             // 内部根据当前运行是创建,可能是input元素,也可能是flash.
133             pick: '#filePicker',
134             //只允许选择图片
135             accept: {
136                 title: 'Images',
137                 extensions: 'gif,jpg,jpeg,bmp,png',
138                 mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp'
139             }
140         });
141        
142         // 当有文件添加进来的时候
143         uploader.on('fileQueued', function (file) {
144             var $li = $(
145                     '<div id="' + file.id + '" class="cp_img">' +
146                         '<img>' +
147                     '<div class="cp_img_jian"></div></div>'
148                     ),
149                 $img = $li.find('img');
150             // $list为容器jQuery实例
151             $list.append($li);
152             // 创建缩略图
153             // 如果为非图片文件,可以不用调用此方法。
154             // thumbnailWidth x thumbnailHeight 为 100 x 100
155             uploader.makeThumb(file, function (error, src) {
156                 if (error) {
157                     $img.replaceWith('<span>不能预览</span>');
158                     return;
159                 }
160 
161                 $img.attr('src', src);
162             }, thumbnailWidth, thumbnailHeight);
163         });
164 
165         // 文件上传过程中创建进度条实时显示。
166         uploader.on('uploadProgress', function (file, percentage) {
167             var $li = $('#' + file.id),
168                 $percent = $li.find('.progress span');
169 
170             // 避免重复创建
171             if (!$percent.length) {
172                 $percent = $('<p class="progress"><span></span></p>')
173                         .appendTo($li)
174                         .find('span');
175             }
176 
177             $percent.css('width', percentage * 100 + '%');
178         });
179 
180         // 文件上传成功,给item添加成功class, 用样式标记上传成功。
181         uploader.on('uploadSuccess', function (file, response) {
182             $('#' + file.id).addClass('upload-state-done');
183             $("#photoUrlSplits").val($("#photoUrlSplits").val() + response.filePath + ";");//"/Upload/9bd17b72a61043cf857fb112df3c3cf1.png"
184             //alert("uploadSuccess");
185         });
186 
187         // 文件上传失败,显示上传出错。
188         uploader.on('uploadError', function (file) {
189             var $li = $('#' + file.id),
190                 $error = $li.find('div.error');
191 
192             // 避免重复创建
193             if (!$error.length) {
194                 $error = $('<div class="error"></div>').appendTo($li);
195             }
196             $error.text('上传失败');
197         });
198 
199         // 完成上传完了,成功或者失败,先删除进度条。
200         uploader.on('uploadComplete', function (file) {
201             $('#' + file.id).find('.progress').remove();
202             //alert("uploadComplete");
203         });
204 
205         //所有文件上传完毕
206         uploader.on("uploadFinished", function ()
207         {
208            //提交表单
209             //alert("uploadFinished");
210             
211             if ($("div.error").length > 0) {
212                 $("#btnSubmit").attr("disabled");
213                 //alert("部分文件上传失败,可能是文件过大或文件格式不正确。请排查或咨询管理员!");
214                 layer.msg("部分文件上传失败,可能是文件过大或文件格式不正确。请排查或咨询管理员!", { icon: 2, time: 0, closeBtn: 1 });
215             }
216             else {
217                 $("#btnSubmit").removeAttr("disabled");
218                 //alert("所有文件上传完毕,请检查是否有错误,若全部正确请提交");
219 
220                 layer.msg("所有文件上传完毕,请检查是否有错误,若全部正确请提交!", { icon: 1, time: 4000, closeBtn: 1 });
221             }
222         });
223 
224         //开始上传
225         $("#ctlBtn").click(function () {
226             uploader.upload();
227 
228             event.preventDefault();
229         });
230         //以下方法原计划实现:鼠标移上去显示删除按钮,移出则不显示。原demo的live代码可实现、但live在jq1.9已被删除、新的on()做不到对未来元素、指定某未来元素的控制。而本AdminLTEd需要需要jq2.2
231         //
232         //1.
233         //$(document).on("mouseover", ".cp_img_jian", function () {
234         //    //此处的$(this)指$( "#testDiv"),而非$(document) 
235         //    $(this).show();
236         //});
237 
238         //2.
239         //$(document).on("mouseout", ".cp_img_jian", function () {
240         //    //此处的$(this)指$( "#testDiv"),而非$(document) 
241         //    $(this).hide();
242         //});
243 
244         //3.
245         //$('#fileList').on('mouseover', function (e) {
246         //    $('.cp_img_jian').show();
247         //});
248         //$('#fileList').on('mouseout', function (e) {
249         //    $('.cp_img_jian').hide();
250         //});
251 
252         //4.
253         //$(".cp_img").mouseover(function () {
254         //    alert("mouseover");
255         //});
256         //$(".cp_img").mouseout(function () {
257         //    alert("mouseout");
258         //});
259 
260         //5.
261         //显示删除按钮
262         $(".cp_img").live("mouseover", function ()
263         {
264             $(this).children(".cp_img_jian").css('display', 'block');
265         });
266         //隐藏删除按钮
267         $(".cp_img").live("mouseout", function () {
268             $(this).children(".cp_img_jian").css('display', 'none');
269         });
270         //执行删除方法
271         $list.on("click", ".cp_img_jian", function ()
272         {
273             var Id = $(this).parent().attr("id");
274             uploader.removeFile(uploader.getFile(Id,true));
275             $(this).parent().remove();
276         });
277       
278     });
279 
280 </script>
View Code

效果图:

 

不足(都不是大问题):

1.图片是单个单个上传的、没有分片,可能会速度慢

2.单个图片失败可能会没有提示

3.仅在点击“上传图片”后可定点删除图片,不能在点击“上传图片”前删除。不过这个不是重点问题不大

posted on 2018-12-19 13:46  nlh774  阅读(906)  评论(0编辑  收藏  举报