酒店预订平台
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

433 líneas
25 KiB

  1. define(['jquery', 'bootstrap', 'dropzone', 'template'], function ($, undefined, Dropzone, Template) {
  2. var Upload = {
  3. list: {},
  4. options: {},
  5. config: {
  6. container: document.body,
  7. classname: '.plupload:not([initialized]),.faupload:not([initialized])',
  8. previewtpl: '<li class="col-xs-3"><a href="<%=fullurl%>" data-url="<%=url%>" target="_blank" class="thumbnail"><img src="<%=fullurl%>" onerror="this.src=\'' + Fast.api.fixurl("ajax/icon") + '?suffix=<%=suffix%>\';this.onerror=null;" class="img-responsive"></a><a href="javascript:;" class="btn btn-danger btn-xs btn-trash"><i class="fa fa-trash"></i></a></li>',
  9. },
  10. events: {
  11. //初始化
  12. onInit: function () {
  13. },
  14. //上传成功的回调
  15. onUploadSuccess: function (up, ret, file) {
  16. var button = up.element;
  17. var onUploadSuccess = up.options.onUploadSuccess;
  18. var data = typeof ret.data !== 'undefined' ? ret.data : null;
  19. //上传成功后回调
  20. if (button) {
  21. //如果有文本框则填充
  22. var input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
  23. if (input_id) {
  24. var urlArr = [];
  25. var inputObj = $("#" + input_id);
  26. if ($(button).data("multiple") && inputObj.val() !== "") {
  27. urlArr.push(inputObj.val());
  28. }
  29. urlArr.push(data.url);
  30. inputObj.val(urlArr.join(",")).trigger("change").trigger("validate");
  31. }
  32. //如果有回调函数
  33. var onDomUploadSuccess = $(button).data("upload-success");
  34. if (onDomUploadSuccess) {
  35. if (typeof onDomUploadSuccess !== 'function' && typeof Upload.api.custom[onDomUploadSuccess] === 'function') {
  36. onDomUploadSuccess = Upload.api.custom[onDomUploadSuccess];
  37. }
  38. if (typeof onDomUploadSuccess === 'function') {
  39. var result = onDomUploadSuccess.call(button, data, ret);
  40. if (result === false)
  41. return;
  42. }
  43. }
  44. }
  45. if (typeof onUploadSuccess === 'function') {
  46. var result = onUploadSuccess.call(button, data, ret);
  47. if (result === false)
  48. return;
  49. }
  50. },
  51. //上传错误的回调
  52. onUploadError: function (up, ret, file) {
  53. var button = up.element;
  54. var onUploadError = up.options.onUploadError;
  55. var data = typeof ret.data !== 'undefined' ? ret.data : null;
  56. if (button) {
  57. var onDomUploadError = $(button).data("upload-error");
  58. if (onDomUploadError) {
  59. if (typeof onDomUploadError !== 'function' && typeof Upload.api.custom[onDomUploadError] === 'function') {
  60. onDomUploadError = Upload.api.custom[onDomUploadError];
  61. }
  62. if (typeof onDomUploadError === 'function') {
  63. var result = onDomUploadError.call(button, data, ret);
  64. if (result === false)
  65. return;
  66. }
  67. }
  68. }
  69. if (typeof onUploadError === 'function') {
  70. var result = onUploadError.call(button, data, ret);
  71. if (result === false) {
  72. return;
  73. }
  74. }
  75. Toastr.error(ret.msg.toString().replace(/(<([^>]+)>)/gi, "") + "(code:" + ret.code + ")");
  76. },
  77. //服务器响应数据后
  78. onUploadResponse: function (response, up, file) {
  79. try {
  80. var ret = typeof response === 'object' ? response : JSON.parse(response);
  81. if (!ret.hasOwnProperty('code')) {
  82. $.extend(ret, {code: -2, msg: response, data: null});
  83. }
  84. } catch (e) {
  85. var ret = {code: -1, msg: e.message, data: null};
  86. }
  87. return ret;
  88. },
  89. //上传全部结束后
  90. onUploadComplete: function (up, files) {
  91. var button = up.element;
  92. var onUploadComplete = up.options.onUploadComplete;
  93. if (button) {
  94. var onDomUploadComplete = $(button).data("upload-complete");
  95. if (onDomUploadComplete) {
  96. if (typeof onDomUploadComplete !== 'function' && typeof Upload.api.custom[onDomUploadComplete] === 'function') {
  97. onDomUploadComplete = Upload.api.custom[onDomUploadComplete];
  98. }
  99. if (typeof onDomUploadComplete === 'function') {
  100. var result = onDomUploadComplete.call(button, files);
  101. if (result === false)
  102. return;
  103. }
  104. }
  105. }
  106. if (typeof onUploadComplete === 'function') {
  107. var result = onUploadComplete.call(button, files);
  108. if (result === false) {
  109. return;
  110. }
  111. }
  112. }
  113. },
  114. api: {
  115. //上传接口
  116. upload: function (element, onUploadSuccess, onUploadError, onUploadComplete) {
  117. element = typeof element === 'undefined' ? Upload.config.classname : element;
  118. $(element, Upload.config.container).each(function () {
  119. if ($(this).attr("initialized")) {
  120. return true;
  121. }
  122. $(this).attr("initialized", true);
  123. var that = this;
  124. var id = $(this).prop("id") || $(this).prop("name") || Dropzone.uuidv4();
  125. var url = $(this).data("url");
  126. var maxsize = $(this).data("maxsize");
  127. var maxcount = $(this).data("maxcount");
  128. var mimetype = $(this).data("mimetype");
  129. var multipart = $(this).data("multipart");
  130. var multiple = $(this).data("multiple");
  131. //填充ID
  132. var input_id = $(that).data("input-id") ? $(that).data("input-id") : "";
  133. //预览ID
  134. var preview_id = $(that).data("preview-id") ? $(that).data("preview-id") : "";
  135. //上传URL
  136. url = url ? url : Config.upload.uploadurl;
  137. url = Fast.api.fixurl(url);
  138. var chunking = false, chunkSize = Config.upload.chunksize || 2097152, timeout = Config.upload.timeout || 600000;
  139. //最大可上传文件大小
  140. maxsize = typeof maxsize !== "undefined" ? maxsize : Config.upload.maxsize;
  141. //文件类型
  142. mimetype = typeof mimetype !== "undefined" ? mimetype : Config.upload.mimetype;
  143. //请求的表单参数
  144. multipart = typeof multipart !== "undefined" ? multipart : Config.upload.multipart;
  145. //是否支持批量上传
  146. multiple = typeof multiple !== "undefined" ? multiple : Config.upload.multiple;
  147. //后缀特殊处理
  148. mimetype = mimetype.split(",").map(function (k) {
  149. return k.indexOf("/") > -1 ? k : (!k || k === "*" || k.charAt(0) === "." ? k : "." + k);
  150. }).join(",");
  151. mimetype = mimetype === '*' ? null : mimetype;
  152. //最大文件限制转换成mb
  153. var maxFilesize = 500;
  154. var options = $(this).data() || {};
  155. delete options.success;
  156. delete options.url;
  157. multipart = $.isArray(multipart) ? {} : multipart;
  158. Upload.list[id] = new Dropzone(this, $.extend({
  159. url: url,
  160. params: function (files, xhr, chunk) {
  161. var params = multipart;
  162. if (chunk) {
  163. return $.extend({}, params, {
  164. filesize: chunk.file.size,
  165. filename: chunk.file.name,
  166. chunkid: chunk.file.upload.uuid,
  167. chunkindex: chunk.index,
  168. chunkcount: chunk.file.upload.totalChunkCount,
  169. chunksize: this.options.chunkSize,
  170. chunkfilesize: chunk.dataBlock.data.size,
  171. width: chunk.file.width || 0,
  172. height: chunk.file.height || 0,
  173. type: chunk.file.type,
  174. });
  175. }
  176. return params;
  177. },
  178. chunking: chunking,
  179. chunkSize: chunkSize,
  180. maxFilesize: 500,
  181. acceptedFiles: mimetype,
  182. maxFiles: (maxcount && parseInt(maxcount) > 1 ? maxcount : (multiple ? null : 1)),
  183. timeout: timeout,
  184. parallelUploads: 1,
  185. previewsContainer: false,
  186. dictDefaultMessage: __("Drop files here to upload"),
  187. dictFallbackMessage: __("Your browser does not support drag'n'drop file uploads"),
  188. dictFallbackText: __("Please use the fallback form below to upload your files like in the olden days"),
  189. dictInvalidFileType: __("You can't upload files of this type"),
  190. dictResponseError: __("Server responded with %s code.", "{{statusCode}}"),
  191. dictCancelUpload: __("Cancel upload"),
  192. dictUploadCanceled: __("Upload canceled"),
  193. dictCancelUploadConfirmation: __("Are you sure you want to cancel this upload?"),
  194. dictRemoveFile: __("Remove file"),
  195. dictMaxFilesExceeded: __("You can only upload a maximum of %s files", "{{maxFiles}}"),
  196. init: function () {
  197. Upload.events.onInit.call(this);
  198. //必须添加dz-message,否则点击icon无法唤起上传窗口
  199. $(">i", this.element).addClass("dz-message");
  200. this.options.elementHtml = $(this.element).html();
  201. },
  202. addedfiles: function (files) {
  203. if (this.options.maxFiles && (!this.options.maxFiles || this.options.maxFiles > 1) && this.options.inputId) {
  204. var inputObj = $("#" + this.options.inputId);
  205. if (inputObj.size() > 0) {
  206. var value = $.trim(inputObj.val());
  207. var nums = value === '' ? 0 : value.split(/\,/).length;
  208. var remain = this.options.maxFiles - nums;
  209. if (remain === 0 || files.length > remain) {
  210. files = Array.prototype.slice.call(files, remain);
  211. for (var i = 0; i < files.length; i++) {
  212. this.removeFile(files[i]);
  213. }
  214. Toastr.error(__("You can only upload a maximum of %s files", this.options.maxFiles));
  215. }
  216. }
  217. }
  218. },
  219. success: function (file, response) {
  220. var ret = Upload.events.onUploadResponse(response, this, file);
  221. file.ret = ret;
  222. if (ret.code === 1) {
  223. Upload.events.onUploadSuccess(this, ret, file);
  224. } else {
  225. Upload.events.onUploadError(this, ret, file);
  226. }
  227. },
  228. error: function (file, response, xhr) {
  229. var responseObj = $("<div>" + (xhr && typeof xhr.responseText !== 'undefined' ? xhr.responseText : response) + "</div>");
  230. responseObj.find("style, title, script").remove();
  231. var ret = {code: 0, data: null, msg: responseObj.text()};
  232. Upload.events.onUploadError(this, ret, file);
  233. },
  234. uploadprogress: function (file, progress, bytesSent) {
  235. if (file.upload.chunked) {
  236. $(this.element).prop("disabled", true).html("<i class='fa fa-upload'></i> " + __('Upload') + Math.floor((file.upload.bytesSent / file.size) * 100) + "%");
  237. }
  238. },
  239. totaluploadprogress: function (progress, bytesSent) {
  240. if (this.getActiveFiles().length > 0 && !this.options.chunking) {
  241. $(this.element).prop("disabled", true).html("<i class='fa fa-upload'></i> " + __('Upload') + Math.floor(progress) + "%");
  242. }
  243. },
  244. queuecomplete: function () {
  245. Upload.events.onUploadComplete(this, this.files);
  246. this.removeAllFiles(true);
  247. $(this.element).prop("disabled", false).html(this.options.elementHtml);
  248. },
  249. chunkSuccess: function (chunk, file, response) {
  250. },
  251. chunksUploaded: function (file, done) {
  252. var that = this;
  253. Fast.api.ajax({
  254. url: this.options.url,
  255. data: $.extend({}, multipart, {
  256. action: 'merge',
  257. filesize: file.size,
  258. filename: file.name,
  259. chunkid: file.upload.uuid,
  260. chunkcount: file.upload.totalChunkCount,
  261. })
  262. }, function (data, ret) {
  263. done(JSON.stringify(ret));
  264. return false;
  265. }, function (data, ret) {
  266. file.accepted = false;
  267. that._errorProcessing([file], ret.msg);
  268. });
  269. },
  270. onUploadSuccess: onUploadSuccess,
  271. onUploadError: onUploadError,
  272. onUploadComplete: onUploadComplete,
  273. }, Upload.options, options));
  274. //拖动排序
  275. if (preview_id && multiple) {
  276. require(['dragsort'], function () {
  277. $("#" + preview_id).dragsort({
  278. dragSelector: "li a:not(.btn-trash)",
  279. dragEnd: function () {
  280. $("#" + preview_id).trigger("fa.preview.change");
  281. },
  282. placeHolderTemplate: '<li class="col-xs-3"></li>'
  283. });
  284. });
  285. }
  286. //刷新隐藏textarea的值
  287. var refresh = function (name) {
  288. var data = {};
  289. var textarea = $("textarea[name='" + name + "']");
  290. var container = textarea.prev("ul");
  291. $.each($("input,select,textarea", container).serializeArray(), function (i, j) {
  292. var reg = /\[?(\w+)\]?\[(\w+)\]$/g;
  293. var match = reg.exec(j.name);
  294. if (!match)
  295. return true;
  296. if (!isNaN(match[2])) {
  297. data[i] = j.value;
  298. } else {
  299. match[1] = "x" + parseInt(match[1]);
  300. if (typeof data[match[1]] === 'undefined') {
  301. data[match[1]] = {};
  302. }
  303. data[match[1]][match[2]] = j.value;
  304. }
  305. });
  306. var result = [];
  307. $.each(data, function (i, j) {
  308. result.push(j);
  309. });
  310. textarea.val(JSON.stringify(result));
  311. };
  312. if (preview_id && input_id) {
  313. $(document.body).on("keyup change", "#" + input_id, function (e) {
  314. var inputStr = $("#" + input_id).val();
  315. var inputArr = inputStr.split(/\,/);
  316. $("#" + preview_id).empty();
  317. var tpl = $("#" + preview_id).data("template") ? $("#" + preview_id).data("template") : "";
  318. var extend = $("#" + preview_id).next().is("textarea") ? $("#" + preview_id).next("textarea").val() : "{}";
  319. var json = {};
  320. try {
  321. json = JSON.parse(extend);
  322. } catch (e) {
  323. }
  324. $.each(inputArr, function (i, j) {
  325. if (!j) {
  326. return true;
  327. }
  328. var suffix = /[\.]?([a-zA-Z0-9]+)$/.exec(j);
  329. suffix = suffix ? suffix[1] : 'file';
  330. var value = (json && typeof json[i] !== 'undefined' ? json[i] : null);
  331. var data = {url: j, fullurl: Fast.api.cdnurl(j), data: $(that).data(), key: i, index: i, value: value, row: value, suffix: suffix};
  332. var html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
  333. $("#" + preview_id).append(html);
  334. });
  335. refresh($("#" + preview_id).data("name"));
  336. });
  337. $("#" + input_id).trigger("change");
  338. }
  339. if (preview_id) {
  340. //监听文本框改变事件
  341. $("#" + preview_id).on('change keyup', "input,textarea,select", function () {
  342. refresh($(this).closest("ul").data("name"));
  343. });
  344. // 监听事件
  345. $(document.body).on("fa.preview.change", "#" + preview_id, function () {
  346. var urlArr = [];
  347. $("#" + preview_id + " [data-url]").each(function (i, j) {
  348. urlArr.push($(this).data("url"));
  349. });
  350. if (input_id) {
  351. $("#" + input_id).val(urlArr.join(","));
  352. }
  353. refresh($("#" + preview_id).data("name"));
  354. });
  355. // 移除按钮事件
  356. $(document.body).on("click", "#" + preview_id + " .btn-trash", function () {
  357. $(this).closest("li").remove();
  358. $("#" + preview_id).trigger("fa.preview.change");
  359. });
  360. }
  361. if (input_id) {
  362. //粘贴上传、拖拽上传
  363. $("body").on('paste drop', "#" + input_id, function (event) {
  364. var originEvent = event.originalEvent;
  365. var button = $(".plupload[data-input-id='" + $(this).attr("id") + "'],.faupload[data-input-id='" + $(this).attr("id") + "']");
  366. if (event.type === 'paste' && originEvent.clipboardData && originEvent.clipboardData.items) {
  367. var items = originEvent.clipboardData.items;
  368. if ((items.length === 1 && items[0].type.indexOf("text") > -1) || (items.length === 2 && items[1].type.indexOf("text") > -1)) {
  369. } else {
  370. Upload.list[button.attr("id")].paste(originEvent);
  371. return false;
  372. }
  373. }
  374. if (event.type === 'drop' && originEvent.dataTransfer && originEvent.dataTransfer.files) {
  375. Upload.list[button.attr("id")].drop(originEvent);
  376. return false;
  377. }
  378. });
  379. }
  380. });
  381. },
  382. /**
  383. * @deprecated Use upload instead.
  384. */
  385. plupload: function (element, onUploadSuccess, onUploadError, onUploadComplete) {
  386. return Upload.api.upload(element, onUploadSuccess, onUploadError, onUploadComplete);
  387. },
  388. /**
  389. * @deprecated Use upload instead.
  390. */
  391. faupload: function (element, onUploadSuccess, onUploadError, onUploadComplete) {
  392. return Upload.api.upload(element, onUploadSuccess, onUploadError, onUploadComplete);
  393. },
  394. // AJAX异步上传
  395. send: function (file, onUploadSuccess, onUploadError, onUploadComplete) {
  396. var index = Layer.msg(__('Uploading'), {offset: 't', time: 0});
  397. var id = "dropzone-" + Dropzone.uuidv4();
  398. $('<button type="button" id="' + id + '" class="btn btn-danger hidden faupload" />').appendTo("body");
  399. $("#" + id).data("upload-complete", function (files) {
  400. Layer.close(index);
  401. Upload.list[id].removeAllFiles(true);
  402. });
  403. Upload.api.upload("#" + id, onUploadSuccess, onUploadError, onUploadComplete);
  404. setTimeout(function () {
  405. Upload.list[id].addFile(file);
  406. }, 1);
  407. },
  408. custom: {
  409. //自定义上传完成回调
  410. afteruploadcallback: function (response) {
  411. console.log(this, response);
  412. alert("Custom Callback,Response URL:" + response.url);
  413. },
  414. }
  415. }
  416. }
  417. ;
  418. return Upload;
  419. });