CDN那么多,怎样批量管理七牛云、易速云、又拍云等多个CDN资源解决方案

原创| 开发动态| 一个月前| 阅读 66 次 | 0赞同 0反对

概述:板砖发现,不少的平台在整个运行周期内可能同时或者分时段使用了不同的CDN云存储,而管理这些资源的时候使用者脑壳是很大的,而且如何深度使用这些CDN资源也是一个问题。那么板砖今天来讲一下我的管理方式。

板砖在平台开发的经历中,特别推荐七牛云存储,便宜稳定。然而很多开发者甚至我曾经开发的应用中在未来还会使用更多品牌的CDN,因此板砖决定不使用云存储提供的SDK,而自己来打造一个较为规范的资源管理工具。

首先来整理一下思路哈,便于需要这个解决方案的同学自己去改造系统,在文末将附上前端代码:

1. 建立记录所有资源的系统表,这个表将你存在所有的CDN的资源路径、名称等记录下来,如何记录资源的cdn信息,板砖不用再多说,看官自己看着办吧

该表是板砖建的基础表,你可以根据需求去改


2. 建立资源的分组表,可以是功能分组,也可以是CDN品牌的分组,这个看自己了,这个分组表就不再赘述了,上图中groupid就是本表的主键。

3. 使用板砖的资源管理工具即可,根据自己的需求改装。


注意:在本解决方案中使用了webuploader控件,保存方法等需要各位自己解决,另外分页插件是用js写的原生插件,后期还会继续更新。

如果有对本篇感兴趣且不是特别明白的,欢迎加QQ554305954和板砖一起探讨,如果您觉得本篇还行,感谢扫描下图中的小程序码支持一下。



板砖的资源管理器一览

新增资源分组,板砖是以应用场景来分组的

修改资源属性,重新分组和alt重命名

