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

Vue3.5 企业级管理系统实战(十七):角色管理

本篇主要探讨角色管理功能,其中菜单权限这里先不实现,后续在菜单管理中再进行实现。接口部分依然是使用 Apifox mock 的。

1 角色 api

在 src/api/role.ts 中添加角色相关 api,代码如下:

//src/api/role.ts
import service from "./config/request";
import type { ApiResponse } from "./type";export interface IRole {id: number;name: string;description: string;is_default: number;
}//定义state类型
export interface IRoleState {roles: IRole[];count: number;
}export interface IRoleParams {pageNum: number;pageSize: number;
}// 获取角色
export const getRoles = (params = { pageNum: 0, pageSize: 10 }
): Promise<ApiResponse<IRoleState>> => {return service.get("/role", {params});
};// 新增角色
export const addRole = (data: IRole): Promise<ApiResponse> => {return service.post("/role", data);
};// 更新角色
export const updateRole = (id: number,data: Partial<IRole>
): Promise<ApiResponse> => {return service.put("/role/" + id, data);
};// 删除角色
export const removeRole = (id: number): Promise<ApiResponse> => {return service.delete("/role/" + id);
};

2 角色 store

在 src/stores/role.ts 中添加角色相关方法,代码如下:

//src/stores/role.ts
import type { IRole, IRoleParams, IRoleState } from "@/api/role";
import {getRoles as getRolesApi,addRole as addRoleApi,updateRole as updateRoleApi,removeRole as removeRoleApi
} from "@/api/role";
type WithRoleParmas = IRole & IRoleParams;export const useRoleStore = defineStore("role", () => {//状态const state = reactive<IRoleState>({roles: [],count: 0});//获取角色const getRoles = async (params: IRoleParams) => {const res = await getRolesApi(params);const { data } = res;state.roles = data.roles;state.count = data.count;};//添加角色const addRole = async (data: WithRoleParmas) => {const { pageNum, pageSize, ...obj } = data;const res = await addRoleApi(obj);if (res.code == 0) {getRoles({ pageNum, pageSize });}};//修改角色const updateRole = async (data: WithRoleParmas) => {const { pageNum, pageSize, ...obj } = data;const res = await updateRoleApi(obj.id, obj);if (res.code == 0) {getRoles({ pageNum, pageSize });}};//删除角色const removeRole = async (data: WithRoleParmas) => {const { pageNum, pageSize, id } = data;const res = await removeRoleApi(id);if (res.code == 0) {getRoles({ pageNum, pageSize });}};return { getRoles, addRole, updateRole, removeRole, state };
});

3 角色管理页面开发

角色管理页面文件结构如下图所示:

3.1 角色处理函数封装

在 src/views/system/role/roleHelpers.ts 中封装角色处理的相关操作函数(增删改查),代码如下:

