Authored by 陈峰

完成商品缓存清理功能

@@ -20,6 +20,7 @@ class ProductCache extends Model{ @@ -20,6 +20,7 @@ class ProductCache extends Model{
20 return; 20 return;
21 } 21 }
22 let url = apis[0].priceCacheApi; 22 let url = apis[0].priceCacheApi;
  23 + self._broadcast(`开始提交:批量变价`);
23 await self._batchPost(list, url); 24 await self._batchPost(list, url);
24 } 25 }
25 async removeProductCache(list) { 26 async removeProductCache(list) {
@@ -30,6 +31,7 @@ class ProductCache extends Model{ @@ -30,6 +31,7 @@ class ProductCache extends Model{
30 return; 31 return;
31 } 32 }
32 let url = apis[0].productCacheApi; 33 let url = apis[0].productCacheApi;
  34 + self._broadcast(`开始提交:其它批量`);
33 await self._batchPost(list, url); 35 await self._batchPost(list, url);
34 } 36 }
35 async _batchPost(list, url) { 37 async _batchPost(list, url) {
@@ -51,6 +53,7 @@ class ProductCache extends Model{ @@ -51,6 +53,7 @@ class ProductCache extends Model{
51 await post(++i, tick); 53 await post(++i, tick);
52 }, 500); 54 }, 500);
53 } else { 55 } else {
  56 + self._broadcast(`提交完成!`);
54 resolve(); 57 resolve();
55 } 58 }
56 } 59 }
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 'use strict'; 7 'use strict';
8 8
9 import Router from 'koa-router'; 9 import Router from 'koa-router';
  10 +import xlsx from 'node-xlsx';
  11 +import fs from 'fs';
10 import { 12 import {
11 ProductCache 13 ProductCache
12 } from '../../models' 14 } from '../../models'
@@ -18,13 +20,32 @@ const productCache = { @@ -18,13 +20,32 @@ const productCache = {
18 await ctx.render('action/product_cache'); 20 await ctx.render('action/product_cache');
19 }, 21 },
20 async clear(ctx) { 22 async clear(ctx) {
  23 + let excelFile = ctx.request.body._files && ctx.request.body._files.excelFile;
21 let type = ctx.request.body.type; 24 let type = ctx.request.body.type;
22 - if (type) {  
23 - ProductCache.removePriceCache([51068877, 51068893, 51117073]) 25 + if (excelFile && type) {
  26 + let sheets = xlsx.parse(fs.readFileSync(excelFile.path));
  27 + if (sheets.length) {
  28 + let rows = sheets[0].data;
  29 + if (rows.length > 1) {
  30 + let data = [];
  31 + for (var i = 1; i < rows.length; i++) {
  32 + var row = rows[i];
  33 + if (row.length) {
  34 + data.push(row[0]);
  35 + }
  36 + }
  37 + if (type === '1') {
  38 + ProductCache.removePriceCache(data)
  39 + } else if (type === '2') {
  40 + ProductCache.removeProductCache(data)
  41 + }
  42 +
  43 + }
  44 + }
24 } 45 }
25 - return ctx.body = { 46 + ctx.body = {
26 code: 200 47 code: 200
27 - }; 48 + }
28 } 49 }
29 } 50 }
30 51
@@ -20,11 +20,15 @@ @@ -20,11 +20,15 @@
20 <div class="panel-body"> 20 <div class="panel-body">
21 <div class="col-sm-6"> 21 <div class="col-sm-6">
22 <div class="operations mb20"> 22 <div class="operations mb20">
  23 + <label class="control-label">导入文件:</label>
  24 + <div class="file-upload"></div>
  25 + <select id="selectType" class="form-control input-sm selcet-auto pull-left mr20">
  26 + <option value="1">批量变价</option>
  27 + <option value="2">其它批量</option>
  28 + </select>
  29 + <button class="btn btn-warning btn-clear pull-left">清除</button>
