900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > SSH企业案例_CRM客户管理系统(三):客户管理联系人管理

SSH企业案例_CRM客户管理系统(三):客户管理联系人管理

时间:2020-08-28 21:30:45

相关推荐

SSH企业案例_CRM客户管理系统(三):客户管理联系人管理

文章目录

1、CRM综合练习:客户管理-保存客户上传客户资质图片文件上传回顾文件上传的代码实现2、CRM综合练习:客户管理-删除客户客户删除操作3、CRM综合练习:客户管理-修改客户客户的修改操作4、CRM综合练习:客户管理-条件查询客户客户管理的条件查询5、CRM综合练习:联系人管理-查询列表联系人准备工作查询联系人列表

1、CRM综合练习:客户管理-保存客户上传客户资质图片

文件上传回顾

什么是文件上传

 将本地文件通过流的形式写到服务器上

文件上传技术

 JspSmartUpload(很少用)

fileupload

 Servlet3.0

 文件上传

 注解开发

 异步请求

Struts2框架

 底层的实现还是FileUpload,对FileUpload进行封装

文件上传要素

 表单的提交方式必须是POST

 表单中需要提供<input type="file" name="upload">并且这个文件项必须有name属性和值

 表单的enctype属性必须是multipart/form-data

文件上传的代码实现

第一步:修改JSP页面(添加)

 提供文件上传项

 修改表单的enctype属性

第二步:编写UpLoadUtils

public class UpLoadUtils {//获得uuid文件名的方法public static String getUploadFileName(String fileName){int idx = fileName.lastIndexOf(".");//aa.txtString extions = fileName.substring(idx);//.txtString uuid = UUID.randomUUID().toString().replace("-", ""); //07d12c2a……fileName = uuid+extions;//全名称return fileName;}//用于目录分离的方法public static String getPath(String uuidFileName){int code1 = uuidFileName.hashCode();int d1 = code1 & 0xf;//作为一级目录,相当于&1111,结果就为d1int code2 = code1 >>> 4;//因为int是4个字节,所以右移4位int d2 = code2 & 0xf;//作为二级目录return "/"+d1+"/"+d2;}//用于测试是否可行public static void main(String[] args) {String file = "aa.txt";int idx = file.lastIndexOf(".");//aa.txtString extions = file.substring(idx);//txtSystem.out.println(extions);//String uuid = UuidUtil.getTimeBasedUuid().toString();String uuid = UUID.randomUUID().toString();file = uuid+extions;System.out.println(uuid);System.out.println(file);}}

第三步:修改Action中的save方法

 Struts2的文件上传

 在Action中提供三个属性,对三个属性提供set方法

 字符串类型上传项名称+FileName

 文件类型上传项名称

 字符串类型上传项名称+ContentType

//页面传递过来的属性private String uploadFileName;//可用准确的拿到页面提交的文件名private File upload;//保存着源文件的代码数据private String uploadContentType;//保存着源文件的编码类型public void setUploadFileName(String uploadFileName) {this.uploadFileName = uploadFileName;}public void setUpload(File upload) {this.upload = upload;}public void setUploadContentType(String uploadContentType) {this.uploadContentType = uploadContentType;}//保存客户的方法public String save() throws IOException{System.out.println("Action中的save方法执行了....");//若web层没有使用struts2,则必须如下编写:/*ServletContext sc = ServletActionContext.getServletContext();WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(sc);CustomerService service = (CustomerService)context.getBean("customerService");*///customerService.save(customer);//上传公司资质文件的部分if(upload!=null){//文件上传//设置文件上传的路径String path = "D:/Study-program/SSH-image";//一个目录下存放的相同文件名:随机文件名uploadFileName = UpLoadUtils.getUploadFileName(uploadFileName);//一个目录下存放的文件过多:目录分离String realPath = UpLoadUtils.getPath(uploadFileName);String url = path+realPath;File dir = new File(url);//绝对路径if(!dir.exists())dir.mkdirs();//创建多级目录//文件上传File file = new File(url+"/"+uploadFileName);FileUtils.copyFile(upload, file);//前是源文件,即网页传过来的文件}return NONE;}

第四步:将文件上传路径存入到数据库中

