feat: 角色管理添加按钮级权限管理
This commit is contained in:
@@ -178,3 +178,8 @@ user:buttons:roleDataList: User Role Data List
|
|||||||
user:buttons:permisssionList: User Permisssion List
|
user:buttons:permisssionList: User Permisssion List
|
||||||
user:buttons:uploadAvatar: Upload Avatar
|
user:buttons:uploadAvatar: Upload Avatar
|
||||||
user:buttons:resetPassword: Reset Password
|
user:buttons:resetPassword: Reset Password
|
||||||
|
role:buttons:addPermission: Add Role Permission
|
||||||
|
role:buttons:deletePermission: Delete Role Permission
|
||||||
|
role:buttons:updatePermission: Update Role Permission
|
||||||
|
role:buttons:permissiomInfo: Role Permissiom Info
|
||||||
|
role:buttons:permissionDataList: Rolr Permission Data List
|
||||||
|
|||||||
@@ -178,3 +178,8 @@ user:buttons:roleDataList: 用户角色列表
|
|||||||
user:buttons:permisssionList: 用户权限列表
|
user:buttons:permisssionList: 用户权限列表
|
||||||
user:buttons:uploadAvatar: 上传头像
|
user:buttons:uploadAvatar: 上传头像
|
||||||
user:buttons:resetPassword: 重置密码
|
user:buttons:resetPassword: 重置密码
|
||||||
|
role:buttons:addPermission: 添加角色权限
|
||||||
|
role:buttons:deletePermission: 删除角色权限
|
||||||
|
role:buttons:updatePermission: 更新角色权限
|
||||||
|
role:buttons:permissiomInfo: 角色权限详情
|
||||||
|
role:buttons:permissionDataList: 角色权限列表
|
||||||
|
|||||||
@@ -318,6 +318,15 @@ export const deleteRoleAPI = (id: string) => {
|
|||||||
return http.request<null>("post", `/api/role/delete/${id}`);
|
return http.request<null>("post", `/api/role/delete/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**批量删除角色 */
|
||||||
|
export const deleteRoleListAPI = (ids: string[]) => {
|
||||||
|
return http.request<null>("post", `/api/role/deleteList`, {
|
||||||
|
data: {
|
||||||
|
ids
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// --------------------------用户相关--------------------------------------
|
// --------------------------用户相关--------------------------------------
|
||||||
|
|
||||||
/**添加用户参数 */
|
/**添加用户参数 */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { FormRules } from "element-plus";
|
|||||||
import { getDepartmentListAPI } from "@/api/system";
|
import { getDepartmentListAPI } from "@/api/system";
|
||||||
import type { DepartmentInfo } from "types/system";
|
import type { DepartmentInfo } from "types/system";
|
||||||
import { usePublicHooks } from "../../hooks";
|
import { usePublicHooks } from "../../hooks";
|
||||||
|
import { handleTree } from "@pureadmin/utils";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "SystemRoleForm"
|
name: "SystemRoleForm"
|
||||||
@@ -53,7 +54,9 @@ function getRef() {
|
|||||||
const getDepartments = async () => {
|
const getDepartments = async () => {
|
||||||
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
departments.value = formatHigherOptions(res.data.result);
|
departments.value = formatHigherOptions(
|
||||||
|
handleTree(res.data.result, "id", "parent_id")
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
departments.value = [];
|
departments.value = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import Close from "@iconify-icons/ep/close";
|
|||||||
import Check from "@iconify-icons/ep/check";
|
import Check from "@iconify-icons/ep/check";
|
||||||
import { onBeforeRouteUpdate } from "vue-router";
|
import { onBeforeRouteUpdate } from "vue-router";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
import { hasAuth } from "@/utils/auth";
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "SystemRole"
|
name: "SystemRole"
|
||||||
});
|
});
|
||||||
@@ -51,8 +52,8 @@ const {
|
|||||||
curRow,
|
curRow,
|
||||||
loading,
|
loading,
|
||||||
columns,
|
columns,
|
||||||
rowStyle,
|
|
||||||
dataList,
|
dataList,
|
||||||
|
selectedNum,
|
||||||
treeData,
|
treeData,
|
||||||
treeProps,
|
treeProps,
|
||||||
isLinkage,
|
isLinkage,
|
||||||
@@ -61,8 +62,11 @@ const {
|
|||||||
isSelectAll,
|
isSelectAll,
|
||||||
treeSearchValue,
|
treeSearchValue,
|
||||||
departments,
|
departments,
|
||||||
|
rowStyle,
|
||||||
onSearch,
|
onSearch,
|
||||||
resetForm,
|
resetForm,
|
||||||
|
onSelectionCancel,
|
||||||
|
onbatchDel,
|
||||||
openDialog,
|
openDialog,
|
||||||
handleMenu,
|
handleMenu,
|
||||||
handleSave,
|
handleSave,
|
||||||
@@ -71,8 +75,9 @@ const {
|
|||||||
transformI18n,
|
transformI18n,
|
||||||
onQueryChanged,
|
onQueryChanged,
|
||||||
handleSizeChange,
|
handleSizeChange,
|
||||||
handleCurrentChange
|
handleCurrentChange,
|
||||||
} = useRole(treeRef);
|
handleSelectionChange
|
||||||
|
} = useRole(treeRef, tableRef);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
useResizeObserver(contentRef, async () => {
|
useResizeObserver(contentRef, async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@@ -180,6 +185,7 @@ onBeforeRouteUpdate((to, from, next) => {
|
|||||||
>
|
>
|
||||||
<template #buttons>
|
<template #buttons>
|
||||||
<el-button
|
<el-button
|
||||||
|
v-if="hasAuth('role:btn:add')"
|
||||||
type="primary"
|
type="primary"
|
||||||
:icon="useRenderIcon(AddFill)"
|
:icon="useRenderIcon(AddFill)"
|
||||||
@click="openDialog()"
|
@click="openDialog()"
|
||||||
@@ -188,8 +194,42 @@ onBeforeRouteUpdate((to, from, next) => {
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot="{ size, dynamicColumns }">
|
<template v-slot="{ size, dynamicColumns }">
|
||||||
|
<div
|
||||||
|
v-if="selectedNum > 0"
|
||||||
|
v-motion-fade
|
||||||
|
class="bg-[var(--el-fill-color-light)] w-full h-[46px] mb-2 pl-4 flex items-center"
|
||||||
|
>
|
||||||
|
<div class="flex-auto">
|
||||||
|
<span
|
||||||
|
style="font-size: var(--el-font-size-base)"
|
||||||
|
class="text-[rgba(42,46,54,0.5)] dark:text-[rgba(220,220,242,0.5)]"
|
||||||
|
>
|
||||||
|
已选 {{ selectedNum }} 项
|
||||||
|
</span>
|
||||||
|
<el-button type="primary" text @click="onSelectionCancel">
|
||||||
|
{{ t("buttons:Deselect") }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-popconfirm
|
||||||
|
v-if="hasAuth('role:btn:delete')"
|
||||||
|
title="是否确认删除?"
|
||||||
|
@confirm="onbatchDel"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
text
|
||||||
|
class="mr-1"
|
||||||
|
:disabled="selectedNum < 0 || hasAuth('role:btn:delete')"
|
||||||
|
>
|
||||||
|
{{ t("buttons:DeleteInBatches") }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</div>
|
||||||
<pure-table
|
<pure-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
row-key="id"
|
||||||
align-whole="center"
|
align-whole="center"
|
||||||
showOverflowTooltip
|
showOverflowTooltip
|
||||||
table-layout="auto"
|
table-layout="auto"
|
||||||
@@ -208,6 +248,7 @@ onBeforeRouteUpdate((to, from, next) => {
|
|||||||
background: 'var(--el-fill-color-light)',
|
background: 'var(--el-fill-color-light)',
|
||||||
color: 'var(--el-text-color-primary)'
|
color: 'var(--el-text-color-primary)'
|
||||||
}"
|
}"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
@page-size-change="handleSizeChange"
|
@page-size-change="handleSizeChange"
|
||||||
@page-current-change="handleCurrentChange"
|
@page-current-change="handleCurrentChange"
|
||||||
>
|
>
|
||||||
@@ -217,6 +258,7 @@ onBeforeRouteUpdate((to, from, next) => {
|
|||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
:size="size"
|
:size="size"
|
||||||
|
:disabled="!hasAuth('role:btn:update')"
|
||||||
:icon="useRenderIcon(EditPen)"
|
:icon="useRenderIcon(EditPen)"
|
||||||
@click="openDialog('修改', row)"
|
@click="openDialog('修改', row)"
|
||||||
>
|
>
|
||||||
@@ -232,6 +274,7 @@ onBeforeRouteUpdate((to, from, next) => {
|
|||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
:size="size"
|
:size="size"
|
||||||
|
:disabled="!hasAuth('role:btn:delete')"
|
||||||
:icon="useRenderIcon(Delete)"
|
:icon="useRenderIcon(Delete)"
|
||||||
>
|
>
|
||||||
{{ t("buttons:Delete") }}
|
{{ t("buttons:Delete") }}
|
||||||
@@ -243,6 +286,7 @@ onBeforeRouteUpdate((to, from, next) => {
|
|||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
:size="size"
|
:size="size"
|
||||||
|
:disabled="!hasAuth('role:btn:permissionInfo')"
|
||||||
:icon="useRenderIcon(Menu)"
|
:icon="useRenderIcon(Menu)"
|
||||||
@click="handleMenu(row)"
|
@click="handleMenu(row)"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { message } from "@/utils/message";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
deleteRoleAPI,
|
deleteRoleAPI,
|
||||||
|
deleteRoleListAPI,
|
||||||
getPermissionListAPI,
|
getPermissionListAPI,
|
||||||
getRoleListAPI,
|
getRoleListAPI,
|
||||||
postAddRoleAPI,
|
postAddRoleAPI,
|
||||||
@@ -26,7 +27,7 @@ import type {
|
|||||||
RolePermissionInfo
|
RolePermissionInfo
|
||||||
} from "types/system";
|
} from "types/system";
|
||||||
|
|
||||||
export const useRole = (treeRef: Ref) => {
|
export const useRole = (treeRef: Ref, tableRef: Ref) => {
|
||||||
/**查询表单 */
|
/**查询表单 */
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: "",
|
name: "",
|
||||||
@@ -47,6 +48,10 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
* 加载状态
|
* 加载状态
|
||||||
*/
|
*/
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
/**
|
||||||
|
* 已选数量
|
||||||
|
*/
|
||||||
|
const selectedNum = ref<number>(0);
|
||||||
/**
|
/**
|
||||||
* 标签样式
|
* 标签样式
|
||||||
*/
|
*/
|
||||||
@@ -87,6 +92,12 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
/**是否全选 */
|
/**是否全选 */
|
||||||
const isSelectAll = ref<boolean>(false);
|
const isSelectAll = ref<boolean>(false);
|
||||||
const columns: TableColumnList = [
|
const columns: TableColumnList = [
|
||||||
|
{
|
||||||
|
label: "勾选列", // 如果需要表格多选,此处label必须设置
|
||||||
|
type: "selection",
|
||||||
|
fixed: "left",
|
||||||
|
reserveSelection: true // 数据刷新后保留选项
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "角色名称",
|
label: "角色名称",
|
||||||
prop: "name",
|
prop: "name",
|
||||||
@@ -150,7 +161,10 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
dataList.value = data.data.result;
|
dataList.value = data.data.result;
|
||||||
pagination.total = data.data.total;
|
pagination.total = data.data.total;
|
||||||
pagination.currentPage = data.data.page;
|
pagination.currentPage = data.data.page;
|
||||||
|
pagination.pageSize = data.data.pageSize;
|
||||||
|
message(data.msg, {
|
||||||
|
type: data.success ? "success" : "error"
|
||||||
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
@@ -171,22 +185,61 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
dataList.value = data.result;
|
dataList.value = data.result;
|
||||||
pagination.total = data.total;
|
pagination.total = data.total;
|
||||||
pagination.currentPage = data.page;
|
pagination.currentPage = data.page;
|
||||||
|
pagination.pageSize = res.data.pageSize;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**处理每页数量变化 */
|
/**
|
||||||
|
* 处理页码变化
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
const handleCurrentChange = async (val: number) => {
|
const handleCurrentChange = async (val: number) => {
|
||||||
|
loading.value = true;
|
||||||
const res = await getRoleListAPI({
|
const res = await getRoleListAPI({
|
||||||
page: val,
|
page: val,
|
||||||
pageSize: pagination.pageSize
|
pageSize: pagination.pageSize,
|
||||||
|
...toRaw(form)
|
||||||
});
|
});
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
const data = res.data;
|
dataList.value = res.data.result;
|
||||||
dataList.value = data.result;
|
pagination.total = res.data.total;
|
||||||
pagination.total = data.total;
|
pagination.currentPage = res.data.page;
|
||||||
pagination.currentPage = data.page;
|
pagination.pageSize = res.data.pageSize;
|
||||||
}
|
}
|
||||||
|
message(res.msg, {
|
||||||
|
type: res.success ? "success" : "error"
|
||||||
|
});
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
/** 当CheckBox选择项发生变化时会触发该事件 */
|
||||||
|
const handleSelectionChange = async (val: any) => {
|
||||||
|
selectedNum.value = val.length;
|
||||||
|
// 重置表格高度
|
||||||
|
tableRef.value.setAdaptive();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 取消选择 */
|
||||||
|
const onSelectionCancel = async () => {
|
||||||
|
selectedNum.value = 0;
|
||||||
|
// 用于多选表格,清空用户的选择
|
||||||
|
tableRef.value.getTableRef().clearSelection();
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
*/
|
||||||
|
const onbatchDel = async () => {
|
||||||
|
// 返回当前选中的行
|
||||||
|
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||||
|
const res = await deleteRoleListAPI(getKeyList(curSelected, "id"));
|
||||||
|
if (res.success) {
|
||||||
|
message(res.msg, {
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
tableRef.value.getTableRef().clearSelection();
|
||||||
|
onSearch();
|
||||||
|
} else {
|
||||||
|
message(res.msg, { type: "error", duration: 5000 });
|
||||||
|
}
|
||||||
|
};
|
||||||
const handleDelete = async (row: RoleInfo) => {
|
const handleDelete = async (row: RoleInfo) => {
|
||||||
const res = await deleteRoleAPI(row.id);
|
const res = await deleteRoleAPI(row.id);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
@@ -237,7 +290,6 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
}
|
}
|
||||||
FormRef.validate(async (valid: any) => {
|
FormRef.validate(async (valid: any) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
console.log("curData", curData);
|
|
||||||
// 表单规则校验通过
|
// 表单规则校验通过
|
||||||
if (title === "新增") {
|
if (title === "新增") {
|
||||||
// 实际开发先调用新增接口,再进行下面操作
|
// 实际开发先调用新增接口,再进行下面操作
|
||||||
@@ -335,13 +387,15 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
const getDepartments = async () => {
|
const getDepartments = async () => {
|
||||||
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
departments.value = formatHigherOptions(res.data.result);
|
departments.value = formatHigherOptions(
|
||||||
|
handleTree(res.data.result, "id", "parent_id")
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
departments.value = [];
|
departments.value = [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const formatHigherOptions = treeList => {
|
const formatHigherOptions = (treeList: any) => {
|
||||||
// 根据返回数据的status字段值判断追加是否禁用disabled字段,返回处理后的树结构,用于上级部门级联选择器的展示
|
// 根据返回数据的status字段值判断追加是否禁用disabled字段,返回处理后的树结构,用于上级部门级联选择器的展示(实际开发中也是如此,不可能前端需要的每个字段后端都会返回,这时需要前端自行根据后端返回的某些字段做逻辑处理)
|
||||||
if (!treeList || !treeList.length) return;
|
if (!treeList || !treeList.length) return;
|
||||||
const newTreeList = [];
|
const newTreeList = [];
|
||||||
for (let i = 0; i < treeList.length; i++) {
|
for (let i = 0; i < treeList.length; i++) {
|
||||||
@@ -379,6 +433,7 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
loading,
|
loading,
|
||||||
columns,
|
columns,
|
||||||
dataList,
|
dataList,
|
||||||
|
selectedNum,
|
||||||
treeData,
|
treeData,
|
||||||
treeProps,
|
treeProps,
|
||||||
isLinkage,
|
isLinkage,
|
||||||
@@ -390,6 +445,8 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
rowStyle,
|
rowStyle,
|
||||||
onSearch,
|
onSearch,
|
||||||
resetForm,
|
resetForm,
|
||||||
|
onSelectionCancel,
|
||||||
|
onbatchDel,
|
||||||
openDialog,
|
openDialog,
|
||||||
handleMenu,
|
handleMenu,
|
||||||
handleSave,
|
handleSave,
|
||||||
@@ -398,6 +455,7 @@ export const useRole = (treeRef: Ref) => {
|
|||||||
transformI18n,
|
transformI18n,
|
||||||
onQueryChanged,
|
onQueryChanged,
|
||||||
handleSizeChange,
|
handleSizeChange,
|
||||||
handleCurrentChange
|
handleCurrentChange,
|
||||||
|
handleSelectionChange
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user