CMS客户关系管理系统【下】
CMS客户关系管理系统【下】
引言:此文承接上一篇cms文章:https://developers.weixin.qq.com/community/develop/article/doc/00006c503209c8789ffaf9b2f5b013
当前常量和枚举
package com.sxt.common;
/**
* @Description: 所有常量
* 存储系统中需要使用到的所有常量
* @author: Mr.T
* @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: 系统的业务码和业务消息枚举
* 存放整个系统需要用到业务码和对应的业务消息
* @author: Mr.T
* @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
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
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
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
public void init() throws ServletException {
visitLogService = new VisitLogServiceImpl();
}
@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
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 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: 登录过滤器
* @author: Mr.T
* @date 2020-09-15 15:19
*/
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOExce...
0 回复
