feat: role member
This commit is contained in:
parent
ace03e5b5a
commit
569d16d735
@ -1,7 +1,7 @@
|
||||
import { get, post, del } from '@/request/index'
|
||||
import type { Ref } from 'vue'
|
||||
import { Result } from '@/request/Result'
|
||||
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, RoleMemberItem, CreateMemberParams } from '@/api/type/role'
|
||||
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, PageList, RoleMemberItem, CreateMemberParamsItem } from '@/api/type/role'
|
||||
import { RoleTypeEnum } from '@/enums/system'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
|
||||
@ -66,7 +66,7 @@ const getRoleMemberList: (
|
||||
page: pageRequest,
|
||||
param: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<RoleMemberItem>> = (role_id, page, param, loading) => {
|
||||
) => Promise<Result<PageList<RoleMemberItem[]>>> = (role_id, page, param, loading) => {
|
||||
return get(
|
||||
`${prefix}/${role_id}/user_list/${page.current_page}/${page.page_size}`,
|
||||
param,
|
||||
@ -79,7 +79,7 @@ const getRoleMemberList: (
|
||||
*/
|
||||
const CreateMember: (
|
||||
role_id: string,
|
||||
data: CreateMemberParams,
|
||||
data: { members: CreateMemberParamsItem[] },
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (role_id, data, loading) => {
|
||||
return post(`${prefix}/${role_id}/add_member`, data, undefined, loading)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { RoleTypeEnum } from '@/enums/system'
|
||||
|
||||
import type { FormItemRule } from 'element-plus'
|
||||
interface RoleItem {
|
||||
id: string,
|
||||
role_name: string,
|
||||
@ -49,8 +49,27 @@ interface RoleMemberItem {
|
||||
workspace_name: string,
|
||||
}
|
||||
|
||||
interface CreateMemberParams {
|
||||
members: { user_ids: string[], workspace_ids: string[] }[]
|
||||
interface CreateMemberParamsItem {
|
||||
user_ids: string[],
|
||||
workspace_ids: string[]
|
||||
}
|
||||
|
||||
export type { RoleItem, RolePermissionItem, RoleTableDataItem, CreateOrUpdateParams, ChildrenPermissionItem, RoleMemberItem, CreateMemberParams }
|
||||
interface PageList<T> {
|
||||
current: number,
|
||||
size: number,
|
||||
total: number,
|
||||
records: T
|
||||
}
|
||||
|
||||
type Arrayable<T> = T | T[]
|
||||
interface FormItemModel {
|
||||
path: string
|
||||
label?: string
|
||||
rules?: Arrayable<FormItemRule>,
|
||||
selectProps: {
|
||||
options?: { label: string, value: string }[]
|
||||
placeholder?: string
|
||||
}
|
||||
}
|
||||
|
||||
export type { RoleItem, FormItemModel, RolePermissionItem, RoleTableDataItem, CreateOrUpdateParams, PageList, ChildrenPermissionItem, RoleMemberItem, CreateMemberParamsItem }
|
||||
@ -26,7 +26,15 @@ const getProfile: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) =
|
||||
// return get('/profile', undefined, loading)
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取全部用户
|
||||
*/
|
||||
const getUserList: (loading?: Ref<boolean>) => Promise<Result<Record<string, any>[]>> = (loading) => {
|
||||
return get('/user/list', undefined, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
getUserProfile,
|
||||
getProfile
|
||||
getProfile,
|
||||
getUserList
|
||||
}
|
||||
|
||||
98
ui/src/views/role/component/AddMemberDrawer.vue
Normal file
98
ui/src/views/role/component/AddMemberDrawer.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<el-drawer v-model="visible" size="600" :destroy-on-close="true" :before-close="handleCancel">
|
||||
<template #header>
|
||||
<h4>{{ $t('views.role.member.add') }}</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<MemberFormContent ref="memberFormContentRef" :models="formItemModel" v-model:form="list" />
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleCancel">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="handleAdd()" :loading="loading">
|
||||
{{ $t('common.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
import type { CreateMemberParamsItem, FormItemModel } from '@/api/type/role'
|
||||
import RoleApi from '@/api/system/role'
|
||||
import UserApi from '@/api/user/user'
|
||||
import MemberFormContent from './MemberFormContent.vue'
|
||||
import { t } from '@/locales'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
|
||||
const props = defineProps<{
|
||||
roleId: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'refresh'): void;
|
||||
}>();
|
||||
|
||||
const loading = ref(false)
|
||||
const visible = ref(false)
|
||||
const list = ref<CreateMemberParamsItem[]>([]);
|
||||
|
||||
const formItemModel = ref<FormItemModel[]>([
|
||||
{
|
||||
path: 'user_ids',
|
||||
label: t('views.role.member.title'),
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`,
|
||||
},
|
||||
],
|
||||
selectProps: {
|
||||
options: [],
|
||||
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workspace_ids',
|
||||
label: t('views.role.member.workspace'),
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`,
|
||||
},
|
||||
],
|
||||
selectProps: {
|
||||
options: [], // TODO
|
||||
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`
|
||||
}
|
||||
},
|
||||
]);
|
||||
onBeforeMount(async () => {
|
||||
const res = await UserApi.getUserList();
|
||||
formItemModel.value[0].selectProps.options = res.data?.map(item => ({ label: item.nick_name, value: item.id }))
|
||||
})
|
||||
|
||||
function open() {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
visible.value = false
|
||||
list.value = []
|
||||
}
|
||||
|
||||
const memberFormContentRef = ref<InstanceType<typeof MemberFormContent>>()
|
||||
function handleAdd() {
|
||||
memberFormContentRef.value?.validate().then(async (valid) => {
|
||||
if (valid) {
|
||||
await RoleApi.CreateMember(props.roleId, { members: list.value }, loading)
|
||||
MsgSuccess(t('common.addSuccess'))
|
||||
handleCancel();
|
||||
emit('refresh')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
@ -17,12 +17,10 @@
|
||||
<el-table-column prop="nick_name" :label="$t('views.userManage.form.nick_name.label')" />
|
||||
<el-table-column prop="username" :label="$t('views.userManage.form.username.label')" />
|
||||
<el-table-column prop="workspace_name" :label="$t('views.role.member.workspace')" />
|
||||
<!-- TODO -->
|
||||
<el-table-column prop="nick_name" :label="$t('views.role.member.role')" />
|
||||
<el-table-column :label="$t('common.operation')" width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip effect="dark" :content="`${$t('common.create')}${$t('views.role.customRole')}`" placement="top">
|
||||
<el-button type="primary" text @click.stop="handleDelete(row)" :title="$t('common.edit')">
|
||||
<el-tooltip effect="dark" :content="`${$t('views.role.member.delete.button')}`" placement="top">
|
||||
<el-button type="primary" text @click.stop="handleDelete(row)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
@ -32,7 +30,7 @@
|
||||
</el-table-column>
|
||||
</app-table>
|
||||
</div>
|
||||
<!-- <AddMemberDrawer ref="addMemberDrawerRef" /> -->
|
||||
<AddMemberDrawer ref="addMemberDrawerRef" :role-id="props.currentRole?.id as string" @refresh="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -41,6 +39,7 @@ import RoleApi from '@/api/system/role'
|
||||
import type { RoleItem, RoleMemberItem } from '@/api/type/role'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { t } from '@/locales'
|
||||
import AddMemberDrawer from './AddMemberDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
currentRole?: RoleItem
|
||||
@ -66,7 +65,8 @@ async function getList() {
|
||||
[searchType.value]: searchForm.value[searchType.value],
|
||||
}
|
||||
const res = await RoleApi.getRoleMemberList(props.currentRole?.id as string, paginationConfig, params, loading)
|
||||
console.log('🤔️ =>', res);
|
||||
tableData.value = res.data.records
|
||||
paginationConfig.total = res.data.total
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
@ -85,8 +85,9 @@ watch(() => props.currentRole?.id, () => {
|
||||
getList()
|
||||
})
|
||||
|
||||
// TODO
|
||||
const addMemberDrawerRef = ref<InstanceType<typeof AddMemberDrawer>>()
|
||||
function handleAdd() {
|
||||
addMemberDrawerRef.value?.open();
|
||||
}
|
||||
|
||||
function handleDelete(row: RoleMemberItem) {
|
||||
|
||||
72
ui/src/views/role/component/MemberFormContent.vue
Normal file
72
ui/src/views/role/component/MemberFormContent.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<el-form :model="form" ref="formRef" label-position="top" require-asterisk-position="right">
|
||||
<el-scrollbar>
|
||||
<div v-for="(element, index) in form" :key="index" class="flex w-full">
|
||||
<el-form-item v-for="model of props.models" :key="model.path" :prop="`[${index}].${model.path}`"
|
||||
:rules="model.rules" :label="index === 0 && model.label ? model.label : ''" class="mr-8" style="flex: 1">
|
||||
<el-select v-model="element[model.path]"
|
||||
:placeholder="model.selectProps.placeholder ?? $t('common.selectPlaceholder')" clearable filterable multiple
|
||||
style="width: 100%">
|
||||
<el-option v-for="opt in model.selectProps.options" :key="opt.value" :label="opt.label"
|
||||
:value="opt.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 删除按钮 -->
|
||||
<el-button @click="handleDelete(index)"
|
||||
:style="{ 'margin-top': index === 0 && props.models.some((item) => item.label) ? '30px' : '' }">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<!-- 添加按钮 -->
|
||||
<el-button type="primary" text class="mt-2" @click="handleAdd">
|
||||
<el-icon class="mr-4">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
{{ $t('views.role.member.add') }}
|
||||
</el-button>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import type { FormItemModel } from '@/api/type/role'
|
||||
|
||||
const props = defineProps<{
|
||||
models: FormItemModel[];
|
||||
}>()
|
||||
|
||||
const formRef = ref()
|
||||
const formItem: Record<string, any> = {};
|
||||
const form = defineModel<Record<string, any>[]>('form', {
|
||||
default: [],
|
||||
});
|
||||
|
||||
function handleAdd() {
|
||||
form.value.push({ ...formItem });
|
||||
}
|
||||
|
||||
watch(() => props.models, () => {
|
||||
props.models.forEach((e) => {
|
||||
formItem[e.path] = [];
|
||||
});
|
||||
handleAdd();
|
||||
}, { immediate: true })
|
||||
|
||||
function handleDelete(index: number) {
|
||||
form.value.splice(index, 1);
|
||||
}
|
||||
|
||||
const validate = () => {
|
||||
if (formRef.value) {
|
||||
return formRef.value?.validate()
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
defineExpose({ validate })
|
||||
|
||||
</script>
|
||||
@ -69,7 +69,7 @@
|
||||
<el-dropdown-item @click.stop="createOrUpdateRole(row)" class="p-8"> {{ $t('common.rename') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.stop="deleteRole(row)" class="border-t p-8"> {{ $t('common.delete')
|
||||
}}
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
@ -85,12 +85,13 @@
|
||||
</div>
|
||||
|
||||
<!-- 右边 -->
|
||||
<div class="role-right">
|
||||
<div class="role-right" v-loading="loading">
|
||||
<div class="flex-between mb-16 p-24 pb-0">
|
||||
<div class="flex align-center">
|
||||
<span>
|
||||
{{ currentRole?.role_name }}
|
||||
<span v-if="currentRole?.type" class="color-input-placeholder ml-4">({{ roleTypeMap[currentRole?.type as
|
||||
<span v-if="currentRole?.type && !currentRole.internal" class="color-input-placeholder ml-4">({{
|
||||
roleTypeMap[currentRole?.type as
|
||||
RoleTypeEnum] }})
|
||||
</span>
|
||||
</span>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user