客户管理系统

目录

0  引言

1  系统分析

1.1  需求分析

1.2  可行性分析

2  总体设计

2.1  项目规划

2.2  系统功能结构图

3  系统设计

3.1  设计目标

3.2  开发及运行环境

3.3  数据库设计

4  客户管理模块设计

4.1  主要模块设计

     5  结束语-----------------------------------------------------------

      感谢

0  引言

信息时代的今天,各企业商家所关心的不再局限于自身的产品质量、生产设备、员工的素质,更多的是关心自己的销售群体(客户群),关心他们的想法、需求、购卖目的。

众所周知,顾客就是我们的上帝,我们只有满足了上帝的需求,上帝才能给我们带来一切。一个企业要生存、要发展,就是要不断的满足客户的需求,无论我们做出什么样的决策,最终都是为了这个的目。每个领域都有自身生存法则,但无论这个法则如何变化,为客户服务的宗旨是不会变的。作为企业,我们只有不断地挖掘新客户,维护好和老客户的关系,占领市场客户群体的绝大多数份额,才能在整个领域取得一席之地。海尔总裁张瑞敏指出:“客户资源决定企业核心竞争力”,上个世纪80年代是物品短缺的时代,而现在,信息时代是客户短缺的时代。企业发展所需的各种资源(包括人力、物力、生产力)都是可以创造的,但每个领域中的客户资源确是有限的,所以通过创新(产品的创新、企业管理的创新、服务的创新)来抢占有限的客户资源、维护好企业和客户之间的关系、了解客户的需求动向,成为企业生存发展面临的重大问题。

1  系统分析

1.1  需求分析

通过调查研究,要求系统满足有以下功能;

  1. 由于操作人员的计算机知识普遍较差,要求有良好的人机界面。
  2. 方便的数据选择查询,支持模糊查询功能。
  3. 管理客户的详细信息:包括客户的基本信息、联系人信息、和服务信息。
  4. 数据计算自动完成,尽量减少人工干预。

1.2  可行性分析

  1. 经济性

通过计算机网络对客户信息进行管理,使企业对自身拥有的客户有了一个更为深该的了解。不仅能全面的统计客户的购买数量,及时的了解客户的动态信息,还可以根据计算机记录的数据信息,不断的调整企业的生产发展动向。

  1. 技术性

   √  采用 Struts2.0+Spring3.0+Hibernate3.2 开源框架

   √  数据库采用 SQLServer 2005

 框架详解:  

  1. Struts2.0:     Struts 2是Struts的下一代产品,是在 struts 和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2只有很小的变化。
  2. Spring3.0:    是为了解决企业应用程序开发复杂性由Rod Johnson创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
  3. Hibernate3.2: 是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
  4. SQL是英文Structured Query Language的缩写,意思为结构化查询语言。SQL语言的主要功能就是同各种数据库建立联系,进行沟通。按照ANSI(美国国家标准协会)的规定,SQL被作为关系型数据库管理系统的标准语言。

2  总体设计

2.1  项目规划

客户关系管理系统是一个典型的数据库开发应用程序,营销管理,客户管理,服务管理,

统计报表,基础数据如下:

  1. 营销管理模块

该模块主要功能是对销售机会,客户开发计划进行增删改查操作。

  1. 客户管理模块

该模块的主要功能是对客户信息,联系人,交往记录,历史订单等增删改查操作。

  1. 服务管理模块

该模块主要功能是对客户服务进行添加、删除、查询等操作。

  1. 报表管理模块

该模块主要起到统计数据的作用。

  1. 基础数据模块

对字典表数据进行增删改查操作。

2.2  系统功能结构图

图1  数据表树型结构图

3  系统设计

3.1  设计目标

  

项目详解:

因为项目中有许多重复的代码,我们可以将他抽象出一个公共的父类(BaseDao(对数据访问,制定出增删改查方法),BaseAction(定义request,response,分页,页面返回变量)等等)

com.action (存放Action类 用来处理用户请求和业务逻辑)

com.biz(用来存放业务逻辑接口)

com.bizImpl(业务逻辑接口的实现类)

com.dao(用来存放数据访问接口)

com.daoImpl(数据访问接口实现类)

com.entity(存放实体类)

com.util(存放工具类)

JuTest(单元测试类)

