一、实现用户登录流程图
二、搭建MyBatis逆向工程
简介:根据表生成mapper层三部分代码:实体类,mapper接口,映射文件。
1.创建meacen项目
2.修改pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjpowernode.crm</groupId>
<artifactId>crm-mybatis-generator</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<!--myBatis逆向工程插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.添加相关的配置文件
jdbc.driverLocation是mysql连接数据库jar包的位置
jdbc.driverLocation=E:/Program/Project/Projectjava/reposity/mysql/mysql-connector-java/5.1.32/mysql-connector-java-5.1.32.jar
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://127.0.0.1:3307/crm2008?useUnicode=true&characterEncoding=UTF-8
jdbc.userId=root
jdbc.password=123456
targetPackage:代码保存的目录
table:表的信息 需要哪一个表就打开那个
<?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>
<!--指定mysql数据库驱动-->
<!--<classPathEntry location="E://repository-p2p//mysql//mysql-connector-java//5.1.43//mysql-connector-java-5.1.43.jar"/>-->
<!--导入属性配置-->
<properties resource="generator.properties"></properties>
<!--指定特定数据库的jdbc驱动jar包的位置-->
<classPathEntry location="${jdbc.driverLocation}"/>
<context id="default" targetRuntime="MyBatis3">
<!-- optional,旨在创建class时,对注释进行控制,false生成注释,true无注释 -->
<commentGenerator>
<property name="suppressDate" value="false"/>
<property name="suppressAllComments" value="false"/>
</commentGenerator>
<!--jdbc的数据库连接 -->
<jdbcConnection
driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.userId}"
password="${jdbc.password}">
</jdbcConnection>
<!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径|指定生成到的工程名称
-->
<javaModelGenerator targetPackage="com.bjpowernode.crm.settings.domain"
targetProject="E:/Program/Project/Projectjava/CRM/crm-project/crm/src/main/java">
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="false"/>
<!-- 是否对model添加 构造函数 true添加,false不添加-->
<property name="constructorBased" value="false"/>
<!-- 是否对类CHAR类型的列的数据进行trim操作 -->
<property name="trimStrings" value="true"/>
<!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 -->
<property name="immutable" value="false"/>
</javaModelGenerator>
<!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
<sqlMapGenerator targetPackage="com.bjpowernode.crm.settings.mapper"
targetProject="E:/Program/Project/Projectjava/CRM/crm-project/crm/src/main/java">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
-->
<javaClientGenerator targetPackage="com.bjpowernode.crm.settings.mapper"
targetProject="E:/Program/Project/Projectjava/CRM/crm-project/crm/src/main/java" type="XMLMAPPER">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="tbl_user" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<!--
<table tableName="tbl_clue" domainObjectName="Clue"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_clue_activity_relation" domainObjectName="ClueActivityRelation"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_clue_remark" domainObjectName="ClueRemark"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
-->
<!--
<table tableName="tbl_contacts" domainObjectName="Contacts"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_contacts_activity_relation" domainObjectName="ContactsActivityRelation"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_contacts_remark" domainObjectName="ContactsRemark"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
-->
<!--
<table tableName="tbl_customer" domainObjectName="Customer"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_customer_remark" domainObjectName="CustomerRemark"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
-->
<!--
<table tableName="tbl_dictionary_type" domainObjectName="DictionaryType"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_dictionary_value" domainObjectName="DictionaryValue"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_marketing_activities" domainObjectName="MarketingActivities"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_marketing_activities_remark" domainObjectName="MarketingActivitiesRemark"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
-->
<!--
<table tableName="tbl_transaction" domainObjectName="Transaction"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_transaction_history" domainObjectName="TransactionHistory"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="tbl_transaction_remark" domainObjectName="TransactionRemark"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
-->
</context>
</generatorConfiguration>
4.点击运行
三、实现Mapper层和Service层
Mapper
/**
* 根据账号和密码查询用户
*/
User selectUserByLoginActAndPwd(Map<String,Object> map);
<select id="selectUserByLoginActAndPwd" parameterType="map" resultMap="BaseResultMap">
select<include refid="Base_Column_List"></include>
from tbl_user
where login_act=#{loginAct} and login_pwd=#{loginPwd}
</select>
<!--注册mapper.xml文件-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjpowernode.crm.settings.mapper"></property>
</bean>
解释
//@Service //交给Spring去创建对象
//public class UsersServiceImpl implements UsersService {
//切记切记:在所有的业务逻辑层中一定会有数据访问层的对象
/**
* //1.读取核心配置文件
* InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
* //2.创建工厂对象
* SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
* //3.取出sqlSession
* sqlSession = factory.openSession(true);//自动提交事务
* //4.取出动态代理的对象,完成接口中方法的调用,实则是调用xml文件中相的标签的功能
* usersMapper = sqlSession.getMapper(UsersMapper.class);
*/
//在以前我们通过上面的获取usersmapper,我们需要的是数据访问层的功能
//现在我们通过注解,spring帮我们完成注入
/*
MapperScannerConfigurer类已经完成了动态代理的实现
<!--注册mapper.xml文件-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjpowernode.mapper"></property>
</bean>
*/
/*
@Autowired
UsersMapper usersMapper;
@Override
public int insert(Users users) {
int num = usersMapper.insert(users);
}
}
*/
别忘了改这个地方
<!--注册实体类-->
<property name="typeAliasesPackage" value="com/bjpowernode/crm/settings/domain"></property>
Service
public interface UserService {
User selectUserByLoginActAndPwd(Map<String,Object> map);
}
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User selectUserByLoginActAndPwd(Map<String, Object> map) {
return userMapper.selectUserByLoginActAndPwd(map);
}
}
<!--添加包扫描-->
<context:component-scan base-package="com.bjpowernode.crm.settings.service"></context:component-scan>
四、完成Controller层
1.搭建逻辑框架UserController
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/settings/qx/user/toLogin.do")
public String toLogin(){
//请求转发到登录页面
return "settings/qx/user/login";
}
@RequestMapping("/settings/qx/user/login.do")
@ResponseBody
public Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request){
//封装参数
Map<String,Object> map=new HashMap<>();
map.put("loginAct",loginAct);
map.put("loginPwd",loginPwd);
//调用service层方法,查询用户
User user=userService.selectUserByLoginActAndPwd(map);
//根据查询结果,生成响应信息
if(user==null){
//登录失败,用户名或者密码错误
}else{//进一步判断账号是否合法
//user.getExpireTime() //2019-10-20
// new Date() //2020-09-10
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowStr=sdf.format(new Date());
if(nowStr.compareTo(user.getExpireTime())>0){
//登录失败,账号已过期
}else if("0".equals(user.getLockState())){
//登录失败,状态被锁定
}else if(!user.getAllowIps().contains(request.getRemoteAddr())){
//登录失败,ip受限
}else{
//登录成功
}
}
}
}
2.添加实体类
package com.bjpowernode.crm.commons.domain;
public class ReturnObject {
private String code; //处理成功或者失败的标记 1 成功 0失败
private String message;//提示信息
private Object returnData; //其他数据
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getReturnData() {
return returnData;
}
public void setReturnData(Object returnData) {
this.returnData = returnData;
}
}
3.完善UserController
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/settings/qx/user/toLogin.do")
public String toLogin(){
//请求转发到登录页面
return "settings/qx/user/login";
}
@RequestMapping("/settings/qx/user/login.do")
@ResponseBody
public Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request){
//封装参数
Map<String,Object> map=new HashMap<>();
map.put("loginAct",loginAct);
map.put("loginPwd",loginPwd);
//调用service层方法,查询用户
User user=userService.selectUserByLoginActAndPwd(map);
//根据查询结果,生成响应信息
ReturnObject returnObject =new ReturnObject();
if(user==null){
//登录失败,用户名或者密码错误
returnObject.setCode("0");
returnObject.setMessage("用户名或者密码错误");
}else{//进一步判断账号是否合法
//user.getExpireTime() //2019-10-20
// new Date() //2020-09-10
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowStr=sdf.format(new Date());
if(nowStr.compareTo(user.getExpireTime())>0){
//登录失败,账号已过期
returnObject.setCode("0");
returnObject.setMessage("账号已过期");
}else if("0".equals(user.getLockState())){
//登录失败,状态被锁定
returnObject.setCode("0");
returnObject.setMessage("状态被锁定");
}else if(!user.getAllowIps().contains(request.getRemoteAddr())){
//登录失败,ip受限
returnObject.setCode("0");
returnObject.setMessage("ip受限");
}else{
//登录成功
returnObject.setCode("1");
}
}
return returnObject;
}
}
4.优化UserController
public class DateUtils {
//对指定的date对象进行格式化 yyyy-MM-dd HH:mm:ss"
public static String formateDateTime(Date date){
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr=sdf.format(date);
return dateStr;
}
//对指定的date对象进行格式化 yyyy-MM-dd HH:mm:ss"
public static String formateDate(Date date){
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String dateStr=sdf.format(date);
return dateStr;
}
//对指定的date对象进行格式化HH:mm:ss"
public static String formateTime(Date date){
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
String dateStr=sdf.format(date);
return dateStr;
}
}
public class Contants {
//保存ReturnObject类中的Code值
public static final String RETURN_OBJECT_CODE_SUCCESS="1";//成功的
public static final String RETURN_OBJECT_CODE_FAIL="0";//失败的
}
ReturnObject returnObject =new ReturnObject();
if(user==null){
//登录失败,用户名或者密码错误
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("用户名或者密码错误");
}else{//进一步判断账号是否合法
//user.getExpireTime() //2019-10-20
// new Date() //2020-09-10
String nowStr=DateUtils.formateDateTime(new Date());
if(nowStr.compareTo(user.getExpireTime())>0){
//登录失败,账号已过期
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("账号已过期");
}else if("0".equals(user.getLockState())){
//登录失败,状态被锁定
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("状态被锁定");
}else if(!user.getAllowIps().contains(request.getRemoteAddr())){
//登录失败,ip受限
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("ip受限");
}else{
//登录成功
returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);
}
}
return returnObject;
}
5.修改前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<meta charset="UTF-8">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
//给"登录"按钮添加单击事件
$("#loginBtn").click(function () {
//收集参数
var loginAct=$.trim($("#loginAct").val());
var loginPwd=$.trim($("#loginPwd").val());
var isRemPwd=$("#isRemPwd").prop("checked");
//表单验证
if(loginAct==""){
alert("用户名不能为空");
return;
}
if(loginPwd==""){
alert("密码不能为空");
return;
}
//发送请求
$.ajax({
url:'settings/qx/user/login.do',
data:{
loginAct:loginAct,
loginPwd:loginPwd,
isRemPwd:isRemPwd
},
type:'post',
dataType:'json',
success:function (data) {
if(data.code=="1"){
//跳转到业务主页面
window.location.href="workbench/index.do";
}else{
//提示信息
$("#msg").text(data.message);
}
}
});
});
});
</script>
</head>
<body>
<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
</div>
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">©2019 动力节点</span></div>
</div>
<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
<div style="position: absolute; top: 0px; right: 60px;">
<div class="page-header">
<h1>登录</h1>
</div>
<form action="workbench/index.html" class="form-horizontal" role="form">
<div class="form-group form-group-lg">
<div style="width: 350px;">
<input class="form-control" id="loginAct" type="text" placeholder="用户名">
</div>
<div style="width: 350px; position: relative;top: 20px;">
<input class="form-control" id="loginPwd" type="password" placeholder="密码">
</div>
<div class="checkbox" style="position: relative;top: 30px; left: 10px;">
<label>
<input type="checkbox" id="isRemPwd"> 十天内免登录
</label>
<span id="msg" style="color: red"></span>
</div>
<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block" style="width: 350px; position: relative;top: 45px;">登录</button>
</div>
</form>
</div>
</div>
</body>
</html>
@Controller
public class WorkbenchIndexController {
@RequestMapping("/workbench/index.do")
public String index(){
//跳转到业务主页面
return "workbench/index";
}
}
<context:component-scan base-package="com.bjpowernode.crm.workbench.web.controller"></context:component-scan>
6.登录之后显示业务与主页面名称
+
先把这个复制过去然后再改成jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<meta charset="UTF-8">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
//页面加载完毕
$(function(){
//导航中所有文本颜色为黑色
$(".liClass > a").css("color" , "black");
//默认选中导航菜单中的第一个菜单项
$(".liClass:first").addClass("active");
//第一个菜单项的文字变成白色
$(".liClass:first > a").css("color" , "white");
//给所有的菜单项注册鼠标单击事件
$(".liClass").click(function(){
//移除所有菜单项的激活状态
$(".liClass").removeClass("active");
//导航中所有文本颜色为黑色
$(".liClass > a").css("color" , "black");
//当前项目被选中
$(this).addClass("active");
//当前项目颜色变成白色
$(this).children("a").css("color","white");
});
window.open("main/index.html","workareaFrame");
});
</script>
</head>
<body>
<!-- 我的资料 -->
<div class="modal fade" id="myInformation" role="dialog">
<div class="modal-dialog" role="document" style="width: 30%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">我的资料</h4>
</div>
<div class="modal-body">
<div style="position: relative; left: 40px;">
姓名:<b>张三</b><br><br>
登录帐号:<b>zhangsan</b><br><br>
组织机构:<b>1005,市场部,二级部门</b><br><br>
邮箱:<b>zhangsan@bjpowernode.com</b><br><br>
失效时间:<b>2017-02-14 10:10:10</b><br><br>
允许访问IP:<b>127.0.0.1,192.168.100.2</b>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<!-- 修改密码的模态窗口 -->
<div class="modal fade" id="editPwdModal" role="dialog">
<div class="modal-dialog" role="document" style="width: 70%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">修改密码</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="oldPwd" class="col-sm-2 control-label">原密码</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="oldPwd" style="width: 200%;">
</div>
</div>
<div class="form-group">
<label for="newPwd" class="col-sm-2 control-label">新密码</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="newPwd" style="width: 200%;">
</div>
</div>
<div class="form-group">
<label for="confirmPwd" class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="confirmPwd" style="width: 200%;">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="window.location.href='login.html';">更新</button>
</div>
</div>
</div>
</div>
<!-- 退出系统的模态窗口 -->
<div class="modal fade" id="exitModal" role="dialog">
<div class="modal-dialog" role="document" style="width: 30%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">离开</h4>
</div>
<div class="modal-body">
<p>您确定要退出系统吗?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="window.location.href='login.html';">确定</button>
</div>
</div>
</div>
</div>
<!-- 顶部 -->
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">©2022 动力节点</span></div>
<div style="position: absolute; top: 15px; right: 15px;">
<ul>
<li class="dropdown user-dropdown">
<a href="javascript:void(0)" style="text-decoration: none; color: white;" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-user"></span> zhangsan <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="settings/index.html"><span class="glyphicon glyphicon-wrench"></span> 系统设置</a></li>
<li><a href="javascript:void(0)" data-toggle="modal" data-target="#myInformation"><span class="glyphicon glyphicon-file"></span> 我的资料</a></li>
<li><a href="javascript:void(0)" data-toggle="modal" data-target="#editPwdModal"><span class="glyphicon glyphicon-edit"></span> 修改密码</a></li>
<li><a href="javascript:void(0);" data-toggle="modal" data-target="#exitModal"><span class="glyphicon glyphicon-off"></span> 退出</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- 中间 -->
<div id="center" style="position: absolute;top: 50px; bottom: 30px; left: 0px; right: 0px;">
<!-- 导航 -->
<div id="navigation" style="left: 0px; width: 18%; position: relative; height: 100%; overflow:auto;">
<ul id="no1" class="nav nav-pills nav-stacked">
<li class="liClass"><a href="main/index.html" target="workareaFrame"><span class="glyphicon glyphicon-home"></span> 工作台</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-tag"></span> 动态</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-time"></span> 审批</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-user"></span> 客户公海</a></li>
<li class="liClass"><a href="activity/index.html" target="workareaFrame"><span class="glyphicon glyphicon-play-circle"></span> 市场活动</a></li>
<li class="liClass"><a href="clue/index.html" target="workareaFrame"><span class="glyphicon glyphicon-search"></span> 线索(潜在客户)</a></li>
<li class="liClass"><a href="customer/index.html" target="workareaFrame"><span class="glyphicon glyphicon-user"></span> 客户</a></li>
<li class="liClass"><a href="contacts/index.html" target="workareaFrame"><span class="glyphicon glyphicon-earphone"></span> 联系人</a></li>
<li class="liClass"><a href="transaction/index.html" target="workareaFrame"><span class="glyphicon glyphicon-usd"></span> 交易(商机)</a></li>
<li class="liClass"><a href="visit/index.html" target="workareaFrame"><span class="glyphicon glyphicon-phone-alt"></span> 售后回访</a></li>
<li class="liClass">
<a href="#no2" class="collapsed" data-toggle="collapse"><span class="glyphicon glyphicon-stats"></span> 统计图表</a>
<ul id="no2" class="nav nav-pills nav-stacked collapse">
<li class="liClass"><a href="chart/activity/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 市场活动统计图表</a></li>
<li class="liClass"><a href="chart/clue/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 线索统计图表</a></li>
<li class="liClass"><a href="chart/customerAndContacts/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 客户和联系人统计图表</a></li>
<li class="liClass"><a href="chart/transaction/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 交易统计图表</a></li>
</ul>
</li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-file"></span> 报表</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-shopping-cart"></span> 销售订单</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-send"></span> 发货单</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-earphone"></span> 跟进</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-leaf"></span> 产品</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-usd"></span> 报价</a></li>
</ul>
<!-- 分割线 -->
<div id="divider1" style="position: absolute; top : 0px; right: 0px; width: 1px; height: 100% ; background-color: #B3B3B3;"></div>
</div>
<!-- 工作区 -->
<div id="workarea" style="position: absolute; top : 0px; left: 18%; width: 82%; height: 100%;">
<iframe style="border-width: 0px; width: 100%; height: 100%;" name="workareaFrame"></iframe>
</div>
</div>
<div id="divider2" style="height: 1px; width: 100%; position: absolute;bottom: 30px; background-color: #B3B3B3;"></div>
<!-- 底部 -->
<div id="down" style="height: 30px; width: 100%; position: absolute;bottom: 0px;"></div>
</body>
</html>
五、完善功能
1.登录成功之后,所有业务页面显示当前用户的名称
回顾知识点:
pageContext:同一页面不同标签之间传递数据。 request:在同一个请求过程中传递数据。 sesson:在同一个浏览器窗口的不同请求之间传递数据。 application:所有用户共享的数据,并且是频繁使用的
我们把”sessionUser”设置为一个常量,将来改的时候只需要改这个就行
public class Contants {
//保存ReturnObject类中的Code值
public static final String RETURN_OBJECT_CODE_SUCCESS="1";//成功的
public static final String RETURN_OBJECT_CODE_FAIL="0";//失败的
//保存当前用户的key
public static final String SESSION_USER="sessionUser";
}
public Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpSession session){
//封装参数
Map<String,Object> map=new HashMap<>();
map.put("loginAct",loginAct);
map.put("loginPwd",loginPwd);
//调用service层方法,查询用户
User user=userService.selectUserByLoginActAndPwd(map);
//根据查询结果,生成响应信息
ReturnObject returnObject =new ReturnObject();
if(user==null){
//登录失败,用户名或者密码错误
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("用户名或者密码错误");
}else{//进一步判断账号是否合法
//user.getExpireTime() //2019-10-20
// new Date() //2020-09-10
String nowStr= DateUtils.formateDateTime(new Date());
if(nowStr.compareTo(user.getExpireTime())>0){
//登录失败,账号已过期
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("账号已过期");
}else if("0".equals(user.getLockState())){
//登录失败,状态被锁定
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("状态被锁定");
}else if(!user.getAllowIps().contains(request.getRemoteAddr())){
//登录失败,ip受限
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("ip受限");
}else{
//登录成功
returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);
//把User保存到session中
session.setAttribute(Contants.SESSION_USER,user);
}
}
<!-- 顶部 -->
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">©2019 动力节点</span></div>
<div style="position: absolute; top: 15px; right: 15px;">
<ul>
<li class="dropdown user-dropdown">
<a href="javascript:void(0)" style="text-decoration: none; color: white;" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-user"></span> ${sessionScope.sessionUser.name}<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="../settings/index.html"><span class="glyphicon glyphicon-wrench"></span> 系统设置</a></li>
<li><a href="javascript:void(0)" data-toggle="modal" data-target="#myInformation"><span class="glyphicon glyphicon-file"></span> 我的资料</a></li>
<li><a href="javascript:void(0)" data-toggle="modal" data-target="#editPwdModal"><span class="glyphicon glyphicon-edit"></span> 修改密码</a></li>
<li><a href="javascript:void(0);" data-toggle="modal" data-target="#exitModal"><span class="glyphicon glyphicon-off"></span> 退出</a></li>
</ul>
</li>
</ul>
</div>
</div>
添加一个小功能
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<meta charset="UTF-8">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
//给"登录"按钮添加单击事件
$("#loginBtn").click(function () {
//收集参数
var loginAct=$.trim($("#loginAct").val());
var loginPwd=$.trim($("#loginPwd").val());
var isRemPwd=$("#isRemPwd").prop("checked");
//表单验证
if(loginAct==""){
alert("用户名不能为空");
return;
}
if(loginPwd==""){
alert("密码不能为空");
return;
}
//1.第一种方式在这个地方也可以
//显示正在验证
//$("#msg").text("正在努力验证");
//发送请求
$.ajax({
url:'settings/qx/user/login.do',
data:{
loginAct:loginAct,
loginPwd:loginPwd,
isRemPwd:isRemPwd
},
type:'post',
dataType:'json',
success:function (data) {
if(data.code=="1"){
//跳转到业务主页面
window.location.href="workbench/index.do";
}else{
//提示信息
$("#msg").text(data.message);
}
},
//第二种方式在这个地方
beforeSend:function (){ //当ajax向后台发送请求之前,会自动执行本函数
//该函数的返回值能决定ajax是否真正向后台发送请求。
//如果该函数返回true,则ajax会真正向后台发送请求,否则不会发送请求
//显示正在验证
$("#msg").text("正在努力验证");
}
});
});
});
</script>
</head>
<body>
<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
</div>
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">©2019 动力节点</span></div>
</div>
<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
<div style="position: absolute; top: 0px; right: 60px;">
<div class="page-header">
<h1>登录</h1>
</div>
<form action="workbench/index.html" class="form-horizontal" role="form">
<div class="form-group form-group-lg">
<div style="width: 350px;">
<input class="form-control" id="loginAct" type="text" placeholder="用户名">
</div>
<div style="width: 350px; position: relative;top: 20px;">
<input class="form-control" id="loginPwd" type="password" placeholder="密码">
</div>
<div class="checkbox" style="position: relative;top: 30px; left: 10px;">
<label>
<input type="checkbox" id="isRemPwd"> 十天内免登录
</label>
<span id="msg" style="color: red"></span>
</div>
<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block" style="width: 350px; position: relative;top: 45px;">登录</button>
</div>
</form>
</div>
</div>
</body>
</html>
2.实现回车登录
知识点:jquery事件函数的用法
1.**选择器.click(function(){ //给指定的元素添加事件**
//js代码 });
2.选择器.click();//在指定的元素上模拟发生的一次事件
//...............
$(function () {
//给整个浏览器窗口添加键盘按下事件
$(window).keydown(function (e){
//如果按下的是回车键,则提交登录请求
if(e.keyCode==13){
$("#loginBtn").click();
}
});
//给"登录"按钮添加单击事件
$("#loginBtn").click(function () {
//收集参数
var loginAct=$.trim($("#loginAct").val());
var loginPwd=$.trim($("#loginPwd").val());
var isRemPwd=$("#isRemPwd").prop("checked");
//表单验证
if(loginAct==""){
alert("用户名不能为空");
return;
}
if(loginPwd==""){
alert("密码不能为空");
return;
}
//............
3.实现记住密码十天内免登录
如果上次记住密码,自动填上账户和密码,否则,不填。
如何判断上次记住密码?
—上次登录成功,判断是否需要记住密码:如果需要记住密码,则往浏览器写cookie;否则.删除cookie。
而且cookie的值必须是该用户的loginAct和loginPwd。
—下次登录时,判断该用户有没有cookie,如果有则自动填写账号和密码,如果没有则不写。
而且填写的是cookie的值。
returnObject.setMessage("ip受限");
}else{
//登录成功
returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);
//把User保存到session中
session.setAttribute(Contants.SESSION_USER,user);
//如果需要记住密码,则写cookie
if("true".equals(isRemPwd)){
Cookie c1 =new Cookie("loginAct",user.getLoginAct());
c1.setMaxAge(10*24*60*60);
response.addCookie(c1);
Cookie c2= new Cookie("loginPwd",user.getLoginPwd());
c2.setMaxAge(10*24*60*60);
response.addCookie(c2);
}else{
//把没有过期的cookie删除
Cookie c1= new Cookie("loginAct","1");
c1.setMaxAge(0);
response.addCookie(c1);
Cookie c2= new Cookie("loginPwd","1");
c2.setMaxAge(0);
response.addCookie(c2);
}
}
}
return returnObject;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<meta charset="UTF-8">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
//给整个浏览器窗口添加键盘按下事件
$(window).keydown(function (e){
//如果按下的是回车键,则提交登录请求
if(e.keyCode==13){
$("#loginBtn").click();
}
});
//给"登录"按钮添加单击事件
$("#loginBtn").click(function () {
//收集参数
var loginAct=$.trim($("#loginAct").val());
var loginPwd=$.trim($("#loginPwd").val());
var isRemPwd=$("#isRemPwd").prop("checked");
//表单验证
if(loginAct==""){
alert("用户名不能为空");
return;
}
if(loginPwd==""){
alert("密码不能为空");
return;
}
//1.第一种方式在这个地方也可以
//显示正在验证
//$("#msg").text("正在努力验证");
//发送请求
$.ajax({
url:'settings/qx/user/login.do',
data:{
loginAct:loginAct,
loginPwd:loginPwd,
isRemPwd:isRemPwd
},
type:'post',
dataType:'json',
success:function (data) {
if(data.code=="1"){
//跳转到业务主页面
window.location.href="workbench/index.do";
}else{
//提示信息
$("#msg").text(data.message);
}
},
//第二种方式在这个地方
beforeSend:function (){ //当ajax向后台发送请求之前,会自动执行本函数
//该函数的返回值能决定ajax是否真正向后台发送请求。
//如果该函数返回true,则ajax会真正向后台发送请求,否则不会发送请求
//显示正在验证
$("#msg").text("正在努力验证");
}
});
});
});
</script>
</head>
<body>
<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
</div>
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">©2019 动力节点</span></div>
</div>
<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
<div style="position: absolute; top: 0px; right: 60px;">
<div class="page-header">
<h1>登录</h1>
</div>
<form action="workbench/index.html" class="form-horizontal" role="form">
<div class="form-group form-group-lg">
<div style="width: 350px;">
<input class="form-control" id="loginAct" type="text" value="${cookie.loginAct.value}" placeholder="用户名">
</div>
<div style="width: 350px; position: relative;top: 20px;">
<input class="form-control" id="loginPwd" type="password" value="${cookie.loginPwd.value}" placeholder="密码">
</div>
<div class="checkbox" style="position: relative;top: 30px; left: 10px;">
<label>
<c:if test="${not empty cookie.loginAct and not empty cookie.loginPwd}">
<input type="checkbox" id="isRemPwd" checked="true">
</c:if>
<c:if test="${empty cookie.loginAct or empty cookie.loginPwd}">
<input type="checkbox" id="isRemPwd" >
</c:if>
十天内免登录
</label>
<span id="msg" style="color: red"></span>
</div>
<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block" style="width: 350px; position: relative;top: 45px;">登录</button>
</div>
</form>
</div>
</div>
</body>
</html>