23 30
24 </div> 31 </div>
25 - <div class="query">  
26 - <textarea name="" id="uri" cols="30" rows="20" class="form-control" placeholder="支持多条换行输入"></textarea>  
27 - </div>  
28 </div> 32 </div>
29 <div class="col-sm-6"> 33 <div class="col-sm-6">
30 <div class="panel"> 34 <div class="panel">
@@ -40,11 +44,7 @@ @@ -40,11 +44,7 @@
40 </div> 44 </div>
41 </div> 45 </div>
42 <div class="panel-footer"> 46 <div class="panel-footer">
43 - <select id="selectType" class="form-control input-sm selcet-auto pull-left mr20">  
44 - <option value="1">批量变价</option>  
45 - <option value="2">其它批量</option>  
46 - </select>  
47 - <button class="btn btn-warning btn-clear pull-left">清除</button> 47 +
48 <div class="result pull-left ml20"></div> 48 <div class="result pull-left ml20"></div>
49 </div> 49 </div>
50 </div> 50 </div>
@@ -54,16 +54,40 @@ @@ -54,16 +54,40 @@
54 <script> 54 <script>
55 var posing = false; 55 var posing = false;
56 $(document).on('ready pjax:success', function() { 56 $(document).on('ready pjax:success', function() {
57 - $('.btn-clear').click(function() {  
58 - var selectType = $('#selectType').val();  
59 - if (selectType) {  
60 - $logs.empty();  
61 - $.post('/product_cache/clear', {  
62 - type: selectType  
63 - }, function(res) {  
64 - }); 57 +
  58 + var fileUpload = $('.file-upload').uploadFile({
  59 + url: '/product_cache/clear',
  60 + method: 'POST',
  61 + autoSubmit: false,
  62 + uploadStr: '浏览',
  63 + multiple: false,
  64 + maxFileCount: 1,
  65 + fileName: 'excelFile',
  66 + allowedTypes: 'xlsx,xls',
  67 + dynamicFormData: function() {
  68 + return {type: $('#selectType').val()}
  69 + },
  70 + onSuccess: function(files, data, xhr, pd) {
  71 + console.log('success')
  72 + fileUpload.reset();
  73 + },
  74 + onError: function(files, data, xhr, pd) {
  75 + console.log('onError')
  76 + fileUpload.reset();
65 } 77 }
66 }) 78 })
  79 + $('.btn-clear').click(function() {
  80 + // var selectType = $('#selectType').val();
  81 + // if (selectType) {
  82 + // $logs.empty();
  83 + // // $.post('/product_cache/clear', {
  84 + // // type: selectType
  85 + // // }, function(res) {
  86 + // // });
  87 +
  88 + // }
  89 + fileUpload.startUpload();
  90 + })
67 91
68 function layoutResize() { 92 function layoutResize() {
69 $('.yoho-log-dark').height($('body').height() - 450); 93 $('.yoho-log-dark').height($('body').height() - 450);
@@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
18 <link href="/css/style.datatables.css" rel="stylesheet"> 18 <link href="/css/style.datatables.css" rel="stylesheet">
19 <link href="/css/dataTables.responsive.css" rel="stylesheet"> 19 <link href="/css/dataTables.responsive.css" rel="stylesheet">
20 <link href="/css/custom.css" rel="stylesheet"> 20 <link href="/css/custom.css" rel="stylesheet">
  21 + <link href="/css/uploadfile.css" rel="stylesheet">
21 <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> 22 <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
22 <!--[if lt IE 9]> 23 <!--[if lt IE 9]>
23 <script src="js/html5shiv.js"></script> 24 <script src="js/html5shiv.js"></script>
@@ -52,6 +53,7 @@ @@ -52,6 +53,7 @@
52 <script src="/js/retina.min.js"></script> 53 <script src="/js/retina.min.js"></script>
53 <script src="/js/jquery.cookies.js"></script> 54 <script src="/js/jquery.cookies.js"></script>
54 <script src="/js/jquery.form.min.js"></script> 55 <script src="/js/jquery.form.min.js"></script>
  56 + <script src="/js/jquery.uploadfile.min.js"></script>
55 <script src="/js/flot/jquery.flot.min.js"></script> 57 <script src="/js/flot/jquery.flot.min.js"></script>
56 <script src="/js/flot/jquery.flot.resize.min.js"></script> 58 <script src="/js/flot/jquery.flot.resize.min.js"></script>
57 <script src="/js/flot/jquery.flot.spline.min.js"></script> 59 <script src="/js/flot/jquery.flot.spline.min.js"></script>
@@ -28,8 +28,8 @@ @@ -28,8 +28,8 @@
28 <li class="parent"><a href=""><i class="fa fa-history"></i> <span>缓存管理</span></a> 28 <li class="parent"><a href=""><i class="fa fa-history"></i> <span>缓存管理</span></a>
29 <ul class="children"> 29 <ul class="children">
30 <li><a href="/page_cache/query">PageCahe清理</a></li> 30 <li><a href="/page_cache/query">PageCahe清理</a></li>
31 - {{!-- <li><a href="/cdn_cache/query">CDN清理</a></li>  
32 - <li><a href="/product_cache/query">商品清理</a></li> --}} 31 + <li><a href="/cdn_cache/query">CDN清理</a></li>
  32 + <li><a href="/product_cache/query">商品清理</a></li>
33 <li><a href="/api_cache">ApiCahe清理</a></li> 33 <li><a href="/api_cache">ApiCahe清理</a></li>
34 </ul> 34 </ul>
35 </li> 35 </li>
@@ -41,6 +41,7 @@ @@ -41,6 +41,7 @@
41 "glob": "^7.0.5", 41 "glob": "^7.0.5",
42 "handlebars": "^4.0.5", 42 "handlebars": "^4.0.5",
43 "influx": "^4.2.1", 43 "influx": "^4.2.1",
  44 + "install": "^0.8.1",
44 "koa": "^2.0.0", 45 "koa": "^2.0.0",
45 "koa-body": "^1.4.0", 46 "koa-body": "^1.4.0",
46 "koa-convert": "^1.2.0", 47 "koa-convert": "^1.2.0",
@@ -55,7 +56,9 @@ @@ -55,7 +56,9 @@
55 "moment": "^2.13.0", 56 "moment": "^2.13.0",
56 "nedb": "^1.8.0", 57 "nedb": "^1.8.0",
57 "nedb-promise": "^2.0.0", 58 "nedb-promise": "^2.0.0",
  59 + "node-xlsx": "^0.7.4",
58 "node-zookeeper-client": "^0.2.2", 60 "node-zookeeper-client": "^0.2.2",
  61 + "npm": "^3.10.9",
59 "qn": "^1.3.0", 62 "qn": "^1.3.0",
60 "qs": "^6.2.0", 63 "qs": "^6.2.0",
61 "request-promise": "^4.1.1", 64 "request-promise": "^4.1.1",
  1 +.ajax-file-upload-statusbar {
  2 +border: 1px solid #0ba1b5;
  3 +margin-top: 10px;
  4 +width: 420px;
  5 +margin-right: 10px;
  6 +margin: 5px;
  7 +-moz-border-radius: 4px;
  8 +-webkit-border-radius: 4px;
  9 +border-radius: 4px;
  10 +padding: 5px 5px 5px 15px
  11 +}
  12 +
  13 +.ajax-file-upload-filename {
  14 +width: 300px;
  15 +height: auto;
  16 +margin: 0 5px 5px 0px;
  17 +
  18 +}
  19 +
  20 +.ajax-file-upload-filesize {
  21 +width: 50px;
  22 +height: auto;
  23 +margin: 0 5px 5px 0px;
  24 +display: inline-block;
  25 +vertical-align:middle;
  26 +}
  27 +.ajax-file-upload-progress {
  28 +margin: 5px 10px 5px 0px;
  29 +position: relative;
  30 +width: 250px;
  31 +border: 1px solid #ddd;
  32 +padding: 1px;
  33 +border-radius: 3px;
  34 +display: inline-block;
  35 +color:#FFFFFF;
  36 +
  37 +}
  38 +.ajax-file-upload-bar {
  39 +background-color: #0ba1b5;
  40 +width: 0;
  41 +height: 20px;
  42 +border-radius: 3px;
  43 +color:#FFFFFF;
  44 +
  45 +}
  46 +.ajax-file-upload-percent {
  47 +position: absolute;
  48 +display: inline-block;
  49 +top: 3px;
  50 +left: 48%
  51 +}
  52 +.ajax-file-upload-red {
  53 +-moz-box-shadow: inset 0 39px 0 -24px #e67a73;
  54 +-webkit-box-shadow: inset 0 39px 0 -24px #e67a73;
  55 +box-shadow: inset 0 39px 0 -24px #e67a73;
  56 +background-color: #e4685d;
  57 +-moz-border-radius: 4px;
  58 +-webkit-border-radius: 4px;
  59 +border-radius: 4px;
  60 +display: inline-block;
  61 +color: #fff;
  62 +font-family: arial;
  63 +font-size: 13px;
  64 +font-weight: normal;
  65 +padding: 4px 15px;
  66 +text-decoration: none;
  67 +text-shadow: 0 1px 0 #b23e35;
  68 +cursor: pointer;
  69 +vertical-align: top;
  70 +margin: 5px 10px 5px 0px;
  71 +}
  72 +.ajax-file-upload-green {
  73 +background-color: #77b55a;
  74 +-moz-border-radius: 4px;
  75 +-webkit-border-radius: 4px;
  76 +border-radius: 4px;
  77 +margin: 0;
  78 +padding: 0;
  79 +display: inline-block;
  80 +color: #fff;
  81 +font-family: arial;
  82 +font-size: 13px;
  83 +font-weight: normal;
  84 +padding: 4px 15px;
  85 +text-decoration: none;
  86 +cursor: pointer;
  87 +text-shadow: 0 1px 0 #5b8a3c;
  88 +vertical-align: top;
  89 +margin: 5px 10px 5px 0px;
  90 +}
  91 +.ajax-file-upload {
  92 + font-family: Arial, Helvetica, sans-serif;
  93 + font-size: 16px;
  94 + font-weight: bold;
  95 + padding: 15px 20px;
  96 + cursor:pointer;
  97 + line-height:20px;
  98 + height:25px;
  99 + margin:0 10px 10px 0;
  100 + display: inline-block;
  101 + background: #fff;
  102 + border: 1px solid #e8e8e8;
  103 + color: #888;
  104 + text-decoration: none;
  105 + border-radius: 3px;
  106 + -webkit-border-radius: 3px;
  107 + -moz-border-radius: 3px;
  108 + -moz-box-shadow: 0 2px 0 0 #e8e8e8;
  109 + -webkit-box-shadow: 0 2px 0 0 #e8e8e8;
  110 + box-shadow: 0 2px 0 0 #e8e8e8;
  111 + padding: 6px 10px 4px 10px;
  112 + color: #fff;
  113 + background: #2f8ab9;
  114 + border: none;
  115 + -moz-box-shadow: 0 2px 0 0 #13648d;
  116 + -webkit-box-shadow: 0 2px 0 0 #13648d;
  117 + box-shadow: 0 2px 0 0 #13648d;
  118 + vertical-align: middle;
  119 + }
  120 +
  121 +.ajax-file-upload:hover {
  122 + background: #3396c9;
  123 + -moz-box-shadow: 0 2px 0 0 #15719f;
  124 + -webkit-box-shadow: 0 2px 0 0 #15719f;
  125 + box-shadow: 0 2px 0 0 #15719f;
  126 +}
  127 +
  128 +.ajax-upload-dragdrop
  129 +{
  130 +
  131 + border:2px dotted #A5A5C7;
  132 + width:420px;
  133 + color: #DADCE3;
  134 + text-align:left;
  135 + vertical-align:middle;
  136 + padding:10px 10px 0px 10px;
  137 +}
  138 +
  139 +.state-hover
  140 +{
  141 + border:2px solid #A5A5C7;
  142 +}
  143 +.ajax-file-upload-container
  144 +{
  145 + margin:20px 0px 20px 0px;
  146 +}
  1 +/*!
  2 + * jQuery Upload File Plugin
  3 + * version: 4.0.10
  4 + * @requires jQuery v1.5 or later & form plugin
  5 + * Copyright (c) 2013 Ravishanker Kusuma
  6 + * http://hayageek.com/
  7 + */
  8 +!function(e){void 0==e.fn.ajaxForm&&e.getScript(("https:"==document.location.protocol?"https://":"http://")+"malsup.github.io/jquery.form.js");var a={};a.fileapi=void 0!==e("<input type='file'/>").get(0).files,a.formdata=void 0!==window.FormData,e.fn.uploadFile=function(t){function r(){S||(S=!0,function e(){if(w.sequential||(w.sequentialCount=99999),0==x.length&&0==D.length)w.afterUploadAll&&w.afterUploadAll(C),S=!1;else{if(D.length<w.sequentialCount){var a=x.shift();void 0!=a&&(D.push(a),a.removeClass(C.formGroup),a.submit())}window.setTimeout(e,100)}}())}function o(a,t,r){r.on("dragenter",function(a){a.stopPropagation(),a.preventDefault(),e(this).addClass(t.dragDropHoverClass)}),r.on("dragover",function(a){a.stopPropagation(),a.preventDefault();var r=e(this);r.hasClass(t.dragDropContainerClass)&&!r.hasClass(t.dragDropHoverClass)&&r.addClass(t.dragDropHoverClass)}),r.on("drop",function(r){r.preventDefault(),e(this).removeClass(t.dragDropHoverClass),a.errorLog.html("");var o=r.originalEvent.dataTransfer.files;return!t.multiple&&o.length>1?void(t.showError&&e("<div class='"+t.errorClass+"'>"+t.multiDragErrorStr+"</div>").appendTo(a.errorLog)):void(0!=t.onSelect(o)&&l(t,a,o))}),r.on("dragleave",function(a){e(this).removeClass(t.dragDropHoverClass)}),e(document).on("dragenter",function(e){e.stopPropagation(),e.preventDefault()}),e(document).on("dragover",function(a){a.stopPropagation(),a.preventDefault();var r=e(this);r.hasClass(t.dragDropContainerClass)||r.removeClass(t.dragDropHoverClass)}),e(document).on("drop",function(a){a.stopPropagation(),a.preventDefault(),e(this).removeClass(t.dragDropHoverClass)})}function s(e){var a="",t=e/1024;if(parseInt(t)>1024){var r=t/1024;a=r.toFixed(2)+" MB"}else a=t.toFixed(2)+" KB";return a}function i(a){var t=[];t="string"==jQuery.type(a)?a.split("&"):e.param(a).split("&");var r,o,s=t.length,i=[];for(r=0;s>r;r++)t[r]=t[r].replace(/\+/g," "),o=t[r].split("="),i.push([decodeURIComponent(o[0]),decodeURIComponent(o[1])]);return i}function l(a,t,r){for(var o=0;o<r.length;o++)if(n(t,a,r[o].name))if(a.allowDuplicates||!d(t,r[o].name))if(-1!=a.maxFileSize&&r[o].size>a.maxFileSize)a.showError&&e("<div class='"+a.errorClass+"'><b>"+r[o].name+"</b> "+a.sizeErrorStr+s(a.maxFileSize)+"</div>").appendTo(t.errorLog);else if(-1!=a.maxFileCount&&t.selectedFiles>=a.maxFileCount)a.showError&&e("<div class='"+a.errorClass+"'><b>"+r[o].name+"</b> "+a.maxFileCountErrorStr+a.maxFileCount+"</div>").appendTo(t.errorLog);else{t.selectedFiles++,t.existingFileNames.push(r[o].name);var l=a,p=new FormData,u=a.fileName.replace("[]","");p.append(u,r[o]);var c=a.formData;if(c)for(var h=i(c),f=0;f<h.length;f++)h[f]&&p.append(h[f][0],h[f][1]);l.fileData=p;var w=new m(t,a),g="";g=a.showFileCounter?t.fileCounter+a.fileCounterStyle+r[o].name:r[o].name,a.showFileSize&&(g+=" ("+s(r[o].size)+")"),w.filename.html(g);var C=e("<form style='display:block; position:absolute;left: 150px;' class='"+t.formGroup+"' method='"+a.method+"' action='"+a.url+"' enctype='"+a.enctype+"'></form>");C.appendTo("body");var b=[];b.push(r[o].name),v(C,l,w,b,t,r[o]),t.fileCounter++}else a.showError&&e("<div class='"+a.errorClass+"'><b>"+r[o].name+"</b> "+a.duplicateErrorStr+"</div>").appendTo(t.errorLog);else a.showError&&e("<div class='"+a.errorClass+"'><b>"+r[o].name+"</b> "+a.extErrorStr+a.allowedTypes+"</div>").appendTo(t.errorLog)}function n(e,a,t){var r=a.allowedTypes.toLowerCase().split(/[\s,]+/g),o=t.split(".").pop().toLowerCase();return"*"!=a.allowedTypes&&jQuery.inArray(o,r)<0?!1:!0}function d(e,a){var t=!1;if(e.existingFileNames.length)for(var r=0;r<e.existingFileNames.length;r++)(e.existingFileNames[r]==a||w.duplicateStrict&&e.existingFileNames[r].toLowerCase()==a.toLowerCase())&&(t=!0);return t}function p(e,a){if(e.existingFileNames.length)for(var t=0;t<a.length;t++){var r=e.existingFileNames.indexOf(a[t]);-1!=r&&e.existingFileNames.splice(r,1)}}function u(e,a){if(e){a.show();var t=new FileReader;t.onload=function(e){a.attr("src",e.target.result)},t.readAsDataURL(e)}}function c(a,t){if(a.showFileCounter){var r=e(t.container).find(".ajax-file-upload-filename").length;t.fileCounter=r+1,e(t.container).find(".ajax-file-upload-filename").each(function(t,o){var s=e(this).html().split(a.fileCounterStyle),i=(parseInt(s[0])-1,r+a.fileCounterStyle+s[1]);e(this).html(i),r--})}}function h(t,r,o,s){var i="ajax-upload-id-"+(new Date).getTime(),d=e("<form method='"+o.method+"' action='"+o.url+"' enctype='"+o.enctype+"'></form>"),p="<input type='file' id='"+i+"' name='"+o.fileName+"' accept='"+o.acceptFiles+"'/>";o.multiple&&(o.fileName.indexOf("[]")!=o.fileName.length-2&&(o.fileName+="[]"),p="<input type='file' id='"+i+"' name='"+o.fileName+"' accept='"+o.acceptFiles+"' multiple/>");var u=e(p).appendTo(d);u.change(function(){t.errorLog.html("");var i=(o.allowedTypes.toLowerCase().split(","),[]);if(this.files){for(g=0;g<this.files.length;g++)i.push(this.files[g].name);if(0==o.onSelect(this.files))return}else{var p=e(this).val(),u=[];if(i.push(p),!n(t,o,p))return void(o.showError&&e("<div class='"+o.errorClass+"'><b>"+p+"</b> "+o.extErrorStr+o.allowedTypes+"</div>").appendTo(t.errorLog));if(u.push({name:p,size:"NA"}),0==o.onSelect(u))return}if(c(o,t),s.unbind("click"),d.hide(),h(t,r,o,s),d.addClass(r),o.serialize&&a.fileapi&&a.formdata){d.removeClass(r);var f=this.files;d.remove(),l(o,t,f)}else{for(var w="",g=0;g<i.length;g++)w+=o.showFileCounter?t.fileCounter+o.fileCounterStyle+i[g]+"<br>":i[g]+"<br>",t.fileCounter++;if(-1!=o.maxFileCount&&t.selectedFiles+i.length>o.maxFileCount)return void(o.showError&&e("<div class='"+o.errorClass+"'><b>"+w+"</b> "+o.maxFileCountErrorStr+o.maxFileCount+"</div>").appendTo(t.errorLog));t.selectedFiles+=i.length;var C=new m(t,o);C.filename.html(w),v(d,o,C,i,t,null)}}),o.nestedForms?(d.css({margin:0,padding:0}),s.css({position:"relative",overflow:"hidden",cursor:"default"}),u.css({position:"absolute",cursor:"pointer",top:"0px",width:"100%",height:"100%",left:"0px","z-index":"100",opacity:"0.0",filter:"alpha(opacity=0)","-ms-filter":"alpha(opacity=0)","-khtml-opacity":"0.0","-moz-opacity":"0.0"}),d.appendTo(s)):(d.appendTo(e("body")),d.css({margin:0,padding:0,display:"block",position:"absolute",left:"-250px"}),-1!=navigator.appVersion.indexOf("MSIE ")?s.attr("for",i):s.click(function(){u.click()}))}function f(a,t){return this.statusbar=e("<div class='ajax-file-upload-statusbar'></div>").width(t.statusBarWidth),this.preview=e("<img class='ajax-file-upload-preview' />").width(t.previewWidth).height(t.previewHeight).appendTo(this.statusbar).hide(),this.filename=e("<div class='ajax-file-upload-filename'></div>").appendTo(this.statusbar),this.progressDiv=e("<div class='ajax-file-upload-progress'>").appendTo(this.statusbar).hide(),this.progressbar=e("<div class='ajax-file-upload-bar'></div>").appendTo(this.progressDiv),this.abort=e("<div>"+t.abortStr+"</div>").appendTo(this.statusbar).hide(),this.cancel=e("<div>"+t.cancelStr+"</div>").appendTo(this.statusbar).hide(),this.done=e("<div>"+t.doneStr+"</div>").appendTo(this.statusbar).hide(),this.download=e("<div>"+t.downloadStr+"</div>").appendTo(this.statusbar).hide(),this.del=e("<div>"+t.deletelStr+"</div>").appendTo(this.statusbar).hide(),this.abort.addClass("ajax-file-upload-red"),this.done.addClass("ajax-file-upload-green"),this.download.addClass("ajax-file-upload-green"),this.cancel.addClass("ajax-file-upload-red"),this.del.addClass("ajax-file-upload-red"),this}function m(a,t){var r=null;return r=t.customProgressBar?new t.customProgressBar(a,t):new f(a,t),r.abort.addClass(a.formGroup),r.abort.addClass(t.abortButtonClass),r.cancel.addClass(a.formGroup),r.cancel.addClass(t.cancelButtonClass),t.extraHTML&&(r.extraHTML=e("<div class='extrahtml'>"+t.extraHTML()+"</div>").insertAfter(r.filename)),"bottom"==t.uploadQueueOrder?e(a.container).append(r.statusbar):e(a.container).prepend(r.statusbar),r}function v(t,o,s,l,n,d){var h={cache:!1,contentType:!1,processData:!1,forceSync:!1,type:o.method,data:o.formData,formData:o.fileData,dataType:o.returnType,beforeSubmit:function(a,r,d){if(0!=o.onSubmit.call(this,l)){if(o.dynamicFormData){var u=i(o.dynamicFormData());if(u)for(var h=0;h<u.length;h++)u[h]&&(void 0!=o.fileData?d.formData.append(u[h][0],u[h][1]):d.data[u[h][0]]=u[h][1])}return o.extraHTML&&e(s.extraHTML).find("input,select,textarea").each(function(a,t){void 0!=o.fileData?d.formData.append(e(this).attr("name"),e(this).val()):d.data[e(this).attr("name")]=e(this).val()}),!0}return s.statusbar.append("<div class='"+o.errorClass+"'>"+o.uploadErrorStr+"</div>"),s.cancel.show(),t.remove(),s.cancel.click(function(){x.splice(x.indexOf(t),1),p(n,l),s.statusbar.remove(),o.onCancel.call(n,l,s),n.selectedFiles-=l.length,c(o,n)}),!1},beforeSend:function(e,t){s.progressDiv.show(),s.cancel.hide(),s.done.hide(),o.showAbort&&(s.abort.show(),s.abort.click(function(){p(n,l),e.abort(),n.selectedFiles-=l.length,o.onAbort.call(n,l,s)})),a.formdata?s.progressbar.width("1%"):s.progressbar.width("5%")},uploadProgress:function(e,a,t,r){r>98&&(r=98);var i=r+"%";r>1&&s.progressbar.width(i),o.showProgress&&(s.progressbar.html(i),s.progressbar.css("text-align","center"))},success:function(a,r,i){if(s.cancel.remove(),D.pop(),"json"==o.returnType&&"object"==e.type(a)&&a.hasOwnProperty(o.customErrorKeyStr)){s.abort.hide();var d=a[o.customErrorKeyStr];return o.onError.call(this,l,200,d,s),o.showStatusAfterError?(s.progressDiv.hide(),s.statusbar.append("<span class='"+o.errorClass+"'>ERROR: "+d+"</span>")):(s.statusbar.hide(),s.statusbar.remove()),n.selectedFiles-=l.length,void t.remove()}n.responses.push(a),s.progressbar.width("100%"),o.showProgress&&(s.progressbar.html("100%"),s.progressbar.css("text-align","center")),s.abort.hide(),o.onSuccess.call(this,l,a,i,s),o.showStatusAfterSuccess?(o.showDone?(s.done.show(),s.done.click(function(){s.statusbar.hide("slow"),s.statusbar.remove()})):s.done.hide(),o.showDelete?(s.del.show(),s.del.click(function(){p(n,l),s.statusbar.hide().remove(),o.deleteCallback&&o.deleteCallback.call(this,a,s),n.selectedFiles-=l.length,c(o,n)})):s.del.hide()):(s.statusbar.hide("slow"),s.statusbar.remove()),o.showDownload&&(s.download.show(),s.download.click(function(){o.downloadCallback&&o.downloadCallback(a)})),t.remove()},error:function(e,a,r){s.cancel.remove(),D.pop(),s.abort.hide(),"abort"==e.statusText?(s.statusbar.hide("slow").remove(),c(o,n)):(o.onError.call(this,l,a,r,s),o.showStatusAfterError?(s.progressDiv.hide(),s.statusbar.append("<span class='"+o.errorClass+"'>ERROR: "+r+"</span>")):(s.statusbar.hide(),s.statusbar.remove()),n.selectedFiles-=l.length),t.remove()}};o.showPreview&&null!=d&&"image"==d.type.toLowerCase().split("/").shift()&&u(d,s.preview),o.autoSubmit?(t.ajaxForm(h),x.push(t),r()):(o.showCancel&&(s.cancel.show(),s.cancel.click(function(){x.splice(x.indexOf(t),1),p(n,l),t.remove(),s.statusbar.remove(),o.onCancel.call(n,l,s),n.selectedFiles-=l.length,c(o,n)})),t.ajaxForm(h))}var w=e.extend({url:"",method:"POST",enctype:"multipart/form-data",returnType:null,allowDuplicates:!0,duplicateStrict:!1,allowedTypes:"*",acceptFiles:"*",fileName:"file",formData:!1,dynamicFormData:!1,maxFileSize:-1,maxFileCount:-1,multiple:!0,dragDrop:!0,autoSubmit:!0,showCancel:!0,showAbort:!0,showDone:!1,showDelete:!1,showError:!0,showStatusAfterSuccess:!0,showStatusAfterError:!0,showFileCounter:!0,fileCounterStyle:"). ",showFileSize:!0,showProgress:!1,nestedForms:!0,showDownload:!1,onLoad:function(e){},onSelect:function(e){return!0},onSubmit:function(e,a){},onSuccess:function(e,a,t,r){},onError:function(e,a,t,r){},onCancel:function(e,a){},onAbort:function(e,a){},downloadCallback:!1,deleteCallback:!1,afterUploadAll:!1,serialize:!0,sequential:!1,sequentialCount:2,customProgressBar:!1,abortButtonClass:"ajax-file-upload-abort",cancelButtonClass:"ajax-file-upload-cancel",dragDropContainerClass:"ajax-upload-dragdrop",dragDropHoverClass:"state-hover",errorClass:"ajax-file-upload-error",uploadButtonClass:"ajax-file-upload",dragDropStr:"<span><b>Drag &amp; Drop Files</b></span>",uploadStr:"Upload",abortStr:"Abort",cancelStr:"Cancel",deletelStr:"Delete",doneStr:"Done",multiDragErrorStr:"Multiple File Drag &amp; Drop is not allowed.",extErrorStr:"is not allowed. Allowed extensions: ",duplicateErrorStr:"is not allowed. File already exists.",sizeErrorStr:"is not allowed. Allowed Max size: ",uploadErrorStr:"Upload is not allowed",maxFileCountErrorStr:" is not allowed. Maximum allowed files are:",downloadStr:"Download",customErrorKeyStr:"jquery-upload-file-error",showQueueDiv:!1,statusBarWidth:400,dragdropWidth:400,showPreview:!1,previewHeight:"auto",previewWidth:"100%",extraHTML:!1,uploadQueueOrder:"top"},t);this.fileCounter=1,this.selectedFiles=0;var g="ajax-file-upload-"+(new Date).getTime();this.formGroup=g,this.errorLog=e("<div></div>"),this.responses=[],this.existingFileNames=[],a.formdata||(w.dragDrop=!1),a.formdata||(w.multiple=!1),e(this).html("");var C=this,b=e("<div>"+w.uploadStr+"</div>");e(b).addClass(w.uploadButtonClass),function F(){if(e.fn.ajaxForm){if(w.dragDrop){var a=e('<div class="'+w.dragDropContainerClass+'" style="vertical-align:top;"></div>').width(w.dragdropWidth);e(C).append(a),e(a).append(b),e(a).append(e(w.dragDropStr)),o(C,w,a)}else e(C).append(b);e(C).append(C.errorLog),w.showQueueDiv?C.container=e("#"+w.showQueueDiv):C.container=e("<div class='ajax-file-upload-container'></div>").insertAfter(e(C)),w.onLoad.call(this,C),h(C,g,w,b)}else window.setTimeout(F,10)}(),this.startUpload=function(){e("form").each(function(a,t){e(this).hasClass(C.formGroup)&&x.push(e(this))}),x.length>=1&&r()},this.getFileCount=function(){return C.selectedFiles},this.stopUpload=function(){e("."+w.abortButtonClass).each(function(a,t){e(this).hasClass(C.formGroup)&&e(this).click()}),e("."+w.cancelButtonClass).each(function(a,t){e(this).hasClass(C.formGroup)&&e(this).click()})},this.cancelAll=function(){e("."+w.cancelButtonClass).each(function(a,t){e(this).hasClass(C.formGroup)&&e(this).click()})},this.update=function(a){w=e.extend(w,a)},this.reset=function(e){C.fileCounter=1,C.selectedFiles=0,C.errorLog.html(""),0!=e&&C.container.html("")},this.remove=function(){C.container.html(""),e(C).remove()},this.createProgress=function(e,a,t){var r=new m(this,w);r.progressDiv.show(),r.progressbar.width("100%");var o="";return o=w.showFileCounter?C.fileCounter+w.fileCounterStyle+e:e,w.showFileSize&&(o+=" ("+s(t)+")"),r.filename.html(o),C.fileCounter++,C.selectedFiles++,w.showPreview&&(r.preview.attr("src",a),r.preview.show()),w.showDownload&&(r.download.show(),r.download.click(function(){w.downloadCallback&&w.downloadCallback.call(C,[e])})),w.showDelete&&(r.del.show(),r.del.click(function(){r.statusbar.hide().remove();var a=[e];w.deleteCallback&&w.deleteCallback.call(this,a,r),C.selectedFiles-=1,c(w,C)})),r},this.getResponses=function(){return this.responses};var x=[],D=[],S=!1;return this}}(jQuery);