【C#MVC4】選單管理和訪問許可權分配(四)
這一篇,介紹選單的管理功能。
上一篇中,我們完成了過渡,明白了本例是通過讀取xml檔案的方式載入選單到easyui的tree控制元件上的。也自己模擬了而一個選單(手動建立),選單最終肯定是要從資料庫中載入而得,由於資料庫目前是空的,暫時不做這一塊的東西。等到專案最後再回頭做。這裡使用這個模擬的選單做 選單的建立工作。
按照習慣,從後往前書寫,做選單管理就是對Menu_list的正刪改查:
Service層:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Arise.Model;
using Arise.Common;
namespace Arise.Service
{
public class Menu_List_Service
{
public IList<Menu_List> GetAllMenuList()
{
using(AriseEntities ariseEntities = new AriseEntities())
{
return ariseEntities.Menu_List.ToList();
}
}
public Menu_List GetMenuListById(Guid MenuListId)
{
using(AriseEntities ariseEntities = new AriseEntities())
{
return ariseEntities.Menu_List.Where(ml => ml.Menu_List_Id == MenuListId).FirstOrDefault();
}
}
public void SaveMenuList(Menu_List menuList,string saveType)
{
using(AriseEntities ariseEntities = new AriseEntities())
{
try
{
if(saveType.ToUpper() == "ADD")
{
ariseEntities.Menu_List.Add(menuList);
}
else
{
ariseEntities.Entry(menuList).State = System.Data.Entity.EntityState.Modified;
}
ariseEntities.SaveChanges();
}
catch(Exception ex)
{
throw ex;
}
}
}
public void DeleteMenuList(Guid menuListId)
{
using(AriseEntities ariseEntities = new AriseEntities())
{
//這裡最好加上當前刪除的連結是否有使用者在使用的業務
//....
Menu_List menuList = ariseEntities.Menu_List.Where(ml => ml.Menu_List_Id == menuListId).FirstOrDefault();
ariseEntities.Entry(menuList).State = System.Data.Entity.EntityState.Deleted;
ariseEntities.SaveChanges();
}
}
}
}
上面的方法很明顯了,
GetAllMenuList():獲取所有選單,裝載到list集合中。
GetMenuListById():通過Id獲取Menu物件。
SaveMenuList():新增和修改Menu,這裡通過欄位saveType來判斷是新增還是修改Menu。
DeleteMenuList():刪除Menu,這裡做的不是很完善,當期按鈕若存在使用者使用時,不應該刪除成功的,但是這裡沒做這個業務,有興趣的可以自己判斷一下,就是去關聯查詢Menu_List_Access,若存在則不允許刪除即可。
Manager層:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Arise.Model;
using Arise.Service;
namespace Arise.Manager
{
public class Menu_List_Manager
{
private Menu_List_Service menuListService = new Menu_List_Service();
public IList<Menu_List> GetAllMenuList()
{
return menuListService.GetAllMenuList();
}
public Menu_List GetMenuListById(string MenuListId)
{
if (MenuListId == "")
{
return null;
}
return menuListService.GetMenuListById(Guid.Parse(MenuListId));
}
public void SaveMenuList(Menu_List menuList, string saveType)
{
try
{
menuListService.SaveMenuList(menuList,saveType);
}
catch(Exception ex)
{
throw ex;
}
}
public void DeleteMenuList(string menuListId)
{
if (menuListId != "")
{
menuListService.DeleteMenuList(Guid.Parse(menuListId));
}
}
}
}
這裡什麼贅述的,就是簡單的呼叫,值得一提的是,因為資料庫Id欄位為uniqueidentifier,這裡需要使用Guid。
重點來了,一大波程式碼正在前進:
我先將Controller的程式碼和View的發出來,兩相結合,講解:
Controller層:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Arise.Common;
using Arise.Model;
using Arise.Manager;
namespace Arise.Web.Controllers
{
public class AdminController : BaseController
{
//
// GET: /Admin/
public ActionResult Home()
{
User_Master userMaster = (User_Master)Session["UserMaster"];
ViewBag.User = userMaster.User_Name;
ViewBag.Date = DateTime.Now;
string userMasterId = userMaster.User_Master_Id.ToString();
string userMenuPath = System.Configuration.ConfigurationManager.AppSettings["UserMenuPath"].ToString().Trim();
string xmlPath = userMenuPath + userMasterId + ".xml";
ViewBag.MenuTreeList = MenuXMLHelper.LoadMenuXML(xmlPath);
return View();
}
public ActionResult Index()
{
return View();
}
#region Menu List Page
public ActionResult MenuList()
{
return View();
}
/*
*獲取選單資訊,並將選單資訊拼接成tree能夠識別的字串
* */
public string GeneratePermission()
{
string type = Request.Params["Type"].ToString().Trim();
Menu_List_Manager menuListManager = new Menu_List_Manager();
List<Menu_List> listMenu = menuListManager.GetAllMenuList().ToList();
string permissionList = "[";
//若menu_Level為空則表示為選單父分類
var parentlist = listMenu.Where(p => p.Menu_Level.ToString() == "").OrderBy(p => p.Serial).ToList();
for (int i = 0; i < parentlist.Count; i++)
{
if (type != "")//表示為選單管理頁面
{
permissionList += "{\"id\":\"" + parentlist[i].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + parentlist[i].Menu_Name.ToString().Trim() + " /Serial:" + parentlist[i].Serial.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"1\"}";
}
else//表示為選單許可權分配頁面
{
permissionList += "{\"id\":\"" + parentlist[i].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + parentlist[i].Menu_Name.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"1\"}";
}
//若menu_list不為空,則為父分類的ID,
var childlist = listMenu.Where(p => p.Menu_Level == parentlist[i].Menu_List_Id.ToString()).OrderBy(p => p.Serial).ToList();
if (childlist.Count != 0)
{
permissionList += ",\"children\":[";
}
for (int j = 0; j < childlist.Count; j++)
{
if (type != "")
{
permissionList += "{\"id\":\"" + childlist[j].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + childlist[j].Menu_Name.ToString().Trim() + " /Serial:" + childlist[j].Serial.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"2\"}},";
}
else
{
permissionList += "{\"id\":\"" + childlist[j].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + childlist[j].Menu_Name.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"2\"}},";
}
if (childlist.Count != 0 && j == childlist.Count - 1)
{
permissionList = permissionList.Substring(0, permissionList.Length - 1);
permissionList += "]";
}
}
permissionList += "},";
}
permissionList = permissionList.Substring(0, permissionList.Length - 1);
permissionList += "]";
return permissionList;
}
public JsonResult SaveMenuList()
{
try
{
string saveType = Request.Params["SaveType"].ToString().Trim();
string menuListId = Request.Params["MenuListId"].ToString().Trim();
string requestURL = Request.Params["RequestURL"].ToString().Trim();
string menuName = Request.Params["MenuName"].ToString().Trim();
int serial = Utility.ConvertToInt32(Request.Params["Serial"].ToString().Trim());
string menuLevel = Request.Params["MenuLevel"].ToString().Trim();
string iconName = "icon-system";
Menu_List_Manager menuListManager = new Menu_List_Manager();
Menu_List menuList = null;
if (menuListId != null)
{
menuList = menuListManager.GetMenuListById(menuListId);
}
if (saveType.ToUpper() == "ADD")
{
if (menuList != null)
{
Utility.ReturnJsonResult("0", UserMessageShow.Invaild);
}
menuList = new Menu_List();
menuList.Menu_List_Id = Guid.NewGuid();
menuList.Request_URL = requestURL;
menuList.Menu_Name = menuName;
menuList.Menu_Level = menuLevel;
menuList.Serial = serial;
menuList.Icon_Name = iconName;
}
else
{
if (menuList == null)
{
Utility.ReturnJsonResult("0", UserMessageShow.Invaild);
}
menuList.Request_URL = requestURL;
menuList.Menu_Name = menuName;
menuList.Menu_Level = menuLevel;
menuList.Serial = serial;
menuList.Icon_Name = iconName;
}
menuListManager.SaveMenuList(menuList, saveType);
return Utility.ReturnJsonResult("1", UserMessageShow.SaveSuccess);
}
catch(Exception ex)
{
return Utility.ReturnJsonResult("0",ex.Message);
}
}
public JsonResult GetMenuByMenuId()
{
try
{
string menuListId = Request.Params["MenuListId"].ToString().Trim();
Menu_List_Manager menuListManager = new Menu_List_Manager();
Menu_List menuList = menuListManager.GetMenuListById(menuListId);
return Utility.ReturnJsonResult<Menu_List>(menuList);
}
catch(Exception ex)
{
return Utility.ReturnJsonResult("0",ex.Message);
}
}
public JsonResult DeleteMenuByMenuId()
{
string menuListId = Request.Params["MenuListId"].ToString().Trim();
Menu_List_Manager menuListManager = new Menu_List_Manager();
menuListManager.DeleteMenuList(menuListId);
return Utility.ReturnJsonResult("0", UserMessageShow.DeleteSuccess);
}
#endregion
}
}
在程式碼段#region Menu List Page下為MenuList頁面對應的action。
View層:
@{
ViewBag.Title = "Menu List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
function AddParentMenu()
{
$("#AddMenuInformation").dialog({
title: 'Add Menu Information',
width: 500,
height: 250
});
$('#trParentName').css("display", "none");
$('#trRequestURL').css("display", "none");
$('#hfSaveType').val("ADD");
$('#hfParentId').val("");
$("#txtMenuName").focus();
$('#txtParentMenuName').val("");
$('#hfMenuId').val("");
$('#txtMenuName').val('');
$('#txtMenuRequestURL').val('');
$('#txtSerialNumber').val('');
$("#AddMenuInformation").dialog('open');
}
function AddMenu() {
var node = $('#tt').tree('getSelected');
if (node == null) {
alert("Please select a menu Item!");
}
if (node.attributes.level == "2") {
alert("This menu can not be added child menu!");
return;
}
$('#hfParentId').val(node.id);
$("#AddMenuInformation").dialog({
title: 'Add Menu Information',
width: 500,
height: 250
});
$('#trParentName').css("display", "");
$('#trRequestURL').css("display", "");
$('#hfSaveType').val("ADD");
$("#txtMenuName").focus();
$('#txtParentMenuName').val(node.text.substring(0, node.text.indexOf("/")));
$('#hfMenuId').val("");
$('#txtMenuName').val('');
$('#txtMenuRequestURL').val('');
$('#txtSerialNumber').val('');
$("#AddMenuInformation").dialog('open');
}
function SaveMenuInfo() {
var type = $('#hfSaveType').val();
var menuId = $('#hfMenuId').val();
var parentMenuId = $('#hfParentId').val();
var menuName = $('#txtMenuName').val();
var menuRequestURL = $('#txtMenuRequestURL').val();
var serialNumber = $('#txtSerialNumber').val();
$.ajax({
url: '/Admin/SaveMenuList',
data: {
SaveType: type, MenuListId: menuId, MenuLevel: parentMenuId, MenuName: menuName, RequestURL: menuRequestURL, Serial: serialNumber
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.result == "0") {
alert(data.message);
} else {
$("#AddMenuInformation").dialog('close');
alert(data.message);
$('#tt').tree('reload');
}
}
});
}
function DeleteMenu() {
var node = $('#tt').tree('getSelected');
if (node.attributes.level == "1") {
alert("This menu can not be deleted!");
return;
}
if (confirm("Are you sure delete this menu?")) {
$.ajax({
url: '/Admin/DeleteMenuByMenuId',
data: {
MenuListId: node.id
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.result == "0") {
alert(data.message);
$('#tt').tree('reload');
} else {
alert(data.message);
}
}
});
}
}
function EditMenu() {
var node = $('#tt').tree('getSelected');
if (node == null) {
alert("Please select a menu Item!");
}
if (node.attributes.level == "1") {
return;
}
var nodeParent = $('tt').tree('getParent', node.target)
$('#hfMenuId').val(node.id);
$('#hfParentId').val(nodeParent.id);
$.ajax({
url: '/Admin/GetMenuByMenuId',
data: {
MenuListId: node.id
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.result == "1") {
alert(data.message);
} else {
$("#AddMenuInformation").dialog({
title: 'Edit Menu Information',
width: 500,
height: 250
});
$('#trParentName').css("display", "");
$('#trRequestURL').css("display", "");
$('#hfSaveType').val("Update");
$('#txtParentMenuName').val(nodeParent.text.substring(0, nodeParent.text.indexOf("/")));
$('#txtMenuName').val(data.Menu_Name);
$('#txtMenuRequestURL').val(data.Request_URL);
$('#txtSerialNumber').val(data.Serial);
$("#AddMenuInformation").dialog('open');
}
}
});
}
</script>
<div style="padding-top: 2px; padding-left: 2px;font-size:8px;">
<div id="dQueryPermissionList" class="easyui-panel" style="float: left; width: 360px; height: 'auto';
padding: 10px; background-color: #FFFFFF;" title="Menu List">
<div style="width: 330px; height: 450px; overflow: auto;">
<ul id="tt" class="easyui-tree" data-options="url:'/Admin/GeneratePermission?Type=S',method:'get',animate:true"></ul>
</div>
</div>
<div style="margin-top:15px;">
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add'" onclick="AddMenu();" style="margin-right: 18px;">Add</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit'" onclick="EditMenu();" style="margin-right: 18px;">Edit</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-cancel'" onclick="DeleteMenu();" style="margin-right: 18px;">Delete</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-cancel'" onclick="AddParentMenu();" style="margin-right: 18px;">AddParentMenu</a>
</div>
<div id="AddMenuInformation" class="easyui-dialog" closed="true" buttons="#AddMenuInformation-Buttons"
style="padding: 10px 20px">
<table>
<tr id="trParentName">
<td>
Parent Menu Name:
</td>
<td>
<input type="text" id="txtParentMenuName" name="txtParentMenuName" class="easyui-textbox" style="width: 238px" readonly="readonly" />
<input type="hidden" id="hfParentId" name="hfParentId" />
<input type="hidden" id="hfMenuId" name="hfMenuId" />
<input type="hidden" id="hfSaveType" name="hfSaveType" />
</td>
</tr>
<tr>
<td>
Menu Name:
</td>
<td>
<input type="text" id="txtMenuName" name="txtMenuName" class="easyui-textbox" style="width: 238px" />
</td>
</tr>
<tr id="trRequestURL">
<td>
Menu Request URL:
</td>
<td>
<input type="text" id="txtMenuRequestURL" name="txtMenuRequestURL" class="easyui-textbox" style="width: 238px" />
</td>
</tr>
<tr>
<td>
Serial Number:
</td>
<td>
<input type="text" id="txtSerialNumber" name="txtSerialNumber" class="easyui-textbox" style="width: 238px" onkeyup="onlyNumber(this)" onafterpaste="onlyNumber(this)" />
</td>
</tr>
</table>
</div>
<div id="AddMenuInformation-Buttons">
<a href="#" class="easyui-linkbutton" iconcls="icon-ok" onclick="SaveMenuInfo();">
Save
</a> <a href="#" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript: $('#AddMenuInformation').dialog('close');">
Close
</a>
</div>
</div>
頁面顯示:
好了,程式碼貼完了,講解開始,
在頁面我們看到tree是通過下面這個程式碼載入的:
<div style="width: 330px; height: 400px; overflow: auto;">
<ul id="tt" class="easyui-tree" data-options="url:'/Admin/GeneratePermission?Type=S',method:'get',animate:true"></ul>
</div>
在頁面easyui通過tree控價訪問url獲取選單資訊,最終展示,這個返回的資料easyui是有規範的,他給提供一些可選引數,大致類似這種:
[{
"id":"5686e272-cc26-4039-8519-705baa2ab88d",
"text":"Setting /Serial:1",
"iconCls":"icon-system",
"children":[{
"id":"9c40bb25-92cb-40c8-a7cf-59f2e11c89ba",
"text":"Test /Serial:1",
"iconCls":"icon-system",
"attributes":{"level":"2"}},
{"id":"dc686259-11dc-4dbf-997f-c823c55387fd",
"text":"Test2 /Serial:2",
"iconCls":"icon-system",
"attributes":{"level":"2"}}]
}]
一串json,這個引數標準是easyui提供的,不是我們隨意定義的,這個具體還有那些引數可選呢?
每個節點可以包括下列屬性:(這個是easyui官網提供的可選引數)
id:節點的 id,它對於載入遠端資料很重要。
text:要顯示的節點文字。
state:節點狀態,’open’ 或 ‘closed’,預設是 ‘open’。當設定為 ‘closed’ 時,該節點有子節點,並且將從遠端站點載入它們。
checked:指示節點是否被選中。
attributes:給一個節點新增的自定義屬性。
children:定義了一些子節點的節點陣列
官網提供的一個Demo:
[{
"id":1,
"text":"Folder1",
"iconCls":"icon-save",
"children":[{
"text":"File1",
"checked":true
},{
"text":"Books",
"state":"open",
"attributes":{
"url":"/demo/book/abc",
"price":100
},
"children":[{
"text":"PhotoShop",
"checked":true
},{
"id": 8,
"text":"Sub Bookds",
"state":"closed"
}]
}]
},{
"text":"Languages",
"state":"closed",
"children":[{
"text":"Java"
},{
"text":"C#"
}]
}]
根據你專案的需要你可以選擇性的新增或是刪除某些不重要的屬性。所以這裡你應該知道了,伺服器端有兩種實現方式,一種是你建立對應的Model,然後使用Utility裡面的Object直接轉成json;一種是自己拼接字串。
第二種看似很傻,但是對於這種複用不是很強的業務,是沒必要建立Model的,所以這裡直接拼接字串。
獲取所有列表,並將列表資訊,轉換成easyui的tree等夠識別的json字元:
public string GeneratePermission()
{
string type = Request.Params["Type"].ToString().Trim();
Menu_List_Manager menuListManager = new Menu_List_Manager();
List<Menu_List> listMenu = menuListManager.GetAllMenuList().ToList();
string permissionList = "[";
//若menu_Level為空則表示為選單父分類
var parentlist = listMenu.Where(p => p.Menu_Level.ToString() == "").OrderBy(p => p.Serial).ToList();
for (int i = 0; i < parentlist.Count; i++)
{
if (type != "")//表示為選單管理頁面
{
permissionList += "{\"id\":\"" + parentlist[i].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + parentlist[i].Menu_Name.ToString().Trim() + " /Serial:" + parentlist[i].Serial.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"1\"}";
}
else//表示為選單許可權分配頁面
{
permissionList += "{\"id\":\"" + parentlist[i].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + parentlist[i].Menu_Name.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"1\"}";
}
//若menu_list不為空,則為父分類的ID,
var childlist = listMenu.Where(p => p.Menu_Level == parentlist[i].Menu_List_Id.ToString()).OrderBy(p => p.Serial).ToList();
if (childlist.Count != 0)
{
permissionList += ",\"children\":[";
}
for (int j = 0; j < childlist.Count; j++)
{
if (type != "")
{
permissionList += "{\"id\":\"" + childlist[j].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + childlist[j].Menu_Name.ToString().Trim() + " /Serial:" + childlist[j].Serial.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"2\"}},";
}
else
{
permissionList += "{\"id\":\"" + childlist[j].Menu_List_Id.ToString().Trim() + "\",\"text\":\"" + childlist[j].Menu_Name.ToString().Trim() + "\",\"iconCls\":\"" + parentlist[i].Icon_Name.ToString().Trim() + "\",\"attributes\":{\"level\":\"2\"}},";
}
if (childlist.Count != 0 && j == childlist.Count - 1)
{
permissionList = permissionList.Substring(0, permissionList.Length - 1);
permissionList += "]";
}
}
permissionList += "},";
}
permissionList = permissionList.Substring(0, permissionList.Length - 1);
permissionList += "]";
return permissionList;
}
這裡有兩個關鍵的點,需要略作解釋:
var parentlist = listMenu.Where(p => p.Menu_Level.ToString() == "").OrderBy(p => p.Serial).ToList();
取出所有父節點,並根據Serial排序。
這裡是使用linq將集合中符合條件的物件篩選出來,所以以後不要別人問你linq,你就只知道linq to ef。這是不全面的。linq不止有跟EF連用哦,功能強大著呢。
var childlist = listMenu.Where(p => p.Menu_Level == parentlist[i].Menu_List_Id.ToString()).OrderBy(p => p.Serial).ToList();
這裡是將當前父節點的所有子節點取出來。
這列的type引數你可能會有點迷惑,這個是新增用來區分做許可權分配時候顯示的那個tree的。因為做許可權分配的時候也需要顯示一個tree結構,重寫一個方法又太麻煩了,所以都在這個方法裡寫了,這樣可能會對你現在造成一些麻煩,這樣,你看著太亂,就現將判斷type的那部分刪了,這樣就清晰了。
顯示講完之後,好像就沒什麼好講的了,新增和修改公用的同一個方法,新增父節點,跟新增子節點不太一下,所以就專門開了一個按鈕,這裡你可能遇到的問題就是easyui的dialg控制元件了。這個是easyui固定的寫法格式,自己多看兩遍熟悉一下就好了,基本用法都在程式碼中了,這裡不過多解釋,希望可以自己鑽研一番。謝謝大家
相關文章
- 許可權之選單許可權
- 選單許可權和按鈕許可權設定
- [BUG反饋]許可權管理 -> 訪問授權 點選後報錯
- ecshop後臺新增左側選單與分配許可權
- odoo 許可權分配Odoo
- 選單許可權表sqlite和mysqlSQLiteMySql
- java的訪問許可權Java訪問許可權
- 刪除Windows 10右鍵選單中的授予訪問許可權選項Windows訪問許可權
- ClickHouse學習系列之六【訪問許可權和賬戶管理】訪問許可權
- Android6.0------許可權申請管理(單個許可權和多個許可權申請)Android
- win7訪問xp您沒有許可權訪問 共享。請與網路管理員聯絡請求訪問許可權Win7訪問許可權
- Java 訪問許可權控制(6)Java訪問許可權
- mongoDB 3.0 安全許可權訪問MongoDB
- Swift4.0 訪問許可權Swift訪問許可權
- AndroidPermission訪問許可權大全Android訪問許可權
- public, private, protected 訪問許可權訪問許可權
- 利用sudo命令為Ubuntu分配管理許可權(轉)Ubuntu
- java基礎(八)—–深入解析java四種訪問許可權Java訪問許可權
- java基礎(七) java四種訪問許可權深入解析Java訪問許可權
- MongoDB入門系列(四):許可權管理MongoDB
- 使用nginx控制ElasticSearch訪問許可權NginxElasticsearch訪問許可權
- Think IN JAVA --------JAVA訪問許可權控制Java訪問許可權
- 賬號和許可權管理
- 訪問管理系統--研究許可權一起來看看
- C++中封裝和繼承的訪問許可權C++封裝繼承訪問許可權
- vue+element-ui實現動態的許可權管理和選單渲染VueUI
- django許可權之二級選單Django
- android自定義訪問許可權permissionAndroid訪問許可權
- android:各種訪問許可權PermissionAndroid訪問許可權
- Java:談談protected訪問許可權薦Java訪問許可權
- 利用django-suit模板在管理後臺新增自定義的選單和自定義的頁面、設定訪問許可權DjangoUI訪問許可權
- mysql 新增、刪除使用者和許可權分配MySql
- win10老跳出訪問許可權怎麼辦_win10訪問許可權怎麼關閉Win10訪問許可權
- Linux-許可權管理(ACL許可權)Linux
- Ubuntu共享資料夾訪問許可權問題Ubuntu訪問許可權
- 新建使用者組後,分配首頁和內容兩個選單時,顯示的選單和許可權設定不匹配
- YII管理後臺許可權分配關於整理舊程式碼
- PostgreSQL:許可權管理SQL