基于JAVA技术的客户关系管理系统
Posted dejyyhg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于JAVA技术的客户关系管理系统相关的知识,希望对你有一定的参考价值。
获取项目源文件,技术交流与指导联系Q:1225467431
摘要:该客户关系管理系统是基于J2EE技术进行开发,主要采用JAVA语言作为开发语言,基于MVC的设计思想,利用J2EE网页制作技术完成前台静态页面和动态页面的设计,同时利用JDBC技术完成前台页面和后台mysql数据库的连接操作,最终完成一个客户关系管理系统。该系统共分为营销管理、客户管理、服务管理和统计报表四个功能模块,系统可以帮助企业发掘并创建客户信息记录,对所有的客户进行有效的管理;按照客户的一些基本信息和业务信息进行分类,掌握老客户的基本动态和对公司的贡献等级,不断的发掘新的客户,同时对客户流失的原因进行了解,不断改进,帮助提高企业的经济效益。
关键词:客户关系管理;J2EE;数据库;JAVA
1 引言
随着经济的不断发展和企业的不断发展壮大,如何获取更大的消费市场、降低自己的生产成本以及获取更大的销售利润成为企业生存所面临的首要问题,客户在企业的发展中扮演了一个极其重要的角色,客户资源就是企业的宝贵财富,同时企业对于客户的依赖已经提高到了关乎企业生存的高度,而这些客户有分不同的客户群体,例如有小客户、大客户,而客户的等级对于企业发展的重要性也是不一样的,而且这些客户有可能来自不同的行业,不同的区域,必须对这些客户进行有效的管理;而且每个客户对企业的需求和要求也是不同的,只有尽可能的满足不同客户的不同需求,才能提高企业的核心竞争力,获取和创造利益的最大化。在过去的10年当中,有许多原因导致客户关系的管理变得非常重要。国际市场竞争已成为极具竞争力,如果他们不喜欢他们所得到的服务,客户就可以变更企业。
客户关系管理一个主要的目标就是维护客户。当它被使用有效完全的时候,公司将能够与客户建立一个长久的关系。客户关系管理工具通常会以现实的软件方式实现。每一个软件程序可能不同的方式方法实现客户关系管理。但是那是很重要的客户关系管理不仅仅是一个技术,客户关系管理可以更好地界定为一种方法,一个公司将实现自己的目标的方法,它应该是直接和公司的理念相关联,有许多原因企业应该拥有客户关系管理系统。客户关系管理系统能够帮助公司找到最适合客户的因素。一个公司必须认识到,如果他们不满足欲望和需求的客户,他们也不可能获得成功,而客户关系管理是一个功能强大的系统将允许他们这样做,实现企业的目标。
本系统的设计理念就是帮助企业对客户进行有效的管理,可以用来研究用户、管理用户、开发用户。代替了之前的手工记录和传统记忆方式,避免了客户数据的遗漏和丢失,同时可以对客户进行一系列的需求和分类操作,添加新客户,对新客户进行操作,对即将流失的客户进行了解和分析,不断完善流失客户的需求,同时对客户提出的问题加以改进;通过计算机进行登录和管理,操作简单易懂,更符合公司的发展需要。
2 系统方案论证
2.1 系统可行性研究分析
在进行系统开发之前,需要确定系统开发方案,可行性分析的目的是在系统开发之前,经过详细的阅读需求文档以及各个功能模块的设计要求以及实现要求,明确系统开发的可行性,而可行性则取决于现实应用系统的资源和条件,对系统开发条件不成熟的地方加以讨论。通过对系统实现目标以及对四个功能模块的初步了解和分析,提出可行性的方案并进行论证,本文在这里主要从技术可行性、经济可行性和操作可行性三方面进行分析和对比论证,寻找出在各个方面都适合系统开发的条件。
2.1.1 技术可行性论证
就技术而言,技术可行性分析是根据讨论和研究的客户关系管理系统需求分析所得到的对系统开发所需要的软件和技术支持。通过讨论和论证,本系统主要采用MVC设计模式,选用Windows XP作为服务器端的操作系统,主要采用面向对象的设计方法进行系统设计,在软件开发中选择MyEclipse9.0软件为开发工具;前台系统操作界面采用J2EE网页制作静态页面技术和JSP实现动态网页技术开发的;后台数据库采用MySQL设计完成,安装简单,实用,并采用JDBC、Servlet、Hibernate等技术实现数据库的连接;同时采用Tomcat 7.0应用服务器,安装以后可以直接运行,采用火狐浏览器作为主浏览窗口;同时也采用CSS、javascript脚本语言实现网页不布局和表单提交的验证功能,系统具有界面美观、操作方便、可扩充性强等特点,给用户带来不一样的体验。
2.1.2 经济可行性论证
软件的经济可行性论证是指进行客户关系管理系统开发所投入的人力与资金的论证,以及将来是否能达到所需要的效益,主要是指对客户关系管理系统开发的成本进行估算,而本系统的应用开发软件、硬件系统也易于获得。所需要的软件开发工具均可以从互联网和导师处获取,开发成本相对较低。而在一些小型企业引进使用本系统后,与传统的手工记录方式和操作相比,具有高效率、低成本的特点,可以节省人力和物力。所以从经济可行性的角度来看,该客户关系管理系统可以进行开发。
2.1.3 操作可行性论证
操作可行性论证主要是在客户关系管理系统开发过程中对四个功能模块的实现是否存在可行性,以及对系统完成后的操作是否被企业用户容易接受等方面进行论证。首先,通过详细的阅读了系统的需求规格说明书,明确了该系统的功能需要,确定可行。同时该客户管理系统对操作人员专业要求比较低,具有一定的计算机知识便可以对系统进行操作。
3 系统开发技术及思想介绍
3.1 J2EE网页制作技术
首先,网页制作技术分为静态网页部分和动态网页部分二部分,静态页面部分主要包括html,CSS,JAVASCRIPT三部分;其中HTML字面上翻译就是超文本标示语言,通过其基本元素的操作可是实现网页界面的完整性;通过定义CSS样式表,能让网页具有美观一致的画面,一个样式文件可以作用于多个界面,其中<STYLE>和</STYLE>标签之间的所有内容都是样式规则;JAVASCRIPT即是一种描述语言,也是一种基于对象和事件驱动,通常JAVASCRIPT代码使用<SCRIPT>和</SCRIPT>标记嵌入HTML文档中,通过使用JAVASCRIPT可以实现基本的表单提交验证功能。动态页面部分主要包括Servlet和JSP二部分,其中Servlet允许用户在服务器上运行JAVA代码和生成动态内容。
在本系统中,通过详细的阅读系统需求文档,在系统的设计过程中也运用了以上的知识,首先利用HTML和CSS样式表基本知识进行开发,实现了基本的系统操作界面的静态网页;为了方便统一开发,利用页面框架技术将网页设计开发部分分为三个部分来实现,利用HTML实现基本网页内容,利用JAVASCRIPT技术实现表单的验证,利用CSS布局实现界面的美观修饰,给用户呈现出一个美观易懂的画面。
3.2 数据库技术
数据库是存储在一起的相关数据的集合,这些数据是结构化的,并为多种运用服务,数据的存储独立于使用它的程序。而在数据库中,SQL语句是一种通用的数据库查询语言,SQL一般有数据定义语言、数据操纵语言和数据控制语言组成,数据定义功能包括对基本表、视图、索引的创建、删除和修改操作。而在系统中,数据查询是数据库的核心操作,SQL语言的数据查询只有一条SELECT语句,查询有单表查询、多表连接查询、嵌套查询和集合查询几个部分组成。SQL的数据更新包括数据的插入、修改和删除等三种情况。
在本系统中,运用了MySQL数据库管理系统,对系统的数据库进行设计,对于不同模块的不同需求,通过设计在数据库中创建了多张相对应的表,对于用户表和职位表是在系统运行之前就插入,其余各个表数据的存储和操作是等系统完成之后运行用户自己插入存储。
3.3 J2SE技术介绍
在J2SE技术当中,JSP是一种JAVA服务器端技术,它主要用来产生动态网页内容,JSP页面使用HTML表示网页上的静态内容,而在其中添加JAVA代码表示动态内容 JSP是一种实现普通静态HTML和动态HTML混合编码的技术。JDBC(JAVA数据库连接)是一种用于执行SQL语句的JAVA API,可以为多种关系数据库提供统一访问,它有一组用JAVA语言编写的类和接口组成。而JDBC当中定义像DriverManager等一系列的类和接口,利用以上类和接口,程序员很容易实现与数据库的连接,传递SQL语句和处理检索结果。
在系本统中,运用了该技术实现了前台静态网页和后台数据库的连接功能,实现了数据的交换、插入、修改和存储,是客户关系管理系统中关键的技术。
3.4 MVC设计思想
MVC 设计思想是将程序分成相对独立,而又能协同工作的三个部分。MVC 是Model 、View 、Controller 三个词的缩写,三个词分别代表应用的三个组成部分:模型、视图与控制器。Model有JavaBean来控制;View就是视图,由JSP等等构成,用途包括数据的呈现和收集用户的数据,Controller是控制器,由Servlet来控制完成,作用包括接受客户端的请求,调用模型完成业务逻辑和将下一个页面呈现给用户。设计思想如图4.4 MVC模式图例所示。
图4.1 MVC模式图例
MVC模型工作流程是由客户端发出一个请求,首先给控制器Controll,之后控制器调用模型层Model,就是访问Pojo和Dao,Pojo的作用是传递参数,Dao是用来连接和访问数据库的,当有数据进行返回交换时,先返回给Dao,再返回给控制器,控制器在完成业务逻辑之后,通过视图将界面呈现给用户。
4 系统开发软件介绍
4.1 DreamWeaver 软件概述
DreamWeaver是一款网页开发工具,是可视化的网页编辑软件,它能快速地创建网页,还提供了强大的网站管理和维护功能。Dreamweaver还提供了开放的编辑环境,它可以协同相关软件和编程语言共同工作。而且可以有多种视窗模式,提供了代码视图、设计视图、代码与设计视图3种视窗模式,运用所学习的静态网页的基本知识,可以完成基本网页的编写。实现系统操作的界面要求。软件使用如下图4.1所示:
图4.1 DreamWeaver软件运行图
4.2 MySQL 数据库软件概述
MySQL是一个数据库管理系统,与其他数据库像DB2、Oracle、SQL Server等相比,规模小而且功能有限,但是对于客户关系管理系统来说,简单且易于安装和操作,MySQL数据库能够很好的完成开发任务,实现系统功能需求。MySQL数据库运行截图如图4.2所示:
图4.2 MySQL数据库运行图
4.3 MyEclipse 软件概述
MyEclipse 是一种集成开发环境,利用它我们可以在数据库和网页上的开发、发布以及应用程序服务器的整合方面极大的提高工作效率。MyEclipse也是一种基于JAVA的可扩展的开源的开发平台。就其本身而言,它仅仅只是一个框架和一组服务,主要用于通过插件组件构建开发环境。尽管MyEclipse是使用JAVA语言开发的,但它的用途并不限于JAVA语言;例如,支持诸如C/C++等编程语言的插件已经可用。MyEclipse框架还可用来作为与软件开发无关的其他应用程序类型的基础。同时我们可以用MyEclipse来开发JAVA应用程序,在本系统中就是运用该技术实现系统的功能。MyEclipse软件运行图如图4.3所示:
图4.3 MyEclipse软件运行图
5 系统总体开发
5.1 系统概述
该客户关系管理系统共分为营销管理模块、客户管理模块、服务管理模块和统计报表四个功能模块。为了更好的发掘老客户的价值和作用,并开发更多的新客户,通过这个系统完成对客户基本信息、联系人信息、交往信息、客户服务信息的数字化记录,进行充分共享和对企业进行规范化的管理提供帮助;通过对销售机会的创建、客户开发过程的追踪和记录,提高新客户的开发能力;在客户将要流失时系统及时预警,以便公司企业人员及时采取相关措施,降低公司损失;同时系统能够提供相关有关客户的报表,以便公司高层随时了解公司客户情况,帮助制定公司下一阶段的发展方向。
5.2 系统需求分析
整个客户关系管理系统都需要以客户为中心,从而简化各类与客户相关操作的信息,如销售、服务和查询等等,在构建系统的时候,应当考虑与公司其他系统之间的协调,但是本系统仅仅局限于进行对企业客户的一些基本管理,假设现在系统的使用者是某小型企业,那么,企业对该系统提出了如下需求:首先系统需要包括营销管理模块、客户管理模块、服务管理模块和统计报表模块。系统需要提供权限管理,以便于更好的管理,对于不同的角色能够赋予不同的权限,但是由于为了更好的有利于公司企业的发展,均设置为最高权限,即客户经理权限;同时为了更好的和企业客户交流,系统还需要提供一个客户联系人功能,用来管理和编辑存储客户的联系人信息;为了更好的统计企业目前的销售情况,系统还需要提供一个销售管理的功能,为公司下一步制定销售计划提供帮助;还需要提供一个服务反馈管理功能,能够及时的记录和操作顾客反馈的信息,对信息进行研究与分析,对公司发展所出现的问题进行分析和改正,最大限度的维护与老客户之间的关系,实现企业发展目标。功能需求如图2.1 客户关系管理系统功能图所示。
图2.1 客户关系管理系统功能图
客户关系管理系统要求实现营销管理模块中的销售机会管理和客户开发计划功能; 实现客户管理模块中的客户信息管理功能;实现服务管理模块中的服务创建、服务分配、服务处理、服务反馈和服务归档功能;实现统计报表模块中的客户构成分析和客户服务分析功能。
5.3 系统功能分析
5.3.1 系统营销管理模块
在系统的营销管理模块中,该模块用来处理公司企业的营销信息,包括销售机会管理和客户开发计划二个子模块功能。客户经理在企业的发展过程当中扮演了一个重要的角色,客户经理有开发新客户的任务,在客户经理发现对于公司有利的销售机会时,应在该系统中录入该销售机会的信息,以便对该销售机会进行更好的开发。同时销售主管也可以在客户管理管理系统中创建销售机会。创建的销售机会由销售主管进行分配,以便更好的开发,每个销售机会分配给一个客户经理。客户经理对分配给自己的销售机会制定相应客户开发计划,在制定完客户开发计划后,客户经理按实际实际当中的开发效果填写计划中每个步骤的执行效果进行比较和确认,同时在开发计划结束的时候,根据开发的结果不同,设置该销售机会为“开发失败”或“开发成功”,如果开发客户成功,系统自动创建新的客户记录。功能需求如图3.1 营销管理模块功能图所示。
图3.1 营销管理模块功能
5.3.2 系统客户管理模块
系统中的客户管理模块用来管理客户的信息,包括客户基本信息、联系人信息、客户交往记录信息、历史订单信息等功能。客户是公司发展的构成部分之一,而客户的信息是企业发展的重要因素,应对企业所有的客户信息进行妥善保管、充分分析和利用,在客户的开发过程当中,每个客户经理有责任维护和保护自己负责的客户信息,随时更新。在本系统中,客户信息将得到充分的共享,从而发挥最大的价值。功能需求如图3.2 客户管理模块功能图所示。
图3.2 客户管理模块功能
5.3.3 系统服务管理模块
服务管理模块用来处理客户服务信息,包括服务创建、服务分配、服务处理、服务反馈和服务归档等功能模块。在服务创建模块中,客户服务是客户管理的重要工作,通过客户服务所获取的信息企业可以帮助客户更好的解决问题,进而提高客户满意度,更好的利于公司的发展。同时还可以随时了解客户最新的动态,对于公司提供服务的要求,以便采取应对措施。在服务分配模块中,销售主管对状态为“新创建”的服务进行分配,收到处理请求的客户经理对服务进行处理。在服务处理模块中,被分配处理服务的客户经理负责对服务请求做出相应的处理,需要在客户管理管理系统中录入处理的结果。在服务反馈模块中,对状态为“已处理”的服务主动联系客户进行反馈,填写处理结果,尽可能的挽留客户,提高客户对公司的满意度,系统可以对已归档的服务进行查询、查阅。便于参考和解决类似的客户问题。为更好的发展客户打下坚实的基础。功能需求如图3.3 服务管理模块功能图所示。
图3.3 服务管理模块功能
5.3.4 系统统计报表模块
统计报表模块用来生成报表数据信息,包括客户构成分析和客户服务分析二个功能模块。在该模块中,企业可以了解客户对企业的贡献以及了解某种类型的客户有多少及所占比例;根据服务类型对服务进行统计;查看已经确认流失的客户流失记录,功能需求如图3.4 统计报表模块功能图所示。
图3.4 统计报表模块功能
6 数据库逻辑设计
本系统中采用MySQL数据库作为系统开发数据库,在仔细阅读了系统的需求文档之后,对于不同模块的不同需要,需要对数据库进行逻辑设计,实现功能完成系统需要建立如下17张表,当模块需要传输和存储数据的时候,可以运用数据库技术对表进行连接查询,得到所需要的数据资料,将查询所得到的结果返回给客户端。
1.用户职位表
该表用来创建企业系统操作员工的权限问题而设置的,主要包括的职位的ID和所对应的职位名称,其中表中的职位ID设置成为主键,用来和其他表中数据的关联查询,这里需要特别注意的是,用户表里面的职位ID必须和用户职位表中的职位ID相对应。用户职位表的定义如表6.1和图6.1所示:
表6.1 用户职位表table tbl_position
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
positionId |
int |
not null |
职位id(主键) |
positionName |
varchar(50) |
not null |
职位名称 |
图6.1 用户职位表table tbl_position
2.用户表
该表为用户表,包含和存储了用户的一些基本的信息,其中用户ID设置成为主键,其中包含了用户设置的用户名和密码,这也是系统登录时所需要输入的用户名和密码,是在系统运行之前设置,因为系统登录需要和数据库内部的用户表数据进行对比,对比成功方可进入操作系统,在创建数据的时候,需要注意和用户职位表当中的职位ID相对应。用户表的定义如表6.2和图6.2所示:
表6.2 用户表table tbl_user
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id , |
int |
not null |
用户id(自增) |
name |
varchar(20) |
not null |
用户姓名 |
pwd |
varchar(50) |
not null, |
用户密码 |
sex |
int |
DEFAULT 0, |
性别0男1女 |
phone |
char(11), |
|
手机号码 |
positionId |
int, |
|
职位id,参照用户职位表的id |
图6.2 用户表table tbl_user
3.客户等级表
在客户等级表中包含了客户等级ID字段和客户等级名称字段,在数据库设置的时候,一般将客户分为战略合作伙伴、合作伙伴、大客户、普通客户和重点开发客户五个级别,同时他们和设定的用户等级ID相对应,须将客户等级ID设置成为主键。客户等级表的定义如表6.3和图6.3所示:
表6.3 客户等级表table tbl_grade
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
客户等级的id(自增) |
name |
varchar(30) |
not null |
客户等级的名称 |
图6.3 客户等级表table tbl_grade
4.联系人表
联系人表中包含了联系人的一些基本信息,包含了姓名、性别、联系方式等字段,通过联系人数据的插入,可以迅速的在系统查询联系人的信息。联系人表的定义如表6.4和图6.4所示:
表6.4 联系人表table tbl_contact
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
contactId |
int |
not null |
联系人id(自增) |
name |
varchar(20) |
not null |
联系人姓名 |
sex |
int |
DEFAULT 0 |
联系人性别0男1女 |
contactPosition |
varchar(50) |
not null |
联系人职位 |
telephone |
varchar(20) |
not null |
联系人办公电话 |
phone |
char(11) |
|
联系人手机 |
customerId |
int |
not null |
联系人所属的客户id(参照客户表的Id) |
remark |
char(100) |
not null |
备注 |
图6.4 联系人表table tbl_contact
5.客户表
客户表的定义中包含了客户的一些基本信息,将客户ID设置成为主键,通过客户ID可以查询到客户的基本信息,其中客户所对应的客户经理需要连接用户表来查询,而客户的等级则需要参照客户等级表来查询。客户表的定义如表6.5和图6.5所示:
表6.5 客户表table tbl_customer
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
customerId |
int |
not null |
客户id(自增) |
customerName |
varchar(50) |
not null |
客户名称 |
area |
varchar(50) |
not null |
客户所处的地区 |
userid |
int |
not null |
客户所对应的客户经理(参照用户表的Id) |
grade |
int |
not null |
客户等级的id(参照客户等级表的id) |
pleased |
int |
not null |
客户满意度 |
credit |
int |
not null |
客户信用度 |
address |
varchar(200) |
not null |
客户地址 |
zip |
char(6) |
not null |
邮政编码 |
phone |
varchar(15) |
not null |
电话号码 |
fax |
varchar(20) |
not null |
传真号码 |
website |
varchar(50) |
not null |
网址 |
licenseNum |
varchar(30) |
|
营业执照注册号 |
corporation |
varchar(20) |
not null |
法人 |
capital |
int |
|
注册资金(万元) |
turnover |
int |
|
年营业额(万元) |
bank |
varchar(100) |
not null |
开户银行 |
bankNum |
varchar(30) |
not null |
银行账号 |
localtax |
varchar(40) |
|
地税登记号 |
nationtax |
varchar(40) |
|
国税登记号 |
图6.5 客户表table tbl_customer
6.服务归档表
通过对服务归档表的创建,可以实现对服务归档信息录入的保存操作,在将来企业的运作中可以及时查询,表中将服务归档ID设置成为主键,需要从已经反馈得瑟服务表中获得数据,这里需要参照服务反馈表的ID来获取数据进行服务归档操作,而服务归档的时间设置成为系统的当前时间。服务归档表的定义如表6.6和图6.6所示:
表6.6 服务归档表table tbl_toFile
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
服务归档的id(自增) |
serviceFeedbackId |
int |
not null |
已经反馈的服务的id(参照服务反馈表的id) |
toFileTime |
timestamp(14) |
not null |
归档的时间 |
图6.6 服务归档表table tbl_toFile
7.销售机会指派表
企业要求对于新开发的销售机会进行指派,由指派的客户经理进行进一步开发,销售机会指派表中的数据获取需要参照销售机会表和用户表,而指派的时间则为系统的当前时间,销售机会指派表的定义如表6.7和图6.7所示:
表6.7 销售机会指派表table tbl_sellControlAppoint
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
sellControlAppointId |
int |
not null |
销售机会指派表Id(自增) |
sellControlId |
int |
not null |
销售机会id(参照销售机会表的id) |
userId |
int |
not null |
指派给员工id号(参照用户表的id) |
appointTime |
timestamp(14) |
not null |
指派时间 |
图6.7 销售机会指派表table tbl_sellControlAppoint
8.销售机会表
系统对于刚刚获得的销售机会进行存储和操作,需要在系统中录入有关于销售机会的一些基本信息,其中的联系人字段需要参照联系人表中的数据,通过联系人表中的主键联系人ID来连接,创建人则参照创建的用户表中的信息,创建时间为系统的当前时间。销售机会表的定义如表6.8和图6.8所示:
表6.8 销售机会表table tbl_sellControl
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
Id |
int |
not null |
销售机会id(自增) |
comefrom |
varchar(50) |
|
机会来源 |
customerId |
int |
not null |
客户的id(参照客户表的Id) |
success |
int |
not null |
成功机率用0-100之间的数字表示 |
contactId |
int |
|
联系人id(参照联系人表的id) |
state |
varchar(50) |
|
销售机会的状态 冗余字段 |
detail |
varchar(200) |
not null |
机会描述 |
userid |
int |
not null |
创建人(参照用户表id) |
createTime |
timestamp(14) |
not null |
创建时间 |
图6.8 销售机会表table tbl_sellControl
9.销售机会计划表
对于创建的销售机会需要进行销售机会开发计划的制定,以便更好的开发客户,其中的基本数据需要以销售机会指派表的ID来连接获得,用户可以编辑计划内容,计划时间为系统的当前时间。销售机会计划表的定义如表6.9和图6.9所示:
表6.9 销售机会计划表table tbl_sellControlPlan
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
销售机会计划id(自增) |
sellControlAppointId |
int |
not null |
销售机会id(参照销售机会指派表的id) |
planTime |
timestamp(14) |
not null |
计划时间 |
planContents |
varchar(200) |
not null |
计划内容 |
result |
varchar(200) |
|
执行结果 |
图6.9 销售机会计划表table tbl_sellControlPlan
10.交往记录表
对于企业而言,需要了解客户的一些交往信息,交往记录表中包含了一些有关于客户交往的基本信息,表中将交往记录ID设置成为主键,参照客户表中的客户,定义了与客户交易的时间、地点等属性。交往记录表的定义如表6.10和图6.10所示:
表6.10 交往记录表table tbl_transactionRecords
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
recordsId |
int |
not null |
交往记录的id(自增) |
customerId |
int |
not null |
客户的id(参照客户表的Id) |
transactiontime |
timestamp |
not null |
交易的时间 |
area |
varchar(100) |
not null |
交易的地点 |
gist |
varchar(100) |
not null |
交易的概要 |
detail |
varchar(200) |
|
交易的详情 |
remarks |
varchar(100) |
|
交易的备注 |
图6.10 交往记录表table tbl_transactionRecords
11.订单表
用于显示和存储有关客户的订单信息,包括了订单时间、订单的送货地点、订单的总金额等等字段,需要在系统中录入,存储和查询。订单表的定义如表6.11和图6.11所示:
表6.11 订单表table tbl_orders
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
订单的id(自增) |
ordertime |
timestamp(14) |
not null |
订单的时间 |
address |
varchar(100) |
|
订单的送货地点 |
total |
double |
not null |
订单的总金额 |
status |
varchar(20) |
|
订单的状态 |
图6.11 订单表table tbl_orders
12.商品表
商品表中定义了一些和客户交往有关商品的一些商品信息,表中将商品的ID设置成为主键,包含了商品的名字、商品的单价等属性。商品表的定义如表6.12和图6.12所示:
表6.12 商品表table tbl_goods
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
商品的id(自增) |
name |
varchar(100) |
not null |
商品的名字 |
unit |
float |
not null |
商品的单价 |
measurement |
varchar(10) |
not null |
商品的计数单位 |
图6.12 商品表table tbl_goods
13.服务表
在客户关系管理系统中,我们可以对客户提出的要求进行服务的创建,将服务ID设置成为主键,包含了类型、概要等一系列属性,表中的客户ID属性需要参照客户表中的ID属性,创建人的ID属性需要参照用户表的ID属性,创建服务的时间为系统的当前时间。服务表的定义如表6.13和图6.13所示:
表6.13 服务表table tbl_service
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
服务的id(自增) |
serviceType |
varchar(20) |
not null |
服务的类型 |
gist |
varchar(100) |
not null |
概要 |
customerId |
int |
not null |
客户的id(参照客户表的id) |
request |
varchar(200) |
not null |
服务的请求 |
userid |
int |
not null |
创建人的id(参照用户表的id) |
createTime |
timestamp(14) |
not null |
创建服务的时间 |
图6.13 服务表table tbl_service
14.服务分配表
在系统中需要对已经创建的服务进行分配,服务的ID需要参照服务表的中的服务ID来获取数据,同时要分配的对象需要参照用户表数据中的用户ID,服务分配表的定义如表6.14和图6.14所示:
表6.14 服务分配表table tbl_serviceAllot
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
服务分配表id(自增) |
serviceId |
int |
not null |
服务的id(参照服务表的id) |
userid |
int |
not null |
分配id(参照用户表的id) |
图6.14 服务分配表table tbl_serviceAllot
15.订单详细表
在创建订单表的同时需要创建一张订单详细表来对订单表进行辅助说明,详细数据的获取需要依据订单表的ID,详细表中的商品信息则需要参照商品表中的商品ID,商品的数量默认为一件,订单详细表的定义如表6.15和图6.15所示:
表6.15订单详细表table tbl_orderItems
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
订单相信表的id(自增) |
ordersId |
int |
not null |
订单的id(参照订单表的id) |
goodsId |
int |
not null |
商品的id(参照商品的id) |
amount |
int |
DEFAULT 1 |
商品的数量(默认值为1件) |
图6.15订单详细表table tbl_orderItems
16.服务处理表
在系统的处理业务流程中,客户经理需要对已经分配自己的服务进行处理,数据需要参照服务分配表,同时处理人则需要参照用户表中的数据,服务处理时间为系统的当前时间。服务处理表的定义如表6.16和图6.16所示:
表6.16 服务处理表table tbl_serviceDeal
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
服务处理的id(自增) |
serviceAllotId |
int |
not null |
处理分配的服务的id(参照服务分配表的id) |
deal |
varchar(200) |
not null |
处理的内容 |
dealer |
int |
not null |
处理人(参照用户表的id) |
dealTime |
timestamp(14) |
not null |
服务处理的时间 |
图6.16 服务处理表table tbl_serviceDeal
17.服务反馈表
对已经经过客户经理处理过的服务反馈给客户,表中内容需要参照服务处理表中的内容,表中包含了服务处理结果和服务处理满意度属性,服务反馈表的定义如表6.17和图6.17所示:
表6.17 服务反馈表table tbl_serviceFeedback
字段名 |
数据类型(数据范围) |
是否可空 |
说明 |
id |
int |
not null |
服务反馈的id(自增) |
serviceDealId |
int |
not null |
要反馈的已经处理的服务的id(参照服务处理表的id) |
result |
varchar(100) |
not null |
服务处理的结果 |
pleased |
int |
not null |
服务处理的满意度 |
图6.17 服务反馈表table tbl_serviceFeedback
7 总结与展望
7.1 研究与总结
在进行客户关系管理系统开发之前,首先详细的阅读了客户关系管理系统的需求分析,确定了系统的各个功能模块要求,运用所学习的JAVA和数据库等知识,基本实现了各个功能模块的要求,完成了整个客户关系管理系统;所开发的项目能够适用于许多的小型企业,帮助企业对客户进行简单管理,实现企业发展的目标。系统开发成果如下:
1.在所有功能都能基本实现的基础上,为了能够给企业客户一个更好的体验,在前台页面的设计上要求设计的更加美观,采用CSS网页布局,同时系统是基于MVC设计思想来实现功能,数据库由于完成设计和资金预算需要采用MySQL小型数据库来实现。
2.通过的系统详细设计和编码等各种步骤实现之后,在自己个人PC机上能够实现运行该系统,真正的能够运用到我们的实际生活中。
7.2 展望
本系统开发开发系统过程中运用JAVA和数据库等知识,所开发的项目能够实现各个功能模块的要求,所开发系统能够适用于许多的中小型企业。本系统的开发过程及维护在以下方面还需要进一步的探索。
1.本课题开发的软件设计方面,对于系统设计者来说代码编写也比较繁琐,在进一步的研究与学习之后可以考虑使用Hibernate等框架知识来实现系统。
2.本课题开发的数据库方面,由于MySQL是小型数据库,容量较小,可能会限制企业的发展,客户较多时的存储空间不够,在为了满足企业的发展需要,在将来的设计实现中可以考虑使用Oracle数据库来实现。
3,本课题开发的功能模块方面可以和公司其他的系统相联系起来,更加有利于公司的发展,例如公司的考勤管理系统。
参考文献
[1] 李兆丰.《Java Web项目开发案例精粹》.电子工业出版社,2010.6:462.
[2] 何薇.《网络数据库技术与应用》.清华大学出版社,2005.11:299.
[3] Jacky Lee.《Eclipse 整合开发工具(基础篇)》.2005.03:221.
[4] Bruce Eckel.《thinking in java 4》.2006.02:685.
致谢
本文是在我最尊敬的导师裴晓芳老师的悉心指导下完成的,在此首先特别感谢我的导师裴晓芳老师,她严肃的科学态度,严谨的治学精神深深地感染并激励着我。从课题的讨论、选择确定到每周都向老师汇报毕业设计进度,再到客户关系管理系统的最终完成,都离不开裴晓芳老师耐心的指导和不懈的支持,在此对裴老师表示深深的谢意。同时在完成系统设计的过程当中,滨江的各位老师和辅导员,以及同学都给予了自己很大的帮助,在此对他们表示由衷的感谢;其次感谢在江苏南大苏福特IBM-ETP培训基地的老师们, 包括翟积人老师、张双虎老师以及其他老师,在向我们传授软件开发知识的同时,督促我们项目系统的完成,同时遇到问题的同时帮助我们解决问题,给予我们很大的帮助。最后感谢父母,朋友和帮助过自己的人们,感谢南京信息工程大学滨江学院,我的成功离不开你们的帮助,在将来的生活与工作中,我会一如既往的学习,奋斗,实现人生价值,给母校添彩。
The System of Customer Relationship management Based on JAVA
Ye Jia
Electronic and Information Engineering, Binjiang College, Nanjing University of Information Science & Technology, Nanjing 210044
ABSTRACT
The System of Customer Relationship management is based on the J2EE technology and it mainly adopts Java language as to develop language ,It designed according to MVC .The system data base completed by making the use of MySQL;The system Makes use of the J2EE web page to manufacture technique complete front-office quiescent page and dynamic state page.The front-office quiescent page and data base at the same time is completed by the connectivity operation of JDBC technique, finally complete a The System of Customer Relationship management .The system is totally divided into four functions, service function and statistics report of marketing function, and the system can in aid of business discovers and establish a customer information record, It also can carry on an useful supervision to all customers;According to the customer‘s some basic information and traffic information progress sort, Customer can control old customer of basic watch and the contribution of companies, continuously of exhumation new of customer, run off the customer of reason progress understand, continuously betterment,and raise the economic benefit of business.
Key word: Customer Relationship management;J2EE;Data base;JAVA
附录一: 系统运行图片
在运用Eclipese9.0作为开发工具完成了系统设计和开发之后,该系统能够在自己你的PC机上运行起来,当然,在开发过程中也能遇到一系列的问题,但是自己能够运用软件测试的一些思想和方法进行解决,从而编写数据进行测试,得到以下的系统测试图片:
1.客户管理管理系统登录验证界面
在火狐浏览器下运行该系统,可以显示如下登录界面,当用户名为空时,客户端会给出提示用户名不能为空,在系统运行之前,需要在数据库的用户表中插入用户名和密码数据,当客户端输入的用户名和密码和数据库中插入的不一致时,客户端会提示错误信息。系统截图如图7.1所示:
图7.1 客户管理系统登录验证界面
2.客户关系管理系统登录界面
当输入的用户名和密码和数据库当中设置的一致时,就能进如系统主操作页面。系统页面右上角会出现欢迎字样,系统页面的左侧为系统的四个功能模块,用户可以点击运行期中任何的一个模块,系统截图如图7.2和图7.3所示:
图7.2 客户关系管理系统登录界面
图7.3 客户关系管理系统首页
3.营销机会管理模块主操作界面
用户可以以客户名称、概要或者联系人为条件来查询已经创建的营销机会,下方的分页功能可以查询多条数据,而分页显示的数据条数可以在代码中设置,同时也可以点击画面右上角新建按钮来新建营销机会,进行编辑输入,点击保存按钮就可以保存该营销机会,系统截图如图7.4图7.5和图7.6所示:
图7.4 系统营销机会管理模块主操作页面
图7.5 营销机会管理模块新建销售机会页面
图7.6 营销机会管理模块销售机会保存页面
4.销售机会修改保存界面
当用户需要对已经编辑的销售机会进行修改时,可以点击页面操作下的编辑按钮,对销售机会进行修改,最后点击保存,就可以更新所修改的销售机会。系统截图如图7.7和图7.8所示:
图7.7 营销机会管理模块销售机会修改页面
图7.8 营销机会管理模块销售机会修改保存页面
5.销售机会删除界面
系统可以对已经不需要的销售机会进行删除操作,当对已经创建的销售机会进行删除时,系统客户端会给用户一个删除的提示,避免用户删错销售机会。系统截图如图7.9所示:
图7.9 营销机会管理模块销售机会删除确认页面
6.指派和销售机会界面
客户经理和用户可以对销售机会进行指派,点击主操作页面下面的指派按钮,就可以跳转到指派界面,进行该销售机会的指派业务,对已经分配的销售计划进行保存,页面就会跳转到客户开发计划功能模块中,系统截图如图7.10和图7.11所示:
图7.10 营销机会管理模块销售机会指派页面
图7.11系统客户开发计划模块主操作页面
7.客户开发计划界面
客户经理对分配给自己的客户进行开发,制定计划项,点击新建按钮,就可以编辑和输入新建的计划项,点击保存,系统就会自动在页面和数据库中保存该数据。同时,系统要求客户经理可以对已经编辑的计划项进行编辑和删除操作。系统截图如图7.12、图7.13和图7.14所示:
图7.12 系统客户开发计划模块制定计划初始页面
图7.13 系统客户开发计划模块制定计划完成页面
图7.14 系统客户开发计划模块制定计划修改完成页面
8.客户开发计划模块执行计划界面
根据制定的计划项和实际与客户交流的实际情况,进行实际执行效果的输入和确认,点击保存按钮之后也可以对已经确定的执行效果进行编辑和删除操作,最终确定客户的开发结果,当开发成功时,系统客户端会给用户提供一个确认提示。系统截图如图7.15、图7.16和图7.17所示:
图7.15 系统客户开发计划模块执行计划操作页面
图7.16 系统客户开发计划模块执行计划完成页面
图7.17 系统客户开发计划模块执行计划开发成功确认页面
9.客户信息管理模块主操作界面
用户和客户经理可以依据客户名称、客户等级和法人对已经编辑的客户信息进行查询,同时也可以新建编辑客户信息,系统截图如图7.18和图7.19所示:
图7.18 系统客户信息管理模块主操作页面
图7.19 系统客户信息管理模块页查询结果页面
10.客户信息管理模块详细查询结果页面
对已经查询的某一条客户信息可以进行详细信息的查询,了解他的客户等级等一系列基本信息,同时点击交往记录按钮,可以查询企业与该客户的一些交往信息,这些数据都是在数据库中存储。系统截图如图7.20和图7.21所示:
图7.20 系统客户信息管理模块详细查询结果页面
图7.21 系统客户信息管理模块交往记录操作主页面
11.客户信息管理模块交往记录界面
对于已经查询所得到的企业与客户交往记录可以点击编辑按钮进行编辑操作,也可以对已经不需要保存的交往记录进行删除操作,对于新的交往记录用户可以在系统中进行输入,同时保存到数据库当中,系统截图如图7.22、图7.23、图7.24和图7.25所示:
图7.22 系统客户信息管理模块交往记录编辑修改页面
图7.23 系统客户信息管理模块新建交往记录操作主页面
图7.24 系统客户信息管理模块新建交往记录编辑操作页面
图7.25 系统客户信息管理模块交往记录新建完成结束页面
12.客户信息管理新建客户信息界面
用户可以点击新建按钮编辑新建客户信息,点击保存按钮,就可以新增添一条客户记录,同时保存到数据库中。系统截图如图7.26和图7.27所示:
图7.26 系统客户信息管理模块新建客户信息编辑操作页面
图7.27 系统客户信息管理模块编辑客户信息页面
13.服务管理模块主操作界面
用户可以根据客户的需要创建一条服务记录,确定服务类型和服务请求内容,点击保存按钮之后,该记录就跳转到服务分配界面中,用户可以对该服务记录进行分配和删除操作,系统截图如图7.28、图7.29和图7.30所示:
图7.28 系统服务管理模块服务创建初始页面
图7.29 系统服务管理模块服务创建编辑页面
图7.30 系统服务管理模块服务分配操作页面
14.服务管理模块服务处理界面
对已经分配的服务记录进行处理,用户和客户经理根据实际情况填写服务处理效果。系统截图如图7.31、图7.32所示:
图7.31 系统服务管理模块服务处理初始页面
图7.32 系统服务管理模块服务处理操作页面
15.服务管理模块服务反馈界面
对于已经分配处理的界面进行反馈,填写处理结果,根据实际处理情况确定处理成功或失败,反馈给客户和公司企业。系统截图如图7.33、图7.34和图7.35所示:
图7.33 系统服务管理模块服务反馈初始页面
图7.34 系统服务管理模块服务反馈操作页面
图7.35 系统服务管理模块服务反馈操作结束页面
16.统计报表模块界面
在客户构成分析中,用户可以查询之前有关客户的一些信息的统计,包括客户的等级和客户的数量,对还未进行的服务处理进行统计,帮助用户和客户经理进行管理。系统截图如图7.36和图7.37所示:
图7.36 系统统计报表模块客户构成分析主页面
图7.37 系统统计报表模块客户服务分析主页面
附录二: 系统主要程序
为了很好的完成客户关系管理系统,首先需要完成系统的静态页面,在系统完成初期,就要运用CSS等HTML网页制作知识完成静态页面,后期需要和数据库连接,改成JSP动态网页,在这里,将网页部分分成三个部分来完成,首先就是CSS布局,完成一个系统页面的布局大小,其次就是网页的页面内容的编辑,最后就是网页提交表单的验证过程,是用JAVASCRIPT来完成表单的验证过程。
通过定义CSS样式表,能让网页具有美观一致的画面,可以将网页制作的更加绚丽多彩,一个样式文件可以用于多个文件,具有更好的易用性和可扩展性。系统服务分配页面的主要CSS布局代码如下:
body {
margin:0;
padding:0;
width:660px;
height:500px;
font-size:14px;
}
#container {
width:660px;
height:500px;
}
#space {
width:650px;
height:10px;
}
#menuTitle {
width:650px;
height:30px;
text-align:left;
font-weight:bold;
font-size:20px;
margin-left:10px;
}
#tool {
width:650px;
height:30px;
text-align:right;
margin-left:10px;
}
#searchInfo {
width:650px;
margin-left:10px;
}
#searchInfo table {
width:100%;
text-align:center;
background-color:#ECEEFA;
}
#searchInfo table, #searchInfo th, #searchInfo td, #searchInfo tr {
border:1px solid #79ABCD;
border-collapse:collapse;
}
#searchInfo input {
width:120px;
}
#searchInfo .blue {
width:100px;
height:25px;
background-color:#6BC4F6;
}
form {
margin:0;
display:inline;
}
#contents {
clear:both;
width:650px;
height:330px;
margin-left:10px;
}
#contents table, #contents td, #contents tr, #contents th {
border:none;
}
#contents table {
margin-top:10px;
width:650px;
border-collapse:collapse;
border:1px solid #FFF;
}
#contents th {
background-color:#0065CC;
height:30px;
color:#FFF;
}
#contents td {
text-align:center;
height:30px;
border:1px solid #FFF;
}
#contents td img {
margin-top:auto;
margin-bottom:auto;
border:none;
}
#navigation {
margin-top:10px;
width:647px;
height:30px;
border:1px solid #3875AD;
text-align:right;
color:#00C;
padding-top:10px;
}
#navigation input {
width:25px;
}
#navigation a:link, #navigation a:visited, #navigation a:hover {
color:#00C;
text-decoration:none;
}
.lightBlue {
background-color:#7EC4F8;
}
.gray {
background-color:#EEEEF8;
}
在制作页面当中,可以运用一系列的网页标签来完成,服务分配页面的主要内容代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>服务分配</title>
<link type="text/css" rel="stylesheet" href="css/allotService.css" />
</head>
<body>
<div id="container">
<div id="space"> </div>
<div id="menuTitle">客户服务管理 > 服务分配</div>
<form name="inquireForm" method="post" action="service_select">
<div id="tool">
<input type="submit" id="save" value="查询" />
</div>
<div id="searchInfo">
<table cellpadding="0" cellspacing="0">
<tr>
<td class="blue">客户名称</td>
<td><input type="text" name="service.customer.customerName" /></td>
<td class="blue">概要</td>
<td><input type="text" name="service.gist" /></td>
<td class="blue">服务类型</td>
<td><input type="text" name="service.serviceType" /></td>
</tr>
</table>
</div>
</form>
<div id="contents">
<table cellspacing="0" cellpadding="0">
<tr>
<th>编号</th>
<th>客户</th>
<th>概要</th>
<th>服务类型</th>
<th>创建人</th>
<th>创建日期</th>
<th>分配给</th>
<th>操作</th>
</tr>
<s:iterator var="ss" value="services" status="index">
<s:if test="#index.odd"><tr class="gray"></s:if>
<s:else><tr class="lightBlue"></s:else>
<td id="serviceId"><s:property value="#ss.id"/></td>
<td><s:property value="#ss.customer.customerName"/></td>
<td><s:property value="#ss.gist"/></td>
<td><s:property value="#ss.serviceType"/></td>
<td><s:property value="#ss.user.name"/></td>
<td><s:date name="%{#ss.createTime}" format="yyyy年MM月dd日"/></td>
<td><s:select list="#session.users" listKey="id" listValue="name" theme="simple" id="userId"></s:select>
<a href="#" title="指派" onclick="return toAllot()"><img alt="指派" src="images/give.png" /></a>
</td>
<td>
<a href="service_delete?service.id=<s:property value="#ss.id"/>" id="delete" title="删除" onclick="return del()"><img alt="删除" src="images/delete.png" /></a>
</td>
</tr>
</s:iterator>
</table>
<div id="navigation">
共<s:property value="page.totalRecord"/>条记录 第<span id="pageCurrent"><s:property value="page.currentPage"/></span>/<s:property value="page.totalPage"/>页
<s:if test="page.currentPage != 1"><a href="service_page?currentPage=1">首 页</a></s:if>
<s:if test="page.currentPage != 1"><a href="service_page?currentPage=<s:property value="page.previousPage"/>">上一页</a></s:if>
<s:if test="page.currentPage != page.totalPage"><a href="service_page?currentPage=<s:property value="page.nextPage"/>">下一页</a></s:if>
<s:if test="page.currentPage != page.totalPage"><a href="service_page?currentPage=<s:property value="page.totalPage"/>">尾 页</a></s:if> 转到第
<form name="changePage" method="post" action="service_page">
<input type="text" id="changePageNum" name="currentPage" />
<input type="submit" value="GO" />
</form>
</div>
</div>
</div>
</body>
</html>
<scriptlanguage="javascript"type="text/javascript"src="js/allotService.js"></script>
在完成代码和系统的过程,完善系统需要进行表单的验证,使用JAVASCRIPT是一种十分便捷的解决方法,它不但能检查用户输入的无效或错误数据,还能检查用户遗漏的必选项,从而减轻服务器端的压力,避免服务器端的数据无法更新而出现新错误,在系统中的服务分配页面的主要表单提交验证代码如下:
function del() {
if(confirm("你确定要删除吗?")) {
return true;
}
return false;
}
function toAllot() {
varserviceId=document.getElementById("serviceId").innerHTML.trim();
var sel = document.getElementById("userId");
var userId = sel.options[sel.options.selectedIndex].value;
location.replace("service_allotService?serviceAllot.service.id=" + serviceId + "&serviceAllot.user.id=" +userId);
return false;
}
在完成客户关系管理系统的前台页面和数据库设计之后,接下来在代码之中就需要创建一系列的ACTION来处理客户端所发出的请求,在这里主要附录LOGIN,也就是登录界面的ACTION。action是用户请求和业务逻辑之间的桥梁,它主要负责处理客户端发来的请求,并调用相应的组件完成业务逻辑,并将处理好的结果返回给客户端。
package com.les.action;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.les.dao.ILogin;
import com.les.pojo.User;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport implements SessionAware {
private String userName;
private String userPwd;
private String message;
private Map<String, Object> session;
ILogin login;
@Override
public String execute() throws Exception {
User user = login.verify(userName, userPwd);
if (null != user) {
session.put("user", user);
return SUCCESS;
}
message = "用户名或密码错误";
return "fail";
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ILogin getLogin() {
return login;
}
public void setLogin(ILogin login) {
this.login = login;
}
}
在完成LOGIN的ACTION之后,需要创建一个DAO用来进行和数据库的访问和连接操作,dao是数据访问对象的接口,里面定义了用来访问数据库的方法,先定义一个DAO,然后定义一个接口,接口与包类似,也是用来组织应用中的各类并调节他们的相互关系的一种结构,实现类间多重继承功能。
package com.les.dao.impl;
import com.les.dao.ILogin;
import com.les.dao.IUser;
import com.les.pojo.User;
public class LoginImpl implements ILogin {
private IUser user;
public LoginImpl() {}
public IUser getUser() {
return user;
}
public void setUser(IUser user) {
this.user = user;
}
@Override
public User verify(String name, String pwd) {
User u = null;
u = user.getUser(name, pwd);
return u;
}
}
package com.les.dao;
import com.les.pojo.User;
/**
* 这个接口中定义了一系列和登录有关的操作
*
*/
public interface ILogin {
public User verify(String name, String pwd);
}
pojo就是简单的JAVA对象,实际上就是普通的JAVABEANS,用来实现和数据库中的表相对应的实体类。在每一次创建和传输对象,我们都需要创建一个个实体类来将对象实体化,在和客户所有相关的信息中封装在实体类当中。
package com.les.pojo;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
*对应数据库中的tbl_customer表
*
*/
@Entity
@Table(name = "tbl_customer", catalog = "customerrelationship")
public class Customer implements java.io.Serializable {
private Integer customerId;
/**
* 客户等级的
*/
private Grade grade;
/**
* 客户对应的客户经理
*/
private User user;
private String customerName;
/**
* 客户所处的地区
*/
private String area;
/**
* 客户满意度
*/
private Integer pleased;
/**
* 客户信用度
*/
private Integer credit;
private String address;
private String zip;
private String phone;
private String fax;
private String website;
/**
*营业执照注册号
*/
private String licenseNum;
/**
* 法人
*/
private String corporation;
/**
* 注册资金
*/
private Integer capital;
/**
* 年营业额
*/
private Integer turnover;
/**
* 开户银行
*/
private String bank;
/**
* 开户账号
*/
private String bankNum;
/**
* 地税登记号
*/
private String localtax;
/**
* 国税登记号
*/
private String nationtax;
private Set<TransactionRecords> transactionRecordses = new HashSet<TransactionRecords>(0);
private Set<SellControl> sellControls = new HashSet<SellControl>(0);
private Set<Service> services = new HashSet<Service>(0);
private Set<Contact> contacts = new HashSet<Contact>(0);
public Customer() {
}
public Customer(Grade grade, User user, String customerName, String area,
Integer pleased, Integer credit, String address, String zip,
String phone, String fax, String website, String corporation,
String bank, String bankNum) {
this.grade = grade;
this.user = user;
this.customerName = customerName;
this.area = area;
this.pleased = pleased;
this.credit = credit;
this.address = address;
this.zip = zip;
this.phone = phone;
this.fax = fax;
this.website = website;
this.corporation = corporation;
this.bank = bank;
this.bankNum = bankNum;
}
public Customer(Grade grade, User user, String customerName, String area,
Integer pleased, Integer credit, String address, String zip,
String phone, String fax, String website, String licenseNum,
String corporation, Integer capital, Integer turnover, String bank,
String bankNum, String localtax, String nationtax,
Set<Service> services, Set<Contact> contacts) {
this.grade = grade;
this.user = user;
this.customerName = customerName;
this.area = area;
this.pleased = pleased;
this.credit = credit;
this.address = address;
this.zip = zip;
this.phone = phone;
this.fax = fax;
this.website = website;
this.licenseNum = licenseNum;
this.corporation = corporation;
this.capital = capital;
this.turnover = turnover;
this.bank = bank;
this.bankNum = bankNum;
this.localtax = localtax;
this.nationtax = nationtax;
this.services = services;
this.contacts = contacts;
}
@Id
@GeneratedValue
@Column(name = "customerId", unique = true, nullable = false)
public Integer getCustomerId() {
return this.customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "grade", nullable = false)
public Grade getGrade() {
return this.grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "userid", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
@Column(name = "customerName", nullable = false, length = 50)
public String getCustomerName() {
return this.customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
@Column(name = "area", nullable = false, length = 50)
public String getArea() {
return this.area;
}
public void setArea(String area) {
this.area = area;
}
@Column(name = "pleased", nullable = false)
public Integer getPleased() {
return this.pleased;
}
public void setPleased(Integer pleased) {
this.pleased = pleased;
}
@Column(name = "credit", nullable = false)
public Integer getCredit() {
return this.credit;
}
public void setCredit(Integer credit) {
this.credit = credit;
}
@Column(name = "address", nullable = false, length = 200)
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
@Column(name = "zip", nullable = false, length = 6)
public String getZip() {
return this.zip;
}
public void setZip(String zip) {
this.zip = zip;
}
@Column(name = "phone", nullable = false, length = 15)
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Column(name = "fax", nullable = false, length = 20)
public String getFax() {
return this.fax;
}
public void setFax(String fax) {
this.fax = fax;
}
@Column(name = "website", nullable = false, length = 50)
public String getWebsite() {
return this.website;
}
public void setWebsite(String website) {
this.website = website;
}
@Column(name = "licenseNum", length = 30)
public String getLicenseNum() {
return this.licenseNum;
}
public void setLicenseNum(String licenseNum) {
this.licenseNum = licenseNum;
}
@Column(name = "corporation", nullable = false, length = 20)
public String getCorporation() {
return this.corporation;
}
public void setCorporation(String corporation) {
this.corporation = corporation;
}
@Column(name = "capital")
public Integer getCapital() {
return this.capital;
}
public void setCapital(Integer capital) {
this.capital = capital;
}
@Column(name = "turnover")
public Integer getTurnover() {
return this.turnover;
}
public void setTurnover(Integer turnover) {
this.turnover = turnover;
}
@Column(name = "bank", nullable = false, length = 100)
public String getBank() {
return this.bank;
}
public void setBank(String bank) {
this.bank = bank;
}
@Column(name = "bankNum", nullable = false, length = 30)
public String getBankNum() {
return this.bankNum;
}
public void setBankNum(String bankNum) {
this.bankNum = bankNum;
}
@Column(name = "localtax", length = 40)
public String getLocaltax() {
return this.localtax;
}
public void setLocaltax(String localtax) {
this.localtax = localtax;
}
@Column(name = "nationtax", length = 40)
public String getNationtax() {
return this.nationtax;
}
public void setNationtax(String nationtax) {
this.nationtax = nationtax;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "customer")
public Set<TransactionRecords> getTransactionRecordses() {
return this.transactionRecordses;
}
public void setTransactionRecordses(
Set<TransactionRecords> transactionRecordses) {
this.transactionRecordses = transactionRecordses;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "customer")
public Set<SellControl> getSellControls() {
return this.sellControls;
}
public void setSellControls(Set<SellControl> sellControls) {
this.sellControls = sellControls;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Service> getServices() {
return this.services;
}
public void setServices(Set<Service> services) {
this.services = services;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Contact> getContacts() {
return this.contacts;
}
public void setContacts(Set<Contact> contacts) {
this.contacts = contacts;
}
}
当系统之中插入数据较多时,需要进行分页的处理,分页使用了Mysql数据库当中的limit语句实现了数据库的分页操作。而每一页显示的数据量可以通过代码的编写来实现,同时也实现了页面的前后检索功能。
package com.les.tool;
public class Page {
public static final int PAGESIZE = 2;
private int totalPage;
private int currentPage;
private int currentRecord;
private int totalRecord;
private int nextPage;
private int previousPage;
public Page() {}
public Page(int totalPage, int currentPage, int totalRecord,
int currentRecord) {
this.totalPage = totalPage;
this.currentPage = currentPage;
this.totalRecord = totalRecord;
this.currentRecord = currentRecord;
}
public int getCurrentPage() {
return currentPage;
}
public int getTotalPage() {
if(totalRecord % PAGESIZE == 0) {
totalPage = totalRecord / PAGESIZE;
} else {
totalPage = totalRecord/PAGESIZE + 1;
}
return totalPage;
}
public int getCurrentRecord() {
return currentRecord;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setCurrentRecord(int currentRecord) {
this.currentRecord = currentRecord;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getFirstCurrentRecord() {
int firstRecord = (currentPage - 1) * PAGESIZE;
if (firstRecord < 0) {
firstRecord = 0;
}
return firstRecord;
}
public int getLastCurrentRecord() {
int lastRecord = currentPage * PAGESIZE;
if(lastRecord > totalRecord)
lastRecord = totalRecord;
return lastRecord;
}
public int getPreviousPage() {
previousPage = currentPage -1;
if(previousPage < 1)
previousPage = 1;
return previousPage;
}
public int getNextPage() {
nextPage = currentPage + 1;
if(nextPage > totalPage)
nextPage = totalPage;
return nextPage;
}
}
Srevlet API中最重要的一个功能就是能够为Servlet和JSP页面定义过滤器,过滤器可以以常规的方式调用资源,也可以利用修改过的请求信息来调用资源,在本系统中就定义了一个这样的过滤器。
package com.les.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncodeFilter implements Filter {
private String encode;
public void init(FilterConfig fConfig) throws ServletException {
encode = fConfig.getInitParameter("encode");
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encode);
response.setContentType("text/html;charset="+encode);
chain.doFilter(request, response);
}
public void destroy() {
}
}
以上是关于基于JAVA技术的客户关系管理系统的主要内容,如果未能解决你的问题,请参考以下文章
基于Java/Swing技术的KTV包间管理系统的设计与实现