当前位置: 首页 > news >正文

Nuxt3 全栈作品【通用信息管理系统】角色管理(含配置权限 -- 菜单权限 vs 操作权限)

最终效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

前端代码

pages/system/role/list.vue

<script lang="ts" setup>
import { Model } from "./model";
import { superAdmin, handleTable_initData } from "./initData";import type { TreeInstance, CheckboxValueType } from "element-plus";const PageConfig = {//被操作实体的名称entity: "role",entityName: "角色",hideDetailBtn: true,
};
const dialogVisible_edit_permission = ref(false);
const activeTab = ref("menu");
const callbackMessage = ref({show: false,valid: true,content: "",
});
let handle_row: any = {};
const menuStore = useMenuStore();
const ref_menuTree = ref<TreeInstance>();
const ref_table = ref(null);
const handle_tableData = reactive(handleTable_initData);// 按钮 -- 配置权限
const edit_permission = async (row: any) => {activeTab.value = "menu";handle_row = JSON.parse(JSON.stringify(row));dialogVisible_edit_permission.value = true;await nextTick();let permissionDic = handle_row.permissionDic;let menu_permission = permissionDic.menu || [];ref_menuTree.value!.setCheckedKeys(menu_permission);let handle_permission = permissionDic.handle || [];handle_tableData.forEach((item: any) => {item.permissionList = [];item.checkAll = false;item.isIndeterminate = false;let baseList = [];if (!item.hideAdd) {baseList.push(`${item.entity}:add`);}if (!item.hideEdit) {baseList.push(`${item.entity}:edit`);}if (!item.hideDel) {baseList.push(`${item.entity}:del`);}if (!item.hideDetail) {baseList.push(`${item.entity}:detail`);}baseList.forEach((item_temp: any) => {let index = handle_permission.indexOf(item_temp);if (index > -1) {item.permissionList.push(item_temp);handle_permission.splice(index, 1);}});if (Array.isArray(item.extra_handleList)) {item.extra_handleList.forEach((item_temp: any) => {let target = `${item.entity}:${item_temp.code}`;let index = handle_permission.indexOf(target);if (index > -1) {item.permissionList.push(target);handle_permission.splice(index, 1);}});}getAll_handlePermissionList(item);if (isEqualArray_simple(item.AllPermissionList, item.permissionList)) {item.checkAll = true;}if (item.permissionList.length > 0 &&item.permissionList.length < item.AllPermissionList.length) {item.isIndeterminate = true;}});
};// 按钮 -- 保存配置的权限
const save_permission = async () => {let handle_permissionList: any = [];handle_tableData.forEach((item: any) => {handle_permissionList.push(...item.permissionList);});let permissionDic = {menu: ref_menuTree.value!.getCheckedNodes(false, true).map((menuNode) => menuNode.path),handle: handle_permissionList,};// 使用拦截器自动添加认证头try {await $fetch(`/api/role/edit`, {body: {...handle_row,permissionDic: permissionDic,},method: "POST",});callbackMessage.value = {show: true,valid: true,content: "操作成功",};setTimeout(() => {dialogVisible_edit_permission.value = false;ref_table.value && (ref_table.value as any).saveOK();}, 500);} catch (error) {console.log(error);}
};// 获取所有的操作权限
const getAll_handlePermissionList = (row: any) => {if (Array.isArray(row.AllPermissionList) &&row.AllPermissionList.length > 0) {return row.AllPermissionList;}let AllPermissionList = [];if (!row.hideAdd) {AllPermissionList.push(`${row.entity}:add`);}if (!row.hideEdit) {AllPermissionList.push(`${row.entity}:edit`);}if (!row.hideDel) {AllPermissionList.push(`${row.entity}:del`);}if (!row.hideDetail) {AllPermissionList.push(`${row.entity}:detail`);}if (row.extra_handleList) {AllPermissionList.push(...row.extra_handleList.map((item: any) => `${row.entity}:${item.code}`));}row.AllPermissionList = AllPermissionList;return AllPermissionList;
};// 配置权限弹窗中 -- 操作权限 -- 勾选权限子项的回调
const handleCheckAllChange = (val: CheckboxValueType, row: any) => {const { permissionList } = toRefs(row);permissionList.value = val? row.AllPermissionList || getAll_handlePermissionList(row): [];row.isIndeterminate = false;
};// 配置权限弹窗中 -- 操作权限 -- 勾选操作对象的回调
const handleCheckedChange = (value: CheckboxValueType[], row: any) => {let AllPermissionList_length = (row.AllPermissionList || getAll_handlePermissionList(row)).length;const checkedCount = value.length;row.checkAll = checkedCount === AllPermissionList_length;row.isIndeterminate =checkedCount > 0 && checkedCount < AllPermissionList_length;
};// 列表加载完成的回调
const getList_done = async (data: any[], total: number) => {if (total === 0) {// 自动创建超级管理员let new_addsuerAdmin = debounce(addsuerAdmin);new_addsuerAdmin();setTimeout(() => {ref_table.value && (ref_table.value as any).getList();}, 1000);}
};// 访问接口--新增超级管理员
const addsuerAdmin = async () => {await $fetch(`/api/role/add`, {body: superAdmin,method: "POST",});
};
</script>
<template><S-comMangeInforef="ref_table":Model="Model":PageConfig="PageConfig"@getList_done="getList_done"><template #myHandle="{ row }"><el-buttonv-if="row.name !== '超级管理员'"linktype="primary"size="small"@click="edit_permission(row)">配置权限</el-button></template></S-comMangeInfo><el-dialogv-model="dialogVisible_edit_permission"title="配置权限"width="600"><el-tabs type="border-card" v-model="activeTab"><el-tab-pane label="菜单权限" name="menu"><el-treeref="ref_menuTree"show-checkbox:data="menuStore.menu_list"node-key="path"default-expand-all:expand-on-click-node="false":indent="40"></el-tree></el-tab-pane><el-tab-pane label="操作权限" name="handle"><el-table :data="handle_tableData" border><el-table-columnlabel="操作对象"prop="entityName"align="center"width="100"><template #default="scope"><el-checkboxv-model="scope.row.checkAll":indeterminate="scope.row.isIndeterminate"@change="handleCheckAllChange($event, scope.row)">{{ scope.row.entityName }}</el-checkbox></template></el-table-column><el-table-column label="操作方式" align="center"><template #default="scope"><el-checkbox-groupv-model="scope.row.permissionList"@change="handleCheckedChange($event, scope.row)"class="flex flex-wrap"><el-checkboxv-if="!scope.row.hideAdd":label="scope.row.add_nickName || '新增'":value="`${scope.row.entity}:add`"/><el-checkboxv-if="!scope.row.hideEdit":label="scope.row.edit_nickName || '编辑'":value="`${scope.row.entity}:edit`"/><el-checkboxv-if="!scope.row.hideDel":label="scope.row.del_nickName || '删除'":value="`${scope.row.entity}:del`"/><el-checkboxv-if="!scope.row.hideDetail"label="详情":value="`${scope.row.entity}:detail`"/><el-checkboxv-for="item in scope.row.extra_handleList":label="item.name":value="`${scope.row.entity}:${item.code}`"/></el-checkbox-group></template></el-table-column></el-table></el-tab-pane></el-tabs><template #footer><div class="dialog-footer"><el-button @click="dialogVisible_edit_permission = false">取消</el-button><el-button type="primary" @click="save_permission"> 保存 </el-button></div></template><S-msgWin :msg="callbackMessage" :duration="1000" /></el-dialog>
</template>

pages/system/role/model.ts

export const Model: {[key: string]: any;
} = {name: {label: "角色名称",search: true,require: true,},createdAt: {label: "创建时间",formHide: "all",},updatedAt: {label: "修改时间",formHide: "all",},
};

pages/system/role/initData.ts

// 操作权限
export const handleTable_initData = [{entity: "user",entityName: "用户",extra_handleList: [{name: "重置密码",code: "resetPassword",},],permissionList: [],},{entity: "menu",entityName: "菜单",add_nickName: "添加",edit_nickName: "修改",hideDetail: true,extra_handleList: [{name: "添加顶级菜单",code: "addTop",},],permissionList: [],},{entity: "permission",entityName: "权限",permissionList: [],},{entity: "role",entityName: "角色",extra_handleList: [{name: "配置权限",code: "setPermission",},],permissionList: [],},{entity: "dic",entityName: "字典",hideDetail: true,permissionList: [],},
];export const superAdmin = {name: "超级管理员",
};

依赖组件 S-comMangeInfo

https://blog.csdn.net/weixin_41192489/article/details/149768541

依赖组件 S-msgWin

https://blog.csdn.net/weixin_41192489/article/details/149717948

接口开发

server/models/role.ts

import { defineMongooseModel } from "#nuxt/mongoose";
export interface RoleDataProps {name: string;permissionDic: Object;createdAt: string;updatedAt: string;
}
export const RoleSchema = defineMongooseModel<RoleDataProps>("Role",{name: { type: String, unique: true },permissionDic: { type: Object },},{timestamps: true,toJSON: {// 过滤掉敏感字段transform(doc: any, ret: Record<string, any>, options: any) {delete ret.__v;},},}
);

validators/role.ts

import { z } from "zod";
export const roleCreateSchema = z.object({_id: z.string().optional(),name: z.string(),permissionDic: z.object({menu: z.array(z.string()),handle: z.array(z.string()),}).optional(),
});
export const roleUpdateSchema = roleCreateSchema.omit({});
export type RoleCreateType = z.infer<typeof roleCreateSchema>;

server/api/role/list.ts

import type { SortOrder } from "mongoose";
export default defineEventHandler(async (event) => {const config = {// 查询的数据库表Schema: RoleSchema,// 列表展示的字段fieldList: ["name", "permissionDic", "createdAt", "updateAt"],};const queryObj = getQuery(event);const { orderBy = "createdAt", order = "desc" } = queryObj;const customSort = {[orderBy as string]: order as SortOrder,};const currentPage = Number(queryObj.currentPage) || 1;const pageSize = Number(queryObj.pageSize) || 10;const skip = (currentPage - 1) * pageSize;const findCondition: {[key: string]: any;} = {};if (queryObj.name) {findCondition.name = {// 模糊匹配$regex: queryObj.name,};}const res_list = await config.Schema.find(findCondition).select(config.fieldList).skip(skip).limit(pageSize).sort(customSort).lean();const total = await config.Schema.find(findCondition).countDocuments();return {data: res_list,total,pageSize,currentPage,};
});

server/api/role/add.post.ts

import { roleCreateSchema } from "~/validators/role";
export default defineEventHandler(async (event) => {const result = await runValidate(roleCreateSchema, event);const { name } = result.data;// findOne 是 Mongoose 的方法,用于查找符合条件的第一条数据。const oldData = await RoleSchema.findOne({name: name,}).lean();if (oldData) {throw createError({statusCode: 409,statusMessage: "数据已存在,请修改后重试",});}const newData = await RoleSchema.create(result.data);return newData;
});

server/api/role/edit.post.ts

import { roleUpdateSchema } from "~/validators/role";
export default defineEventHandler(async (event) => {const result = await runValidate(roleUpdateSchema, event);const newData = RoleSchema.findByIdAndUpdate(result.data._id, result.data, {new: true,});return newData;
});

server/api/role/[id].delete.ts

export default defineEventHandler((event) => {const id = getRouterParam(event, "id");const result = RoleSchema.findByIdAndDelete(id);return result;
});

server/api/role/all.ts

// 查询全量数据
export default defineEventHandler(async () => {try {const res_list = await RoleSchema.find({}).lean();return {data: res_list,};} catch (error) {throw createError({statusCode: 500,statusMessage: "查询全量角色信息失败",});}
});

server/api/role/[id].ts

根据 id 查询数据详情

export default defineEventHandler((event) => {const id = getRouterParam(event, "id");const result = RoleSchema.findById(id);return result;
});
http://www.dtcms.com/a/306873.html

相关文章:

  • 差分数组前缀和优化,降低时间复杂度
  • vue+elementui+vueCropper裁剪上传图片背景颜色为黑色解决方案
  • ‌我的第一个开源项目:跃动的心
  • 物流分拣漏检率↓78%!陌讯动态光流算法在包裹移动识别的技术突破
  • GCC链接技术深度解析:性能与空间优化
  • [mcp: McpSchema]-源码分析
  • 第1课:向量与矩阵运算
  • 搭建实时足球比分系统从零到一的实战指南
  • Day 4-1: 机器学习算法全面总结
  • 全新AI工具小程序源码 全开源(源码下载)
  • 深入浅出:在 Spring Boot 中构建实时应用 - 全面掌握 WebSocket
  • 解决 Docker 报错 “exec: no such file or directory”
  • 文件权限值的表示方法
  • PHP/Java/Python实现:如何有效防止恶意文件上传
  • Go 语言make函数
  • 输电线路绝缘子泄漏电流在线监测装置的技术解析与应用价值
  • Python读取获取波形图波谷/波峰
  • Directory Opus 使用优化
  • 30道JS高频经典笔试题集合+详解(一)
  • 视觉系统引导冲床冲压:工业自动化的“智能之眼”
  • Dify 从入门到精通(第 4/100 篇):快速上手 Dify 云端:5 分钟创建第一个应用
  • AI培训项目《人工智能大模型应用工程师》课程学习大纲分享!
  • 【sklearn(01)】数据集加载、划分,csv文件创建,特征工程,无量纲化
  • 【编号65】广西地理基础数据(道路、水系、四级行政边界、地级城市、DEM等)
  • 我的世界模组开发教程——资源(1)
  • JeecgBoot(1):前后台环境搭建
  • C#_创建自己的MyList列表
  • 汽车电子控制系统开发的整体安全理念
  • SOA增益谱与ASE光谱的区别
  • SSRF漏洞基础