目录标题
0.讲给世界听:
什么是快,什么是慢。
如果Javaweb项目是我写这篇大博客的重要节点的话,那么这篇博客就是我Java知识体系中的一道分水岭。
这篇博客注定了写起来会很麻烦,我现在还差最后一章:十五章学习结束就可以完成培训内容了,我现在已经开始了实战阶段的经历。没有任何培训的伙伴有写他的想法。。网上也没有找到类似的内容。
我要完成他吗,即使写完了也没有什么人看。有什么意义呢?
我要完成他吧,毕竟我们最后还是要以自己的方式来理解世界的。
而且不写出来我的Java知识体系博客没有办法闭合,我的面试没有抓手。毕竟自己是一个遗忘属性点满地点人啊。
什么是快,什么是慢。快即是慢,慢即是快。写完这个博客再开始学习下一章吧。
一.开发背景
是培训进度使然,亦是我学习Java的必然。
附录:培训给的学习资料。这个可以上网继续搜索的。
链接:https://pan.baidu.com/s/1UDJ_rKJjIJO-TwVazmuxvA
提取码:1111
1.1任务要求视频(只有这一个视频):
后台视频
1.2山东医院问题“
系统的用户和权限:
管理员:所有权限
前台挂号员:密码管理、挂号信息管理
住院办理员:住院办理、住院结算、密码管理
医药管理员:药品管理、在院发药、密码管理
医生:收费项登记、密码管理
做登录的人员的 过滤器:以及 判断
当前登录人 的状态,是否被删除 ,
当前登录人的角色 是否被 禁用,,
当前登录人 对应的 菜单 资源 是否 被 禁用
项目中的问题:
发药库存的问题 :
开药之后的药品数量 : 就不能退药 了
发药之后 库存应该是 现在的库存 - 医生给开的药品数量
收费项目登记 :只登记 所做的检查 的 项目
住院结算中 详情中的 感冒药 为 单独 查询 药品表 查询出来,,展示 出来
分页显示:可以 封装一个 包装类, 把收费项目的类 和 药品 的类 包含进去 从而 就可以 分页展示
//去掉收费项目详情 中的 分页
发药的时候 只能给 住院的 人 发药 。所以:在院发药中 查出来的 是 住院表 中的 信息
发药的问题:发药的时候 要异步检测一下 余额是否 大于 当前药品的价格否则 ,不能发药成功
住院结算:详情展示:跟 收费项目 登记中的 详情 是不一样的
科室表 不能写死
1.36人打分卡:
我主要完成系统的用户和权限问题,对应打分卡的p1,p6
二.系统分析
这里是缺失的部分。样式,要求都给我们了。没有进行分析的过程。
以后的项目有这个过程,我会写上的。
这里写上为了结构的完整性。
2.1需求分析:
医院管理平台,具体的完成情况见视频。
2.2功能分析:
随便选一个任务卡,完成他就可以了。
三.系统设计:
3.1用例图设计系统功能
山东医院后台是一个管理医院内部人员使用的系统。也就是说不是所有人都能使用他,不同的人有不同的身份,管理不同的功能。主要分为管理员,药品管理员,医生,医院前台,住院办理员这五类。
其角色权限划分如下:
1.管理员:用户管理,角色管理,资源管理,门诊医生管理,收费项管理,密码管理。
2.药品管理员:药品管理,在院发药,密码管理。
3.医生:收费项目登记,密码管理。
4.医院前台:挂号信息管理,密码管理。
住院办理员:住院办理,住院结算,密码管理。
我主要复制角色权限管理部分,用户管理,角色管理,资源管理,密码管理功能。
下面以管理员为例绘制其所对应的用例图如下:
3.2绘制系统流程图
本系统首先要进行验证码的校验,校验完后开始对用户的角色进行识别,角色识别合格后对用户的身份进行识别,如果用户正常存在则对用户是否正常使用进行识别。满足以上识别条件后,进入后台系统后,在系统首页的菜单栏可以选择各种链接来进行各种操作。由于不同权限的用户对于系统有
不同的功能,下面以我主要做的管理员为例。(门诊医生管理,收费项管理这俩功能没有做,就不写上了)
3.3系统演示
具体的操作的话我就不说了,因为我会直接放视频,我给的资料直接运行也可以得到结果。
3.3.1p6-登录功能
关于以下功能的演示:
用户的角色校验功能
用户名,密码,验证码为空校验及错误校验+提示
验证码更换
系统正常拦截非登录校验
登录到系统首页
用户的真实姓名显示
退出登录
视频如下:
ssm_登录模块视频
3.3.2p6-密码管理
关于以下功能的演示:
原密码,新密码,重复密码的非空验证和强度验证
新密码和原密码,新密码和确认密码的一致性验证
原密码的准确性验证
修改密码成功
视频如下:
ssm_密码管理模块
3.3.3p1-逻辑实现
关于以下功能的演示:
左侧菜单栏的显示
登录不同的角色,查看左侧不同的菜单
实现,新增加的菜单,赋予新的角色,创建新用户拥有新角色,左侧得到相对应的菜单
失效菜单,不可以显示
禁用角色,所有该角色下用户不可以登录
禁用角色,该用户不可以登录
视频如下:
ssm_用户角色逻辑实现
3.3.4p1-用户管理
关于以下功能的演示:
视频如下:
ssm_用户管理
3.3.5p1-角色管理
关于以下功能的演示:
视频如下:
ssm_角色管理
3.3.6p1-资源管理
关于以下功能的演示:
视频如下:
ssm_资源管理
3.4系统开发环境
类似这样的:
我的idea是2019.3.4版本,试用
数据库是5.7的,windows系统。
3.5文件家组织结构
在编写代码之前,首先需要将系统中可能用到的文件夹创建好,这样可以方便网站开发工作,同时规范网站的整体架构,本系统的文件夹组织结构如下:
四.数据库的分析与设计
4.1数据库分析
这个都是给好的数据库设计表,按照页面也特别好猜测数据库。这是我当时分析时画的。我要做的就是权限相关的那几个表。因为他们正好是一个闭环。
4.2数据库设计
整体设计需要十一个表,我做和权限相关的四个表。之前的Javaweb前置项目里我说过权限模块。这里不用重复。ER图不画了。
4.2.1逻辑设计
用户表
角色表
菜单表
角色-菜单表
4.2.2具体数据表
用户表
角色表
菜单表
角色-菜单表
补充:接口设计:
这个以后加上,但是目前理解不到,先空着吧。
五.公共设计
5.1代码生成器
这个在36-Mybatis-13里说过,我不在重复。发一下代码
pom.xml
<!-- 反向生成插件依赖-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>com.liferay</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.3.LIFERAY-PATCHED-2</version>
</dependency>
<resources>
<resource>
<directory>src/main/resources</directory>
<!--所在的目录-->
<includes>
<!--包括目录下的.properties,.xml 文件都会被扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<!--反向生成插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<!--配置文件的路径-->
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
</configuration>
</plugin>
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器:标了序号的部分都需要修改为自己的内容 -->
<generatorConfiguration>
<!--1、数据库驱动jar:添加自己的jar路径 -->
<classPathEntry location="D:\zyrj\A01Java\a07_maven\maven_repository\mysql\mysql-connector-java\8.0.23\mysql-connector-java-8.0.23.jar"/>
<context id="MyBatis" targetRuntime="MyBatis3">
<!--去除注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--2、数据库连接 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/ssm_xm_shandong_hospital?useUnicode=true&characterEncoding=utf-8"
userId="kaikeba"
password="kaikeba">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer;
为 true时把JDBC DECIMAL和NUMERIC类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--3、生成实体类 指定包名 以及生成的地址 (可以自定义地址,但是路径不存在不会自动创建 使用Maven生成在target目录下,会自动创建) -->
<javaModelGenerator targetPackage="com.kkb.pojo" targetProject="src\main\java">
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--4、生成SQLmapper.xml映射文件 -->
<sqlMapGenerator targetPackage="com.kkb.mapper"
targetProject="src\main\resources"></sqlMapGenerator>
<!--5、生成Dao(Mapper)接口文件,-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.kkb.mapper"
targetProject="src\main\java"></javaClientGenerator>
<!--6、要生成哪些表(更改tableName和domainObjectName就可以) -->
<!-- tableName:要生成的表名
enableCountByExample:Count语句中加入where条件查询,默认为true开启
enableUpdateByExample:Update语句中加入where条件查询,默认为true开启
enableDeleteByExample:Delete语句中加入where条件查询,默认为true开启
enableSelectByExample:Select多条语句中加入where条件查询,默认为true开启
selectByExampleQueryId:Select单个对象语句中加入where条件查询,默认为true开启 -->
<!-- <table tableName="Team" enableCountByExample="false" enableUpdateByExample="false"-->
<!-- enableUpdateByPrimaryKey="false" enableDeleteByExample="false" enableDeleteByPrimaryKey="false"-->
<!-- enableSelectByExample="false" selectByExampleQueryId="false">-->
<!-- <property name="useActualColumnNames" value="true"/>-->
<!-- </table>-->
<table tableName="menu">
</table>
<table tableName="role">
</table>
<table tableName="user">
</table>
</context>
</generatorConfiguration>
其自动生成的文件如下:
5.2用户工具类
我在代码里的很多地方用到了使用session获取用户名,,角色id的方法
package com.kkb.util;
import javax.servlet.http.HttpSession;
/**
* 用户工具类
* 功能:存取用户名,角色id
*/
public class UserUtil {
public static void setUserName(HttpSession session, String username){
session.setAttribute("adminUserName",username);
}
public static String getUserName(HttpSession session){
String userName = (String) session.getAttribute("adminUserName");
return userName;
}
public static void setRoleId(HttpSession session, Integer rId){
session.setAttribute("rId",rId);
}
public static int getRoleId(HttpSession session){
return (int) session.getAttribute("rId");
}
}
5.3返回结果的统一封装类
一共有五个。这里放第一个:返回结果的统一封装类:
他可以:
返回集合,返回单个对象,返回分页对象
返回的状态码为200,展示给用户的信息为ok。
还可以返回菜单集合,用户集合,角色集合
package com.kkb.vo;
import com.github.pagehelper.PageInfo;
import com.kkb.pojo.Menu;
import com.kkb.pojo.Role;
import com.kkb.pojo.User;
import java.util.List;
/**
* 返回结果的统一封装类
*/
public class ResultVO<T> {
private List<T> list; //返回集合
private T obj;//返回单个对象
private PageInfo<T> pageInfo;// 返回分页对象
private Integer code=200;// 表示返回的状态码
private String msg="ok";// 表示可以展示给用户的信息
private List<Menu> menuList; // 返回菜单集合1
private List<Menu> menu; // 返回菜单集合1
private List<User> userList; // 返回用户集合
private List<Role> roleList; // 返回角色集合
public ResultVO(PageInfo<T> pageInfo, List<Role> roleList) {
this.pageInfo = pageInfo;
this.roleList = roleList;
}
public ResultVO(List<Menu> menuList,List<Menu> menu,T obj) {
this.menuList = menuList;
this.menu = menu;
this.obj = obj;
}
public ResultVO(List<T> list, List<User> userList) {
this.list = list;
this.userList = userList;
}
public ResultVO(T obj, List<Menu> menuList) {
this.obj = obj;
this.menuList = menuList;
}
public PageInfo<T> getPageInfo() {
return pageInfo;
}
public void setPageInfo(PageInfo<T> pageInfo) {
this.pageInfo = pageInfo;
}
public ResultVO() {
}
public ResultVO(T obj) {
this.obj = obj;
}
public ResultVO(List<T> list, T obj) {
this.list = list;
this.obj = obj;
}
public ResultVO(List<T> list) {
this.list = list;
}
public ResultVO(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public ResultVO(List<T> list, T obj, List<User> userList) {
this.list = list;
this.obj = obj;
this.userList = userList;
}
public List<Menu> getMenu() {
return menu;
}
public void setMenu(List<Menu> menu) {
this.menu = menu;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
public List<Menu> getMenuList() {
return menuList;
}
public void setMenuList(List<Menu> menuList) {
this.menuList = menuList;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "ResultVO{" +
"list=" + list +
", obj=" + obj +
", code=" + code +
", msg='" + msg + '\'' +
", menuList=" + menuList +
", userList=" + userList +
", roleList=" + roleList +
'}';
}
}
六.具体代码设计
6.1系统登录模块
这里是总-分-总的模式
6.1.1登录流程
登录大体的思路是这样的。
首先进行登录的时候,未登录/登录不成功的人是不可以访问系统的。
登录时本系统首先要进行验证码的校验,校验完后开始对用户的角色进行识别,角色识别合格后对用户的身份进行识别,如果用户正常存在则对用户是否正常使用进行识别。满足以上识别条件后,进入后台系统,在系统首页显示用户的真实姓名,点击退出返回登录页面。
6.1.2系统正常拦截非登录校验
这个用了过滤器方法来实现此功能,逻辑是这样的。当我们成功登录页面后,会把用户名信息以session形式保存。未成功登录页面时,session里没有对应的用户名信息。过滤器通过判断session来过滤登录信息。如果用户名不为空,则正常登录,否则显示对应错误信息。
过滤器代码如下:
web.xml里没有与之相关的过滤器配置。我把过滤路径放在@WebFilter里了。
web.xml里有的两个过滤器是为了post请求中文乱码问题,使用Rest风格的URI 将页面普通的post请求转为指定的delete或者put请求。
package com.kkb.filter;
import com.kkb.util.UserUtil;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter({
"/pages/index.html","/pages/doctor/*","/pages/hospital/*","/pages/medicine/*","/pages/registration/*","/pages/resource/*","/pages/role/*","/pages/user/*"})
public class AccessControllerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化过滤器");
}
// 通过判断session来过滤登录信息
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request1=(HttpServletRequest) request ;
HttpServletResponse response1=(HttpServletResponse) response;
String userName = UserUtil.getUserName(request1.getSession());
StringBuffer requestURL = request1.getRequestURL();
String s = requestURL.toString();
if(userName!=null||s.equals("http://localhost/role/getroleinfo.do")){
chain.doFilter(request, response);
}else {
response1.sendError(404,"很遗憾,权限不足");
}
}
@Override
public void destroy() {
System.out.println("过滤器销毁");
}
}
与之相关的登录代码
UserUtil.setUserName(request.getSession(), uLoginname);
UserUtil.setRoleId(request.getSession(),role);
6.1.3验证码更换及校验
关于验证码的部分,我全都放在了前端。
输入及显示验证码如下:
<input type="text" id="inputVerify" name="verify" class="input-medium" placeholder="验证码">
<span id="verify" style="margin-left: 10px; font-size: 20px; color: #1c6a9e;" onclick="changeVerify()">7777</span>
验证码验证
function isVerify() {
let initData = $("#verify").html();
let inputData = $("#inputVerify").val();
if(inputData == ''){
alert("请输入验证码");
return false;
} else {
if(inputData.toUpperCase() == initData.toUpperCase()){
return true;
} else{
alert("验证码输入有误,请重新输入")
return false;
}
}
}
生成验证码
function changeVerify() {
//生成4位i随机数
let str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
let arr = str.split("");
let result = "";
for(let i=0;i<4;i++)
{
let n = Math.floor(Math.random() * arr.length);
result += arr[n];
}
$("#verify").html(result);
}
放入总校验
$(function (){
$("#inputVerify").blur(function() {
isVerify();
});
});
6.1.4用户的角色校验功能
不是一上来就可以直接校验角色的,要先显示角色列表。
获取角色列表的前端方法:
请选择角色:<select id="role">
</select>
$(function (){
$.getJSON("/role/getroleinfo.do",null,function (vo){
let list=vo.list;
let str="";
for (let i=0;i<list.length;i++){
str+="<option value=\""+list[i].rId+"\">"+list[i].rName+"\n";
}
$("#role").html(str);
});
})
获取角色列表的后端方法:
角色controller:
@Resource
private RoleService roleService;
/**
* 获取全部的角色信息
* @return
*/
@RequestMapping("getroleinfo.do")
public ResultVO<Role> getRoleInfo(){
List<Role> roles = roleService.queryAll();
return new ResultVO<>(roles);
}
角色service:
@Resource
private RoleMapper roleMapper;
/**
* 查询所有的角色信息
* @return
*/
public List<Role> queryAll(){
List<Role> roles = roleMapper.selectByExample(null);
return roles;
}
角色mapper及对应的xml
List<Role> selectByExample(RoleExample example);
<select id="selectByExample" parameterType="com.kkb.pojo.RoleExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from role
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${
orderByClause}
</if>
</select>
之后就是进行角色的判断。
他的思路是这样的:
前端在登录方法传入用户名,密码,用户角色。登录成功跳转到系统首页。失败返回对应错误信息。
<h2 class="form-signin-heading"> 登录系统</h2>
<input id="uLoginname" type="text" name="username" class="input-block-level" placeholder="账号"><span id="uNameMsg"></span>
<input id="uPassword" type="password" name="password" class="input-block-level" placeholder="密码"><span id="uPassMsg"></span>
请选择角色:<select id="role">
</select>
<input type="text" id="inputVerify" name="verify" class="input-medium" placeholder="验证码">
<span id="verify" style="margin-left: 10px; font-size: 20px; color: #1c6a9e;" onclick="changeVerify()">7777</span>
<p> <button id="access" class="btn btn-large btn-primary" type="button" onclick="login()">登录</button></p>
function login(){
let uLoginname = $("#uLoginname").val();
let uPassword=$("#uPassword").val();
let role = $("#role option:selected").val();
$.getJSON("/login.do",{
uLoginname:uLoginname,uPassword:uPassword,role:role},function (vo){
if(vo.code==200){
let uId=vo.obj.uId;
alert("登陆成功");
window.location.href="/pages/index.html?rId="+vo.obj.rId+"&uId="+uId;
}else {
alert(vo.msg);
}
});
}
后端接收这些参数。
1,后端获取角色列表,并遍历角色列表
2,如果登录角色id=遍历到的角色id,正常使用的往下走,否则结果集中填写对应错误信息
3,根据传入的三个参数,进行模糊查询,返回符合条件用户信息
4,获取角色的状态码
5,如果该角色是被正常使用的往下走,否则结果集中填写对应错误信息
6,如果该用户正常存在的往下走,否则结果集中填写对应错误信息
7,通过用户的状态码判断用户是否正常存在。如果该用户是被正常使用的往下走,否则结果集中填写对应错误信息
8,通过用户工具类存入对应用户信息,角色信息到session。并把用户信息存入结果集中
所以判断还是很多的。
登录controller
@Resource
private UserService userService;
@Resource
private RoleService roleService;
/**
* 登录操作
* @param request
* @return
*/
@RequestMapping("login.do")
public ResultVO<User> login(HttpServletRequest request) {
// 1,获取登录名称,密码。登录角色Id
String uLoginname = request.getParameter("uLoginname");
String uPassword = request.getParameter("uPassword");
int role = Integer.parseInt(request.getParameter("role"));
// 2,获取角色列表
List<Role> roles = roleService.queryAll();
// 3,定义结果集
ResultVO<User> vo = new ResultVO<>();
for (Role r : roles) {
// 4,遍历角色列表
if (r.getrId() == role) {
// 5,如果登录角色id=遍历到的角色id,正常使用的往下走,否则结果集中填写对应错误信息
// 6,模糊查询,返回符合条件用户信息
List<User> users = userService.queryLPR(uLoginname, uPassword, role);
// 7,获取角色的状态码
Integer rState = r.getrState();
if (rState == 0) {
// 8.1如果该角色是被正常使用的往下走,否则结果集中填写对应错误信息
if (users.size() > 0) {
// 8.2如果该用户正常存在的往下走,否则结果集中填写对应错误信息
if (users.get(0).getuState() == 0) {
// 8.3如果该用户是被正常使用的往下走,否则结果集中填写对应错误信息
// 9,设置用户的登录名称,和其角色id,并把用户信息存入结果集中
UserUtil.setUserName(request.getSession(), uLoginname);
UserUtil.setRoleId(request.getSession(),role);
vo.setObj(users.get(0));
System.out.println(vo);// 看一下结果
} else {
vo.setCode(500);
vo.setMsg("该用户已被禁用或删除");
}
} else {
vo.setCode(500);
vo.setMsg("密码错误或角色不匹配,请重新输入");
}
} else {
vo.setCode(500);
vo.setMsg("该角色已被删除或禁用");
}
}
}
return vo;
}
获取角色列表方法同上。
模糊查询,返回符合条件用户信息方法
用户service
@Resource
private UserMapper userMapper;
public List<User> queryLPR(String uLoginname,String uPassword,int rId){
UserExample example=new UserExample();
UserExample.Criteria criteria = example.createCriteria();
criteria.andULoginnameEqualTo(uLoginname);
criteria.andUPasswordEqualTo(uPassword);
criteria.andRIdEqualTo(rId);
List<User> users = userMapper.selectByExample(example);
return users;
}
用户mapper
List<User> selectByExample(UserExample example);
<select id="selectByExample" parameterType="com.kkb.pojo.UserExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${
orderByClause}
</if>
</select>
这里讲一下:
1,Criteria 表示通过面向对象化的设计,将数据查询条件封装为一个对象。简单来讲,Criteria Query可以看作是传统SQL的对象化表示
2,distinct是为了降重,Base_Column_List是表示*,但是用这个字段效率更高,,如果只有一个参数,那么_parameter 就代表该参数,如果有多个参数,那么_parameter 可以get(0)得到第一个参数, 最后就是排序了。
6.1.5用户名,密码为空校验及错误校验+提示
这里都是前端内容。没什么好说的,直接附代码:
<input id="uLoginname" type="text" name="username" class="input-block-level" placeholder="账号"><span id="uNameMsg"></span>
<input id="uPassword" type="password" name="password" class="input-block-level" placeholder="密码"><span id="uPassMsg"></span>
function validataPwd() {
var pwd = $("#uPassword").val();
var msg = $("#uPassMsg");
if(pwd == "") {
msg.html("密码不能为空").css("color", "red");
return false;
} else if(pwd.length < 8) {
msg.html("密码长度必须大于8位").css("color", "red");
return false;
} else {
msg.html("ok").css("color", "green");
return true;
}
}
function validatauLoginname() {
var pwd = $("#uLoginname").val();
var msg = $("#uNameMsg");
if(pwd == "") {
msg.html("账户名不能为空").css("color", "red");
return false;
} else if(pwd.length < 8) {
msg.html("账户名长度必须大于8位").css("color", "red");
return false;
} else {
msg.html("ok").css("color", "green");
return true;
}
}
总验证:
$(function (){
$("#uPassword").blur(function() {
validataPwd();
});
$("#uLoginname").blur(function() {
validatauLoginname();
});
$("#inputVerify").blur(function() {
isVerify();
});
});
6.1.6登录到系统首页
这个是有些麻烦的,前端是一个固定的方法,BUI框架。
失效菜单不可以展示。
BUI.use('common/main',function(){
//let configTest = new Array();
$(function () {
$.getJSON("/getInfo.do",null,function (vo) {
// 获取封装菜单数据
let menuList = vo.obj.role.menuList;
let totalItems = new Array();
for (let i = 0; i < menuList.length; i++) {
if (menuList[i].m_state == 0){
// 失效菜单,不可以展示
let itemList = {
id:menuList[i].m_id.toString(),text:menuList[i].m_name,href:menuList[i].m_url};
totalItems.push(itemList);
}
}
console.log("totalList")
console.log(totalItems)
let config = [
{
id:'1',menu:[
{
text:'快速通道',items: totalItems}
]}
];
new PageUtil.MainPage({
modulesConfig : config
});
})
})
});
后端逻辑如下:
首先,通过用户的roleId查找相连的资源list,然后通过角色id查询对应的菜单资源集合,并把菜单资源添加到对应的角色中,最后把对应的角色信息添加给对应的用户,并把用户返回给前端
登录croller:
/**
* 权限管理功能
* @param request
* @return
*/
@RequestMapping("getInfo.do")
public ResultVO getUserInfo(HttpServletRequest request){
// 获取登录后的用户信息
HttpSession session = request.getSession();
User userInfo = (User) session.getAttribute("userInfo");
// 通过用户的roleId查找相连的资源list,
// 实际上涉及到了三表操作:通过角色id查询对应的菜单资源集合,并把菜单资源添加到对应的角色中,
// 然后把对应的角色信息添加给对应的用户,并把用户返回给前端
Role role = roleService.findById(userInfo.getrId());
userInfo.setRole(role);
System.out.println(userInfo);
return new ResultVO(userInfo);
}
查询角色service:
查询未被删除的角色,根据角色id查询对应菜单。如果该角色可以被正常使用,
把对应的的菜单资源放到角色中。
/**
* 通过roleId查找相连的资源list
* @param id
* @return
*/
public Role findById(Integer id){
// 先查询role
// 查询未被删除的角色
RoleExample roleExample = new RoleExample();
RoleExample.Criteria criteria = roleExample.createCriteria();
criteria.andRStateEqualTo(0);
criteria.andRIdEqualTo(id);
List<Role> roles = roleMapper.selectByExample(roleExample);
Role role = roles.get(0);
// 通过roleId 查询 menu菜单
List<Menu> menus = roleMapper.selectMenusByRoleId(id);
System.out.println(menus);
role.setMenuList(menus);
System.out.println(role);
return role;
}
mapper:
第一个,查询未被删除的角色,用到是自动生成的方法。
第二个,通过roleId 查询 menu菜单的方法需要我们自定义。
List<Menu> menus = roleMapper.selectMenusByRoleId(id);
/**
* 通过roleId 查询菜单列表
* @param id
* @return
*/
List<Menu> selectMenusByRoleId(@Param("id") Integer id);
<select id="selectMenusByRoleId" parameterType="java.lang.Integer" resultType="map">
select m.m_id,m.m_name,m.m_url,m.m_state from role_menu rm,menu m
where rm.r_id = #{
id} and rm.m_id = m.m_id and m.m_state = 0;
</select>
6.1.7用户的真实姓名显示
这个没什么难度,直接附代码了。
前端:
<div style="float:right; color:#fff;">欢迎您,<span class="dl-log-user" id="trueName">
$.getJSON("/getusername.do", null, function (vo) {
$("#trueName").html(vo.obj.uTruename);
});
后端:
/**
* 获取用户的真实姓名
* @param request
* @return
*/
@RequestMapping("getusername.do")
public ResultVO<User> getUserName(HttpServletRequest request) {
// 获取用户的登录名,根据用户的登录名称获取用户的信息返回给前台,前台展示真实姓名
String userName = UserUtil.getUserName(request.getSession());
List<User> users = userService.queryByLoginName(userName);
return new ResultVO<>(users.get(0));
}