SpringBoot 框架搭建 用户管理系统(附代码)

您所在的位置:网站首页 用户管理系统1921681011 SpringBoot 框架搭建 用户管理系统(附代码)

SpringBoot 框架搭建 用户管理系统(附代码)

2023-07-23 09:42| 来源: 网络整理| 查看: 265

使用SpringBoot 框架搭建用户管理系统,代码附在文末 快~点这里来试试(●’◡’●)

1、项目解决问题

  用户管理系统:用户的信息做统一的管理

2、需求功能分析

1、登录功能(普通管理员登陆、超级管理员的登录) 2、用户列表页面(普通用户的列表、超级管理员的列表页) 3、条件查询(组合条件查询、不定规则查询) 4、分页功能 5、添加功能(普通管理员的添加、超级管理员的添加) 6、单挑删除功能 7、多条删除功能

3、设计数据库

  用户管理系统,所以只需要设置一张用户表即可,SQL语句如下:

drop database if exists userdb; create DATABASE if not exists userdb character set utf8; use userdb; drop table if exists userinfo; create table `userinfo` ( `id` INT PRIMARY KEY auto_increment, `name` varchar(60), --姓名 `username` varchar(60) default 'root', `password` varchar(60) default '123456', `sex` varchar(4), --性别 `age` int, --年龄 `address` varchar(90), --邮箱 `qq` varchar (20), -- QQ `email` varchar (30), --是否为超管,默认为否 `isadmin` int not null default 0 ); INSERT INTO userinfo VALUES(1,'超级管理员','admin','123','男',18,'成都','1262913815','[email protected]',1); INSERT INTO userinfo VALUES(2,'张飞','zhangfei','123','男',18,'成都','1262913815','[email protected]',0); INSERT INTO userinfo VALUES(3,'关羽','guanyu','1234','男',18,'西安','1262913816','[email protected]',0); INSERT INTO userinfo VALUES(4,'张三','zhangsan','1235','女',19,'西安','1262913817','[email protected]',0); INSERT INTO userinfo VALUES(5,'李四','lisi','1236','男',20,'北京','1262913818','[email protected]',0); INSERT INTO userinfo VALUES(6,'王五','wangwu','1237','女',21,'西安','1262913819','[email protected]',0); INSERT INTO userinfo VALUES(7,'孙权','sunquan','1238','男',22,'上海','1262913814','[email protected]',0); INSERT INTO userinfo VALUES(8,'孙悟空','sunwukong','1239','男',23,'西安','1262913813','[email protected]',0); INSERT INTO userinfo VALUES(9,'猪八戒','zhubajie','1239','男',23,'上海','1262913813','[email protected]',0); 4、返回原则:所有接口必须有统一的返回格式

  为前端返回JSON字符串,包含 {status,data,message}   第一种封装方法:定义一个全局的返回时调用此对象进行返回。   第二种封装方法:Advice 接口实现统一的数据封装   这里采用第二种:定义全区的返回掉用对象来实现统一返回原则,泛用性强

package com.example.usermanager.tools; import lombok.Data; @Data public class ResponseBody { private int status; private String message; private T data; public ResponseBody(int status, String message, T data) { this.status = status; this.message = message; this.data = data; } }

  在之后写的后端controller类下各种方法,都将其返回值设置为ResponseBody,根据需求返回值不同,设置data属性为需要的属性。

5、登录

  先贴上登录的前端页面:login.html

