SpringBoot + Vue前后端分离项目实战 || 五:用户管理功能后续

news/2024/11/13 4:28:43/

系列文章:
SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计
SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接
SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现
SpringBoot + Vue前后端分离项目实战 || 五:用户管理功能后续

文章目录

    • 回顾与展望
    • 新增用户功能实现
      • 前端实现
      • 前端接口实现
    • 后端实现
      • 新增用户
      • 修改用户
      • 删除用户
      • 根据id查找用户,显示数据在修改表单中
    • 完结撒花!!!

回顾与展望

之前介绍了用户管理界面的数据展示,接下来需要做新增、修改、删除用户的功能
在这里插入图片描述
在这里插入图片描述

新增用户功能实现

前端实现

user.vue编写弹窗对话框的代码,该代码同样来自Element-UI组件
在这里插入图片描述

<!-- 用户信息编辑对话框 -->
<!-- :title 加了冒号就变成一个变量,属性绑定了,后面的东西需要在data中说明 -->
<el-dialog @close="clearForm" :title="title" :visible.sync="dialogFormVisible"><el-form :model="userForm" ref="userFormRef" :rules="rules"><el-form-item label="用户名" prop="username" :label-width="formLabelWidth"><el-input v-model="userForm.username" autocomplete="off"></el-input></el-form-item><el-form-item v-if="userForm.id == null || userForm.id == undefined"label="登录密码" prop="password" :label-width="formLabelWidth"><el-input type="password" v-model="userForm.password" autocomplete="off"></el-input></el-form-item><el-form-item label="联系电话" prop="phone" :label-width="formLabelWidth"><el-input v-model="userForm.phone" autocomplete="off"></el-input></el-form-item><el-form-item label="用户状态" :label-width="formLabelWidth"><el-switch v-model="userForm.status" :active-value="1":inactive-value="0"active-color="#13ce66" inactive-color="#ff4949"></el-switch></el-form-item><el-form-item label="电子邮件" prop="email" :label-width="formLabelWidth"><el-input v-model="userForm.email" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="saveUser">确 定</el-button></div>
</el-dialog>

该对话框有三个比较重要的属性
在这里插入图片描述

  • 红色:关闭对话框的操作,关闭对话框后需要清空表单,并且清空表单的效验规则,这部分代码写在methods
    在这里插入图片描述
  • 橙色:为弹出对话框的标题,此处我们将新增对话框和编辑对话框设置为同一个,根据不同的操作,显示不同的名称
    在这里插入图片描述
    在这里插入图片描述
    因为:title是变量,所以需要注册
    在这里插入图片描述
  • 白色:修改弹窗是否显示,其实弹窗一直都在,只是点击按钮后,将其显示出来,关闭后又将其隐藏起来,同样身为变量需要注册,先让其不可见
    在这里插入图片描述