<link rel="stylesheet" type="text/css" href="/static/webupload/webuploader.css">
<link rel="stylesheet" type="text/css" href="/static/webupload/style.css">
<style>
    .file-item{float:left;position:relative;width:110px;height:110px;margin:0 20px 20px 0;padding:4px}
    .file-item .info{overflow:hidden}
    .uploader-list{width:100%;overflow:hidden}
    #img_data{margin:8px 0}
    .piclib{float:left;margin-left:10px;background:#02b7ee;border:0;border-radius:3px;color:#fff;padding:10px 16px}
</style>

<div id="fileList" class="uploader-list"></div>
<div id="imgPicker" style="float:left;">上传图片</div>    
<input type="button" class="piclib" onclick="loadGroups();loadImages(1);$('.yunsource').show();" value="图库选图"/>

<script type="text/javascript" src="/static/webupload/webuploader.min.js"></script>
<script type="text/javascript">
    var uploader = WebUploader.create({     
        auto: true,
        swf: '/static/js/webupload/Uploader.swf',
        server: "{:url('upload')}",
        duplicate :true,
        pick: '#imgPicker',

        accept: {
            title: 'Images',
            extensions: 'gif,jpg,jpeg,bmp,png',
            mimeTypes: 'image/jpg,image/jpeg,image/png'
        },

        'onUploadSuccess': function(file, data, response) {
            $("#data_photo").val(data._raw);
            $("#img_data").attr('src', data._raw).show();
        }
    });

    uploader.on( 'fileQueued', function( file ) {
        $('#fileList').html( '<div id="' + file.id + '" class="item">' +
            '<h4 class="info">' + file.name + '</h4>' +
            '<p class="state">正在上传...</p>' +
        '</div>' );
    });

    uploader.on( 'uploadSuccess', function( file ) {
        $( '#'+file.id ).find('p.state').text('上传成功!');
    });

    uploader.on( 'uploadError', function( file ) {
        $( '#'+file.id ).find('p.state').text('上传出错!');
    });
</script>  
<!-----------------------------------------------资源框框里面的-------------------------------------------------------->
<style>
    .yunsource{width:800px;height:560px;display:none;position:fixed;z-index:1000;top:150px;left:30%;border:1px solid #efefef;box-shadow:1px 1px 1px #eee;background:#fff}
    .yunsource .yun_left{width:120px;float:left}
    .yunsource .yun_left ul{list-style:none;margin: 0;padding: 15px;}
    .yunsource .yun_left ul li{line-height:3}
    .yunsource .yun_left ul li a{color:#666;font-size: 1.2em;}
    .yunsource .yun_left ul li a .active{color:#666}
    .yunsource .yun_right,.save_group,.save_source{width:678px;float:left;border-left:2px solid #eee;height:100%}
    .yunsource .yun_right #items img{display:block;width:150px;height:120px;margin:5px;object-fit:cover;border-radius:4px;overflow:hidden;border:1px solid #eee;transition:all .6s;}
    .yunsource #items{width:100%;display:inline-block}
    .yunsource #items .item{width:160px;height:150px;float: left;}
    .yunsource #items .item div{width: 100%; text-align:center;}
    .yunsource #items .item a:first-child{color: #3f51b5;margin-right: 2px;}
    .yunsource #items .item a:last-child{color: #f44336;margin-left: 2px;}
    .yunsource .barcon{width:100%;line-height:24px;    text-align: CENTER;}
    .yunsource .barcon a{padding: 3px 6px;;}
    .yunsource .save_group,.save_source{display:none;line-height: 2;padding: 50px;}
</style>
<div class="yunsource">
    <div class="yun_left">
    <ul>
    </ul>
    </div>
    <div class="yun_right">
    <span onclick="$('.yunsource').hide()" style="float: right;padding: 10px;color: red;"><i class="fas fa-window-close"></i></span>
    <div id="items"></div>
    <div id="barcon" class="barcon"></div>
    </div>
    <div class="save_group">
        <h4>图片分组</h4>
        <input type="text" id="yun_groupname" value="" class="form-control" placeholder="请输入分组名" style="margin-bottom: 20px;"/>
        <button class="btn btn-danger" type="button" onclick="saveGroup()">提交</button>
        <button class="btn btn-success" type="button" onclick='$(".yun_right").fadeIn(600);$(".save_group").fadeOut(600);'>取消</button>
    </div>
    
    <div class="save_source">
    <h4>资源编辑</h4>
    <img src="" id="editurl" style="max-height: 250px;"/>
    <input type="hidden" id="yun_id"/>
    <select id="yun_groupid" class="form-control"  style="margin-bottom: 20px;"></select>
    <input type="text" id="yun_title" value="" class="form-control" placeholder="请输入图片名称" style="margin-bottom: 20px;"/>
    <div style="display: inline-block;width: 100%;">
        <button class="btn btn-danger" type="button" onclick="saveSource()">提交</button>
        <button class="btn btn-success" type="button" onclick='$(".yun_right").fadeIn(600);$(".save_source").fadeOut(600);'>取消</button>
    </div>
</div>
</div>
<script>  
    var nowGroupId = 0;
    var pageRows=16;

    function groupClick (groupid) {
        if (groupid == nowGroupId) {
            return true;
        }
        nowGroupId = groupid;
        loadImages(1);
    }

    //加载分组
    function loadGroups() {
        $(".yun_left>ul>li").remove();
        $("#yun_groupid>option").remove();
        $(".yun_left>ul").append('<li><a href="javascript:groupClick(0);">全部</a></li>');
        $.post("{:url('yun/groups')}", { groupid: 0 }, function (res) {
            if (res.code == 1) {
                for (let i in res.data) {
                    var r=res.data[i];
                    $(".yun_left>ul").append('<li><a href="javascript:groupClick(' + r.id + ');">' + r.name + '</a></li>');
                    $("#yun_groupid").append('<option value="' + r.id + '">' + r.name + '</option>');
                }
            }
            $(".yun_left>ul").append('<li><a href="javascript:newGroup();">新增分组</a></li>');
        });
    }

    //加载图片,刷新分页插件
    function loadImages(nowPage) {
        $.post("{:url('yun/index')}", { groupid: nowGroupId, page: nowPage, rows: pageRows }, function (res) {
            $("#items").html('');
            iniPage(nowPage, pageRows, res.count);
            for (let i in res.list) {
                var img = res.list[i];
                $("#items").append('<div class="item"><img src="' + img.url + '" onerror="/static/admin/images/no_img.jpg" class="yunsourceimg"/>'
                    + '<div><a href="javascript:editsource(' + img.id + ');">编辑</a>' 
                    + '<a href="javascript:delsource(' + img.id + ');">删除</a></div></div>');
            }
        });
    }

    //新开一个分组,跳出分组页面
    function newGroup() {
        $(".yun_right").fadeOut(600);
        $(".save_group").fadeIn(600);
    }

    function editsource(id){            
        $("#yun_id").val(id);
        $.getJSON("{:url('yun/getsource')}",{id:id,r:Math.random()},function(res){                
            $("#editurl").attr("src",res.data.url);
            $("#yun_title").val(res.data.title);
            $(".yun_right").fadeOut(600);
            $(".save_source").fadeIn(600);
        });
    }
</script>

<script type="text/javascript">
    //所有提交都在这里解决
    function saveGroup(){
        if($("#yun_groupname").val().length<1){
            layer.msg('请输入分组名', { icon: 5, time: 1500, shade: 0.1 });
            return false;
        }

        $.post("{:url('yun/savegroup')}",{act:'new',id:0,name:$("#yun_groupname").val()},function(data){
            if (data.code == 1) {
                layer.msg(data.msg, { icon: 6, time: 1500, shade: 0.1 }, function (index) {
                    loadGroups();                        
                    $(".yun_right").fadeIn(600);
                    $(".save_group").fadeOut(600);
                    return true;
                });
            } else {
                layer.msg(data.msg, { icon: 5, time: 1500, shade: 0.1 });
                return false;
            }
        })
    }
    
    //所有提交都在这里解决
    function saveSource(){
        if($("#yun_title").val().length<1){
            layer.msg('请输入资源名', { icon: 5, time: 1500, shade: 0.1 });
            return false;
        }

        $.post("{:url('yun/savesource')}",{act:'edit',id:$('#yun_id').val(),title:$("#yun_title").val(),groupid:$("#yun_groupid").val()},    function(data){
            if (data.code == 1) {
                layer.msg(data.msg, { icon: 6, time: 1500, shade: 0.1 }, function (index) {
                    loadGroups();                        
                    $(".yun_right").fadeIn(600);
                    $(".save_group").fadeOut(600);
                    return true;
                });
            } else {
                layer.msg(data.msg, { icon: 5, time: 1500, shade: 0.1 });
                return false;
            }
        })
    }

    function delsource(id) {
        if (confirm('本删除仅删除数据库记录,不删除CDN资源')) {
            $.post("{:url('yun/savesource')}", { act: 'del', id: id }, function (data) {
                if (data.code == 1) {
                    layer.msg(data.msg, { icon: 6, time: 1500, shade: 0.1 }, function (index) {
                        loadImages(1);
                        return true;
                    });
                } else {
                    layer.msg(data.msg, { icon: 5, time: 1500, shade: 0.1 });
                    return false;
                }
            });
        }
    }
</script>
<script>
    // 生成自定义分页
    function iniPage(currentPage, pageSize, totalRows) {

        var totalPage = 0;
        if ((totalRows % pageSize) != 0) {
            totalPage = parseInt(totalRows / pageSize) + 1;
        } else {
            totalPage = parseInt(totalRows / pageSize);
        }

        var startRow = (currentPage - 1) * pageSize + 1;
        var endRow = currentPage * pageSize;
        endRow = (endRow > totalRows) ? totalRows : endRow;

        var tempStr = "<span>共" + totalPage + "页</span>";

        if (currentPage > 1) {
            tempStr += "<span class='btn' href=\"#\" onClick=\"loadImages(" + (1) + ")\">首页</span>";
            tempStr += "<span class='btn' href=\"#\" onClick=\"loadImages(" + (currentPage - 1) + ")\">上一页</span>"
        }

        for (var pageIndex = 1; pageIndex < totalPage + 1; pageIndex++) {
            if(currentPage==pageIndex){
                tempStr += "<a><span style='color:#333;'>" + pageIndex + "</span></a>";
            }
            else{
                tempStr += "<a onclick=\"loadImages(" + pageIndex + ")\"><span>" + pageIndex + "</span></a>";
            }
        }

        if (currentPage < totalPage) {
            tempStr += "<span class='btn' href=\"#\" onClick=\"loadImages(" + (currentPage + 1) + ")\">下一页</span>";
            tempStr += "<span class='btn' href=\"#\" onClick=\"loadImages(" + (totalPage) + ")\">尾页</span>";
        }

        document.getElementById("barcon").innerHTML = tempStr;
    }
</script>

<script>
    var copyto = '[copyto]';
    $('#items').on("click",'.yunsourceimg', function () {
        var source = $(this).attr('src');
        switch (copyto) {
            case "kindeditor":
                break;
            case "ueditor":
                break;
            default:
                $("#data_photo").val(source);
                $("#img_data").attr('src', source).show();
                $(".yunsource").hide();
                break;
        }
    });
</script>




DMAKE 点击这里下载本文PDF

本频道需要登陆后才能评论,请登录


暂无评论...