vue3-实战-10-管理后台-权限管理之用户管理模块开发

news2024/11/28 9:38:22

目录

1-用户首页列表开发

1.1-需求原型分析

1.2-封装请求和数据类型

1.3-数据页面渲染和展示

1.4-点击搜索按钮搜索用户

1.5-点击重置按钮

2-新增编辑用户

2.1-原型需求分析

2.2-表单页面数据收集

 2.3-页面校验规则的定义

2.4-添加用户按钮编辑按钮逻辑

2.5-保存和取消用户信息逻辑

3-删除和批量删除用户

4-分配角色


1-用户首页列表开发

1.1-需求原型分析

       基本结构跟之前的商品管理模块的结构差不多,只不过这里多了一个按照用户名搜索用户,点击搜索就向服务器发送查询,点击重置,清空输入框内容,重新拉取用户列表。在页面加载的过程中,我们需要发送请求获取数据。

      列表页面需要使用到el-card组件;搜索输入那边需要使用到el-form组件并且使用行内form,属性:inline="true"

1.2-封装请求和数据类型

该模块所有的接口和数据类型全部定义在此章节,文章下面的模块不在单独定义接口和数据类型。文件src\api\acl\user\type.ts定义数据类型:

//账号信息的ts类型
export interface ResponseData {
  code: number
  message: string
  ok: boolean
}
//代表一个账号信息的ts类型
export interface User {
  id?: number
  createTime?: string
  updateTime?: string
  username?: string
  password?: string
  name?: string
  phone?: null
  roleName?: string
}
//数组包含全部的用户信息
export type Records = User[]
//获取全部用户信息接口返回的数据ts类型
export interface UserResponseData extends ResponseData {
  data: {
    records: Records
    total: number
    size: number
    current: number
    pages: number
  }
}

//代表一个职位的ts类型
export interface RoleData {
  id?: number
  createTime?: string
  updateTime?: string
  roleName: string
  remark: null
}
//全部职位的列表
export type AllRole = RoleData[]
//获取全部职位的接口返回的数据ts类型
export interface AllRoleResponseData extends ResponseData {
  data: {
    assignRoles: AllRole
    allRolesList: AllRole
  }
}

//给用户分配职位接口携带参数的ts类型
export interface SetRoleData {
  roleIdList: number[]
  userId: number
}

文件src\api\acl\user\index.ts定义请求服务端相关接口:
 

//用户管理模块的接口
import request from '@/utils/request'
import type {
  UserResponseData,
  User,
  AllRoleResponseData,
  SetRoleData,
} from './type'
//枚举地址
enum API {
  ALLUSER_URL = '/admin/acl/user/',  //获取全部已有用户账号信息
  ADDUSER_URL = '/admin/acl/user/save', //添加一个新的用户账号
  UPDATEUSER_URL = '/admin/acl/user/update',//更新已有的用户账号
  ALLROLEURL = '/admin/acl/user/toAssign/',//获取全部角色,当前账号拥有的角色接口
  SETROLE_URL = '/admin/acl/user/doAssignRole',//给已有的用户分配角色接口
  DELETEUSER_URL = '/admin/acl/user/remove/', //删除某一个账号
  DELETEALLUSER_URL = '/admin/acl/user/batchRemove',//批量删除的接口
}
//获取用户账号信息的接口
export const reqUserInfo = (page: number, limit: number, username: string) =>
  request.get<any, UserResponseData>(
    API.ALLUSER_URL + `${page}/${limit}/?username=${username}`,
  )
//添加用户与更新已有用户的接口
export const reqAddOrUpdateUser = (data: User) => {
  //携带参数有ID更新
  if (data.id) {
    return request.put<any, any>(API.UPDATEUSER_URL, data)
  } else {
    return request.post<any, any>(API.ADDUSER_URL, data)
  }
}
//获取全部角色以及包含当前用户的已有的角色
export const reqAllRole = (userId: number) =>
  request.get<any, AllRoleResponseData>(API.ALLROLEURL + userId)
//分配角色
export const reqSetUserRole = (data: SetRoleData) =>
  request.post<any, any>(API.SETROLE_URL, data)
//删除某一个账号的信息
export const reqRemoveUser = (userId: number) =>
  request.delete<any, any>(API.DELETEUSER_URL + userId)
