CRM客户关系管理系统开发第十七讲——实现客户拜访记录管理模块中分页查询客户拜访记录列表的功能
在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類,在該類中使用注解完成屬性注入。
然后,創建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客户关系管理系统开发第十七讲——实现客户拜访记录管理模块中分页查询客户拜访记录列表的功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spss24 中文版 2.数据清洗与处理
- 下一篇: 【idea2018调节字体大小】