//src/views/system/role/roleHelpers.ts
// 从 @/api/role 模块中导入 IRole 类型
import type { IRole } from "@/api/role";
// 从 @/stores/role 模块中导入 useRoleStore 函数
import { useRoleStore } from "@/stores/role";/*** 自定义组合式函数,用于处理角色相关的操作* @param pageSize - 每页显示的记录数,使用 Ref 类型* @param pageNum - 当前页码,使用 Ref 类型* @returns 包含角色操作方法和状态的对象*/
export const useRoleHelpers = ({pageSize,pageNum
}: {pageSize: Ref<number>;pageNum: Ref<number>;
}) => {// 获取当前组件实例的代理对象const { proxy } = getCurrentInstance()!;// 定义编辑类型,-1 表示初始状态,0 表示编辑,1 表示新增const editType = ref(-1);// 定义模态框的可见状态const visible = ref(false);// 定义要编辑的数据,初始值为 undefinedconst editData = ref<IRole | undefined>(undefined);// 获取角色状态管理仓库的实例const store = useRoleStore();// 计算面板的标题,根据编辑类型决定显示“增加角色”还是“修改角色”const panelTitle = computed(() =>editType.value == 1 ? "增加角色" : "修改角色");/*** 处理编辑角色的操作* @param role - 要编辑的角色对象*/const handleEditRole = (role: IRole) => {// 设置编辑类型为 0,表示编辑editType.value = 0;// 复制要编辑的角色数据editData.value = { ...role };// 显示模态框visible.value = true;};/*** 处理添加新角色的操作*/const hanleAddRole = () => {// 设置编辑类型为 1,表示新增editType.value = 1;// 初始化要编辑的数据为空的角色对象editData.value = {} as IRole;// 显示模态框visible.value = true;};/*** 添加新角色的异步方法* @param data - 要添加的角色数据*/const addNewRole = async (data: IRole) => {// 调用仓库的 addRole 方法添加角色,并传递分页信息await store.addRole({...data,pageNum: pageNum.value,pageSize: pageSize.value});// 显示成功提示信息proxy?.$message.success("角色添加成功");// 隐藏模态框visible.value = false;};/*** 编辑角色的异步方法* @param data - 要编辑的角色数据*/const editRow = async (data: IRole) => {// 调用仓库的 updateRole 方法更新角色,并传递分页信息await store.updateRole({...data,pageNum: pageNum.value,pageSize: pageSize.value});// 显示成功提示信息proxy?.$message.success("角色编辑成功");// 隐藏模态框visible.value = false;};/*** 处理提交表单的异步方法,根据编辑类型调用不同的处理方法* @param data - 表单提交的角色数据*/const handleSubmit = async (data: IRole) => {if (editType.value === 1) {// 如果是新增类型,调用 addNewRole 方法await addNewRole(data);} else {// 如果是编辑类型,调用 editRow 方法await editRow(data);}};/*** 处理删除角色的异步方法* @param data - 要删除的角色数据*/const handleRemove = async (data: IRole) => {try {// 弹出确认对话框,确认是否删除角色await proxy?.$confirm("你确定删除" + data.name + "角色吗?", {type: "warning"});// 调用仓库的 removeRole 方法删除角色,并传递分页信息await store.removeRole({...data,pageNum: pageNum.value,pageSize: pageSize.value});// 显示成功提示信息proxy?.$message.success("角色删除成功");} catch {// 如果用户取消删除,显示取消提示信息proxy?.$message.info("取消删除");}};// 返回包含角色操作方法和状态的对象return {handleSubmit,handleRemove,handleEditRole,hanleAddRole,panelTitle,editType,visible,editData};
};

3.2 editorRole 组件封装

在 src/views/system/role/components/editorRole.vue 中,对角色的新增编辑页面进行封装,代码如下:

