Skip to content

Commit 569d16d

Browse files
committed
feat: role member
1 parent ace03e5 commit 569d16d

File tree

7 files changed

+217
-18
lines changed

7 files changed

+217
-18
lines changed

ui/src/api/system/role.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { get, post, del } from '@/request/index'
22
import type { Ref } from 'vue'
33
import { Result } from '@/request/Result'
4-
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, RoleMemberItem, CreateMemberParams } from '@/api/type/role'
4+
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, PageList, RoleMemberItem, CreateMemberParamsItem } from '@/api/type/role'
55
import { RoleTypeEnum } from '@/enums/system'
66
import type { pageRequest } from '@/api/type/common'
77

@@ -66,7 +66,7 @@ const getRoleMemberList: (
6666
page: pageRequest,
6767
param: any,
6868
loading?: Ref<boolean>,
69-
) => Promise<Result<RoleMemberItem>> = (role_id, page, param, loading) => {
69+
) => Promise<Result<PageList<RoleMemberItem[]>>> = (role_id, page, param, loading) => {
7070
return get(
7171
`${prefix}/${role_id}/user_list/${page.current_page}/${page.page_size}`,
7272
param,
@@ -79,7 +79,7 @@ const getRoleMemberList: (
7979
*/
8080
const CreateMember: (
8181
role_id: string,
82-
data: CreateMemberParams,
82+
data: { members: CreateMemberParamsItem[] },
8383
loading?: Ref<boolean>,
8484
) => Promise<Result<any>> = (role_id, data, loading) => {
8585
return post(`${prefix}/${role_id}/add_member`, data, undefined, loading)

ui/src/api/type/role.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RoleTypeEnum } from '@/enums/system'
2-
2+
import type { FormItemRule } from 'element-plus'
33
interface RoleItem {
44
id: string,
55
role_name: string,
@@ -49,8 +49,27 @@ interface RoleMemberItem {
4949
workspace_name: string,
5050
}
5151

52-
interface CreateMemberParams {
53-
members: { user_ids: string[], workspace_ids: string[] }[]
52+
interface CreateMemberParamsItem {
53+
user_ids: string[],
54+
workspace_ids: string[]
55+
}
56+
57+
interface PageList<T> {
58+
current: number,
59+
size: number,
60+
total: number,
61+
records: T
62+
}
63+
64+
type Arrayable<T> = T | T[]
65+
interface FormItemModel {
66+
path: string
67+
label?: string
68+
rules?: Arrayable<FormItemRule>,
69+
selectProps: {
70+
options?: { label: string, value: string }[]
71+
placeholder?: string
72+
}
5473
}
5574

56-
export type { RoleItem, RolePermissionItem, RoleTableDataItem, CreateOrUpdateParams, ChildrenPermissionItem, RoleMemberItem, CreateMemberParams }
75+
export type { RoleItem, FormItemModel, RolePermissionItem, RoleTableDataItem, CreateOrUpdateParams, PageList, ChildrenPermissionItem, RoleMemberItem, CreateMemberParamsItem }

ui/src/api/user/user.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ const getProfile: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) =
2626
// return get('/profile', undefined, loading)
2727
// }
2828

29+
/**
30+
* 获取全部用户
31+
*/
32+
const getUserList: (loading?: Ref<boolean>) => Promise<Result<Record<string, any>[]>> = (loading) => {
33+
return get('/user/list', undefined, loading)
34+
}
35+
2936
export default {
3037
getUserProfile,
31-
getProfile
38+
getProfile,
39+
getUserList
3240
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<template>
2+
<el-drawer v-model="visible" size="600" :destroy-on-close="true" :before-close="handleCancel">
3+
<template #header>
4+
<h4>{{ $t('views.role.member.add') }}</h4>
5+
</template>
6+
<template #default>
7+
<MemberFormContent ref="memberFormContentRef" :models="formItemModel" v-model:form="list" />
8+
</template>
9+
<template #footer>
10+
<div style="flex: auto">
11+
<el-button @click="handleCancel">{{ $t('common.cancel') }}</el-button>
12+
<el-button type="primary" @click="handleAdd()" :loading="loading">
13+
{{ $t('common.add') }}
14+
</el-button>
15+
</div>
16+
</template>
17+
</el-drawer>
18+
</template>
19+
20+
<script setup lang="ts">
21+
import { onBeforeMount, ref } from 'vue'
22+
import type { CreateMemberParamsItem, FormItemModel } from '@/api/type/role'
23+
import RoleApi from '@/api/system/role'
24+
import UserApi from '@/api/user/user'
25+
import MemberFormContent from './MemberFormContent.vue'
26+
import { t } from '@/locales'
27+
import { MsgSuccess } from '@/utils/message'
28+
29+
const props = defineProps<{
30+
roleId: string
31+
}>()
32+
33+
const emit = defineEmits<{
34+
(e: 'refresh'): void;
35+
}>();
36+
37+
const loading = ref(false)
38+
const visible = ref(false)
39+
const list = ref<CreateMemberParamsItem[]>([]);
40+
41+
const formItemModel = ref<FormItemModel[]>([
42+
{
43+
path: 'user_ids',
44+
label: t('views.role.member.title'),
45+
rules: [
46+
{
47+
required: true,
48+
message: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`,
49+
},
50+
],
51+
selectProps: {
52+
options: [],
53+
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`
54+
}
55+
},
56+
{
57+
path: 'workspace_ids',
58+
label: t('views.role.member.workspace'),
59+
rules: [
60+
{
61+
required: true,
62+
message: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`,
63+
},
64+
],
65+
selectProps: {
66+
options: [], // TODO
67+
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`
68+
}
69+
},
70+
]);
71+
onBeforeMount(async () => {
72+
const res = await UserApi.getUserList();
73+
formItemModel.value[0].selectProps.options = res.data?.map(item => ({ label: item.nick_name, value: item.id }))
74+
})
75+
76+
function open() {
77+
visible.value = true
78+
}
79+
80+
function handleCancel() {
81+
visible.value = false
82+
list.value = []
83+
}
84+
85+
const memberFormContentRef = ref<InstanceType<typeof MemberFormContent>>()
86+
function handleAdd() {
87+
memberFormContentRef.value?.validate().then(async (valid) => {
88+
if (valid) {
89+
await RoleApi.CreateMember(props.roleId, { members: list.value }, loading)
90+
MsgSuccess(t('common.addSuccess'))
91+
handleCancel();
92+
emit('refresh')
93+
}
94+
})
95+
}
96+
97+
defineExpose({ open })
98+
</script>

ui/src/views/role/component/Member.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@
1717
<el-table-column prop="nick_name" :label="$t('views.userManage.form.nick_name.label')" />
1818
<el-table-column prop="username" :label="$t('views.userManage.form.username.label')" />
1919
<el-table-column prop="workspace_name" :label="$t('views.role.member.workspace')" />
20-
<!-- TODO -->
21-
<el-table-column prop="nick_name" :label="$t('views.role.member.role')" />
2220
<el-table-column :label="$t('common.operation')" width="100" fixed="right">
2321
<template #default="{ row }">
24-
<el-tooltip effect="dark" :content="`${$t('common.create')}${$t('views.role.customRole')}`" placement="top">
25-
<el-button type="primary" text @click.stop="handleDelete(row)" :title="$t('common.edit')">
22+
<el-tooltip effect="dark" :content="`${$t('views.role.member.delete.button')}`" placement="top">
23+
<el-button type="primary" text @click.stop="handleDelete(row)">
2624
<el-icon>
2725
<EditPen />
2826
</el-icon>
@@ -32,7 +30,7 @@
3230
</el-table-column>
3331
</app-table>
3432
</div>
35-
<!-- <AddMemberDrawer ref="addMemberDrawerRef" /> -->
33+
<AddMemberDrawer ref="addMemberDrawerRef" :role-id="props.currentRole?.id as string" @refresh="getList" />
3634
</template>
3735

3836
<script setup lang="ts">
@@ -41,6 +39,7 @@ import RoleApi from '@/api/system/role'
4139
import type { RoleItem, RoleMemberItem } from '@/api/type/role'
4240
import { MsgSuccess, MsgConfirm } from '@/utils/message'
4341
import { t } from '@/locales'
42+
import AddMemberDrawer from './AddMemberDrawer.vue'
4443
4544
const props = defineProps<{
4645
currentRole?: RoleItem
@@ -66,7 +65,8 @@ async function getList() {
6665
[searchType.value]: searchForm.value[searchType.value],
6766
}
6867
const res = await RoleApi.getRoleMemberList(props.currentRole?.id as string, paginationConfig, params, loading)
69-
console.log('🤔️ =>', res);
68+
tableData.value = res.data.records
69+
paginationConfig.total = res.data.total
7070
} catch (error) {
7171
console.error(error)
7272
}
@@ -85,8 +85,9 @@ watch(() => props.currentRole?.id, () => {
8585
getList()
8686
})
8787
88-
// TODO
88+
const addMemberDrawerRef = ref<InstanceType<typeof AddMemberDrawer>>()
8989
function handleAdd() {
90+
addMemberDrawerRef.value?.open();
9091
}
9192
9293
function handleDelete(row: RoleMemberItem) {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<template>
2+
<el-form :model="form" ref="formRef" label-position="top" require-asterisk-position="right">
3+
<el-scrollbar>
4+
<div v-for="(element, index) in form" :key="index" class="flex w-full">
5+
<el-form-item v-for="model of props.models" :key="model.path" :prop="`[${index}].${model.path}`"
6+
:rules="model.rules" :label="index === 0 && model.label ? model.label : ''" class="mr-8" style="flex: 1">
7+
<el-select v-model="element[model.path]"
8+
:placeholder="model.selectProps.placeholder ?? $t('common.selectPlaceholder')" clearable filterable multiple
9+
style="width: 100%">
10+
<el-option v-for="opt in model.selectProps.options" :key="opt.value" :label="opt.label"
11+
:value="opt.value" />
12+
</el-select>
13+
</el-form-item>
14+
<!-- 删除按钮 -->
15+
<el-button @click="handleDelete(index)"
16+
:style="{ 'margin-top': index === 0 && props.models.some((item) => item.label) ? '30px' : '' }">
17+
<el-icon>
18+
<Delete />
19+
</el-icon>
20+
</el-button>
21+
</div>
22+
</el-scrollbar>
23+
24+
<!-- 添加按钮 -->
25+
<el-button type="primary" text class="mt-2" @click="handleAdd">
26+
<el-icon class="mr-4">
27+
<Plus />
28+
</el-icon>
29+
{{ $t('views.role.member.add') }}
30+
</el-button>
31+
</el-form>
32+
</template>
33+
34+
<script setup lang="ts">
35+
import { ref, watch } from 'vue'
36+
import type { FormItemModel } from '@/api/type/role'
37+
38+
const props = defineProps<{
39+
models: FormItemModel[];
40+
}>()
41+
42+
const formRef = ref()
43+
const formItem: Record<string, any> = {};
44+
const form = defineModel<Record<string, any>[]>('form', {
45+
default: [],
46+
});
47+
48+
function handleAdd() {
49+
form.value.push({ ...formItem });
50+
}
51+
52+
watch(() => props.models, () => {
53+
props.models.forEach((e) => {
54+
formItem[e.path] = [];
55+
});
56+
handleAdd();
57+
}, { immediate: true })
58+
59+
function handleDelete(index: number) {
60+
form.value.splice(index, 1);
61+
}
62+
63+
const validate = () => {
64+
if (formRef.value) {
65+
return formRef.value?.validate()
66+
}
67+
return Promise.resolve()
68+
}
69+
70+
defineExpose({ validate })
71+
72+
</script>

ui/src/views/role/index.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<el-dropdown-item @click.stop="createOrUpdateRole(row)" class="p-8"> {{ $t('common.rename') }}
7070
</el-dropdown-item>
7171
<el-dropdown-item @click.stop="deleteRole(row)" class="border-t p-8"> {{ $t('common.delete')
72-
}}
72+
}}
7373
</el-dropdown-item>
7474
</el-dropdown-menu>
7575
</template>
@@ -85,12 +85,13 @@
8585
</div>
8686

8787
<!-- 右边 -->
88-
<div class="role-right">
88+
<div class="role-right" v-loading="loading">
8989
<div class="flex-between mb-16 p-24 pb-0">
9090
<div class="flex align-center">
9191
<span>
9292
{{ currentRole?.role_name }}
93-
<span v-if="currentRole?.type" class="color-input-placeholder ml-4">({{ roleTypeMap[currentRole?.type as
93+
<span v-if="currentRole?.type && !currentRole.internal" class="color-input-placeholder ml-4">({{
94+
roleTypeMap[currentRole?.type as
9495
RoleTypeEnum] }})
9596
</span>
9697
</span>

0 commit comments

Comments
 (0)