SSH企业案例_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.txt
		String extions = fileName.substring(idx);	//.txt
		String 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,结果就为d1
		int 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.txt
		String extions = file.substring(idx);	//txt
		System.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

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

第三步:编写Dao

@Override
public Customer getById(Long cust_id) {
	return this.getHibernateTemplate().get(Customer.class, cust_id);
}
@Override
public 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

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

编写Dao

@Override
public 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=sChannel2
	style="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"
    "http://www.hibernate.org/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

//action
public class LinkManAction extends ActionSupport implements ModelDriven<LinkMan>{
	//模型驱动使用的对象
	private LinkMan linkMan = new LinkMan();
	@Override
	public LinkMan getModel() {
		return linkMan;
	}
	//注入Service
	private LinkManService linkManService;
	public void setLinkManService(LinkManService linkManService) {
		this.linkManService = linkManService;
	}
}
//service
public class LinkManServiceImpl implements LinkManService {
	//注入dao
	private LinkManDao dao;
	public void setDao(LinkManDao dao) {
		this.dao = dao;
	}
}
//dao
public 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
action1
编写service
service1
编写dao
dao1
list页面显示联系人信息

<TR>
	<TD>
		<TABLE id=grid
			style="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>
				<TR
					style="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">
					<TR
						style="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>
			<DIV
				style="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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hillain

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

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

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

打赏作者

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

抵扣说明:

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

余额充值