從零開始Blazor Server(10)--編輯角色

2022-08-11 15:04:51

例圖

目前的樣式是這樣的:

role.png


其中角色在一個table裡,然後可以增刪改查,並且可以給指定的使用者分配許可權。

建立檔案

首先我們在Pages/Admin目錄下新建一個Role.razor。因為我們的Admin目錄已經使用了_Import來給整個資料夾新增了授權特性,所以我們就無需再次新增了。

新增table

這裡新增一個table來顯示所有的角色。

<Table TItem="RoleEntity" IsBordered="true" ShowAddButton="true" ShowToolbar="true"
       ShowExtendButtons="true" ShowDeleteButtonCallback="entity =>  entity.Id != 1"
       OnQueryAsync="OnQueryAsync" OnSaveAsync="OnSaveAsync">
    <TableColumns>
        <TableColumn @bind-Field="@context.Name"></TableColumn>
    </TableColumns>
    <RowButtonTemplate>
        <TableCellButton Color="Color.Success" Icon="fa fa-edit" Text="編輯許可權" OnClick="() => RoleClick(context)"></TableCellButton>
    </RowButtonTemplate>
</Table>

這裡稍微解釋一下這個Table。

ShowAddButton="true" ShowToolbar="true"讓table顯示工具列並且顯示新增按鈕。

ShowExtendButtons="true"顯示每行的擴充套件按鈕。

ShowDeleteButtonCallback="entity => entity.Id != 1"這個注意一下,我們要保留一個管理員許可權不能刪除,所以我們這裡強制讓RoleId=1的列不顯示刪除按鈕,這樣我們就不能刪除這一列了。

OnQueryAsync="OnQueryAsync" OnSaveAsync="OnSaveAsync"這兩個方法一個是查詢時使用的,返回資料。一個是儲存時使用的,修改的資料入庫。

<TableCellButton Color="Color.Success" Icon="fa fa-edit" Text="編輯許可權" OnClick="() => RoleClick(context)"></TableCellButton>這裡我們新增一個按鈕,這個按鈕就叫編輯許可權,裡面我們可以給這個角色賦權。

編寫方法

OnQueryAsync:

private Task<QueryData<RoleEntity>> OnQueryAsync(QueryPageOptions arg)
    {
        var roles = RoleEntity.Select.IncludeMany(x => x.Permissions).Page(arg.PageIndex, arg.PageItems)
            .Count(out var count).ToList();
        return Task.FromResult<QueryData<RoleEntity>>(new QueryData<RoleEntity>()
        {
            TotalCount = (int)count,
            Items = roles
        });
    }

這裡沒啥說的,就是使用分頁引數來分頁,並且返回總行數和分頁資料。這裡我們不涉及搜尋之類的高階選項,所以整體非常簡單。


OnSaveAsync

private Task<bool> OnSaveAsync(RoleEntity arg1, ItemChangedType arg2)
    {
        arg1.Save();
        return Task.FromResult<bool>(true);
    }

這個處理更簡單,直接Save就好了。


RoleClick:

private void RoleClick(RoleEntity roleEntity)
    {
        RoleEntity = roleEntity;
        Menus = CascadingTree(MenuEntity.Select.ToList(), roleEntity.Permissions, new TreeViewItem<MenuEntity>(new MenuEntity())).ToList();
        RoleModal?.Toggle();
    }
    
    private IEnumerable<TreeViewItem<MenuEntity>> CascadingTree(IEnumerable<MenuEntity> items, IEnumerable<MenuEntity>? selectedItems, TreeViewItem<MenuEntity> parent) => items.Where(i => i.ParentId == parent.Value.Id).Select(i =>
    {
        var item = new TreeViewItem<MenuEntity>(i)
        {
            Text = i.Name,
            Icon = i.Icon,
            Value = i
        };
        item.Items = CascadingTree(items, selectedItems, item).ToList();
        item.Parent = parent;
        if (selectedItems?.Any(x => x.Id == i.Id) == true)
        {
            item.CheckedState = CheckboxState.Checked;
        }
        return item;
    });

這裡的分配許可權點選後有兩個事要做,一個是獲取到所有的Menu,並且做成TreeItem的List,並且根據本身的許可權給tree進行勾選。另一個就是開啟Modal。

新增Modal

這裡我們直接使用Modal來做了,理解起來相對比較簡單,如果是正式專案,建議還是使用Dialog來做,更清晰一些。


這裡我們在專案裡繼續加上Modal

<Modal @ref="RoleModal">
    <ModalDialog Title="編輯許可權">
        <BodyTemplate>
            <TreeView TItem="MenuEntity" Items="@Menus" ShowCheckbox="true" AutoCheckParent="true" AutoCheckChildren="true"></TreeView>
        </BodyTemplate>
        <FooterTemplate>
            <Button OnClick="SavePermission">儲存</Button>
        </FooterTemplate>
    </ModalDialog>
</Modal>

這個Modal只有一個功能,就是在Save的時候獲取到所有的已勾選許可權,存庫。

private void SavePermission()
    {
        if (RoleEntity == null)
        {
            return;
        }
        var menus = new List<MenuEntity>();
        SaveRole(Menus!.Where(x => x.CheckedState != CheckboxState.UnChecked), menus);
        RoleEntity.Permissions = menus;
        RoleEntity.SaveMany(nameof(RoleEntity.Permissions));
        RoleModal?.Toggle();
    }

    private void SaveRole(IEnumerable<TreeViewItem<MenuEntity>> items, List<MenuEntity> menus)
    {
        menus.AddRange(items.Select(x => x.Value));
        foreach (var treeViewItem in items)
        {
            if (treeViewItem.Items.Any(x => x.CheckedState != CheckboxState.UnChecked))
            {
                SaveRole(treeViewItem.Items.Where(x => x.CheckedState != CheckboxState.UnChecked), menus);
            }
        }
    }

程式碼在Github:https://github.com/j4587698/BlazorLearn,分支lesson10。