4. 联系人管理
4.1 联系人与客户关系分析
客户:指的是有很多员工的公司、组织、企业或类似机构。
例如:传智学院
联系人:与某公司(客户)进行对接时,所需要找该公司具体的员工。
例如:教学-梁老师、就业-刘老师、后勤-唐老师
根据分析,在CRM系统中,客户和联系人的关系是一对多,一个公司有多个对接人。
4.2 查询所有联系人
4.2.1 查询所有
需求:
步骤:
步骤1:入口
步骤2:编写LinkManController
步骤3:编写LinkManService 接口、实现类
步骤4:修改 linkman/list.jsp 展示数据
步骤1:入口
步骤2:编写LinkManController
package com.czxy.crm.controller; import com.czxy.crm.domain.LinkMan; import com.czxy.crm.service.LinkManService; import com.czxy.crm.vo.LinkManVo; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Controller @RequestMapping("/linkman") public class LinkManController { @Resource private LinkManService linkManService; @RequestMapping("/findAll") public String findAll(Model model){ // 查询所有 List<LinkMan> linkManList = linkManService.findAll(); model.addAttribute("linkManList", linkManList); return "linkman/list"; } }
步骤3:编写LinkManService 接口、实现类
接口
package com.czxy.crm.service; import com.czxy.crm.domain.LinkMan; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ public interface LinkManService { /** * 查询所有 * @param linkManVo * @return */ List<LinkMan> findAll(); }
实现类
package com.czxy.crm.service.impl; import com.czxy.crm.domain.LinkMan; import com.czxy.crm.mapper.LinkManMapper; import com.czxy.crm.service.LinkManService; import com.github.pagehelper.PageHelper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import tk.mybatis.mapper.entity.Example; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service @Transactional public class LinkManServiceImpl implements LinkManService { @Resource private LinkManMapper linkManMapper; @Override public List<LinkMan> findAll() { //1 条件查询 Example example = new Example(LinkMan.class); //2 分页查询 //3 查询 List<LinkMan> linkManList = linkManMapper.selectByExample(example); //4 关联 linkManList.forEach(linkMan -> { Customer customer = customerMapper.selectByPrimaryKey(linkMan.getCustId()); linkMan.setCustomer(customer); }); //5 封装 return linkManList; //return new PageInfo<>(linkManList); } }
步骤4:修改 linkman/list.jsp 展示数据
<c:forEach items="${linkManList}" var="linkman"> <TR style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none"> <TD>${linkman.lkmName }</TD> <TD>${linkman.lkmGender }</TD> <TD>${linkman.lkmPhone }</TD> <TD>${linkman.lkmMobile }</TD> <TD>${linkman.lkmEmail }</TD> <TD>${linkman.lkmPosition }</TD> <TD>${linkman.lkmMemo }</TD> <TD>${linkman.customer.custName}</TD> <TD> <a href="${pageContext.request.contextPath }/linkman/editUI.action?lkmId=${linkman.lkmId}">修改</a> <a href="javascript:void(0)" οnclick="deleteLinkMan('${linkman.lkmId}','${linkman.lkmName}')">删除</a> </TD> </TR> </c:forEach>
4.2.2 条件查询
需求:
步骤:
步骤1:入口,确定查询表单
步骤2:创建LinkManVo,用于封装查询条件
步骤3:修改LinkManController,获得查询条件
步骤4:修改LinkManService,使用查询条件
步骤1:入口,确定查询表单
步骤2:创建LinkManVo,用于封装查询条件
package com.czxy.crm.vo; /** * @author 桐叔 * @email liangtong@itcast.cn */ public class LinkManVo { private String lkmName; public String getLkmName() { return lkmName; } public void setLkmName(String lkmName) { this.lkmName = lkmName; } }
步骤3:修改LinkManController,获得查询条件
步骤4:修改LinkManService,使用查询条件
接口
实现类
package com.czxy.crm.service.impl; import com.czxy.crm.domain.LinkMan; import com.czxy.crm.mapper.LinkManMapper; import com.czxy.crm.service.LinkManService; import com.czxy.crm.vo.LinkManVo; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import tk.mybatis.mapper.entity.Example; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service @Transactional public class LinkManServiceImpl implements LinkManService { @Resource private LinkManMapper linkManMapper; @Override public List<LinkMan> findAll(LinkManVo linkManVo) { //1 条件查询 Example example = new Example(LinkMan.class); Example.Criteria criteria = example.createCriteria(); if(StringUtils.isNotBlank(linkManVo.getLkmName())) { criteria.andLike("lkmName", "%"+linkManVo.getLkmName()+"%"); } //2 分页查询 //3 查询 List<LinkMan> linkManList = linkManMapper.selectByExample(example); //4 关联 linkManList.forEach(linkMan -> { Customer customer = customerMapper.selectByPrimaryKey(linkMan.getCustId()); linkMan.setCustomer(customer); }); //5 封装 return linkManList; } }
4.2.3 分页查询
需求:
步骤
步骤1:修改LinkManVo,获得分页参数
步骤2:修改LinkManController,返回pageInfo
步骤3:修改LinkManService,封装PageInfo
步骤4:修改jsp,展示列表数据
步骤5:修改jsp,展示分页条
步骤1:修改LinkManVo,获得分页参数
package com.czxy.crm.vo; /** * @author 桐叔 * @email liangtong@itcast.cn */ public class LinkManVo { private String lkmName; private Integer pageNum = 1; private Integer pageSize = 2; //getter和setter }
步骤2:修改LinkManController,返回pageInfo
步骤3:修改LinkManService,封装PageInfo
接口
实现类
package com.czxy.crm.service.impl; import com.czxy.crm.domain.Customer; import com.czxy.crm.domain.LinkMan; import com.czxy.crm.mapper.CustomerMapper; import com.czxy.crm.mapper.LinkManMapper; import com.czxy.crm.service.LinkManService; import com.czxy.crm.vo.LinkManVo; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import tk.mybatis.mapper.entity.Example; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service @Transactional public class LinkManServiceImpl implements LinkManService { @Resource private LinkManMapper linkManMapper; @Resource private CustomerMapper customerMapper; @Override public PageInfo<LinkMan> findAll(LinkManVo linkManVo) { //1 条件查询 Example example = new Example(LinkMan.class); Example.Criteria criteria = example.createCriteria(); if(StringUtils.isNotBlank(linkManVo.getLkmName())) { criteria.andLike("lkmName", "%"+linkManVo.getLkmName()+"%"); } //2 分页查询 PageHelper.startPage(linkManVo.getPageNum() ,linkManVo.getPageSize()); //3 查询 List<LinkMan> linkManList = linkManMapper.selectByExample(example); //4 关联 linkManList.forEach(linkMan -> { Customer customer = customerMapper.selectByPrimaryKey(linkMan.getCustId()); linkMan.setCustomer(customer); }); //5 封装 return new PageInfo<>(linkManList); } }
步骤4:修改jsp,展示列表数据
步骤5:修改jsp,展示分页条
查询表单
分页条
当前第[<B>${pageInfo.pageNum}</B>]页,共[<B>${pageInfo.total}</B>]条
,每页显示
<select οnchange="change(this)"> <option value="1" ${pageInfo.pageSize == 1 ? 'selected' : ''}>1</option> <option value="2" ${pageInfo.pageSize == 2 ? 'selected' : ''}>2</option> <option value="3" ${pageInfo.pageSize == 3 ? 'selected' : ''}>3</option> <option value="5" ${pageInfo.pageSize == 5 ? 'selected' : ''}>5</option> <option value="10" ${pageInfo.pageSize == 10 ? 'selected' : ''}>10</option> </select> 条 <c:if test="${pageInfo.pageNum > 1}"> [<a href="javascript:void(0)" οnclick="page(1)">首页</a>] [<a href="javascript:void(0)" οnclick="page(${pageInfo.pageNum - 1})">上一页</a>] </c:if> <c:forEach begin="1" end="${pageInfo.pages}" var="num"> <b><a href="javascript:void(0)" οnclick="page(${num})">${num}</a></b> </c:forEach> <c:if test="${pageInfo.pageNum < pageInfo.pages}"> [<a href="javascript:void(0)" οnclick="page(${pageInfo.pageNum + 1})">下一页</a>] [<a href="javascript:void(0)" οnclick="page(${pageInfo.pages})">尾页</a>] </c:if> 到 <input type="number" style="width: 35px;" value="${customerVo.pageNum}" id="goId"/> 页 <input type="button" value="Go" οnclick="page(goId.value)"/> JS函数 <SCRIPT language=javascript> function change(obj) { // 重置,如果修改了pageSize,从1开始 pageNumId.value = 1 // 修改隐藏字段 pageSize pageSizeId.value = obj.value // 提交表单 linkmanFormId.submit() } function page(pageNum) { // 修改pageNum的值 pageNumId.value = pageNum // 提交表单 linkmanFormId.submit() } </SCRIPT>
4.3 添加联系人
4.3.1 需求
4.3.2 显示表单
步骤:
步骤1:入口
步骤2:修改LinkManController,用于显示 linkman/add.jsp 页面
查询所有客户
步骤3:编写CustomerService,查询所有客户。
步骤4:修改add.jsp,显示客户列表。
步骤1:入口
步骤2:修改LinkManController,用于显示 linkman/add.jsp 页面
查询所有客户
package com.czxy.crm.controller; import com.czxy.crm.domain.Customer; import com.czxy.crm.domain.LinkMan; import com.czxy.crm.service.CustomerService; import com.czxy.crm.service.LinkManService; import com.czxy.crm.vo.CustomerVo; import com.czxy.crm.vo.LinkManVo; import com.github.pagehelper.PageInfo; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Controller @RequestMapping("/linkman") public class LinkManController { @Resource private LinkManService linkManService; @Resource private CustomerService customerService; /** * 显示添加页面 * @param model * @return */ @RequestMapping("/addUI") public String addUI(Model model) { // 查询所有客户 List<Customer> allCustomer = customerService.selectAll(); model.addAttribute("allCustomer", allCustomer); return "linkman/add"; } }
步骤3:编写CustomerService,查询所有客户。
接口
/** * 查询所有 * @return */ List<Customer> selectAll();
实现类
@Override public List<Customer> selectAll() { return customerMapper.selectAll(); }
步骤4:修改add.jsp,显示客户列表。
<select name="custId"> <option value="">--请选择--</option> <c:forEach items="${allCustomer}" var="customer"> <option value="${customer.custId}">${customer.custName}</option> </c:forEach> </select>
4.3.3 添加
步骤:
步骤1:修改add.jsp页面,确定表单提交路径 /linkman/add.action
步骤2:修改LinkManController,添加add方法,并处理成功和失败。
步骤3:修改LinkManService,添加add方法
步骤4:修改add.jsp,显示错误信息
步骤1:修改add.jsp页面,确定表单提交路径 /linkman/add.action
步骤2:修改LinkManController,添加add方法,并处理成功和失败。
/** * 添加联系人 * @param linkMan * @param model * @return */ @RequestMapping("/add") public String add(LinkMan linkMan , Model model) { try { // 查询所有客户 boolean result = linkManService.add(linkMan); if(result) { return "redirect:/linkman/findAll.action"; } else { model.addAttribute("error", "添加联系人失败"); return "linkman/add"; } } catch (Exception e) { e.printStackTrace(); model.addAttribute("error", e.getMessage()); return "linkman/add"; } }
步骤3:修改LinkManService,添加add方法
接口
实现类
@Override public boolean add(LinkMan linkMan) { int insert = linkManMapper.insertSelective(linkMan); return insert == 1; }
步骤4:修改add.jsp,显示错误信息
4.4 修改联系人
4.4.1 需求
4.4.2 显示表单,回显数据
步骤:
步骤1:入口 /linkman/editUI.action?lkmId=1
步骤2:修改LinkManController,用于显示 linkman/edit.jsp 页面
查询所有客户
查询当前联系人
步骤3:编写LinkManService,查询联系人详情。
步骤4:修改edit.jsp,显示客户列表,回显联系人信息。
步骤1:入口 /linkman/editUI.action?lkmId=1
步骤2:修改LinkManController,用于显示 linkman/edit.jsp 页面
查询所有客户
查询当前联系人
/** * 编辑前操作 * @param lkmId * @param model * @return */ @RequestMapping("/editUI") public String editUI(Long lkmId, Model model) { // 查询所有客户 List<Customer> allCustomer = customerService.selectAll(); model.addAttribute("allCustomer", allCustomer); // 查询详情 LinkMan linkMan = linkManService.selectById(lkmId); model.addAttribute("linkMan", linkMan); return "linkman/edit"; }
步骤3:编写LinkManService,查询联系人详情。
接口
/** * 查询详情 * @param lkmId * @return */ LinkMan selectById(Long lkmId);
实现类
@Override public LinkMan selectById(Long lkmId) { return linkManMapper.selectByPrimaryKey(lkmId); }
步骤4:修改edit.jsp,显示客户列表,回显联系人信息。
4.4.3 修改
步骤:
步骤1:修改edit.jsp页面,确定表单提交路径 /linkman/edit.action
步骤2:修改LinkManController,添加edit方法,并处理成功和失败。
步骤3:修改LinkManService,添加edit方法
步骤4:修改edit.jsp,显示错误信息
步骤1:修改edit.jsp页面,确定表单提交路径 /linkman/edit.action
步骤2:修改LinkManController,添加edit方法,并处理成功和失败。
/** * 修改联系人 * @param linkMan * @param model * @return */ @RequestMapping("/edit") public String edit(LinkMan linkMan , Model model) { try { // 查询所有客户 boolean result = linkManService.update(linkMan); if(result) { return "redirect:/linkman/findAll.action"; } else { model.addAttribute("error", "修改联系人失败"); return "linkman/edit"; } } catch (Exception e) { e.printStackTrace(); model.addAttribute("error", e.getMessage()); return "linkman/edit"; } }
步骤3:修改LinkManService,添加edit方法
接口
实现类
@Override public boolean update(LinkMan linkMan) { int update = linkManMapper.updateByPrimaryKeySelective(linkMan); return update == 1; }
步骤4:修改edit.jsp,显示错误信息
4.5 删除联系人
步骤:
步骤1:入口 linkman/delete.action?lkmId=1
步骤2:修改LinkManController,添加delete方法,删除成功重定向到列表页。
步骤3:修改LinkManService,添加delete方法
步骤1:入口 linkman/delete.action?lkmId=1
<a href="${pageContext.request.contextPath }/linkman/delete.action?lkmId=${linkman.lkmId}" οnclick="return confirm('您确定要删除【${linkman.lkmName}】吗?')">删除</a>
步骤2:修改LinkManController,添加delete方法,删除成功重定向到列表页。
/** * 通过id删除联系人 * @param lkmId * @return */ @RequestMapping("/delete") public String delete(Long lkmId) { // 删除 linkManService.deleteById(lkmId); // 重定向列表页 return "redirect:/linkman/findAll.action"; }
步骤3:修改LinkManService,添加delete方法
接口
/** * 删除 * @param lkmId */ void deleteById(Long lkmId);
实现类
@Override public void deleteById(Long lkmId) { linkManMapper.deleteByPrimaryKey(lkmId); }
4.6 完善:删除客户
4.6.1 问题:客户和联系人主外键约束
当联系人使用了客户后,此时如果删除客户,默认出现:
4.6.2 解决方案1:自动删除联系人
需求:删除客户前,先删除联系人
步骤:
步骤1:修改 LinkManMapper ,添加 deleteAllByCustId方法
步骤2:修改 CustomerServiceImpl,修改 deleteById 方法
步骤1:修改 LinkManMapper ,添加 deleteAllByCustId方法
package com.czxy.crm.mapper; import com.czxy.crm.domain.LinkMan; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Param; import tk.mybatis.mapper.common.Mapper; /** * @author 桐叔 * @email liangtong@itcast.cn */ public interface LinkManMapper extends Mapper<LinkMan> { /** * 删除指定客户的联系人 * @param custId */ @Delete("DELETE FROM cst_linkman WHERE lkm_cust_id = #{custId}") void deleteAllByCustId(@Param("custId") Long custId); }
步骤2:修改 CustomerServiceImpl,修改 deleteById 方法
@Override public void deleteById(Long custId) { // 依次删除联系人 linkManMapper.deleteAllByCustId(custId); // 删除客户 customerMapper.deleteByPrimaryKey(custId); }
4.6.3 作业:完善删除提示
在删除客户时,完成如下2个需求:
需求1:如果客户==没有==关联的联系人,删除时提示“您确定要删除【xxx】吗?”
需求2:如果客户==有==关联的联系人,删除时提示“【xxx】客户关联3个联系人,您确定一并删除吗?”