Web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

//配置DWR

<servlet>

<servlet-name>dwr</servlet-name>

<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>dwr</servlet-name>

<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

//解决页面使用懒加载问题

<filter>

<filter-name>openSessionInView</filter-name>

<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>openSessionInView</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

//定义过滤去进行拦截转码

<filter>

<filter-name>doFilter</filter-name>

<filter-class>com.util.Filter</filter-class>

</filter>

<filter-mapping>

<filter-name>doFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

//Struts自带的过滤器

<filter>

<filter-name>struts2</filter-name>

<filter-class>

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

</filter-class>

</filter>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

//定义监听程序系统初始化时,启动

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

//指定 applicationContext.xml 位置,classpath代表src目录下

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:applicationContext.xml</param-value>

</context-param>

<welcome-file-list>

<welcome-file>login.jsp</welcome-file>

</welcome-file-list>

</web-app>

Datasource.properties(配置文件):

//在程序启动时由Spring工厂对此配置文件进行解析加载

datasource.type=sqlserver

hibernate.dialect=org.hibernate.dialect.SQLServerDialect

datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

datasource.url=jdbc\:sqlserver\://localhost\:1433;DatabaseName\=client

datasource.username=sa

datasource.password=123

struts.xml:

//接受页面请求(如user_login) 为跳转到userAction 下的login方法

<action name="*_*" class="{1}Action" method="{2}">

<interceptor-ref name="defaultStack"></interceptor-ref>

  //返回堆栈下的信息来进行,跳转或重定向

<result name="success">${successResultValue}</result>

<result name="redirect" type="redirect">${redirectPath}</result>

</action>

applicationContext.xml(Hibernate由 Spring 控制管理):

// 加载datasource.properties 里的数据配置信息

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location" value="classpath:datasource.properties"></property>

</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"

destroy-method="close" dependency-check="none">

<property name="driverClass">

<value>${datasource.driverClassName}</value>

</property>

<property name="jdbcUrl">

<value>${datasource.url}</value>

</property>

<property name="user">

<value>${datasource.username}</value>

</property>

<property name="password">

<value>${datasource.password}</value>

</property>

</bean>

 //Hibernate配置与注入数据源

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

<property name="dataSource">

<ref bean="dataSource"></ref>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.hbm2ddl.auto">

updates

</prop>

<prop key="hibernate.dialect">

${hibernate.dialect}

</prop>

<prop key="hibernate.show_sql">

${hibernate.show_sql}

</prop>

<prop key="hibernate.format_sql">

${hibernate.format_sql}

</prop>

<prop key="hibernate.jdbc.fetch_size">

${hibernate.jdbc.fetch_size}

</prop>

<prop key="hibernate.jdbc.batch_size">

${hibernate.jdbc.batch_size}

</prop>

<prop key="hibernate.cglib.use_reflection_optimizer">

false

</prop>

<prop key="hibernate.connection.release_mode">

${hibernate.connection.release_mode}

</prop>

</props>

</property>

   //扫描 com.entity下的所有类

       <property name="packagesToScan">

<list>

<value>com.entity</value>

</list>

</property>

  // Hibernate 持久化层 模板化

 <bean

id="hibernateTemplate"  class="org.springframework.orm.hibernate3.HibernateTemplate">

 <property name="sessionFactory" ref="sessionFactory"></property>

</bean>

//注入事物管理器

<bean id="txManager"

class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory" />

<property name="dataSource" ref="dataSource"></property>

</bean>

<!--使用基于注解方式配置事务 -->

<tx:annotation-driven transaction-manager="txManager" />

</beans>

 log4j.properties :

//日志信息管理

3.2  开发及运行环境

开发工具:Myeclipse 8.5(java开发工具),Powerdesigner(数据库建模工具) ,SQLServer(微软的数据库产品)

开发环境: Windows操作系统,Tomcat服务器,JDK6.0    

硬件平台:

  1. CPU:P41。8GHz;
  2. 内存:256MB以上。

软件平台:

  1. 操作系统:Windows 系统;
  2. 数据库:SQL Server 2000;
  3. 浏览器:推荐使用IE6.0;
  4. Web服务器:IIS5.0;
  5. 分辨率:最佳效果1024*768。

3.3  数据库设计