用户信息管理系统登录页面 html, body { width: 100%; height: 100%; margin: 0; padding: 0; overflow: auto; } body { background: url(images/acg.gy_16.jpg) no-repeat 100% 100%; background-size: cover; } 后台管理员登录 用户名: 密码: 测试超管帐号:admin          测试密码:123 function mysub() { // 获取用户名 var username = jQuery("#username"); // 获取密码 var password = jQuery("#password"); // 非空效验 if (username.val().trim() == "" || password.val().trim() == "") { alert("请先输入用户名和密码才能进行登录!"); return false; } // 提交数据到后端进行登录效验 jQuery.getJSON("/user/login", { "username": username.val(), "password": password.val() }, function (result) { if (result != null && result.status == 0) { // 登录成功 alert("登录成功"); location.href = "list.html"; } else { // todo:安全限制(如果一定时间内输入的用户名和密码错误次数过多,就可以先冻结账户一段时间) alert(resulssage); } }); }

  登录功能需要做的就是两件事,第一件事,拿到前端传来的帐号和密码后,去数据库验证,验证成功则登录,失败则拒绝登录;第二件事,登陆成功后,将当前登录用户的Session信息保存下来

package com.example.usermanager.controller; import com.example.usermanager.mapper.UserMapper; import com.example.usermanager.model.UserInfo; import com.example.usermanager.tools.AppFinal; import com.example.usermanager.tools.ResponseBody; import com.example.usermanager.tools.SessionUtil; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.HashMap; import java.util.List; @RestController @RequestMapping("/user") public class UserController { @Resource private UserMapper userMapper; // 注入UserMapper.class接口类,用于映射与数据库沟通的方法 // 登录方法 @RequestMapping("/login") public ResponseBody login(@RequestParam String username, @RequestParam String password, HttpServletRequest request) { UserInfo userInfo = userMapper.login(username, password); int status = -1; String message = "用户或密码错误!"; if (userInfo != null && userInfo.getId() > 0) { // 登录成功 status = 0; message = ""; // 将用户对象存储到 session 中 HttpSession session = request.getSession(); session.setAttribute(AppFinal.USERINFO_SESSION_KEY, userInfo); } return new ResponseBody(status, message, userInfo); }

  UserMapper.class接口类,用于映射UserMapper.xml配置类中的具体操作数据库的方法

package com.example.usermanager.mapper; import com.example.usermanager.model.UserInfo; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface UserMapper { public UserInfo login(String username, String password);

  UserMapper.xml配置文件,用于具体操作数据库的SQL语句书写

DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> select * from userinfo where username=#{username} and password=#{password} 6、添加用户页面 —— 拥有两个访问后端的接口

  先贴上添加用户的前端页面:add.html

添加用户 添加用户 登录名: 姓名: 密码: 确认密码: 性别: 男 ;;; 女 年龄: 籍贯: 北京 上海 广州 深圳 成都 杭州 重庆 西安 武汉 沧州 QQ: Email: 超级管理员: 是 ;;; 否 jQuery.getJSON("/user/checkadmin",{},function (result) { if(result!=null && result.data==1){ // 超级管理员 jQuery("#adminDiv").show(); } }); // 提交方法 function mysub() { // 1.非空效验 var username = jQuery("#username"); var name = jQuery("#name"); var password = jQuery("#password"); var password2 = jQuery("#password2"); var age = jQuery("#age"); var qq = jQuery("#qq"); var email = jQuery("#email"); if(username.val().trim()==""){ alert("请先输入登录名!"); username.focus(); return false; } if(name.val().trim()==""){ alert("请先输入姓名!"); name.focus(); return false; } if(password.val().trim()==""){ alert("请先输入密码!"); password.focus(); return false; } if(password2.val().trim()==""){ alert("请先输入确认密码!"); password2.focus(); return false; } if(password.val()!=password2.val()){ alert("两次输入的密码不一致,请检查!"); password.focus(); return false; } if(age.val().trim()==""){ alert("请先输入年龄!"); age.focus(); return false; } if(qq.val().trim()==""){ alert("请先输入QQ!"); qq.focus(); return false; } if(email.val().trim()==""){ alert("请先输入电子邮箱!"); email.focus(); return false; } // 提交数据到后端 jQuery.getJSON("/user/add",{ "username":username.val().trim(), "name":name.val().trim(), "password":password.val().trim(), "sex":jQuery("input[name=sex]:checked").val(), "age":age.val().trim(), "address":jQuery("#address").val(), "qq":qq.val().trim(), "email":email.val().trim(), "isadmin":jQuery("input[name=isadmin]:checked").val() },function (result) { if(result!=null && result.status==0 && result.data>0){ // 添加成功 alert("恭喜:添加成功!"); // todo:继续添加或返回到列表页 }else{ alert("抱歉:添加失败,"+resulssage); } }); }

(1)获取当前用户登录权限的接口(超级管理员还是普通管理员)   要实现用户信息管理,需要验证当前登录的账号是普通的用户管理员还是超级管理员,这两者的区别是,普通管理员用户只可以看到其他的普通管理员用户信息,添加新的用户时不能添加超管用户,同时也看不到超管用户的信息;但超管用户可以添加普通管理员和超管的新用户,并且可以看见所有用户的信息。   下列所有controller又是对用户进行操作,所以都在UserController类下,所以,每一部分只列出当前部分的方法,就不复制整体类的其他代码了;同样UserMapper.class接口类同样只写新添加的;UserMapper.xml配置文件也是。   所以在登录之后,首先要验证当前用户的权限

// 查询当前登录用户的权限 @RequestMapping("/checkadmin") public ResponseBody checkAdmin(HttpServletRequest request) { int data = 0; HttpSession session = request.getSession(false); // 拿到Session中的用户信息 UserInfo userInfo = null; if (session != null && (userInfo = (UserInfo) session.getAttribute(AppFinal.USERINFO_SESSION_KEY)) != null) { data = userInfo.getIsadmin(); // 根据Session中保存的用户信息,拿到 管理员权限 字段,返回这个字段的属性 } return new ResponseBody(0, "", data); }

(2)添加用户接口   添加用户方法,有两种情况,一种是添加普通用户,一种是添加超管用户,添加超管用户前需要对当前用户的权限进行验证,验证权限的方法与上一段逻辑大体相同,都是拿到Session的用户属性,然后拿到用户属性中的 是否为管理员权限 字段的属性   验证完用户权限后,就需要使用Mybatis进行数据库沟通,添加新用户   在UserController类下的add方法内引入UserMapper.class接口,作为映射UserMapper.xml中间介质——>data = userMapper.add(userInfo);   在mapper类下的UserMapper.class接口中添加 public int add(UserInfo userInfo);   通过在类上添加@Mapper注释,让UserMapper.class类映射到resources资源文件下的mybatis文件中的UserMapper.xml配置文件

// 添加用户方法 @RequestMapping("/add") public ResponseBody add(UserInfo userInfo, HttpServletRequest request) { int status = 0; String message = ""; int data = 0; // 安全效验 UserInfo user = SessionUtil.getUserBySession(request); if (user == null) { // 未登录 status = -1; message = "当前用户未登录,请先登录"; } else if (userInfo.getIsadmin() == 1) { // 要添加超级管理员 if (user.getIsadmin() == 0) { status = -2; message = "当前登录用户权限不足,不能操作"; } else if (user.getIsadmin() == 1) { // 当前登录用户为超级管理员 data = userMapper.add(userInfo); status = 0; } } else if (userInfo.getIsadmin() == 0) { // 添加一个普通管理员 data = userMapper.add(userInfo); } return new ResponseBody(status, message, data); }

  在UserMapper.class接口类中添加如下方法:

public int add(UserInfo userInfo);

  在UserMapper.xml配置文件中添加如下SQL语句

insert into userinfo(username,name,password,sex,age,address,qq,email ,isadmin ) values(#{username},#{name},#{password},#{sex},#{age},#{address},#{qq},#{email} ,#{isadmin} ) 7、修改用户页面 —— update.html?uid=xxx

  先贴上修改用户的前端页面:update.html

修改用户 修改用户 登录名: 姓名: 性别: 男 ;;; 女 年龄: 籍贯: 北京 上海 广州 深圳 成都 杭州 重庆 西安 武汉 沧州 QQ: Email: 超级管理员: 是 ;;; 否 // 获取参数 function getParam(key) { // 得到当前url中的参数 ?uid=xxx var params = location.search; params = params.substring(1); // uid=xxx var paramArr = params.split("&"); for (var i = 0; i return item[1]; } } return null; } var uid = getParam("uid"); if (uid != null && uid > 0) { // 查询用户的详情进行展示 jQuery.getJSON("/user/getuser", {"uid": uid}, function (result) { if (result != null && result.status == 0 && result.data.id > 0) { // 查询用户信息成功 var userinfo = result.data; jQuery("#username").val(userinfo.username); jQuery("#name").val(userinfo.name); if (userinfo.sex == "男") { jQuery("#man").attr("checked", "checked"); } else if (userinfo.sex == "女") { jQuery("#women").attr("checked", "checked"); } jQuery("#age").val(userinfo.age); jQuery("#address").val(userinfo.address); jQuery("#qq").val(userinfo.qq); jQuery("#email").val(userinfo.email); if (userinfo.isadmin == 0) { jQuery("#admin_no").attr("checked", "checked"); } else if (userinfo.isadmin == 1) { jQuery("#admin_yes").attr("checked", "checked"); } } else { alert("查询失败,请重试!"); } }); } else { alert("无效参数"); // todo:可以实现后续跳转(如:列表页 || 登录页) } function mysub() { // 1.非空效验 var name = jQuery("#name"); var age = jQuery("#age"); var qq = jQuery("#qq"); var email = jQuery("#email"); if (name.val().trim() == "") { alert("请先输入姓名!"); name.focus(); return false; } if (age.val().trim() == "") { alert("请先输入年龄!"); age.focus(); return false; } if (qq.val().trim() == "") { alert("请先输入QQ!"); qq.focus(); return false; } if (email.val().trim() == "") { alert("请先输入电子邮箱!"); email.focus(); return false; } // 提交数据到后端 jQuery.getJSON("/user/update", { "id": uid, "name": name.val().trim(), "sex": jQuery("input[name=sex]:checked").val(), "age": age.val().trim(), "address": jQuery("#address").val(), "qq": qq.val().trim(), "email": email.val().trim(), "isadmin": jQuery("input[name=isadmin]:checked").val() }, function (result) { if (result != null && result.status == 0 && result.data > 0) { // 操作成功 alert("恭喜:修改成功!"); // todo:返回到列表页 } else { alert("抱歉:修改失败," + resulssage); } }); }

(1)从url中获取uid   因为要对展示的列表中的某个用户进行信息的修改,所以要向后端传输时,传输当前要修改用户的uid,所以要拿到当前用户的uid   这部分在前端代码中完成,通过如下代码拿到URL地址中用户的uid

// 获取参数 function getParam(key) { // 得到当前url中的参数 ?uid=xxx var params = location.search; params = params.substring(1); // uid=xxx var paramArr = params.split("&"); for (var i = 0; i return item[1]; } } return null; }

(2)展示信息(用户登录状态判断-权限判断)   在UserController类下新增查询用户详细信息的方法   此处可以进行权限验证,当用户登录的情况下(Session)中有信息,才会展示用户信息

@RequestMapping("/getuser") public ResponseBody getUser(@RequestParam int uid) { int status = -1; String message = "未知错误"; UserInfo userInfo = userMapper.getUser(uid); if (userInfo != null) { // todo:权限效验 status = 0; } return new ResponseBody(status, message, userInfo); }

  在UserMapper.class接口类中添加如下方法:

public UserInfo getUser(int uid);

  在UserMapper.xml配置文件中添加如下SQL语句

select * from userinfo where id=#{uid}

(3)编辑/提交信息(用户登录状态判断、权限判断)   这里的权限效验,主要是要验证当前用户是否是超级管理员,如果不是超级管理员,就不能添加超级管理员的账户

@RequestMapping("/update") public ResponseBody update(UserInfo userInfo) { int data = 0; // todo:权限效验 data = userMapper.update(userInfo); return new ResponseBody(0, "", data); }

  在UserMapper.class接口类中添加如下方法:

public int update(UserInfo userInfo);

  在UserMapper.xml配置文件中添加如下SQL语句

update userinfo set name=#{name}, sex=#{sex}, age=#{age}, address=#{address}, qq=#{qq}, email=#{email}, isadmin=#{isadmin} where id=#{id} 8、用户列表显示

  先将用户列表显示的前端页面贴在这里:list.html

DOCTYPE html> 用户信息管理系统 td, th { text-align: center; } 用户信息列表 姓名 籍贯 邮箱 查询 添加用户 删除选中 选择 编号 姓名 性别 年龄 籍贯 QQ 邮箱 超管 操作 var name = ""; var address = ""; var email = ""; var cpage = 1; var psize = 5 function oncli(){ name = jQuery("#ipt_name").val().trim(); address = jQuery("#ipt_address").val().trim(); email = jQuery("#ipt_email").val().trim(); getData(); // 查询后端接口,展示信息 } // 点击分页按钮 function cliPage(cp) { cpage = cp; getData(); } function getData(){ jQuery.getJSON("/user/list",{ "name":name, "address":address, "email":email, "cpage":cpage, "psize":psize },function (result) { if(result != null && result.data.list != null && result.data.list.length > 0) { // 1、绑定列表数据 var listHtml = ""; for (var i = 0; i if(cpage != 1){ pageHtml += '\n' + ' «\n' } for(var j = 1; j // 高亮当前页面序号 pageHtml += '' + j + '\n'; }else{ pageHtml += '' + j + '\n'; } } // 下一页的按钮 与 动态显示:共 ? 条记录,共?页 if(cpage != tpage) { pageHtml += '\n' + ' »\n' + ' \n' + ' 共' + result.data.tcount + '条记录,共' + tpage + '页\n' + ' \n' } } jQuery("#all").html(pageHtml); } }); } getData(); // 单条删除 function del(id) { if (confirm("是否进行删除?")) { jQuery.getJSON("/user/del", {"id": id}, function (result) { if (result != null && result.data > 0) { alert("恭喜:删除成功!"); // 刷新当前页面 location.href = location.href; } else { alert("抱歉:删除失败 "+resulssage); } }); } } // 多条删除 // 思路1、for循环多条id,每次循环调用单条循环删除方法的接口;缺点:需要与后端进行N次交互,浪费带宽 // 思路2、将所有id集合一次发送给后端,后端对前端传递的id集合做统一的删除(使用这条思路) // (a) 点击选中按钮后,拿到选中的用户id集合 // (b) 后端拿到id集合之后,使用循环的标签,实现多条信息的删除 function delSelect() { // 1、获取需要删除的用户id集合 var ids = ""; jQuery("#info").find("tr").each(function (i) { //jQuery(this) == 当前行tr if(jQuery(this).find("th:first").find("input").prop("checked")==true){ // 判断 当前行tr的第一列的input控件中的 chekbox属性 是否为选中状态 prop("checked")判断当前控件是否为选中状态 ids += ((jQuery(this).find("th:first").find("input").attr("id")) + ',') }; }); if(ids != ""){ confirm("确认删除?") // 2、访问后端接口进行操作 jQuery.getJSON("/user/dels",{"ids":ids},function (result) { if(result != null && result.status == 0 && result.data > 0){ alert("删除成功"); location.href = location.href; }else { alert("删除失败"); } }) }else { alert("请先选中要删除的数据") } }

  根据前端页面所写,当用户登录进入到list.html这个页面,静态页面加载完成后,首先会执行getData()这个中的内容,这部分就是以列表的形式,返回所有用户的信息,而且因为我们需要分页查询,所以需要将cpage (当前页码)、psize(每页显示条数)传递给后端;并且要实现使用用户姓名、籍贯或者邮箱查询用户,所以同时也需要将name,adress、email传递,所以传递给后端的jQuery.getJSON中,传递的参数格式应该写成{"name":name,"address":address, "email":email,"cpage":cpage,"psize":psize };如果后端查询用户信息成功后使用jQuery("#info").html(listHtml);将循环赋值的listHtml对象展示到给前端页面上   (1)展示用户信息,以及分页   UserController类下新增list方法,该方法用于查询用户的信息,同时也需要验证一下当前用户是否为超管,普通管理员用户,是不能查询到超管用户的信息的

@RequestMapping("/list") public ResponseBody getList(String name, String address, String email, int cpage, int psize, HttpServletRequest request ) { // 1.权限效验 UserInfo userInfo = SessionUtil.getUserBySession(request); if (userInfo == null) { // 未登录 return new ResponseBody(-1, "当前用户未登录", null); } // 2.判断权限 Integer isadmin = null; if (userInfo.getIsadmin() == 0) { // 如果是普通管理员用户,这里将isadmin置为0 isadmin = 0; // 后续在查询的时候,他只能查询到isadmin为0,即只能查询到非超管用户 } // 如果是超管,isadmin则为null,查询时,就不考虑这项属性 // 处理前端的查询参数 name = name.equals("") ? null : name; address = address.equals("") ? null : address; email = email.equals("") ? null : email; // 3.构建分页查询字段 limit xx,psize 查询当前页面的列表信息 // 跳过查询的条数 int skipCount = (cpage - 1) * psize; // 查询一页的列表信息 List list = userMapper.getListByPage(name, address, email, skipCount, psize, isadmin); // 4.查询满足条件的数据总条数 int tcount = userMapper.getCount(name, address, email, isadmin); // 总页数 int tpage = (int) Math.ceil(tcount / (psize * 1.0)); // 封装统一返回对象 HashMap data = new HashMap(); data.put("list", list); data.put("tcount", tcount); // 总条数 data.put("tpage", tpage); // 总条数 return new ResponseBody(0, "", data); }

  在UserMapper.class接口类中添加如下方法:

// 查询一页信息 public List getListByPage(String name, String address, String email, int skipCount, int psize, Integer isadmin); // 查询满足条件的信息条数 public int getCount(String name, String address, String email, Integer isadmin);

  在UserMapper.xml配置文件中添加如下SQL语句,getListByPage为查询一页信息,getCount为查询满足条件的信息条数

select * from userinfo and name like concat('%',#{name},'%') and address=#{address} and email=#{email} and isadmin=#{isadmin} order by id desc limit #{skipCount},#{psize} select count(*) from userinfo and name like concat('%',#{name},'%') and address=#{address} and email=#{email} and isadmin=#{isadmin}

(2)单挑删除,以及多条删除

@RequestMapping("/del") public ResponseBody del(@RequestParam int id, HttpServletRequest request) { // 权限效验 UserInfo userInfo = SessionUtil.getUserBySession(request); if (userInfo == null) { // 未登录 return new ResponseBody(-1, "未登录", 0); } // 判断删除的是否是自己 if (id == userInfo.getId()) { // 删除的是自己 return new ResponseBody(-2, "不能删除自己", 0); } // 权限效验 Integer isadmin = null; if (userInfo.getIsadmin() == 0) { isadmin = 0; } int result = userMapper.del(id, isadmin); return new ResponseBody(0, "", result); } // 多条数据删除 @RequestMapping("dels") public ResponseBody dels(String ids) { int result = 0; result = userMapper.dels(ids.split(",")); System.out.println("ids:" + ids); return new ResponseBody(0, "", result); }

  在UserMapper.class接口类中添加如下方法:

// 单挑删除 public int del(int id, Integer isadmin); // 多条删除 public int dels(String[] ids);

  在UserMapper.xml配置文件中添加如下SQL语句

delete from userinfo where id=#{id} and isadmin=#{isadmin} delete from userinfo where id in #{item}

项目工程的完整文件可以点这里 链接:https://pan.baidu.com/s/1iw82k7R_ohRcSMwm7RfMag 提取码:jrdc

点这里可以去我的网页上看看~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3