迅睿cms读取zip压缩包文件目录结构配合jsTree展示文件树列表

本文教程最终实现的效果是通过后台自定义字段,上传Zip文件压缩包不解压缩的前提下,读取zip的文件目录配合jsTree展示文件树列表。教程主要分2个部分,前面为压缩包上传在网站服务器本地的教程。如果压缩包使用的云存储例如阿里云oss ,则可以参考后半部分把云存储挂载到本地硬盘。

本地压缩包读取方式

新建内容字段

登录后台-模块管理-模块内容字段-添加-字段类别(单文件File)-本文字段名称以down示例

二次开发代码

复制下方代码粘贴到 站点根目录/config/custom.php 代码功能可参考注释(这个是开发者自定义函数文件,不影响系统后续升级)

<?php

/**
 * 开发者自定义函数文件
 */
function generateHtmlTree($down)
//获取自定义字段传递的下载字段值,down改成你的自定义字段名
{
    // 获取文件路径,down改成你的自定义字段名
    $url = dr_get_file($down);
    //获取url路径,去掉域名截断
    $parts = parse_url($url);
    $path = $parts['path'];
    //组装url地址,tmp改成压缩包在路径,本地上传tmp改成站点目录名称
    $zipName = '/www/wwwroot/tmp/' . $path;

    // 检查缓存是否存在且未过期
    $cacheName = 'tree-' . md5($zipName);
    // 缓存文件路径根据实际情况修改
    $cacheDir = '/www/wwwroot/tmp/cache/';
    $cacheFile = $cacheDir . $cacheName;
    $cacheTime = 86400; // 缓存时间,单位为秒
    if (is_file($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
        // 从缓存中获取 HTML 树
        $html = file_get_contents($cacheFile, false, stream_context_create(['http' => ['timeout' => 5]]));
    } else {
        // 打开 zip 文件并获取文件结构
        $zip = new ZipArchive();
        if ($zip->open($zipName) === true) {
           // 初始化文件树结构
			$tree = [];
			for ($i = 0; $i < $zip->numFiles; $i++) {
			// 获取文件名
			$filename = $zip->getNameIndex($i);
			// 分割路径为数组
			$path = explode('/', $filename);
			$node = &$tree;
			foreach ($path as $dir) {
            if (!isset($node[$dir])) {
                $node[$dir] = [];
                }
                    $node = &$node[$dir];
			}
		}
            $zip->close();
            $html = treeToHtml($tree);
            file_put_contents($cacheFile, $html);
        }
    }
    // 输出 HTML 树
    echo '<div id="jstree-basic">' . $html . '</div>';
}
 // 生成 HTML 树
function treeToHtml($tree) {
            $html = '<ul>';
            // 先输出文件夹
            foreach ($tree as $name => $subtree) {
                if (!empty($name) && empty(pathinfo($name, PATHINFO_EXTENSION))) {
                    $html .= '<li';
                    if (!empty($subtree)) {
                        $html .= '   data-jstree=\'{"type":"folder"}\'';
                    }
                    $html .= '>' . htmlentities($name);
                    if (!empty($subtree)) {
                        $html .= treeToHtml($subtree);
                    }
                    $html .= '</li>';
                }
            }

        // 再输出文件
        foreach ($tree as $name => $subtree) {
            if (!empty($name) && !empty(pathinfo($name, PATHINFO_EXTENSION))) {
                $ext = pathinfo($name, PATHINFO_EXTENSION);
                $html .= '<li';
                if (!empty($subtree)) {
                    $html .= '  data-jstree=\'{"type":"folder"}\'';
                }
                $html .= ' data-jstree=\'{"type":"'.$ext.'"}\'';
                $html .= '>' . htmlentities($name);
                if (!empty($subtree)) {
                    $html .= treeToHtml($subtree);
                }
                $html .= '</li>';
            }
        }

    $html .= '</ul>';
    return $html;
 }

前端调用代码

前端使用jstree.js 请自行官方下载 或 在本文章结尾下载。教程提供的下载包,包括了我自己用的一些图标素材。

前端调用代码

 {generateHtmlTree($down)}
 // down改成你的自定义字段

前端引用jstree

我这里是把dist文件夹放到了网站根目录/static/模板风格文件夹中,引用示例代码如下:

<link rel="stylesheet" href="{HOME_THEME_PATH}dist/themes/default/style.min.css" />
<script src="{HOME_THEME_PATH}dist/jstree.min.js"></script>

前端图标代码

配合jstree.js 给各种文件图标,示例代码如下:

<script>
  $(document).ready(function() {
    function generateIconObject() {
      const icons = [
        ['default', 'bx  bxs-file-blank'],
        ['folder', 'bx bx-folder'],
        ['html', 'bx bxl-html5 text-warning'],
        ['css', 'bx bxl-css3 text-primary'],
        ['js', 'bx bxl-javascript text-warning'],
        ['php', 'bx bxl-php text-primary'],
        ['sql', 'bx bx-data text-danger'],
        ['jpg', 'bx bx-image text-success'],
        ['jpeg', 'bx bx-image text-success'],
        ['png', 'bx bx-image text-success'],
        ['gif', 'bx bx-image text-success']
      ];

      const types = {};

      icons.forEach(icon => {
        types[icon[0]] = {
          'icon': icon[1]
        };
      });

      return types;
    }

    $('#jstree-basic').jstree({
      'plugins': ['types'],
      'types': generateIconObject()
    });
  });
</script>

如果需要默认节点展开的话,可以在上方代码结尾部分处做修改,在数组中添加 'state' 然后设置 state:{opened:true} 即可,需要修改的代码部分如下:

    $('#jstree-basic').jstree({
      'plugins': ['types','state'],
      'types': generateIconObject(),
      'state': {"opened":true},
    });

OSS压缩包读取方式

安装ossfs 

这里以阿里云OSS做示例,首先服务器安装 ossfs 挂在到本地硬盘(需要注意的是目录权限的问题)

此操作需一点运维知识,可参考阿里云教程 https://help.aliyun.com/document_detail/32195.html 

温馨提示:腾讯云COSFS 宝塔有免费的官方插件。

压缩包目录

根据自己挂载路径,自行修改custom.php二次开发代码中的tmp目录名。

教程说明

以上教程代码可以直接拿走复制黏贴直接使用,需要注意的点是文件路径和缓存路径要修改。另外jstree图标引用样式需自己根据实际情况修改完善。

教程附件

教程附件仅限 高级/渠道 会员下载,请先登录平台账号