在CRM客户关系管理系统中,客户的拜访是很重要的一个环节,由业务员面见客户并介绍公司的相关的业务,在业务员回到公司以后,需要对此次的拜访的整个过程记录下来,记录中需要包含拜访的客户的姓名,拜访的时间以及拜访的地点等信息。

准备工作

在正式编写代码实现客户拜访记录管理模块中分页查询客户拜访记录列表的功能之前,我们得做一些准备工作,因为这个功能实现起来还是比较难的,不能一蹴而就。

分析客户表和用户表它俩之间的关系

一个使用系统的用户其实就是一个公司的业务员,公司业务员需要对客户进行拜访,并对拜访的过程进行记录。现在出现了一个问题,那就是客户表和用户表它俩之间到底是啥子关系呢?正常情况下,需要根据具体业务具体分析,但一般都逃不过如下两种关系:

  • 一对多的关系:可能公司比较小,产品比较单一,只允许一个业务员对应多个客户,这就是一对多的关系;
  • 多对多的关系:一些大公司有不同的产品,不同产品下有不同业务员都可以接触到同一个客户,即一个客户对应了多个业务员,不仅如此,一个业务员也可以拜访多个客户,即一个业务员对应了多个客户,这就是多对多的关系。

大部分情况下,客户表和用户表它俩之间是多对多的关系,这里,我们也采用这种关系。既然是多对多的关系,那就需要创建中间表了,正常的中间表是只需要有两个字段的,而且这两个字段分别作为外键指向多对多双方各自的主键。但是我们现在的要求是需要记录拜访的时间,拜访地点等信息的,所以这些信息也需要存在于中间表中。

创建拜访记录表

在crm数据库下新建一张拜访记录表,也即中间表,其建表的sql语句如下:

