merge: t18 角色成员与空角色清空
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import type { ApiResult, PageResult } from '@/api';
|
import type { ApiResult, PageResult } from '@/api';
|
||||||
import type { Role, RoleParam } from './model';
|
import type { Role, RoleMember, RoleMemberParam, RoleParam } from './model';
|
||||||
import type { Menu } from '../menu/model';
|
import type { Menu } from '../menu/model';
|
||||||
import { SERVER_API_URL } from '@/config/setting';
|
import { SERVER_API_URL, THINK_API_URL } from '@/config/setting';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询角色
|
* 分页查询角色
|
||||||
@@ -117,3 +117,45 @@ export async function updateRoleMenus(roleId?: number, data?: number[]) {
|
|||||||
}
|
}
|
||||||
return Promise.reject(new Error(res.data.message));
|
return Promise.reject(new Error(res.data.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询角色成员
|
||||||
|
*/
|
||||||
|
export async function pageRoleMembers(params: RoleMemberParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<RoleMember>>>(
|
||||||
|
THINK_API_URL + '/system/role-member/page',
|
||||||
|
{ params }
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加角色成员
|
||||||
|
*/
|
||||||
|
export async function addRoleMember(data: RoleMemberParam) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
|
THINK_API_URL + '/system/role-member',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除角色成员
|
||||||
|
*/
|
||||||
|
export async function removeRoleMember(roleId?: number, userId?: number) {
|
||||||
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
|
THINK_API_URL + '/system/role-member',
|
||||||
|
{ params: { roleId, userId } }
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,3 +25,31 @@ export interface RoleParam extends PageParam {
|
|||||||
roleCode?: string;
|
roleCode?: string;
|
||||||
comments?: string;
|
comments?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色成员
|
||||||
|
*/
|
||||||
|
export interface RoleMember {
|
||||||
|
// 用户id
|
||||||
|
userId?: number;
|
||||||
|
// 账号
|
||||||
|
username?: string;
|
||||||
|
// 真实姓名
|
||||||
|
realName?: string;
|
||||||
|
// 昵称
|
||||||
|
nickname?: string;
|
||||||
|
// 所属组织id
|
||||||
|
organizationId?: number;
|
||||||
|
// 所属组织名称
|
||||||
|
organizationName?: string;
|
||||||
|
// 状态, 0启用, 1停用
|
||||||
|
status?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色成员查询/操作参数
|
||||||
|
*/
|
||||||
|
export interface RoleMemberParam extends PageParam {
|
||||||
|
roleId?: number;
|
||||||
|
userId?: number;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import type { ApiResult, PageResult } from '@/api';
|
import type { ApiResult, PageResult } from '@/api';
|
||||||
import type { User, UserParam } from './model';
|
import type { User, UserParam } from './model';
|
||||||
import { SERVER_API_URL } from '@/config/setting';
|
import { SERVER_API_URL, THINK_API_URL } from '@/config/setting';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询用户
|
* 分页查询用户
|
||||||
@@ -97,7 +97,7 @@ export async function addUser(data: User) {
|
|||||||
*/
|
*/
|
||||||
export async function updateUser(data: User) {
|
export async function updateUser(data: User) {
|
||||||
const res = await request.put<ApiResult<unknown>>(
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
SERVER_API_URL + '/system/user',
|
THINK_API_URL + '/system/user',
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
|
|||||||
@@ -0,0 +1,230 @@
|
|||||||
|
<!-- 角色成员维护弹窗 -->
|
||||||
|
<template>
|
||||||
|
<ele-modal
|
||||||
|
:width="720"
|
||||||
|
title="角色成员"
|
||||||
|
:visible="visible"
|
||||||
|
:body-style="{ paddingBottom: '8px' }"
|
||||||
|
:footer="null"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
>
|
||||||
|
<div style="margin-bottom: 12px">
|
||||||
|
<a-space>
|
||||||
|
<a-select
|
||||||
|
v-model:value="selectedUserId"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
:filter-option="false"
|
||||||
|
:options="userOptions"
|
||||||
|
:loading="userLoading"
|
||||||
|
placeholder="输入姓名或账号搜索启用用户"
|
||||||
|
style="width: 320px"
|
||||||
|
@search="searchUsers"
|
||||||
|
/>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
:loading="adding"
|
||||||
|
:disabled="!selectedUserId"
|
||||||
|
@click="addOne"
|
||||||
|
>
|
||||||
|
添加成员
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
<div class="ele-text-secondary" style="margin-top: 6px">
|
||||||
|
角色:{{ data?.roleName }}({{ data?.roleCode }})
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a-table
|
||||||
|
size="small"
|
||||||
|
row-key="userId"
|
||||||
|
:columns="columns"
|
||||||
|
:data-source="members"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="false"
|
||||||
|
:scroll="{ y: '46vh' }"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'userName'">
|
||||||
|
{{ record.realName || record.nickname || '-' }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'organizationName'">
|
||||||
|
{{ record.organizationName || '-' }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'status'">
|
||||||
|
<a-tag :color="record.status === 0 ? 'green' : 'red'">
|
||||||
|
{{ record.status === 0 ? '启用' : '停用' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'action'">
|
||||||
|
<a-popconfirm
|
||||||
|
placement="topRight"
|
||||||
|
title="确定要移除该成员吗?"
|
||||||
|
@confirm="removeOne(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">移除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import type { ColumnItem } from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
|
import {
|
||||||
|
addRoleMember,
|
||||||
|
pageRoleMembers,
|
||||||
|
removeRoleMember
|
||||||
|
} from '@/api/system/role';
|
||||||
|
import type { Role, RoleMember } from '@/api/system/role/model';
|
||||||
|
import { pageUsers } from '@/api/system/user';
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
// 当前角色数据
|
||||||
|
data?: Role | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = ref<ColumnItem[]>([
|
||||||
|
{ title: '姓名', key: 'userName', width: 120 },
|
||||||
|
{ title: '账号', dataIndex: 'username', width: 150 },
|
||||||
|
{ title: '所属组织', key: 'organizationName' },
|
||||||
|
{ title: '状态', key: 'status', width: 90, align: 'center' },
|
||||||
|
{ title: '操作', key: 'action', width: 90, align: 'center' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 成员列表
|
||||||
|
const members = ref<RoleMember[]>([]);
|
||||||
|
|
||||||
|
// 成员请求状态
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 添加状态
|
||||||
|
const adding = ref(false);
|
||||||
|
|
||||||
|
// 候选用户请求状态
|
||||||
|
const userLoading = ref(false);
|
||||||
|
|
||||||
|
// 候选用户下拉选项
|
||||||
|
const userOptions = ref<{ label: string; value: number }[]>([]);
|
||||||
|
|
||||||
|
// 选中的候选用户
|
||||||
|
const selectedUserId = ref<number | undefined>(undefined);
|
||||||
|
|
||||||
|
// 用户搜索关键词
|
||||||
|
const keyword = ref('');
|
||||||
|
|
||||||
|
// 当前角色id
|
||||||
|
const roleId = computed(() => props.data?.roleId);
|
||||||
|
|
||||||
|
// 已是成员的候选用户id
|
||||||
|
const memberIds = computed(() => new Set(members.value.map((d) => d.userId)));
|
||||||
|
|
||||||
|
/* 查询角色成员 */
|
||||||
|
const queryMembers = () => {
|
||||||
|
if (!roleId.value) {
|
||||||
|
members.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
pageRoleMembers({ roleId: roleId.value, page: 1, limit: 2000 })
|
||||||
|
.then((res) => {
|
||||||
|
loading.value = false;
|
||||||
|
members.value = res?.list ?? [];
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
members.value = [];
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 搜索启用用户作为候选 */
|
||||||
|
const searchUsers = (value?: string) => {
|
||||||
|
keyword.value = value ?? '';
|
||||||
|
userLoading.value = true;
|
||||||
|
pageUsers({
|
||||||
|
keywords: keyword.value || undefined,
|
||||||
|
status: 0,
|
||||||
|
page: 1,
|
||||||
|
limit: 20
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
userLoading.value = false;
|
||||||
|
userOptions.value = (res?.list ?? [])
|
||||||
|
.filter((d) => d.userId != null && !memberIds.value.has(d.userId))
|
||||||
|
.map((d) => ({
|
||||||
|
label: `${d.realName || d.nickname || d.username}(${d.username})`,
|
||||||
|
value: d.userId as number
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
userLoading.value = false;
|
||||||
|
userOptions.value = [];
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 添加成员 */
|
||||||
|
const addOne = () => {
|
||||||
|
if (!roleId.value || selectedUserId.value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adding.value = true;
|
||||||
|
addRoleMember({ roleId: roleId.value, userId: selectedUserId.value })
|
||||||
|
.then((msg) => {
|
||||||
|
adding.value = false;
|
||||||
|
selectedUserId.value = undefined;
|
||||||
|
message.success(msg);
|
||||||
|
queryMembers();
|
||||||
|
searchUsers(keyword.value);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
adding.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 移除成员 */
|
||||||
|
const removeOne = (row: RoleMember) => {
|
||||||
|
if (!roleId.value || row.userId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removeRoleMember(roleId.value, row.userId)
|
||||||
|
.then((msg) => {
|
||||||
|
message.success(msg);
|
||||||
|
queryMembers();
|
||||||
|
searchUsers(keyword.value);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
members.value = [];
|
||||||
|
userOptions.value = [];
|
||||||
|
selectedUserId.value = undefined;
|
||||||
|
keyword.value = '';
|
||||||
|
queryMembers();
|
||||||
|
searchUsers('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
@@ -39,6 +39,8 @@
|
|||||||
<a-space>
|
<a-space>
|
||||||
<a @click="openEdit(record)">修改</a>
|
<a @click="openEdit(record)">修改</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
|
<a @click="openMember(record)">成员</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
<a @click="openAuth(record)">分配权限</a>
|
<a @click="openAuth(record)">分配权限</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a-popconfirm
|
<a-popconfirm
|
||||||
@@ -57,6 +59,8 @@
|
|||||||
<role-edit v-model:visible="showEdit" :data="current" @done="reload" />
|
<role-edit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||||
<!-- 权限分配弹窗 -->
|
<!-- 权限分配弹窗 -->
|
||||||
<role-auth v-model:visible="showAuth" :data="current" />
|
<role-auth v-model:visible="showAuth" :data="current" />
|
||||||
|
<!-- 成员维护弹窗 -->
|
||||||
|
<role-member v-model:visible="showMember" :data="current" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -77,6 +81,7 @@
|
|||||||
import RoleSearch from './components/role-search.vue';
|
import RoleSearch from './components/role-search.vue';
|
||||||
import RoleEdit from './components/role-edit.vue';
|
import RoleEdit from './components/role-edit.vue';
|
||||||
import RoleAuth from './components/role-auth.vue';
|
import RoleAuth from './components/role-auth.vue';
|
||||||
|
import RoleMember from './components/role-member.vue';
|
||||||
import { pageRoles, removeRole, removeRoles } from '@/api/system/role';
|
import { pageRoles, removeRole, removeRoles } from '@/api/system/role';
|
||||||
import type { Role, RoleParam } from '@/api/system/role/model';
|
import type { Role, RoleParam } from '@/api/system/role/model';
|
||||||
|
|
||||||
@@ -120,7 +125,7 @@
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 200,
|
width: 260,
|
||||||
align: 'center'
|
align: 'center'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@@ -137,6 +142,9 @@
|
|||||||
// 是否显示权限分配弹窗
|
// 是否显示权限分配弹窗
|
||||||
const showAuth = ref(false);
|
const showAuth = ref(false);
|
||||||
|
|
||||||
|
// 是否显示成员维护弹窗
|
||||||
|
const showMember = ref(false);
|
||||||
|
|
||||||
// 表格数据源
|
// 表格数据源
|
||||||
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||||
return pageRoles({ ...where, ...orders, page, limit });
|
return pageRoles({ ...where, ...orders, page, limit });
|
||||||
@@ -160,6 +168,12 @@
|
|||||||
showAuth.value = true;
|
showAuth.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 打开成员维护弹窗 */
|
||||||
|
const openMember = (row?: Role) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showMember.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
/* 删除单个 */
|
/* 删除单个 */
|
||||||
const remove = (row: Role) => {
|
const remove = (row: Role) => {
|
||||||
const hide = messageLoading('请求中..', 0);
|
const hide = messageLoading('请求中..', 0);
|
||||||
|
|||||||
@@ -255,14 +255,8 @@
|
|||||||
// trigger: 'blur'
|
// trigger: 'blur'
|
||||||
// }
|
// }
|
||||||
// ],
|
// ],
|
||||||
roles: [
|
// 角色可以为空:清空并保存表示删除该用户的全部角色关联
|
||||||
{
|
roles: [],
|
||||||
required: true,
|
|
||||||
message: '请选择角色',
|
|
||||||
type: 'array',
|
|
||||||
trigger: 'blur'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
email: [
|
email: [
|
||||||
{
|
{
|
||||||
pattern: emailReg,
|
pattern: emailReg,
|
||||||
|
|||||||
Reference in New Issue
Block a user