 修改实体:增加一个属性-cust_image

 修改映射:增加一个属性映射-cust_image

 修改ActionResult:增加一个saveSuccess的result

<result name="saveSuccess" type="redirectAction">customer_findAll</result>

 修改文件上传代码

//页面传递过来的属性private String uploadFileName;//可用准确的拿到页面提交的文件名private File upload;//保存着源文件的代码数据private String uploadContentType;//保存着源文件的编码类型public void setUploadFileName(String uploadFileName) {this.uploadFileName = uploadFileName;}public void setUpload(File upload) {this.upload = upload;}public void setUploadContentType(String uploadContentType) {this.uploadContentType = uploadContentType;}//保存客户的方法publicString save() throws IOException{//上传公司资质文件的部分if(upload!=null){//文件上传//设置文件上传的路径String path = "D:/Study-program/SSH-image";//一个目录下存放的相同文件名:随机文件名uploadFileName = UpLoadUtils.getUploadFileName(uploadFileName);//一个目录下存放的文件过多:目录分离String realPath = UpLoadUtils.getPath(uploadFileName);String url = path+realPath;File dir = new File(url);//绝对路径if(!dir.exists())dir.mkdirs();//创建多级目录//文件上传File file = new File(url+"/"+uploadFileName);customer.setCust_image(url+"/"+uploadFileName);FileUtils.copyFile(upload, file);//前是源文件,即网页传过来的文件}//最后执行保存客户的方法customerService.save(customer);return "saveSuccess";}

对于上传文件的几点扩展

 可以设置一次上传中总的最大的文件大小限制

 可以设置一次上传中每个文件的最大大小限制

 可以设置一次上传中每个文件的文件类型与扩展名

 设置完这些限制之后要写个input视图和页面错误回显,否则页面就崩了

2、CRM综合练习:客户管理-删除客户

客户删除操作

第一步:修改list页面中的删除链接

<a href="${pageContext.request.contextPath }/customer_delete?cust_id=<s:property value="cust_id"/>">删除</a>

第二步:编写Service

@Overridepublic Customer getById(Long cust_id) {return dao.getById(cust_id);}@Overridepublic void delete(Customer customer) {dao.delete(customer);}

第三步:编写Dao

@Overridepublic Customer getById(Long cust_id) {return this.getHibernateTemplate().get(Customer.class, cust_id);}@Overridepublic void delete(Customer customer) {this.getHibernateTemplate().delete(customer);}

第四步:编写Action

//删除客户的方法public String delete(){//调用service中的查找单个客户方法Customer cust = customerService.getById(customer.getCust_id());//先删除客户中保存的资质文件if(cust.getCust_image()!=null){File file = new File(cust.getCust_image());file.delete();}//最后执行删除用户的操作customerService.delete(cust);return "deleteSuccess";}

第五步:配置deleteSuccess的result

<result name="deleteSuccess" type="redirectAction">customer_findAll</result>

3、CRM综合练习:客户管理-修改客户

客户的修改操作

修改list页面的修改链接

<a href="${pageContext.request.contextPath }/customer_edit?cust_id=<s:property value="cust_id"/>">修改</a>

编写Action中的edit方法

//修改客户的方法public String edit(){System.out.println("Action的edit方法被执行了");//调用service中的查找单个客户方法customer = customerService.getById(customer.getCust_id());//将customer传递到页面的两种方式://第一种:回显数据-<s:property value="cust_name"/> <s:textfield name="cust_name"/>//第二种:回显数据-<s:property value="model.cust_name"/> 第二种不用写代码ActionContext.getContext().getValueStack().push(customer);//第一种方式//跳转页面return "editSuccess";}

在页面中回显数据

