angular编写仿Explorer资源管理器

八年前,写过一个 简单的 ASP版本的 仿 Explorer资源管理器(http://www.miaoqiyuan.cn/p/asp-explorer),没想到最近了有网友通过这边文章找到了我,想实现查看 网站下 某个目录 占用的空间大小(用的虚拟主机,没有服务器权限,网站太大,下载非常麻烦)。打开这边文章,发现 太丑了,太简陋了。正好最近学习 angular.js,用周末的时间用 angular.js 重新写一个版本。

这次准备下一个通用的版本,angular实现前端,可以通过前端输入调用的接口和密码,通过 jsonp 的方式去调取后端数据。空间里只需要放一个 脚本 文件就可以实现文件浏览的功能。现在程序已经完成。

实现的 登录界面如下。

web-explorer

点击 测试,可以用 以我的博客 的 某个目录为根目录的 后端脚本。
web-explorer-2

点击 文件夹,可以打开 点击的文件夹,列出 文件夹的内容。点击文件,可以直接打开文件。
web-explorer-3

点击 顶部的 目录导航,可以返回 任意一级的 父级目录(我的这个演示脚本,限制只能访问:/products/web-explorer)。演示地址:http://www.miaoqiyuan.cn/products/web-explorer/

前端代码如下:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--引用 bootstarp,angular.js,jquery.js-->
<link rel="stylesheet" href="static/bootstrap.css?ver=3.3.4.mini.css">
<link rel="stylesheet" href="static/web-explorer.css?ver=1.0.css">
<script src="static/angular.js?ver=1.4.6.mini.js"></script>
<script src="static/jquery.js?ver=1.8.2.min.js"></script>
</head>
<body>


<div class="container">
  <div ng-app="file-explorer" ng-controller="explorer-list" class="web-explorer panel panel-default">
    <div class="panel-heading">
      <ul class="path-list">
        <!--父级目录列表-->
        <li ng-repeat="path in data.pathList" ng-click="openFolder(path.path)">
           <!--选中的目录(实际是最后一个),按钮设置为蓝色-->
          <button class="btn btn-xs" ng-class="{true:'btn-primary', false:'btn-default'}[!!path.active]">{{ path.name }}</button>
          <i ng-if="!path.active">/</i>
        </li>
      </ul>
      <b>文件浏览器</b>
      <!--系统运行状态,反应给用户-->
      <span ng-if="waitData" class="loading">{{ taskMsg }}中..</span>
    </div>
    <div class="panel-body">
      <!--如果链接失败,提示用户输入API地址,API密码(后端提供)-->
      <form ng-if="!connected" class="form-inline ">
        <div class="form-group">
          <input class="form-control"ng-model="query.apiadr" placeholder="API地址,不能为空">
        </div>
        <div class="form-group">
          <input class="form-control" ng-model="query.apipwd" placeholder="API密码,如果没有设置请留空">
        </div>
        <button type="button" class="btn btn-primary" ng-click="openFolder('/')">连接</button>
        <!--测试-->
        <button type="button" class="btn btn-danger" ng-click="demo()">测试</button>
      </form>
      <!--文件夹和文件视图-->
      <div class="explorer-view">
        <dl ng-repeat="folder in data.folder">
          <dt ng-click="openFolder(data.path + '/' + folder.name)" class="folder">
            <i ng-if="folder.size">{{ folder.size | fileSize }}</i>
            <i ng-if="!folder.size">wait...</i>
            <b>{{ folder.name }}</b>
          </dt>
        </dl>
        <dl ng-repeat="file in data.file">
          <dt ng-click="openFile(file)" ng-class="file.ext" class="file">
            <i>{{ file.size | fileSize }}</i>
            <b>{{ file.name }}</b>
          </dt>
        </dl>
      </div>
    </div>
  </div>
</div>

<!--程序,为了方便注释,放到 app.js中-->
<script src="static/app.js"></script>

</body>
</html>

引用的 web-explorer.css

/*!
 * web-explorer.css
 * Author: miaoqiyuan.cn
 */

body{padding-top:80px;}
.navbar-brand{font-family:'Microsoft Yahei';}
.clearfix{clear:both;float:none;}
.loading{padding:2px 5px;font-family:'Impact';font-weight:200;background:#FF0;color:#F00;}

ul.path-list{float:right;list-style:none;padding:0;}
ul.path-list li{float:left;margin-left:5px;cursor:pointer;}
ul.path-list li i{color:#CCC;padding:0 5px;}

.explorer-view dl{list-style:none;margin:0;padding:5px 10px;float:left;}
.explorer-view dl dt{cursor:pointer;border:solid 1px transparent;border-radius:5px;background:url('icon.png') no-repeat;padding-top:100px;width:100px;height:130px;overflow:hidden;}
.explorer-view dl dt i{position:absolute;margin-top:-95px;margin-left:35px;width:60px;text-align:center;border:solid 1px #006;opacity:0.8;color:#FFF;background:#009;font-weight:200;font-size:10px;line-height:20px;border-radius:5px;}
.explorer-view dl dt b{text-align:center;vertical-align:bottom;text-decoration:none;display:block;line-height:15px;font-size:12px;font-weight:400;height:30px;color:#666;}
.explorer-view dl dt:hover{background-color:#FAFAFA;border-color:#EEE;}
.explorer-view dl dt:hover b{border-bottom-left-radius:5px;color:#666;border-bottom-right-radius:5px;}

/*图标,在easyicon.net上下载后,合并的,每个图标尺寸100px*/
.explorer-view .folder{background-position-x:-100px;}
.explorer-view .file.sql{background-position-x:-200px;}
.explorer-view .file.asp{background-position-x:-300px;}
.explorer-view .file.css{background-position-x:-400px;}
.explorer-view .file.html{background-position-x:-500px;}
.explorer-view .file.js{background-position-x:-600px;}
.explorer-view .file.xml{background-position-x:-700px;}
.explorer-view .file.php{background-position-x:-800px;}
.explorer-view .file.jpg,
.explorer-view .file.gif,
.explorer-view .file.png{background-position-x:-900px;}
.explorer-view .file.mdb{background-position-x:-1000px;}
.explorer-view .file.txt{background-position-x:-1100px;}
.explorer-view .file.zip,
.explorer-view .file.rar,
.explorer-view .file.tar,
.explorer-view .file.gz{background-position-x:-1200px;}

static/app.js 代码如下:

var app = angular.module('file-explorer', []);
app.controller('explorer-list', function($scope, $location, $http) {
	$scope.waitData = false;  //不在等待进程中
	$scope.query = $location.search(); //路由信息
	$scope.query['apiadr'] = $scope.query['apiadr'] || "";
	$scope.query['apipwd'] = $scope.query['apipwd'] || "";
	$scope.query['path'] = $scope.query['path'] || "";
	
        //提供一个路径,分析父级目录
	var pathList = function(path){
		var arr = [{
			name : '根目录',
			path : ''
		}];
		if( path ){
			var ptmp = '',parr = path.split('/');
			for(var i = 1 ; i < parr.length ; i++ ){
				ptmp += '/' + parr[i];
				arr.push({
					name : parr[i],
					path : ptmp
				});
			}
		}
		arr[ arr.length - 1 ].active = true;
		return arr;
	};
	
	//测试
	$scope.demo = function(){
		$scope.query.apiadr = "http://www.miaoqiyuan.cn/products/web-explorer/demo.asp";
		$scope.openFolder("");
	}
	
	//打开文件夹
	$scope.openFolder = function(path){
		$scope.waitData = true;
		$scope.connected = false;
		if( $scope.query['apiadr'] != ''){
			$scope.taskMsg = "打开目录" + path;
			$scope.query['path'] = path;
			$location.search($scope.query);
			$http.jsonp($scope.query['apiadr'] + '?pwd=' + $scope.query['apipwd'] + '&path=' + $scope.query['path'] + '&callback=JSON_CALLBACK')
			.success(function (result) {
				if( !!result.folder || !!result.file ){
					var _tmp_name;
					$scope.connected = true;
					for(var i = 0 ; i < result.file.length ; i++){
						_tmp_name = result.file[i].name.split('.');
						result.file[i].ext = _tmp_name[_tmp_name.length - 1];
					}
					$scope.data = result;
					$scope.data.pathList = pathList(result.path);
					$scope.waitData = false;
					
					$scope.getFolderSize(0, result.path);
				}else if( !!result.err ){
					$scope.taskMsg = result.err + ",等待用户输入";
				}else{
					$scope.taskMsg = "未知错误,等待用户输入";
				}
			});
		}else{
			$scope.taskMsg = "请输入正确的API地址,等待用户输入";
		}
	};
	
	//获取文件夹大小
	$scope.getFolderSize = function(index, parent){
		if( index < $scope.data.folder.length && parent == $scope.data.path ){
			var _tmp_name = parent + "/" + $scope.data.folder[index].name;
			$scope.waitData = true;
			$scope.taskMsg = "计算" + _tmp_name + "大小";
			$http.jsonp($scope.query['apiadr'] + '?pwd=' + $scope.query['apipwd'] + '&path=' + _tmp_name + '&action=getsize&index=' + index + '&callback=JSON_CALLBACK')
			.success(function (result) {
				$scope.waitData = false;
				$scope.data.folder[result.index].size = result.size;
				$scope.getFolderSize(result.index + 1, result.parent); //获取下一个
			});
		}
	}
	
	//点击文件,打开文件
	$scope.openFile = function(file){
		window.open($scope.data.path + '/' + file.name);
	};

	//页面打开时,尝试打开目录 
	//$scope.query['path'] = $scope.query['path'] || "";	
	$scope.openFolder($scope.query['path']);
	
}).filter("fileSize",[function(e){ 
	//格式化文件大小
	return function(size, e){
		if( size < 1024 ){
			return size + "B";
		}else if( size < 1048576){
			return (size / 1024).toFixed(3) + "KB";
		}else if( size < 1073741824){
			return (size / 1048576).toFixed(3) + "MB";
		}else{
			return (size / 1073741824).toFixed(3) + "GB";
		}
	}
}]);

PHP版本的后端代码已经放出,请移步:angular编写仿Explorer资源管理器 – php的api接口

angular编写仿Explorer资源管理器》上有1条评论

  1. Pingback引用通告: angular编写仿Explorer资源管理器 – php的api接口 | 苗启源

发表评论

电子邮件地址不会被公开。 必填项已用*标注