zoukankan      html  css  js  c++  java
  • 权限管理(java+struts2(自定义标签)实现)--------->全代码演示

    地址:http://blog.chinaunix.net/uid-24343152-id-3673026.html

    最近由于项目不是很紧所以总结了之前做了n遍的权限管理功能。以便之后系统copy之用。
    之前做过权限绑定给具体人的操作,而这次做的是权限绑定给角色,人员去选择角色。
    废话不多说,先看效果
    1.页面展示(新建角色,绑定权限)




    2.权限管理数据库设计

    -- ----------------------------
    -- Table structure for `account` 登录账号表
    -- ----------------------------
    DROP TABLE IF EXISTS `account`;
    CREATE TABLE `account` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `uid` bigint(20) NOT NULL,
      `accId` varchar(200) NOT NULL,
      `pw` varchar(200) NOT NULL,
      `loginTime` datetime DEFAULT NULL,
      `isBenefit` smallint(6) NOT NULL DEFAULT '1',
      `remark` varchar(500) DEFAULT NULL,
      `createTime` datetime DEFAULT NULL,
      `createUser` bigint(20) DEFAULT NULL,
      `updateTime` datetime DEFAULT NULL,
      `updateUser` bigint(20) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `account_uid_user` (`uid`) USING BTREE,
      KEY `account_createUser_user` (`createUser`) USING BTREE,
      KEY `account_updateUser_user` (`updateUser`) USING BTREE,
      CONSTRAINT `account_ibfk_1` FOREIGN KEY (`createUser`) REFERENCES `user` (`id`),
      CONSTRAINT `account_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`id`),
      CONSTRAINT `account_ibfk_3` FOREIGN KEY (`updateUser`) REFERENCES `user` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
    
    
    -- ----------------------------
    -- Table structure for `authority`角色菜单绑定表
    -- ----------------------------
    DROP TABLE IF EXISTS `authority`;
    CREATE TABLE `authority` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `roleId` int(11) NOT NULL,
      `sysmodelId` int(11) NOT NULL,
      `remark` text,
      `createTime` datetime DEFAULT NULL,
      `createUser` int(11) DEFAULT NULL,
      `updateTime` datetime DEFAULT NULL,
      `updateUser` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=877 DEFAULT CHARSET=utf8;
    
    
    
    -- ----------------------------
    -- Table structure for `role`角色表
    -- ----------------------------
    DROP TABLE IF EXISTS `role`;
    CREATE TABLE `role` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `roleName` varchar(200) NOT NULL,
      `createTime` datetime DEFAULT NULL,
      `createUser` int(11) DEFAULT NULL,
      `updateTime` datetime DEFAULT NULL,
      `updateUser` int(11) DEFAULT NULL,
      `remark` text,
      `isBenefit` smallint(6) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of role
    -- ----------------------------
    INSERT INTO `role` VALUES ('1', '经销商', null, null, '2013-05-08 11:25:55', null, '经销商备注', null);
    INSERT INTO `role` VALUES ('9', '管理员', null, null, '2013-05-08 11:25:59', null, '管理员权限', null);
    
    -- ----------------------------
    -- Table structure for `sysmodel`系统菜单表
    -- ----------------------------
    DROP TABLE IF EXISTS `sysmodel`;
    CREATE TABLE `sysmodel` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `title` varchar(200) NOT NULL,
      `modelName` varchar(200) NOT NULL,
      `createTime` datetime DEFAULT NULL,
      `createUser` int(11) DEFAULT NULL,
      `updateTime` datetime DEFAULT NULL,
      `updateUser` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of sysmodel
    -- ----------------------------
    INSERT INTO `sysmodel` VALUES ('1', '经销商管理', 'M01', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('2', '经销商入库', 'M0101', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('3', '经销商出库', 'M0102', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('4', '经销商分销', 'M0103', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('5', '经销商退货', 'M0104', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('6', '分销商管理', 'M02', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('7', '分销商入库', 'M0201', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('8', '分销商出库', 'M0202', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', '1');
    INSERT INTO `sysmodel` VALUES ('9', '分销商分销', 'M0203', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', null);
    INSERT INTO `sysmodel` VALUES ('10', '分销商退货', 'M0204', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', null);
    INSERT INTO `sysmodel` VALUES ('11', '管理员管理', 'M03', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', null);
    INSERT INTO `sysmodel` VALUES ('12', '角色管理', 'M04', '2011-12-02 00:00:00', '1', '2011-12-02 00:00:00', null);
    
    -- ----------------------------
    -- Table structure for `user`用户表
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `badge` varchar(20) DEFAULT NULL,
      `name` varchar(200) NOT NULL,
      `ename` varchar(200) DEFAULT NULL,
      `gender` varchar(5) DEFAULT NULL,
      `company` varchar(200) DEFAULT NULL,
      `department` varchar(200) DEFAULT NULL,
      `job` varchar(200) DEFAULT NULL,
      `idCardNo` varchar(20) DEFAULT NULL,
      `birthday` date DEFAULT NULL,
      `workYears` varchar(20) DEFAULT NULL,
      `workLocation` varchar(200) DEFAULT NULL,
      `email` varchar(200) DEFAULT NULL,
      `mobile` varchar(20) DEFAULT NULL,
      `createTime` datetime DEFAULT NULL,
      `createUser` bigint(20) DEFAULT NULL,
      `updateTime` datetime DEFAULT NULL,
      `updateUser` bigint(20) DEFAULT NULL,
      `roleId` int(11) DEFAULT NULL,
      `status` varchar(10) NOT NULL DEFAULT 'on',
      PRIMARY KEY (`id`),
      KEY `createUser` (`createUser`) USING BTREE,
      KEY `updateUser` (`updateUser`) USING BTREE,
      CONSTRAINT `user_ibfk_1` FOREIGN KEY (`createUser`) REFERENCES `user` (`id`),
      CONSTRAINT `user_ibfk_2` FOREIGN KEY (`updateUser`) REFERENCES `user` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
    3. 页面代码
    注意:此处tree用到的dtree,基于javascript写的。而本人用过zTree后更推荐使用ztree,基于jquery的代码(功能点多,api详细)
    因此必须先下载dtree,此处省略下载。
     
    下载后将dtree自带的css和图片存放在项目制定路径下。
    
    本人主要修改了dtree的js代码:实现checkbox,和异步访问功能
    点击(此处)折叠或打开
    /*--------------------------------------------------|
    
    | dTree 2.05 | www.destroydrop.com/javascript/tree/ |
    
    |---------------------------------------------------|
    
    | Copyright (c) 2002-2003 Geir Landr? |
    
    | |
    
    | This script can be used freely as long as all |
    
    | copyright messages are intact. |
    
    | |
    
    | Updated: 17.04.2003 |
    
    |--------------------------------------------------*/
    
    
    
    // Node object
    
    function Node(id, pid, name, url, title, target, icon, iconOpen, open) {
    
        this.id = id;
    
        this.pid = pid;
    
        this.name = name;
    
        this.url = url;
    
        this.title = title;
    
        this.target = target;
    
        this.icon = icon;
    
        this.iconOpen = iconOpen;
    
        this._io = open || false;
    
        this._is = false;
    
        this._ls = false;
    
        this._hc = false;
    
        this._ai = 0;
    
        this._p;
        //add by ljt
    //    this.checked=checked||false;
    
    };
    
    
    
    // Tree object
    
    function dTree(objName) {
    
        this.config = {
    
            target                    : null,
           //ljt changed it to be false
            folderLinks            : false,
    
            useSelection        : true,
    
            useCookies            : true,
    
            useLines                : true,
    
            useIcons                : true,
    
            useStatusText        : false,
    
            closeSameLevel    : false,
    
            inOrder    : false,
            
            check: true //添加选择框
    
        }
     //ljt changed this to his own path 
        this.icon = {
    
            //root                : '../images/dtree/base.gif',
         root                : '../images/dtree/ware.png',
    
            //folder            : '../images/dtree/folder.gif',
         folder                : '../images/dtree/note.png',
    
            //folderOpen        : '../images/dtree/folderopen.gif',
         folderOpen            : '../images/dtree/note.png',
    
            //node                : '../images/dtree/page.gif',
         node                : '../images/dtree/note.png',
    
            empty                : '../images/dtree/empty.gif',
    
            line                : '../images/dtree/line.gif',
    
            join                : '../images/dtree/join.gif',
    
            joinBottom    : '../images/dtree/joinbottom.gif',
    
            plus                : '../images/dtree/plus.gif',
    
            plusBottom    : '../images/dtree/plusbottom.gif',
    
            minus                : '../images/dtree/minus.gif',
    
            minusBottom    : '../images/dtree/minusbottom.gif',
    
            nlPlus            : '../images/dtree/nolines_plus.gif',
    
            nlMinus            : '../images/dtree/nolines_minus.gif'
    
        };
        //add by ljt
        this.cbCollection=new Object();
        
        
        this.obj = objName;
    
        this.aNodes = [];
        
        this.aIndent = [];
    
        this.root = new Node(-1);
    
        this.selectedNode = null;
    
        this.selectedFound = false;
    
        this.completed = false;
    
    };
    
    
    // Adds a new node to the node array
    
    dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) {
     
        this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);
    
    };
    
    // Open/close all nodes
    
    dTree.prototype.openAll = function() {
    
        this.oAll(true);
    
    };
    
    dTree.prototype.closeAll = function() {
    
        this.oAll(false);
    
    };
    
    
    
    // Outputs the tree to the page
    
    dTree.prototype.toString = function() {
    
        var str = '<div class="dtree">n';
    
        if (document.getElementById) {
    
            if (this.config.useCookies) this.selectedNode = this.getSelected();
    
            str += this.addNode(this.root);
    
        } else str += 'Browser not supported.';
    
        str += '</div>';
    
        if (!this.selectedFound) this.selectedNode = null;
    
        this.completed = true;
        
        return str;
    
    };
    
    
    
    // Creates the tree structure
    
    dTree.prototype.addNode = function(pNode) {
    
        var str = '';
    
        var n=0;
    
        if (this.config.inOrder) n = pNode._ai;
    
        for (n; n<this.aNodes.length; n++) {
    
            if (this.aNodes[n].pid == pNode.id) {
    
                var cn = this.aNodes[n];
    
                cn._p = pNode;
    
                cn._ai = n;
    
                this.setCS(cn);
    
                if (!cn.target && this.config.target) cn.target = this.config.target;
    
                if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id);
    
                if (!this.config.folderLinks && cn._hc) cn.url = null;
    
                if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) {
    
                        cn._is = true;
    
                        this.selectedNode = n;
    
                        this.selectedFound = true;
    
                }
    
                str += this.node(cn, n);
    
                if (cn._ls) break;
    
            }
    
        }
    
        return str;
    
    };
    //设置某节点不可选
    dTree.prototype.unSelected=function(nodeId){
        var ids=document.getElementsByName("c"+this.obj+"_Id");
        var tempIds=nodeId.split(",");
        for(var n=1;n<tempIds.length;n++){
            for(var i=0;i<ids.length;i++){
                if("c"+this.obj+tempIds[n]==ids[i].id){
                    ids[i].disabled=true;
                    break;
                }
            }
        }
    }
    //add by ljt set Default checked
    dTree.prototype.defaultChecked=function(nodeId){
    //    var checkbox_nameId="c"+this.obj+"_Id";
        var ids = document.getElementsByName("c"+this.obj+"_Id");
        var tempIds=nodeId.split(",");
        for(var n=0; n < tempIds.length; n++){
         for(var i=0; i<ids.length; i++){
                if("c"+this.obj+tempIds[n] == ids[i].id){
                 ids[i].checked=true;
                 break;
                }
            }
        }
         
    };
    
    //add by ljt 
    dTree.prototype.co=function(id){ 
        if (this.cbCollection[id])return this.cbCollection[id]; 
        for(var n=0; n<this.aNodes.length; n++){ 
            if(this.aNodes[n].id==id){ 
               this.cbCollection[id]=document.getElementById("c"+this.obj+id); 
                break; 
            } 
        } 
        return this.cbCollection[id]; 
    }; 
    
    //获取选择的节点
    dTree.prototype.getText=function(){
         var value=new Array();
         var cko;//checkobject
         
             for(var n=0;n<this.aNodes.length;n++){
         cko=this.co(this.aNodes[n].id);
         if(cko!=null){
         if(cko.checked==true){
                 value[value.length]=this.aNodes[n].id;
                }
         }
         }
         return value;
         
    };
    
    
    
    // Creates the node icon, url and text
    
    dTree.prototype.node = function(node, nodeId) {
    
        var str = '<div class="dTreeNode">' + this.indent(node, nodeId);
    
        if (this.config.useIcons) {
    
            if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node);
    
            if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node;
    
            if (this.root.id == node.pid) {
    
                node.icon = this.icon.root;
    
                node.iconOpen = this.icon.root;
    
            }
    
            str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />';
            
            //添加输出的复选框
            if(this.config.check==true){
             str+='<input type="checkbox" name="c'+this.obj+'_Id" id="c'+this.obj+node.id+'" onclick="javascript:'+this.obj+'.cc(''+node.id+'',''+node.pid+'')"/>';
            }
    
        }
        //复选框
        dTree.prototype.cc=function(nodeId, nodePid){
         
        //首先获取这个复选框的id
         var cs = document.getElementById("c" + this.obj + nodeId).checked;
         
        var n,node = this.aNodes[nodeId];
         
        var len = this.aNodes.length;
         
        for (n=0; n<len; n++) { //循环每一个节点
            if (this.aNodes[n].pid == nodeId) { //选择的是非子节点,则要把父节点和子节点全部选中
                document.getElementById("c" + this.obj + this.aNodes[n].id).checked = cs; 
                this.cc(this.aNodes[n].id, nodeId); //循环节点 
            } 
        } 
        
         if(cs==true){ //节点被选中状态
            var pid=nodePid; 
            var bSearch; 
            do{ 
                bSearch=false; 
                for(n=0;n<len;n++){ //循环每一个节点
                    if(this.aNodes[n].id==pid){ //如果循环的节点的Id等于PId
                         document.getElementById("c"+this.obj+pid).checked=true; //那么这个循环的节点应该被选中
                        pid=this.aNodes[n].pid; 
                        bSearch= true; 
                        break; 
                    } 
                } 
            }while(bSearch==true);
           }
           
          if(cs==false){ //取消选择
            var pid = nodePid; 
            do{ 
                for(j=0;j<len;j++){ //循环每一个多选框,如果该节点有其他子节点被选中,则不取消
                    if(this.aNodes[j].pid==pid && document.getElementById("c" + this.obj + this.aNodes[j].id).checked==true){ 
                        return; 
                    } 
                } 
                if(j==len){ //循环结束
                    for(k=0;k<len;k++){ 
                        if(this.aNodes[k].id==pid){ //找到父节点
                            document.getElementById("c"+this.obj+this.aNodes[k].id).checked=false; 
                            pid=this.aNodes[k].pid; 
                            break; 
                        } 
                    } 
                } 
            }while(pid!=-1); 
        }
     }
    
    
        if (node.url) {
    
            str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"';
    
            if (node.title) str += ' title="' + node.title + '"';
    
            if (node.target) str += ' target="' + node.target + '"';
    
            if (this.config.useStatusText) str += ' onmouseover="window.status='' + node.name + '';return true;" onmouseout="window.status='';return true;" ';
    
            if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc))
    
                str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"';
    
            str += '>';
    
        }
    
        else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id)
    
            str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">';
    
        str += node.name;
    
        if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>';
    
        str += '</div>';
    
        if (node._hc) {
    
            str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">';
    
            str += this.addNode(node);
    
            str += '</div>';
    
        }
    
        this.aIndent.pop();
    
        return str;
    
    };
    
    
    
    // Adds the empty and line icons
    
    dTree.prototype.indent = function(node, nodeId) {
    
        var str = '';
    
        if (this.root.id != node.pid) {
    
            for (var n=0; n<this.aIndent.length; n++)
    
                str += '<img src="' + ( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty ) + '" alt="" />';
    
            (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1);
    
            if (node._hc) {
    
                str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');"><img id="j' + this.obj + nodeId + '" src="';
    
                if (!this.config.useLines) str += (node._io) ? this.icon.nlMinus : this.icon.nlPlus;
    
                else str += ( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) );
    
                str += '" alt="" /></a>';
    
            } else str += '<img src="' + ( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty) + '" alt="" />';
    
        }
    
        return str;
    
    };
    
    
    
    // Checks if a node has any children and if it is the last sibling
    
    dTree.prototype.setCS = function(node) {
    
        var lastId;
    
        for (var n=0; n<this.aNodes.length; n++) {
    
            if (this.aNodes[n].pid == node.id) node._hc = true;
    
            if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id;
    
        }
    
        if (lastId==node.id) node._ls = true;
    
    };
    
    
    
    // Returns the selected node
    
    dTree.prototype.getSelected = function() {
    
        var sn = this.getCookie('cs' + this.obj);
    
        return (sn) ? sn : null;
    
    };
    
    
    
    // Highlights the selected node
    
    dTree.prototype.s = function(id) {
    
        if (!this.config.useSelection) return;
    
        var cn = this.aNodes[id];
    
        if (cn._hc && !this.config.folderLinks) return;
    
        if (this.selectedNode != id) {
    
            if (this.selectedNode || this.selectedNode==0) {
    
                eOld = document.getElementById("s" + this.obj + this.selectedNode);
    
                eOld.className = "node";
    
            }
    
            eNew = document.getElementById("s" + this.obj + id);
    
            eNew.className = "nodeSel";
    
            this.selectedNode = id;
    
            if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id);
    
        }
    
    };
    
    
    
    // Toggle Open or close
    
    dTree.prototype.o = function(id) {
    
        var cn = this.aNodes[id];
    
        this.nodeStatus(!cn._io, id, cn._ls);
    
        cn._io = !cn._io;
    
        if (this.config.closeSameLevel) this.closeLevel(cn);
    
        if (this.config.useCookies) this.updateCookie();
    
    };
    
    
    
    // Open or close all nodes
    
    dTree.prototype.oAll = function(status) {
    
        for (var n=0; n<this.aNodes.length; n++) {
    
            if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
    
                this.nodeStatus(status, n, this.aNodes[n]._ls)
    
                this.aNodes[n]._io = status;
    
            }
    
        }
    
        if (this.config.useCookies) this.updateCookie();
    
    };
    
    
    
    // Opens the tree to a specific node
    
    dTree.prototype.openTo = function(nId, bSelect, bFirst) {
    
        if (!bFirst) {
    
            for (var n=0; n<this.aNodes.length; n++) {
    
                if (this.aNodes[n].id == nId) {
    
                    nId=n;
    
                    break;
    
                }
    
            }
    
        }
    
        var cn=this.aNodes[nId];
    
        if (cn.pid==this.root.id || !cn._p) return;
    
        cn._io = true;
    
        cn._is = bSelect;
    
        if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls);
    
        if (this.completed && bSelect) this.s(cn._ai);
    
        else if (bSelect) this._sn=cn._ai;
    
        this.openTo(cn._p._ai, false, true);
    
    };
    
    
    
    // Closes all nodes on the same level as certain node
    
    dTree.prototype.closeLevel = function(node) {
    
        for (var n=0; n<this.aNodes.length; n++) {
    
            if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) {
    
                this.nodeStatus(false, n, this.aNodes[n]._ls);
    
                this.aNodes[n]._io = false;
    
                this.closeAllChildren(this.aNodes[n]);
    
            }
    
        }
    
    }
    
    
    
    // Closes all children of a node
    
    dTree.prototype.closeAllChildren = function(node) {
    
        for (var n=0; n<this.aNodes.length; n++) {
    
            if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) {
    
                if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls);
    
                this.aNodes[n]._io = false;
    
                this.closeAllChildren(this.aNodes[n]);        
    
            }
    
        }
    
    }
    
    
    
    // Change the status of a node(open or closed)
    
    dTree.prototype.nodeStatus = function(status, id, bottom) {
    
        eDiv    = document.getElementById('d' + this.obj + id);
    
        eJoin    = document.getElementById('j' + this.obj + id);
    
        if (this.config.useIcons) {
    
            eIcon    = document.getElementById('i' + this.obj + id);
    
            eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon;
    
        }
    
        eJoin.src = (this.config.useLines)?
    
        ((status)?((bottom)?this.icon.minusBottom:this.icon.minus):((bottom)?this.icon.plusBottom:this.icon.plus)):
    
        ((status)?this.icon.nlMinus:this.icon.nlPlus);
    
        eDiv.style.display = (status) ? 'block': 'none';
    
    };
    
    
    
    
    
    // [Cookie] Clears a cookie
    
    dTree.prototype.clearCookie = function() {
    
        var now = new Date();
    
        var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
    
        this.setCookie('co'+this.obj, 'cookieValue', yesterday);
    
        this.setCookie('cs'+this.obj, 'cookieValue', yesterday);
    
    };
    
    
    
    // [Cookie] Sets value in a cookie
    
    dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path, domain, secure) {
    
        document.cookie =
    
            escape(cookieName) + '=' + escape(cookieValue)
    
            + (expires ? '; expires=' + expires.toGMTString() : '')
    
            + (path ? '; path=' + path : '')
    
            + (domain ? '; domain=' + domain : '')
    
            + (secure ? '; secure' : '');
    
    };
    
    
    
    // [Cookie] Gets a value from a cookie
    
    dTree.prototype.getCookie = function(cookieName) {
    
        var cookieValue = '';
    
        var posName = document.cookie.indexOf(escape(cookieName) + '=');
    
        if (posName != -1) {
    
            var posValue = posName + (escape(cookieName) + '=').length;
    
            var endPos = document.cookie.indexOf(';', posValue);
    
            if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
    
            else cookieValue = unescape(document.cookie.substring(posValue));
    
        }
    
        return (cookieValue);
    
    };
    
    
    
    // [Cookie] Returns ids of open nodes as a string
    
    dTree.prototype.updateCookie = function() {
    
        var str = '';
    
        for (var n=0; n<this.aNodes.length; n++) {
    
            if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
    
                if (str) str += '.';
    
                str += this.aNodes[n].id;
    
            }
    
        }
    
        this.setCookie('co' + this.obj, str);
    
    };
    
    
    
    // [Cookie] Checks if a node id is in a cookie
    
    dTree.prototype.isOpen = function(id) {
    
        var aOpen = this.getCookie('co' + this.obj).split('.');
    
        for (var n=0; n<aOpen.length; n++)
    
            if (aOpen[n] == id) return true;
    
        return false;
    
    };
    
    
    
    // If Push and pop is not implemented by the browser
    
    if (!Array.prototype.push) {
    
        Array.prototype.push = function array_push() {
    
            for(var i=0;i<arguments.length;i++)
    
                this[this.length]=arguments[i];
    
            return this.length;
    
        }
    
    };
    
    if (!Array.prototype.pop) {
    
        Array.prototype.pop = function array_pop() {
    
            lastElement = this[this.length-1];
    
            this.length = Math.max(this.length-1,0);
    
            return lastElement;
    
        }
    
    };
    

      

    jsp:代码
    RoleManagerEdit.jsp

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    
    <html>
    <head><title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <% String path=request.getContextPath();
       String objId = (String)request.getAttribute("objId");
       %>
    
    <link rel="stylesheet" type="text/css" href="<%=path%>/css/jquery-ui-1.8.23.custom.css" />
    <link rel="stylesheet" type="text/css" href="<%=path%>/css/dtree.css" />
    
    <script type=text/javascript src="<%=path%>/js/common/jquery-1.7.2.js"></script>
    <script type=text/javascript src="<%=path%>/js/common/jquery-ui-1.8.23.custom.min.js"></script>
    <script type=text/javascript src="<%=path%>/js/common/jquery.ui.datepicker-zh-CN.js"></script>
    <script type=text/javascript src="<%=path%>/js/common/dateUtil.js"></script>
    <script type=text/javascript src="<%=path%>/js/common/page.js"></script>
    <script type=text/javascript src="<%=path%>/js/dynamic.jsp"></script>
    <script type="text/javascript" src="<%=path%>/js/dtree.js"></script>
    <script type="text/javascript" src="<%=path%>/js/authorityTree.js"></script>
    <script type="text/javascript">
    var tree = new dTree("tree");
    /* function doSave(p, url) {
        var array = p.getText();
        $("#authority").val(array);
        $('form')[0].action=url;
        $('form')[0].submit();
    } */
    function doSave(p, url) {
        var array = p.getText();
        $("#authority").val(array);
        
        var msg = "";
        var roleName = $('#roleName');
        if(roleName.val()==''){
            if(msg!="")
            {
                msg+="、请填写角色名称";
            }else{
                msg +="请填写角色名称";
            }
            roleName.addClass("terror"); 
        }
        if(msg!="") {
             $("#messageDivId").html(msg);
             window.scrollTo(0);//置顶
             return false;
        }else{
             if(confirm("确认 提交?")){
                 $('form')[0].action=url;
                 $('form')[0].submit();
             }
            
           }
    }
    $(document).ready(function () {
        var author = $("#authority").val();
        authority($("#tree"), tree, author);
    
    });
    function goback(url){
        $('form')[0].action=url;
        $('form')[0].submit();
    }
    </script>
    </head>
    <body>
    <form action="" method="post" name="_testForm" id="form" >
    <s:token />
     <input type="hidden" name="detailBean.authority" id="authority" value="<s:property value="detailBean.authority"/>"/>
      <input type="hidden" name="detailBean.id" id="deId" value="<s:property value="detailBean.id"/>"/>
    <div id="main">
    <jsp:include page="head.jsp" />
            <div id="middle">
            <jsp:include page="leftMenu.jsp" />
             <div class="left_middle"> 
                <p>当前位置:<span id="position_span"></span></p>
                  <h2>角色信息</h2> 
               <div id="messageDivId"></div>
                  <ul> 
                  <table width="100%" cellspacing="0" border="0" style="padding-left: 25px"> 
                  <tbody>
                  <tr>
                  <td width="70px">角色名称:</td>
                  <td><s:textfield name="detailBean.roleName" id="roleName"/> <font color="red">*</font></td> 
                   </tr>
                  <tr>
                   <td width="70px">角色描述:</td>
                  <td><s:textarea cols="95" rows="4" name="detailBean.remark" cssStyle="70%;" cssClass="toff" onchange="this.className='toff'" /> </td> 
                    </tr>
                  </tbody> 
                </table> 
                 <h4>权限分配</h4>
            <div class="dtree">
              <p><a href="javascript: tree.openAll();">全部展开</a> | <a href="javascript: tree.closeAll();">全部收拢</a></p>
              <div id="tree">
              </div> 
            </div>
            <div style="padding-top: 20px">
             <input type="button" name="save" class="button1" value="提交" onclick="doSave(tree,'<%=path%>/role/roleManagerupdate.do')" />
               <input type="button" name="back" class="button1" value="返回" onclick="goback('<%=path%>/role/roleManagerlist.do')">
              
            </div>
                
          </div>
            <div style="clear:both"></div>
        </div>
      </div>
       <script type="text/javascript">switchLeftMenu(17);</script>
      <jsp:include page="footer.jsp"></jsp:include>
    </form>
    </body>
    </html>
    

      自定义权限标签:expand.tld

    <?xml version="1.0" encoding="UTF-8"?>
    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>Schedule Tag Library</description>
    <tlib-version>1.0</tlib-version>
    <short-name>expand</short-name>
    <uri>/expand</uri>
    <tag>
    <name>ifauthorize</name>
    <tag-class>com.easytalent.common.tag.PermissionTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
    <name>author</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>
    <tag>
    <name>notauthorize</name>
    <tag-class>com.easytalent.common.tag.NoPermissionTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
    <name>author</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>
    </taglib>
    后端java代码待整理

      

    Action层代码:

    package com.easytalent.manager.action;
    
    import java.util.List;
    
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    
    import org.hibernate.annotations.common.util.StringHelper;
    import org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException;
    
    import com.easytalent.base.action.BaseAction;
    import com.easytalent.manager.bean.RoleBean;
    import com.easytalent.manager.task.RoleManagerTask;
    import com.easytalent.storage.model.Role;
    import com.easytalent.storage.model.Sysmodel;
    import com.easytalent.util.Page;
    import com.easytalent.util.StackTraceUtil;
    
    public class RoleManagerAction extends BaseAction {
    
        private RoleManagerTask roleManagerTask;//角色管理task
        private List<Role> roleList;//角色list
        private RoleBean detailBean=new RoleBean();//详细bean
        private RoleBean searchBean;//查询bean
        private Page page =new Page();
        
        
        
        public Page getPage() {
            return page;
        }
        public void setPage(Page page) {
            this.page = page;
        }
        public RoleManagerTask getRoleManagerTask() {
            return roleManagerTask;
        }
        public void setRoleManagerTask(RoleManagerTask roleManagerTask) {
            this.roleManagerTask = roleManagerTask;
        }
        public List<Role> getRoleList() {
            return roleList;
        }
        public void setRoleList(List<Role> roleList) {
            this.roleList = roleList;
        }
        public RoleBean getDetailBean() {
            return detailBean;
        }
        public void setDetailBean(RoleBean detailBean) {
            this.detailBean = detailBean;
        }
        public RoleBean getSearchBean() {
            return searchBean;
        }
        public void setSearchBean(RoleBean searchBean) {
            this.searchBean = searchBean;
        }
        /**
         * 角色管理action
         * @return
         */
        public String list() {
            try {
                this.initBase();
                roleList = roleManagerTask.getAll(searchBean,page);
                this.page.setPagebar();
                return LIST;
            } catch (Exception e) {
                logger.error(StackTraceUtil.getStackTrace(e));
            } finally {
            }
            return ERROR;
        }
        /**
         * 角色管理新增空跳转
         * @return
         */
        public String add() {
            try {
                this.initBase(); // 初始化
                StringBuilder sb = new StringBuilder("");
                String objId = utilBean.getObjId();
                return EDIT;
            } catch (HibernateObjectRetrievalFailureException e) {
                // 如果关联到了脏数据,会抛出磁异常(数据库没设外间,有可能有脏数据在里面)
            } catch (Exception e) {
            } finally {
            }
            return ERROR;
        }
        /**
         * 获得菜单树
         * 
         * @return
         */
        public String tree() {
            try {
                this.initBase(); // 初始化
                List<Sysmodel> list = roleManagerTask.getAuthorityTree();
                JSONArray jsonArray = new JSONArray();
               JSONObject json = null;
                for (Sysmodel model : list) {
                    json = new JSONObject();
                    json.put("id", model.getId());
                    json.put("name", model.getModelName());
                    json.put("title", model.getTitle());
                    jsonArray.add(json);
                }
                json=new JSONObject();
               json.put("success", true);
               json.put("data", jsonArray);
               this.outPrint(json);
                return NONE;
            } catch (HibernateObjectRetrievalFailureException e) {
                // 如果关联到了脏数据,会抛出磁异常(数据库没设外间,有可能有脏数据在里面)
            } catch (Exception e) {
            } finally {
            }
            return ERROR;
        }
        /**
         * 查看方法
         * @return
         */
        public String detail() {
            try {
                this.initBase();// 初始化
                String objId = this.utilBean.getObjId();
                StringBuilder sb = new StringBuilder("");
                if (StringHelper.isNotEmpty(objId)) {
                    Role model = roleManagerTask.findById(Long.valueOf(objId));
                    this.detailBean = roleManagerTask.model2detailBean(model);
                    List<String> authors = roleManagerTask.getAuthors(Long.valueOf(objId));
                    if (authors != null) {
                        for (String author : authors) {
                            sb.append(",");
                            sb.append(author);
                        }
                    }
                    if (sb.length() > 0) {
                        detailBean.setAuthority(sb.substring(1));
                        detailBean.setId(Long.valueOf(objId));
                    } else {
                        detailBean.setAuthority("");
                        detailBean.setId(Long.valueOf(objId));
                    }
                    return DETAIL;
                }
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return LIST;
        }
        /**
         * 修改新增方法
         * @return
         */
        public String update() {
            try {
                this.initBase();// 初始化
                Long objId = this.detailBean.getId();
                if (request.getParameter("struts.token").equals( 
                        request.getSession().getAttribute("struts.token"))) {
                    if (objId!=null) {// 修改
                        Role model = roleManagerTask.detail2model(detailBean);
                        model = roleManagerTask.updateRole(model);
                        roleManagerTask.saveAuthority(model.getId(), detailBean.getAuthority());//先删掉之前的在新增现在的
                        this.utilBean.setMessage(this.getText("msg.update.success"));
                    } else {// 新增
                        Role model = roleManagerTask.detail2model(detailBean);
                        model = roleManagerTask.saveRole(model);
                        roleManagerTask.saveAuthority(model.getId(), detailBean.getAuthority());
                        this.utilBean.setMessage(this.getText("msg.submit.success"));
                    }
                }
                return list();// 一览页面
            } catch (Exception e) {
            } finally {
            }
            return ERROR;
        }
    }
    

      Task业务层:

    package com.easytalent.manager.task.impl;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import org.springframework.beans.BeanUtils;
    
    import com.easytalent.manager.bean.RoleBean;
    import com.easytalent.manager.task.RoleManagerTask;
    import com.easytalent.storage.dao.AccountDao;
    import com.easytalent.storage.dao.AuthorityDao;
    import com.easytalent.storage.dao.RoleManagerDao;
    import com.easytalent.storage.dao.SysmodelDao;
    import com.easytalent.storage.model.Account;
    import com.easytalent.storage.model.Authority;
    import com.easytalent.storage.model.Role;
    import com.easytalent.storage.model.Sysmodel;
    import com.easytalent.util.ComUtil;
    import com.easytalent.util.Page;
    
    public class RoleManagerTaskImpl implements RoleManagerTask {
    
        private RoleManagerDao roleManagerDao;// 角色管理dao
        private AccountDao accountDao;
        private AuthorityDao authorityDao;// 角色权限表
        private SysmodelDao sysmodelDao;// 系统菜单表
    
        public SysmodelDao getSysmodelDao() {
            return sysmodelDao;
        }
    
        public void setSysmodelDao(SysmodelDao sysmodelDao) {
            this.sysmodelDao = sysmodelDao;
        }
    
        public AuthorityDao getAuthorityDao() {
            return authorityDao;
        }
    
        public void setAuthorityDao(AuthorityDao authorityDao) {
            this.authorityDao = authorityDao;
        }
    
        public AccountDao getAccountDao() {
            return accountDao;
        }
    
        public void setAccountDao(AccountDao accountDao) {
            this.accountDao = accountDao;
        }
    
        public RoleManagerDao getRoleManagerDao() {
            return roleManagerDao;
        }
    
        public void setRoleManagerDao(RoleManagerDao roleManagerDao) {
            this.roleManagerDao = roleManagerDao;
        }
    
        public List<Role> getAll(RoleBean bean, Page page) throws Exception {
            try {
                if (page.getOrderBy() == null || "".equals(page.getOrderBy())) {
                    page.setOrderBy("o.updateTime desc");
                }
                List<Role> list = roleManagerDao.getAllRolses(bean, page);
                return list;
            } catch (Exception e) {
                // logger.error(StackTraceUtil.getStackTrace(e));
                throw e;
            } finally {
            }
        }
    
        public Role saveRole(Role model) throws Exception {
            try {
                model = roleManagerDao.save(model);
                return model;
            } catch (Exception e) {
                // logger.error(StackTraceUtil.getStackTrace(e));
                throw e;
            } finally {
            }
        }
    
        @Override
        public Role detail2model(RoleBean detailBean) {
            Role modelBean = null;
            if (detailBean != null) {
                modelBean = new Role();
                BeanUtils.copyProperties(detailBean, modelBean);
            }
            return modelBean;
        }
    
        @Override
        public RoleBean model2detailBean(Role model) {
            RoleBean detailBean = null;
            if (model != null) {
                detailBean = new RoleBean();
                BeanUtils.copyProperties(model, detailBean);
    
            }
            return detailBean;
        }
    
        @Override
        public Role findById(Long objId) throws Exception {
            try {
                return roleManagerDao.get(objId);
            } catch (Exception e) {
                // logger.error(StackTraceUtil.getStackTrace(e));
                throw e;
            } finally {
            }
        }
    
        @Override
        public Account getUserInfo(String id) throws Exception {
            try {
                return accountDao.get(Long.valueOf(id));
            } catch (Exception e) {
                // logger.error(StackTraceUtil.getStackTrace(e));
                throw e;
            } finally {
            }
        }
    
        @Override
        public List<String> getAuthors(Long roleId) {
            List<String> authors = authorityDao.getByRoleId(roleId);
            if (authors == null) {
                return null;
            }
            List<String> authority = new ArrayList<String>();
            for (String author : authors) {
                authority.add(author);
            }
            return authority;
        }
    
        @Override
        public List<Sysmodel> getAuthorityTree() throws Exception {
            try {
                List<Sysmodel> list = sysmodelDao.getAuthorityList();
                return list;
            } catch (Exception e) {
                // logger.error(StackTraceUtil.getStackTrace(e));
                throw e;
            } finally {
            }
        }
    
        public String saveAuthority(Long roleId, String authorlist)
                throws Exception {
            authorityDao.deleteAuthority(roleId);// 清空此角色的权限
            if (authorlist == null) {
                return "";
            }
            Authority authority = null;
            for (String author : authorlist.split(",", -1)) {
                authority = new Authority();
                Sysmodel sysmodel = sysmodelDao.getSysmodel(author);
                if (sysmodel == null) {
                    continue;
                }
                authority.setRoleId(roleId);
                authority.setSysmodel(sysmodel);
                authority.setCreateTime(new Date());
                authority.setUpdateTime(new Date());
                this.authorityDao.save(authority);
            }
            return authorlist;
    
        }
    
        @Override
        public Role updateRole(Role model) throws Exception {
            Date nowDate = ComUtil.getSystemDate();
            model.setUpdateTime(nowDate);
            return roleManagerDao.update(model);
        }
    
    }
    

      DAO层

    RoleManagerDaoImpl
    
    package com.easytalent.storage.dao.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.hibernate.annotations.common.util.StringHelper;
    
    import java.util.List;
    
    import com.easytalent.base.dao.impl.GenericDaoImpl;
    import com.easytalent.manager.bean.RoleBean;
    import com.easytalent.storage.dao.RoleManagerDao;
    import com.easytalent.storage.model.Role;
    import com.easytalent.util.Page;
    
    public class RoleManagerDaoImpl extends GenericDaoImpl<Role, Long> implements
            RoleManagerDao {
        public RoleManagerDaoImpl() {
            super(Role.class);
        }
        /**
           * 取得学位List
           */
          public List<Role> getRoleList() {
              String hql = "from Role c order by c.id asc";
              return this.findByHql(hql);
          }
        @Override
        public List<Role> getAllRolses(RoleBean bean, Page page) {
            Object[] paramArray = null;
            StringBuilder hql = new StringBuilder();
            hql.append("from Role o where 1=1 ");
            if (bean != null) {
                List<Object> param = new ArrayList<Object>();
                String name = bean.getRoleName();
                if (StringHelper.isNotEmpty(name)) {
                    hql.append("and o.roleName like ? ");
                    param.add("%" + name.trim() + "%");
                }
                paramArray = param.toArray();
            }
            hql.append(" order by ");
            hql.append(page.getOrderBy());
            return this.findByHql(hql.toString(), paramArray, page);
        }
    
    }
    

      

    package com.easytalent.storage.dao.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.easytalent.base.dao.impl.GenericDaoImpl;
    import com.easytalent.storage.dao.SysmodelDao;
    import com.easytalent.storage.model.Sysmodel;
    
    public class SysmodelDaoImpl extends GenericDaoImpl<Sysmodel, Long> implements
            SysmodelDao {
        public SysmodelDaoImpl() {
            super(Sysmodel.class);
        }
    
        @Override
        public List<Sysmodel> getAuthorityList() {
            String hql = "from Sysmodel t order by t.modelName asc ";
            return this.findByHql(hql);
        }
         /**
         * 通过名称取得菜单模型
         * @return
         */
        public Sysmodel getSysmodel(String modelName) {
            Object[] paramArray = null;
            List<Object> param = new ArrayList<Object>();
            String hql = "from Sysmodel t where t.modelName = ? ";
            param.add(modelName);
            paramArray = param.toArray();
            Object obj = this.findUniqueResult(hql, paramArray);
            if (obj != null) {
                return (Sysmodel) obj;
            }
            return null;
        }
    }
    

      

    package com.easytalent.storage.dao.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.easytalent.base.dao.impl.GenericDaoImpl;
    import com.easytalent.storage.dao.AuthorityDao;
    import com.easytalent.storage.model.Authority;
    
    public class AuthorityDaoImpl extends GenericDaoImpl<Authority, Long> implements AuthorityDao {
        public AuthorityDaoImpl() {
            super(Authority.class);
        }
    
        @Override
        public int deleteAuthority(Long roleId) throws Exception {
            Object[] paramArray = null;
            List<Object> param = new ArrayList<Object>();
            String hql = "delete from Authority t where t.roleId = ? ";
            param.add(roleId);
            paramArray = param.toArray();
            return this.execByHql(hql, paramArray);
        }
    
        @Override
        public List<String> getByRoleId(Long roleId) {
            Object[] paramArray = null;
            List<Object> param = new ArrayList<Object>();
            //因为 authority 和sysmodel是多对一,所以,查询多条authority势必会发送多条语句去查询sysmodel
            //为了避免这个问题,用复杂的hql关联查询,返回obj[]的list
            String hql = "select s.modelName from Authority t join t.sysmodel s where t.roleId = ? ";
            param.add(roleId);
            paramArray = param.toArray();
            List<String> authorlist = this.findByHqlReturnObjectArray(hql, paramArray);
            return authorlist;
        }
    }
    

      Struts.xml配置:

    <package name="role" namespace="/role" extends="struts-elearning">
            <action name="roleManager*" class="roleManagerAction" method="{1}">
                <result name="list">/jsp/common/RoleManagerList.jsp</result>
                <result name="edit">/jsp/common/RoleManagerEdit.jsp</result>
                <result name="detail">/jsp/common/RoleManagerEdit.jsp</result>
            </action>
        </package>
    

      

  • 相关阅读:
    mysql常用基本命令
    mysql8.0.13下载与安装图文教程
    k8s ingress 增加跨域配置
    Jenkins 备份恢复插件 thinBackup 使用
    k8s HA master 节点宕机修复
    nginx 跨域问题解决
    mongodb 3.4.24 主从复制
    k8s 线上安装 jenkins并结合 jenkinsfile 实现 helm 自动化部署
    k8s helm 运用与自建helm仓库chartmuseum
    centos6 源码安装 unzip
  • 原文地址:https://www.cnblogs.com/a757956132/p/4355174.html
Copyright © 2011-2022 走看看