index.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. {extend name="../../base/view/common/base" /}
  2. {block name="style"}
  3. <style>
  4. body { display: flex; overflow: hidden; height: 100vh; }
  5. ::-webkit-scrollbar { display: none; width: 6px; height: 6px; }
  6. ::-webkit-scrollbar-thumb { border-radius: 10px; background-color: #e1e1e1; }
  7. .layui-tab{margin:0;}
  8. .container { display: flex; flex: 1; flex-direction: column; overflow: hidden; padding:12px;}
  9. .file-container { display: flex; flex: 1; flex-direction: column; overflow: hidden; border-radius: 2px; background: #ffffff; box-shadow: rgba(0, 0, 0, 0.05) 0 1px 2px 0; }
  10. .file-item {display: flex; flex: 1; justify-content: space-between; overflow: hidden; }
  11. .file-header {padding-top: 4px; }
  12. /** 分组 **/
  13. .file-item .group { position: relative; display: flex; flex-direction: column; padding-top: 8px; width: 200px; border-right: 1px solid #f6f6f6; }
  14. .file-item .group ul::-webkit-scrollbar { display: block; }
  15. .file-item .group ul { flex: 1; overflow: hidden; overflow-y: auto; }
  16. .file-item .group ul li {display: flex; align-items: center; justify-content: space-between; cursor:pointer; padding: 0 12px; height: 38px; font-size: 13px; color: #666666; }
  17. .file-item .group ul li i.iconfont{ margin-right:8px; font-size:24px; color:#E1AF1A; font-weight:800;}
  18. .file-item .group ul li > span { display: flex; flex: 1; overflow: hidden; margin-right: 0.5rem; text-overflow: ellipsis; white-space: nowrap; }
  19. .file-item .group ul li.active { background: #edefff; }
  20. .file-item .group ul li:hover { background: #f5f7fa; }
  21. .file-item .group ul li .dropdown:hover dl { display: block; }
  22. .file-item .group ul li .dropdown dl { position: absolute; top: 36px; right: -15px; z-index: 10000; display: none; padding: 5px 0; width: 88px; border-radius: 2px; text-align: center; background-color: #ffffff; box-shadow: #cccccc 0 0 10px; }
  23. .file-item .group ul li .dropdown dl dd { height: 32px; line-height: 32px; }
  24. .file-item .group ul li .dropdown dl dd:hover { color: #4a5dff; background-color: #edefff; }
  25. .file-item .group ul li .dropdown dl::before { position: absolute; top: -16px; left: 44px; z-index: 12; display: block; padding: 0; width: 0; height: 0; border-top: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 8px solid #ffffff; border-left: 8px solid transparent; content: ""; box-sizing: content-box; }
  26. .file-item .group .footer { display: flex; align-items: center; justify-content: center; width: 100%; height: 50px; border-top: 1px solid #f2f2f2; border-right: 1px solid #f2f2f2; }
  27. /** 菜单 **/
  28. .file-item .attach #move:hover { position: relative; opacity: 1; }
  29. .file-item .attach #move:hover .dropdown { display: block; background-color: #ffffff; }
  30. .file-item .attach .dropdown { position: absolute; top: 38px; z-index: 100000; display: none; padding: 5px 0; width: 150px; border: 1px solid #dddddd; text-align: left; background-color: #ffffff; line-height: 1.6; }
  31. .file-item .attach .dropdown em { font-size: 13px; font-weight: 400; color: #333333; font-style: normal; }
  32. .file-item .attach .dropdown em { display: block; clear: both; padding: 6px 20px; white-space: nowrap; }
  33. .file-item .attach .dropdown em:hover { background: #eeeeee; }
  34. .file-item .attach .dropdown em:first-child { font-size: 12px; color: #999999; }
  35. .file-item .attach .dropdown::before { position: absolute; top: -16px; left: 21px; z-index: 12; display: block; padding: 0; width: 0; height: 0; border-top: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 8px solid #ffffff; border-left: 8px solid transparent; content: ""; box-sizing: content-box; }
  36. .file-item .attach .dropdown::after { position: absolute; top: -18px; left: 20px; z-index: 10; display: block; padding: 0; width: 0; height: 0; border-top: 9px solid transparent; border-right: 9px solid transparent; border-bottom: 9px solid #cccccc; border-left: 9px solid transparent; content: ""; box-sizing: content-box; }
  37. /** 文件 **/
  38. .file-item .attach { position: relative; display: flex; flex: 1; flex-direction: column; }
  39. .file-item .attach .header { display: flex; align-items: center; justify-content: space-between; padding:12px 15px; margin:0;}
  40. .file-item .attach .header .search{ display: flex; }
  41. .file-item .attach .header .search input { height: 30px; border-color: #eeeeee; border-top-right-radius: 0; border-bottom-right-radius: 0; }
  42. .file-item .attach .header .search button { border-color: #eeeeee; background: #f5f7fa; border-top-left-radius: 0; border-bottom-left-radius: 0; }
  43. .file-item .attach .header .search button:hover { background-color: #eeeeef; }
  44. .file-item .attach .subject { flex: 1; overflow: hidden; overflow-y: auto; margin: 10px; box-sizing: border-box; }
  45. .file-item .attach .subject:hover::-webkit-scrollbar { display: block; }
  46. .file-item .attach .subject ul { display: flex; flex-wrap: wrap; }
  47. .file-item .attach .subject ul li { position: relative; height: 120px; margin: 8px; padding: 8px; border: 1px solid rgba(0, 0, 0, 0.05); border-radius: 3px; transition: all 0.2s ease-in-out; }
  48. .file-item .attach .subject ul li:hover {border: 1px solid #dddddd; background-color:#f5f5f5;}
  49. .file-item .attach .subject ul li.on {border: 1px solid #ff5722; }
  50. .file-item .attach .subject ul li img { width: 50px; height: 50px; padding:25px;}
  51. .file-item .attach .subject ul li img.file-image { width: 100px; height: 100px; padding:0; border-radius: 2px; }
  52. .file-item .attach .subject ul li video { width: 100px; height: 100px; border-radius: 3px; }
  53. .file-item .attach .subject ul li p {overflow: hidden; margin: 5px 0 0; width: 98px; font-size: 13px; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
  54. .file-item .attach .subject ul li .file-check{position: absolute; width:20px; height:20px; left: 0; top: 0; display: none; font-size: 14px; border-radius:2px 0 4px 0; text-align: center; line-height: 20px; color: #ffffff; background-color:#fff; border-right:1px solid #dddddd; border-bottom:1px solid #dddddd; cursor:pointer;}
  55. .file-item .attach ul li .layui-btn-ctrl{position:absolute; top:0; right:0; opacity: 0;}
  56. .file-item .attach ul li:hover .layui-btn-ctrl{opacity: 1;}
  57. .file-item .attach .subject ul li:hover .file-check{display: block;}
  58. .file-item .attach .subject ul li.on .file-check{ display: block; background: #ff5722; border-color:#ff5722}
  59. .file-item .attach .footer { display: flex; align-items: center; justify-content: end; padding: 5px 15px 0; height: 45px; border-top: 1px solid #f2f2f2; text-align: center; background: #ffffff; }
  60. /** 无数据 **/
  61. .file-item .empty { display: flex; flex: 1; align-items: center; flex-direction: column; justify-content: center; overflow: hidden; text-align: center; color: #cccccc; }
  62. .file-item .empty i { font-size: 180px; }
  63. .file-item .empty p { width: 180px; text-align: center; }
  64. </style>
  65. {/block}
  66. <!-- 主体 -->
  67. {block name="body"}
  68. <div class="container">
  69. <div class="file-container">
  70. <div class="file-header">
  71. <div class="layui-tabs layui-tab-brief" id="tab">
  72. <ul class="layui-tabs-header">
  73. <li class="layui-this" data-tab="0">全部</li>
  74. <li data-tab="1">图片</li>
  75. <li data-tab="2">视频</li>
  76. <li data-tab="3">音频</li>
  77. <li data-tab="4">文档</li>
  78. <li data-tab="5">压缩包</li>
  79. </ul>
  80. </div>
  81. </div>
  82. <div class="file-item">
  83. <!-- 分组 -->
  84. <div class="group">
  85. <ul id="group" class="groups">
  86. <li data-id="" class="active"><i class="iconfont icon-xiangmuguanli"></i><span>全部</span></li>
  87. <li data-id="0"><i class="iconfont icon-xiangmuguanli"></i><span>未分组</span></li>
  88. </ul>
  89. <div class="footer">
  90. <span class="layui-btn layui-btn-primary layui-btn-sm add-new">添加分组</span>
  91. </div>
  92. </div>
  93. <!-- 文件 -->
  94. <div class="attach">
  95. <!-- 工具 -->
  96. <form class="layui-form" lay-filter="barsearchform" style="display:block; margin:0;padding:0;">
  97. <div class="header">
  98. <div class="layui-btn-group">
  99. <span class="layui-btn layui-btn-sm layui-btn-normal" id="fileUpload">上传文件</span>
  100. <span class="layui-btn layui-btn-sm layui-btn-danger" id="fileDelete">批量删除</span>
  101. <span class="layui-btn layui-btn-sm layui-btn-warm" id="fileMove">移动至 <i class="layui-icon layui-icon-triangle-d"></i></span>
  102. <span style="margin-left:36px;"><input type="checkbox" name="select_all" lay-filter="all" title="全选"></span>
  103. </div>
  104. <div class="search">
  105. <input type="hidden" name="limit" value="44" />
  106. <input type="hidden" name="page" value="1" />
  107. <input type="hidden" name="tab" value="0" />
  108. <input type="hidden" name="group_id" value="" />
  109. <label><input type="text" name="keywords" placeholder="请输入名称" autocomplete="off" class="layui-input"></label>
  110. <button type="button" class="layui-btn layui-btn-sm layui-btn-primary" lay-submit="" lay-filter="webform"><i class="layui-icon layui-icon-search"></i></button>
  111. </div>
  112. </div>
  113. </form>
  114. <!-- 主体 -->
  115. <div class="subject">
  116. <ul id="filesBox"></ul>
  117. </div>
  118. <!-- 页脚 -->
  119. <div class="footer">
  120. <div id="laypage"></div>
  121. </div>
  122. </div>
  123. </div>
  124. </div>
  125. </div>
  126. <script type="text/html" id="toolbarDemo">
  127. <h3 class="h3-title" style="height:28px;">审批列表</h3>
  128. </script>
  129. {/block}
  130. <!-- /主体 -->
  131. {block name="copyright"}{/block}
  132. <!-- 脚本 -->
  133. {block name="script"}
  134. <script>
  135. const moduleInit = ['tool'];
  136. function isValidFileName(fileName) {
  137. const illegalChars = /[\\\/\*\:"<>|\?]/;
  138. return !illegalChars.test(fileName);
  139. }
  140. function gouguInit() {
  141. var table = layui.table, tool = layui.tool ,form = layui.form,laypage = layui.laypage,upload = layui.upload, tabs = layui.tabs, dropdown=layui.dropdown;
  142. let fileGroup = [{id:0,title:'未分组'}];
  143. tabs.on('afterChange(tab)', function(data){
  144. $('[name="tab"]').val(data.index);
  145. $('[lay-filter="webform"]').click();
  146. return false;
  147. });
  148. //监听多选框点击事件 通过 lay-filter="menu"来监听
  149. form.on('checkbox(all)', function (data) {
  150.   let val = data.value;
  151. if(data.elem.checked){
  152. //判断当前多选框是选中还是取消选中
  153. $('#filesBox li').addClass('on');
  154. }
  155. else{
  156. $('#filesBox li').removeClass('on');
  157. }
  158. });
  159. var uploadInst = upload.render({
  160. elem: '#fileUpload'
  161. ,url: "/api/index/upload"
  162. , accept: 'file' //普通文件
  163. , exts: 'jpeg|jpg|png|gif|doc|docx|ppt|pptx|xls|xlsx|pdf|zip|rar|7z|txt|mp4|mp3|wav|psd|svg' //只允许上传文件
  164. , before: function (obj) {
  165. layer.msg('上传中...', { time: 3600000 });
  166. }
  167. ,done: function (res) {
  168. layer.msg(res.msg);
  169. $('[lay-filter="webform"]').click();
  170. }, error: function (index, upload) {
  171. layer.msg('上传失败');
  172. }
  173. });
  174. $('body').on('click','.add-new',function(){
  175. add_group(0,'');
  176. });
  177. $('#group').on('click','li',function(){
  178. let id=$(this).data('id');
  179. $(this).siblings().removeClass('active');
  180. $(this).addClass('active');
  181. $('[name="group_id"]').val(id);
  182. $('[lay-filter="webform"]').click();
  183. });
  184. $('#fileDelete').on('click',function(){
  185. let select_array = [];
  186. $('#filesBox').find('li.on').each(function(index,item){
  187. select_array.push($(item).data('id'));
  188. })
  189. if(select_array.length<1){
  190. layer.msg('请先选择文件');
  191. }
  192. else{
  193. layer.confirm('确定要删除这些文件吗?请慎重', { icon: 3, title: '提示' }, function (index) {
  194. let callback = function (e) {
  195. layer.closeAll();
  196. layer.msg(e.msg);
  197. $('[lay-filter="webform"]').click();
  198. }
  199. tool.delete("/home/files/delete", {ids:select_array.join(',')}, callback);
  200. });
  201. }
  202. });
  203. function add_group(id,val){
  204. var title = '新增分组';
  205. if(id>0){
  206. title = '编辑分组';
  207. }
  208. layer.prompt({
  209. title: title,
  210. value: val,
  211. yes: function(index, layero) {
  212. // 获取文本框输入的值
  213. var value = layero.find(".layui-layer-input").val();
  214. if (value!='') {
  215. let callback = function (e) {
  216. layer.msg(e.msg);
  217. if(e.code==0){
  218. location.reload();
  219. }
  220. }
  221. tool.post("/home/files/add_group", {id: id,title: value}, callback);
  222. layer.close(index);
  223. } else {
  224. layer.msg('请填写分组名称');
  225. }
  226. }
  227. })
  228. }
  229. var data = form.val('barsearchform');
  230. get_files(data);
  231. get_group();
  232. function get_group(param){
  233. $.ajax({
  234. url:"/home/files/get_group",
  235. success:function(res){
  236. if(res.code==0){
  237. var group=res.data,item='';
  238. if(group.length>0){
  239. for(var a=0;a<group.length;a++){
  240. item+='<li data-id="'+group[a].id+'" data-title="'+group[a].title+'"><i class="iconfont icon-xiangmuguanli"></i><span>'+group[a].title+'</span><i class="layui-icon layui-icon-more-vertical dropdown-on"></i></li>';
  241. }
  242. $('#group').append(item);
  243. fileGroup = fileGroup.concat(group);
  244. // 自定义事件
  245. dropdown.render({
  246. elem: '.dropdown-on',
  247. trigger: 'hover',
  248. align: 'right',
  249. data: [{
  250. title: '重命名分组',
  251. id: 100
  252. },{
  253. title: '删除该分组',
  254. id: 101
  255. }],
  256. click: function(data, othis){
  257. let id = $(this.elem).parent().data('id');
  258. let title = $(this.elem).parent().data('title');
  259. if(data.id==100){
  260. add_group(id,title);
  261. }else{
  262. del_group(id);
  263. }
  264. }
  265. });
  266. }
  267. group.push({id:0,title:'未分组'});
  268. dropdown.render({
  269. elem: '#fileMove',
  270. data: group,
  271. click: function(obj){
  272. let select_array = [];
  273. $('#filesBox').find('li.on').each(function(index,item){
  274. select_array.push($(item).data('id'));
  275. })
  276. if(select_array.length<1){
  277. layer.msg('请先选择文件');
  278. }
  279. else{
  280. layer.confirm('确定要把选中的文件移动到『'+obj.title+'』分组吗?', { icon: 3, title: '提示' }, function (index) {
  281. let callback = function (e) {
  282. layer.closeAll();
  283. layer.msg(e.msg);
  284. $('[lay-filter="webform"]').click();
  285. }
  286. tool.delete("/home/files/move", {group_id:obj.id,ids:select_array.join(',')}, callback);
  287. });
  288. }
  289. }
  290. });
  291. }
  292. }
  293. });
  294. }
  295. function del_group(id) {
  296. layer.confirm('确定要删除该分组吗?请慎重', { icon: 3, title: '提示' }, function (index) {
  297. let callback = function (e) {
  298. layer.closeAll();
  299. layer.msg(e.msg);
  300. if(e.code==0){
  301. location.reload();
  302. }
  303. }
  304. tool.delete("/home/files/del_group", {ids:id}, callback);
  305. });
  306. }
  307. function get_files(param){
  308. var loadIndex = layer.load(0);
  309. $.ajax({
  310. url:"/home/files/index",
  311. data:param,
  312. complete:function(){
  313. setTimeout(function(){
  314. layer.close(loadIndex)
  315. }, 200);
  316. },
  317. success:function(res){
  318. $('[name="select_all"]').prop('checked', false);
  319. form.render('checkbox');
  320. if(res.code==0){
  321. laypage.render({
  322. elem: 'laypage',
  323. limit:param['limit'],
  324. curr:param['page'],
  325. count: res.count, // 数据总数
  326. jump: function(obj, first){
  327. console.log(obj.curr); // 得到当前页,以便向服务端请求对应页的数据。
  328. console.log(obj.limit); // 得到每页显示的条数
  329. // 首次不执行
  330. if(!first){
  331. var data = form.val('barsearchform');
  332. data['page'] = obj.curr;
  333. get_files(data);
  334. }
  335. }
  336. });
  337. var item=res.data,li='';
  338. if(item.length>0){
  339. for(var a=0;a<item.length;a++){
  340. let image = ['jpg','jpeg','png','gif'];
  341. let office = ['doc','docx','xls','xlsx','ppt','pptx'];
  342. let zip = ['zip','rar','7z','gz','tar'];
  343. let video = ['mpg','mp4','mpeg','avi','wmv','mov','flv','m4v'];
  344. let audio = ['mp3','wav','wma','flac','midi'];
  345. let type = 0,ext="zip";
  346. // 判断元素是否在数组中
  347. let path='/static/home/images/icon/file.png';
  348. if (image.includes(item[a].fileext)) {
  349. path=item[a].thumbpath;
  350. type = 1;
  351. ext="image";
  352. }
  353. if (item[a].fileext == 'pdf'||item[a].fileext == 'txt') {
  354. type = 1;
  355. ext="pdf";
  356. path='/static/home/images/icon/'+item[a].fileext+'.png';
  357. }
  358. if (office.includes(item[a].fileext)) {
  359. type = 1;
  360. ext="office";
  361. path='/static/home/images/icon/'+item[a].fileext+'.png';
  362. }
  363. if (video.includes(item[a].fileext)) {
  364. type = 1;
  365. ext="video";
  366. path='/static/home/images/icon/video.png';
  367. }
  368. if (audio.includes(item[a].fileext)) {
  369. type = 1;
  370. ext="audio";
  371. path='/static/home/images/icon/audio.png';
  372. }
  373. if (zip.includes(item[a].fileext)) {
  374. type = 1;
  375. ext="zip";
  376. path='/static/home/images/icon/rar.png';
  377. }
  378. ctrl = '<span class="layui-btn layui-btn-xs layui-btn-normal file-ctrl" data-ctrl="edit" data-id="'+item[a].id+'" data-fileid="'+item[a].id+'" data-href="'+item[a].filepath+'" data-filename="'+item[a].name+'" data-ext="'+ext+'" data-type="'+type+'">操作</span>';
  379. li+='<li data-id="'+item[a].id+'" data-title="'+item[a].name+'" data-ext="'+item[a].fileext+'"><img src="'+path+'" alt="'+item[a].name+'" style="object-fit: contain;" class="file-items file-'+ext+'"><p title="'+item[a].name+'">'+item[a].name+'</p><div class="layui-btn-ctrl">'+ctrl+'<span class="name-edit green" style="display:none;" data-id="'+item[a].id+'" data-fileid="'+item[a].id+'" id="fileEdit'+item[a].id+'" title="重命名"></span><span class="file-delete red" style="display:none;" data-id="'+item[a].id+'" data-fileid="'+item[a].id+'" id="fileDel'+item[a].id+'" title="删除"></span></div><div class="file-check">✔</div></li>';
  380. }
  381. $('#filesBox').html(li);
  382. $('#laypage').show();
  383. }
  384. else{
  385. $('#filesBox').html('<div class="empty"><i class="layui-icon layui-icon-upload"></i><p>无文件文件,赶紧去上传吧!</p></div>');
  386. $('#laypage').hide();
  387. }
  388. }
  389. }
  390. });
  391. }
  392. $('#filesBox').on('click','.file-check',function(){
  393. $(this).parent().toggleClass("on");
  394. })
  395. $('#filesBox').on('click','.file-delete',function(){
  396. let id = $(this).parent().parent().data('id');
  397. layer.confirm('确定要删除该文件吗?请慎重', { icon: 3, title: '提示' }, function (index) {
  398. let callback = function (e) {
  399. layer.closeAll();
  400. layer.msg(e.msg);
  401. $('[lay-filter="webform"]').click();
  402. }
  403. tool.delete("/home/files/delete", {ids:id}, callback);
  404. });
  405. })
  406. $('#filesBox').on('click','.name-edit',function(){
  407. let id = $(this).parent().parent().data('id');
  408. let title = $(this).parent().parent().data('title');
  409. let ext = $(this).parent().parent().data('ext');
  410. layer.prompt({
  411. title: '重命名',
  412. value: title.replace(/\.[^.]+$/, ""),
  413. yes: function(index, layero) {
  414. // 获取文本框输入的值
  415. var value = layero.find(".layui-layer-input").val();
  416. if (value!='') {
  417. if(isValidFileName(value)==false){
  418. layer.msg('文件名不能包含下列任何字符:\/:*?".<>|');
  419. return false;
  420. }
  421. let callback = function (e) {
  422. layer.msg(e.msg);
  423. $('[lay-filter="webform"]').click();
  424. }
  425. tool.post("/home/files/edit", {id: id,title: value+'.'+ext}, callback);
  426. layer.close(index);
  427. } else {
  428. layer.msg('请填写文件名称');
  429. }
  430. }
  431. })
  432. })
  433. //监听搜索提交
  434. form.on('submit(webform)', function(data) {
  435. get_files(data.field);
  436. return false;
  437. });
  438. }
  439. </script>
  440. {/block}
  441. <!-- /脚本 -->