index.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>layui</title>
  6. <meta name="renderer" content="webkit">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  8. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  9. <link rel="stylesheet" href="__PUBLIC__/layui/css/layui.css" media="all">
  10. <link rel="stylesheet" href="__PUBLIC__/font-awesome/css/font-awesome.min.css" media="all"/>
  11. <link rel="stylesheet" href="__CSS__/admin.css" media="all">
  12. </head>
  13. <body style="padding:10px;">
  14. <div class="tplay-body-div">
  15. <div class="layui-tab">
  16. <ul class="layui-tab-title">
  17. <li class="layui-this">文件列表</li>
  18. <li><a href="javascript:;" permission="{:url('upload')}" class="a_menu" id="upload">上传文件</a></li>
  19. </ul>
  20. </div>
  21. <form class="layui-form serch" action="{:url('index')}" method="post">
  22. <div class="layui-form-item" style="float: left;">
  23. <div class="layui-input-inline" style="width:260px">
  24. <input type="text" name="keyword" autocomplete="off" placeholder="请输入文件名称,或文件路径"
  25. class="layui-input layui-btn-sm">
  26. </div>
  27. <div class="layui-input-inline" style="width:75px">
  28. <button class="layui-btn layui-btn-sm" lay-submit="" lay-filter="serch">筛选</button>
  29. </div>
  30. </div>
  31. </form>
  32. <script type="text/html" id="toolbarDemo">
  33. <div class="layui-btn-container">
  34. <button class="layui-btn layui-btn-sm" lay-event="createDir">新建目录</button>
  35. {notempty name="relative_path"}
  36. <span style="display: inline-block;margin-right: 10px;"><i class="layui-icon">当前目录 {$Think.DS}{$relative_path}</i></span>
  37. <button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="goback">返回上级</button>
  38. {/notempty}
  39. </div>
  40. </script>
  41. <table class="layui-table" id="table" lay-filter="table"></table>
  42. {include file="public/foot"}
  43. <script src="__PUBLIC__/clipboard.min.js"></script>
  44. <a id="down"></a>
  45. <script type="text/javascript">
  46. layui.use(['table', 'layer', 'form'], function () {
  47. var table = layui.table,
  48. form = layui.form,
  49. layer = layui.layer;
  50. //第一个实例
  51. table.render({
  52. id: 'table'
  53. , elem: '#table'
  54. , size: 'sm' //小尺寸的表格
  55. , toolbar: '#toolbarDemo'
  56. , defaultToolbar: []
  57. , limits: [10]
  58. , url: "{:url('index')}?relative_path={$relative_path|replaceUrlDS}" //数据接口
  59. , cols: [[ //表头
  60. {type: 'checkbox'},
  61. {
  62. field: 'filename', title: '名称 (可点击)', minWidth: 120, templet: function (row) {
  63. var fullname = getfullname(row.filename, row.fileext, row.filetype);
  64. var relative_path = "{notempty name='$relative_path'}{$relative_path|replaceUrlDS}/{/notempty}";
  65. if(row.filetype == 'dir'){
  66. return "<a href=\"{:url('index')}?relative_path=" + relative_path + fullname + "\">" + '<i class="fa fa-folder fa-lg" style="color: orange"/> ' + fullname + "</a>";
  67. }else{
  68. return "<a href='javascript:;' lay-event=\"edit\">" + '<i class="fa fa-file-o"/> ' + fullname + "</a>";
  69. }
  70. }
  71. },
  72. {
  73. field: 'path', title: '路径', templet: function (row) {
  74. var fullname = getfullname(row.filename, row.fileext, row.filetype);
  75. return "{$fullPath|addslashes}" + fullname;
  76. }
  77. },
  78. {
  79. field: 'filetype', title: '类型', width: 80, templet: function (row) {
  80. return row.filetype == 'file' ? "文件" : (row.filetype == "dir" ? "目录" : row.filetype );
  81. }
  82. },
  83. {
  84. field: 'filesize', title: '大小', width: 100, templet: function (row) {
  85. return row.filetype == 'dir' ? '' : format_bytes(row.filesize, '');
  86. }
  87. },
  88. {field: 'fileatime', title: '最后访问时间', width: 150},
  89. {field: 'filectime', title: '索引修改时间', width: 150},
  90. {field: 'filemtime', title: '内容修改时间', width: 150},
  91. {field: 'action', title: '操作', align: 'center', fixed: 'right', width: 160 ,templet:function (row) {
  92. var html = '<div class="layui-btn-group">';
  93. if(row.filetype == 'dir'){
  94. html+='<button class="layui-btn layui-btn-xs a_menu" lay-event="down" title="打开">打开</button>';
  95. }else{
  96. html+='<button class="layui-btn layui-btn-xs a_menu" lay-event="down" title="下载">下载</button>';
  97. }
  98. return html +'<button class="layui-btn layui-btn-xs a_menu" lay-event="rename" title="改名">改名</button>'
  99. +'<button class="layui-btn layui-btn-xs a_menu" lay-event="del" title="删除">删除</button>'
  100. + '</div>';
  101. }}
  102. ]],
  103. done: function (res, curr, count) {
  104. if (res.url) {
  105. console.log(res.url + '?relative_path=' + res.msg)
  106. location.href = res.url + '?relative_path=' + res.msg
  107. }
  108. }
  109. });
  110. form.on('submit(serch)', function (data) {
  111. table.reload('table', {
  112. where: data.field
  113. , page: {
  114. curr: 1 //重新从第 1 页开始
  115. }
  116. });
  117. return false;
  118. });
  119. //编辑
  120. table.on('tool(table)', function (obj) {
  121. if (obj.event == 'edit') {
  122. var filename = obj.data.filename;
  123. var fileext = obj.data.fileext;
  124. var filetype = obj.data.filetype;
  125. var relative_path = "{notempty name='$relative_path'}{$relative_path|replaceUrlDS}/{/notempty}";
  126. var fullname = getfullname(filename, fileext, filetype);
  127. if (filetype == 'dir') {
  128. location.href = "{:url('index')}?relative_path=" + relative_path + fullname;
  129. return;
  130. }
  131. var editable = ["txt", "html", "css", "js", "log"];
  132. if (editable.indexOf(fileext) > -1) {
  133. window.parent.tab.tabAdd({
  134. icon: "fa-bookmark",
  135. id: 'filemanage_' + filename + fileext,
  136. title: '文件:' + fullname,
  137. url: "{:url('publish')}?relative_path={$relative_path|replaceUrlDS}&fullname=" + fullname
  138. });
  139. return;
  140. }
  141. var imgs = ["jpg", "png", "gif", "jpeg"];
  142. if (imgs.indexOf(fileext) > -1) {
  143. window.open("/uploads/q1464674022/" + relative_path + fullname, "_blank")
  144. return;
  145. }
  146. var videos = ["mp4"];
  147. if (videos.indexOf(fileext) > -1) {
  148. var src = "/uploads/q1464674022/" + relative_path + fullname;
  149. layer.open({
  150. type: 2,
  151. title: fullname,
  152. content: src,
  153. area: ['500px', '300px'],
  154. btn: ['复制代码'],
  155. btnAlign: 'c',
  156. yes: function(index, layero){
  157. var clipboard = new ClipboardJS('.layui-layer-btn0', {
  158. text: function () {
  159. return '<video width="100%" height="100%" src="'+src+'" autoplay="autoplay" controls="controls"> <source src="'+src+'" type="video/mp4"> </video>';
  160. }
  161. });
  162. clipboard.on('success', function (e) {
  163. layer.close(index);//如果设定了yes回调,需进行手工关闭
  164. layer.msg('复制成功');
  165. });
  166. clipboard.on('error', function (e) {
  167. console.log(e);
  168. layer.msg('复制失败');
  169. });
  170. }
  171. });
  172. return;
  173. }
  174. var src = "/uploads/q1464674022/" + relative_path + fullname;
  175. var download = document.getElementById('down');
  176. download.setAttribute('href', src);
  177. download.setAttribute('download', fullname);
  178. download.click();
  179. }
  180. else if (obj.event == 'down') {
  181. var filename = obj.data.filename;
  182. var fileext = obj.data.fileext;
  183. var filetype = obj.data.filetype;
  184. var relative_path = "{notempty name='$relative_path'}{$relative_path|replaceUrlDS}/{/notempty}";
  185. var fullname = getfullname(filename, fileext, filetype);
  186. if (filetype == 'dir') {
  187. location.href = "{:url('index')}?relative_path=" + relative_path + fullname;
  188. return;
  189. }
  190. var src = "/uploads/q1464674022/" + relative_path + fullname;
  191. var download = document.getElementById('down');
  192. download.setAttribute('href', src);
  193. download.setAttribute('download', fullname);
  194. download.click();
  195. }
  196. else if (obj.event == 'del') {
  197. var fullname = getfullname(obj.data.filename, obj.data.fileext, obj.data.filetype);
  198. layer.confirm('确定要删除?', function (index) {
  199. $.ajax({
  200. url: "{:url('delete')}",
  201. dataType: 'json',
  202. type: 'post',
  203. data: {fullname: fullname, relative_path: '{$relative_path|replaceUrlDS}'},
  204. success: function (res) {
  205. layer.msg(res.msg);
  206. if (res.code == 1) {
  207. table.reload('table');
  208. }
  209. }
  210. })
  211. })
  212. }
  213. else if (obj.event == 'rename') {
  214. var fullname = getfullname(obj.data.filename, obj.data.fileext, obj.data.filetype);
  215. layer.prompt({
  216. title: '重命名 ' + fullname,
  217. value: fullname,
  218. }, function (value, index, elem) {
  219. $.post("{:url('rename')}", {
  220. oldname: fullname,
  221. newname: value,
  222. relative_path: '{$relative_path|replaceUrlDS}'
  223. }, function (res) {
  224. layer.msg(res.msg);
  225. if (res.code == 1) {
  226. table.reload('table');
  227. }
  228. });
  229. layer.close(index);
  230. });
  231. }
  232. });
  233. //监听事件
  234. table.on('toolbar(table)', function (obj) {
  235. if (obj.event == 'ftp_cover') {
  236. var checkStatus = table.checkStatus(obj.config.id);//获取选中的数据
  237. var data = checkStatus.data;
  238. if (data.length > 0) {
  239. var ids = [];//数组
  240. data.forEach(function (item, key) {
  241. var fullname = getfullname(item.filename, item.fileext, item.filetype);
  242. ids[key] = fullname;
  243. })
  244. layer.confirm('确认覆盖远程?', function (index, layero) {
  245. var load = layer.load(1, {
  246. shade: [0.1, '#fff'] //0.1透明度的白色背景
  247. });
  248. $.ajax({
  249. url: "{:url('ftpCover')}",
  250. dataType: 'json',
  251. data: {"file_list": ids, relative_path: '{$relative_path|replaceUrlDS}'},
  252. type: 'post',
  253. success: function (res) {
  254. layer.alert(res.msg, function (index) {
  255. layer.msg(res.msg);
  256. })
  257. },
  258. complete: function () {
  259. layer.close(load);
  260. }
  261. })
  262. layer.close(index)
  263. });
  264. } else {
  265. layer.msg('请先勾选需要操作的记录');
  266. }
  267. }
  268. else if (obj.event == 'goback') {
  269. location.href = "{:url('index')}?relative_path={$parentPath|replaceUrlDS}"
  270. }
  271. else if (obj.event == 'createDir') {
  272. layer.prompt({
  273. title: '新建',
  274. value: '新建文件夹',
  275. }, function (value, index, elem) {
  276. $.post("{:url('createDir')}", {
  277. name: value,
  278. relative_path: '{$relative_path|replaceUrlDS}'
  279. }, function (res) {
  280. layer.msg(res.msg);
  281. if (res.code == 1) {
  282. table.reload('table');
  283. }
  284. });
  285. layer.close(index);
  286. });
  287. }
  288. else if (obj.event == 'unzip') {
  289. var checkStatus = table.checkStatus(obj.config.id);//获取选中的数据
  290. var data = checkStatus.data;
  291. if (data.length > 0) {
  292. var ids = [];//数组
  293. var stop = 0;
  294. data.forEach(function (item, key) {
  295. if ('zip' != item.fileext) {
  296. stop = 1;
  297. }
  298. var fullname = getfullname(item.filename, item.fileext, item.filetype);
  299. ids[key] = fullname;
  300. })
  301. if (stop) {
  302. layer.msg('只支持zip文件解压');
  303. return;
  304. }
  305. layer.confirm('解压会覆盖同名文件,请确认?', function (index, layero) {
  306. var load = layer.load(1, {
  307. shade: [0.1, '#fff'] //0.1透明度的白色背景
  308. });
  309. $.ajax({
  310. url: "{:url('unzip')}",
  311. dataType: 'json',
  312. data: {"file_list": ids, relative_path: '{$relative_path|replaceUrlDS}'},
  313. type: 'post',
  314. success: function (res) {
  315. layer.alert(res.msg, function (index) {
  316. layer.msg(res.msg);
  317. })
  318. },
  319. complete: function () {
  320. layer.close(load);
  321. table.reload('table');
  322. }
  323. })
  324. layer.close(index)
  325. });
  326. } else {
  327. layer.msg('请先勾选需要操作的记录');
  328. }
  329. }
  330. });
  331. });
  332. function getfullname(filename, fileext, filetype) {
  333. return filetype == 'dir' || fileext == "" ? filename : filename + '.' + fileext;
  334. }
  335. </script>
  336. <script>
  337. layui.use('upload', function () {
  338. var $ = layui.jquery,
  339. upload = layui.upload;
  340. //指定允许上传的文件类型
  341. upload.render({
  342. elem: '#upload'
  343. , url: "{:url('upload')}?relative_path={$relative_path|replaceUrlDS}"
  344. , accept: 'file' //普通文件
  345. , multiple: true
  346. // , exts: 'html|js|css|mp4|jpg|png|gif|zip' //只允许上传的文件
  347. , allDone: function (obj) { //当文件全部被提交后,才触发
  348. console.log('总文件数:' + obj.total + ' 成功的文件数:' + obj.successful + ' 失败的文件数:' + obj.aborted);
  349. setTimeout(function () {
  350. location.reload();
  351. }, 1500)
  352. }
  353. , progress: function (n) {
  354. var percent = n + '%' //获取进度百分比
  355. element.progress('demo', percent); //可配合 layui 进度条元素使用
  356. }
  357. , done: function (res) { //每个文件提交一次触发一次
  358. layer.msg(res.msg);
  359. }
  360. });
  361. });
  362. </script>
  363. </div>
  364. </body>
  365. </html>