 普通输入框的回显

<td>客户名称:</td><td><s:hidden name="cust_image"/>//这里一定要有隐藏id<s:hidden name="cust_id"/><s:textfield cssClass="textbox" cssStyle="WIDTH: 180px" maxlength="50" name="cust_name" /></td>......

 下拉列表的回显

<script type="text/javascript">$(function(){/*页面加载函数就会执行页面加载,异步查询字典数据加载客户来源*/$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"002"},function(data){//遍历json的数据$(data).each(function(i,n){$("#cust_source").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");});//利用EL获取到值栈的数据$("#cust_source option[value='${cust_source.dict_id}']").prop("selected","selected");},"json");$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"001"},function(data){$(data).each(function(i,n){$("#cust_industry").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");});$("#cust_industry option[value='${cust_industry.dict_id}']").prop("selected","selected");},"json");$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"006"},function(data){$(data).each(function(i,n){$("#cust_level").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");});$("#cust_level option[value='${cust_level.dict_id}']").prop("selected","selected");},"json");});</script>

修改edit.jsp中的提交路径

<s:form id="form1" name="form1" action="customer_update" namespace="/" method="post" enctype="multipart/form-data" theme="simple">

编写Service

@Overridepublic void update(Customer customer) {dao.update(customer);}

编写Dao

@Overridepublic void update(Customer customer) {this.getHibernateTemplate().update(customer);}

编写Action中的update方法

//修改客户的方法public String update() throws IOException{//文件是否已经选择,若选择了就上传;否则使用原来的if(upload != null){String cust_image = customer.getCust_image();if(cust_image!=null || !"".equals(cust_image)){//删除原有文件File old_file = new File(cust_image);if(old_file.exists())old_file.delete();}//设置文件上传的路径String path = "D:/Study-program/SSH-image";//一个目录下存放的相同文件名:随机文件名uploadFileName = UpLoadUtils.getUploadFileName(uploadFileName);//一个目录下存放的文件过多:目录分离String realPath = UpLoadUtils.getPath(uploadFileName);String url = path+realPath;File dir = new File(url);//绝对路径if(!dir.exists())dir.mkdirs();//创建多级目录//文件上传File file = new File(url+"/"+uploadFileName);FileUtils.copyFile(upload, file);//前是源文件,即网页传过来的文件customer.setCust_image(url+"/"+uploadFileName);}//调用service中的更新客户的方法customerService.update(customer);return "updateSuccess";}

配置struts中的result

<result name="editSuccess">/jsp/customer/add.jsp</result><result name="updateSuccess" type="redirectAction">customer_findAll</result>

小结:

1、文件上传的代码一定要熟练掌握

2、下拉列表的回显,中间套用了ognl

3、theme="simple"即struts2自带表单的样式为空

4、CRM综合练习:客户管理-条件查询客户

客户管理的条件查询

在list页面准备条件

 提供表单元素

<TD>客户名称:</TD><TD><INPUT class=textbox id=sChannel2style="WIDTH: 80px" maxLength=50 name="cust_name"value="<s:property value="cust_name"/>"></TD><TD>客户来源:</TD><TD><select id="cust_source" name="cust_source.dict_id"><option value="">-请选择-</option></select><TD>客户级别:</TD><TD><select id="cust_level" name="cust_level.dict_id"><option value="">-请选择-</option></select></TD><TD>所属行业:</TD><TD><select id="cust_industry" name="cust_industry.dict_id"><option value="">-请选择-</option></select></TD>

 异步加载数据并在条件上回显数据

<script type="text/javascript">$(function(){/*页面加载函数就会执行页面加载,异步查询字典数据加载客户来源*/$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode.action",{"dict_type_code":"002"},function(data){//遍历json的数据$(data).each(function(i,n){$("#cust_source").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");});},"json");$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode.action",{"dict_type_code":"001"},function(data){//遍历json的数据$(data).each(function(i,n){$("#cust_industry").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");});},"json");$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode.action",{"dict_type_code":"006"},function(data){//遍历json的数据$(data).each(function(i,n){$("#cust_level").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");});},"json");});</script>

改写Action中的findAll方法

//分页查询客户的方法public String findAll(){System.out.println("执行了```");//最好使用DetachedCriteria对象(条件查询--带分页)DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);//设置web查询条件if(customer.getCust_name()!=null){criteria.add(Restrictions.like("cust_name", "%"+customer.getCust_name()+"%"));}if(customer.getCust_source()!=null){if(customer.getCust_source().getDict_id()!=null&&!"".equals(customer.getCust_source().getDict_id())){criteria.add(Restrictions.eq("cust_source.dict_id", customer.getCust_source().getDict_id()));}}if(customer.getCust_level()!=null){if(customer.getCust_level().getDict_id()!=null&&!"".equals(customer.getCust_level().getDict_id())){System.out.println(customer.getCust_level().getDict_id());criteria.add(Restrictions.eq("cust_level.dict_id", customer.getCust_level().getDict_id()));}}if(customer.getCust_industry()!=null){if(customer.getCust_industry().getDict_id()!=null&&!"".equals(customer.getCust_industry().getDict_id())){criteria.add(Restrictions.eq("cust_industry.dict_id", customer.getCust_industry().getDict_id()));}}//调用业务层进行查询PageBean<Customer> pageBean = customerService.findAll(criteria, curPage, pageSize);ServletActionContext.getRequest().setAttribute("pageBean", pageBean);System.out.println(pageBean.getPageSize());return "customer_list";}

5、CRM综合练习:联系人管理-查询列表

联系人准备工作

创建表

CREATE TABLE `cst_linkman` (`lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',`lkm_name` varchar(16) DEFAULT NULL COMMENT '联系人姓名',`lkm_cust_id` bigint(32) NOT NULL COMMENT '客户id',`lkm_gender` char(1) DEFAULT NULL COMMENT '联系人性别',`lkm_phone` varchar(16) DEFAULT NULL COMMENT '联系人办公电话',`lkm_mobile` varchar(16) DEFAULT NULL COMMENT '联系人手机',`lkm_email` varchar(64) DEFAULT NULL COMMENT '联系人邮箱',`lkm_qq` varchar(16) DEFAULT NULL COMMENT '联系人qq',`lkm_position` varchar(16) DEFAULT NULL COMMENT '联系人职位',`lkm_memo` varchar(512) DEFAULT NULL COMMENT '联系人备注',PRIMARY KEY (`lkm_id`),KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

创建实体和映射

 实体类的编写

public class LinkMan {private Long lkm_id;private String lkm_name;private String lkm_gender;private String lkm_phone;private String lkm_mobile;private String lkm_email;private String lkm_qq;private String lkm_position;private String lkm_memo;//联系人属于多的一方private Customer customer;}

 映射的配置

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 建立类与表的映射 --><class name="domain.LinkMan" table="cst_linkman"><!-- 主键字段 --><id name="lkm_id" column="lkm_id"><generator class="native"/></id><!-- 普通的属性字段 --><property name="lkm_name"/><property name="lkm_gender"/><property name="lkm_phone"/><property name="lkm_mobile"/><property name="lkm_email"/><property name="lkm_qq"/><property name="lkm_position"/><property name="lkm_memo"/><many-to-one name="customer" class="domain.Customer" column="lkm_cust_id"/><!-- 如果查询时没用到关联对象就不用设置 --></class></hibernate-mapping>

 在Spring中配置映射:加上<value>domain/LinkMan.hbm.xml</value>

创建相关类

 创建Action

 创建Service

 创建Dao

//actionpublic class LinkManAction extends ActionSupport implements ModelDriven<LinkMan>{//模型驱动使用的对象private LinkMan linkMan = new LinkMan();@Overridepublic LinkMan getModel() {return linkMan;}//注入Serviceprivate LinkManService linkManService;public void setLinkManService(LinkManService linkManService) {this.linkManService = linkManService;}}//servicepublic class LinkManServiceImpl implements LinkManService {//注入daoprivate LinkManDao dao;public void setDao(LinkManDao dao) {this.dao = dao;}}//daopublic class LinkManDaoImpl extends HibernateDaoSupport implements LinkManDao {}

配置Spring的dao、service、action、映射

<bean id="linkManService" class="service.serviceImpl.LinkManServiceImpl"><property name="dao" ref="linkManDao"/></bean><bean id="linkManDao" class="dao.daoImpl.LinkManDaoImpl"><property name="sessionFactory" ref="sessionFactory"/></bean><bean id="linkManAction" class="web.action.LinkManAction" scope="prototype"><property name="linkManService" ref="linkManService"/></bean>

查询联系人列表

修改menu.jsp的链接

<TD class=menuSmall><A class=style2 href="${pageContext.request.contextPath}/linkMan_findAll"

编写action

编写service

编写dao

list页面显示联系人信息

<TR><TD><TABLE id=gridstyle="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-LEFT-COLOR: #cccccc; BORDER-BOTTOM-WIDTH: 0px; BORDER-BOTTOM-COLOR: #cccccc; WIDTH: 100%; BORDER-TOP-COLOR: #cccccc; FONT-STYLE: normal; BACKGROUND-COLOR: #cccccc; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none; BORDER-RIGHT-COLOR: #cccccc"cellSpacing=1 cellPadding=2 rules=all border=0><TBODY><TRstyle="FONT-WEIGHT: bold; FONT-STYLE: normal; BACKGROUND-COLOR: #eeeeee; TEXT-DECORATION: none"><TD>联系人名称</TD><TD>性别</TD><TD>办公电话</TD><TD>手机</TD><TD>邮箱</TD><TD>qq</TD><TD>职位</TD><TD>所属客户</TD><TD>操作</TD></TR><s:iterator value="list"><TRstyle="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none"><TD><s:property value="lkm_name"/></TD><TD><s:property value="lkm_gender"/></TD><TD><s:property value="lkm_phone"/></TD><TD><s:property value="lkm_mobile"/></TD><TD><s:property value="lkm_email"/></TD><TD><s:property value="lkm_qq"/></TD><TD><s:property value="lkm_position"/></TD><TD><s:property value="customer.cust_name"/></TD><TD><a href="${pageContext.request.contextPath }/linkmanServlet?method=edit&lkmId=${linkman.lkmId}">修改</a>&nbsp;&nbsp;<a href="${pageContext.request.contextPath }/linkmanServlet?method=delete&lkmId=${linkman.lkmId}">删除</a></TD></TR></s:iterator></TBODY></TABLE></TD></TR><TR><TD><SPAN id=pagelink><DIVstyle="LINE-HEIGHT: 20px; HEIGHT: 20px; TEXT-ALIGN: right">共[<B><s:property value="totalCount"/></B>]条记录,[<B><s:property value="totalPage"/></B>]页,每页显示<select name="pageSize" onchange="to_page()"><option value="3" <s:if test="pageSize==3">selected</s:if>>3</option><option value="5" <s:if test="pageSize==5">selected</s:if>>5</option><option value="10" <s:if test="pageSize==10">selected</s:if>>10</option></select>条<s:if test="curPage!=1">[<A name="curPage" href="javascript:to_page(<s:property value="curPage"/>-1)">前一页</A>]</s:if><B><s:property value="curPage"/></B><s:if test="curPage!=totalPage">[<A name="curPage" href="javascript:to_page(<s:property value="curPage"/>+1)">后一页</A>] </s:if>到<input type="text" size="3" id="page" name="curPage" />页<input type="button" value="Go" onclick="to_page()"/></DIV></SPAN></TD></TR>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。