file.library.js 18 KB

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