file.library.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. ;(function ($, window, document, undefined) {
  2. /**
  3. * 文件库模块
  4. * @param trigger
  5. * @param options
  6. * @constructor
  7. */
  8. function FileLibrary(trigger, options) {
  9. // 配置项
  10. var defaults = {
  11. type: [],
  12. layerId: 'file-library'
  13. , layerSkin: 'file-library'
  14. , accept: {
  15. title: 'Images',
  16. extensions: 'gif,jpg,jpeg,bmp,png',
  17. mimeTypes: 'image/*'
  18. },
  19. };
  20. this.options = $.extend({}, defaults, options);
  21. // 触发对象
  22. this.$trigger = trigger;
  23. this.$touch = null; // 当前触发元素
  24. // 容器元素
  25. this.$element = null;
  26. // 初始化对象事件
  27. this.init();
  28. }
  29. FileLibrary.prototype = {
  30. data: {
  31. selectedList: []
  32. },
  33. /**
  34. * 初始化
  35. */
  36. init: function () {
  37. var _this = this;
  38. // 打开文件库事件
  39. _this.triggerEvent();
  40. },
  41. /**
  42. * 打开文件库事件
  43. */
  44. triggerEvent: function () {
  45. var _this = this;
  46. if (_this.$trigger !== false) {
  47. // 点击开启文件库弹窗
  48. _this.$trigger.unbind().click(function () {
  49. _this.$touch = $(this);
  50. _this.showLibraryModal();
  51. });
  52. } else {
  53. _this.showLibraryModal();
  54. }
  55. },
  56. /**
  57. * 显示文件库弹窗
  58. */
  59. showLibraryModal: function () {
  60. var _this = this;
  61. _this.getJsonData({group_id: -1, type_arr: _this.options.type}, function (data) {
  62. data.is_default = true;
  63. // 捕获页
  64. layer.open({
  65. type: 1
  66. , id: _this.options.layerId
  67. , title: '文件库'
  68. , skin: _this.options.layerSkin
  69. , area: '840px'
  70. , offset: 'auto'
  71. , anim: 1
  72. , closeBtn: 1
  73. , shade: 0.3
  74. , btn: ['确定', '取消']
  75. , content: template('tpl-file-library', data)
  76. , success: function (layero) {
  77. // 初始化文件库弹窗
  78. _this.initModal(layero);
  79. }
  80. , yes: function (index) {
  81. // 确认回调
  82. _this.done();
  83. layer.close(index);
  84. }
  85. });
  86. });
  87. },
  88. /**
  89. * 初始化文件库弹窗
  90. */
  91. initModal: function (element) {
  92. var _this = this;
  93. _this.$element = element;
  94. // 清空选中的文件
  95. _this.onEmptySelected();
  96. // 注册分组下拉选择组件
  97. _this.selectDropdown();
  98. // 注册分类切换事件
  99. _this.switchClassEvent();
  100. // 注册文件点击选中事件
  101. _this.selectFilesEvent();
  102. // 新增分组事件
  103. _this.addGroupEvent();
  104. // 编辑分组事件
  105. _this.editGroupEvent();
  106. // 删除分组事件
  107. _this.deleteGroupEvent();
  108. //注意上传类型
  109. _this.uploadFileType();
  110. // 注册文件上传事件
  111. _this.uploadImagesEvent();
  112. // 注册文件删除事件
  113. _this.deleteFilesEvent();
  114. // 注册文件移动事件
  115. _this.moveFilesEvent();
  116. // 注册文件列表分页事件
  117. _this.fileListPage();
  118. },
  119. /**
  120. * 清空选中的文件
  121. */
  122. onEmptySelected: function () {
  123. this.data.selectedList = [];
  124. },
  125. /**
  126. * 注册文件列表分页事件
  127. */
  128. fileListPage: function () {
  129. var _this = this;
  130. _this.$element.find('#file-list-body').on('click', '.switch-page', function () {
  131. var page = $(this).data('page');
  132. _this.renderFileList(page);
  133. });
  134. },
  135. /**
  136. * 注册上传文件类型
  137. */
  138. uploadFileType: function () {
  139. var _this = this;
  140. var type = _this.options.type;
  141. //判断传入的值是否是数组
  142. // if (type instanceof Array == false) {
  143. // return;
  144. // }
  145. if (!Array.isArray(type)) {
  146. return;
  147. }
  148. var extensions = '';
  149. var mimeTypes = '';
  150. $.each(type, function (index, item) {
  151. if (item == 'image') {
  152. extensions += 'gif,jpg,jpeg,bmp,png,';
  153. mimeTypes += 'image/*,';
  154. }
  155. if (item == 'pdf') {
  156. extensions += 'pdf,';
  157. mimeTypes += 'application/pdf,';
  158. }
  159. if (item == 'video') {
  160. extensions += 'mp4,';
  161. mimeTypes += 'video/mp4,';
  162. }
  163. })
  164. _this.options.accept = {
  165. extensions: extensions,
  166. mimeTypes: mimeTypes,
  167. };
  168. },
  169. /**
  170. * 文件移动事件
  171. */
  172. moveFilesEvent: function () {
  173. var _this = this
  174. , $groupSelect = _this.$element.find('.group-select');
  175. // 绑定文件选中事件
  176. $groupSelect.on('click', '.move-file-group', function () {
  177. $groupSelect.dropdown('close');
  178. var groupId = $(this).data('group-id')
  179. , fileIds = _this.getSelectedFileIds();
  180. if (fileIds.length === 0) {
  181. layer.msg('您还没有选择任何文件~', {offset: 't', anim: 6});
  182. return false;
  183. }
  184. layer.confirm('确定移动选中的文件吗?', {title: '友情提示'}, function (index) {
  185. var load = layer.load();
  186. $.post(STORE_URL + '/upload.library/moveFiles', {
  187. group_id: groupId
  188. , fileIds: fileIds
  189. }, function (result) {
  190. layer.msg(result.msg);
  191. if (result.code === 1) {
  192. _this.renderFileList();
  193. }
  194. layer.close(load);
  195. });
  196. layer.close(index);
  197. });
  198. });
  199. },
  200. /**
  201. * 删除选中的文件
  202. */
  203. deleteFilesEvent: function () {
  204. var _this = this;
  205. _this.$element.on('click', '.file-delete', function () {
  206. var fileIds = _this.getSelectedFileIds();
  207. if (fileIds.length === 0) {
  208. layer.msg('您还没有选择任何文件~', {offset: 't', anim: 6});
  209. return;
  210. }
  211. layer.confirm('确定删除选中的文件吗?', {title: '友情提示'}, function (index) {
  212. var load = layer.load();
  213. $.post(STORE_URL + '/upload.library/deleteFiles', {
  214. fileIds: fileIds
  215. }, function (result) {
  216. layer.close(load);
  217. if (result.code === 1) {
  218. _this.renderFileList();
  219. }
  220. });
  221. layer.close(index);
  222. });
  223. });
  224. },
  225. /**
  226. * 文件上传 (多文件)
  227. */
  228. uploadImagesEvent: function () {
  229. var _this = this;
  230. var loadIndex = null;
  231. // 文件大小
  232. var maxSize = this.options.maxSize;
  233. // 初始化Web Uploader
  234. var uploader = WebUploader.create({
  235. // 选完文件后,是否自动上传。
  236. auto: true,
  237. // 文件接收服务端。
  238. server: STORE_URL + '/upload/image',
  239. // 选择文件的按钮。可选。
  240. // 内部根据当前运行是创建,可能是input元素,也可能是flash.
  241. pick: {
  242. id: '.j-upload',
  243. multiple: true
  244. },
  245. // 文件上传域的name
  246. fileVal: 'iFile',
  247. // 图片上传前不进行压缩
  248. compress: false,
  249. // 允许重复
  250. duplicate: true,
  251. // 文件总数量
  252. // fileNumLimit: 10,
  253. // 文件大小2m => 2097152
  254. fileSingleSizeLimit: maxSize * 1024,
  255. // 只允许选择图片文件。
  256. accept: this.options.accept,
  257. // 文件上传header扩展
  258. headers: {
  259. 'Accept': 'application/json, text/javascript, */*; q=0.01',
  260. 'X-Requested-With': 'XMLHttpRequest'
  261. }
  262. });
  263. // 验证大小
  264. uploader.on('error', function (type) {
  265. if (type === 'F_DUPLICATE') {
  266. console.log('请不要重复选择文件!');
  267. } else if (type === 'F_EXCEED_SIZE') {
  268. alert('文件大小不可超过' + maxSize/1024 + 'm 哦!换个小点的文件吧!');
  269. }
  270. });
  271. // 文件上传前触发,添加附带参数
  272. uploader.on('uploadBeforeSend', function (obj, data) {
  273. data.group_id = _this.getCurrentGroupId();
  274. });
  275. // 文件上传成功,给item添加成功class, 用样式标记上传成功。
  276. uploader.on('uploadSuccess', function (file, response) {
  277. if (response.code === 1) {
  278. var $list = _this.$element.find('ul.file-list-item');
  279. $list.prepend(template('tpl-file-list-item', [response.data]));
  280. } else {
  281. uploader.uploadError(file, response);
  282. }
  283. });
  284. // 监听文件上传失败
  285. uploader.on('uploadError', function (file, reason) {
  286. uploader.uploadError(file, reason);
  287. });
  288. // 文件上传失败回调函数
  289. uploader.uploadError = function (file, reason) {
  290. layer.msg(reason.msg, {anim: 6});
  291. };
  292. // 文件开始上传
  293. uploader.on('startUpload', function () {
  294. loadIndex = layer.load();
  295. });
  296. // 文件上传结束
  297. uploader.on('uploadFinished', function () {
  298. layer.close(loadIndex);
  299. });
  300. },
  301. /**
  302. * 新增分组事件
  303. */
  304. addGroupEvent: function () {
  305. var _this = this
  306. , $groupList = _this.$element.find('.file-group > ul');
  307. _this.$element.on('click', '.group-add', function () {
  308. layer.prompt({title: '请输入新分组名称'}, function (value, index) {
  309. var load = layer.load();
  310. $.post(STORE_URL + '/upload.library/addGroup', {
  311. group_name: value,
  312. group_type: _this.options.type
  313. }, function (result) {
  314. layer.msg(result.msg);
  315. if (result.code === 1) {
  316. $groupList.append(template('tpl-group-item', result.data));
  317. var $groupSelectList = _this.$element.find('.group-select > .group-list');
  318. $groupSelectList.append(
  319. '<li>' +
  320. ' <a class="move-file-group" data-group-id="' + result.data.group_id + '"' +
  321. ' href="javascript:void(0);">' + result.data.group_name + '</a>' +
  322. '</li>'
  323. );
  324. }
  325. layer.close(load);
  326. });
  327. layer.close(index);
  328. });
  329. });
  330. },
  331. /**
  332. * 编辑分组事件
  333. */
  334. editGroupEvent: function () {
  335. var _this = this;
  336. _this.$element.find('.file-group').on('click', '.group-edit', function () {
  337. var $li = $(this).parent()
  338. , group_id = $li.data('group-id');
  339. layer.prompt({title: '修改分组名称', value: $li.attr('title')}, function (value, index) {
  340. var load = layer.load();
  341. $.post(STORE_URL + '/upload.library/editGroup', {
  342. group_id: group_id
  343. , group_name: value
  344. }, function (result) {
  345. layer.msg(result.msg);
  346. if (result.code === 1) {
  347. $li.attr('title', value).find('.group-name').text(value);
  348. var $groupSelectList = _this.$element.find('.group-select > .group-list');
  349. $groupSelectList.find('[data-group-id="' + group_id + '"]').text(value);
  350. }
  351. layer.close(load);
  352. });
  353. layer.close(index);
  354. });
  355. return false;
  356. });
  357. },
  358. /**
  359. * 删除分组事件
  360. */
  361. deleteGroupEvent: function () {
  362. var _this = this;
  363. _this.$element.find('.file-group').on('click', '.group-delete', function () {
  364. var $li = $(this).parent()
  365. , group_id = $li.data('group-id');
  366. layer.confirm('确定删除该分组吗?', {title: '友情提示'}, function (index) {
  367. var load = layer.load();
  368. $.post(STORE_URL + '/upload.library/deleteGroup', {
  369. group_id: group_id
  370. }, function (result) {
  371. layer.msg(result.msg);
  372. if (result.code === 1) {
  373. $li.remove();
  374. var $groupSelectList = _this.$element.find('.group-select > .group-list');
  375. $groupSelectList.find('[data-group-id="' + group_id + '"]').remove();
  376. }
  377. layer.close(load);
  378. });
  379. layer.close(index);
  380. });
  381. return false;
  382. });
  383. },
  384. /**
  385. * 注册文件选中事件
  386. */
  387. selectFilesEvent: function () {
  388. var _this = this;
  389. // 绑定文件选中事件
  390. _this.$element.find('#file-list-body').on('click', '.file-list-item li', function () {
  391. var $this = $(this)
  392. , data = {
  393. file_id: $this.data('file-id')
  394. , file_path: $this.data('file-path')
  395. , cover_file_path: $this.data('cover-file-path')
  396. , origin_name: $this.data('origin-name')
  397. }
  398. , selectedList = _this.data.selectedList
  399. , index = $.arrayFilterMultiple(selectedList, 'file_id', data.file_id);
  400. index === false ? selectedList.push(data) : selectedList.splice(index, 1);
  401. // 选中状态
  402. $this.toggleClass('active');
  403. });
  404. },
  405. /**
  406. * 分类切换事件
  407. */
  408. switchClassEvent: function () {
  409. var _this = this;
  410. // 注册分类切换事件
  411. _this.$element.find('.file-group').on('click', 'li', function () {
  412. var $this = $(this);
  413. // 切换选中状态
  414. $this.addClass('active').siblings('.active').removeClass('active');
  415. // 重新渲染文件列表
  416. _this.renderFileList();
  417. });
  418. },
  419. /**
  420. * 注册分组下拉选择组件
  421. */
  422. selectDropdown: function () {
  423. this.$element.find('.group-select').dropdown();
  424. },
  425. /**
  426. * 获取文件库列表数据
  427. * @param params
  428. * @param success
  429. */
  430. getJsonData: function (params, success) {
  431. var loadIndex = layer.load();
  432. typeof params === 'function' && (success = params);
  433. // 获取文件库列表
  434. $.getJSON(STORE_URL + '/upload.library/fileList', params, function (result) {
  435. layer.close(loadIndex);
  436. if (result.code === 1) {
  437. typeof success === 'function' && success(result.data);
  438. } else {
  439. layer.msg(result.msg, {anim: 6});
  440. }
  441. });
  442. },
  443. /**
  444. * 重新渲染文件列表
  445. * @param page
  446. */
  447. renderFileList: function (page) {
  448. var _this = this
  449. , groupId = this.getCurrentGroupId();
  450. // 重新渲染文件列表
  451. _this.getJsonData({group_id: groupId, page: page || 1,type_arr: _this.options.type}, function (data) {
  452. _this.$element.find('#file-list-body').html(template('tpl-file-list', data['file_list']));
  453. });
  454. // 清空选中的文件
  455. _this.onEmptySelected();
  456. },
  457. /**
  458. * 获取选中的文件列表
  459. * @returns {Array}
  460. */
  461. getSelectedFiles: function () {
  462. // var selectedList = [];
  463. // this.$element.find('.file-list-item > li.active').each(function (index) {
  464. // var $this = $(this);
  465. // selectedList[index] = {
  466. // file_id: $this.data('file-id')
  467. // , file_path: $this.data('file-path')
  468. // };
  469. // });
  470. // return selectedList;
  471. return this.data.selectedList;
  472. },
  473. /**
  474. * 获取选中的文件的ID集
  475. * @returns {Array}
  476. */
  477. getSelectedFileIds: function () {
  478. var fileList = this.getSelectedFiles();
  479. var data = [];
  480. fileList.forEach(function (item) {
  481. data.push(item.file_id);
  482. });
  483. return data;
  484. },
  485. /**
  486. * 获取当前分组id
  487. * @returns {*}
  488. */
  489. getCurrentGroupId: function () {
  490. return this.$element.find('.file-group > ul > li.active').data('group-id');
  491. },
  492. /**
  493. * 确认回调
  494. */
  495. done: function () {
  496. var selectedList = this.getSelectedFiles();
  497. selectedList.length > 0 && typeof this.options.done === 'function'
  498. && this.options.done(selectedList, this.$touch);
  499. }
  500. };
  501. // 在Jquery插件中使用FileLibrary对象
  502. $.fn.fileLibrary = function (options) {
  503. new FileLibrary(this, options);
  504. };
  505. // 在Jquery插件中使用FileLibrary对象
  506. $.fileLibrary = function (options) {
  507. new FileLibrary(false, options);
  508. };
  509. })(jQuery, window, document);