|
|
@@ -241,6 +241,12 @@ export default function RoleManagement() {
|
|
|
return getDictLabel(DICT_TYPE.SYSTEM_ROLE_TYPE, type) || t('role.unknown');
|
|
|
};
|
|
|
|
|
|
+ // 是否为内置角色(内置角色不可操作)
|
|
|
+ const isBuiltInRole = (row: RoleVO) => {
|
|
|
+ const typeLabel = getRoleTypeLabel(row.type) || '';
|
|
|
+ return typeLabel === '内置' || typeLabel === 'Built-in' || (row as any).builtIn === true;
|
|
|
+ };
|
|
|
+
|
|
|
return (
|
|
|
<div className="space-y-4">
|
|
|
{/* 搜索栏 */}
|
|
|
@@ -378,88 +384,98 @@ export default function RoleManagement() {
|
|
|
{formatDateTimeFull(row.createTime)}
|
|
|
</TableCell>
|
|
|
<TableCell>
|
|
|
- <div className="flex items-center gap-2 justify-center">
|
|
|
- <PermissionWrapper permission="system:role:update">
|
|
|
- <UIButton
|
|
|
- variant="ghost"
|
|
|
- size="sm"
|
|
|
- onClick={() => openForm('update', row.id)}
|
|
|
- className="h-8 px-2 transition-colors hover:underline"
|
|
|
- style={{ color: '#000000' }}
|
|
|
- onMouseEnter={(e) => {
|
|
|
- e.currentTarget.style.color = '#1677ff';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
- }}
|
|
|
- onMouseLeave={(e) => {
|
|
|
- e.currentTarget.style.color = '#000000';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
- }}
|
|
|
- >
|
|
|
- <Edit2 className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
- <span className="ml-1">{t('common.edit')}</span>
|
|
|
- </UIButton>
|
|
|
- </PermissionWrapper>
|
|
|
- <PermissionWrapper permission="system:permission:assign-role-menu">
|
|
|
- <UIButton
|
|
|
- variant="ghost"
|
|
|
- size="sm"
|
|
|
- onClick={() => openAssignMenuForm(row)}
|
|
|
- className="h-8 px-2 transition-colors hover:underline"
|
|
|
- style={{ color: '#000000' }}
|
|
|
- onMouseEnter={(e) => {
|
|
|
- e.currentTarget.style.color = '#1677ff';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
- }}
|
|
|
- onMouseLeave={(e) => {
|
|
|
- e.currentTarget.style.color = '#000000';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
- }}
|
|
|
- >
|
|
|
- <Settings className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
- <span className="ml-1">{t('role.menuPermission')}</span>
|
|
|
- </UIButton>
|
|
|
- </PermissionWrapper>
|
|
|
- <PermissionWrapper permission="system:permission:assign-role-data-scope">
|
|
|
- <UIButton
|
|
|
- variant="ghost"
|
|
|
- size="sm"
|
|
|
- onClick={() => openDataPermissionForm(row)}
|
|
|
- className="h-8 px-2 transition-colors hover:underline"
|
|
|
- style={{ color: '#000000' }}
|
|
|
- onMouseEnter={(e) => {
|
|
|
- e.currentTarget.style.color = '#1677ff';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
- }}
|
|
|
- onMouseLeave={(e) => {
|
|
|
- e.currentTarget.style.color = '#000000';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
- }}
|
|
|
- >
|
|
|
- <Shield className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
- <span className="ml-1">{t('role.dataPermission')}</span>
|
|
|
- </UIButton>
|
|
|
- </PermissionWrapper>
|
|
|
- <PermissionWrapper permission="system:role:delete">
|
|
|
- <UIButton
|
|
|
- variant="ghost"
|
|
|
- size="sm"
|
|
|
- onClick={() => handleDelete(row.id!, row.name)}
|
|
|
- className="h-8 px-2 transition-colors hover:underline"
|
|
|
- style={{ color: '#000000' }}
|
|
|
- onMouseEnter={(e) => {
|
|
|
- e.currentTarget.style.color = '#1677ff';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
- }}
|
|
|
- onMouseLeave={(e) => {
|
|
|
- e.currentTarget.style.color = '#000000';
|
|
|
- e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
- }}
|
|
|
- >
|
|
|
- <Trash2 className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
- <span className="ml-1">{t('common.delete')}</span>
|
|
|
- </UIButton>
|
|
|
- </PermissionWrapper>
|
|
|
- </div>
|
|
|
+ <Tooltip title={isBuiltInRole(row) ? t('role.builtInNoOperation') : undefined}>
|
|
|
+ <div className={`flex items-center gap-2 justify-center ${isBuiltInRole(row) ? 'pointer-events-none opacity-50' : ''}`}>
|
|
|
+ <PermissionWrapper permission="system:role:update">
|
|
|
+ <UIButton
|
|
|
+ variant="ghost"
|
|
|
+ size="sm"
|
|
|
+ disabled={isBuiltInRole(row)}
|
|
|
+ onClick={() => !isBuiltInRole(row) && openForm('update', row.id)}
|
|
|
+ className="h-8 px-2 transition-colors hover:underline"
|
|
|
+ style={{ color: '#000000' }}
|
|
|
+ onMouseEnter={(e) => {
|
|
|
+ if (isBuiltInRole(row)) return;
|
|
|
+ e.currentTarget.style.color = '#1677ff';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
+ }}
|
|
|
+ onMouseLeave={(e) => {
|
|
|
+ e.currentTarget.style.color = '#000000';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Edit2 className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
+ <span className="ml-1">{t('common.edit')}</span>
|
|
|
+ </UIButton>
|
|
|
+ </PermissionWrapper>
|
|
|
+ <PermissionWrapper permission="system:permission:assign-role-menu">
|
|
|
+ <UIButton
|
|
|
+ variant="ghost"
|
|
|
+ size="sm"
|
|
|
+ disabled={isBuiltInRole(row)}
|
|
|
+ onClick={() => !isBuiltInRole(row) && openAssignMenuForm(row)}
|
|
|
+ className="h-8 px-2 transition-colors hover:underline"
|
|
|
+ style={{ color: '#000000' }}
|
|
|
+ onMouseEnter={(e) => {
|
|
|
+ if (isBuiltInRole(row)) return;
|
|
|
+ e.currentTarget.style.color = '#1677ff';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
+ }}
|
|
|
+ onMouseLeave={(e) => {
|
|
|
+ e.currentTarget.style.color = '#000000';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Settings className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
+ <span className="ml-1">{t('role.menuPermission')}</span>
|
|
|
+ </UIButton>
|
|
|
+ </PermissionWrapper>
|
|
|
+ <PermissionWrapper permission="system:permission:assign-role-data-scope">
|
|
|
+ <UIButton
|
|
|
+ variant="ghost"
|
|
|
+ size="sm"
|
|
|
+ disabled={isBuiltInRole(row)}
|
|
|
+ onClick={() => !isBuiltInRole(row) && openDataPermissionForm(row)}
|
|
|
+ className="h-8 px-2 transition-colors hover:underline"
|
|
|
+ style={{ color: '#000000' }}
|
|
|
+ onMouseEnter={(e) => {
|
|
|
+ if (isBuiltInRole(row)) return;
|
|
|
+ e.currentTarget.style.color = '#1677ff';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
+ }}
|
|
|
+ onMouseLeave={(e) => {
|
|
|
+ e.currentTarget.style.color = '#000000';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Shield className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
+ <span className="ml-1">{t('role.dataPermission')}</span>
|
|
|
+ </UIButton>
|
|
|
+ </PermissionWrapper>
|
|
|
+ <PermissionWrapper permission="system:role:delete">
|
|
|
+ <UIButton
|
|
|
+ variant="ghost"
|
|
|
+ size="sm"
|
|
|
+ disabled={isBuiltInRole(row)}
|
|
|
+ onClick={() => !isBuiltInRole(row) && handleDelete(row.id!, row.name)}
|
|
|
+ className="h-8 px-2 transition-colors hover:underline"
|
|
|
+ style={{ color: '#000000' }}
|
|
|
+ onMouseEnter={(e) => {
|
|
|
+ if (isBuiltInRole(row)) return;
|
|
|
+ e.currentTarget.style.color = '#1677ff';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #1677ff');
|
|
|
+ }}
|
|
|
+ onMouseLeave={(e) => {
|
|
|
+ e.currentTarget.style.color = '#000000';
|
|
|
+ e.currentTarget.querySelector('svg')?.setAttribute('style', 'color: #000000');
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Trash2 className="w-4 h-4" style={{ color: '#000000' }} />
|
|
|
+ <span className="ml-1">{t('common.delete')}</span>
|
|
|
+ </UIButton>
|
|
|
+ </PermissionWrapper>
|
|
|
+ </div>
|
|
|
+ </Tooltip>
|
|
|
</TableCell>
|
|
|
</TableRow>
|
|
|
))
|