Skip to content

Commit e728647

Browse files
committed
feat: add default permission settings and dialog for resource authorization
1 parent f7b3cc9 commit e728647

File tree

5 files changed

+148
-23
lines changed

5 files changed

+148
-23
lines changed

ui/src/locales/lang/en-US/views/system.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ export default {
144144
currentOnly: 'Current resource only',
145145
includeAll: 'Include all sub-resources',
146146
effectiveResource: 'Effective Resource',
147+
defaultPermission: 'Default Permission',
148+
defaultPermissionTip: 'Default permissions for all resources under the selected workspace',
147149
},
148150
},
149151
resource_management: {

ui/src/locales/lang/zh-CN/views/system.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ export default {
145145
currentOnly: '仅当前资源',
146146
includeAll: '包含所有子资源',
147147
effectiveResource: '生效资源',
148+
defaultPermission: '默认权限',
149+
defaultPermissionTip: '所选工作空间下所有资源的默认权限',
148150
},
149151
},
150152
resource_management: {

ui/src/locales/lang/zh-Hant/views/system.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ export default {
145145
currentOnly: '僅當前資源',
146146
includeAll: '包含所有子資源',
147147
effectiveResource: '生效資源',
148+
defaultPermission: '預設權限',
149+
defaultPermissionTip: '所選工作空間下所有資源的預設權限',
148150
},
149151
},
150152
resource_management: {

ui/src/views/system-setting/authentication/component/Setting.vue

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,13 @@
172172
</template>
173173

174174
<script setup lang="ts">
175-
import { ref, onMounted, computed } from 'vue'
176-
import { ComplexPermission } from '@/utils/permission/type'
177-
import { PermissionConst, RoleConst } from '@/utils/permission/data'
178-
import type { FormInstance } from 'element-plus'
179-
import { t } from '@/locales'
175+
import {ref, onMounted, computed} from 'vue'
176+
import {ComplexPermission} from '@/utils/permission/type'
177+
import {PermissionConst, RoleConst} from '@/utils/permission/data'
178+
import type {FormInstance} from 'element-plus'
179+
import {t} from '@/locales'
180180
import authApi from '@/api/system-settings/auth-setting.ts'
181-
import { MsgSuccess } from '@/utils/message.ts'
181+
import {MsgSuccess} from '@/utils/message.ts'
182182
import WorkspaceApi from '@/api/workspace/workspace.ts'
183183
import useStore from '@/stores'
184184
@@ -247,14 +247,17 @@ const submit = async () => {
247247
248248
const roleOptions = ref<Array<{ id: string; name: string; type?: string }>>([])
249249
const workspaceOptions = ref<Array<{ id: string; name: string }>>([])
250-
const { user } = useStore()
250+
const {user} = useStore()
251251
const selectedRoleType = ref<string>('') // 存储选中角色类型,用于控制 workspace 显示
252252
const showWorkspaceSelector = computed(() => selectedRoleType.value !== 'ADMIN')
253253
254254
// 当角色变更时更新 selectedRoleType
255255
const handleRoleChange = (roleId: string) => {
256256
const selectedRole = roleOptions.value.find((role) => role.id === roleId)
257257
selectedRoleType.value = selectedRole?.type || ''
258+
if (form.value.workspace_id === 'None' && showWorkspaceSelector) {
259+
form.value.workspace_id = 'default'
260+
}
258261
}
259262
260263
onMounted(async () => {
@@ -265,24 +268,24 @@ onMounted(async () => {
265268
// 并行请求:角色列表 + 登录设置;若为 EE 同时请求 workspace 列表
266269
const roleP = WorkspaceApi.getWorkspaceRoleList()
267270
.then((r) => r)
268-
.catch(() => ({ data: [] }))
271+
.catch(() => ({data: []}))
269272
const settingP = authApi
270273
.getLoginSetting()
271274
.then((r) => r)
272-
.catch(() => ({ data: {} }))
275+
.catch(() => ({data: {}}))
273276
const tasks: Promise<any>[] = [roleP, settingP]
274277
if (isEE) {
275278
tasks.push(
276279
WorkspaceApi.getWorkspaceList()
277280
.then((r) => r)
278-
.catch(() => ({ data: [] })),
281+
.catch(() => ({data: []})),
279282
)
280283
}
281284
282285
const results = await Promise.all(tasks)
283-
const roleRes = results[0] ?? { data: [] }
284-
const settingRes = results[1] ?? { data: {} }
285-
const workspaceRes = isEE ? (results[2] ?? { data: [] }) : null
286+
const roleRes = results[0] ?? {data: []}
287+
const settingRes = results[1] ?? {data: {}}
288+
const workspaceRes = isEE ? (results[2] ?? {data: []}) : null
286289
287290
// 处理角色列表(尽早回显)
288291
const rolesData = Array.isArray(roleRes?.data) ? roleRes.data : []
@@ -307,7 +310,7 @@ onMounted(async () => {
307310
// 处理 workspace 列表(如果需要)
308311
if (isEE && workspaceRes) {
309312
const wks = Array.isArray(workspaceRes.data) ? workspaceRes.data : []
310-
workspaceOptions.value = wks.map((item: any) => ({ id: item.id, name: item.name }))
313+
workspaceOptions.value = wks.map((item: any) => ({id: item.id, name: item.name}))
311314
}
312315
313316
// 初始化 selectedRoleType(基于当前回显的 role_id 与已加载的 roleOptions)

ui/src/views/system/user-manage/component/UserDrawer.vue

Lines changed: 125 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,51 @@
6969
:deleteButtonDisabled="deleteButtonDisabled"
7070
/>
7171
<template #footer>
72-
<el-button @click.prevent="visible = false"> {{ $t('common.cancel') }}</el-button>
73-
<el-button type="primary" @click="submit(userFormRef)" :loading="loading">
74-
{{ $t('common.save') }}
75-
</el-button>
72+
<div style="display: flex; width: 100%;">
73+
<el-button @click="openDialog" v-if="!isEdit && showPermission">
74+
{{ $t('views.system.resourceAuthorization.setting.defaultPermission') }}
75+
</el-button>
76+
<div style="margin-left: auto;">
77+
<el-button @click.prevent="visible = false">{{ $t('common.cancel') }}</el-button>
78+
<el-button type="primary" @click="submit(userFormRef)" :loading="loading">
79+
{{ $t('common.save') }}
80+
</el-button>
81+
</div>
82+
</div>
83+
7684
</template>
7785
</el-drawer>
86+
<el-dialog
87+
v-model="dialogVisible"
88+
:title="$t('views.system.resourceAuthorization.setting.defaultPermission')"
89+
destroy-on-close
90+
@close="closeDialog"
91+
>
92+
<template #header="{ titleId, titleClass }" v-if="user.isEE()">
93+
<div class="dialog-header">
94+
<h4 :id="titleId" :class="titleClass" style="margin: 0;">
95+
{{ $t('views.system.resourceAuthorization.setting.defaultPermission') }}
96+
<span class="dialog-subtitle">
97+
{{ $t('views.system.resourceAuthorization.setting.defaultPermissionTip') }}
98+
</span>
99+
</h4>
100+
</div>
101+
</template>
102+
<el-radio-group v-model="radioPermission" class="radio-block">
103+
<template v-for="(item, index) in permissionOptions" :key="index">
104+
<el-radio :value="item.value" class="mr-16">
105+
<p class="color-text-primary lighter">{{ item.label }}</p>
106+
<el-text class="color-secondary lighter">{{ item.desc }}</el-text>
107+
</el-radio>
108+
</template>
109+
</el-radio-group>
110+
<template #footer>
111+
<div class="dialog-footer mt-24">
112+
<el-button @click="closeDialog"> {{ $t('common.cancel') }}</el-button>
113+
<el-button type="primary" @click="submitDialog"> {{ $t('common.confirm') }}</el-button>
114+
</div>
115+
</template>
116+
</el-dialog>
78117
</template>
79118
<script setup lang="ts">
80119
import {ref, reactive, watch, onBeforeMount, computed} from 'vue'
@@ -85,8 +124,10 @@ import {t} from '@/locales'
85124
import type {FormItemModel} from '@/api/type/role'
86125
import WorkspaceApi from '@/api/workspace/workspace'
87126
import MemberFormContent from '@/views/system/role/component/MemberFormContent.vue'
88-
import {RoleTypeEnum} from '@/enums/system'
127+
import {AuthorizationEnum, RoleTypeEnum} from '@/enums/system'
89128
import useStore from '@/stores'
129+
import {hasPermission} from "@/utils/permission";
130+
import {EditionConst} from "@/utils/permission/data.ts";
90131
91132
const {user} = useStore()
92133
const props = defineProps({
@@ -109,15 +150,56 @@ const memberFormContentLoading = ref(false)
109150
const formItemModel = ref<FormItemModel[]>([])
110151
const roleFormItem = ref<FormItemModel[]>([])
111152
const adminRoleList = ref<any[]>([])
153+
const userRoleList = ref<any[]>([])
112154
const workspaceFormItem = ref<FormItemModel[]>([])
113155
114156
const isAdmin = computed(() => userForm.value['id'] === 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab')
157+
const dialogVisible = ref(false)
158+
const radioPermission = ref('NOT_AUTH')
159+
const defaultPermission = ref('NOT_AUTH')
160+
const permissionOptions = computed(() => {
161+
const baseOptions = [
162+
{
163+
label: t('views.system.resourceAuthorization.setting.check'),
164+
value: AuthorizationEnum.VIEW,
165+
desc: t('views.system.resourceAuthorization.setting.checkDesc'),
166+
},
167+
{
168+
label: t('views.system.resourceAuthorization.setting.management'),
169+
value: AuthorizationEnum.MANAGE,
170+
desc: t('views.system.resourceAuthorization.setting.managementDesc'),
171+
},
172+
{
173+
label: t('views.system.resourceAuthorization.setting.notAuthorized'),
174+
value: AuthorizationEnum.NOT_AUTH,
175+
desc: '',
176+
}
177+
];
115178
116-
function deleteButtonDisabled(element: any) {
117-
if (isAdmin.value && ['ADMIN', 'WORKSPACE_MANAGE', 'USER'].includes(element.role_id)) {
179+
if (hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')) {
180+
baseOptions.splice(2, 0, {
181+
label: t('views.system.resourceAuthorization.setting.role'),
182+
value: AuthorizationEnum.ROLE,
183+
desc: t('views.system.resourceAuthorization.setting.roleDesc'),
184+
});
185+
}
186+
187+
return baseOptions;
188+
});
189+
190+
const showPermission = computed(() => {
191+
//社区版本的可以显示 别的版本 过期了 也可以显示
192+
if (user.isCE() || user.isExpire()) {
118193
return true
119194
}
120-
return false
195+
const hasUserRole = list.value.some((item) => userRoleList.value.includes(item.role_id));
196+
return (user.isEE() || user.isPE()) && hasUserRole
197+
})
198+
199+
200+
function deleteButtonDisabled(element: any) {
201+
return isAdmin.value && ['ADMIN', 'WORKSPACE_MANAGE', 'USER'].includes(element.role_id);
202+
121203
}
122204
123205
async function getRoleFormItem() {
@@ -145,6 +227,10 @@ async function getRoleFormItem() {
145227
},
146228
]
147229
adminRoleList.value = res.data.filter((item) => item.type === RoleTypeEnum.ADMIN)
230+
userRoleList.value = res.data
231+
.filter((item) => item.type === RoleTypeEnum.USER)
232+
.map((item) => item.id)
233+
148234
} catch (e) {
149235
console.error(e)
150236
}
@@ -352,6 +438,7 @@ const submit = async (formEl: FormInstance | undefined) => {
352438
visible.value = false
353439
})
354440
} else {
441+
params.defaultPermission = defaultPermission.value
355442
userManageApi
356443
.postUserManage(params, loading)
357444
.then((res) => {
@@ -369,6 +456,35 @@ const submit = async (formEl: FormInstance | undefined) => {
369456
})
370457
}
371458
459+
const openDialog = () => {
460+
dialogVisible.value = true
461+
}
462+
463+
const closeDialog = () => {
464+
dialogVisible.value = false
465+
}
466+
467+
const submitDialog = () => {
468+
defaultPermission.value = radioPermission.value
469+
closeDialog()
470+
}
471+
472+
372473
defineExpose({open})
373474
</script>
374-
<style lang="scss" scoped></style>
475+
<style lang="scss" scoped>
476+
.dialog-header {
477+
h4 {
478+
display: flex;
479+
align-items: baseline;
480+
gap: 8px;
481+
margin: 0;
482+
}
483+
484+
.dialog-subtitle {
485+
font-size: 14px;
486+
color: var(--el-text-color-secondary);
487+
}
488+
}
489+
490+
</style>

0 commit comments

Comments
 (0)