CMS客户关系管理系统【下】

发布于 5 年前作者 li053574 次浏览最后编辑 5 年前来自 share

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开发由两个部分组成:

  1. web部分
  2. 后台部分

==Web部分后台部分==是通过HTTP协议进行数据交互。在Web项目中,定位问题,根据HTTP协议进行定位,查看 HTTP协议中传输的数据,是不是预期数据。

如果:后台传给WEB是预期数据,问题出在WEB部分

如果: WEB部分传给后台的数据是预期数据,但是后台返回的数据不是预期数据,问题就出在后台。

如何查看HTTP协议中传输的数据:

使用==F12查看网络==,查看请求参数或者响应数据。

修改客户

修改客户

  1. 点击修改客户,弹出模板层
  2. 将当前的行数据,赋值到弹出层中
  3. 获取表单数据,并且新增id属性(由于后台需要通过ID修改数据,弹出层中是没有id这个表单域)
  4. 使用ajax提交数据
  5. 刷新表格

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

  1. 获取所有选中的客户,进行数据校验
  2. 点击设置业务员按钮,弹出层
  3. 获取所有的有效业务员,渲染下拉框
  4. 将所有的客户ID 和 选中的业务员ID提交给后台
  5. 后台接收数据,进行数据操作,返回操作业务结果
  6. 接收结果,刷新表格

1.修改list.jsp

 <%-- 头工具栏 --%>
    <script type="text/html" id="headerBtns">

        <div class="layui-btn-group">
            <button class="layui-btn layui-btn-sm" lay-event="add">
                <i class="layui-icon layui-icon-add-1"></i> 新增
            </button>
            <button class="layui-btn layui-btn-sm  layui-btn-warm" lay-event="setSaleseman">
                <i class="layui-icon layui-icon-set"></i> 设置业务员
            </button>
        </div>

    </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);
    }

新增拜访记录

新增拜访记录

  1. 点击拜访按钮,弹出一个层
  2. 回显数据,显示客户部分信息
  3. 填写拜访的时间
  4. 将数据提交给后台
  5. 后台进行数据处理,返回业务结果
  6. 接收业务结果,展示业务结果

注意: 修改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 回复
暂无回复