Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev #50

Merged
merged 10 commits into from
Dec 16, 2024
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
Loading