宝塔文件管理 批量拖拽上传

宝塔主机管理 里面的文件管理功能做的不错,支持压缩包上传解压,但是距离自己想要的还差一步,所以就有了这个书签小工具。

利用 FileAPI.js 获取 拖拽的文件或目录 直接上传,并且保持与本地同步的目录结构。

Piecon.js 用 Favicon 来显示进度

虽然说是书签小工具,为了方便也可以写成 Userscript

  • 2022-04-18 修复对宝塔 7.9.0 支持
    • 7.9.0 版本 宝塔添加了对 拖拽上传的支持,但是 有 BUG, 如果拖拽上传文件后,文件浏览器切换到其他目录 拖拽上传还是 会 上传到第一次的目录。返回来想用这个脚本发现不能用了, 所有就有了本次更新
  • 2019-10-08 使用 6.9.8 版本 宝塔时候发现不能用了所以更新了下
javascript:(function(){
/*@ 宝塔文件管理 6.9.8 批量拖拽上传工具 **/
// 20220420 修改 对 7.9.0 的支持
var initDndUpload = function(){
    this.getScript = this.getScript || 0;
    if(this.getScript > 3){return}
    if(typeof FileAPI == 'undefined' || typeof Piecon == 'undefined'){
        return create('script', {
            src: 'https://cdn.asilu.com/fileapi.js,piecon.js',
            onload: initDndUpload
        }, 'head');
    }

    function create(tag, attr, to){
        var dom = document.createElement(tag);
        var setAttr = function(dom, attr){
            for(var k in attr){
                if(typeof attr[k] == 'object'){
                    setAttr(dom[k], attr[k]);
                }else{
                    dom[k] = attr[k];
                }
            }
        };
        if(typeof attr == 'object'){
            setAttr(dom, attr)
        }
        document[to == 'head' ? to : 'body'].appendChild(dom);
        return dom;
    }

    var $path = document.querySelector('#fileInputPath');
    if(!$path || window.initDndUploadLoaded){return}
    /* 阻止重复加载 */
    window.initDndUploadLoaded = 1;
    var $mask = create('div', {style:{
        display: 'none',
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100vw',
        height: '100vh',
        background: 'rgba(0,0,0,.5)',
        lineHeight: '100vh',
        textAlign: 'center',
        zIndex: 9999999,
        fontSize: '50px',
        color: '#fff',
    }, innerText: '释放立马上传'});

    /* 版本 6.9.8 token 支持 */
    var token = document.querySelector('#request_token_head');
    var headers = token ? {
        'x-http-token': token.getAttribute('token'),
        'x-cookie-token': getCookie('request_token')
    } : {};

    // 移除 7.9.0 自带上传层
    let oldView = document.querySelector('#uploadView');
    if(oldView){
        oldView.remove();
    }

    FileAPI.event.dnd(window, function(over) {
        $mask.style.display = over ? 'block' : 'none';
    }, function(files) {
        if (files.length) {
            var totalSize = 0;
            var filesInfo = files.map(function(a){
                totalSize += a.size;
                return a.fullPath.padEnd(30) + a.size;
            });

            var path = typeof $path.dataset.path != 'undefined' ? $path.dataset.path : $path.value;
            if(confirm(['确认上传', files.length, '个文件到', path, ', 共', totalSize].join(' ') +'\n'+ filesInfo.join('\n'))){
                console.log(path);
                loopUpload(files, path);
            }
        }
    });

    function loopUpload(files, path, index){
        index = index || 0;
        if(index < files.length){
            var file = files[index];
            Piecon.setProgress((index + 1) / files.length * 100);
            console.log((index + 1) +'/'+ files.length +': '+ path + file.fullPath);
            upload(file, path + file.fullPath.slice(0, -file.name.length), function(ok){
                if(ok !== false){
                    index++;
                    loopUpload(files, path, index);
                }
            });
        }else{
            if(typeof GetFiles == 'function'){
                GetFiles(path);
            }else if(bt_file && typeof bt_file.reader_file_list == 'function'){
                bt_file.reader_file_list({path: path});
            }
            Piecon.reset();
        }
    }
    function upload(file, path, call){
        /* 兼容新版 TOKEN */
        return FileAPI.upload({
            url: '/files?action='+ (token ? 'upload' : ('UploadFile&path='+ encodeURIComponent(path) +'&codeing=byte')),
            files: token ? { blob: file } : { zunfile: file },
            data: !token ? {} : {f_path: path, f_name: file.name, f_size: file.size, f_start: 0},
            headers: headers,
            complete: function(err, xhr) {
                if (!err) {
                    call.call(xhr, xhr.responseText);
                }else{
                    call.call(xhr, false);
                }
            }
        });
    }
};
initDndUpload();

})();

Post Author: admin