Skip to content

Commit c4303a8

Browse files
authored
Merge pull request #5 from AIDotNet/copilot/add-user-management-roles-page
Add user management and role-based data source access control
2 parents 6cf9d90 + 73500be commit c4303a8

File tree

21 files changed

+1740
-0
lines changed

21 files changed

+1740
-0
lines changed
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
@page "/role-configuration"
2+
@using Text2Sql.Net.Domain.Interface
3+
@using Text2Sql.Net.Repositories.Text2Sql.Role
4+
@using Text2Sql.Net.Repositories.Text2Sql.DatabaseConnection
5+
@inject IRoleManagementService RoleManagementService
6+
@inject IDatabaseConnectionConfigRepository DatabaseConnectionConfigRepository
7+
@inject MessageService MessageService
8+
@inject NavigationManager NavigationManager
9+
10+
<PageContainer Title="角色配置">
11+
<Extra>
12+
<Button Type="primary" Icon="plus" @onclick="ShowCreateModal">
13+
创建角色
14+
</Button>
15+
</Extra>
16+
<ChildContent>
17+
<Spin Spinning="@_loading">
18+
<Table TItem="Role" DataSource="@_roles" Loading="@_loading" Bordered>
19+
<PropertyColumn Property="c => c.Name" Title="角色名称" />
20+
<PropertyColumn Property="c => c.Code" Title="角色代码" />
21+
<PropertyColumn Property="c => c.Description" Title="描述" />
22+
<PropertyColumn Property="c => c.IsEnabled" Title="状态">
23+
<Tag Color="@(context.IsEnabled ? "green" : "red")">
24+
@(context.IsEnabled ? "启用" : "禁用")
25+
</Tag>
26+
</PropertyColumn>
27+
<PropertyColumn Property="c => c.CreateTime" Title="创建时间" Format="yyyy-MM-dd HH:mm" />
28+
<ActionColumn Title="操作">
29+
<Space>
30+
<SpaceItem>
31+
<Button Type="link" Size="small" Icon="database" @onclick="() => ShowAssignDataSourcesModal(context)">
32+
分配数据源
33+
</Button>
34+
</SpaceItem>
35+
<SpaceItem>
36+
<Button Type="link" Size="small" Icon="edit" @onclick="() => ShowEditModal(context)">
37+
编辑
38+
</Button>
39+
</SpaceItem>
40+
<SpaceItem>
41+
<Popconfirm Title="确定要删除该角色吗?" OnConfirm="() => DeleteRole(context.Id)">
42+
<Button Type="link" Danger Size="small" Icon="delete">
43+
删除
44+
</Button>
45+
</Popconfirm>
46+
</SpaceItem>
47+
</Space>
48+
</ActionColumn>
49+
</Table>
50+
</Spin>
51+
</ChildContent>
52+
</PageContainer>
53+
54+
@* 创建/编辑角色模态框 *@
55+
<Modal Title="@(_editingRole.Id == null ? "创建角色" : "编辑角色")"
56+
Visible="_roleModalVisible"
57+
OnOk="HandleRoleModalOk"
58+
OnCancel="HandleRoleModalCancel">
59+
<Form Model="@_editingRole" LabelCol="new ColLayoutParam { Span = 6 }" WrapperCol="new ColLayoutParam { Span = 18 }">
60+
<FormItem Label="角色名称" Required>
61+
<Input @bind-Value="_editingRole.Name" Placeholder="请输入角色名称" />
62+
</FormItem>
63+
<FormItem Label="角色代码" Required>
64+
<Input @bind-Value="_editingRole.Code" Placeholder="请输入角色代码(英文)" />
65+
</FormItem>
66+
<FormItem Label="状态">
67+
<Switch @bind-Checked="_editingRole.IsEnabled" CheckedChildren="启用" UnCheckedChildren="禁用" />
68+
</FormItem>
69+
<FormItem Label="描述">
70+
<TextArea @bind-Value="_editingRole.Description" Placeholder="请输入角色描述" Rows="3" />
71+
</FormItem>
72+
</Form>
73+
</Modal>
74+
75+
@* 分配数据源模态框 *@
76+
<Modal Title="分配数据源"
77+
Visible="_assignDataSourcesModalVisible"
78+
OnOk="HandleAssignDataSourcesOk"
79+
OnCancel="HandleAssignDataSourcesCancel">
80+
<div style="margin-bottom: 16px;">
81+
<Text Strong>角色:</Text> @_selectedRole?.Name (@_selectedRole?.Code)
82+
</div>
83+
@if (_allDataSources.Any())
84+
{
85+
<div style="display: flex; flex-direction: column; gap: 12px;">
86+
@foreach (var dataSource in _allDataSources)
87+
{
88+
<Checkbox Checked="@_selectedDataSourceIds.Contains(dataSource.Id)"
89+
CheckedChanged="@(e => HandleDataSourceCheckChange(dataSource.Id, e))">
90+
<div style="display: flex; flex-direction: column;">
91+
<Text Strong>@dataSource.Name</Text>
92+
<Text Type="secondary" Style="font-size: 12px;">
93+
<Tag Color="blue">@dataSource.DbType</Tag>
94+
@dataSource.Description
95+
</Text>
96+
</div>
97+
</Checkbox>
98+
}
99+
</div>
100+
}
101+
else
102+
{
103+
<Empty Description="@("暂无可用数据源")">
104+
<Button Type="link" @onclick="NavigateToDatabaseConnection">
105+
前往创建数据源
106+
</Button>
107+
</Empty>
108+
}
109+
</Modal>
110+
111+
@code {
112+
private List<Role> _roles = new();
113+
private List<DatabaseConnectionConfig> _allDataSources = new();
114+
private bool _loading = false;
115+
private bool _roleModalVisible = false;
116+
private bool _assignDataSourcesModalVisible = false;
117+
private Role _editingRole = new();
118+
private Role? _selectedRole;
119+
private string[] _selectedDataSourceIds = Array.Empty<string>();
120+
121+
protected override async Task OnInitializedAsync()
122+
{
123+
await LoadRoles();
124+
await LoadDataSources();
125+
}
126+
127+
private async Task LoadRoles()
128+
{
129+
_loading = true;
130+
try
131+
{
132+
_roles = await RoleManagementService.GetRolesAsync();
133+
}
134+
catch (Exception ex)
135+
{
136+
_ = MessageService.Error($"加载角色列表失败:{ex.Message}");
137+
}
138+
finally
139+
{
140+
_loading = false;
141+
}
142+
}
143+
144+
private async Task LoadDataSources()
145+
{
146+
try
147+
{
148+
_allDataSources = await DatabaseConnectionConfigRepository.GetListAsync();
149+
}
150+
catch (Exception ex)
151+
{
152+
_ = MessageService.Error($"加载数据源列表失败:{ex.Message}");
153+
}
154+
}
155+
156+
private void ShowCreateModal()
157+
{
158+
_editingRole = new Role { IsEnabled = true };
159+
_roleModalVisible = true;
160+
}
161+
162+
private void ShowEditModal(Role role)
163+
{
164+
_editingRole = new Role
165+
{
166+
Id = role.Id,
167+
Name = role.Name,
168+
Code = role.Code,
169+
IsEnabled = role.IsEnabled,
170+
Description = role.Description
171+
};
172+
_roleModalVisible = true;
173+
}
174+
175+
private async Task HandleRoleModalOk()
176+
{
177+
try
178+
{
179+
if (string.IsNullOrWhiteSpace(_editingRole.Name))
180+
{
181+
_ = MessageService.Warning("请输入角色名称");
182+
return;
183+
}
184+
185+
if (string.IsNullOrWhiteSpace(_editingRole.Code))
186+
{
187+
_ = MessageService.Warning("请输入角色代码");
188+
return;
189+
}
190+
191+
if (string.IsNullOrWhiteSpace(_editingRole.Id))
192+
{
193+
// 创建新角色
194+
await RoleManagementService.CreateRoleAsync(_editingRole);
195+
_ = MessageService.Success("创建角色成功");
196+
}
197+
else
198+
{
199+
// 更新角色
200+
await RoleManagementService.UpdateRoleAsync(_editingRole);
201+
_ = MessageService.Success("更新角色成功");
202+
}
203+
204+
_roleModalVisible = false;
205+
await LoadRoles();
206+
}
207+
catch (Exception ex)
208+
{
209+
_ = MessageService.Error($"操作失败:{ex.Message}");
210+
}
211+
}
212+
213+
private void HandleRoleModalCancel()
214+
{
215+
_roleModalVisible = false;
216+
}
217+
218+
private async Task ShowAssignDataSourcesModal(Role role)
219+
{
220+
_selectedRole = role;
221+
try
222+
{
223+
var roleDataSources = await RoleManagementService.GetRoleDataSourcesAsync(role.Id);
224+
_selectedDataSourceIds = roleDataSources.Select(ds => ds.Id).ToArray();
225+
_assignDataSourcesModalVisible = true;
226+
}
227+
catch (Exception ex)
228+
{
229+
_ = MessageService.Error($"加载角色数据源失败:{ex.Message}");
230+
}
231+
}
232+
233+
private async Task HandleAssignDataSourcesOk()
234+
{
235+
try
236+
{
237+
if (_selectedRole != null)
238+
{
239+
await RoleManagementService.AssignDataSourcesToRoleAsync(_selectedRole.Id, _selectedDataSourceIds.ToList());
240+
_ = MessageService.Success("分配数据源成功");
241+
_assignDataSourcesModalVisible = false;
242+
}
243+
}
244+
catch (Exception ex)
245+
{
246+
_ = MessageService.Error($"分配数据源失败:{ex.Message}");
247+
}
248+
}
249+
250+
private void HandleAssignDataSourcesCancel()
251+
{
252+
_assignDataSourcesModalVisible = false;
253+
}
254+
255+
private async Task DeleteRole(string roleId)
256+
{
257+
try
258+
{
259+
await RoleManagementService.DeleteRoleAsync(roleId);
260+
_ = MessageService.Success("删除角色成功");
261+
await LoadRoles();
262+
}
263+
catch (Exception ex)
264+
{
265+
_ = MessageService.Error($"删除角色失败:{ex.Message}");
266+
}
267+
}
268+
269+
private void NavigateToDatabaseConnection()
270+
{
271+
NavigationManager.NavigateTo("/database-connection");
272+
}
273+
274+
private void HandleDataSourceCheckChange(string dataSourceId, bool isChecked)
275+
{
276+
var list = _selectedDataSourceIds.ToList();
277+
if (isChecked && !list.Contains(dataSourceId))
278+
{
279+
list.Add(dataSourceId);
280+
}
281+
else if (!isChecked && list.Contains(dataSourceId))
282+
{
283+
list.Remove(dataSourceId);
284+
}
285+
_selectedDataSourceIds = list.ToArray();
286+
}
287+
}

0 commit comments

Comments
 (0)