更新权限
This commit is contained in:
@@ -61,6 +61,54 @@ export const delObj = (ids: Object) => {
|
||||
data: ids,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量设置角色分组
|
||||
* @param roleIds 角色ID列表
|
||||
* @param roleGroup 分组名称(空表示未分组)
|
||||
*/
|
||||
export const batchUpdateRoleGroup = (roleIds: string[], roleGroup: string) => {
|
||||
return request({
|
||||
url: '/admin/role/batchGroup',
|
||||
method: 'put',
|
||||
data: { roleIds, roleGroup: roleGroup || '' },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量指定角色关联用户
|
||||
* @param roleId 角色ID
|
||||
* @param userIds 用户ID列表
|
||||
*/
|
||||
export const assignUsersToRole = (roleId: string, userIds: string[]) => {
|
||||
return request({
|
||||
url: '/admin/role/assignUsers',
|
||||
method: 'post',
|
||||
data: { roleId, userIds },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据角色ID查询该角色下绑定的用户列表(含部门、姓名、工号)
|
||||
* @param roleId 角色ID
|
||||
*/
|
||||
export const getUsersByRoleId = (roleId: string) => {
|
||||
return request({
|
||||
url: '/admin/role/users/' + roleId,
|
||||
method: 'get',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 解除指定用户与该角色的关联
|
||||
* @param roleId 角色ID
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
export const unassignUserFromRole = (roleId: string, userId: string) => {
|
||||
return request({
|
||||
url: `/admin/role/users/${roleId}/${userId}`,
|
||||
method: 'delete',
|
||||
});
|
||||
};
|
||||
|
||||
export const permissionUpd = (roleId: string, menuIds: string) => {
|
||||
return request({
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
<el-form-item :label="$t('sysrole.roleCode')" prop="roleCode">
|
||||
<el-input :placeholder="$t('sysrole.please_enter_the_role_Code')" :disabled="form.roleId !== ''" clearable v-model="form.roleCode"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组" prop="roleGroup">
|
||||
<el-input placeholder="用于列表树状分组展示,可留空" clearable v-model="form.roleGroup" maxlength="50" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="roleSort">
|
||||
<el-input-number v-model="form.roleSort" :min="0" :max="9999" placeholder="数值越小越靠前" controls-position="right" style="width: 140px" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('sysrole.roleDesc')" prop="roleDesc">
|
||||
<el-input
|
||||
maxlength="100"
|
||||
@@ -67,6 +73,8 @@ const form = reactive({
|
||||
roleId: '',
|
||||
roleName: '',
|
||||
roleCode: '',
|
||||
roleGroup: '',
|
||||
roleSort: 0,
|
||||
roleDesc: '',
|
||||
dsType: 0,
|
||||
dsScope: '',
|
||||
@@ -187,6 +195,7 @@ const getRoleData = (id: string) => {
|
||||
// 获取部门数据
|
||||
getObj(id).then((res: any) => {
|
||||
Object.assign(form, res.data);
|
||||
if (res.data.roleSort == null) form.roleSort = 0;
|
||||
if (res.data.dsScope) {
|
||||
dataForm.checkedDsScope = res.data.dsScope.split(',');
|
||||
} else {
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10" v-auth="'sys_user_del'" @click="handleDelete(selectObjs)">
|
||||
{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
<el-button plain :disabled="multiple" type="primary" class="ml10" v-auth="'sys_role_edit'" @click="showBatchGroupDialog = true">
|
||||
批量指定分组
|
||||
</el-button>
|
||||
<el-button plain :disabled="selectObjs.length !== 1" type="primary" class="ml10" v-auth="'sys_role_edit'" @click="openAssignUserDialog">
|
||||
批量指定关联用户
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
:export="'sys_role_export'"
|
||||
@@ -36,55 +42,165 @@
|
||||
</div>
|
||||
</el-row>
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
:data="roleTreeData"
|
||||
v-loading="state.loading"
|
||||
style="width: 100%"
|
||||
row-key="roleId"
|
||||
@selection-change="handleSelectionChange"
|
||||
row-key="roleId"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="selection" :selectable="handleSelectable" width="50" align="center" />
|
||||
<el-table-column type="index" :label="$t('sysrole.index')" width="80" />
|
||||
<el-table-column prop="roleName" :label="$t('sysrole.roleName')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="roleCode" :label="$t('sysrole.roleCode')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="roleDesc" :label="$t('sysrole.roleDesc')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="data_authority" :label="$t('sysrole.data_authority')" show-overflow-tooltip>
|
||||
<el-table-column type="selection" :selectable="handleSelectable" width="50" align="left" />
|
||||
<el-table-column type="index" :label="$t('sysrole.index')" width="80">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="dictType" :value="scope.row.dsType"></dict-tag>
|
||||
<span v-if="scope.row._isGroup">—</span>
|
||||
<span v-else>{{ scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" :label="$t('sysrole.createTime')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="$t('common.action')" width="250">
|
||||
<el-table-column prop="roleName" :label="$t('sysrole.roleName')" show-overflow-tooltip min-width="140" align="left">
|
||||
<template #default="scope">
|
||||
<el-button text type="primary" icon="edit-pen" v-auth="'sys_role_edit'" @click="roleDialogRef.openDialog(scope.row.roleId)">{{
|
||||
$t('common.editBtn')
|
||||
}}</el-button>
|
||||
|
||||
<el-button text type="primary" icon="turn-off" v-auth="'sys_role_perm'" @click="permessionRef.openDialog(scope.row)">{{
|
||||
$t('sysrole.permissionTip')
|
||||
}}</el-button>
|
||||
|
||||
<el-tooltip :content="$t('sysrole.deleteDisabledTip')" :disabled="scope.row.roleId !== '1'" placement="top">
|
||||
<span style="margin-left: 12px">
|
||||
<el-button
|
||||
text
|
||||
type="primary"
|
||||
icon="delete"
|
||||
:disabled="scope.row.roleId === '1'"
|
||||
v-auth="'sys_role_del'"
|
||||
@click="handleDelete([scope.row.roleId])"
|
||||
>{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<span v-if="scope.row._isGroup" class="role-group-name">{{ scope.row.roleName }}</span>
|
||||
<span v-else>{{ scope.row.roleName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roleSort" label="排序" width="80" align="center">
|
||||
<template #default="scope">{{ scope.row._isGroup ? '—' : (scope.row.roleSort ?? 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roleCode" :label="$t('sysrole.roleCode')" show-overflow-tooltip min-width="120">
|
||||
<template #default="scope">{{ scope.row._isGroup ? '—' : scope.row.roleCode }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roleDesc" :label="$t('sysrole.roleDesc')" show-overflow-tooltip min-width="140">
|
||||
<template #default="scope">{{ scope.row._isGroup ? '—' : scope.row.roleDesc }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="data_authority" :label="$t('sysrole.data_authority')" show-overflow-tooltip width="100">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row._isGroup">—</template>
|
||||
<dict-tag v-else :options="dictType" :value="scope.row.dsType"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" :label="$t('sysrole.createTime')" show-overflow-tooltip width="165">
|
||||
<template #default="scope">{{ scope.row._isGroup ? '—' : scope.row.createTime }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('common.action')" width="250" fixed="right">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row._isGroup">—</template>
|
||||
<template v-else>
|
||||
<el-button text type="primary" icon="edit-pen" v-auth="'sys_role_edit'" @click="roleDialogRef.openDialog(scope.row.roleId)">{{
|
||||
$t('common.editBtn')
|
||||
}}</el-button>
|
||||
<el-button text type="primary" icon="turn-off" v-auth="'sys_role_perm'" @click="permessionRef.openDialog(scope.row)">{{
|
||||
$t('sysrole.permissionTip')
|
||||
}}</el-button>
|
||||
<el-button text type="primary" icon="user" v-auth="'sys_role_view'" @click="openRoleUsersDialog(scope.row)">查看关联用户</el-button>
|
||||
<el-tooltip :content="$t('sysrole.deleteDisabledTip')" :disabled="scope.row.roleId !== '1'" placement="top">
|
||||
<span style="margin-left: 12px">
|
||||
<el-button
|
||||
text
|
||||
type="primary"
|
||||
icon="delete"
|
||||
:disabled="scope.row.roleId === '1'"
|
||||
v-auth="'sys_role_del'"
|
||||
@click="handleDelete([scope.row.roleId])"
|
||||
>{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 批量指定分组弹窗 -->
|
||||
<el-dialog v-model="showBatchGroupDialog" title="批量指定分组" width="400px" @close="batchGroupName = ''">
|
||||
<el-form label-width="80px">
|
||||
<el-form-item label="分组名称">
|
||||
<el-input v-model="batchGroupName" placeholder="输入分组名,留空为未分组" clearable maxlength="50" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showBatchGroupDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="batchGroupLoading" @click="handleBatchGroup">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 批量指定关联用户弹窗 -->
|
||||
<el-dialog
|
||||
v-model="showAssignUserDialog"
|
||||
title="批量指定关联用户"
|
||||
width="720px"
|
||||
destroy-on-close
|
||||
@close="assignUserKeyword = ''; assignUserType = ''; assignUserList = []; assignUserTree = []; assignSelectedIds = []">
|
||||
<template v-if="assignCurrentRole">
|
||||
<div class="mb12"><el-text type="info">当前角色:{{ assignCurrentRole.roleName }}({{ assignCurrentRole.roleCode }})</el-text></div>
|
||||
<el-form :inline="true" class="mb12">
|
||||
<el-form-item label="用户类型" required>
|
||||
<el-radio-group v-model="assignUserType">
|
||||
<el-radio label="1">教职工</el-radio>
|
||||
<el-radio label="2">学生</el-radio>
|
||||
<el-radio label="3">驻校单位</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名/工号">
|
||||
<el-input v-model="assignUserKeyword" placeholder="姓名或工号检索" clearable style="width: 180px" @keyup.enter="loadAssignUserList" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="assignUserLoading" @click="loadAssignUserList">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="assign-user-tip mb8" v-if="!assignUserType">请先选择用户类型后再查询</div>
|
||||
<el-table
|
||||
v-else
|
||||
:data="assignUserTree"
|
||||
row-key="id"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
default-expand-all
|
||||
v-loading="assignUserLoading"
|
||||
max-height="360"
|
||||
border
|
||||
@selection-change="handleAssignUserSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="left" :selectable="(row: any) => !row._isDept" />
|
||||
<el-table-column prop="label" label="部门 / 姓名" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row._isDept" class="dept-row">{{ row.label }}</span>
|
||||
<span v-else>{{ row.realName || row.username || row.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="工号" width="120">
|
||||
<template #default="{ row }">{{ row._isDept ? '—' : row.username }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="部门" width="140">
|
||||
<template #default="{ row }">{{ row._isDept ? '—' : (row.deptName || '—') }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="showAssignUserDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="assignSubmitLoading" :disabled="assignSelectedIds.length === 0" @click="handleAssignUsersSubmit">确定(已选 {{ assignSelectedIds.length }} 人)</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 查看角色关联用户弹窗 -->
|
||||
<el-dialog v-model="showRoleUsersDialog" title="关联用户" width="560px" destroy-on-close>
|
||||
<template v-if="currentRoleForUsers">
|
||||
<div class="mb12"><el-text type="info">角色:{{ currentRoleForUsers.roleName }}({{ currentRoleForUsers.roleCode }})</el-text></div>
|
||||
<el-table :data="roleUsersList" v-loading="roleUsersLoading" max-height="400" border>
|
||||
<el-table-column prop="deptName" label="部门" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column prop="realName" label="姓名" width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="username" label="工号" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="80" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button text type="danger" icon="delete" v-auth="'sys_role_edit'" @click="handleUnassignUser(row)">解除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt8" v-if="!roleUsersLoading && roleUsersList.length === 0"><el-text type="info">该角色下暂无关联用户</el-text></div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 角色编辑、新增 -->
|
||||
<role-dialog ref="roleDialogRef" @refresh="getDataList()" />
|
||||
<!-- 导入角色 -->
|
||||
@@ -101,8 +217,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="systemRole">
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { pageList, delObj } from '/@/api/admin/role';
|
||||
import { list, delObj, batchUpdateRoleGroup, assignUsersToRole, getUsersByRoleId, unassignUserFromRole } from '/@/api/admin/role';
|
||||
import { pageList as userPageList } from '/@/api/admin/user';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
@@ -121,15 +239,103 @@ const showSearch = ref(true);
|
||||
const selectObjs = ref([]) as any;
|
||||
// 是否可以多选
|
||||
const multiple = ref(true);
|
||||
// 批量指定分组
|
||||
const showBatchGroupDialog = ref(false);
|
||||
const batchGroupName = ref('');
|
||||
const batchGroupLoading = ref(false);
|
||||
|
||||
// 查看角色关联用户
|
||||
const showRoleUsersDialog = ref(false);
|
||||
const roleUsersList = ref<any[]>([]);
|
||||
const roleUsersLoading = ref(false);
|
||||
const currentRoleForUsers = ref<{ roleName: string; roleCode: string; roleId: string } | null>(null);
|
||||
|
||||
// 批量指定关联用户
|
||||
const showAssignUserDialog = ref(false);
|
||||
const assignUserType = ref('');
|
||||
const assignUserKeyword = ref('');
|
||||
const assignUserList = ref<any[]>([]);
|
||||
const assignUserLoading = ref(false);
|
||||
const assignSubmitLoading = ref(false);
|
||||
const assignSelectedIds = ref<string[]>([]);
|
||||
const assignCurrentRole = computed(() => {
|
||||
const id = selectObjs.value && selectObjs.value[0];
|
||||
if (!id) return null;
|
||||
return (state.dataList || []).find((r: any) => r.roleId === id) || null;
|
||||
});
|
||||
/** 按部门分组的用户树(用于表格树形展示) */
|
||||
const assignUserTree = computed(() => {
|
||||
const list = assignUserList.value || [];
|
||||
const map = new Map<string, any[]>();
|
||||
list.forEach((u: any) => {
|
||||
const deptKey = u.deptName && String(u.deptName).trim() ? u.deptName : '未分配部门';
|
||||
if (!map.has(deptKey)) map.set(deptKey, []);
|
||||
map.get(deptKey)!.push({ ...u, id: u.userId, _isDept: false });
|
||||
});
|
||||
const result: any[] = [];
|
||||
map.forEach((users, deptName) => {
|
||||
result.push({
|
||||
id: `dept_${deptName}`,
|
||||
label: deptName,
|
||||
_isDept: true,
|
||||
children: users,
|
||||
});
|
||||
});
|
||||
result.sort((a, b) => a.label.localeCompare(b.label));
|
||||
return result;
|
||||
});
|
||||
|
||||
// 列表不分页,显示全部数据
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
roleName: '',
|
||||
},
|
||||
pageList: pageList, // H
|
||||
isPage: false,
|
||||
pageList: async (params: any) => {
|
||||
const res = await list(params);
|
||||
let data = res?.data || [];
|
||||
if (Array.isArray(data) && params?.roleName) {
|
||||
const kw = String(params.roleName).trim().toLowerCase();
|
||||
if (kw) {
|
||||
data = data.filter(
|
||||
(r: any) =>
|
||||
(r.roleName && r.roleName.toLowerCase().includes(kw)) ||
|
||||
(r.roleCode && r.roleCode.toLowerCase().includes(kw))
|
||||
);
|
||||
}
|
||||
}
|
||||
return { data };
|
||||
},
|
||||
descs: ['create_time'],
|
||||
});
|
||||
|
||||
/** 按分组构建树形数据:分组为父节点,角色为子节点 */
|
||||
const roleTreeData = computed(() => {
|
||||
const list = state.dataList || [];
|
||||
const groupMap = new Map<string, any[]>();
|
||||
list.forEach((row: any) => {
|
||||
const groupName = row.roleGroup && String(row.roleGroup).trim() ? String(row.roleGroup).trim() : '未分组';
|
||||
if (!groupMap.has(groupName)) groupMap.set(groupName, []);
|
||||
groupMap.get(groupName)!.push(row);
|
||||
});
|
||||
const result: any[] = [];
|
||||
groupMap.forEach((roles, groupName) => {
|
||||
result.push({
|
||||
roleId: `group_${groupName}`,
|
||||
roleName: groupName,
|
||||
_isGroup: true,
|
||||
children: roles,
|
||||
});
|
||||
});
|
||||
// 未分组放最后,其余按分组名排序
|
||||
result.sort((a, b) => {
|
||||
if (a.roleName === '未分组') return 1;
|
||||
if (b.roleName === '未分组') return -1;
|
||||
return a.roleName.localeCompare(b.roleName);
|
||||
});
|
||||
return result;
|
||||
});
|
||||
|
||||
const dictType = ref([
|
||||
{
|
||||
label: '全部',
|
||||
@@ -153,8 +359,8 @@ const dictType = ref([
|
||||
},
|
||||
]);
|
||||
|
||||
// table hook
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, downBlobFile, tableStyle } = useTable(state);
|
||||
// table hook(无分页,不暴露 currentChangeHandle/sizeChangeHandle)
|
||||
const { getDataList, downBlobFile, tableStyle } = useTable(state);
|
||||
|
||||
// 清空搜索条件
|
||||
const resetQuery = () => {
|
||||
@@ -167,15 +373,15 @@ const exportExcel = () => {
|
||||
downBlobFile('/admin/role/export',Object.assign(state.queryForm,{ids:selectObjs}), 'role.xlsx');
|
||||
};
|
||||
|
||||
// 是否可以多选
|
||||
// 是否可以多选(分组行不可选,管理员角色不可选)
|
||||
const handleSelectable = (row: any) => {
|
||||
return row.roleId !== '1';
|
||||
return !row._isGroup && row.roleId !== '1';
|
||||
};
|
||||
|
||||
// 多选事件
|
||||
// 多选事件(仅角色行可选,排除分组行)
|
||||
const handleSelectionChange = (objs: { roleId: string }[]) => {
|
||||
selectObjs.value = objs.map(({ roleId }) => roleId);
|
||||
multiple.value = !objs.length;
|
||||
selectObjs.value = objs.map(({ roleId }) => roleId).filter((id: string) => !String(id).startsWith('group_'));
|
||||
multiple.value = !selectObjs.value.length;
|
||||
};
|
||||
|
||||
// 删除操作
|
||||
@@ -194,4 +400,129 @@ const handleDelete = async (ids: string[]) => {
|
||||
useMessage().error(err.msg);
|
||||
}
|
||||
};
|
||||
|
||||
async function loadRoleUsersList() {
|
||||
const role = currentRoleForUsers.value;
|
||||
if (!role) return;
|
||||
roleUsersLoading.value = true;
|
||||
try {
|
||||
const res = await getUsersByRoleId(role.roleId);
|
||||
const data = res?.data;
|
||||
roleUsersList.value = Array.isArray(data) ? data : [];
|
||||
} catch {
|
||||
roleUsersList.value = [];
|
||||
} finally {
|
||||
roleUsersLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function openRoleUsersDialog(row: any) {
|
||||
currentRoleForUsers.value = { roleName: row.roleName, roleCode: row.roleCode, roleId: row.roleId };
|
||||
showRoleUsersDialog.value = true;
|
||||
roleUsersList.value = [];
|
||||
await loadRoleUsersList();
|
||||
}
|
||||
|
||||
async function handleUnassignUser(row: any) {
|
||||
const roleId = currentRoleForUsers.value?.roleId;
|
||||
const userId = row.userId;
|
||||
if (!roleId || !userId) return;
|
||||
try {
|
||||
await useMessageBox().confirm(`确定解除「${row.realName || row.username}」与该角色的关联?`);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await unassignUserFromRole(roleId, userId);
|
||||
useMessage().success('已解除关联');
|
||||
await loadRoleUsersList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
function openAssignUserDialog() {
|
||||
if (selectObjs.value.length !== 1) return;
|
||||
showAssignUserDialog.value = true;
|
||||
assignUserType.value = '';
|
||||
assignUserKeyword.value = '';
|
||||
assignUserList.value = [];
|
||||
assignSelectedIds.value = [];
|
||||
}
|
||||
|
||||
async function loadAssignUserList() {
|
||||
if (!assignUserType.value) return;
|
||||
assignUserLoading.value = true;
|
||||
try {
|
||||
const res = await userPageList({
|
||||
current: 1,
|
||||
size: 2000,
|
||||
userType: assignUserType.value,
|
||||
realName: assignUserKeyword.value ? assignUserKeyword.value.trim() : undefined,
|
||||
});
|
||||
const records = res?.data?.records ?? res?.records ?? (Array.isArray(res?.data) ? res.data : []);
|
||||
assignUserList.value = Array.isArray(records) ? records : [];
|
||||
} catch (e) {
|
||||
assignUserList.value = [];
|
||||
} finally {
|
||||
assignUserLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleAssignUserSelectionChange(rows: any[]) {
|
||||
assignSelectedIds.value = (rows || [])
|
||||
.filter((r: any) => !r._isDept && r.userId)
|
||||
.map((r: any) => r.userId);
|
||||
}
|
||||
|
||||
async function handleAssignUsersSubmit() {
|
||||
const roleId = assignCurrentRole.value?.roleId;
|
||||
if (!roleId || !assignSelectedIds.value.length) {
|
||||
useMessage().warning('请选择要关联的用户');
|
||||
return;
|
||||
}
|
||||
assignSubmitLoading.value = true;
|
||||
try {
|
||||
await assignUsersToRole(roleId, assignSelectedIds.value);
|
||||
useMessage().success('已关联 ' + assignSelectedIds.value.length + ' 名用户');
|
||||
showAssignUserDialog.value = false;
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '操作失败');
|
||||
} finally {
|
||||
assignSubmitLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量指定分组
|
||||
const handleBatchGroup = async () => {
|
||||
const ids = selectObjs.value || [];
|
||||
if (!ids.length) {
|
||||
useMessage().warning('请先勾选要设置分组的角色');
|
||||
return;
|
||||
}
|
||||
batchGroupLoading.value = true;
|
||||
try {
|
||||
await batchUpdateRoleGroup(ids, batchGroupName.value || '');
|
||||
useMessage().success('分组已更新');
|
||||
showBatchGroupDialog.value = false;
|
||||
batchGroupName.value = '';
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '操作失败');
|
||||
} finally {
|
||||
batchGroupLoading.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.role-group-name {
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.mb12 { margin-bottom: 12px; }
|
||||
.mb8 { margin-bottom: 8px; }
|
||||
.mt8 { margin-top: 8px; }
|
||||
.assign-user-tip { color: var(--el-text-color-secondary); font-size: 13px; }
|
||||
.dept-row { font-weight: 600; color: var(--el-text-color-primary); }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user