引言
本文介绍了最近刚做的一个cms小项目,如有不足请各位及时指正,不胜感激!
因受社区文章限制,故将此项目分为上、中、下三部分进行发表
CMS客户关系管理系统【上】
简介
CMS客户关系管理系统,是一套用于管理业务员与客户的拜访记录的一套系统。在这套系统中:
业务员:
- 查询查看客户
- 新增客户
- 业务删除客户
- 变更客户信息
管理员:
- 新增业务员
- 重置业务员密码
- 删除业务员(业务删除)
- 查看拜访记录
当前用户:
- 修改密码
- 修改自己头像
注意:
不同的角色登录,显示的菜单和功能按钮不相同
数据库设计
在开发中,需要根据需求和原型进行数据库==概要设计。设计完成后,进行会议讨论==。每个人负责的模块不尽相同,站的考虑问题的角度也不同,设计者的设计很大可能存在偏向性。需要在会议中进行思想的碰撞,完善设计。
用户表(user):分角色
列 | 类型 | 说明 |
---|---|---|
id | int | |
username | varchar(20) | |
password | varchar(20) | |
realname | varchar(5) | |
role | int(1) | 1:管理员 2:业务员 |
delete | int(1) | 1:有效 2:无效 |
img | varchar(50) | 用户头像 |
create_time | varchar(19) | 创建时间:yyyy-MM-dd HH:mm:ss |
modify_time | varchar(19) | 修改时间:yyyy-MM-dd HH:mm:ss |
delete_time | varchar(19) | 删除时间:yyyy-MM-dd HH:mm:ss |
客户表(customer)
列 | 类型 | 说明 |
---|---|---|
id | int | 客户ID |
name | varchar(20) | 客户名称 |
sex | int(1) | 1 : 男 2 : 女 |
phone | varchar(11) | 手机号 |
salary | int(10) | 工资 |
addresss | varchar(50) | 地址 |
birth | varchar(10) | 生日:yyyy-MM-dd |
delete | int(1) | 1:有效 2:无效 |
user_id | int | 业务员ID |
create_time | varchar(19) | 创建时间:yyyy-MM-dd HH:mm:ss |
modify_time | varchar(19) | 修改时间:yyyy-MM-dd HH:mm:ss |
delete_time | varchar(19) | 删除时间:yyyy-MM-dd HH:mm:ss |
拜访记录表(visit_log)
列 | 类型 | 说明 |
---|---|---|
cust_id | int | 客户ID |
cust_name | varchar(20) | 客户名称 |
user_id | int | 业务员ID |
user_name | varchar(20) | 业务员真实姓名 |
visit_time | varchar(19) | 拜访时间:yyyy-MM-dd HH:mm |
create_time | varchar(19) | 创建时间:yyyy-MM-dd HH:mm:ss |
相关SQL
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '业务员ID',
`username` varchar(20) NOT NULL COMMENT '用户名',
`password` varchar(20) NOT NULL COMMENT '用户密码',
`realname` varchar(5) NOT NULL COMMENT '真名',
`role` int(1) NOT NULL COMMENT '角色:1.管理员 2.业务员',
`delete` int(1) NOT NULL COMMENT '业务删除:1.有效 2.无效',
`img` varchar(50) DEFAULT NULL COMMENT '图片路径',
`create_time` varchar(19) NOT NULL COMMENT '创建时间:yyyy-MM-dd HH:mm:ss',
`modify_time` varchar(19) NOT NULL COMMENT '修改时间:yyyy-MM-dd HH:mm:ss',
`delete_time` varchar(19) DEFAULT NULL COMMENT '删除时间:yyyy-MM-dd HH:mm:ss',
PRIMARY KEY (`id`),
UNIQUE KEY `username_uni_key` (`username`) COMMENT '用户名唯一不能重复'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `customer` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '客户ID',
`name` varchar(20) NOT NULL COMMENT '客户名称',
`sex` int(1) NOT NULL COMMENT '性别:1.男 2.女',
`phone` varchar(11) NOT NULL COMMENT '手机号',
`salary` int(10) NOT NULL COMMENT '工资',
`address` varchar(50) NOT NULL COMMENT '地址',
`birth` varchar(10) NOT NULL COMMENT '生日:yyyy-MM-dd',
`delete` int(1) NOT NULL COMMENT '业务删除:1.有效 2.无效',
`user_id` int(11) NOT NULL COMMENT '业务员ID',
`create_time` varchar(19) NOT NULL COMMENT '创建时间:yyyy-MM-dd HH:mm:ss',
`modify_time` varchar(19) NOT NULL COMMENT '修改时间:yyyy-MM-dd HH:mm:ss',
`delete_time` varchar(19) DEFAULT NULL COMMENT '删除时间:yyyy-MM-dd HH:mm:ss',
PRIMARY KEY (`id`),
UNIQUE KEY `phone_uni_key` (`phone`) COMMENT '手机号不能重复'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `visit_log` (
`cust_id` int(11) NOT NULL COMMENT '客户ID',
`cust_name` varchar(20) NOT NULL COMMENT '客户名称',
`user_id` int(11) NOT NULL COMMENT '业务员ID',
`user_name` varchar(20) NOT NULL COMMENT '业务员真实姓名',
`visit_time` varchar(19) NOT NULL COMMENT '拜访时间:yyyy-MM-dd HH:mm',
`create_time` varchar(19) NOT NULL COMMENT '创建时间:yyyy-MM-dd HH:mm:ss'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
项目架构
前端
在JavaWeb中静态资源文件是直接放在web目录下面,非静态文件是不允许客户端直接访问(jsp文件),基于安全的考虑,需要放在WEB-INF目录下。
静态资源文件,要放在web目录下面,考虑所有的静态资源文件不能被拦截。此时需要设置统一访问路径。一般使用一个统一的文件夹,将所有的静态资源文件装起来,然后判断请求路径前缀是否是这个统一的文件夹名称即可。<mark>__resources__</mark>
所有非静态资源(jsp)页面要放在WEB-INF,基于这样情况,WEB-INF文件相对较乱较杂,创建文件夹进行分类管理。view文件,表示下面是页面,然后基于每个模块,创建相应的文件夹。例如==:== <mark>__用户模块:view/user/list.jsp__</mark>
main.jsp
main.jsp是管理界面的框架,由于需要从session获取当前用户所以使用jsp。
注意:
在web项目中,存在资源路径出现多重路径,使用相对路径会因为URL变化,导致URL请求发生404。所以在使用时使用绝对路径。在URL前面拼接:${pageContext.request.contextPath}
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/layui/css/layui.css">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">CMS管理系统</div>
<!-- 头部区域(可配合layui已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<img src="http://t.cn/RCzsdCq" class="layui-nav-img">
贤心
</a>
<dl class="layui-nav-child">
<dd><a href="">基本资料</a></dd>
<dd><a href="">安全设置</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">基础信息管理</a>
<dl class="layui-nav-child">
<dd><a href="page.do?service=userList" target="content">员工管理</a></dd>
<dd><a href="index2.html" target="content">客户管理</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">密码管理</a></dd>
<dd><a href="javascript:;">头像管理</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">数据分析</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">拜访占比</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">
<iframe name="content" style="width: 100%;height: 100%;border: 0px"></iframe>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
© layui.com - 底部固定区域
</div>
</div>
<script src="${pageContext.request.contextPath}/resources/layui/layui.js"></script>
<script>
//JavaScript代码区域
layui.use('element', function(){
var element = layui.element;
});
</script>
</body>
</html>
控制页面跳转的Servlet
package com.sxt.controller;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* [@Description](/user/Description): 专门用于进行页面跳转
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 10:48
*/
[@WebServlet](/user/WebServlet)("/page.do")
public class PageController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String service = req.getParameter("service");
try {
Method method = this.getClass().getDeclaredMethod(service, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void main(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/view/main.jsp").forward(req,resp);
}
}
注意点:
- 在网页中,每多一个iframe就多一个window对象
- 子iframe 访问父iframe使用window.parent访问父窗口的window对象,根据window对象获取其他对象
- 父iframe访问子iframe
* 使用name直接访问: iframeName.window
* 使用iframe的id,frames\[‘id值’\]
* 使用索引iframes\[索引\]
后台
在JavaWeb开发中,基本都是基于MVC思想进行开发。Web后台框架,主要负责:M层和C层。
C层:使用Servlet技术。
M层主要分为:
- 实体类
- 数据操作层。
但是,在具体的实际开发中,发现:Controller层和M层耦合性极高,代码复用性极差。
按照之前的结构:Controller直接访问Dao层。如果类似以下场景:
用户注册场景:controller层只负责接收View层数据,将数据传递给M层中的Dao层,发现在Dao层, * 查询注册用户名是否存在 * 插入一个数据
修改用户信息场景: * 查询用户名是否已存在 * 修改数据 发现查询用户是否存在是重复操作,并且Dao层并不是单纯只是进行数据库的数据操作。也存在各种业务判断,违背了设计原则:单一职责。并且代码的复用不高,维护性也差。 所以基于这样的情况,在M层加上了service,service只进行业务判断,dao层只做数据操作。controller访问==__service__==层。
相关包如下:
- pojo : 所有的实体类
- dao : 数据操作类
- service :业务处理类
- controller :控制器
- util : 工具类
- common :公共类
- filter : web拦截器
相关jar包
fastjson-1.1.22.jar
hutool-all-5.4.1.jar
jstl-1.2.jar
mysql-connector-java-5.1.47.jar
standard-1.1.2.jar
相关类:
工具类
数据库连接配置文件
#jdbc连接配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/cms?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
数据库连接工具类
package com.sxt.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* [@Description](/user/Description):Jdbc连接工具类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-02 15:55
*/
public abstract class JdbcUtil {
private static final String DRIVER;
private static final String URL;
private static final String USERNAME;
private static final String PASSWORD;
//静态块 加载 配置文件
static {
/**
* 类加载器
* 三种类加载器 : Bootstrap 加载 JDK中核心类库
* 扩展类加载器 加载扩展类库
* 应用类加载器 加载应用程序自定义的类
* 双亲委派加载
* 1. 首先使用 Bootstrap 类加载器加载类 只加载JDK 核心类库
* 2. 扩展类加载器 加载ext文件夹下的类
* 3. 使用应用类加载器加载类 默认加载src源码目录下类
* 为什么Java使用双亲委派加载机制 类一旦被加载 其他类加载器将不会加载这个类
* 类的区分方式,包名+类名
* 如果用户自定义一个类,且类包名,类名与系统类一致。虽然一致,但是由于类加载器不同,所以依然使用系统类。
* 如果不是使用双亲委派机制,如果使用同一个类加载器,可能出现类覆盖。自定义的类覆盖系统类。
* 改写了JDK源代码。容易出现安全问题。
*/
InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
//读入到properties对象中
Properties prop = new Properties();
if (in == null){
throw new RuntimeException("配置文件没有找到");
}
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
DRIVER = prop.getProperty("jdbc.driver");
URL = prop.getProperty("jdbc.url");
USERNAME = prop.getProperty("jdbc.username");
PASSWORD = prop.getProperty("jdbc.password");
try {
//加载驱动
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return
*/
public static Connection getConnection(){
Connection connection = null;
try {
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
/**
* 关闭连接
* @param conn
* @param prep
*/
public static void close(Connection conn, PreparedStatement prep){
if (prep != null){
try {
prep.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 关闭连接
* @param conn
* @param prep
* @param rs
*/
public static void close(Connection conn, PreparedStatement prep, ResultSet rs){
if (rs != null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
close(conn,prep);
}
}
JSON结果数据工具类
package com.sxt.util;
import com.alibaba.fastjson.JSON;
import com.sxt.common.Result;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* [@Description](/user/Description): 响应数据工具类
* 将返回的数据转化为JSON字符串 返回给客户端
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-14 15:19
*/
public abstract class RespUtil {
/**
* 将返回的数据转化为JSON字符串返回给客户端
* @param rs 需要返回的数据
* @param resp 响应对象
* @throws IOException
*/
public static void writer(Result rs, HttpServletResponse resp) throws IOException {
resp.setCharacterEncoding("UTF-8");
//设置返回数据的类型
resp.setContentType("text/json;charset=utf-8");
PrintWriter writer = resp.getWriter();
//将需要返回的数据转化为JSON字符串
String s = JSON.toJSONString(rs);
writer.write(s);
writer.flush();
writer.close();
}
}
公共类
通用数据操作类
package com.sxt.common;
import com.sxt.common.PageInfo;
import com.sxt.util.JdbcUtil;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* [@Description](/user/Description): 数据通用的操作类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-08 09:17
*/
public class BaseDao {
/**
* 数据更新操作
* @param sql
* @param params
* @return
*/
public boolean update(String sql,Object... params){
//获取连接
Connection conn = JdbcUtil.getConnection();
//获取数据操作对象
PreparedStatement prep = null;
try {
prep = conn.prepareStatement(sql);
//校验是否有传输参数
if (params != null && params.length > 0){
//根据for循环设置sql中的参数
for (int i = 1; i <= params.length; i++) {
prep.setObject(i,params[i-1]);
}
}
int count = prep.executeUpdate();
return count == 1 ?true : false;
} catch (Exception throwables) {
throwables.printStackTrace();
}finally {
JdbcUtil.close(conn,prep);
}
return false;
}
/**
* 根据条件查询数据列表
* @param sql
* @param cls
* @param params
* @param <T>
* @return
*/
public <T> List<T> selectList(String sql,Class<T> cls,Object... params){
//获取连接
Connection conn = JdbcUtil.getConnection();
//获取数据操作对象
PreparedStatement prep = null;
//数据结果集
ResultSet rs = null;
List<T> data = new ArrayList<>();
try {
prep = conn.prepareStatement(sql);
int length = params.length;
//循环处理sql参数
if (params != null && length > 0){
//根据for循环设置sql中的参数
for (int i = 1; i <= length; i++) {
prep.setObject(i,params[i-1]);
}
}
//查询 获取结果集
rs = prep.executeQuery();
//获取数据元信息
ResultSetMetaData metaData = rs.getMetaData();
//获取列数
int count = metaData.getColumnCount();
while (rs.next()){
//创建对象
T obj = cls.newInstance();
//对象属性封装
for (int i = 1; i <= count ; i++) {
//根据序列获取列别名
String label = metaData.getColumnLabel(i);
//根据列别名获取数据
Object value = rs.getObject(label);
//进行对象属性设置
//获取属性
try {
Field field = cls.getDeclaredField(label);
//设置属性的访问标识
field.setAccessible(true);
//设置属性值
field.set(obj,value);
}catch (Exception exception){
exception.printStackTrace();
//如果属性不存在 则跳过这个属性的设置
continue;
}
}
data.add(obj);
}
} catch (Exception throwables) {
throwables.printStackTrace();
}finally {
JdbcUtil.close(conn,prep,rs);
}
return data;
}
/**
* 查询一个
* @param sql
* @param cls
* @param params
* @param <T>
* @return
*/
public <T> T selectOne(String sql,Class<T> cls,Object... params){
List<T> data = this.selectList(sql, cls, params);
if (!data.isEmpty() && data.size() > 1){
throw new RuntimeException("查询结果不是一个!!!");
}
if (data.size() == 1){
return data.get(0);
}
return null;
}
/**
* 分页查询
* @param sql 查询的基础sql
* @param cls 封装的类
* @param page 页码
* @param limit 每页数据条数
* @param params 查询的参数
* @param <T>
* @return
*/
public <T> PageInfo<T> selectPage(String sql,Class<T> cls,Integer page,Integer limit,Object... params){
//查询符合条件的总数据条数
int total = selectCount(sql,params);
//根据总数据条数获取总页数
//总数据条数 除以每页条数 如果能除断 说明刚好 则直接 除以
//如果有余数 则使用新一页装剩余的数据 所以加1
int totalPage = total%limit == 0? total/limit : total/limit + 1;
//页码不能大于总页数
//页码的最大值是总页数
if (page > totalPage ){
page = totalPage;
}
//页码的最小值是 1
if (page < 1){
page = 1;
}
//拼接分页查询数据的sql语句
int startRow = (page-1)*limit;
sql = sql +" limit "+ startRow +","+limit;
//获取数据
List<T> data = this.selectList(sql, cls, params);
PageInfo<T> pageInfo = new PageInfo<>(data,total,totalPage,page,limit);
return pageInfo;
}
/**
* 符合条件的总数据条数
* @param sql
* @param params
* @return
*/
private int selectCount(String sql,Object... params){
//组装查询总数据条数的sql语句
StringBuffer sb = new StringBuffer("select count(1) from ");
sb.append("(").append(sql).append(")").append(" as rs");
//获取连接
Connection conn = JdbcUtil.getConnection();
//获取数据操作对象
PreparedStatement prep = null;
//数据结果集
ResultSet rs = null;
try {
prep = conn.prepareStatement(sb.toString());
//循环设置参数
if (params != null && params.length > 0){
for (int i = 1; i <= params.length ; i++) {
prep.setObject(i,params[i-1]);
}
}
//获取查询结果集
rs = prep.executeQuery();
//默认指在元信息
rs.next();
return rs.getInt(1);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtil.close(conn,prep,rs);
}
return 0;
}
}
通用分页封装实体类
package com.sxt.common;
import java.util.List;
/**
* [@Description](/user/Description): 分页数据实体类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-08 10:48
*/
public class PageInfo<T> {
private List<T> data; //具体数据
private int total;//总数据条数
private int pages;//总页数
private int page;//当前页码
private int limit;//每页显示的条数
public PageInfo(List<T> data, int total, int pages, int page, int limit) {
this.data = data;
this.total = total;
this.pages = pages;
this.page = page;
this.limit = limit;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
@Override
public String toString() {
return "PageInfo{" +
"data=" + data +
", total=" + total +
", pages=" + pages +
", page=" + page +
", limit=" + limit +
'}';
}
}
通用的业务结果类
package com.sxt.common;
/**
* [@Description](/user/Description): 数据结果类
* 所有返回给页面的JSON数据 通过该类进行包装
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-14 15:13
*/
public class Result {
private Integer code;//业务码
private String msg;//业务消息 默认操作成功
private Object data; //业务数据
public Result(){
this.code = CodeMsg.SUCCESS.code;
this.msg = CodeMsg.SUCCESS.msg;
}
/**
* 成功的构造方法
* @param data
*/
public Result(Object data) {
this();
this.data = data;
}
/**
* 业务异常的构造方法
* @param codeMsg
*/
public Result(CodeMsg codeMsg) {
this.code = codeMsg.code;
this.msg = codeMsg.msg;
}
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;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
业务码和消息枚举
package com.sxt.common;
/**
* [@Description](/user/Description): 系统的业务码和业务消息枚举
* 存放整个系统需要用到业务码和对应的业务消息
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 14:47
*/
public enum CodeMsg {
//操作成功枚举
SUCCESS(200,"操作成功");
/*
* 由于系统使用时 模块会逐渐增多
* 当业务失败时 所有的业务码 使用 4 开头
* 紧邻的3位是模块编号
* 模块编号后紧邻3位 业务编号
* 例如:用户模块是 1 4001001, 表示用户业务模块 第一个异常编码
* 如果直接:411 随着错误码增多: 4110 此时表示 用户模块 第 10种业务异常
* 如果模块超过了10个 第11个模块第1个业务异常 4111
* 随着模块增多,异常情况增多 可以出现重复业务码 基于这样的情况,才采用4001001格式。
* 业务码不容易重复 其次 格式统一。
*/
public Integer code;
public String msg;
CodeMsg(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
常量接口
package com.sxt.common;
/**
* [@Description](/user/Description): 所有常量
* 存储系统中需要使用到的所有常量
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:39
*/
public interface Constant {
}
filter
编码过滤器
package com.sxt.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* [@Description](/user/Description): 编码过滤器
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-14 15:38
*/
[@WebFilter](/user/WebFilter)("*.do")
public class CharsetEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
登录过滤器
package com.sxt.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* [@Description](/user/Description): 登录过滤器
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:19
*/
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
M层
用户实体类
package com.sxt.pojo;
/**
* [@Description](/user/Description): 用户实体类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:21
*/
public class User {
//用户ID
private Integer id;
//用户名
private String username;
//用户密码
private String password;
//用户真实姓名
private String realname;
//用户角色 1 管理员 2 业务员
private Integer role;
//是否删除 1 未删除 2 已删除
private Integer delete;
//用户头像
private String img;
//创建时间
private String createTime;
//修改时间
private String modifyTime;
//删除时间
private String deleteTime;
public User(){}
public User(Integer id, String username, String password, String realname, Integer role, Integer delete, String img, String createTime, String modifyTime, String deleteTime) {
this.id = id;
this.username = username;
this.password = password;
this.realname = realname;
this.role = role;
this.delete = delete;
this.img = img;
this.createTime = createTime;
this.modifyTime = modifyTime;
this.deleteTime = deleteTime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
public Integer getRole() {
return role;
}
public void setRole(Integer role) {
this.role = role;
}
public Integer getDelete() {
return delete;
}
public void setDelete(Integer delete) {
this.delete = delete;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getModifyTime() {
return modifyTime;
}
public void setModifyTime(String modifyTime) {
this.modifyTime = modifyTime;
}
public String getDeleteTime() {
return deleteTime;
}
public void setDeleteTime(String deleteTime) {
this.deleteTime = deleteTime;
}
}
客户实体类
package com.sxt.pojo;
/**
* [@Description](/user/Description): 客户类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:21
*/
public class Customer {
//客户ID
private Integer id;
//客户名称
private String name;
//客户性别 1 男 2 女
private Integer sex;
//客户电话
private String phone;
//客户工资
private Integer salary;
//客户地址
private String address;
//客户生日
private String birth;
//是否有效 1 有效 2 无效
private Integer delete;
//业务员ID
private Integer userId;
//创建时间
private String createTime;
//修改时间
private String modifyTime;
//删除时间
private String deleteTime;
public Customer(){}
public Customer(Integer id, String name, Integer sex, String phone, Integer salary, String address, String birth, Integer delete, Integer userId, String createTime, String modifyTime, String deleteTime) {
this.id = id;
this.name = name;
this.sex = sex;
this.phone = phone;
this.salary = salary;
this.address = address;
this.birth = birth;
this.delete = delete;
this.userId = userId;
this.createTime = createTime;
this.modifyTime = modifyTime;
this.deleteTime = deleteTime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBirth() {
return birth;
}
public void setBirth(String birth) {
this.birth = birth;
}
public Integer getDelete() {
return delete;
}
public void setDelete(Integer delete) {
this.delete = delete;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getModifyTime() {
return modifyTime;
}
public void setModifyTime(String modifyTime) {
this.modifyTime = modifyTime;
}
public String getDeleteTime() {
return deleteTime;
}
public void setDeleteTime(String deleteTime) {
this.deleteTime = deleteTime;
}
}
拜访记录实体类
package com.sxt.pojo;
/**
* [@Description](/user/Description): 拜访记录
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:21
*/
public class VisitLog {
//客户ID
private Integer custId;
//客户名称
private String custName;
//用户ID
private Integer userId;
//用户名称
private String userName;
//拜访时间
private String visitTime;
//创建时间
private String createTime;
public VisitLog(){}
public VisitLog(Integer custId, String custName, Integer userId, String userName, String visitTime, String createTime) {
this.custId = custId;
this.custName = custName;
this.userId = userId;
this.userName = userName;
this.visitTime = visitTime;
this.createTime = createTime;
}
public Integer getCustId() {
return custId;
}
public void setCustId(Integer custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getVisitTime() {
return visitTime;
}
public void setVisitTime(String visitTime) {
this.visitTime = visitTime;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}
用户数据操作类
package com.sxt.dao;
import com.sxt.common.BaseDao;
/**
* [@Description](/user/Description): 用户数据操作类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:41
*/
public class UserDao extends BaseDao {
}
客户数据操作类
package com.sxt.dao;
import com.sxt.common.BaseDao;
/**
* [@Description](/user/Description): 客户数据操作类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:42
*/
public class CustomerDao extends BaseDao {
}
拜访记录数据操作类
package com.sxt.dao;
import com.sxt.common.BaseDao;
/**
* [@Description](/user/Description): 拜访记录数据操作类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:42
*/
public class VisitLogDao extends BaseDao {
}
用户业务接口
package com.sxt.service;
/**
* [@Description](/user/Description): 用户业务接口
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:43
*/
public interface IUserService {
}
客户业务接口
package com.sxt.service;
/**
* [@Description](/user/Description): 客户业务类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:44
*/
public interface ICustomerService {
}
拜访记录业务接口
package com.sxt.service;
/**
* [@Description](/user/Description): 拜访记录业务类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:44
*/
public interface IVisitLogService {
}
用户业务实现类
package com.sxt.service.impl;
import com.sxt.service.IUserService;
/**
* [@Description](/user/Description): 用户业务实现类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:44
*/
public class UserServiceImpl implements IUserService {
}
客户业务实现类
package com.sxt.service.impl;
import com.sxt.service.ICustomerService;
/**
* [@Description](/user/Description): 客户业务实现类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:45
*/
public class CustomerServiceImpl implements ICustomerService {
}
拜访记录业务实现类
package com.sxt.service.impl;
import com.sxt.service.IVisitLogService;
/**
* [@Description](/user/Description): 拜访记录业务实现类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:45
*/
public class VisitLogServiceImpl implements IVisitLogService {
}
C层
控制页面跳转类
package com.sxt.controller;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* [@Description](/user/Description): 专门用于进行页面跳转
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 10:48
*/
[@WebServlet](/user/WebServlet)("/page.do")
public class PageController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String service = req.getParameter("service");
try {
Method method = this.getClass().getDeclaredMethod(service, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void main(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/view/main.jsp").forward(req,resp);
}
}
用户控制类
package com.sxt.controller;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
/**
* [@Description](/user/Description): 用户控制类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:48
*/
[@WebServlet](/user/WebServlet)("/user.do")
public class UserController extends HttpServlet {
}
客户控制类
package com.sxt.controller;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
/**
* [@Description](/user/Description): 客户控制类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:49
*/
[@WebServlet](/user/WebServlet)("/customer.do")
public class CustomerController extends HttpServlet {
}
拜访记录控制类
package com.sxt.controller;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
/**
* [@Description](/user/Description): 拜访记录控制类
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:50
*/
[@WebServlet](/user/WebServlet)("/log.do")
public class VisitLogController extends HttpServlet {
}
登录功能
登录逻辑
- 获取表单数据
- 使用ajax将数据进行提交
- 处理响应码
* 如果响应码不是200 则将异常业务消息进行提示 * 如果响应码是200,说明成功,则跳转到==__main.jsp__==
1.登录页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页面</title>
<link rel="stylesheet" href="resources/layui/css/layui.css">
<style>
.content{
width: 330px;
height: 330px;
position: absolute;
left: 50%;
top: 50%;
margin-top: -165px;
margin-left: -165px;
box-shadow:2px 2px 10px #909090;
}
</style>
</head>
<body>
<div class="content">
<form class="layui-form layui-form-pane" style="margin:10px">
<h1 style="text-align: center;margin-bottom: 20px;color: rgb(0,150,136);font-weight: bold">用户·登录</h1>
<div class="layui-form-item">
<label class="layui-form-label" style="width: 80px">用户名:</label>
<div class="layui-input-inline">
<input type="text" name="username" autocomplete="off" class="layui-input" placeholder="用户名" lay-verify="required" lay-reqText="请输入用户名" >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label" style="width: 80px">密码:</label>
<div class="layui-input-inline">
<input type="text" name="password" autocomplete="off" class="layui-input" placeholder="密码" lay-verify="required" lay-reqText="请输入密码" >
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label" style="width: 80px">验证码:</label>
<div class="layui-input-inline" style="width: 90px">
<input type="text" name="checkCode" autocomplete="off" class="layui-input" placeholder="验证码" lay-verify="required" lay-reqText="请输入验证码" >
</div>
<img src="code.do" style="height: 38px;margin-left: 10px" id="checkCodeImg">
</div>
</div>
<div class="layui-form-item" style="margin-top: 30px">
<button style="width: 300px" type="button" class="layui-btn" lay-submit lay-filter="subBtnFilter">登 录</button>
</div>
</form>
</div>
<script src="resources/layui/layui.js"></script>
<script>
layui.use(['form','layer','jquery'],function () {
let form = layui.form;
let layer = layui.layer;
let $ = layui.jquery;
//更新验证码
$("#checkCodeImg").click(function () {
$(this).attr("src","code.do?"+new Date());
});
//表单提交
form.on("submit(subBtnFilter)",function (d) {
let data = d.field;//获取表单数据
// 使用ajax提交数据
$.post("user.do?service=login",data,function (rs) {
//rs 是返回的数据 校验业务码
if (rs.code != 200 ){
//当业务码不是200 说明业务操作失败 将失败的原因进行展示
layer.msg(rs.msg);
return false;
}
//操作成功则跳转到list.jsp
location.href = "page.do?service=main";
})
return false;//阻止表单默认提交行为
});
})
</script>
</body>
</html>
2.新增验证码Servlet
package com.sxt.controller;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import com.sxt.common.Constant;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* [@Description](/user/Description): 验证码Servlet
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 16:25
*/
[@WebServlet](/user/WebServlet)("/code.do")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用工具产生验证码对象
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(100, 50, 4, 0);
//获取验证码字符串
String code = captcha.getCode();
//将验证码放入session
req.getSession().setAttribute(Constant.CHECK_CODE_KEY,code);
//将验证码使用流输出
ServletOutputStream outputStream = resp.getOutputStream();
captcha.write(outputStream);
//释放资源
outputStream.close();
}
}
3.修改UserController
private IUserService userService;
@Override
public void init() throws ServletException {
userService = new UserServiceImpl();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String service = req.getParameter("service");
try {
Method method = this.getClass().getDeclaredMethod(service, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理用户登录请求
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取前端参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String checkCode = req.getParameter("checkCode");
//获取验证码
Object o = req.getSession().getAttribute(Constant.CHECK_CODE_KEY);
//校验验证码
if (o == null || !StrUtil.equals(checkCode,o.toString())){
Result rs = new Result(CodeMsg.USER_CHECK_CODE_ERROR);
RespUtil.writer(rs,resp);
return;
}
//校验账号密码
//根据用户名 和 密码查询用户
Result rs = userService.login(username,password);
//登录成功
if (rs.getCode().equals(CodeMsg.SUCCESS.code)){
req.getSession().setAttribute(Constant.CURRENT_USER_KEY,rs.getData());
rs.setData(null);
}
RespUtil.writer(rs,resp);
}
4.修改IUserService
/**
* 用户登录方法
* @param username
* @param password
* @return
*/
Result login(String username, String password);
5.修改UserServiceImpl
UserDao userDao = new UserDao();
@Override
public Result login(String username, String password) {
//根据用户名查询用户
User user = userDao.selectOneByName(username);
//校验账号是否存在
if (user == null){
return new Result(CodeMsg.USER_USERNAME_NOT_EXIST_ERROR);
}
//校验密码是否一致
if (!StrUtil.equals(user.getPassword(),password)){
return new Result(CodeMsg.USER_USERNAME_PASSWORD_ERROR);
}
//校验用户状态是否有效
if (user.getDelete().equals(Constant.USER_STATE_INVALID)){
return new Result(CodeMsg.USER_INVALID_ERROR);
}
return new Result(user);
}
6.修改UserDao
/**
* 根据用户名查询用户
* @param username
* @return
*/
public User selectOneByName(String username) {
String sql = "select id,username,password,realname,role,`delete`,img from user where username=?";
return super.selectOne(sql,User.class,username);
}
7.修改常量
/**
* 验证码 session中的key
*/
String CHECK_CODE_KEY = "code";
/**
* 用户状态 1 有效
*/
Integer USER_STATE_VALID = 1;
/**
* 用户状态 2 无效
*/
Integer USER_STATE_INVALID = 2;
/**
* 当前存放在session中的用户的key
*/
String CURRENT_USER_KEY = "user";
8.修改CodeMsg枚举
USER_CHECK_CODE_ERROR(4002001,"用户验证码不正确"),
USER_USERNAME_NOT_EXIST_ERROR(4002002,"用户名不存在"),
USER_USERNAME_PASSWORD_ERROR(4002003,"用户名密码不匹配"),
USER_INVALID_ERROR(4002004,"用户账号已失效"),
退出功能
退出功能逻辑
- 点击退出
- 服务器删除session中当前用户
- 跳转到登录页面
修改main.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/layui/css/layui.css">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">CMS管理系统</div>
<!-- 头部区域(可配合layui已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<img src="http://t.cn/RCzsdCq" class="layui-nav-img">
贤心
</a>
</li>
<li class="layui-nav-item"><a href="user.do?service=loginOut">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">基础信息管理</a>
<dl class="layui-nav-child">
<dd><a href="page.do?service=userList" target="content">员工管理</a></dd>
<dd><a href="index2.html" target="content">客户管理</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">密码管理</a></dd>
<dd><a href="javascript:;">头像管理</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">数据分析</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">拜访占比</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">
<iframe name="content" style="width: 100%;height: 100%;border: 0px"></iframe>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
© layui.com - 底部固定区域
</div>
</div>
<script src="${pageContext.request.contextPath}/resources/layui/layui.js"></script>
<script>
//JavaScript代码区域
layui.use('element', function(){
var element = layui.element;
});
</script>
</body>
</html>
修改UserController
/**
* 退出
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void loginOut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//删除当前session中用户
req.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
//解除session绑定
req.getSession().invalidate();
//跳转到登录页面
resp.sendRedirect("index.html");
}
显示当前登录用户及头像
修改main.jsp
从session获取当前登录的用户名称
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/layui/css/layui.css">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">CMS管理系统</div>
<!-- 头部区域(可配合layui已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<img onerror="javascript:this.src='${pageContext.request.contextPath}/imgs/default.jpg';" src="${pageContext.request.contextPath}/${user.img}" class="layui-nav-img">
${user.realname}
</a>
</li>
<li class="layui-nav-item"><a href="user.do?service=loginOut">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">基础信息管理</a>
<dl class="layui-nav-child">
<dd><a href="page.do?service=userList" target="content">员工管理</a></dd>
<dd><a href="index2.html" target="content">客户管理</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">密码管理</a></dd>
<dd><a href="javascript:;">头像管理</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">数据分析</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">拜访占比</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">
<iframe name="content" style="width: 100%;height: 100%;border: 0px"></iframe>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
© layui.com - 底部固定区域
</div>
</div>
<script src="${pageContext.request.contextPath}/resources/layui/layui.js"></script>
<script>
//JavaScript代码区域
layui.use('element', function(){
var element = layui.element;
});
</script>
</body>
</html>
新建imgs文件夹
新建imgs文件夹
将default.jpg放入
员工列表
员工列表
- 点击左侧菜单跳转到员工列表页面
- 员工列表页面请求员工列表数据
- 将员工列表数据进行渲染成列表
1.在view文件夹中新建user文件夹,在user文件夹中新建list.jsp
2.list.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>Title</title>
<%-- 引入layui --%>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/layui/css/layui.css">
</head>
<body>
<div>
<form class="layui-form layui-form-pane">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">员工名称</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" id="realname" placeholder="员工名称" autocomplete="off">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">角色</label>
<div class="layui-input-inline">
<select id="role">
<option value="">请选择角色</option>
<option value="1">管理员</option>
<option value="2">业务员</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<select id="delete">
<option value="">状态</option>
<option value="1">在职</option>
<option value="2">离职</option>
</select>
</div>
</div>
<div class="layui-inline">
<button type="button" id="searchBtn" class="layui-btn">查询</button>
</div>
</div>
</form>
<hr>
<table id="dataTable" lay-filter="dataTableFilter"></table>
</div>
<script src="${pageContext.request.contextPath}/resources/layui/layui.js"></script>
<script>
layui.use(['form','table','jquery','layer'],function () {
let form = layui.form;
let table = layui.table;
let $ = layui.jquery;
let layer = layui.layer;
//渲染表格
let opt = {
id:"dataTableId",
elem:"#dataTable",
url:"${pageContext.request.contextPath}/user.do?service=page",
cols:[[
{type:"checkbox"},
{field:"username",title:"用户名"},
{field:"password",title:"密码"},
{field:"realname",title:"用户名"},
{field:"role",title:"角色",templet:function (d) {
let role = d.role;
if (role == 1){
return "<b style='color: #5FB878'>管理员</b>"
}else if (role == 2){
return "<b style='color: red'>业务员</b>"
}
}},
{field:"delete",title:"状态",templet:function (d) {
let del = d.delete;
if (del == 1){
return "<b style='color: #5FB878'>在职</b>"
}else if (del == 2){
return "<b style='color: red'>离职</b>"
}
}},
{field:"createTime",title:"创建时间"},
{title:"操作"},
]],
page:true,
parseData:function (rs) {
return {
"code" : rs.code,
"msg":rs.msg,
"count":rs.data.total,
"data":rs.data.data
}
},
response:{
statusCode:200
}
};
let tabIns = table.render(opt);
//表格查询
$("#searchBtn").click(function () {
let realname = $("#realname").val();
let role = $("#role").val();
let del = $("#delete").val();
tabIns.reload({
where:{
realname:realname,
role:role,
"delete":del
}
})
});
});
</script>
</body>
</html>
3.修改PageController
/**
* 员工列表
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void userList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/view/user/list.jsp").forward(req,resp);
}