Skip to content

Commit

Permalink
Merge pull request #50 from netcorepal/dev
Browse files Browse the repository at this point in the history
dev
  • Loading branch information
witskeeper authored Dec 16, 2024
2 parents b04c81a + f6a42c8 commit 95a34b7
Show file tree
Hide file tree
Showing 38 changed files with 333 additions and 251 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<NetCorePalVersion>2.0.0-preview.1.2411260738</NetCorePalVersion>
<NetCorePalVersion>2.0.0</NetCorePalVersion>
<FrameworkVersion>8.0.10</FrameworkVersion>
<ExtensionsVersion>8.0.0</ExtensionsVersion>
<EntityFrameworkVersion>8.0.0</EntityFrameworkVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

namespace NetCorePal.D3Shop.Admin.Shared.Responses;

public class AdminUserResponse(AdminUserId id, string name, string phone)
public class AdminUserResponse(AdminUserId id, string name, string phone, IEnumerable<string> roles)
{
public AdminUserId Id { get; } = id;
public string Name { get; set; } = name;
public string Phone { get; set; } = phone;
public IEnumerable<string> Roles { get; set; } = roles;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ protected AdminUserPermission()

public AdminUserId AdminUserId { get; private set; } = default!;
public string PermissionCode { get; private set; } = string.Empty;
public string PermissionRemark { get; private set; } = string.Empty;
public List<RoleId> SourceRoleIds { get; } = [];

public AdminUserPermission(string permissionCode, string permissionRemark, RoleId? sourceRoleId = null)
public AdminUserPermission(string permissionCode, RoleId? sourceRoleId = null)
{
PermissionCode = permissionCode;
PermissionRemark = permissionRemark;
if (sourceRoleId is not null)
{
SourceRoleIds.Add(sourceRoleId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
{
public class RolePermission
{
protected RolePermission() { }
protected RolePermission()
{
}

public RoleId RoleId { get; internal set; } = default!;
public string PermissionCode { get; private set; } = string.Empty;
public string PermissionRemark { get; private set; } = string.Empty;

public RolePermission(string permissionCode, string permissionRemark)
public RolePermission(string permissionCode)
{
PermissionCode = permissionCode;
PermissionRemark = permissionRemark;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,61 @@
@{
const string buttonType = ButtonType.Dashed;
// ReSharper disable once AccessToStaticMemberViaDerivedType
const string buttonSize = ButtonSize.Small;
const string buttonType = ButtonType.Dashed;
// ReSharper disable once AccessToStaticMemberViaDerivedType
const string buttonSize = ButtonSize.Small;
}
<GridRow Gutter="16">
<GridCol>
<Button Type="@buttonType" Size="@buttonSize"
@onclick="() => { foreach (var tree in _treeDir.Values) tree.CheckAll();}">
全选
</Button>
</GridCol>
<GridCol>
<Button Type="@buttonType" Size="@buttonSize"
@onclick="() => { foreach (var tree in _treeDir.Values) tree.UncheckAll(); }">
取消全选
</Button>
</GridCol>
<GridCol>
<Button Type="@buttonType" Size="@buttonSize"
OnClick="OnCheckAll">
全选
</Button>
</GridCol>
<GridCol>
<Button Type="@buttonType" Size="@buttonSize"
OnClick="OnUncheckAll">
取消全选
</Button>
</GridCol>
</GridRow>
<Divider/>
<Tabs DefaultActiveKey="@PermissionGroups.FirstOrDefault()?.Name" TabPosition="TabPosition.Left">
@foreach (var permissionGroup in PermissionGroups)
{
<TabPane Key="@permissionGroup.Name" Tab="@permissionGroup.Name">
<GridRow @key="permissionGroup.Name" Gutter="16">
<GridCol Span="10">
<h3>@permissionGroup.Name</h3>
</GridCol>
<GridCol Offset="3">
<Button Type="@buttonType" Size="@buttonSize"
@onclick="() => _treeDir[permissionGroup.Name].CheckAll()">全选
</Button>
</GridCol>
<GridCol>
<Button Type="@buttonType" Size="@buttonSize"
@onclick="() => _treeDir[permissionGroup.Name].UncheckAll()">取消全选
</Button>
</GridCol>
</GridRow>
<Divider/>
<span @key="Id">@BuildTree(permissionGroup)</span>
</TabPane>
}
@foreach (var permissionGroup in PermissionGroups)
{
var groupName = permissionGroup.Name;

<TabPane Key="@groupName" Tab="@groupName">
<GridRow @key="groupName" Gutter="16">
<GridCol Span="10">
<h3>@groupName</h3>
</GridCol>
<GridCol Offset="3">
<Button Type="@buttonType" Size="@buttonSize"
OnClick="() => OnCheckGroupAll(groupName)">
全选
</Button>
</GridCol>
<GridCol>
<Button Type="@buttonType" Size="@buttonSize"
@onclick="() => OnUncheckGroupAll(groupName)">
取消全选
</Button>
</GridCol>
</GridRow>
<Divider/>
<Tree @key="@TreeComponentKey"
TItem="Permission"
@ref="_treeDir[groupName]"
Id="@groupName"
Checkable="true"
DataSource="permissionGroup.Permissions"
TitleExpression="x => x.DataItem.DisplayName"
KeyExpression="x => x.DataItem.Code"
ChildrenExpression="x => x.DataItem.Children"
DefaultCheckedKeys="AssignedPermissionCodes.Intersect(_treeKeysDir[groupName]).ToArray()"
DisabledExpression="x => DisabledPermissionCodes.Contains(x.DataItem.Code) || !x.DataItem.IsEnabled"
CheckStrictly="true"
DefaultExpandAll="true"
OnCheck="args => OnTreeChange(args,groupName)"/>
</TabPane>
}
</Tabs>
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,81 @@ public sealed partial class PermissionManager : ComponentBase
[Parameter] public EventCallback<List<string>> AssignedPermissionCodesChanged { get; set; }
public string[] DisabledPermissionCodes { get; set; } = [];

private readonly Dictionary<string, Tree<Permission>> _treeDir = [];
private readonly Dictionary<string, IEnumerable<string>> _treeKeysDir = [];
private readonly Dictionary<string, EventCallback<TreeEventArgs<Permission>>> _treeOnChangeEventDir = [];
private readonly Dictionary<string, Tree<Permission>> _treeDir = new();
private readonly Dictionary<string, IEnumerable<string>> _treeKeysDir = new();
private PermissionGroup[] PermissionGroups { get; set; } = [];
private Guid Id { get; set; }
private Guid TreeComponentKey { get; set; }

protected override void OnInitialized()
{
PermissionGroups = PermissionDefinitionContext.PermissionGroups.ToArray();
foreach (var group in PermissionGroups)
{
var treeId = group.Name;
_treeDir.Add(treeId, default!);
_treeKeysDir.Add(treeId, group.PermissionsWithChildren.Select(p => p.Code));
_treeOnChangeEventDir.Add(treeId, EventCallback.Factory.Create<TreeEventArgs<Permission>>(this,
async args =>
{
foreach (var key in _treeKeysDir[args.Tree.Id])
{
AssignedPermissionCodes.Remove(key);
}

AssignedPermissionCodes.AddRange(args.Tree.CheckedKeys);

await AssignedPermissionCodesChanged.InvokeAsync(AssignedPermissionCodes);
}));
var groupName = group.Name;
_treeDir[groupName] = default!;
_treeKeysDir[groupName] = group.PermissionsWithChildren.Select(p => p.Code);
}
}

public void Update()
private async Task OnTreeChange(TreeEventArgs<Permission> args, string groupName)
{
Id = Guid.NewGuid();
foreach (var key in _treeKeysDir[groupName])
{
AssignedPermissionCodes.Remove(key);
}
AssignedPermissionCodes.AddRange(args.Tree.CheckedKeys);

await AssignedPermissionCodesChanged.InvokeAsync(AssignedPermissionCodes);
}

private RenderFragment BuildTree(PermissionGroup permissionGroup) => builder =>
private async Task HandleCheckAll(bool isChecked, string? groupName = null)
{
var treeId = permissionGroup.Name;
if (groupName == null)
{
foreach (var tree in _treeDir.Values)
{
if (isChecked)
tree.CheckAll();
else
tree.UncheckAll();
}

builder.OpenComponent<Tree<Permission>>(0); // 动态创建 Tree 组件
builder.AddAttribute(2, "Id", treeId); // 设置树的 Id
builder.AddAttribute(3, "Checkable", true); // 启用 Checkable 属性
builder.AddAttribute(4, "DataSource", permissionGroup.Permissions); // 设置 DataSource 为 Permissions
builder.AddAttribute(5, "TitleExpression",
(Func<TreeNode<Permission>, string>)(x => x.DataItem.DisplayName)); // 设置显示名称
builder.AddAttribute(6, "KeyExpression",
(Func<TreeNode<Permission>, string>)(x => x.DataItem.Code)); // 设置 KeyExpression
builder.AddAttribute(7, "ChildrenExpression",
(Func<TreeNode<Permission>, IEnumerable<Permission>>)(x => x.DataItem.Children)); // 设置 ChildrenExpression
builder.AddAttribute(8, "DefaultCheckedKeys",
AssignedPermissionCodes.Intersect(_treeKeysDir[treeId]).ToArray()); // 设置默认选中的项
builder.AddAttribute(9, "DisabledExpression",
(Func<TreeNode<Permission>, bool>)(x =>
DisabledPermissionCodes.Contains(x.DataItem.Code) || !x.DataItem.IsEnabled)); // 设置禁用规则
builder.AddAttribute(10, "CheckStrictly", true); // 精确检查 treeNode;父树节点和子树节点没有关联
builder.AddAttribute(11, "DefaultExpandAll", true); // 默认展开全部节点
builder.AddAttribute(12, "OnCheck", _treeOnChangeEventDir[treeId]); // 设置 OnCheck 事件处理程序
AssignedPermissionCodes.Clear();
if (isChecked)
{
AssignedPermissionCodes.AddRange(_treeKeysDir.Values.SelectMany(k => k));
}
}
else
{
if (_treeDir.TryGetValue(groupName, out var tree))
{
if (isChecked)
tree.CheckAll();
else
tree.UncheckAll();
}

// 捕获组件的引用
builder.AddComponentReferenceCapture(13, treeRef => { _treeDir[treeId] = (Tree<Permission>)treeRef; });
AssignedPermissionCodes.RemoveAll(code => _treeKeysDir[groupName].Contains(code));
if (isChecked)
{
AssignedPermissionCodes.AddRange(_treeKeysDir[groupName]);
}
}

builder.CloseComponent(); // 关闭 Tree 组件
};
}
await AssignedPermissionCodesChanged.InvokeAsync(AssignedPermissionCodes);
}

private Task OnCheckAll() => HandleCheckAll(true);

private Task OnUncheckAll() => HandleCheckAll(false);

private Task OnCheckGroupAll(string groupName) => HandleCheckAll(true, groupName);

private Task OnUncheckGroupAll(string groupName) => HandleCheckAll(false, groupName);

public void ReRenderTree()
{
TreeComponentKey = Guid.NewGuid();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
OnOk="() => _form.Submit()"
OnCancel="CloseModal"
ConfirmLoading="@_modalConfirmLoading"
Resizable = "@(true)">
DestroyOnClose="@(true)">

<Tabs @ref="_tabs">
<TabPane Tab="基本信息">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{
_modalVisible = true;
_assignedPermissionCodes = await GetAssignedPermissionCodes(Row.Id);
_permissionManagerComponent.Update();
_permissionManagerComponent.ReRenderTree();
}

private async Task<List<string>> GetAssignedPermissionCodes(RoleId id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
_assignedPermissionCodes = adminUserPermissions.Select(p => p.Code).ToList();

_permissionManagerComponent.DisabledPermissionCodes = _permissionCodesFromRoles;
_permissionManagerComponent.Update();
_permissionManagerComponent.ReRenderTree();
}

private async Task<AdminUserAssignedPermissionResponse[]> GetAssignedPermissions(AdminUserId id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

private CheckboxOption<RoleId>[] _roleOptions = [];
private RoleId[] _selectedRoleIds = [];

public record RolesUpdateSucceededEventArgs(AdminUserId AdminUserId, IEnumerable<string> RoleNames);
[Parameter] public EventCallback<RolesUpdateSucceededEventArgs> OnUpdateSucceeded { get; set; }

private bool _modalVisible;
private bool _modalConfirmLoading;
Expand Down Expand Up @@ -52,6 +55,9 @@
{
_modalVisible = false;
_ = Message.Success("更新成功!");
await OnUpdateSucceeded.InvokeAsync(new RolesUpdateSucceededEventArgs(
Row.Id,
_roleOptions.Where(r => _selectedRoleIds.Contains(r.Value)).Select(r => r.Label)));
}
else
{
Expand Down
Loading

0 comments on commit 95a34b7

Please sign in to comment.