1. 程式人生 > >圖片上傳元件webuploader

圖片上傳元件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.僅在點選“上傳圖片”後可定點刪除圖片,不能在點選“上傳圖片”前刪除。不過這個不是重點問題不大