CREATE TABLE `sale_visit` (`visit_id` varchar(32) NOT NULL,`visit_cust_id` bigint(32) DEFAULT NULL COMMENT '客户id',`visit_user_id` bigint(32) DEFAULT NULL COMMENT '负责人id',`visit_time` date DEFAULT NULL COMMENT '拜访时间',`visit_addr` varchar(128) DEFAULT NULL COMMENT '拜访地点',`visit_detail` varchar(256) DEFAULT NULL COMMENT '拜访详情',`visit_nexttime` date DEFAULT NULL COMMENT '下次拜访时间',PRIMARY KEY (`visit_id`),KEY `FK_sale_visit_cust_id` (`visit_cust_id`),KEY `FK_sale_visit_user_id` (`visit_user_id`),CONSTRAINT `FK_sale_visit_cust_id` FOREIGN KEY (`visit_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,CONSTRAINT `FK_sale_visit_user_id` FOREIGN KEY (`visit_user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建SaleVisit实体类及其对应的映射配置文件

首先,在com.meimeixia.crm.domain包下创建一个SaleVisit实体类及其相对应的映射配置文件。

  • SaleVisit实体类:

    package com.meimeixia.crm.domain;import java.util.Date;/*** 客户拜访记录管理的实体* @author liayun**/
    public class SaleVisit {private String visit_id;private Date visit_time;private String visit_addr;private String visit_detail;private Date visit_nexttime;//拜访记录所关联的客户对象private Customer customer;//拜访记录所关联的用户对象private User user;public String getVisit_id() {return visit_id;}public void setVisit_id(String visit_id) {this.visit_id = visit_id;}public Date getVisit_time() {return visit_time;}public void setVisit_time(Date visit_time) {this.visit_time = visit_time;}public String getVisit_addr() {return visit_addr;}public void setVisit_addr(String visit_addr) {this.visit_addr = visit_addr;}public String getVisit_detail() {return visit_detail;}public void setVisit_detail(String visit_detail) {this.visit_detail = visit_detail;}public Date getVisit_nexttime() {return visit_nexttime;}public void setVisit_nexttime(Date visit_nexttime) {this.visit_nexttime = visit_nexttime;}public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}
    

    上面我讲过,如果中间表中有其他的字段参与到业务逻辑运算当中,那么就不能创建普通的多对多的映射关系了,需要创建两个一对多来实现多对多的关系。所以,肯定是要在创建SaleVisit实体类时,在这一端写上一的一方的对象的,需不需要在另外的一端放置多的一方的集合呢?这个得根据具体情况具体分析,就是说你自己要判断好在查询客户的时候,需不需要去关联查询客户所对应的拜访记录,如果不需要,那么配置单向的关联关系就行了。例如,在以上的SaleVisit实体类中,客户和拜访记录就是单向的关联关系(在客户实体类这边并没有放置拜访记录的集合),这意味着在查询拜访记录的时候,可以查看到所关联的客户信息(这个人拜访了哪个客户),在查询客户的时候,不会查看到他具体被哪个用户所拜访了。

  • SaleVisit.hbm.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 建立类与表的映射 --><class name="com.meimeixia.crm.domain.SaleVisit" table="sale_visit"><!-- 建立类中的属性与表中的主键相对应 --><id name="visit_id" column="visit_id"><!-- 主键的生成策略 --><generator class="uuid" /></id><!-- 建立类中的普通属性和表中的字段相对应 --><property name="visit_time" column="visit_time" /><property name="visit_addr" column="visit_addr" /><property name="visit_detail" column="visit_detail" /><property name="visit_nexttime" column="visit_nexttime" /><!-- 配置与客户的关联关系 --><many-to-one name="customer" class="com.meimeixia.crm.domain.Customer" column="visit_cust_id"></many-to-one><!-- 配置与用户的关联关系 --><many-to-one name="user" class="com.meimeixia.crm.domain.User" column="visit_user_id"></many-to-one></class>
    </hibernate-mapping>
    

然后,千万记得要把SaleVisit实体类相对应的映射配置文件交给Spring来管理!

创建相关的类(接口)

之前,我们一直是在使用Spring中IoC的XML开发方式进行开发,这儿,我会换一种开发方式,即使用XML文件和注解的整合开发,在这种整合开发中,我们会使用XML文件来管理Bean,使用注解完成属性注入。接下来,我便会创建客户拜访记录管理模块中相关的类和接口。
首先,创建web层相关的类,即在com.meimeixia.crm.web.action包下创建一个SaleVisitAction类,在该类中使用注解完成属性注入。

package com.meimeixia.crm.web.action;import javax.annotation.Resource;import com.meimeixia.crm.domain.SaleVisit;
import com.meimeixia.crm.service.SaleVisitService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;/*** 客户拜访记录的Action类* @author liayun**/
public class SaleVisitAction extends ActionSupport implements ModelDriven<SaleVisit> {//模型驱动使用的对象private SaleVisit saleVisit = new SaleVisit();@Overridepublic SaleVisit getModel() {return saleVisit;}//在Action中注入service@Resource(name="saleVisitService")private SaleVisitService saleVisitService;}

然后,创建service层相关的类。

  • 先在com.meimeixia.crm.service包下创建一个SaleVisitService接口,一开始该接口中并没有声明任何方法,如下:

    package com.meimeixia.crm.service;/*** 客户拜访记录的业务层的接口* @author liayun**/
    public interface SaleVisitService {}
    
  • 再在com.meimeixia.crm.service.impl包下编写以上接口的一个实现类——SaleVisitServiceImpl.java,在该类中同样使用注解完成属性注入。

    package com.meimeixia.crm.service.impl;import javax.annotation.Resource;import com.meimeixia.crm.dao.SaleVisitDao;
    import com.meimeixia.crm.service.SaleVisitService;/*** 客户拜访记录的业务层的实现类* @author liayun**/
    public class SaleVisitServiceImpl implements SaleVisitService {//注入客户拜访记录的dao@Resource(name="saleVisitDao")private SaleVisitDao saleVisitDao;}
    

接着,创建dao层相关的类。

  • 先在com.meimeixia.crm.dao包下创建一个SaleVisitDao接口,并让其继承通用的BaseDao<T>接口,因为父接口中已经定义了基本的CRUD的操作的相关方法,所以子接口中可以直接从父接口中继承过来,而不再需要自己编写了。

    package com.meimeixia.crm.dao;import com.meimeixia.crm.domain.SaleVisit;/*** 客户拜访记录的dao的接口* @author liayun**/
    public interface SaleVisitDao extends BaseDao<SaleVisit> {}
    
  • 再在com.meimeixia.crm.dao.impl包下编写以上接口的一个实现类——SaleVisitDaoImpl.java。在该实现类中,也不再需要那些任何有关CRUD的代码了,因为在通用的BaseDaoImpl<T>实现类中已经对这些方法实现过了,我们自己编写的SaleVisitDaoImpl实现类只需要继承该通用实现类就可以了。

    package com.meimeixia.crm.dao.impl;import com.meimeixia.crm.dao.SaleVisitDao;
    import com.meimeixia.crm.domain.SaleVisit;/*** 客户拜访记录的dao的实现类* @author liayun**/
    public class SaleVisitDaoImpl extends BaseDaoImpl<SaleVisit> implements SaleVisitDao {}
    

最后,我们还要在Spring配置文件里面开启属性注入的注解,一旦开启了这么一个玩意,那么就可以在没有组件扫描的情况下,来使用那些属性注入的注解了,也就是说可以直接使用@Resource、@Value、@Autowired、@Qualifier这些注解了。

还有不要忘了在Spring配置文件中对以上类进行配置,即将这些相关的类交给Spring来管理。

编写代码实现分页查询客户拜访记录列表的功能

在左侧的菜单页面(menu.jsp)中修改提交路径

编写web层

首先,我们要在SaleVisitAction类中编写一个分页查询客户拜访记录列表的方法。在该方法中,需要接收分页查询的参数,这里最好使用离线条件查询对象(即DetachedCriteria对象),因为用了它之后,在我们底层Hibernate模板调用的时候,直接就可以进行分页查询了,而且后期咱们进行条件查询(条件查询还能带分页),使用DetachedCriteria这个对象就会变得非常方便。

package com.meimeixia.crm.web.action;import javax.annotation.Resource;import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;import com.meimeixia.crm.domain.PageBean;
import com.meimeixia.crm.domain.SaleVisit;
import com.meimeixia.crm.service.SaleVisitService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;/*** 客户拜访记录的Action类* @author liayun**/
public class SaleVisitAction extends ActionSupport implements ModelDriven<SaleVisit> {//模型驱动使用的对象private SaleVisit saleVisit = new SaleVisit();@Overridepublic SaleVisit getModel() {return saleVisit;}//在Action中注入service@Resource(name="saleVisitService")private SaleVisitService saleVisitService;//接收分页查询的参数private Integer currentPage = 1;private Integer pageSize = 3;public void setCurrentPage(Integer currentPage) {if (currentPage == null) {currentPage = 1;}this.currentPage = currentPage;}public void setPageSize(Integer pageSize) {if (pageSize == null) {pageSize = 3;}this.pageSize = pageSize;}/** 查询拜访记录列表的方法*/public String findAll() {//创建离线条件查询对象DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SaleVisit.class);//如果有条件,那么就设置条件//...//调用业务层PageBean<SaleVisit> pageBean = saleVisitService.findByPage(detachedCriteria, currentPage, pageSize);//把pageBean存入值栈ActionContext.getContext().getValueStack().push(pageBean);return "findAll";}}

然后,我们还得在Struts2配置文件中(即struts.xml)对SaleVisitAction进行如下的配置,即配置页面的跳转。

编写service层

首先,在SaleVisitService接口中添加一个分页查询客户拜访记录列表的方法声明,如下:

package com.meimeixia.crm.service;import org.hibernate.criterion.DetachedCriteria;import com.meimeixia.crm.domain.PageBean;
import com.meimeixia.crm.domain.SaleVisit;/*** 客户拜访记录的业务层的接口* @author liayun**/
public interface SaleVisitService {PageBean<SaleVisit> findByPage(DetachedCriteria detachedCriteria, Integer currentPage, Integer pageSize);}

然后,在以上接口的一个实现类(SaleVisitServiceImpl.java)中去实现分页查询客户拜访记录列表的方法。

package com.meimeixia.crm.service.impl;import java.util.List;import javax.annotation.Resource;import org.hibernate.criterion.DetachedCriteria;import com.meimeixia.crm.dao.SaleVisitDao;
import com.meimeixia.crm.domain.PageBean;
import com.meimeixia.crm.domain.SaleVisit;
import com.meimeixia.crm.service.SaleVisitService;/*** 客户拜访记录的业务层的实现类* @author liayun**/
//@Transactional
public class SaleVisitServiceImpl implements SaleVisitService {//注入客户拜访记录的dao@Resource(name="saleVisitDao")private SaleVisitDao saleVisitDao;//业务层分页显示拜访记录的方法@Overridepublic PageBean<SaleVisit> findByPage(DetachedCriteria detachedCriteria, Integer currentPage, Integer pageSize) {PageBean<SaleVisit> pageBean = new PageBean<SaleVisit>();//设置当前页数pageBean.setCurrentPage(currentPage);//设置每页显示的记录数pageBean.setPageSize(pageSize);//设置总记录数Integer totalCount = saleVisitDao.findCount(detachedCriteria);pageBean.setTotalCount(totalCount);//设置总页数double tc = totalCount;Double num = Math.ceil(tc / pageSize);pageBean.setTotalPage(num.intValue());//设置每页显示的数据的集合Integer begin = (currentPage - 1) * pageSize;List<SaleVisit> list = saleVisitDao.findByPage(detachedCriteria, begin, pageSize);pageBean.setList(list);return pageBean;}}

在客户拜访记录列表页面中显示数据

猛然发现没有这个客户拜访记录列表页面啊!那咋办?很简单,复制一份联系人列表页面(list.jsp),将其存放到WebContent/jsp/salevisit目录下,以此作为客户拜访记录列表页面,在该页面中,我们只需要做一点点修改,即将查询出来的客户拜访记录列表数据在页面中显示出来。

该页面底部的分页工具条的实现代码,我们就可以不用写了,复用之前的代码片段就行!此时,发布我们的项目到Tomcat服务器并启动,然后访问该项目的首页,点击客户拜访列表超链接之后,你就能看到客户拜访记录列表了。

CRM客户关系管理系统开发第十七讲——实现客户拜访记录管理模块中分页查询客户拜访记录列表的功能相关推荐

  1. CRM客户关系管理系统开发第十九讲——实现客户拜访记录管理模块中条件查询客户拜访记录列表的功能

    在客户拜访记录列表页面上准备一些筛选条件 首先,咱得在客户拜访记录列表页面上准备一些筛选条件,不妨我们按照拜访时间来进行筛选.之前咱在实现联系人管理模块中条件查询联系人列表的功能时,文本输入框使用的是 ...

  2. CRM客户关系管理系统开发第十八讲——实现客户拜访记录管理模块中保存客户拜访记录的功能

    跳转到客户拜访记录添加页面 要想实现客户拜访记录管理模块中的保存客户拜访记录的功能,首要前提就是点击新增客户拜访超链接之后要能跳转到客户拜访记录添加页面.前面我们都做完两个模块了,做到这一点还不是依葫 ...

  3. CRM客户关系管理系统开发第一讲——搭建开发环境

    这个小项目是我们学习完Spring,Hibernate,Struts2这三个框架后,为了加深对它们的理解所做的SSH项目,为CRM客户关系管理系统. CRM客户关系管理系统的概述 什么是CRM客户关系 ...

  4. java计算机毕业设计-移动公司crm客户关系管理系统开发与实现-源程序+mysql+系统+lw文档+远程调试

    java计算机毕业设计-移动公司crm客户关系管理系统开发与实现-源程序+mysql+系统+lw文档+远程调试 java计算机毕业设计-移动公司crm客户关系管理系统开发与实现-源程序+mysql+系 ...

  5. CRM客户关系管理系统开发第十三讲——实现联系人管理模块中修改联系人的功能

    修改联系人列表页面上的链接地址 编写LinkManAction的edit方法 首先,我们要在LinkManAction类中编写一个跳转到联系人编辑页面的方法.在该方法中,我们不仅要查询出某个联系人,而 ...

  6. CRM客户关系管理系统开发第二讲——实现用户的注册和登录功能

    实现用户注册功能 创建用户表 首先创建一个数据库(例如crm),并在该数据库下新建一张用户表,笔者这里使用的数据库是MySQL. create database crm; use crm;CREATE ...

  7. 电销CRM客户关系管理系统开发12大核心功能

    电销CRM管理系统软件是一款专门针对电销行业开发的客户关系管理软件,它能够帮助企业实现对顾客信息的可视化,智能化,自动化管理,提高电销效率和客户满意度.电销行业在传统互联网营销,新媒体营销,短视频营销 ...

  8. 什么是客户关系管理系统?有哪些分类?

    客户关系管理系统(CRM)是以实现企业以客户为中心的理念为目的,运用先进的管理思想和各种技术对客户数据信息进行管理的一种信息系统.客户关系管理系统对企业营销时与客户发生的交互行为中所产生的信息进行记录 ...

  9. 开发CRM客户关系管理系统需要多少钱

    现阶段各个领域都少不了和客户相处,所以也必须对住户关联进行监管,跟踪业务流程进度情况,促使协作.伴随着现代科技的高速发展,及其管理模式的兴起,CRM客户关系管理系统开发逐步完善,而且在销售工作普及化. ...

最新文章

  1. BZOJ3572: [Hnoi2014]世界树
  2. 批量设置word文档的页面格式 word vba代码注释
  3. 网易云信三周年:我们只做第一
  4. 【机器视觉】 dev_set_preferences算子
  5. 类的加载过程一:Loading
  6. 动态路由协议_动态路由协议的类别
  7. ASP.NET字符显示不正确的解决方法
  8. DNS和DHCP之间有哪些区别
  9. Zxw图纸,鑫制造图纸,蓝瑞图纸,猎人图纸,维修宝典,刚开通 的带维修案例平台
  10. nodejs 查看下载文件路径_Python + selenium + Chrome 模拟登陆QQ邮箱,批量下载附件,本地重命名
  11. DBSCAN 对点云障碍物聚类
  12. 云备份-保障你的数据安全
  13. ANSYS APDL中的ASEL面选择命令
  14. python中str,int,list,list(str),list(int)的相互转换
  15. 第一章-走近群智感知,辨识庐山真面目
  16. sql盲注 各种方法拿到 管理员账户和密码
  17. Android系统小知识
  18. KDE桌面|添加自定义快捷键
  19. 摆线方程推导(向量法)
  20. 通过mac地址查询ip

热门文章

  1. 2-3岁幼儿的教养-叛逆从现在开始
  2. 【推荐系统】召回离线评估指标Hit Ratio
  3. c#窗体调查问卷_如何在Microsoft窗体中创建问卷
  4. 研发需求的验收标准应该怎么写?
  5. 软件测试爬虫,【松勤软件自动化测试】Python3-爬虫~selenium\phantomjs\ActionChains百度例子...
  6. 有趣的HTML实例(一) 倒计时
  7. cocos2dx3.16+lua 音乐音效
  8. 如何从win10中获取3D模型(GLB格式)
  9. 重新认识java(零) --- 不积跬步无以至千里
  10. 推荐最新网赚付费项目,让你实现半年赚20万!