Recentemente, estou trabalhando em um projeto do tipo sites que requer o controle do módulo de acesso do usuário (permissões); portanto, um simples conjunto de funções de controle de permissão é projetado e implementado.
1. Design de banco de dados
Usuário: usuários
Módulos: módulos
Código SQL:
/*Tipo de servidor de destino: MySQLTarget Server Versão: 50628 File Encoding: 65001Date: 2016-08-26 10: 35: 28*/set estrago_key_checks = 0;-------------------------------------- Tabela Estrutura para `Modules`- --------------------- Tabela de queda se exist` ` Auto_increment NULL, `Module` Varchar (30) Comentário Nulo Padrão '模块',` Pid` Int (10) Comentário Nulo Padrão '上一级 Id', `Level` Int (4) NULL Comment 'MODETILIGUENO', UTF8 ---, 级别 ', Key Primary (` Id`)) MONEM = Innodb REFRINGIACHIATIACHIATIACHIACHAI- -------------------------------- Tabela de tabela para `usuários`-- -------------------------------------- Tabela se existe` usuários`; crie a tabela `usuários` (` user_code` varchar (10) não nulo comentário '用户代码', `user_name`arcar (40) comentar nulo '' '' '' '' '' '' ',` `user_name`char`char (40) null comentário' '', 'user_ user_eser_ 100 Comente nulo padrão 'qq', `msn` varchar (50) comentário nulo padrão 'msn',` demo` varchar (100) comentar nulo padrão '备注', `auth_code` text comentário '权限码', chave primária (` user_code`)) = innodb REFERTIONIAI-
1. Implementação de back-end <br /> A estrutura SSM+Freemarker é usada no projeto para encapsular permissões na estrutura de dados da árvore de permissão e depois convertê-la no formato JSON.
1) A camada de exibição adota a árvore Ztree (setUserauthontree.html)
<! Doctype html> <html> <head> <#inclua "Common/res.html"/> <script src = "$ {base.ctx} /js/layer-v2.1/laypage/laypage.js"> </script> <link href = "$ {base.ctx} /js/layer-v2.1/laypage/skin/laypage.css" rel = "stylesheet" type = "text/css"/> <script src = "$ {base.ctx} /js/layer-v2.lystrc =" $ {base.ctx} /js/layer-v2.lys Estilo-> <link href = "$ {base.ctx} /component/ztree/css/ztreestyle/ztreestyle.css" rel = "STILEET" type = "text/css"/> <script type = "text/javascript" src="${base.ctx}/component/ztree/js/jquery.ztree.core-3.5.js"></script><script type="text/javascript" src="${base.ctx}/component/ztree/js/jquery.ztree.excheck-3.5.js"></script><style type = "text/css">. blue-madison {borda: 1px sólido #7ca7cc; Border-top: 0;}. Legenda {Background-Color: #578EBE; Bottom de fronteira: 0; preenchimento: 0 10px; Margin-Bottom: 0; Cor: #fff;} </style> </head> <body> <div style = "overflow-y: automático; largura: 400px; altura: 550px;"> <div id = "ztree"> <l iD = "Treedemo"> </ul> <//Divgin> <div> <div> <align ""> </ul> </liD> </divg. ONCLICK = "EDITMODLE ()"> ok </botão> <button type = "button" id = "cancel"> feche </button> </div> </div> </div> <cript> $ ("document"). Data: {"id": "$ {userID}"}, Datatype: "JSON", Sucesso: função (resultado) {ztreeobj = $ .fn.ztree.init ($ ("#Treedemo"), Result.datas.data); // carrega a árvore var ztreeobj; // For in-depth use, please refer to the API documentation (detailed explanation of setting configuration) var setting = { view : { //dblClickExpand : false, showLine : true, //Does the connection between nodes be displayed}, check: { enable: true, //nocheckInherit: false, chkStyle: "checkbox", chkboxType: { "Y": "ps", "N": "PS"}, // AutoCheckTrigger: true}, retorno de chamada: {Oncheck: ztreeoncheck,}}; // Caixa de seleção Clicou função de evento de retorno de chamada ztreeoncheck (evento, árvore, treenode) { /* var ztree = $ .fn.ztree.getztreeobj ("Treedemo"); var alteroNodes = ztree.getChanGecheckedNodes (); for (var i = 0; i <alteraçõesNodes.Length; i ++) {var Treenode = alteraçãoNodes [i]; } */}; função editModle () {var rootid = null; var midID = nulo; var minid = nulo; var Treeobj = $ .fn.ztree.getztreeobj ("Treedemo"); var nós = Treeobj.getCheckedNodes (); for (var i = 0; i <modes.length; i ++) {if (nós [i] .Level == 0) {rootid = rootid+","+nós [i] .id; } if (nós [i] .LEvel == 1) {midId = midId+","+nós [i] .id; } if (nós [i] .LEvel == 2) {minid = minid+","+nós [i] .id; }} if (rootid! = null) {rootid = rootid.substring (5, rootid.length); } if (midId! = null) {midId = midId.substring (5, midid.length); } if (minid! = null) {minid = minid.substring (5, minid.length); } $ .ajax ({type: "post", url: "$ {base.ctx}/setup/updateUsertrightMaskbyajax", datatype: "json", dados: {"rootId": rootid, "midid": midid, "minid": minid, "userId": "$ {{{{{ if (resultado == "1") {Layer.msg ("Empoderado com sucesso!"); } // Fechar $ ("#cancel"). Clique (function () {top.dialog.get ("set-Dialog"). Close (). Remow ();}); </script> </body> </html> O efeito de exibição é o seguinte:
2) A camada de controle do controlador usa Springmvc
Na camada de controle, converta os dados no formato JSON e envie -os para a camada de exibição.
/** * @fun Obtenha permissões de usuário da filial * @author pi feng * @date 2016/8/25 * @param session * @param id * @param subestoreid * @return */@ReQuestMapping ("getUSerRrightMaskbyId") @ResponseBody Public Object getUsertEdMaskId (HTTPSTSTSTSTSSESSESSÃO, SUBSTITUIÇÃO SUBRESSISSÃO (HTTSTSTSTSTSTSTSTSTSTS, subestoreid = stringUtils.isEmpty (subestoreid)? string.valueof (session.getAttribute ("subestoreid")): subestoreid; // julgue se é um hotel ou uma lista de pousadas <map <string, object>> versionsList = this.setupService.gethoTelversions (sub -suboid); Objeto versions = versionsList.get (0) .get ("versões"); Mapa <string, object> hotelmap = new hashmap <string, object> (); if ((null! = versionsList) && (versionsList.size ()! = 0)) {// Lista não está vazia se ("complete" .equals (versões)) {// hotel // Permissões de permissão de hotel de consulta HotelMap = this.rightMaskSaskService.getUsertMaskontree (subestoreid, id, "); } else if ("simples" .equals (versões)) {// inn // query inn permissão árvore hotelmap = this.rightMaskService.getUserrrightMaskontree (subestoreid, id, "simples"); }} Mapa <string, object> resultmap = new hashmap <string, object> (); resultmap.put ("dados", HotelMap); return jsonObject.TojSonstring (ResultMap, SerializerFeature.WriteMapNullValue); } 3) A camada de serviço encapsula permissões em uma estrutura de dados de árvore que satisfaz o formato Ztree
/** * @fun Obtenha permissões de usuário da filial * @Author Pi Feng * @Date 2016/8/25 * @param subestoreid * @param id * @param versões * @return map <string, object> */@override mapa public <string> objeto> getUserrrightMaskOntree (stringeid, string, string, versões). userrrightMask = this.irightMaskdao.getUserRrightMaskbysubandid (subestoreid, id); List <map <string, object >> listOne = new ArrayList <map <string, object >> (); List <map <string, objeto >> listTwo = new ArrayList <map <string, objeto >> (); // list <map <string, object >>> listThree = new ArrayList <map <string, object >> (); List <map <string, object >>> resultadolist = new ArrayList <map <string, object >> (); if (versions.equals ("complete")) {// hotel listOne = this.irightMaskdao.gettletMaskonhotelone (); listTwo = this.irightMaskdao.gettletMaskonhoteltwo (); // listThree = this.irightMaskdao.gettletReskonhotelThree (); PackagingTotwotree (ResultList, ListOne, ListTwo, UserRrightMask); } else if (versions.equals ("simples")) {// inn listOne = this.irightMaskdao.gettreathMaskontavernone (); listTwo = this.irightMaskdao.gettreathMaskontaverntwo (); // listThree = this.irightMaskdao.gettreathMaskontavernthree (); PackagingTotwotree (ResultList, ListOne, ListTwo, UserRrightMask); } Mapa <string, object> map = new hashmap <string, object> (); map.put ("dados", resultlist); mapa de retorno; }/** * @function encapsular uma árvore de primeiro nível * @author pi feng * @date 2016/8/26 * @param resultList * @param listOne * @param authcode * @return void */private void PackagingToneTeree (list <map <string, object>> result, list <paping <, string <, object> 0; rootmap.put ("id", listOne.get (i) .get ("id")); rootmap.put ("nome", listOne.get (i) .get ("módulo")); if (validaterightMask (listOne, authcode, i)! = -1) {rootmap.put ("verificado", true); } else {rootmap.put ("verificado", false); } resultadoList.add (rootMap); }}/** * @function encapsular uma árvore secundária * @author pi feng * @date 2016/8/26 * @param resultList * @param listOne * @param listtwo * @param <putcode * @return void */private void PackagingToTwotree (list <pap <string, string *>. listTwo, map <string, object >> authcode) {for (int i = 0; i <listOne.size (); i ++) {list <map <string, object >> midlist = new ArrayList <map <string, object >> (); para (int j = 0; j <listtwo.size (); j ++) {if (listtwo.get (j) .get ("pid"). tostring () .equals (listOne.get (i) .get ("id"). Mapa <string, objeto> midmap = new hashmap <string, object> (); midmap.put ("id", listtwo.get (j) .get ("id")); midmap.put ("nome", listTwo.get (j) .get ("módulo")); midmap.put ("crianças", minlist); if (validaterightMask (listtwo, authcode, j)! = -1) {midmap.put ("verificado", true); } else {midmap.put ("verificado", false); } midlist.add (Midmap); }} Mapa <string, object> rootmap = new hashmap <string, object> (); rootmap.put ("id", listOne.get (i) .get ("id")); rootmap.put ("nome", listOne.get (i) .get ("módulo")); rootmap.put ("crianças", lista média); if (validaterightMask (listOne, authcode, i)! = -1) {rootmap.put ("verificado", true); } else {rootmap.put ("verificado", false); } resultadoList.add (rootMap); }}/** * @function encapsular uma árvore de terceiro nível * @Author Pi Feng * @Date 2016/8/26 * @param resultList * @param listOne * @param listTwo * @param listTwo * @param AuthCode * @return void */private PackagingToTTETReeTree ( * @param AuthCode * @return void */private PackagingToTReTree ( ListOne, List <map <string, objeto >> listTwo, list <map <string, object>> listThree, map <string, object> authcode) {for (int i = 0; i <listOne.size (); i ++) {list <map <string, object >> midlist = new Arraylist <pap <pin, object>; para (int j = 0; j <listtwo.size (); j ++) {if (listtwo.get (j) .get ("pid"). tostring () .equals (listOne.get (i) .get ("id"). for (int k = 0; k <listThree.size (); k ++) {map <string, object> minmap = new hashmap <string, object> (); if (listThree.get (k) .get ("pid"). tostring () .equals (listtwo.get (j) .get ("id"). tostring ())) {minmap.put ("id", listThree.get (k) .get ("id"); minmap.put ("nome", listThree.get (k) .get ("módulo")); if (validaterightMask (listThree, authcode, k)! = -1) {minmap.put ("verificado", true); } else {minmap.put ("verificado", false); } minlist.add (minmap); }} Mapa <string, object> midmap = new hashmap <string, object> (); midmap.put ("id", listtwo.get (j) .get ("id")); midmap.put ("nome", listTwo.get (j) .get ("módulo")); midmap.put ("crianças", minlist); if (validaterightMask (listtwo, authcode, j)! = -1) {midmap.put ("verificado", true); } else {midmap.put ("verificado", false); } midlist.add (Midmap); }} Mapa <string, object> rootmap = new hashmap <string, object> (); rootmap.put ("id", listOne.get (i) .get ("id")); rootmap.put ("nome", listOne.get (i) .get ("módulo")); rootmap.put ("crianças", lista média); if (validaterightMask (listOne, authcode, i)! = -1) {rootmap.put ("verificado", true); } else {rootmap.put ("verificado", false); } resultadoList.add (rootMap); }}/** * @function Verifique se existe um código de permissão no AuthCode na lista * @author pi feng * @date 2016/8/26 * @param list * @param authcode * @param i * @return int */private int ValidaterLask (list <pap <pp, object>> authcode.get ("auth_code")! = null? authcode.get ("auth_code"). tostring (): ""; if (! stringUtils.isEmpty (RightMask)) {RightMask = RightMask.replace (";", ","); String [] Array = RightMask.split (","); for (int j = 0; j <arry.length; j ++) {string ArrayRightMask = arry [j]; String listRrightMask = list.get (i) .get ("id"). Tostring (); if (arryrightmask.equals (listrightmask)) {return 1; }}} else {return -1; } retornar -1; } 4) Consulte o banco de dados para obter permissões de usuário
um. Retire diferentes níveis de permissões da tabela de módulos de acordo com o nível de permissão na camada de dados.
Selecione ID, módulo, PID, nível de módulos em que nível = '0' selecione ID, módulo, PID, nível de módulos em que nível = '1' Selecione ID, módulo, PID, nível de módulos em que nível = '2'
b. Retire todas as permissões de um usuário (código de permissão) na tabela de usuários
Selecione auth_code entre usuários onde user_code = 'pifeng'
c. Ao economizar permissões, os códigos de permissão entre diferentes níveis são separados pelo semicolon britânico ";" e os códigos de permissão entre o mesmo nível são separados pela vírgula britânica ". Por exemplo: 1,2,3,4,5,6,7,8,9,10,11,12; 13,14,15,16,17,18,19,20,21,22,23,24,25,26,36,37,27,28,29,30,31,32,33,34,35,38,39,40,41,42,42,444 ,45,46,47,48,49,50,51,52,53,54,56,57,58,59,60,61,62,63,64,133,65,66,67,68,69,70,71,72,73,74,75,1 26,127,128,129,130,131,76,77,78,79,80,81,82,83,84,85,86,87,88,99,124,134,135,136,140,141,89,90,91,92,93,94,95,9 6,97,98.137.138.139.100.101.102.103.106.107.132.108.109.110.111.112.113.114.115.116.125.117.11.11.120.121.122
5) Use a tag Freemarker para controlar se o módulo de função da página é exibido de acordo com o código de permissão do usuário
um. Configuração do Freemarker no arquivo XML
<bean id = "FreemarkerConfig"> <!-Caminho de carregamento de modelo-> <propriedade name = "templatelOaderpath"> <valor>/web-inf/ftl/</value> </propriedade> <names = "freemarkervariables"> <pap> key = "xml_escape" -ref. name = "FreemarkerSettings"> <PRESPS> <propi key = "tag_syntax"> auto_detect </prop> <props key = "template_update_delay"> 0 </prop> <propr key = "default_encoding"> utf-8 </prop> <prop. key = "Locale"> zh_cn </prop> <propi key = "date_format"> yyyy-mm-dd </prop> <propi key = "time_format"> hh: mm: ss </pp> <prop key = "number_format"> 0. <!-Processamento de valor nulo-> <prop key = "Classic_Compatible"> true </pup> <!-importe automaticamente o modelo FTL e use o alias "base" como espaço para nome-> <props key = "auto_import"> inc/spring.ftl como base </prop> </props> </property> </bean "> id = "freemarkerviewResolver"> <propriedade name = "sufix" value = ". html"/> <propriedade name = "cache" value = "false"/> <propriedades name = "viewclass" value = "org.springframework.web.sertlet.view.fremarker.freemerview"/> value = "text/html; charset = utf-8"> </propriedade> <!-Corrigida Exceção: Não é possível expor o atributo da sessão 'sub-reex' por causa de um modelo existente-> <nome da propriedade "PermissessionOverride" value = "true"/> <nome da propriedade = "exposereQuestTributes" = "True"/> <nome "" Exposition = "Expõe exporttriTtr"/"/> <weead"/> <nome da propriedade = "exposmissortTRTTRIBTIBTIBTRIDA"/"/> <weee"/> name = "ExposesPringMacrohelpers" value = "true"/> <!-esse valor variável é pageContext.request, método de uso da página: request.ContextPath-> <Nome da propriedade "RequestContextTtribute" Value = "Request"/> <Nome da propriedade = "Nome do FRIMERTIMAP"> <pAptTtribute " Associado à classe de ferramentas que definimos anteriormente-> <bean/> </sterment> </pap> </Property> </bean>
b. Escreva uma classe para herdar a classe Templatemethodmodel e implementar o método personalizado Freemarker para controlar se o módulo de página exibe login e armazenar o código de permissão do usuário na sessão e obter permissão da sessão. Aqui está um exemplo:
classe pública MenuFunction implementa TemplatemethodModel {@Override public Object Exec (List Arg0) lança TemplatemodException {int Level = Integer.valueof (arg0.get (0) .toString ()); // Nível do módulo int modelId = Integer.ValueOf (arg0.get (1) .toString ()); // ID do módulo Int count = 0; // Registre sessão se o código de permissão para este módulo httpServletRequest request = ((servletRequestattributes) requestContextholder.getRequestAttributes ()). GetRequest (); Session httpSession = request.getSession (); Objeto o = session.getAttribute ("info"); if (o == null) retorna false; Info info = (info) o; String authcode = info.getUser (). GetAuthCode (); // Código de permissão if (authcode.contains (";"; ")) {string [] Masks = authcode.split ("; "); String [] m = máscaras [nível] .split (","); for (int i = 0; i <M.Length; i ++) {if (modelId == Integer.parseint (m [i])) {++ count; } else {count+= 0; }}}} if (count == 0) {return false; } else {return true; }}} c. Use a tag Freemarker na página e controle a exibição do módulo está oculta
Dois parâmetros em Menucall, o primeiro é o nível do módulo e o segundo é o ID do módulo
Por exemplo:
<#IF Menucall (1,122)> <li style = "line-theight: 250%"> <a href = "#" id = "booknew"> <i> </i> reserva </a> </li> </#se>
O exposto acima é a implementação geral do controle do módulo de acesso do usuário (permissões).
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.