本系统数据库采用SQLServer2005数据库,系统数据库名称为jb_crm_team0_Data.MDF。数据库jb_crm_team0_Data.MDF中包含15张表。关于数据库中的数据表请参见后文。

4  客户管理模块设计(主要代码)

√登陆与权限模块

     此模块用于用户的登陆验证与权限

 数据库表

  

             

   用户登录界面

   

  //用户点击登陆 提交SysUser_login

 <script type="text/javascript">

  function tosubmit()

  {

         document.forms[0].action="SysUser_login";

   document.forms[0].submit();   

   }

</script>

 后台数据接收(通过Struts与Spring控制找到请求的Action类)

 //注解 将此类名定义名为SysUserAction(Spring将通过解析找到此类)

  @Component("SysUserAction")

  //继承事先写好的公用类 BaseAction

  public class SysUserAction extends BaseAction {

  //将SysUserBiz(写好的对数据进行逻辑处理的接口,增删改查方法)注入此类

@Resource(name = "SysUserBiz")

private SysUserBiz sysUserBiz;

   //封装SysUser类

    private SysUser sysUser;

public SysUser getSysUser() {

return sysUser;

}

public void setSysUser(SysUser sysUser) {

this.sysUser = sysUser;

}

   //请求的对应方法

   public String login()

{

String Msg="用户名或密码错误!";

this.setSuccessResultValue("login.jsp");

if(sysUserBiz.login(this.sysUser.getUsrName(),        this.sysUser.getUsrPassword()))

{    

Msg="";

this.setSuccessResultValue("html/index.jsp");

this.getRequest().getSession().setAttribute("Uname",sysUserBiz.getByName(this.sysUser.get UsrName()));

}

this.getRequest().setAttribute("Msg", Msg);

return SUCCESS;

}

营销管理模块

     数据库  

 查询所有操作

public String getAll(){

//调用BaseAction里的分页方法

this.doPage("from SalChance", null);

this.setSuccessResultValue("/html/~sale/list.jsp") ;

return SUCCESS;

}

BaseAction的分页方法

public void doPage(String strSql, String urlparam) {

// Page page = new Page(strSql, 20, getPage(), 5,

// urlparam);//10:每页显示10条数据 5:页之间的跨度为5

page_.initPage(strSql, 10, getPage(), 5, urlparam);

setPageHtml(page_.getPageText());// 分页

setPageList(page_.getPageList());

}

模糊查询

 public String getByInfo()

{

String hql ="from SalChance ";

if(salChance.getChcCustName()!=null && !salChance.getChcCustName().equals(""))

    {

hql+="where chcCustName Like '%"+salChance.getChcCustName()+"%'";

}else if(salChance.getChcTitle()!=null && !salChance.getChcTitle().equals(""))

    {

     hql+="where chcTitle Like '%"+salChance.getChcTitle()+"%'";

    }else if(salChance.getChcLinkman()!=null     && !salChance.getChcLinkman().equals(""))

    {

     hql+="where chcLinkman Like '%"+salChance.getChcLinkman()+"%'";

    }

   this.doPage(hql, null);

   this.setSuccessResultValue("/html/~sale/list.jsp") ;

   return SUCCESS;

}

添加

public String add()

{

if(this.salChanceBiz.add(this.salChance)){

   //添加成功后系统将再次加载数据,此处用到了Redirect(重定向)

   this.setRedirectPath("SalChance_getAll");

return Redirect;

}

 this.setSuccessResultValue("/html/~sale/add.jsp");

return SUCCESS;

}

//Form表单里控件的名字要与Action里定义的实体名字吻合。如下为Action实例的salChance类下的chcStatus字段赋值

<input type="hidden" name="salChance.chcStatus" value="0">

修改

 public String update()

    {

       if(this.salChanceBiz.update(this.getSalChance()))

       {

       this.setRedirectPath("SalChance_getAll");

       return Redirect;

       }

       return ERREO;

    }

填充

 public String toEdit()

    {  

      this.getRequest().setAttribute("SalChanceByid",salChanceBiz.getSal(this.salChance.getChcId()));

        this.getRequest().setAttribute("AllUser", sysUserBiz.getAll());

        this.setSuccessResultValue("/html/~sale/edit.jsp");

        return SUCCESS;

}

//在页面获取存在request内的数据对下拉列表填充

<select name="salChance.chcDueTo">

<option>请选择...</option>

            //迭代循环

<s:iterator value="#request.AllUser" var="list">

<option

            value="<s:property value="#list.usrName"/>"><s:property       value="#list.usrName"/> </option>

</s:iterator></select>

  //删除操作

  public String del()

{

 if(this.salChanceBiz.del(this.getSalChance().getChcId()))

 {

 this.setRedirectPath("SalChance_getAll");

return Redirect;

 }

 this.setSuccessResultValue("error.jsp");

return SUCCESS;

}

//通过JAVASCRIPT 提示是否要删除。

<img

οnclick="if(confirm('您确认删除这条数据?'))

{to('<%=path%>/SalChance_del?salChance.chcId=<s:property value="#list.chcId"/>')}" title="删除"src="<%=path%>/html/images/bt_del.gif" class="op_button" />

 客户开发计划:此模块为客户计划操作,分三种状态,制定开发计划,开发计划得到的响应,开发结束(主要知识点介绍,其他请参见上模块)

   //如果状态已完毕

//这里用到了Struts2 标签去判断

<s:if test="#list.chcStatus==3|#list.chcStatus==2">

<img

οnclick="javascript:window.location.href='<%=path%>/salPlan_getByid?salPlan.salChance.chcId=<s:property value="#list.chcId"/>¶m=3'"

title="查看" src="<%=path%>/html/images/bt_detail.gif"

class="op_button" />

</s:if>

//如果状态开发中

<s:else>

<img<s:if test="#session.Uname.sysRole.roleId==1">

οnclick="javascript:window.location.href='<%=path%>/salPlan_getByid?salPlan.salChance.chcId=<s:property value="#list.chcId"/>¶m=1'"

</s:if>

<s:else>

οnclick="javascript:alert('您没有权限!')"

</s:else>

title="制定计划" src="<%=path%>/html/images/bt_plan.gif"

class="op_button" />

<img

<s:if test="#session.Uname.sysRole.roleId==1">

οnclick="javascript:window.location.href='<%=path%>/salPlan_getByid?salPlan.salChance.chcId=<s:property value="#list.chcId"/>¶m=2'"

</s:if>

<s:else>

οnclick="javascript:alert('您没有权限!')"

</s:else>

title="执行计划" src="<%=path%>/html/images/bt_feedback.gif"class="op_button" />

<img<s:if test="#session.Uname.sysRole.roleId==1">

οnclick="alert('用户开发成功,已添加新客户记录。');window.location.href='salPlan_upChan?salChance.chcId=<s:property value="#list.chcId"/>&salChance.chcStatus=2';"

</s:if>

<s:else>

οnclick="javascript:alert('您没有权限!')"

</s:else>

title="开发成功" src="<%=path%>/html/images/bt_yes.gif"

class="op_button" />

</s:else>

//已完毕处理,考虑开发成功只需要状态的修改,所以页面只需要编号(id)和状态(status)通过id进行查询此条信息,然后将状态进行赋值,执行修改。

 public String  upChan()

    {

     String status = this.getSalChance().getChcStatus();

     this.setSalChance(this.salChanceBiz.getSal(this.salChance.getChcId()));

     this.getSalChance().setChcStatus(status);

     if(this.salChanceBiz.update(this.getSalChance()))

     {

     this.setRedirectPath("salPlan_SalChanAll");

     return Redirect;

     }

     this.setSuccessResultValue("error.jsp");

return SUCCESS;

    }

 客户信息管理

介绍:此模块对客户信息的管理及其对子类(联系人,交往记录,历史订单)进行操作(增删改查),如果客户等级为重点客户的信息将不显示删除操作

(主要知识点介绍,其他请参见上模块)

//等级判断如果是重点客户将没有删除按钮

//如果不是则有删除按钮

//通过Struts2标签的if标签,去判断用户等级

<s:if test="#list.custLevel!=2">

<img

<s:if test="#session.Uname.sysRole.roleId==1">

οnclick="if(confirm('您确认删除这条数据?')){to('cstCustomer_del?cstCustomer.custNo=<s:property value="#list.custNo"/>')}"

</s:if>

<s:else>

οnclick="javascript:alert('您没有权限!')"

</s:else>

title="删除" src="<%=path%>/html/images/bt_del.gif"

class="op_button" />

</s:if>

填充

public String toEdit() {

if (this.cstCustomerBiz.getCus(this.cstCustomer.getCustNo()) != null) {

this.getRequest().setAttribute("cstCust",

this.cstCustomerBiz.getCus(this.cstCustomer.getCustNo()));

this.getRequest().setAttribute("basDict",

this.basDictBiz.getByInfo("地区"));

this.getRequest().setAttribute("basDictc",

this.basDictBiz.getByInfo("客户等级"));

}

this.setSuccessResultValue("/html/~cust/cust/edit.jsp");

return SUCCESS;

}

客户流失

介绍:此模块为客户流失,分三种状态(已流失,暂缓流失,警告),默认状态为警告,我们可以进行暂缓和流失操作,确认流失之后将不可对其在操作。(查改)

通过状态判断

<s:if test="#list.lstStatus!=">

//考虑此操作都是对信息的修改操作,只是跳转页面不同,我们可以通过参数判断跳转的页面(param)

javascript:window.location.href='cstCustomer_toRelayOrConfirm?param=relay&cstLost.lstId=8

public String toRelayOrConfirm() {

if (this.cstLostBiz.getCl(this.getCstLost().getLstId()) != null) {

this.getRequest().setAttribute("lost",

this.cstLostBiz.getCl(this.getCstLost().getLstId()));}

if (this.param.equals("relay")) {

this.setSuccessResultValue("/html/~cust/lost/relay.jsp");

} else if (this.param.equals("confirm")) {

this.setSuccessResultValue("/html/~cust/lost/confirm.jsp");

}

return SUCCESS;}

其他模块均为普通增删改查操作(省略)

5 结束语

这次我们设计比较正规化,设计之前要开题,开题报告通过才能展开设计。这不仅让我学到如何做好开题报告,也让我主动的分析设计,在展开设计之前就做了很多工作,培养了我的软件设计能力。在开始具体设计以前,我已经完成系统的结构设计,数据库规划等工作,这样以后的设计就事半功倍了。在毕业设计中除了学习了具体的专业知识外,我认为最重要却是让我们建立了软件设计的正确概念。

在这次毕业设计的过程中,我体会到要想开发一个系统软件,不仅需要相当的专业技术知识,还要有严谨缜密的思维能力。只有思想上清晰了,编程才有意义,否则就是白费力气。同时还要善于捕获细小的方面,因为那往往是这个程序的致命因素。这次毕业设计培养了我的细心和耐性,更树立了一种科学的态度。这对我以后的工作和学习也有很大的帮助和指导作用。同时也深刻认识到了本身不存在很多不足之处,还需要不断地学习来充实完善自己,只有这样才能学有所成,求得更大的发展。

通过交流我也感觉到,无论什么方面的编程,学习过程是一样的,都要经过不断的实践积累,不是一蹴而就的。回想这三个月是艰苦的三个月,也是收获的三个月。了解了正确的管理方法,积累了经验。

致谢

首先我要感谢我的指导老师赵老师,在他的督促帮助下我顺利完成了我的毕业设计。在他的指导下,我从头脑混乱到现在整个思路清晰地完成毕业设计,虽然不能说这个我的系统软件有多完善,但这却是我在赵老师的指导下一步一步完成的。在我外出实习期间,赵老师也一直通过QQ、Email来了解我们的设计进度以及在设计中遇到的困难,帮助我们解决我们设计中的难点。在整个设计过程中,他对我们严格要求,按照计划定期检查我们的设计成果,为我们理清整个设计阶段的任务,使我们能够按计划完成设计。

其次我要感谢我们计算机系的领导对我们毕业生的关心和支持,他们不仅要处理系里的一切大小事情,还要像其他老师一样带毕业设计的学生,在这样的情况下,他们还时时关心我们毕业班的学生,根据我们毕业设计的进度,督促老师多跟我们联系,以便指导我们完成毕业设计。所以我衷心的感谢他们。

最后,我要感谢在毕业设计的整个过程中帮助我的所有领导、老师和同学,没有他们的帮助我也不可能完成此次毕业设计。感谢他们给我的各方面的关心和帮助,对指导老师的认真负责的指导再次致以衷心的感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等天晴i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值