//src/views/system/role/components/editorRole.vue 
<template><el-form :model="editData" label-width="auto" style="max-width: 600px"><el-form-item label="角色名称"><el-input v-model="editData.name" /></el-form-item><el-form-item label="描述"><el-input v-model="editData.description" /></el-form-item><el-form-item label="是否是默认角色 "><el-switchv-model="editData.is_default":active-value="1":inactive-value="0"></el-switch></el-form-item><el-form-item><el-button type="primary" @click="submitForm">提交</el-button><el-button @click="handleReset">重置</el-button></el-form-item></el-form>
</template><script lang="ts" setup>
import type { IRole } from "@/api/role";
import type { PropType } from "vue";
import { ref, defineProps, watchEffect, defineEmits } from "vue";// 定义 editData 响应式变量,用于存储表单数据,初始值为空对象
const editData = ref({name: "",description: "",is_default: 0
});// 定义组件接收的 props
const { data, type } = defineProps({data: {// 指定 data 的类型为 IRole 对象type: Object as PropType<IRole>,// 如果未传入 data,默认返回空对象default: () => ({})},type: {// 指定 type 的类型为数字type: Number,// type 为必填项required: true}
});// 定义默认表单数据,用于重置表单
const defaultProps = {name: "",description: "",is_default: 0
};// 重置表单数据的函数,将默认数据和传入的 data 合并
const resetForm = () => {editData.value = { ...defaultProps, ...data };
};// 监听 data 的变化,当 data 改变时重置表单
watchEffect(() => {if (data) {resetForm();}
});// 定义自定义事件,用于向父组件发送表单数据
const emit = defineEmits(["submit"]);// 提交表单的函数,触发 submit 事件并传递表单数据
const submitForm = () => {emit("submit", editData.value);
};// 处理重置操作的函数,调用 resetForm 重置表单
const handleReset = () => {resetForm();
};
</script>

3.3 角色管理页面

修改 src/views/system/role/index.vue,编写角色管理静态页面,代码如下:

//src/views/system/role/index.vue
<template><div p-30px><h2>角色管理</h2><el-button @click="hanleAddRole">角色添加</el-button><el-table :data="roles" style="width: 100%"><el-table-column prop="id" label="角色id" width="180" /><el-table-column prop="name" label="角色名称" width="180" /><el-table-column prop="description" label="描述" /><el-table-columnprop="is_default"label=" 默认角色":formatter="formatter"/><el-table-column label="操作" fixed="right"><template #default="scope"><el-button link @click="handleEditRole(scope.row)">编辑</el-button><el-button link @click="handleRemove(scope.row)">删除</el-button></template></el-table-column></el-table><el-pagination:page-sizes="[1, 5, 10, 20]"layout="prev, pager, next, sizes, total":total="count":page-size="pageSize"@size-change="handleSizeChange"@current-change="handleCurrentChange"/><!-- 右侧面板组件,使用 v-model 绑定 visible 控制显示隐藏,设置标题 --><right-panel v-model="visible" :title="panelTitle"><!-- 角色编辑组件,传递编辑类型和编辑数据,监听 submit 事件 --><editor-role:type="editType":data="editData"@submit="handleSubmit"></editor-role></right-panel></div>
</template><script lang="ts" setup>
import type { IRole } from "@/api/role";
import { useRoleStore } from "@/stores/role";
import { useRoleHelpers } from "./roleHelpers";
import { ref, toRefs, watchEffect } from "vue";// 获取角色状态管理仓库实例
const store = useRoleStore();
// 当前页码,初始为 0
const pageNum = ref(0);
// 每页显示的记录数,初始为 10
const pageSize = ref(10);// 从 useRoleHelpers 组合式函数中解构出所需的方法和状态
const {handleSubmit,handleRemove,handleEditRole,hanleAddRole,panelTitle,editType,visible,editData
} = useRoleHelpers({ pageNum, pageSize });// 将仓库状态中的 count 和 roles 转换为响应式引用
const { count, roles } = toRefs(store.state);// 监听 pageNum 和 pageSize 的变化,当变化时重新获取角色数据
watchEffect(() => {store.getRoles({ pageNum: pageNum.value, pageSize: pageSize.value });
});// 处理每页显示记录数改变的方法
const handleSizeChange = (val: number) => {pageSize.value = val;
};// 处理当前页码改变的方法
const handleCurrentChange = (val: number) => {pageNum.value = val - 1;
};// 格式化是否为默认角色的显示内容
const formatter = (row: IRole) => {return row.is_default ? "是" : "否";
};
</script>

npm run dev 启动项目后,页面效果如下:

以上,就是角色管理的全部内容。

下一篇将继续探讨 用户管理,敬请期待~

相关文章:

  • WordPress_AdsProPlugin Sql注入漏洞复现(CVE-2024-13322)
  • vue3 computed方法传参数
  • 人工智能 计算智能模糊逻辑讲解
  • 【基于SSM+Vue+Mysql】健身房俱乐部管理系统(附源码+数据库脚本)
  • Kaggle——House Prices(房屋价格预测)简单实现
  • java springboot deepseek流式对话集成示例
  • 推荐系统架构设计
  • 计算机网络复习资料
  • 内存管理(C++)
  • Polygon Miden网络:具有客户端执行的边缘区块链
  • IBM BAW(原BPM升级版)使用教程:基本概念
  • Houdini制作烟雾消散并导入UE5
  • 数字孪生储能充电站,实现智慧能源设施全景管控
  • JDK 发展历史及其版本特性
  • Python训练打卡Day17
  • 基于 AI 的工程投标六随机五区间报价得分模型模拟计算
  • 云计算与大数据进阶 | 25、可扩展系统构建
  • 力扣面试150题--对称二叉树
  • 【大模型面试每日一题】Day 10:混合精度训练如何加速大模型训练?可能出现什么问题?如何解决?
  • MYSQL的DDL语言和单表查询
  • 债券市场“科技板”来了:哪些机构能尝鲜,重点支持哪些领域
  • 公积金利率降至历史最低!多项房地产利好政策落地,购房者置业成本又降了
  • 巴称击落多架印度“阵风”战机,专家:小规模冲突巴空军战力不落下风
  • 国新办将于5月8日10时就《民营经济促进法》有关情况举行新闻发布会
  • 象屿集团:对去化压力大、市场有效需求不足区域坚决暂停投资,打造多元上市路径
  • 这个接班巴菲特的男人,说不出一个打动人心的故事