CMS客户关系管理系统【下】
引言:此文承接上一篇cms文章:https://developers.weixin.qq.com/community/develop/article/doc/00006c503209c8789ffaf9b2f5b013
当前常量和枚举
package com.sxt.common;
/**
* [@Description](/user/Description): 所有常量
* 存储系统中需要使用到的所有常量
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:39
*/
public interface Constant {
/**
* 验证码 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";
/**
* 默认密码
*/
String DEFAULT_PASSWORD = "123456";
/**
* 时间格式:yyyy-MM-dd HH:mm:ss
*/
String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
/**
* 客户状态 1 有效
*/
Integer CUSTOMER_STATE_VALID = 1;
/**
* 客户状态 2 无效
*/
Integer CUSTOMER_STATE_INVALID = 2;
}
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,"操作成功"),
USER_CHECK_CODE_ERROR(4002001,"用户验证码不正确"),
USER_USERNAME_NOT_EXIST_ERROR(4002002,"用户名不存在"),
USER_USERNAME_PASSWORD_ERROR(4002003,"用户名密码不匹配"),
USER_INVALID_ERROR(4002004,"用户账号已失效"),
USER_USERNAME_EXIST_ERROR(4002005,"用户账号已经被使用"),
USER_HAS_CUSTOMER_DELETE_ERROR(4002006,"存在关联客户,离职失败"),
CUSTOMER_PHONE_USED_ERROR(4003001,"客户的手机号已经被使用"),
;
/*
* 由于系统使用时 模块会逐渐增多
* 当业务失败时 所有的业务码 使用 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;
}
}
如何解决开发中的问题
缩小问题的范围!!!
在开发中,解决问题的方案就是不断的缩小问题的范围,从而==定位问题==。
在web开发中,定位和解决问题秉承以上思想。
web开发由两个部分组成:
- web部分
- 后台部分
==Web部分和后台部分==是通过HTTP协议进行数据交互。在Web项目中,定位问题,根据HTTP协议进行定位,查看 HTTP协议中传输的数据,是不是预期数据。
如果:后台传给WEB是预期数据,问题出在WEB部分
如果: WEB部分传给后台的数据是预期数据,但是后台返回的数据不是预期数据,问题就出在后台。
如何查看HTTP协议中传输的数据:
使用==F12查看网络==,查看请求参数或者响应数据。
修改客户
修改客户
- 点击修改客户,弹出模板层
- 将当前的行数据,赋值到弹出层中
- 获取表单数据,并且新增id属性(由于后台需要通过ID修改数据,弹出层中是没有id这个表单域)
- 使用ajax提交数据
- 刷新表格
1.修改list.jsp
//行监听事件
table.on("tool(dataTableFilter)",function (d) {
let event = d.event;
let rowData = d.data;
if (event == "update"){
update(rowData);
}else if (event == "visit"){
}else if (event == "del"){
}
});
//具体的修改方法
function update(rowData) {
if (rowData.delete == 2){
layer.msg("无效客户无法进行修改!");
return false;
}
//如果直接使用layerOpt
//当进行修改时 会修改layerOpt 中success 属性
//再进行新增 数据提交 会向修改的地址提交
//所以将layerOpt 进行复制 避免 layerOpt发生属性修改时 影响了新增业务
let opt = {};
//对象复制
Object.assign(opt,layerOpt)
opt.success = function(l,index){
form.render();//渲染表单
laydate.render({elem:"#editBirth"})
form.val("editFormFilter",rowData);
//设置表单提交监听事件
form.on("submit(subBtnFilter)",function (formData) {
formData.field.id = rowData.id;//新增id属性值
//使用ajax提交数据
$.post("${pageContext.request.contextPath}/customer.do?service=update",formData.field,function (rs) {
if (rs.code != 200){
layer.msg(rs.msg);
return false;
}
//刷新表格
$("#searchBtn").click();
//关闭弹层
layer.close(index);
})
return false;//阻止表单默认提交行为
});
}
//弹出层
layer.open(opt);
}
2.修改CustomerController
/**
* 处理更新请求
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取前端参数
String id = req.getParameter("id");
String name = req.getParameter("name");
String sex = req.getParameter("sex");
String phone = req.getParameter("phone");
String birth = req.getParameter("birth");
String salary = req.getParameter("salary");
String address = req.getParameter("address");
String time = DateUtil.format(new Date(),Constant.YYYY_MM_DD_HH_MM_SS);
Customer customer = new Customer(Integer.parseInt(id),name,Integer.parseInt(sex),phone,Integer.parseInt(salary),address,birth, 0,0,"",time,"");
Result rs = customerService.update(customer);
RespUtil.writer(rs,resp);
}
3.修改ICustomerService
/**
* 更新客户数据
* @param customer
* @return
*/
Result update(Customer customer);
4.修改CustomerServiceImpl
[@Override](/user/Override)
public Result update(Customer customer) {
//修改客户信息
Customer c = customerDao.selectByPhone(customer.getPhone());
//如果查询的客户信息不为空 且客户ID 不为当前客户 说明其它客户使用了这个手机号
if (c != null && !c.getId().equals(customer.getId())){
return new Result(CodeMsg.CUSTOMER_PHONE_USED_ERROR);
}
customerDao.update(customer);
return new Result();
}
5.修改CustomerDao
/**
* 修改客户信息
* @param customer
*/
public void update(Customer customer) {
String sql = "UPDATE `customer` SET `name` = ?, `sex` = ?, `phone` = ?, `salary` = ?, `address` = ?, `birth` = ?, `modify_time` = ? WHERE `id` = ?";
super.update(sql,customer.getName(),customer.getSex(),customer.getPhone(),customer.getSalary(),customer.getAddress(),customer.getBirth(),customer.getModifyTime(),customer.getId());
}
删除客户
删除客户
点击删除按钮
进行数据状态校验
进行二次确认
将数据ID传给后台
展示业务结果,刷新数据表格
1.修改list.jsp
//行监听事件
table.on("tool(dataTableFilter)",function (d) {
let event = d.event;
let rowData = d.data;
if (event == "update"){
update(rowData);
}else if (event == "visit"){
}else if (event == "del"){
del(rowData);
}
});
//客户删除
function del(rowData) {
if (rowData.delete == 2){
layer.msg("无效客户,无须删除");
return false;
}
layer.confirm('确定要删除客户吗?',function (index) {
$.get("${pageContext.request.contextPath}/customer.do?service=delete",{id:rowData.id},function (rs) {
layer.msg(rs.msg);
$("#searchBtn").click();
layer.close(index);
})
});
}
2.修改CustomerController
/**
* 处理删除客户请求
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取前端参数
String id = req.getParameter("id");
Result rs = customerService.delete(id);
RespUtil.writer(rs,resp);
}
3.修改ICustomerService
/**
* 删除客户
* @param id
* @return
*/
Result delete(String id);
4.修改CustomerServiceImpl
[@Override](/user/Override)
public Result delete(String id) {
customerDao.delete(id, Constant.CUSTOMER_STATE_INVALID);
return new Result();
}
5.修改CustomerDao
/**
* 删除数据
* @param id
* @param state
*/
public void delete(String id,Integer state) {
String sql = "update customer set `delete` = ?,modify_time=?,delete_time = ? where id=?";
String time = DateUtil.format(new Date(), Constant.YYYY_MM_DD_HH_MM_SS);
super.update(sql,state,time,time,id);
}
指定业务员
指定业务员
为所有选择的客户,指定某个业务员。批量修改user_id
- 获取所有选中的客户,进行数据校验
- 点击设置业务员按钮,弹出层
- 获取所有的有效业务员,渲染下拉框
- 将所有的客户ID 和 选中的业务员ID提交给后台
- 后台接收数据,进行数据操作,返回操作业务结果
- 接收结果,刷新表格
1.修改list.jsp
<%-- 头工具栏 --%>
<script type="text/html" id="headerBtns"></script>
//头工具栏监听事件
table.on("toolbar(dataTableFilter)",function (d) {
let event = d.event;
if (event == "add"){
add();
}else if (event == "setSaleseman"){
setSalesman();
}
});
//更新选中的客户的业务员
function setSalesman(){
//获取选中的客户
let checkStatus = table.checkStatus("dataTableId");
let customers = checkStatus.data;
if (customers.length == 0){
layer.msg("请选择客户");
return false;
}
let cIds = new Array();
for (let c of customers){
cIds.push("cId="+c.id);
}
let cId = cIds.join("&");
let opt = {};
Object.assign(opt,layerOpt);
opt.area = ["380px","450px"];
opt.content = $("#setSalesmanTpl").html();
opt.success = function(l,index){
//获取所有的业务员
$.get("${pageContext.request.contextPath}/user.do?service=getAllUser", {
role: 2,
delete: 1
}, function (rs) {
let salesman = rs.data;
//获取业务员下拉框
let select = $("#salemanId");
for (let user of salesman) {
select.append('<option value="' + user.id + '">' + user.realname + '</option>');
}
//重新渲染下拉框
form.render("select");
});
//表单提交监听
//设置表单提交监听事件
form.on("submit(subBtnFilter)",function (formData) {
//使用ajax提交数据
$.post("${pageContext.request.contextPath}/customer.do?service=setSalesman&"+cId,formData.field,function (rs) {
if (rs.code != 200){
layer.msg(rs.msg);
return false;
}
//刷新表格
$("#searchBtn").click();
//关闭弹层
layer.close(index);
})
return false;//阻止表单默认提交行为
});
};
layer.open(opt)
}
2.修改CustomerController
/**
* 批量设置业务员
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void setSalesman(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取前端参数
String[] cId = req.getParameterValues("cId");
String userId = req.getParameter("salemanId");
Result rs = customerService.batchSetSalesman(userId,cId);
RespUtil.writer(rs,resp);
}
3.修改ICustomerService
/**
* 批量设置业务员
* @param userId
* @param cId
* @return
*/
Result batchSetSalesman(String userId, String[] cId);
4.修改CustomerServiceImpl
[@Override](/user/Override)
public Result batchSetSalesman(String userId, String[] cId) {
customerDao.batchUpdateUserId(userId,cId);
return new Result();
}
5.修改CustomerDao
public void batchUpdateUserId(String userId, String[] cId) {
String sql = "update customer set user_id = ? ,modify_time=? where id in(";
for (String s : cId) {
sql = sql + s +",";
}
sql = sql +"0)";
String time = DateUtil.format(new Date(),Constant.YYYY_MM_DD_HH_MM_SS);
super.update(sql,userId,time);
}
新增拜访记录
新增拜访记录
- 点击拜访按钮,弹出一个层
- 回显数据,显示客户部分信息
- 填写拜访的时间
- 将数据提交给后台
- 后台进行数据处理,返回业务结果
- 接收业务结果,展示业务结果
注意: 修改VisitLog实体类中userId的类型
1.修改list.jsp
<%-- 新增拜访记录 --%>
<script type="text/html" id="addVisitTpl">
<div style="padding: 20px">
<form class="layui-form layui-form-pane" id="addVisitLogForm" lay-filter="addVisitLogFilter">
<div class="layui-form-item">
<label class="layui-form-label">客户名称</label>
<div class="layui-input-inline">
<input type="text" name="name" class="layui-input" placeholder="客户名称" readonly>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-inline">
<input type="text" name="address" class="layui-input" readonly >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">拜访时间</label>
<div class="layui-input-inline">
<input type="text" name="visitTime" id="visitTime" class="layui-input" placeholder="拜访时间" autocomplete="off" lay-verify="required" lay-reqText="请输入拜访时间" readonly >
</div>
</div>
<button type="button" style="display: none" id="subBtn" lay-submit lay-filter="subBtnFilter"></button>
</form>
</div>
</script>
//行监听事件
table.on("tool(dataTableFilter)",function (d) {
let event = d.event;
let rowData = d.data;
if (event == "update"){
update(rowData);
}else if (event == "visit"){
addVisitLog(rowData);
}else if (event == "del"){
del(rowData);
}
});
//新增拜访记录
function addVisitLog(rowData) {
if (rowData.delete == 2){
layer.msg("无效客户,无须拜访");
return false;
}
let opt = {};
//对象复制
Object.assign(opt,layerOpt)
opt.content = $("#addVisitTpl").html();
opt.area = ['380px','450px'];
opt.success = function(l,index){
form.render();//渲染表单
laydate.render({elem:"#visitTime"})
form.val("addVisitLogFilter",{
name:rowData.name, //为客户名称赋值
address:rowData.address//为客户地址赋值
});
//设置表单提交监听事件
form.on("submit(subBtnFilter)",function (formData) {
formData.field.cId = rowData.id;//新增id属性值
//使用ajax提交数据
$.post("${pageContext.request.contextPath}/log.do?service=add",formData.field,function (rs) {
if (rs.code != 200){
layer.msg(rs.msg);
return false;
}
//关闭弹层
layer.close(index);
})
return false;//阻止表单默认提交行为
});
}
//弹出层
layer.open(opt);
}
2.修改VisitLogController
IVisitLogService visitLogService = null;
[@Override](/user/Override)
public void init() throws ServletException {
visitLogService = new VisitLogServiceImpl();
}
[@Override](/user/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 add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String visitTime = req.getParameter("visitTime");//拜访时间
String cId = req.getParameter("cId");//客户ID
String name = req.getParameter("name");//客户名称
User u = (User) req.getSession().getAttribute(Constant.CURRENT_USER_KEY);
String time = DateUtil.format(new Date(),Constant.YYYY_MM_DD_HH_MM_SS);
VisitLog visitLog = new VisitLog(Integer.parseInt(cId),name,u.getId(),u.getRealname(),visitTime,time);
Result rs = visitLogService.add(visitLog);
RespUtil.writer(rs,resp);
}
3.修改IVisitLogService
/**
* 新增拜访记录
* @param visitLog
* @return
*/
Result add(VisitLog visitLog);
4.修改VisitLogServiceImpl
VisitLogDao visitLogDao = new VisitLogDao();
[@Override](/user/Override)
public Result add(VisitLog visitLog) {
visitLogDao.insert(visitLog);
return new Result();
}
5.修改VisitLogDao
public void insert(VisitLog visitLog) {
String sql = "insert into visit_log (cust_id,cust_name,user_id,user_name,visit_time,create_time) value(?,?,?,?,?,?)";
super.update(sql,visitLog.getCustId(),visitLog.getCustName(),visitLog.getUserId(),visitLog.getUserName(),visitLog.getVisitTime(),visitLog.getCreateTime());
}
根据角色显示不同的菜单和按钮
根据角色显示不同的菜单,一般根据不同的角色显示不同的菜单和按钮:
通过从session中获取当前用户,获取用户对应的角色
通过c标签,控制页面的标签显示
1.修改main.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 使用c标签控制按钮 -->
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">基础信息管理</a>
<dl class="layui-nav-child">
<c:if test="${user.role == 1}">
<dd><a href="page.do?service=userList" target="content">员工管理</a></dd>
</c:if>
<dd><a href="page.do?service=customerList" target="content">客户管理</a></dd>
</dl>
</li>
2.修改customer/list.jsp
<%[@taglib](/user/taglib) prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- 头工具栏 --%>
<script type="text/html" id="headerBtns">
<div class="layui-btn-group">
<c:if test="${user.role == 2}">
<button class="layui-btn layui-btn-sm" lay-event="add">
<i class="layui-icon layui-icon-add-1"></i> 新增
</button>
</c:if>
<c:if test="${user.role == 1}">
<button class="layui-btn layui-btn-sm layui-btn-warm" lay-event="setSaleseman">
<i class="layui-icon layui-icon-set"></i> 设置业务员
</button>
</c:if>
</div>
</script>
<%-- 行工具栏 --%>
<script type="text/html" id="rowBtns">
<c:if test="${user.role == 2}">
<div class="layui-btn-group">
<button class="layui-btn layui-btn-xs layui-btn-warm" lay-event="update">
<i class="layui-icon layui-icon-edit"></i> 修改
</button>
<button class="layui-btn layui-btn-xs" lay-event="visit">
<i class="layui-icon layui-icon-release"></i> 拜访
</button>
<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">
<i class="layui-icon layui-icon-delete"></i> 删除
</button>
</div>
</c:if>
</script>
登录拦截
登录拦截
判断用户是否登录,如果登录了则直接放行。
如果没有登录获取请求的URI,判定URI的资源是否需要登录,如果无需登录则放行,否则跳转到登录页面
1.修改LoginFilter
package com.sxt.filter;
import cn.hutool.core.util.StrUtil;
import com.sxt.common.Constant;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* [@Description](/user/Description): 登录过滤器
* [@author](/user/author): Mr.T
* [@date](/user/date) 2020-09-15 15:19
*/
[@WebFilter](/user/WebFilter)("/*")
public class LoginFilter implements Filter {
[@Override](/user/Override)
public void init(FilterConfig filterConfig) throws ServletException {
}
[@Override](/user/Override)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//获取当前用户
Object o = req.getSession().getAttribute(Constant.CURRENT_USER_KEY);
if (o != null){
//已登录 则放行
chain.doFilter(request,response);
return;
}
//获取请求的资源路径
String uri = req.getRequestURI();
//静态资源文件 :/resources
//登录页面 /index.html
//验证码 :/code.do
//处理登录的请求 : user.do ? service = login
if (uri.startsWith("/resources") || uri.endsWith("index.html") ||uri.endsWith("code.do")){
//无需登录的资源
chain.doFilter(request,response);
return;
}
if (uri.endsWith("user.do") ){
String service = req.getParameter("service");
if (StrUtil.equals("login",service)){
//处理登录请求
chain.doFilter(request,response);
return;
}
}
//其他情况 去 登录页面
resp.sendRedirect(req.getContextPath()+"/index.html");
}
[@Override](/user/Override)
public void destroy() {
}
}
修改密码
修改密码:
- 创建一个修改密码的页面
- 显示用户的部分信息
- 让用户输入原密码、新密码、确认密码
- 将用户输入的数据提交给后台
- 后台进行数据处理
- 返回处理结果
- 显示处理结果
1.新建user/updatePwd.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>修改用户密码</title>
<%-- 引入layui --%>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/layui/css/layui.css">
</head>
<body>
<div style="padding: 20px">
<form class="layui-form layui-form-pane" id="editForm" lay-filter="editFormFilter">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" name="realName" class="layui-input" value="${user.realname}" readonly >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">登录名</label>
<div class="layui-input-inline">
<input type="text" name="username" value="${user.username}" class="layui-input" readonly >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-inline">
<input type="text" name="password" class="layui-input" placeholder="原密码" lay-verify="required" lay-reqText="请输入原密码" >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="text" name="newPassword" class="layui-input" placeholder="新密码" lay-verify="required" lay-reqText="请输入新密码" >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="text" name="confirmPassword" class="layui-input" placeholder="确认密码" lay-verify="required" lay-reqText="请再次新密码">
</div>
</div>
<div class="layui-form-item" style="margin-top: 35px">
<button type="button" class="layui-btn" id="subBtn" lay-submit lay-filter="subBtnFilter">确认修改</button>
</div>
</form>
</div>
<script src="${pageContext.request.contextPath}/resources/layui/layui.js"></script>
<script>
layui.use(['form','jquery','layer'],function (d) {
let form = layui.form;
let $ = layui.jquery;
let layer = layui.layer;
//表单提交事件
form.on("submit(subBtnFilter)",function (formData) {
let data = formData.field;
let newPassword = data.newPassword;
let confirmPassword = data.confirmPassword;
//校验两次密码是否一致
if (newPassword != confirmPassword){
layer.msg("两次密码不一致");
return false;
}
let param = {password:data.password,newPassword:newPassword};
$.post("${pageContext.request.contextPath}/user.do?service=updatePwd",param,function (rs) {
if (rs.code != 200){
layer.msg(rs.msg);
return false;
}
layer.msg("密码修改成功,3秒后重新登录");
setInterval(function () {
//查找父窗口的退出按钮
parent.window.location.href = "${pageContext.request.contextPath}/user.do?service=loginOut"
},3000);
})
})
});
</script>
</body>
</html>
2.修改PageController
/**
* 修改密码页面
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/view/user/updatePwd.jsp").forward(req,resp);
}
3.修改UserController
/**
* 修改用户密码
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String password = req.getParameter("password");
String newPassword = req.getParameter("newPassword");
User user = (User) req.getSession().getAttribute(Constant.CURRENT_USER_KEY);
if (!StrUtil.equals(password,user.getPassword())){
Result rs = new Result(CodeMsg.USER_UPDATE_FAILD_PASSWORD_ERROR);
RespUtil.writer(rs,resp);
return;
}
Result rs = userService.updatePassword(user.getId(),newPassword);
RespUtil.writer(rs,resp);
}
4.修改IUserService
/**
* 修改用户密码
* @param id
* @param newPassword
* @return
*/
Result updatePassword(Integer id, String newPassword);
5.修改UserServiceImpl
[@Override](/user/Override)
public Result updatePassword(Integer id, String newPassword) {
userDao.updatePassword(String.valueOf(id),newPassword);
return new Result();
}
修改头像
修改头像
- 新建user/updateImg.jsp页面,用于修改头像
- 将用户头像显示在页面
- 用户可以选择图片
- 将头像数据上传
- 接收后台返回的数据
- 修改页面头像
layui文件上传API
基础参数
参数名 | 值 | 说明 |
---|---|---|
elem | string/object | 绑定文件上传的组件 |
url | string | 接收上传数据的接口 |
data | object | 附加参数 |
accept | 可选值有:<br/>images(图片)、<br>file(所有文件)、<br/>video(视频)、<br/>audio(音频) | images |
acceptMime | string | 规定打开文件选择框时,筛选出的文件类型 |
exts | 允许上传的文件后缀。 | 默认:jpg|png|gif|bmp|jpeg |
auto | boolean | 默认true, 是否自动上传 false 则为不自动上传 |
bindAction | string/object | 指向一个按钮触发上传,当不为自动上传时,<br/>需指定按钮触发上传 |
field | string | 设定文件域的字段名,默认file.<br>后台根据文件域的字段名获取文件数据 |
size | number | 设置文件最大可允许上传的大小(kb),0(即不限制) |
choose | function(obj) | 选择文件后回调的函数<br>在obj对象中,存在preview的方法,方法中:<br>index: 文件索引<br/> file:文件对象<br/>result:文件base64字符串<br/> |
before | function | 上传前回调的函数 |
done | function | 上传完成回调的函数 |
error | function | 上传异常回调的函数 |
1.user/updateImg.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>修改用户密码</title>
<%-- 引入layui --%>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/layui/css/layui.css">
</head>
<body>
<div style="padding: 20px">
<form class="layui-form layui-form-pane" id="editForm" lay-filter="editFormFilter">
<div class="layui-form-item">
<label class="layui-form-label">用户头像</label>
<div class="layui-input-inline">
<img style="width: 200px;border: #c0c4cc 1px solid" id="userImg" onerror="javascript:this.src='${pageContext.request.contextPath}/imgs/default.jpg';" src="${pageContext.request.contextPath}/${user.img}">
</div>
</div>
<div class="layui-form-item" style="margin-top: 35px;margin-left: 110px">
<button type="button" class="layui-btn" id="subBtn" style="width: 200px;">确认修改</button>
</div>
</form>
</div>
<script src="${pageContext.request.contextPath}/resources/layui/layui.js"></script>
<script>
layui.use(['jquery','layer','upload'],function (d) {
let $ = layui.jquery;
let layer = layui.layer;
let upload = layui.upload;//文件上传组件
let opt = {
elem:"#userImg",//绑定的文件上传的组件
url:"${pageContext.request.contextPath}/user.do?service=upload",
auto:false,//是否自动上传
acceptMime:'image/*',//文件选择框 过滤的类型
bindAction:"#subBtn",//触发文件上传的按钮
field:"userImg",//文件域的名称
size:1024,//允许上传的文件的最大值 单位kb
choose:function (obj) {//选择了文件后调用的函数
obj.preview(function (index,file,result) {
console.log(index);
console.log(file);
console.log(result);
$("#userImg").attr("src",result);//修改图像src属性值 设置为base64字符串
});
},
done:function (rs,index,upload) {
//rs 就是服务器返回的数据
//index 当前上传的文件的索引
//upload 重新上传的对象
layer.msg(rs.msg);//将上传信息进行展示
if (rs.code == 200){//上传成功
//修改用户头像
// 修改用户头像 的src 对应的url值
let url = rs.data;//服务器存储的头像url路径
parent.window.document.getElementById("userIcon").src = "${pageContext.request.contextPath}/"+url;
}
}
};
upload.render(opt);
});
</script>
</body>
</html>
2.修改PageController
/**
* 修改用户头像
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void updateImg(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/view/user/updateImg.jsp").forward(req,resp);
}
3.修改main.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<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 id="userIcon" 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 id="loginOut" 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">
<c:if test="${user.role == 1}">
<dd><a href="page.do?service=userList" target="content">员工管理</a></dd>
</c:if>
<dd><a href="page.do?service=customerList" target="content">客户管理</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="page.do?service=updatePwd" target="content">密码管理</a></dd>
<dd><a href="page.do?service=updateImg" target="content">头像管理</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>
4.修改UserController
在==__UserController上@MultipartConfig__== //加上这个注解才支持文件上传
/**
* 处理文件上传
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void upload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取上传的文件数据
Part userImg = req.getPart("userImg");//获取上传的文件的数据
String realName = getRealName(userImg);
//获取文件后缀 没有 . 号
String extName = FileUtil.extName(realName);
String fileAsName = new Date().getTime()+"."+extName;
//物理路径 进行文件保存
String prePath = req.getServletContext().getRealPath("imgs");
//文件保存的物理路径
String filePath = prePath+ File.separator+fileAsName;
//url 网络访问路径
String url = "imgs/"+fileAsName;//
//先保存到磁盘 然后保存到数据库 如果数据库保存失败 删除磁盘文件
userImg.write(filePath);//保存到磁盘
User user = (User) req.getSession().getAttribute(Constant.CURRENT_USER_KEY);
Result rs = null;
try {
rs = userService.updateUserImg(user.getId(),url);
} catch (Exception exception) {
exception.printStackTrace();
//删除文件
File file = new File(filePath);
if (file.exists()){
file.delete();
}
rs = new Result(CodeMsg.USER_IMG_UPLOAD_ERROR);
}
//将URL保存到数据
//将文件保存在物理磁盘上
RespUtil.writer(rs,resp);
}
/**
* 根据文件信息 获取文件真实名称
* @param part
* @return
*/
private String getRealName(Part part){
//Content-Disposition: form-data; name="userImg"; filename="default.jpg"
String header = part.getHeader("Content-Disposition");
String[] fileInfo = header.split(";");
String fileNameInfo = fileInfo[2].trim();//filename="default.jpg"
//获取第一个 ”
int startIndex = fileNameInfo.indexOf("\"");
//获取最后一个"
int endIndex = fileNameInfo.lastIndexOf("\"");
//截取字符串
fileNameInfo = fileNameInfo.substring(startIndex+1,endIndex);
return fileNameInfo;
}
5.修改IUserService
/**
* 修改用户头像
* @param id
* @param url
* @return
*/
Result updateUserImg(Integer id, String url);
6.修改UserServiceImpl
[@Override](/user/Override)
public Result updateUserImg(Integer id, String url) {
userDao.updateImg(id,url);
return new Result(url);
}
7.修改UserDao
/**
* 修改用户头像
* @param id
* @param url
*/
public void updateImg(Integer id, String url) {
String sql = "update user set img = ? ,modify_time = ? where id=?";
String time = DateUtil.format(new Date(), Constant.YYYY_MM_DD_HH_MM_SS);
super.update(sql,url,time,id);
}