贵美商城案例仓库(SRC内有所需SQL): https://gitee.com/small-kekeaiai/guimei
目录
1. 此案例所需 pom.xml-------------------------------------------------
1. 此案例所需pom.xml 结束-------------------------------------------------------
2.3 interceptor2.3.1 listener登录拦截器
2.4 mapper2.4.1 AdminMapper 用户登录
2.7 impl 接口实现2.7.1 UserServiceImpl
一、准备工作
1. 此案例所需 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.xs</groupId>
<artifactId>guimei</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>guimei Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.22</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<!-- 其他相关依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>
</project>
1. 此案例所需pom.xml 结束-------------------------------------------------------
1.1.1 此外还需导入layUI(在仓库)
2. webapp
WEB-INF
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置多个applicationContext.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>
<!-- 该监听器用于加载applicationContext.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springmvc.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
</web-app>
3. HTML
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>layout 管理系统大布局 - Layui</title>
<link rel="stylesheet" href="/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo layui-hide-xs layui-bg-black">xx商城后台管理</div>
<!-- 头部区域(可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<!-- 移动端显示 -->
<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
<i class="layui-icon layui-icon-spread-left"></i>
</li>
<li class="layui-nav-item layui-hide-xs"><a href="">导航一</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">导航二</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">导航三</a></li>
<!-- <li class="layui-nav-item">-->
<!-- <a href="javascript:;">nav groups</a>-->
<!-- <dl class="layui-nav-child">-->
<!-- <dd><a href="">menu 11</a></dd>-->
<!-- <dd><a href="">menu 22</a></dd>-->
<!-- <dd><a href="">menu 33</a></dd>-->
<!-- </dl>-->
<!-- </li>-->
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
<a href="javascript:;">
<img src="https://tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
admin
</a>
<dl class="layui-nav-child">
<dd><a href="">个人资料</a></dd>
<dd><a href="">设置</a></dd>
<!-- <a href="#" target="_top">退出</a>-->
<dd><a href="/admin/logout" target="_top">退出</a></dd>
</dl>
</li>
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
<a href="javascript:;">
<i class="layui-icon layui-icon-more-vertical"></i>
</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">
<!-- 1、 onclick:单击事件 = 跳转页面
2、openUrl 用户查询的Js方法 126行实现
-->
<dd><a href="javascript:;" onclick="openUrl('userList.html')">用户查询</a></dd>
<dd><a href="javascript:;" onclick="openUrl('userAdd.html')">用户新增</a></dd>
<dd><a href="javascript:;" onclick="openUrl('userGender.html')">用户男女比例</a></dd>
<dd><a href="javascript:;" onclick="openUrl('userAddress.html')">用户位置分布</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a class="" href="javascript:;">公告管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">公告查询</a></dd>
<dd><a href="javascript:;">公告新增</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<!-- 3、主页面中间显示内容-->
<div class="layui-body" id="center">
<!-- 内容主体区域 -->
<div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
底部固定区域
</div>
</div>
<script src="/layui/layui.js"></script>
<script>
//JS
layui.use(['element', 'layer', 'util'], function(){
var element = layui.element
,layer = layui.layer
,util = layui.util
,$ = layui.$;
//头部事件
util.event('lay-header-event', {
//左侧菜单事件
menuLeft: function(othis){
layer.msg('展开左侧菜单的操作', {icon: 0});
}
,menuRight: function(){
layer.open({
type: 1
,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
,area: ['260px', '100%']
,offset: 'rt' //右上角
,anim: 5
,shadeClose: true
});
}
});
});
</script>
</body>
<!-- 4、引入jquery.js -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
<script type="application/javascript">
<!-- 2、js方法 url:地址 -->
function openUrl(url){
// 2.1、 点用户查询就是 URL 就是 ArrayList
// 2.2、 点用户新增就是 URL 就是 UserAdd
//alert(url);
// $("#center").load(url) 此方法 就是打开中间页面
$("#center").load(url);// 加载相关路径
}
</script>
</html>
userAdd.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/layui/css/layui.css">
</head>
<script src="/layui/layui.js" charset="utf-8"></script>
<body>
<form class="layui-form" action="/user/addUser">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<!-- lay-verify="required": 必需写 -->
<input type="text" name="userName" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码框</label>
<div class="layui-input-inline">
<input type="password" name="userPwd" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
<!-- <div class="layui-form-mid layui-word-aux">密码必须以字母开头</div>-->
<div class="layui-form-mid layui-word-aux">请不要忘记密码</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-block">
<input type="text" name="userRealname" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
<input type="radio" name="userGender" value="男" title="男">
<input type="radio" name="userGender" value="女" title="女" checked>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-block">
<input type="text" name="userEmail" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话</label>
<div class="layui-input-block">
<input type="text" name="userPhone" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">身份证号</label>
<div class="layui-input-block">
<input type="text" name="userId" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">日期</label>
<div class="layui-input-inline">
<input type="text" name="userBirthdate" class="layui-input" id="userBirthdate" placeholder="yyyy-MM-dd">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否锁定</label>
<div class="layui-input-block">
<select name="userLock" lay-verify="required">
<option value=""></option>
<option value="0">解锁</option>
<option value="1">锁定</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-block">
<input type="text" name="userAddress" class="layui-input">
</div>
</div>
<div class="layui-upload-drag" id="test10">
<i class="layui-icon"></i>
<p>点击上传,或将文件拖拽到此处</p>
<div class="layui-hide" id="uploadDemoView">
<hr>
<img src="" alt="上传成功后渲染" style="max-width: 196px">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block"><!-- lay-filter="formDemo">立即提交: 118行实现方法 -->
<button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</body>
<script>
//Demo
layui.use('form', function(){
var form = layui.form;
//监听提交
form.on('submit(formDemo)', function(data){
//layer.msg(JSON.stringify(data.field));
return true;//true表示走action
});
});
</script>
<script>
layui.use('laydate', function(){
var laydate = layui.laydate;
//常规用法
laydate.render({
elem: '#userBirthdate'
});
});
</script>
<script>
layui.use(['upload'], function(){
var $ = layui.jquery,
upload = layui.upload
//拖拽上传
upload.render({
elem: '#test10'
,url: '/user/upload' //此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
,done: function(res){
layer.msg('上传成功');
layui.$('#uploadDemoView').removeClass('layui-hide').find('img').attr('src', res.data);
console.log(res)
}
});
});
</script>
</html>
userList.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Layui</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/layui/css/layui.css" tppabs="http://res.layui.com/layui/dist/css/layui.css" media="all">
<!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
</head>
<body>
<table class="layui-hide" id="test" lay-filter="test"></table>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="batchDel">批量删除</button><!-- 88行实现方法 -->
<button class="layui-btn layui-btn-sm" lay-event="writeExcel">导出Excel</button><!-- 111行实现方法 -->
<button class="layui-btn layui-btn-sm" lay-event="getExcelTemplate">获取Excel模板</button><!-- 126行实现方法 -->
<!-- 330行实现方法 -->
<button type="button" class="layui-btn" id="test1">
<i class="layui-icon"></i>导入Excel
</button>
</div>
</script>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><!-- 162行 实现编辑方法-->
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
<script src="/layui/layui.js" charset="utf-8"></script>
<!-- 注意:如果你直接复制所有代码到本地,上述 JS 路径需要改成你本地的 -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
<script>
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#test'
,url:'/user/findByPage'/*tpa=https://www.layuiweb.com/test/table/demo1.json*/
,toolbar: '#toolbarDemo' //开启头部工具栏,并为其绑定左侧模板
,defaultToolbar: ['filter', 'exports', 'print', { //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可
title: '提示'
,layEvent: 'LAYTABLE_TIPS'
,icon: 'layui-icon-tips'
}]
,title: '用户数据表'
,cols: [[
{type: 'checkbox', fixed: 'left'}
,{field:'id', title:'ID', width:100, fixed: 'left', sort: true}
,{field:'userName', title:'用户名', width:100}
,{field:'userPwd', title:'密码', width:100}
,{field:'userRealname', title:'真实名称', width:100}
,{field:'userGender', title:'性别', width:100}
,{field:'userEmail', title:'邮箱', width:100}
,{field:'userId', title:'身份证', width:100}
,{field:'userBirthdate', title:'生日', width:100,
templet:"<div>{{ layui.util.toDateString(d.userBirthdate,'yyyy-MM-dd') }}</div>"
}
,{field:'userLock', title:'锁定状态', width:100}
,{field:'userAddress', title:'地址', width:100}
,{field:'userImage', title:'头像', width:100,
templet:"<div><img src='{{ d.userImage }}' width='50' height='50'></div>"
}
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
]]
//,page: true
,page: { //支持传入 laypage 组件的所有参数(某些参数除外,如:jump/elem) - 详见文档
layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //自定义分页布局
,curr: 1 //设定初始在第 1 页
,groups: 3 //只显示 3 个连续页码
,first: "首页" //不显示首页
,last: "尾页" //不显示尾页
,limit:3
,limits:[3,7,10]
}
});
//头工具栏事件
table.on('toolbar(test)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'batchDel':
var data = checkStatus.data;
//layer.alert(JSON.stringify(data));
//获取选中数据的id
var ids = "";
//遍历
for(let i = 0; i < data.length; i++){
ids += "&ids=" + data[i].id;
}
alert("批量删除的ids:" + ids)
//发送ajax,调用后台接口
$.get("/user/deleteByIds", ids,
function(data){
if("success" == data){
table.reload("test",{});//重载当前表格
}
});
break;
case 'writeExcel':<!-- 实现方法导出Excel -->
var data = checkStatus.data;
//layer.msg('选中了:'+ data.length + ' 个');
//获取选中数据的id
var ids = "";
//遍历
for(let i = 0; i < data.length; i++){
ids += "&ids=" + data[i].id;
}
alert("要查询的ids:" + ids)
location.href = "/user/findByIds?ids="+ids;
break;
case 'getExcelTemplate':
//layer.msg(checkStatus.isAll ? '全选': '未全选');
location.href = "/excel/user.xlsx"
break;
//自定义头工具栏右侧图标 - 提示
case 'LAYTABLE_TIPS':
layer.alert('这是工具栏右侧自定义的一个图标按钮');
break;
};
});
//监听行工具事件
table.on('tool(test)', function(obj){
var data = obj.data;
//console.log(obj)
if(obj.event === 'del'){
layer.confirm('真的删除行么', function(index){
obj.del();//删除结构,没有调用后台接口
layer.close(index);
//获取id,删除
var deleteId = data.id;
//发送ajax,调用后台接口
$.get("/user/deleteById", { "id": deleteId },
function(data){
if("success" == data){
table.reload("test",{});//重载当前表格
}
});
// 编辑方法
});
} else if(obj.event === 'edit'){
// layer.prompt({
// formType: 2
// ,value: data.email
// }, function(value, index){
// obj.update({
// email: value
// });
// layer.close(index);
// });
//编辑之前需要查询单个
//layer.alert(JSON.stringify(data));
findById(data);
}
});
});
</script>
</body>
<script>
function findById(data) {
//弹框
layer.open({
type: 1,
content: $("#updateForm").html(),
title: ['修改页面', 'font-size:18px;'],
area: ['600px', '600px'],
//弹出后回调
success: function(){
$("#id").val(data.id);
$("#userName").val(data.userName);
$("#userPwd").val(data.userPwd);
$("#userRealname").val(data.userRealname);
if('男' == data.userGender){
$("#userGender").append("<input type='radio' name='userGender' value='男' checked />"+'男'+"<input type='radio' name='userGender' value='女'/>"+'女'+"")
}else{
$("#userGender").append("<input type='radio' name='userGender' value='男' />"+'男'+"<input type='radio' name='userGender' value='女' checked />"+'女'+"")
}
$("#userEmail").val(data.userEmail);
$("#userPhone").val(data.userPhone);
$("#userId").val(data.userId);
$("#userBirthdate").val(layui.util.toDateString(data.userBirthdate,'yyyy-MM-dd'));
if("0" == data.userLock){
$("#userLock").append("<option value='0' selected>"+'解锁'+"</option> <option value='1'>"+'锁定'+"</option>");
}else{
$("#userLock").append("<option value='0' >"+'解锁'+"</option> <option value='1' selected>"+'锁定'+"</option>");
}
$("#userAddress").val(data.userAddress);
//渲染页面
layui.form.render();
},
btn: ['提交', '取消']
,yes: function(index, layero){
alert("-----")
//修改操作
$.get("/user/updateUser", $("#updateUser").serialize(),
function(data){
if("success" == data){
location.reload();//刷新当前页面
}
});
}
,btn2: function(index, layero){
alert("取消")
}
});
}
</script>
<script type="text/html" id="updateForm">
<form class="layui-form" id="updateUser">
<!-- 把id 作为隐藏域传过去 -->
<input type="hidden" name="id" id="id">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input type="text" name="userName" id="userName" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码框</label>
<div class="layui-input-inline">
<input type="password" name="userPwd" id="userPwd" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">密码必须以字母开头</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-block">
<input type="text" name="userRealname" id="userRealname" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block" id="userGender">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-block">
<input type="text" name="userEmail" id="userEmail" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话</label>
<div class="layui-input-block">
<input type="text" name="userPhone" id="userPhone" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">身份证号</label>
<div class="layui-input-block">
<input type="text" name="userId" id="userId" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">日期</label>
<div class="layui-input-inline">
<input type="date" name="userBirthdate" id="userBirthdate" class="layui-input" id="userBirthdate" placeholder="yyyy-MM-dd">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否锁定</label>
<div class="layui-input-block">
<select name="userLock" id="userLock" lay-verify="required">
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-block">
<input type="text" name="userAddress" id="userAddress" class="layui-input">
</div>
</div>
</form>
</script>
<!-- 导入Excel -->
<script>
layui.use('upload', function(){
var upload = layui.upload;
//执行实例
var uploadInst = upload.render({
elem: '#test1' //绑定元素
,accept: 'file'
,url: '/user/readExcel' //上传接口
,done: function(res){
if("success" == res.msg){
alert("导入数据成功");
location.reload();
}
}
,error: function(){
//请求异常回调
alert("导入数据失败")
}
});
});
</script>
</html>
userAddress.html用户位置分布
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户位置分布</title>
</head>
<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="/js/echarts.min.js"></script>
<!-- jquery.js -->
<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
</body>
<script>
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: 'Access From',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '40',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
// { value: 1048, name: 'Search Engine' },
// { value: 735, name: 'Direct' },
// { value: 580, name: 'Email' },
// { value: 484, name: 'Union Ads' },
// { value: 300, name: 'Video Ads' }
]
}
]
};
//myChart.setOption(option);
//发送ajax
$.get("/user/getUserAddressDto",
function(userAddressDto){
alert("userAddressDto:" + userAddressDto)
//赋值
option.series[0].data = userAddressDto;
//配置
myChart.setOption(option);
});
</script>
</html>
userGender.html柱状图男女人数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>柱状图男女人数</title>
</head>
<!-- 导入本地echarts.js -->
<script src="/js/echarts.min.js"></script>
<!-- 导入官方jquery.js -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: '用户性别比例'
},
tooltip: {},
legend: {
data: ['性别']
},
xAxis: {
//data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
// {
// name: '性别',
// type: 'bar',
// data: [5, 20, 36, 10, 10, 20]
// }
]
};
// 使用刚指定的配置项和数据显示图表。
//myChart.setOption(option);
//发送ajax
$.get("/user/getUserGenderDto",
function(userGenderDto){
//赋值
option.xAxis.data = userGenderDto.genderData;
option.series = userGenderDto;
//配置
myChart.setOption(option);
});
</script>
</body>
</html>
adminLogin.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<link rel="stylesheet" type="text/css" href="css/htstart.css"/>
<link rel="stylesheet" type="text/css" href="css/htenter.css"/>
</head>
<body onload="showTime()">
<div align="center" style="height:150px;">
<div id="gmsctp">
<img src="image/logo.jpg"/>
</div>
<div id="daohang">
<ul>
<li>
<a href="#">首页</a></li>
<li>
<a href="#">用户</a></li>
<li style="width:100px; background-size:100px 33px;">
<a href="#">商品分类</a></li>
<li>
<a href="#">订单</a></li>
<li style="width:100px; background-size:100px 33px;">
<a href="#">商品详情</a></li>
<li>
<a href="#">公告</a></li>
</ul>
</div>
<div id="time" >
<font>管理员您好,今天是<span id="currentTime">2015-11-26</span>,欢迎回到管理后台。</font>
</div>
<div id="weizi">
<font>您现在的位置: <a href="#">贵美商城</a> > 管理后台</font>
</div>
</div>
<br />
<div align="center">
<div id="denglu" >
<div align="left">
<img src="image/redarrows.jpg"/> <b>管理首页</b>
</div>
<hr color="#FF5F11" />
<br /><br /><br /><br />
<div id="hydl">欢迎登录贵美商城系统</div>
<br /><br />
<form action="/admin/login">
<div id="xinxi">
用户名: <input type="text" name="adminName"/><br /><br />
登录密码: <input type="password" name="adminPwd" style="width:160px;"/>
</div><br />
<input name="submit" type="submit" id="submit" value="立即登录" />
</form>
</div>
</div>
<br /><br /><br />
<div id="xia">
Copyright © yangl ALL Rights Reserved.京ICP证1000001号
</div>
</body>
<script>
function showTime(){
let spanNode = document.getElementById("currentTime");
spanNode.innerHTML = new Date().toLocaleTimeString();
}
//每隔多久调用一次该函数,1000毫秒
setInterval("showTime()",1000)
</script>
</html>
3. resources
applicationContext-aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
<!-- 配置springmvc三大组件 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 扫描包下的注解,springmvc只扫描controller层
切记:只对web层扫描,否则可能出现问题,比如:AOP不生效
-->
<context:component-scan base-package="com.qf.controller"></context:component-scan>
<!-- 放行静态资源 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- 配置文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.qf.interceptor.LoginIntercetor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
applicationContext-bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
<!-- 扫描对应包下的注解 -->
<context:component-scan base-package="com.qf">
<!-- 排除要扫描的注解 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 导入jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- dataSource连接数据库 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>
<!-- sqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 必选属性 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 加载Mapper.xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
<!-- 加载mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 配置分页 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 -->
<value>
helperDialect=mysql
reasonable=true
supportMethodsArguments=true
</value>
</property>
</bean>
</array>
</property>
</bean>
<!-- 扫描Mapper接口,生成代理对象 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.qf.mapper"></property>
</bean>
<!-- AOP的配置 -->
<!-- TX的配置 -->
</beans>
applicationContext-tx.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
<!-- dataSource连接数据库 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>
<!-- 配置事务(使用xml方式配置) -->
<!-- 事务平台管理器,封装了所有的事务操作,依赖数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 对那些方法配置事务
isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
-->
<tx:attributes>
<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置织入 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="txPc" expression="execution( * com.qf.service.impl.*ServiceImpl.*(..))"/>
<!-- 配置切面 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"></aop:advisor>
</aop:config>
</beans>
jdbc.properties
jdbc.username=root(自己的账号)
jdbc.password=自己的密码
jdbc.url=jdbc:mysql://localhost:3306/guimeiuseUnicode=true&characterEncoding=utf8&useSSL=false```(自己的数据库)
jdbc.driver=com.mysql.cj.jdbc.Driver(注意版本是否添加.cj)
log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER"
"http://org/apache/log4j/xml/log4j.dtd">
<log4j:configuration>
<!-- org.apache.log4j.ConsoleAppender 输出到控制台 -->
<appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
<!--输出格式-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
</layout>
</appender>
<!-- 输出到文件 -->
<appender name="myFile1" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="d:/logs/mylog1.log"/><!--文件位置-->
<param name="Append" value="true"/><!--是否选择追加-->
<param name="MaxFileSize" value="1kb"/><!--文件最大字节数-->
<param name="MaxBackupIndex" value="2" /><!--新文件数量-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n" />
</layout>
</appender>
<!-- 输出到文件(每天生成一个新的日志文件) -->
<appender name="myFile2" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="d:/logs/mylog2.log"/><!--文件位置-->
<param name="Append" value="true"/><!--是否选择追加-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
</layout>
</appender>
<!-- 根logger的设置-->
<root>
<!--优先级设置,all < trace < debug < info < warn < error < fatal < off -->
<!-- 配置info,则info级别以上的信息都显示出来-->
<priority value="all"/>
<appender-ref ref="myConsole"/>
<!-- <appender-ref ref="myFile1"/>-->
<!-- <appender-ref ref="myFile2"/>-->
</root>
</log4j:configuration>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置日志 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
</configuration>
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
<!-- 配置springmvc三大组件 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 扫描包下的注解,springmvc只扫描controller层
切记:只对web层扫描,否则可能出现问题,比如:AOP不生效
-->
<context:component-scan base-package="com.qf.controller"></context:component-scan>
<!-- 放行静态资源 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- 配置文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.qf.interceptor.LoginIntercetor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
4. mapper
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xs.mapper.UserMapper">
<resultMap id="userMap" type="com.xs.entity.User">
<id column="ID" property="id" jdbcType="INTEGER"/>
<result column="USER_NAME" property="userName" jdbcType="VARCHAR"/>
<result column="USER_PWD" property="userPwd" jdbcType="VARCHAR"/>
<result column="USER_REALNAME" property="userRealname" jdbcType="VARCHAR"/>
<result column="USER_GENDER" property="userGender" jdbcType="CHAR"/>
<result column="USER_EMAIL" property="userEmail" jdbcType="VARCHAR"/>
<result column="USER_PHONE" property="userPhone" jdbcType="CHAR"/>
<result column="USER_ID" property="userId" jdbcType="CHAR"/>
<result column="USER_BIRTHDATE" property="userBirthdate" jdbcType="DATE"/>
<result column="USER_LOCK" property="userLock" jdbcType="INTEGER"/>
<result column="USER_ADDRESS" property="userAddress" jdbcType="VARCHAR"/>
<result column="USER_IMAGE" property="userImage" jdbcType="VARCHAR"/>
</resultMap>
<sql id="baseSql">
select ID,
USER_NAME,
USER_PWD,
USER_REALNAME,
USER_GENDER,
USER_EMAIL,
USER_PHONE,
USER_ID,
USER_BIRTHDATE,
USER_LOCK,
USER_ADDRESS,
USER_IMAGE
from t_user
</sql>
<!-- 1、查询所有用户 -->
<select id="findAll" resultMap="userMap">
<include refid="baseSql"></include>
</select>
<!-- 2、添加用户 -->
<insert id="addUser" parameterType="com.xs.entity.User">
insert into t_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userName != null">
USER_NAME,
</if>
<if test="userPwd != null">
USER_PWD,
</if>
<if test="userRealname != null">
USER_REALNAME,
</if>
<if test="userGender != null">
USER_GENDER,
</if>
<if test="userEmail != null">
USER_EMAIL,
</if>
<if test="userPhone != null">
USER_PHONE,
</if>
<if test="userId != null">
USER_ID,
</if>
<if test="userBirthdate != null">
USER_BIRTHDATE,
</if>
<if test="userLock != null">
USER_LOCK,
</if>
<if test="userAddress != null">
USER_ADDRESS,
</if>
<if test="userImage != null">
USER_IMAGE,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userName != null">
#{userName,jdbcType=VARCHAR},
</if>
<if test="userPwd != null">
#{userPwd,jdbcType=VARCHAR},
</if>
<if test="userRealname != null">
#{userRealname,jdbcType=VARCHAR},
</if>
<if test="userGender != null">
#{userGender,jdbcType=CHAR},
</if>
<if test="userEmail != null">
#{userEmail,jdbcType=VARCHAR},
</if>
<if test="userPhone != null">
#{userPhone,jdbcType=CHAR},
</if>
<if test="userId != null">
#{userId,jdbcType=CHAR},
</if>
<if test="userBirthdate != null">
#{userBirthdate,jdbcType=DATE},
</if>
<if test="userLock != null">
#{userLock,jdbcType=INTEGER},
</if>
<if test="userAddress != null">
#{userAddress,jdbcType=VARCHAR},
</if>
<if test="userImage != null">
#{userImage,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<!-- 3、修改用户 -->
<update id="updateUser" parameterType="com.xs.entity.User">
update t_user
<set>
<if test="userName != null">
USER_NAME = #{userName,jdbcType=VARCHAR},
</if>
<if test="userPwd != null">
USER_PWD = #{userPwd,jdbcType=VARCHAR},
</if>
<if test="userRealname != null">
USER_REALNAME = #{userRealname,jdbcType=VARCHAR},
</if>
<if test="userGender != null">
USER_GENDER = #{userGender,jdbcType=CHAR},
</if>
<if test="userEmail != null">
USER_EMAIL = #{userEmail,jdbcType=VARCHAR},
</if>
<if test="userPhone != null">
USER_PHONE = #{userPhone,jdbcType=CHAR},
</if>
<if test="userId != null">
USER_ID = #{userId,jdbcType=CHAR},
</if>
<if test="userBirthdate != null">
USER_BIRTHDATE = #{userBirthdate,jdbcType=DATE},
</if>
<if test="userLock != null">
USER_LOCK = #{userLock,jdbcType=INTEGER},
</if>
<if test="userAddress != null">
USER_ADDRESS = #{userAddress,jdbcType=VARCHAR},
</if>
<if test="userImage != null">
USER_IMAGE = #{userImage,jdbcType=VARCHAR},
</if>
</set>
where ID = #{id,jdbcType=INTEGER}
</update>
<!-- 4、删除单个用户 -->
<delete id="deleteById">
delete from t_user
<where>
<if test="id != null">
ID = #{id}
</if>
</where>
</delete>
<!-- 5、批量删除用户 -->
<delete id="deleteByIds">
delete from t_user
<where>
id in
<foreach collection="array" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</where>
</delete>
</mapper>
AdminMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xs.mapper.AdminMapper">
<resultMap id="adminMap" type="com.xs.entity.Admin">
<id column="ADMIN_ID" property="adminId" jdbcType="INTEGER"/>
<result column="ADMIN_NAME" property="adminName" jdbcType="VARCHAR"/>
<result column="ADMIN_PWD" property="adminPwd" jdbcType="VARCHAR"/>
<result column="ADMIN_REALNAME" property="adminRealname" jdbcType="VARCHAR"/>
<result column="ADMIN_EMAIL" property="adminEmail" jdbcType="VARCHAR"/>
</resultMap>
<sql id="baseSql">
select ADMIN_ID, ADMIN_NAME, ADMIN_PWD, ADMIN_REALNAME, ADMIN_EMAIL
from t_admin
</sql>
<!-- 登录 -->
<select id="login" resultMap="adminMap">
<include refid="baseSql"></include>
<where>
ADMIN_NAME = #{adminName} and ADMIN_PWD = #{adminPwd}
</where>
</select>
</mapper>
二、JAVA
2.1 controller
2.1.1 AdminController
package com.xs.controller;
import com.xs.entity.Admin;
import com.xs.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@Controller
@RequestMapping("admin")
public class AdminController {
@Autowired
private AdminService adminService;
/**
* 登录
* @param admin
* @param httpSession
* @return
*/
@RequestMapping("login")
public String login(Admin admin, HttpSession httpSession) {
// 查询数据库
Admin db_admin = adminService.login(admin);
// 判断
if (db_admin != null && db_admin.getAdminName() != null) {
// 登录成功,放到session中
httpSession.setAttribute("admin", db_admin);
// 调用记录的方法(未写)
return "redirect:/index.html";
} else {
return "redirect:/adminLogin.html";
}
}
/**
* 退出登录
* @param request
* @param response
* @throws IOException
*/
@RequestMapping("logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
// session(false)
HttpSession session = request.getSession(false);
session.removeAttribute("admin");//移除数据
// 销毁session invalidate: 无效 使session失效
// session.invalidate();
response.sendRedirect(request.getContextPath() + "/adminLogin.html");
}
}
2.1.2 UserController
package com.xs.controller;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xs.dto.UserAddress;
import com.xs.dto.UserAddressDto;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import com.xs.service.UserService;
import com.xs.utils.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@RestController// 1、控制器
@RequestMapping("user") // 2、请求映射:用在类上表示是一级路径
public class UserController {
@Autowired// 3、自动接线---业务层
private UserService userService;
// 3.1 添加---用于接收上路径
String userImagePath = null;
@RequestMapping("findAll") // 4、请求映射:用在方法上表示是二级路径
public List<User> fidAll() { // 5、查询所有方法
return userService.findAll();
}
/**
* 1、分页
*
* @param pageNum
* @param pageSize
* @return
*/
@RequestMapping("findByPage")
public JsonResult<User> findByPage(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(value = "limit", required = false, defaultValue = "3") Integer pageSize
) {
// 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 只对紧跟startPage后面的方法才会进行分页
List<User> userList = userService.findAll();
// 封装到PageInfo对象中
PageInfo<User> userPageInfo = new PageInfo<>(userList);
// 判断
if (userList != null) {
// 返回分页数据
JsonResult jsonResult = JsonResult.ok();
// 返回分页数据
jsonResult.setData(userPageInfo.getList());
// 返回总记录数
jsonResult.setCount(userPageInfo.getTotal());
return jsonResult;
}
return JsonResult.error();
}
/**
* 2、layUI上传封装对象的名称使用file
*/
@RequestMapping("upload")
public JsonResult upload(MultipartFile file) {
// 2.1 获取上传路径
String uploadPath = "D:\\tomcat-two\\apache-tomcat-9.0.33\\webapps\\guimei\\";
// 2.2 获取上传的文件名
String filename = file.getOriginalFilename();
System.out.println(filename);
// 2.3 如果图片名称是中文,需要转换
try {
filename = new String(filename.getBytes("iso-8859-1"), "utf-8");
System.out.println("转换后的中文图片名称:" + filename);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 2.4 在上传之前我们要考虑文件名的唯一性
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
// 拼接后的文件名
String uploadFileName = uuid + filename;
System.out.println("上传的文件名:" + uploadFileName);
// 2.5 创建上传的文件对象
File uploadFile = new File(uploadPath, uploadFileName);
// 2.6 上传
try {
file.transferTo(uploadFile);
} catch (IOException e) {
e.printStackTrace();
}
// 2.7 保存到数据库的路径
userImagePath = "http://localhost:8083/guimei/" + uploadFileName;
JsonResult jsonResult = JsonResult.ok();
jsonResult.setData(userImagePath);
return jsonResult;
}
/**
* 3、添加
*/
@RequestMapping("addUser")
public void addUser(User user, HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println(user);
// 设置上传路径
if (user != null) {
user.setUserImage(userImagePath);
// 添加
userService.addUser(user);
// 跳转页面
response.sendRedirect(request.getContextPath() + "/index.html");
} else {
throw new RuntimeException("user为空");
}
}
/**
* 4、修改
*/
@RequestMapping("updateUser")
public String updateUser(User user) {
if (user != null) {
userService.updateUser(user);
return "success";
} else {
throw new RuntimeException("user为空");
}
}
/**
* 5、删除用户
*/
@RequestMapping("deleteById")
public String deleteById(Integer id) {
userService.deleteById(id);
return "success";
}
/**
* 6、批量删除用户
*/
@RequestMapping("deleteByIds")
public String deleteByIds(Integer[] ids) {
System.out.println("deleteByIds: " + Arrays.toString(ids));
userService.deleteByIds(ids);
return "success";
}
/**
* 7、导出Excel
*/
@RequestMapping("findByIds")
public void findByIds(Integer[] ids, HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println(Arrays.toString(ids));
// 7.1 判断ids不为空,确保导出数据存在数值
if (ids != null && ids.length > 0) {
List<User> userList = userService.findByIds(ids);// 返回7.2 User List集合
System.out.println("userList: " + userList);
// 7.3 第一种方式: 写入Excel System.currentTimeMillis() : 系统当前时间(选中对象的当前毫秒值)
// String fileName = "D:/" + System.currentTimeMillis() + ".xlsx";
// EasyExcel.write(fileName,User.class).sheet("模板").doWrite(userList);
// 7.4 第二种方式: 以下载的方式导出Excel
String fileName = System.currentTimeMillis() + ".xlsx";
// 7.5 设置响应头,Content-Disposition: attachment; filename=aaa.zip --告诉浏览器以下载方式打开资源(文件下载)
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
// 7.6 获取流对象 = 响应.获取输出流
ServletOutputStream outputStream = response.getOutputStream();
// 7.7 写入Excel
EasyExcel.write(outputStream, User.class).sheet("用户列表").doWrite(userList);
} else {
throw new RuntimeException("ids为空");
}
}
/**
* 8、导入Excel
*/
@RequestMapping("readExcel")
public JsonResult readExcel(MultipartFile file) {
if (file != null) {
userService.readExcel(file);
return JsonResult.ok();
}
throw new RuntimeException("上传文件异常");
}
/**
* 9、男女用户比例(柱状图)
*/
@RequestMapping("getUserGenderDto")
public UserGenderDto getUserGenderDto() {
// 先去数据库查询男女人数(用户性别 Dto 列表)
List<UserGenderDto> userGenderDtoList = userService.findGender();
System.out.println(userGenderDtoList);
// 存储: 男, 女
String [] genders = new String[userGenderDtoList.size()];
// 存储:7, 5
Integer [] genderNums = new Integer[userGenderDtoList.size()];
// 遍历并赋值 (用户性别 Dto 列表.size())
for (int i = 0; i < userGenderDtoList.size(); i++) {
genders[i] = userGenderDtoList.get(i).getGender();// 女
genderNums[i] = userGenderDtoList.get(i).getGenderNum();// 5
}
// 赋值 用户性别 Dto
UserGenderDto userGenderDto = new UserGenderDto();
userGenderDto.setGendersDate(genders);
userGenderDto.setName("性别");
userGenderDto.setType("bar");
userGenderDto.setData(genderNums);
return userGenderDto;
}
/**
* 10、获取用户位置以及人数
*/
@RequestMapping("getUserAddressDto")
public List<UserAddressDto> getUserAddressDto() {
// 查询数据
List<UserAddress> userAddressList = userService.findAddress();
// 赋值
List<UserAddressDto> userAddressDtoList = new ArrayList<>();
// 遍历
for (int i = 0; i < userAddressList.size(); i++) {
UserAddressDto userAddressDto = new UserAddressDto();
// 赋值
userAddressDto.setName(userAddressList.get(i).getAddress());
userAddressDto.setValue(BigDecimal.valueOf(userAddressList.get(i).getAddressNum()));
// 添加到集合
userAddressDtoList.add(userAddressDto);
}
return userAddressDtoList;
}
}
2.2 dto
2.2.1 UserAddress用户地址
package com.xs.dto;
import lombok.Data;
@Data//用户地址
public class UserAddress {
private String address;
private Integer addressNum;
}
2.2.2 UserAddressDto用户位置分布
package com.xs.dto;
import lombok.Data;
import java.math.BigDecimal;
// 用户位置分布
@Data
public class UserAddressDto {
private BigDecimal value;
private String name;
}
2.2.3 UserGenderDto柱状图男女人数
package com.xs.dto;
import lombok.Data;
// 柱状图男女人数
@Data
public class UserGenderDto {
// 性别数据内容
private String [] gendersDate;
private String name;
private String type;
// 数量
private Integer [] data;
// 另外声明两个属性,用于映射数据库中的数据
private String gender;
private Integer genderNum;
}
2.3 interceptor
2.3.1 listener登录拦截器
package com.xs.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashSet;
import java.util.Set;
// 登录拦截器
public class LoginInterceptor implements HandlerInterceptor {
// 设置白名单
private Set<String> whiteUrls = new HashSet<>();
public LoginInterceptor() {
// 自定义放行路径
whiteUrls.add("/login");
whiteUrls.add("/adminLogin.html");
// 。。。。。
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("登录拦截器preHandel");
// 获取当前正在访问的路径
String requestURL = request.getRequestURL().toString();// http://localhost:8080/index.html
String requestURI = request.getRequestURI();// index.html
System.out.println("requestURL:" + requestURL);
System.out.println("requestURI:" + requestURI);
// 遍历白名单
for (String url : whiteUrls) {
// 判断
if (requestURL.endsWith(url)) {
return true;
}
}
// 如若已有登录,将放行
HttpSession session = request.getSession(false);
// 判断 登录状态是否存在
if (session != null) {
// 判断
if (session.getAttribute("admin") != null) {
return true;
}
}
// 未登录去登录页面
// 请求.获取请求调度程序
// request.getRequestDispatcher("adminLogin.html").forward(request,response);
response.sendRedirect("adminLogin.html");
return false;
}
}
2.4 mapper
2.4.1 AdminMapper 用户登录
package com.xs.mapper;
import com.xs.entity.Admin;
import org.springframework.stereotype.Repository;
@Repository //存储库
public interface AdminMapper {
/**
* 用户登录
* @param admin
* @return
*/
Admin login(Admin admin);
}
2.4.2 UserMapper 数据访问层
package com.xs.mapper;
import com.xs.dto.UserAddress;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import org.springframework.stereotype.Repository;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@Repository// 1、存储库
public interface UserMapper {
/**
* 查询所有用户
* Mapper.xml实现查询所有方法
* @return
*/
List<User> findAll();
/**
* 添加用户
* @param user
*/
void addUser(User user);
/**
* 修改用户
* @param user
*/
void updateUser(User user);
/**
* 删除单个用户
* @param id
*/
void deleteById(Integer id);
/**
* 批量删除
* @param ids
*/
void deleteByIds(Integer[] ids);
/**
* 导出Excel
* @param ids
* @return
*/
List<User> findByIds(Integer[] ids);
/**
* 批量插入
* @param cachedDataList
*/
void save(List<User> cachedDataList);
/**
* 获取男女人数
* @return
*/
List<UserGenderDto> findGender();
/**
* 用户地址以及人数
* @return
*/
List<UserAddress> findAddress();
}
2.5 entity
2.5.1 User
package com.xs.entity;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* 用户表t_user
*CREATE TABLE t_user(
*ID INT(10)PRIMARY KEY NOT NULL AUTO_INCREMENT,
*USER_NAME VARCHAR(40),
*USER_PWD VARCHAR(60),
*USER_REALNAME VARCHAR(40),
*USER_GENDER CHAR(2),
*USER_EMAIL VARCHAR(60)UNIQUE,
*USER_PHONE CHAR(11)UNIQUE,
*USER_ID CHAR(18)UNIQUE,
*USER_BIRTHDATE DATE,
*USER_LOCK INT(1),
*USER_ADDRESS VARCHAR(255),
*USER_IMAGE VARCHAR(255)
*)ENGINE=INNODB DEFAULT CHARSET=utf8;
*/
@Data
public class User {
//@ExcelProperty("编号")//给导出的属性起别名
private Integer id;
//@ExcelProperty("姓名")
private String userName;
private String userPwd;
private String userRealname;
private String userGender;
private String userEmail;
private String userPhone;
private String userId;
// @DateTimeFormat: 日期时间格式((pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date userBirthdate;
private Integer userLock;
private String userAddress;
//@ExcelIgnore//不导出该属性
private String userImage;
}
2.5.2 Admin
package com.xs.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class Admin implements Serializable {
private Integer adminId;
private String adminName;
private String adminPwd;
private String adminRealname;
private String adminEmail;
}
2.6 service 业务逻辑层
2.6.1 UserService
package com.xs.service;
import com.xs.dto.UserAddress;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 业务逻辑层
*/
public interface UserService {
/**
* 查看所有用户
* @return
*/
List<User> findAll();
/**
* 添加用户
* @param user
*/
void addUser(User user);
/**
* 修改用户
* @param user
*/
void updateUser(User user);
/**
* 删除单个用户
* @param id
*/
void deleteById(Integer id);
/**
* 批量删除
* @param ids
*/
void deleteByIds(Integer[] ids);
/**
* 导出Excel
* @param ids
* @return
*/
List<User> findByIds(Integer[] ids);
/**
* 导入Excel
* @param file
*/
void readExcel(MultipartFile file);
/**
* 获取男女人数
* @return
*/
List<UserGenderDto> findGender();
/**
* 获取用户地址以及人数
* @return
*/
List<UserAddress> findAddress();
}
2.6.2 AdminService 管理服务层
package com.xs.service;
import com.xs.entity.Admin;
import org.springframework.stereotype.Service;
@Service
public interface AdminService {
/**
* 用户登录
* @param admin
* @return
*/
Admin login(Admin admin);
}
2.7 impl 接口实现
2.7.1 UserServiceImpl
package com.xs.service.impl;
import com.alibaba.excel.EasyExcel;
import com.xs.dto.UserAddress;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import com.xs.listener.UserListener;
import com.xs.mapper.UserMapper;
import com.xs.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Service // 1、业务逻辑接口实现类
public class UserServiceImpl implements UserService {
@Autowired // 2、自动接线数据访问层
private UserMapper userMapper;
@Override // 3、重写业务逻辑层的查询所有用户方法
public List<User> findAll() {
return userMapper.findAll();
}
@Override // 4、添加用户
public void addUser(User user) {
userMapper.addUser(user);
}
@Override // 5、修改用户
public void updateUser(User user) {
userMapper.updateUser(user);
}
@Override // 6、删除用户
public void deleteById(Integer id) {
userMapper.deleteById(id);
}
@Override // 7、批量删除
public void deleteByIds(Integer[] ids) {
userMapper.deleteByIds(ids);
}
@Override // 8、导出Excel
public List<User> findByIds(Integer[] ids) {
return userMapper.findByIds(ids);
}
@Override // 9、导入Excel
public void readExcel(MultipartFile file) {
// 9.1 获取输入流对象
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
// 9.2 读取、导入 用流读取
EasyExcel.read(inputStream, User.class, new UserListener(userMapper)).sheet().doRead();
}
@Override // 10、获取男女人数
public List<UserGenderDto> findGender() {
return userMapper.findGender();
}
@Override // 11、获取用户地址以及人数
public List<UserAddress> findAddress() {
return userMapper.findAddress();
}
}
2.7.2 AdminServiceImpl 管理服务实现
package com.xs.service.impl;
import com.xs.entity.Admin;
import com.xs.mapper.AdminMapper;
import com.xs.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
/**
* 用户登录
* @param admin
* @return
*/
@Override
public Admin login(Admin admin) {
return adminMapper.login(admin);
}
}
3 . utils
JsonResult (json结果 前端异步数据)
package com.xs.utils;
import lombok.Data;
@Data // 数据
public class JsonResult<T> {
private Integer code;
private String msg;
private T data;
private Long count; // 以layui默认规定的数据格式要求 声明
// 成功返回
public static JsonResult ok(){
JsonResult jsonResult = new JsonResult<>();
jsonResult.setCode(0);//layui中数据表格返回成功的code值,必须是0
jsonResult.setMsg("success");
return jsonResult;
}
// 失败返回
public static JsonResult error(){
JsonResult jsonResult = new JsonResult<>();
jsonResult.setCode(-200);
jsonResult.setMsg("fail");
return jsonResult;
}
}
本文含有隐藏内容,请 开通VIP 后查看