表单的三个属性
在这里插入图片描述

  • 红:表单数据的一级变量名,若要访问里面的数据可用userForm.username,这是input中的v-model字段,该字段应与后端实体类名一致。 同时item中prop字段也与后端一致

  • 橙:ref用于表单校验时的变量名,前面clearForm中有用到

  • 白:定义表单校验规则,如下代码可在Element-UI官网中找到,代码写在datareturn区域内,不是methods内
    在这里插入图片描述

    rules:{   // 表单校验username: [{ required: true, message: '请输入用户名', trigger: 'blur' },{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }],password: [{ required: true, message: '请输入初始密码', trigger: 'blur' },{ min: 6, max: 16, message: '长度在 6 到 16 个字符', trigger: 'blur' }],email: [{ required: true, message: '请输入电子邮件', trigger: 'blur' },{ validator: checkEmail, trigger: 'blur' }],phone: [{ validator: checkPhone, trigger: 'blur' }],},
    

    在这里插入图片描述

    规则校验中有两个是自定义的规则校验:checkEmailcheckPhone,这两个为正则表达式,可百度搜索邮箱、电话的效验规则,此处拿过来直接用。注意这两个校验规则写在data里,而不是data\return
    在这里插入图片描述

     var checkEmail = (rule, value, callback) => {var reg = /^([a-zA-Z\d][\w-]{2,})@(\w{2,})\.([a-z]{2,})(\.[a-z]{2,})?$/if (!reg.test(value)) {return callback(new Error('邮箱格式错误'));}callback();   // 效验成功};var checkPhone = (rule, value, callback) => {var reg = /^[1]+\d{10}$/if (!reg.test(value)) {return callback(new Error('请输入正确的手机号码'));}callback();    // 效验成功};
    

表单整体为下图红色部分
在这里插入图片描述

  • 橙色:为表单接收字段的变量名,与后端数据库实体类保持一致
  • 白色:在修改用户信息时,不给修改密码的机会。但是新增用户时,会设置初始密码,所以需要做一个判断。如果为修改用户,那么该用户会有一个id,通过userForm.id访问,存在的话说明是修改用户,会将该用户的信息展示出来,再进行修改。
    注意:后端传过来的是实体类中的所有属性,userForm也接收了所有属性,只是展示出来的只有姓名、邮箱等,其余的属性没有展示,仍然可访问

提交按钮
在这里插入图片描述

  • 橙色:点击取消按钮,将对话框的显示属性设为false,不可见
  • 白色: 点击保存按钮触发的函数:saveUser,此函数的操作流程在注释中已说明
    在这里插入图片描述
    saveUser(){// 触发表单验证this.$refs.userFormRef.validate((valid) => {if (valid) {  // 验证通过// 数据传给后端userApi.saveUser(this.userForm).then(response=>{// 提交成功后的操作// 插入数据成功提示this.$message({message: response.message,type: 'success'});// 关闭对话框,清除表单数据this.dialogFormVisible = false;this.clearForm();// 刷新表格this.getUserList();});} else {  // 验证失败console.log('error submit!!');return false;}});},
    

所有对话框表单的vue代码如下

<!-- 用户信息编辑对话框 -->
<!-- :title 加了冒号就变成一个变量,属性绑定了,后面的东西需要在data中说明 -->
<el-dialog @close="clearForm" :title="title" :visible.sync="dialogFormVisible"><el-form :model="userForm" ref="userFormRef" :rules="rules"><el-form-item label="用户名" prop="username" :label-width="formLabelWidth"><el-input v-model="userForm.username" autocomplete="off"></el-input></el-form-item><el-form-item v-if="userForm.id == null || userForm.id == undefined"label="登录密码" prop="password" :label-width="formLabelWidth"><el-input type="password" v-model="userForm.password" autocomplete="off"></el-input></el-form-item><el-form-item label="联系电话" prop="phone" :label-width="formLabelWidth"><el-input v-model="userForm.phone" autocomplete="off"></el-input></el-form-item><el-form-item label="用户状态" :label-width="formLabelWidth"><el-switch v-model="userForm.status" :active-value="1":inactive-value="0"active-color="#13ce66" inactive-color="#ff4949"></el-switch></el-form-item><el-form-item label="电子邮件" prop="email" :label-width="formLabelWidth"><el-input v-model="userForm.email" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="saveUser">确 定</el-button></div>
</el-dialog>

前端接口实现

前端接口的文件在路径src\api\userManage.js中,注意增删改查对应的方法分别是post/delete/put/get

import request from '@/utils/request'export default{getUserList(searchModel){return request({url:'/user/list',method:'get',params:{    // 传给后端的参数,对应后端的 @RequestParampageNo: searchModel.pageNo,pageSize: searchModel.pageSize,username: searchModel.username,phone: searchModel.phone,}});},addUser(user){return request({url:'/user',method:'post',data:user   // 传回后端的实体数据});},saveUser(user){if(user.id == null || user.id == undefined){return this.addUser(user);}else{return this.updateUser(user);}},updateUser(user){return request({url:'/user',method:'put',data:user});},getUserById(id){return request({// url:'/user/' + id,   // 写法一url:`/user/${id}`,    // 写法二 ,对应后端的 @PathVariablemethod:'get'});},deleteUserById(id){return request({url:`/user/${id}`,    // 对应后端的 @PathVariablemethod:'delete'});},}

后端实现

后端代码在UserController.java

新增用户

在这里插入图片描述

	 // 前端addUser方法的url就是"/user" 故此处无url@PostMappingpublic Result<?> addUser(@RequestBody User user){// @RequestBody 用于json转为实体对象// 做了加盐处理user.setPassword(passwordEncoder.encode(user.getPassword()));userService.save(user);return Result.success("新增用户成功");}

与对应的前端如下:
在这里插入图片描述

加密操作
新增用户中有个密码加密功能,将用户密码写入数据库时,对其加密加盐,如下图,密码明文是123456
在这里插入图片描述

(加盐:针对同一个密码组合,密文也是不同的)

pom.xml中添加依赖:

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId>
</dependency>

在启动类里注册Bean
在这里插入图片描述

@Bean
public PasswordEncoder passwordEncoder(){// 密码加密的工具类,来自依赖spring-security-corereturn new BCryptPasswordEncoder();
}

UserController里注册变量
在这里插入图片描述

修改登录逻辑
密码加密后,登录时不能简单匹配数据库的密码,需要有个解密匹配过程
修改后端文件service\impl\UserServiceImpl

@Override
public Map<String, Object> login(User user) {// 根据用户名查询LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.eq(User::getUsername, user.getUsername());User loginUser = this.baseMapper.selectOne(wrapper);// 结果不为空,并且密码与数据库解密后的密码匹配,生成token,将用户信息存入redisif (loginUser != null &&passwordEncoder.matches(user.getPassword(), loginUser.getPassword())    // 匹配加密密码) {// 用UUID,终极方案是jwtString key = "user:" + UUID.randomUUID();// 存入redisloginUser.setPassword(null);    // 设置密码为空,密码没必要放入redisTemplate.opsForValue().set(key, loginUser,10, TimeUnit.MINUTES);   // timeout为登录时间// 返回数据Map<String, Object> data = new HashMap<>();data.put("token",key);return data;}// 结果不为空,生成token,前后端分离,前端无法使用session,可以使用token// 并将用户信息存入redisreturn null;
}

至此,新增用户功能完毕


修改用户

在这里插入图片描述

	@PutMappingpublic Result<?> updateUser(@RequestBody User user){// @RequestBody 用于json转为实体对象user.setPassword(null);userService.updateById(user);return Result.success("修改用户成功");}

对应的前端如下:
在这里插入图片描述

删除用户

在这里插入图片描述

	@DeleteMapping("/{id}")public Result<?> deleteUserById(@PathVariable("id") Integer id){userService.removeById(id);return Result.success("删除用户成功");}

前端如下:
在这里插入图片描述

在公司项目管理中,一般都是使用逻辑删除,并不是真正删除数据库里的记录,而是在数据表中设置一个字段deleted做一个标记位。0表示未删除,1表示已删除
在这里插入图片描述

resources\application.yml中添加配置

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名,与数据库的字段名一致logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

这样,Spring会在查询时自动拼接SQL语句WHERE deleted = 0
在这里插入图片描述

配置好后,删除oioi用户前的数据库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
删除后,最后一个字段变为1


根据id查找用户,显示数据在修改表单中

在这里插入图片描述

	@GetMapping("/{id}")public Result<User> getUserById(@PathVariable("id") Integer id){User user = userService.getById(id);return Result.success(user);}

对应的前端如下:
在这里插入图片描述

完结撒花!!!


http://www.ppmy.cn/news/637692.html

相关文章

呼叫中心语音外呼营销系统软件成企业首选

网络电话&#xff0c;云呼&#xff0c;电销&#xff0c;博主从事多年智能机器人&#xff0c;外呼中心技术开发。有问题找博主。电信诈骗是今年工信部讨论的热词&#xff0c;为了更好的规范通讯业务和市场&#xff0c;相继出台了许多规定&#xff0c;并做了严格规定与限制。为此…

2.IT-解决方案-2-FAX

一. 目的: 1. 企业与企业,企业与个人,之间的沟通 2. 使用分机号 A. 根据企业架构-获取-企业联络表 B. 根据企业架构-在传真服务器中按部门来建立相应的部门 C. 根据企业架构-为各部编号,比如总经理 11 财务 12 D. 根据企业架构-为部门下面员工,首先固定传真机号码,如总经理 111…

ubuntu中实现tif格式转换为pdf或者其它各种格式的方法

在做一个OA系统项目中&#xff0c;开发到传真模块&#xff0c;传真数据是通过aofax收发的&#xff0c;现在要把收到的tif文档显示到浏览器上。最好的办法是把tif文档转换成pdf的格式。 步骤如下&#xff1a; 1、运行以下五条代码 sudo aptitude update sudo aptitude insta…

Sqlserver2005 Sqlcmd查看数据库/表/字段的命令

分类&#xff1a; Other 2011-05-09 17:57 2931人阅读 评论(1) 收藏 举报 sqlserver 数据库 join server 工具 go Sqlcmd是sqlserver自带的命令行工具&#xff0c;可以在不打开企业管理器的时候访问本地或者远程的数据库&#xff0c;对数据库进行管理。 Sqlcmd连接数据库&a…

C# WebForm定义全局变量

在项目中新建一个.cs的类&#xff0c;里面定义一些变量如 using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using S…

呼叫中心是什么?

一、呼叫中心是什么? 谈及呼叫中心&#xff0c;大家或许有些陌生&#xff0c;但是它的运用却是无处不在&#xff0c;房地产、保险信贷公司等销售业实现的批量外呼;电信公司10086等客服语音导航高级IVR语音识别功能;政府公安等机构需要的电话录音功能;医院银行涉及到的TTS文本播…

SFB 项目经验-57-Skype for business-录音系统-你拥有吗(模拟线路)

项目需求&#xff1a; 你企业有Skype for business Server 2015、Lync Server 2013? 老板说&#xff1a;“小刘&#xff0c;我们所有对外电话拔打与接听&#xff0c;需要录音。有利于提升公司的企业形象!” 小刘说&#xff1a;“老板&#xff0c;好的&#xff0c;我去了解方案…

工作中遇到的一些其他问题以及解决方案

前言 本篇文章主要介绍的是工作中遇到的一些其他问题以及解决方案。 1.问题&#xff1a;传真发送文件 有一台Windows服务器&#xff0c;部署了传真软件&#xff0c;称之为传真服务器&#xff1b; 有一台linux服务器&#xff0c;部署了javaweb项目&#xff0c;称之为应用服务…