//批量删除的接口
export const reqSelectUser = (idList: number[]) =>
  request.delete(API.DELETEALLUSER_URL, { data: idList })

1.3-数据页面渲染和展示

定义请求和接受服务器端返回的相关数据类型: 

import useLayOutSettingStore from '@/store/modules/setting'
import { ref, onMounted, reactive, nextTick } from 'vue';
import { reqSelectUser, reqRemoveUser, reqUserInfo, reqAddOrUpdateUser, reqAllRole, reqSetUserRole } from '@/api/acl/user'
import type { SetRoleData, UserResponseData, Records, User, AllRoleResponseData, AllRole } from '@/api/acl/user/type';
import { ElMessage } from 'element-plus';

let pageNo = ref<number>(1);//默认页码
let pageSize = ref<number>(5);//一页展示几条数据
let total = ref<number>(0);//用户总个数
let userArr = ref<Records>([]);//存储全部用户的数组
//组件挂载完毕
onMounted(() => {
    getHasUser();
});
//获取全部已有的用户信息
const getHasUser = async (pager = 1) => {
    //收集当前页码
    pageNo.value = pager;
    let result: UserResponseData = await reqUserInfo(pageNo.value, pageSize.value, keyword.value);
    if (result.code == 200) {
        total.value = result.data.total;
        userArr.value = result.data.records;
    }
}
//分页器下拉菜单的自定义事件的回调
const handler = () => {
    getHasUser();
}

 动态渲染数据类型:

1.4-点击搜索按钮搜索用户

 填写关键字信息,点击搜索按钮,调用用户列表接口获取用户属性;完成后,关键字置空。
ps:这里可以建议不置空(方便用户查看自己输入的关键字),点击重置的时候,置空再获取用户信息

let keyword = ref<string>('');//定义响应式数据:收集用户输入进来的关键字

//搜索按钮的回调
const search = () => {
    getHasUser();//根据关键字获取相应的用户数据
    //清空关键字
    keyword.value = '';
}

1.5-点击重置按钮

       点击重置按钮,我们改变当前的系统配置的仓库里面的refsh属性,因为我们之前监听了属性变化,dom重新加载。所以会自动调用接口。

文件src\views\acl\user\index.vue中获取配置以及方法回调

import useLayOutSettingStore from '@/store/modules/setting'

//重置按钮
const reset = () => {
    settingStore.refsh = !settingStore.refsh;
}

2-新增编辑用户

2.1-原型需求分析

       

点击添加用户的时候,需要有个抽屉效果,需要使用到el-drawer组件,里面对用户名-用户昵称-用户密码进行相关的校验。点击保存就调用服务端接口保存用户,取消就需要关闭抽屉和清除相关数据。

2.2-表单页面数据收集

定义收集表单的数据类型对象:


//收集用户信息的响应式数据
let userParams = reactive<User>({
    username: '',
    name: '',
    password: ''
});

页面结构的开发:

 2.3-页面校验规则的定义

      我们需要对页面的输入参数进行简单校验,在实际项目中,可以根据自己的实际项目要求制定规则,复杂的可以采用正则表达式来实现。

//表单校验的规则对象
const rules = {
    //用户名字
    username: [{ required: true, trigger: 'blur', validator: validatorUsername }],
    //用户昵称
    name: [{ required: true, trigger: 'blur', validator: validatorname }],
    //用户的密码
    password: [{ required: true, trigger: 'blur', validator: validatorPassword }],
}


//校验用户名字回调函数
const validatorUsername = (rule: any, value: any, callBack: any) => {
    //用户名字|昵称,长度至少五位
    if (value.trim().length >= 5) {
        callBack();
    } else {
        callBack(new Error('用户名字至少五位'))
    }
}
//校验用户名字回调函数
const validatorname = (rule: any, value: any, callBack: any) => {
    //用户名字|昵称,长度至少五位
    if (value.trim().length >= 5) {
        callBack();
    } else {
        callBack(new Error('用户昵称至少五位'))
    }
}
const validatorPassword = (rule: any, value: any, callBack: any) => {
    //用户名字|昵称,长度至少五位
    if (value.trim().length >= 6) {
        callBack();
    } else {
        callBack(new Error('用户密码至少六位'))
    }
}

2.4-添加用户按钮编辑按钮逻辑

//添加用户按钮的回调
const addUser = () => {  
    drawer.value = true;//抽屉显示出来  
    Object.assign(userParams, {id: 0,username: '',name: '',password: ''}); //清空数据
    //清除上一次的错误的提示信息
    nextTick(() => {
        formRef.value.clearValidate('username');
        formRef.value.clearValidate('name');
        formRef.value.clearValidate('password');
    });
}

点击编辑用户按钮,需要回显用户信息:

//更新已有的用户按钮的回调
//row:即为已有用户的账号信息
const updateUser = (row: User) => {    
    drawer.value = true;//抽屉显示出来   
    Object.assign(userParams, row);//存储收集已有的账号信息
    //清除上一次的错误的提示信息
    nextTick(() => {
        formRef.value.clearValidate('username');
        formRef.value.clearValidate('name');
    });
}

2.5-保存和取消用户信息逻辑

       点击保存和取消按钮的时候,需要开发相关的业务逻辑,先需要通过之前的表单校验规则校验相关的字段,当校验通过后,在向服务器发送请求,保存用户信息。

3-删除和批量删除用户

点击列表操作按钮中的删除和上面的批量删除按钮,需要弹框提示用户确认删除信息,然后调用服务端接口,不管成功还是失败提示用户,删除完成后,需要重新获取列表页面的数据。

//删除某一个用户
const deleteUser = async (userId: number) => {
    let result: any = await reqRemoveUser(userId);
    if (result.code == 200) {
        ElMessage({ type: 'success', message: '删除成功' });
        getHasUser(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1);
    }
}

批量删除用户信息:

let selectIdArr = ref<User[]>([]);//准备一个数组存储批量删除的用户的ID

//table复选框勾选的时候会触发的事件
const selectChange = (value: any) => {
    selectIdArr.value = value;
}

//批量删除按钮的回调
const deleteSelectUser = async () => {
    //整理批量删除的参数
    let idsList: any = selectIdArr.value.map(item => {
        return item.id;
    });
    //批量删除的请求
    let result: any = await reqSelectUser(idsList);
    if (result.code == 200) {
        ElMessage({ type: 'success', message: '删除成功' });
        getHasUser(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1);
    }
}

4-分配角色

 

点击列表页面的分配角色,抽屉弹出用户有的角色信息,已经全部的角色信息。点击单个角色的时候,进行勾选或者取消。当我们单个全部选中的时候,上面的全选就勾选上。
ps:这里的重难点在于,角色列表展示的时候,全选和半选状态的切换以及判断等

let drawer1 = ref<boolean>(false);//控制分配角色抽屉显示与隐藏
let allRole = ref<AllRole>([]);//存储全部角色的数据
let userRole = ref<AllRole>([]);//当前用户已有的角色

//分配角色按钮的回调
const setRole = async (row: User) => {
    Object.assign(userParams, row);//存储已有的用户信息
    //获取全部的角色的数据与当前用户已有的角色的数据
    let result: AllRoleResponseData = await reqAllRole((userParams.id as number));
    if (result.code == 200) {       
        allRole.value = result.data.allRolesList;//存储全部的角色        
        userRole.value = result.data.assignRoles;//存储当前用户已有的角色        
        drawer1.value = true;//抽屉显示出来
    }
}

const checkAll = ref<boolean>(false);//收集顶部复选框全选数据
const isIndeterminate = ref<boolean>(true);//控制顶部全选复选框不确定的样式
//顶部的全部复选框的change事件
const handleCheckAllChange = (val: boolean) => {
    //val:true(全选)|false(没有全选)
    userRole.value = val ? allRole.value : [];
    //不确定的样式(确定样式)
    isIndeterminate.value = false
}
//顶部全部的复选框的change事件
const handleCheckedCitiesChange = (value: string[]) => {
    //顶部复选框的勾选数据
    //代表:勾选上的项目个数与全部的职位个数相等,顶部的复选框勾选上
    checkAll.value = value.length === allRole.value.length;
    //不确定的样式
    isIndeterminate.value = value.length !== allRole.value.length
}

点击保存按钮,需要将收集到的数据组装成一个对象提交给服务器,这里我们需要提交用户的id和角色的id集合。

//确定按钮的回调(分配角色)
const confirmClick = async () => {
    //收集参数
    let data: SetRoleData = {
        userId: (userParams.id as number),
        roleIdList: userRole.value.map(item => {
            return (item.id as number)
        })
    }
    //分配用户的角色
    let result: any = await reqSetUserRole(data);
    if (result.code == 200) {       
        ElMessage({ type: 'success', message: '分配职务成功' });//提示信息      
        drawer1.value = false;//关闭抽屉      
        getHasUser(pageNo.value);//获取更新完毕用户的信息,更新完毕留在当前页
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/664654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++个人通信录系统

背景&#xff1a; 使用C编写一个通信录程序&#xff0c;来完成作业上的一些需求。 1-提供录入个人信息、修改个人信息&#xff08;姓名和出生日期除外&#xff09;、删除个人信息等编辑功能 2-提供按姓名查询个人信息的功能 3-提供查找在5天之内过生日的人员的信息&#xf…

Gof23设计模式之工厂方法模式和抽象工厂模式

在java中&#xff0c;万物皆对象&#xff0c;这些对象都需要创建&#xff0c;如果创建的时候直接new该对象&#xff0c;就会对该对象耦合严重&#xff0c;假如我们要更换对象&#xff0c;所有new对象的地方都需要修改一遍&#xff0c;这显然违背了软件设计的开闭原则。 如果我们…

机器学习之K-Means(k均值)算法

1 K-Means介绍 K-Means算法又称K均值算法&#xff0c;属于聚类&#xff08;clustering&#xff09;算法的一种&#xff0c;是应用最广泛的聚类算法之一。所谓聚类&#xff0c;即根据相似性原则&#xff0c;将具有较高相似度的数据对象划分至同一类簇&#xff0c;将具有较高相异…

NDK使用LLVM编译Boost库给Android使用

1.下载boost库 ​ wget https://boostorg.jfrog.io/artifactory/main/release/1.71.0/source/boost_1_71_0.tar.gz​ 选择1.71.0版本 NDK版本19 ,ANDROID版本 24 进入然后后的目录 (不指定平台 默认为当前系统平台) ./bootstrap.sh --prefix=./android_build --libdir=.…

Java---阶段项目----五子棋

Java---阶段项目----五子棋 需求说明技术实现棋盘制作完整代码 需求说明 五子棋棋盘为一个1010的方格&#xff0c;五子棋玩家共为两个(A,B)&#xff0c;A在棋盘上落子后&#xff0c;B再落子&#xff0c;依次往复&#xff0c;直到一方胜利或者棋盘空间用完为止&#xff0c;判断…

StarCCM+ 命令行运行(Windows)

添加环境变量 找到启动程序的位置。找到当初安装starccm的文件夹&#xff0c;一般就是 Siemens 文件夹&#xff0c;进入会看到各版本的安装文件夹&#xff08;如果你没有安装多个版本则只有一个&#xff09;&#xff0c;然后参考下面我的路径找到相应的文件夹。在bin文件夹内可…

【openGauss简单使用---快速入门】

【openGauss简单使用---快速入门】 &#x1f53b; 一、openGauss使用&#x1f530; 1.1 连接openGauss&#x1f530; 1.2 创建数据库用户和授权&#x1f530; 1.3 创建数据库&#x1f530; 1.4 创建SCHEMA&#x1f530; 1.5 创建表 &#x1f53b; 二、总结—温故知新 &#x1f…

信息系统之网络安全方案 — “3保1评”

信息系统之网络安全方案 — “3保1评” 序&#xff1a;什么是“3评1保”&#xff1f;一、网络安全等级保护1.1 概念1.2等保发展1.3法律要求1.4分级及工作流程 二、涉密信息系统分级保护2.1概念2.2法律要求2.3分级及工作流程 三、关键信息基础设施保护3.1概念3.2关保的发展3.3法…

建立和使用Python自定义模块:打包+pip安装

文章目录 &#xff08;零&#xff09;拷目录-无法卸载&#xff08;一&#xff09;打包结构&#xff08;1.1&#xff09;__init__.py&#xff08;1.2&#xff09;setup.py &#xff08;二&#xff09;开始打包&#xff08;2.1&#xff09;命令出错&#xff1f; &#xff08;三&a…

构建高可用、高并发和高性能的微服务系统(Spring Cloud实现)

目前Java都在流行一个说词&#xff1a;高并发。 反正不管是不是&#xff0c;反正就是高并发。 谈高并发&#xff0c;我们需要知道几个名词&#xff1a; -响应时间(Response Time&#xff0c;RT)-吞吐量(Throughput)-每秒查询率QPS(Query Per Second)-每秒事务处理量TPS(Transa…

SuiteQlet Bundle

Content​​​​​​​ 1. Foreword 2. Overview 2.1 Glossary 2.2 Features 2.3 Design Description 3. Install 4. Setup 5. Instruction 5.1 Query 5.2 Chart 5.3 Publish Dashboard 6. Note 7. Video Link 1. Foreword SuiteQL is a powerful tool for data q…

python 第八章 集合set {}

系列文章目录 第一章 初识python 第二章 变量 第三章 基础语句 第四章 字符串str 第五章 列表list [] 第六章 元组tuple ( ) 第七章 字典dict {} 文章目录 8.1 创建集合8.2集合常见操作方法增加数据删除数据查找数据 8.1 创建集合 创建集合使用 { } 或 set()&#xff0c;但是如…

【MySQL】增删查改基础

目录 一、Create(创建) 1、insert(插入) 1.1单行数据插入 1.2多行数据插入 1.3插入或者替换更新 2、replace(替换) 二、Retrieve(读取) 1、select 1.1全列查询 1.2指定列查询利用selsct计算表达式 1.3筛选结果去重 2、where 2.1运算符 2.2找到英语小于60分的同学…

RFID课程要点总结_4 Tag Identification Protocol

4. Tag Identification Protocol Checksum procedure: parity checks, LRC, CRC 奇偶校验不多说&#xff0c;查1的个数&#xff0c;poor error recognition。电路通过所有位异或是偶校验&#xff0c;结果为1说明有错误&#xff1b;再取反是奇校验。 LRC longitudinal redund…

02 React组件、React组件实例的三大核心属性

总结 一、React组件 1.1 函数组件 定义 要求组件名称的首字母需要大写 function 组件名称(){ // 返回一段jsx的视图结构 return <div></div> }调用 <组件名称></组件名称> 或 <组件名称 /> 组件名首字母必须大写. 因为react以此来区分组件元…

一、动画 - 过渡效果transition

内容目录&#xff1a; 过渡动画&#xff1b;过渡动画的属性&#xff1b; 一、过渡动画 过渡&#xff08;transition&#xff09;作用&#xff1a;- 通过过渡可以指定一个属性发生变化时的切换方式- 通过过渡可以创建一些非常好的效果&#xff0c;提升用户的体验现在我们通过一…

nginx的操作手册和nginx的升级

总结 目录 一首先关闭防火墙和下载nginx包 1.安装依赖包 2.创建运行用户与组 3.进入nginx的目录下进行编译安装 4. 编译和编译安装 5.让系统识别nginx的操作命令 ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ 6.添加nginx系统服务把nginx服务加入到…

Idea+maven+springboot项目搭建系列--3 整合阿里云Canal完成Mysql数据的监听

前言&#xff1a;在搭建canal 服务之后&#xff0c;项目中就可以连接canal &#xff0c;完成对感兴趣的数据库及其表中数据的变动完成监听&#xff0c;本文依赖于你已经完成了对canal 服务的搭建工作&#xff1b; 1 Cannal 特点&#xff1a; Canal是阿里巴巴开源的一款基于My…

Spring Boot实战:拦截器和监听器的应用指南

当使用Spring Boot时&#xff0c;我们可以通过拦截器&#xff08;Interceptor&#xff09;和监听器&#xff08;Listener&#xff09;来实现对请求和响应的处理。拦截器和监听器提供了一种可插拔的机制&#xff0c;用于在请求处理过程中进行自定义操作&#xff0c;例如记录日志…

使用自动化测试获取手机短信验证码

目前在职测试开发,,写一些脚本,个人认为这职业不科学不应该有的职业,测试就是测试,开发就是开发,运维还是老鸟,这行业总能折腾些莫名其妙的东西出来,刚做这行时学的第一门语言是bash shell, 去新去单位上班直接写了个一键搭建测试环境的测试脚本,本来不想干测试了,好好做微信小…