Open fredshare opened 8 years ago
前言
之前在大公司里有现成文件发布系统。今年在创业公司,很多工具都得自己从头搭建,比如日志、itil监控、用户信息监控。这次是源码发布系统。在最开始我们直接使用ftp上传到idc机器,因为idc机器只有一台,用ftp很简单;随着业务不断扩大,idc机器越来越多,ftp发布就变得很麻烦了,你得一个文件一个文件上传不说,还得切换机器上传。我们研究了常见的文件同步软件后,采用了rsync软件同步。 rsync很方便的就是可以一次同步到多个机器,可以备份,方便回退;唯一的缺点就是命令行操作,不能查看以往的发布记录。所以当团队越来越大的时候很有必要基于sync做一个可视化的发布系统。
一个一个解决
随便百度了下,发现有很多这样的开源项目,采用了jstree项目,这个项目对服务器上的路径的目录文件能很好的解析,同时配备js代码绘制树形结构,很方便就画好文档树了。如下图
* 任务发布 当点击文件的时候,将文件展示出来,并添加查看源码和文件对比的功能。
$('#tree') .jstree({ 'core' : { 'data' : { 'url' : '/release/getNodeInfo?path='+path+'&operation=get_node', 'data' : function (node) { return { 'id' : node.id }; } }, 'check_callback' : function(o, n, p, i, m) { if(m && m.dnd && m.pos !== 'i') { return false; } if(o === "move_node" || o === "copy_node") { if(this.get_node(n).parent === this.get_node(p).id) { return false; } } return true; }, 'themes' : { 'responsive' : false, 'variant' : 'small', 'stripes' : true } }, 'sort' : function(a, b) { return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : (this.get_type(a) >= this.get_type(b) ? 1 : -1); }, 'contextmenu' : { 'items' : function(node) { var tmp = $.jstree.defaults.contextmenu.items(); delete tmp.create.action; tmp.create.label = "New"; tmp.create.submenu = { "create_folder" : { "separator_after" : true, "label" : "Folder", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.create_node(obj, { type : "default" }, "last", function (new_node) { setTimeout(function () { inst.edit(new_node); },0); }); } }, "create_file" : { "label" : "File", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.create_node(obj, { type : "file" }, "last", function (new_node) { setTimeout(function () { inst.edit(new_node); },0); }); } } }; if(this.get_type(node) === "file") { delete tmp.create; } return tmp; } }, 'types' : { 'default' : { 'icon' : 'folder' }, 'file' : { 'valid_children' : [], 'icon' : 'file' } }, 'unique' : { 'duplicate' : function (name, counter) { return name + ' ' + counter; } }, 'plugins' : ['state','dnd','sort','types','contextmenu','unique'] }) .on('delete_node.jstree', function (e, data) { $.get('/release/getNodeInfo?path='+path+'&operation=delete_node', { 'id' : data.node.id }) .fail(function () { data.instance.refresh(); }); }) .on('create_node.jstree', function (e, data) { $.get('/release/getNodeInfo?path='+path+'&operation=create_node', { 'type' : data.node.type, 'id' : data.node.parent, 'text' : data.node.text }) .done(function (d) { data.instance.set_id(data.node, d.id); }) .fail(function () { data.instance.refresh(); }); }) .on('rename_node.jstree', function (e, data) { $.get('/release/getNodeInfo?path='+path+'&operation=rename_node', { 'id' : data.node.id, 'text' : data.text }) .done(function (d) { data.instance.set_id(data.node, d.id); }) .fail(function () { data.instance.refresh(); }); }) .on('move_node.jstree', function (e, data) { $.get('/release/getNodeInfo?path='+path+'&operation=move_node', { 'id' : data.node.id, 'parent' : data.parent }) .done(function (d) { //data.instance.load_node(data.parent); data.instance.refresh(); }) .fail(function () { data.instance.refresh(); }); }) .on('copy_node.jstree', function (e, data) { $.get('/release/getNodeInfo?path='+path+'&operation=copy_node', { 'id' : data.original.id, 'parent' : data.parent }) .done(function (d) { //data.instance.load_node(data.parent); data.instance.refresh(); }) .fail(function () { data.instance.refresh(); }); }) .on('changed.jstree', function (e, data) { if(data && data.selected && data.selected.length) { var id = data.selected.join(':'); if(id.split('.').length>1){ //保存id信息 if(!isIdExist(id)){ saveId(id); $('#js_file_list').append('<li class="jstree-node jstree-no"><span class="js_path">'+ id +'</span> <a href="#del" class="js_del">删除</a> <a href="#query" class="js_query">查看文件</a> <a href="#query" class="js_diff">对比文件</a></li>'); } } } else { //$('#data .content').hide(); $('#data .default').html('Select a file from the tree.').show(); } }); function isIdExist(id){ for (var i = 0; i < fileList.length; i++) { if(fileList[i] == id){ return true; } }; return false; } function saveId(id){ fileList.push(id); } function delId(id){ for (var i = 0; i < fileList.length; i++) { if(fileList[i] == id){ fileList.splice(i,1) } }; } $('body').delegate('.js_del','click',function(e){ var target = $(e.target).closest('li'), id = target.find('.js_path').text(); console.log(target); target.remove(); delId(id); }) $('body').delegate('.js_query','click',function(e){ var target = $(e.target).closest('li'), id = target.find('.js_path').text(); var loading_id = layer.load(2); $.get('/release/getNodeInfo?path='+path+'&operation=get_content&id=' + id, function (d) { if(d && typeof d.type !== 'undefined') { switch(d.type) { case 'text': case 'txt': case 'md': case 'htaccess': case 'log': case 'sql': case 'php': case 'js': case 'json': case 'css': case 'html': //$('#data .code').show(); //$('#code').val(d.content); //break; case 'png': case 'jpg': case 'jpeg': case 'bmp': case 'gif': /*$('#data .image img').one('load', function () { $(this).css({'marginTop':'-' + $(this).height()/2 + 'px','marginLeft':'-' + $(this).width()/2 + 'px'}); }).attr('src',d.content); $('#data .image').show();*/ layer.close(loading_id); layer.open({ type: 2, title: false, closeBtn: 0, //不显示关闭按钮 shade: [0], area: ['340px', '215px'], offset: 'rb', //右下角弹出 time: 1000, //1秒后自动关闭 shift: 2, content: ['/release/fileInfo?path='+path+'&operation=get_content&id='+id, 'no'], //iframe的url,no代表不显示滚动条 end: function(){ //此处用于演示 layer.open({ type: 2, title: '源码查看-'+id, shadeClose: true, shade: false, maxmin: true, //开启最大化最小化按钮 area: ['893px', '600px'], content: '/release/fileInfo?path='+path+'&operation=get_content&id='+id }); } }); break; default: //$('#data .default').html(d.content).show(); //$('#js_file_list').append('<li class="jstree-node jstree-no">'+data.selected.join(':')+' <a href="#del">删除</a> <a href="#query">查看文件</a></li>'); break; } } }); }) $('body').delegate('#js_release','click',function(e){ console.log(fileList); }) $('body').delegate('.js_diff','click',function(e){ var target = $(e.target).closest('li'), id = target.find('.js_path').text(); var loading_id = layer.load(2); layer.close(loading_id); layer.open({ type: 2, title: false, closeBtn: 0, //不显示关闭按钮 shade: [0], area: ['340px', '215px'], offset: 'rb', //右下角弹出 time: 1000, //1秒后自动关闭 shift: 2, content: ['/release/diffFile?path='+path+'&id='+id, 'no'], //iframe的url,no代表不显示滚动条 end: function(){ //此处用于演示 layer.open({ type: 2, title: '源码对比-'+id, shadeClose: true, shade: false, maxmin: true, //开启最大化最小化按钮 area: ['893px', '600px'], content: '/release/diffFile?path='+path+'&id='+id }); } }); }) });
效果如下图:
文件源码查看和问价对比
文件源码查看比较简单,路径发到后台,后台读出文档内容返回给前端,前端用codemirror渲染下就行了,如下:
文件对比就比较麻烦了,你得分别读开发环境下的文件的线上的文件,再一行一行的对比,还得渲染出来,不过网上还蛮多这样的开源项目,拿来主义,哈哈。我采用了[php-diff](https://github.com/chrisboulton/php-diff)项目。效果如下:
php打造可视化源码发布系统
前言
之前在大公司里有现成文件发布系统。今年在创业公司,很多工具都得自己从头搭建,比如日志、itil监控、用户信息监控。这次是源码发布系统。在最开始我们直接使用ftp上传到idc机器,因为idc机器只有一台,用ftp很简单;随着业务不断扩大,idc机器越来越多,ftp发布就变得很麻烦了,你得一个文件一个文件上传不说,还得切换机器上传。我们研究了常见的文件同步软件后,采用了rsync软件同步。 rsync很方便的就是可以一次同步到多个机器,可以备份,方便回退;唯一的缺点就是命令行操作,不能查看以往的发布记录。所以当团队越来越大的时候很有必要基于sync做一个可视化的发布系统。
一个一个解决
随便百度了下,发现有很多这样的开源项目,采用了jstree项目,这个项目对服务器上的路径的目录文件能很好的解析,同时配备js代码绘制树形结构,很方便就画好文档树了。如下图
效果如下图:
文件源码查看和问价对比
文件源码查看比较简单,路径发到后台,后台读出文档内容返回给前端,前端用codemirror渲染下就行了,如下: