crm系统 SSH框架 源码

crm系统,SSH框架实现

公网访问地址点我

 

项目源码:这几天查资料时遇到好多收费或者要积分的资源,烦死了,马上考研了,做点好事吧,放一份csdn要积分的,再放一份网盘下载。csdn也骗了200多积分了,还剩160,感觉没啥用了2333333333

积分下载

直接下载

网盘下载  提取码:433z

(注意上传路径写死了,客户列表的资质超链接地址也写死了,修改修改为自己主机上存在的路径,否则上传和查看上传功能不能呢个用  分别在uploadUtils.java和customer的list.jsp的资质处)

运行截图:

随便放两张吧:

crm系统 SSH框架 源码_第1张图片

crm系统 SSH框架 源码_第2张图片

crm系统 SSH框架 源码_第3张图片

下面放出所有源码,方便以后当文档查询


目录

目录结构

com.itheima.dao

BaseDao.java

BaseDaoImpl.java

CustomerDao.java

CustomerDaoImpl.java

DictDao.java

DictDaoImpl.java

LinkmanDao.java

LinkmanDaoImpl.java

UserDao.java

UserDaoImpl.java

VisitDao.java

VisitDaoImpl.java

com.itheima.domain

Customer.java

Dict.java

Linkman.java

PageBean.java

User.java

Visit.java

domainXml

Customer.hbm.xml

Dict.hbm.xml

Linkman.hbm.xml

User.hbm.xml

Visit.hbm.xml

com.itheima.service

CustomerService.java

CustomerServiceImpl.java

DictService.java

DictServiceImpl.java

LinkmanService.java

LinkmanServiceImpl.java

UserService.java

UserServiceImpl.java

VisitService.java

VisitServiceImpl.java

com.itheima.utils

FastJsonUtil.java

MD5Utils.java

UploadUtils.java

com.itheima.web.action

BaseAction.java

CustomerAction.java

DictAction.java

LinkmanAction.java

UserAction.java

VisitAction.java

com.itheima.web.interceptor

UserInterceptor.java

核心xml

applicationContext.xml

struts.xml

web.xml

log4j.properties

JSP

WebContent

index.jsp

login.jsp

regist.jsp

top.jsp

welcome.jsp

/jsp/customer

add.jsp0

edit.jsp0

list.jsp0

/jsp/linkman

add.jsp1

edit.jsp1

list.jsp1

/jsp/totals

sources.jsp

/jsp/visit

add.jsp3

list.jsp3

SQL


 

目录结构

crm系统 SSH框架 源码_第4张图片

com.itheima.dao

BaseDao.java

package com.itheima.dao;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;

import com.itheima.domain.PageBean;

/**
 * 以后所有的dao接口都需要继承BaseDao	接口
 *写成泛型形式,方便动态传入类型
 */
public interface BaseDao {
	
	public void save(T t);
	
	public void delete(T t);
	
	public void update(T t);
	
	public T findById(Long id);
	
	public T findById(String id);//重载id
	
	public List findAll();
	
	public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria);
	
}

BaseDaoImpl.java

package com.itheima.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.itheima.domain.Customer;
import com.itheima.domain.PageBean;

/**
 * 以后所有的DaoImpl都可以继承BaseDaoImpl,那么通用增删改查和分页就可以直接用了
 * @author 寒面银枪
 * 2019年7月6日-下午2:31:22
 */ 
@SuppressWarnings("all")  //忽略所有警告
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao {

	//定义成员属性(为了拿到T的类型 T.class不行报错)
	private Class clazz;
	/*public BaseDaoImpl(Class clazz) {
		this.clazz = clazz;//让子类来传类型   (重写子类无参构造器  daoimpl一般也不会有带参构造器 所以很安全了)
	}//注意此类没有无参构造器了  子类必须自己重写无参构造器了(因为继承不到了)  
		能解决问题 但是很麻烦  每次都要重写无参构造器
	*/
	public BaseDaoImpl() {
		//验证创建子类 父类构造器会自动执行,并且this指的是子类
		//System.out.println("BaseDaoImpl执行了...  "+this.getClass().getSimpleName());
		
		//下面利用反射 一步一步拿到子类继承此父类时注入的泛型T
		
		//1.拿到子类对象
		Class c=this.getClass();
		
		//2.获取到BaseDaoImpl
		Type type = c.getGenericSuperclass();
		
		//将type转换为另一个子类 即可获得泛型
		if(type instanceof ParameterizedType) {//注意ParameterizedType是反射包里的
			ParameterizedType ptype=(ParameterizedType) type;
			//获取Customer
			Type[] types = ptype.getActualTypeArguments();//之所以是数组 因为有的泛型有好多个类型 eg:Map
			this.clazz=(Class) types[0];
		}
		
	}
	
	/**
	 * 添加
	 */
	@Override
	public void save(T t) {
		this.getHibernateTemplate().save(t);		
	}

	/**
	 * 删除
	 */
	@Override
	public void delete(T t) {
		this.getHibernateTemplate().delete(t);		
	}

	/**
	 * 修改
	 */
	@Override
	public void update(T t) {
		this.getHibernateTemplate().update(t);
	}
	
	/**
	 * 通过主键查询
	 */
	@Override
	public T findById(Long id) {
		T t = (T) this.getHibernateTemplate().get(clazz, id);
		return t;
	}

	/**
	 * 通过主键查询
	 */
	@Override
	public T findById(String id) {
		T t = (T) this.getHibernateTemplate().get(clazz, id);
		return t;
	}

	/**
	 * 查询所有数据
	 */
	@Override
	public List findAll() {
		//此时HQL查询最方便			clazz.getSimpleName()拿到类型名
		return (List) this.getHibernateTemplate().find("from "+clazz.getSimpleName());
	}

	/**
	 * 分页查询
	 */
	@Override
	public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria) {
		//创建分页的对象
		PageBean page=new PageBean();
		page.setPageCode(pageCode);
		page.setPageSize(pageSize);
		
		/*hibernate要么用HQL(Hibernate查询语句   要么用QBC 条件查询  好好看QBC条件查询  Hibernate_day04 列了5大类查询)*/
		
		//总记录数
		criteria.setProjection(Projections.rowCount());
		List list = (List) this.getHibernateTemplate().findByCriteria(criteria);
		if(list!=null && list.size()>0) {
			page.setTotalCount(list.get(0).intValue());
		}
		
		criteria.setProjection(null);//一定先清空查询条件   否则默认会发送select count(*) ...语句

		//每页的数据(pageSize条记录)
		List beanList = (List) this.getHibernateTemplate().findByCriteria(criteria, (pageCode-1)*pageSize, pageSize);
		
		page.setBeanList(beanList);
		return page;
	}

}

CustomerDao.java

package com.itheima.dao;

import java.util.List;

import com.itheima.domain.Customer;

public interface CustomerDao extends BaseDao{

	List findBySource();
	
	//接口继承了父接口 父接口里都有这些方法的声明了 就不用在写了
	
	//public void save(Customer customer);

	//public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria);

	//public Customer findById(Long cust_id);

	//public void delete(Customer customer);

	//public void update(Customer customer);

}

CustomerDaoImpl.java

package com.itheima.dao;

import java.util.List;

import com.itheima.domain.Customer;

/**
 * 客户的持久层
 * @author 寒面银枪
 * 2019年7月2日-下午8:22:52
 */											//继承的时候传递了正确的类型就行了
public class CustomerDaoImpl extends BaseDaoImpl implements CustomerDao {

	/*基本的增删改查都不用写了  BaseDaoImpl根据泛型已经都实现了通用的方法 */
	
	/**
	 * 查询对应的来源(网络营销、电话营销分别有几个人)
	 */
	@Override
	public List findBySource() {
		// 定义HQL
		// SELECT * FROM cst_customer c,base_dict d WHERE d.dict_id = c.cust_source
		// 分组查询 SELECT * FROM cst_customer c,base_dict d WHERE d.dict_id = c.cust_source group by d.dict_id
		// 查询内容:SELECT d.dict_item_name,count(*) FROM cst_customer c,base_dict d WHERE d.dict_id = c.cust_source group by d.dict_id
		String hql = "select c.source.dict_item_name,count(*) from Customer c inner join c.source group by c.source";
		// 查询
		return (List) this.getHibernateTemplate().find(hql);
	}


}

DictDao.java

package com.itheima.dao;

import java.util.List;

import com.itheima.domain.Dict;

public interface DictDao {

	List findByCode(String dict_type_code);

}

DictDaoImpl.java

package com.itheima.dao;

import java.util.List;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.itheima.domain.Dict;

public class DictDaoImpl extends HibernateDaoSupport implements DictDao {

	/**
	 * 根据类别代码 查询字典对应项值  eg:006查询所有的客户级别可取的值
	 */
	@Override
	public List findByCode(String dict_type_code) {
		return (List) this.getHibernateTemplate().find("from Dict where dict_type_code = ?", dict_type_code);
	}

}

LinkmanDao.java

package com.itheima.dao;

import com.itheima.domain.Linkman;

/**
 * 联系人模块dao
 * @author 寒面银枪
 * 2019年7月6日-下午6:25:39
 */
public interface LinkmanDao extends BaseDao {

}

LinkmanDaoImpl.java

package com.itheima.dao;

import com.itheima.domain.Linkman;

public class LinkmanDaoImpl extends BaseDaoImpl implements LinkmanDao {
	
}
 

UserDao.java

package com.itheima.dao;

import com.itheima.domain.User;

public interface UserDao {

	User checkCode(String user_code);

	void save(User user);

	User login(User user);

}

UserDaoImpl.java

package com.itheima.dao;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.itheima.domain.User;

/**
 * 持久层:都可以继承HibernateDaoSupport (提供模板  注入sessionFactory即可)
 * @author 寒面银枪
 * 2019年7月3日-下午8:34:43
 */
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

	/**
	 * 通过用户名进行验证
	 */
	@Override
	public User checkCode(String user_code) {
		/*DetachedCriteria criteria=DetachedCriteria.forClass(Use.class);
		criteria.add(Restrictions.eq("user_code",user_code));
		User user=(User) this.getHibernateTemplate().findByCriteria(criteria);
		return user;*/
		List list = (List) this.getHibernateTemplate().find("from User where user_code = ?",user_code);
		if(list!=null && list.size()>0) {
			return list.get(0);
		}
		return null;
		
	}

	/**
	 * 保存用户
	 */
	@Override
	public void save(User user) {
		this.getHibernateTemplate().save(user);
	}

	/**
	 * 用户登录:查询用户
	 * 通过登录名和密码和状态
	 */
	@Override
	public User login(User user) {
		//QBC 按条件查询
		DetachedCriteria criteria=DetachedCriteria.forClass(User.class);
		//拼接条件
		criteria.add(Restrictions.eq("user_code", user.getUser_code()));
		criteria.add(Restrictions.eq("user_password", user.getUser_password()));
		criteria.add(Restrictions.eq("user_state", "1"));//注意直接写1
		//查询
		List list= (List) this.getHibernateTemplate().findByCriteria(criteria);
		if(list!=null&&list.size()>0) {
			return list.get(0);
		}
		return null;
	}
	

}

VisitDao.java

package com.itheima.dao;

import com.itheima.domain.Visit;

public interface VisitDao extends BaseDao{

}

VisitDaoImpl.java

package com.itheima.dao;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.itheima.domain.Visit;

/**
 * 客户拜访的持久层
 * @author 寒面银枪
 * 2019年7月7日-下午2:53:31
 */
@Repository(value="visitDao")
public class VisitDaoImpl extends BaseDaoImpl implements VisitDao {//实现dao别忘了
	
	/*
	 * 注意:注入sessionfactory本来应该在父类BaseDaoImpl中写的  但由于之前都是配置文件方式,不好破坏BaseDaoImpl的结构,就直接在这里写了
	 */
	
	//注入sessionfactory
	/*@Resource(name="sessionFactory")
	private SessionFactory sessionFactory;   
	不行 报错 无法修改HibernateDaoSupprot中的sessionfactory属性进行注解
	原因:父类HibernateDaoSupport的setSessionFacoty方法没有加注解@Autowired或者@Resource spring无法自动注入
		mybatis的setSqlSessionFacoty方法就加了注解 避免了这个麻烦的问题
	*/
	
	@Resource(name="sessionFactory")  //本来就在IOC的配置文件里 不怕,能直接拿到  内存(IOC容器)中有名称为sessionFactory的对象就注入
	public void set2SessionFactory(SessionFactory sessionFactory) {
		//关键 调用父类的set方法注入sessionFactory
		super.setSessionFactory(sessionFactory);
	}
	
	/*//网上号称最简单的方式
	@Autowired  按类型自动装配,只要内存中有sessionFactory对象  显然不如上面按名称注入的好
	public void setMySessionFactory(SessionFactory sessionFactory){  
	    super.setSessionFactory(sessionFactory);  
	}  */
	
}

com.itheima.domain

Customer.java

package com.itheima.domain;

import java.util.HashSet;
import java.util.Set;

import com.alibaba.fastjson.annotation.JSONField;

public class Customer {
	
	private Long cust_id;//客户名称
	private String cust_name;//客户姓名
	private Long cust_user_id;//负责人id
	private Long cust_create_id;//创建人id 这两个暂时不管
	
	/*private String cust_source;//客户来源
	private String cust_industry;//客户所属行业(eg:客户来自于百度  那么行业可以是互联网)
	private String cust_level;//客户级别*/	
	
	private String cust_linkman;//联系人
	private String cust_phone;//固定电话
	private String cust_mobile;//移动电话
	
	//一对多 多方写对象   那么上面普通字段的写法就要注释掉了
	//一:客户来源  多:客户
	private Dict source;	
	//一:客户行业  多:客户
	private Dict industry;
	//一:客户级别  多:客户
	private Dict level;
	
	// 上传文件保存的路径
	private String filepath;
	
	/**
	 * 和联系人配置一对多  (我:百度公司 有多个联系人:CEO、CFO等等...)
	 * 
	 * customer(1)和linkman(多)       同样一方可以不写集合(此处还是写了,为了演示问题) 全部交给有外键的多方去配,有双方有一方维护外键就够了
	  *   客户写了联系人   联系人又写了客户  双方互相包含 真的会出现很多问题,不如不写呢  一方维护就行了呗
	 */
	@JSONField(serialize=false)  //必须禁止set转json 否则就是死循环
	private Set linkmans=new HashSet();
	
	//一方这次似乎真的放弃的 都给多方去维护  不写多方的中间表了
	
	
	public Long getCust_id() {
		return cust_id;
	}
	public void setCust_id(Long cust_id) {
		this.cust_id = cust_id;
	}
	public String getCust_name() {
		return cust_name;
	}
	public void setCust_name(String cust_name) {
		this.cust_name = cust_name;
	}
	public Long getCust_user_id() {
		return cust_user_id;
	}
	public void setCust_user_id(Long cust_user_id) {
		this.cust_user_id = cust_user_id;
	}
	public Long getCust_create_id() {
		return cust_create_id;
	}
	public void setCust_create_id(Long cust_create_id) {
		this.cust_create_id = cust_create_id;
	}
	public String getCust_linkman() {
		return cust_linkman;
	}
	public void setCust_linkman(String cust_linkman) {
		this.cust_linkman = cust_linkman;
	}
	public String getCust_phone() {
		return cust_phone;
	}
	public void setCust_phone(String cust_phone) {
		this.cust_phone = cust_phone;
	}
	public String getCust_mobile() {
		return cust_mobile;
	}
	public void setCust_mobile(String cust_mobile) {
		this.cust_mobile = cust_mobile;
	}
	public Dict getSource() {
		return source;
	}
	public void setSource(Dict source) {
		this.source = source;
	}
	public Dict getIndustry() {
		return industry;
	}
	public void setIndustry(Dict industry) {
		this.industry = industry;
	}
	public Dict getLevel() {
		return level;
	}
	public void setLevel(Dict level) {
		this.level = level;
	}
	public String getFilepath() {
		return filepath;
	}
	public void setFilepath(String filepath) {
		this.filepath = filepath;
	}
	public Set getLinkmans() {
		return linkmans;
	}
	public void setLinkmans(Set linkmans) {
		this.linkmans = linkmans;
	}
		
}

Dict.java

package com.itheima.domain;
/**
 * 数据字典表
 * @author 寒面银枪
 * 2019年7月4日-下午1:52:54
 */
public class Dict {
	/**
	 *   `dict_id` varchar(32) NOT NULL COMMENT '数据字典id(主键)',
  `dict_type_code` varchar(10) NOT NULL COMMENT '数据字典类别代码',
  `dict_type_name` varchar(64) NOT NULL COMMENT '数据字典类别名称',
  `dict_item_name` varchar(64) NOT NULL COMMENT '数据字典项目名称',
  `dict_item_code` varchar(10) DEFAULT NULL COMMENT '数据字典项目(可为空)',
  `dict_sort` int(10) DEFAULT NULL COMMENT '排序字段',
  `dict_enable` char(1) NOT NULL COMMENT '1:使用 0:停用',
  `dict_memo` varchar(64) DEFAULT NULL COMMENT '备注',
	 */
	
	private String dict_id;//主键
	
	private String dict_type_code;//数据字典类别代码	eg:01   			06
	private String dict_type_name;//数据字典类别名称	eg:01客户行业			06客户级别
	private String dict_item_name;//数据字典项目名称	eg:01:教务培训|房地产   06:普通客户|VIP客户
	private String dict_item_code;//数据字典项目(可为空)
	
	private Integer dict_sort;//排序字段
	private String dict_enable;//1:使用 0:停用
	private String dict_memo;//备注
	
	
	//并没有要查字典的需求  也即没有要查譬如某个级别的客户有多少个这种需求  那么就不必在一方这里写set集合了  正好外键一方维护也就够了
	
	
	public String getDict_id() {
		return dict_id;
	}
	public void setDict_id(String dict_id) {
		this.dict_id = dict_id;
	}
	public String getDict_type_code() {
		return dict_type_code;
	}
	public void setDict_type_code(String dict_type_code) {
		this.dict_type_code = dict_type_code;
	}
	public String getDict_type_name() {
		return dict_type_name;
	}
	public void setDict_type_name(String dict_type_name) {
		this.dict_type_name = dict_type_name;
	}
	public String getDict_item_name() {
		return dict_item_name;
	}
	public void setDict_item_name(String dict_item_name) {
		this.dict_item_name = dict_item_name;
	}
	public String getDict_item_code() {
		return dict_item_code;
	}
	public void setDict_item_code(String dict_item_code) {
		this.dict_item_code = dict_item_code;
	}
	public Integer getDict_sort() {
		return dict_sort;
	}
	public void setDict_sort(Integer dict_sort) {
		this.dict_sort = dict_sort;
	}
	public String getDict_enable() {
		return dict_enable;
	}
	public void setDict_enable(String dict_enable) {
		this.dict_enable = dict_enable;
	}
	public String getDict_memo() {
		return dict_memo;
	}
	public void setDict_memo(String dict_memo) {
		this.dict_memo = dict_memo;
	}
}

Linkman.java

package com.itheima.domain;

/**
 * 客户的联系人
 * 多方
 * @author Administrator
 */
public class 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 '联系人备注',
	 */
	
	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;
	
	// 编写一个对象,不要自己new
	private Customer customer;
	
	public Long getLkm_id() {
		return lkm_id;
	}
	public void setLkm_id(Long lkm_id) {
		this.lkm_id = lkm_id;
	}
	public String getLkm_name() {
		return lkm_name;
	}
	public void setLkm_name(String lkm_name) {
		this.lkm_name = lkm_name;
	}
	public String getLkm_gender() {
		return lkm_gender;
	}
	public void setLkm_gender(String lkm_gender) {
		this.lkm_gender = lkm_gender;
	}
	public String getLkm_phone() {
		return lkm_phone;
	}
	public void setLkm_phone(String lkm_phone) {
		this.lkm_phone = lkm_phone;
	}
	public String getLkm_mobile() {
		return lkm_mobile;
	}
	public void setLkm_mobile(String lkm_mobile) {
		this.lkm_mobile = lkm_mobile;
	}
	public String getLkm_email() {
		return lkm_email;
	}
	public void setLkm_email(String lkm_email) {
		this.lkm_email = lkm_email;
	}
	public String getLkm_qq() {
		return lkm_qq;
	}
	public void setLkm_qq(String lkm_qq) {
		this.lkm_qq = lkm_qq;
	}
	public String getLkm_position() {
		return lkm_position;
	}
	public void setLkm_position(String lkm_position) {
		this.lkm_position = lkm_position;
	}
	public String getLkm_memo() {
		return lkm_memo;
	}
	public void setLkm_memo(String lkm_memo) {
		this.lkm_memo = lkm_memo;
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
}

PageBean.java

package com.itheima.domain;

import java.util.List;

/**
 * 分页的JavaBean
 * @author Administrator
 */
public class PageBean {
	
	// 当前页
	private int pageCode;
	
	// 总页数
	// private int totalPage;  //不用属性  直接写方法就够了
	
	// 总记录数(数据库总共多少条记录)
	private int totalCount;
	// 每页显示的记录条数
	private int pageSize;
	// 每页显示的数据
	private List beanList;
	
	public int getPageCode() {
		return pageCode;
	}
	public void setPageCode(int pageCode) {
		this.pageCode = pageCode;
	}
	
	/**
	 * 调用getTotalPage() 获取到总页数
	 * JavaBean的属性规定:totalPage是JavaBean是属性 ${pageBean.totalPage}
	 * @return
	 */
	public int getTotalPage() {
		// 计算
		int totalPage = totalCount / pageSize;
		// 说明整除
		if(totalCount % pageSize == 0){
			return totalPage;
		}else{
			return totalPage + 1;
		}
	}
	
	/*public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}*/
	
	public int getTotalCount() {
		return totalCount;
	}
	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public List getBeanList() {
		return beanList;
	}
	public void setBeanList(List beanList) {
		this.beanList = beanList;
	}
}

User.java

package com.itheima.domain;

/**
  *  用户的模块
 * @author 寒面银枪
 * 2019年7月3日-下午8:09:27
 */
public class User {
	private Long user_id;//主键
	private String user_code;//登录名称
	private String user_name;//用户姓名
	private String user_password;//密码
	private String user_state;//用户状态 1正常 0暂停
	
	public Long getUser_id() {
		return user_id;
	}
	public void setUser_id(Long user_id) {
		this.user_id = user_id;
	}
	public String getUser_code() {
		return user_code;
	}
	public void setUser_code(String user_code) {
		this.user_code = user_code;
	}
	public String getUser_name() {
		return user_name;
	}
	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}
	public String getUser_password() {
		return user_password;
	}
	public void setUser_password(String user_password) {
		this.user_password = user_password;
	}
	public String getUser_state() {
		return user_state;
	}
	public void setUser_state(String user_state) {
		this.user_state = user_state;
	}
	/*写好javaBean立刻想着去写映射*/

}

Visit.java

package com.itheima.domain;

/**
 * 客户拜访的javaBean
 * @author 寒面银枪
 * 2019年7月7日-下午2:14:47
 */
public class 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` VARCHAR(32) DEFAULT NULL COMMENT '拜访时间',
  `visit_interviewee` VARCHAR(32) DEFAULT NULL COMMENT '被拜访人',
  `visit_addr` VARCHAR(128) DEFAULT NULL COMMENT '拜访地点',
  `visit_detail` VARCHAR(256) DEFAULT NULL COMMENT '拜访详情',
  `visit_nexttime` VARCHAR(32) DEFAULT NULL COMMENT '下次拜访时间',
	 */
	private String visit_id;//主键
	private String visit_time;//拜访时间
	private String visit_interviewee;//被拜访的人
	private String visit_addr;//拜访地点
	private String visit_detail;//拜访详情
	private String 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 String getVisit_time() {
		return visit_time;
	}
	public void setVisit_time(String visit_time) {
		this.visit_time = visit_time;
	}
	public String getVisit_interviewee() {
		return visit_interviewee;
	}
	public void setVisit_interviewee(String visit_interviewee) {
		this.visit_interviewee = visit_interviewee;
	}
	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 String getVisit_nexttime() {
		return visit_nexttime;
	}
	public void setVisit_nexttime(String 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;
	}

}

domainXml

Customer.hbm.xml



    

	
	
		
			
		
		
		
		
		
		
		
		
		
		
		
		
		
		 
		
		      
		
		
		
		
		
		
		 
			
			
		
		
	
	
    

Dict.hbm.xml



    

	
	
		
			
			
		
		
		
		
		
		
		
		
		
		
		
	
	
    

Linkman.hbm.xml




	
	
		
			
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	


User.hbm.xml



    

	
	
		
			
		
		
		
		
		
		
		
	
	
    

Visit.hbm.xml




	
	
		
			
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	


com.itheima.service

CustomerService.java

package com.itheima.service;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;

import com.itheima.domain.Customer;
import com.itheima.domain.PageBean;

public interface CustomerService {
	
	public void save(Customer customer);

	public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria);

	public Customer findById(Long cust_id);

	public void delete(Customer customer);

	public void update(Customer customer);

	public List findAll();

	public List findBySource();

}

CustomerServiceImpl.java

package com.itheima.service;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.transaction.annotation.Transactional;

import com.itheima.dao.CustomerDao;
import com.itheima.domain.Customer;
import com.itheima.domain.PageBean;

/**
 * 客户的业务层
 * @author 寒面银枪  
 * 2019年7月2日-下午7:06:18
 */
@Transactional //下面的方法就都有了事务
public class CustomerServiceImpl implements CustomerService {

	private CustomerDao customerDao;
	public void setCustomerDao(CustomerDao customerDao) {
		this.customerDao = customerDao;
	}

	/**
	 * 保存客户
	 */
	public void save(Customer customer) {
		customerDao.save(customer);
	}

	/**
	 * 分页查询
	 */
	@Override
	public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria) {
		return customerDao.findByPage(pageCode,pageSize,criteria);
	}

	/**
	 * 通过主键查询客户
	 */
	@Override
	public Customer findById(Long cust_id) {
		return customerDao.findById(cust_id);
	}

	/**
	 * 删除客户
	 */
	@Override
	public void delete(Customer customer) {
		customerDao.delete(customer);
	}

	/**
	 * 更新客户
	 */
	@Override
	public void update(Customer customer) {
		customerDao.update(customer);
	}

	/**
	 * 查询所有客户
	 */
	@Override
	public List findAll() {
		return customerDao.findAll();
	}

	/**
	 * 统计来源客户的数量
	 */
	@Override
	public List findBySource() {
		return customerDao.findBySource();
	}

}

DictService.java

package com.itheima.service;

import java.util.List;

import com.itheima.domain.Dict;

public interface DictService {

	List findByCode(String dict_type_code);

}

DictServiceImpl.java

package com.itheima.service;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.itheima.dao.DictDao;
import com.itheima.domain.Dict;

/**
 * 字典业务层
 * @author 寒面银枪
 * 2019年7月4日-下午9:16:13
 */
@Transactional
public class DictServiceImpl implements DictService {
	
	private DictDao dictDao;
	public void setDictDao(DictDao dictDao) {
		this.dictDao = dictDao;
	}
	
	/**
	 * 根据类别代码 查询字典对应项值  eg:006查询所有的客户级别可取的值
	 */
	@Override
	public List findByCode(String dict_type_code) {
		return dictDao.findByCode(dict_type_code);
	}
	

}

LinkmanService.java

package com.itheima.service;

import org.hibernate.criterion.DetachedCriteria;

import com.itheima.domain.Linkman;
import com.itheima.domain.PageBean;

public interface LinkmanService {

	PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria);

	void save(Linkman model);

	Linkman findById(Long lkm_id);

	void delete(Linkman model);

	void update(Linkman model);
	
}

LinkmanServiceImpl.java

package com.itheima.service;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.transaction.annotation.Transactional;

import com.itheima.dao.LinkmanDao;
import com.itheima.domain.Linkman;
import com.itheima.domain.PageBean;

@Transactional
public class LinkmanServiceImpl implements LinkmanService {
	
	private LinkmanDao linkmanDao;
	public void setLinkmanDao(LinkmanDao linkmanDao) {
		this.linkmanDao = linkmanDao;
	}
	
	/**
	 * 分页查询
	 * @return 
	 */
	public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria) {
		return (PageBean) linkmanDao.findByPage(pageCode, pageSize, criteria);
	}

	/**
	 * 保存客户(添加记录)
	 */
	@Override
	public void save(Linkman linkman) {
		linkmanDao.save(linkman);
	}

	/**
	 * 根据Id查询联系人
	 */
	@Override
	public Linkman findById(Long lkm_id) {
		return linkmanDao.findById(lkm_id);
	}

	/**
	 * 删除联系人
	 */
	@Override
	public void delete(Linkman linkman) {
		linkmanDao.delete(linkman);
	}

	/**
	 * 修改联系人
	 */
	@Override
	public void update(Linkman linkman) {
		linkmanDao.update(linkman);
	}	
	
	
}

UserService.java

package com.itheima.service;

import com.itheima.domain.User;

public interface UserService {

	User checkCode(String user_code);

	void save(User user);

	User login(User user);

}

UserServiceImpl.java

package com.itheima.service;

import org.springframework.transaction.annotation.Transactional;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;
import com.itheima.utils.MD5Utils;

/**
 * 用户的业务层  (业务层一创建 立刻写注解 配置事务  applicationContext拷贝过来的 事务管理器和事务注解都配好了)
 * @author 寒面银枪
 * 2019年7月3日-下午8:28:00
 */
@Transactional
public class UserServiceImpl implements UserService {
	//事务注解写好 然后就立刻配置service IOC
	
	private UserDao userDao;
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	/**
	 * 通过登录名进行校验
	 */
	@Override
	public User checkCode(String user_code) {
		return userDao.checkCode(user_code);
	}

	/**
	 * 保存用户 ,密码需要加密(导入工具类)   注意不加事务成功不了 是只读缓存 也即必须提交★
	 */
	@Override
	public void save(User user) {
		String pwd=user.getUser_password();
		//给密码加密
		user.setUser_password(MD5Utils.md5(pwd));
		//用户默认1状态
		user.setUser_state("1");
		//调用持久层
		userDao.save(user);
		
	}

	/**
	 * 登录;通过登录名和密码校验
	 * 注意密码先加密,再查询
	 */
	@Override
	public User login(User user) {
		String pwd=user.getUser_password();
		//给密码加密
		user.setUser_password(MD5Utils.md5(pwd));
		return userDao.login(user);//都这么写 方法就有了通用性  保持好习惯
	}
	
	
}

VisitService.java

package com.itheima.service;

import org.hibernate.criterion.DetachedCriteria;

import com.itheima.domain.PageBean;
import com.itheima.domain.Visit;

public interface VisitService {

	PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria);

	void save(Visit model);

}

VisitServiceImpl.java

package com.itheima.service;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.itheima.dao.VisitDao;
import com.itheima.domain.PageBean;
import com.itheima.domain.Visit;

@Service(value="visitService")
@Transactional
public class VisitServiceImpl implements VisitService {
	
	@Resource(name="visitDao")
	private VisitDao visitDao;

	/**
	 * 分页查询
	 */
	@Override
	public PageBean findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria) {
		return visitDao.findByPage(pageCode, pageSize, criteria);
	}

	/**
	 * 保存拜访记录
	 */
	@Override
	public void save(Visit visit) {
		visitDao.save(visit);
		
	}
}

com.itheima.utils

FastJsonUtil.java

package com.itheima.utils;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class FastJsonUtil {
	
	/**
	 * 将对象转成json串
	 * @param object
	 * @return
	 */
	public static String toJSONString(Object object){
		//DisableCircularReferenceDetect来禁止循环引用检测
		return JSON.toJSONString(object,SerializerFeature.DisableCircularReferenceDetect);
	}
	
	/**
	 * 向浏览器写回json
	 */
	public static void write_json(HttpServletResponse response,String jsonString)
	{
		response.setContentType("application/json;utf-8");
		response.setCharacterEncoding("UTF-8");
		try {
			response.getWriter().print(jsonString);
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	
	/**
	 * ajax提交后回调的json字符串
	 * @return
	 */
	public static String ajaxResult(boolean success,String message)
	{
		Map map=new HashMap();
		map.put("success", success);//是否成功
		map.put("message", message);//文本消息
		String json= JSON.toJSONString(map);		
		return json;
	}
	

	/**
	 * JSON串自动加前缀
	 * @param json 原json字符串
	 * @param prefix 前缀
	 * @return 加前缀后的字符串
	 */

	public static String JsonFormatterAddPrefix(String json,String prefix,Map newmap)
	{
		if(newmap == null){
			newmap = new HashMap();
		}
		Map map = (Map) JSON.parse(json);

		for(String key:map.keySet())
		{
			Object object=map.get(key);
			if(isEntity(object)){
				String jsonString = JSON.toJSONString(object);
				JsonFormatterAddPrefix(jsonString,prefix+key+".",newmap);
				
			}else{
				newmap.put(prefix+key, object);
			}
			
		}
		return JSON.toJSONString(newmap);		
	}
	/**
	 * 判断某对象是不是实体
	 * @param object
	 * @return
	 */
	private static boolean isEntity(Object object)
	{
		if(object instanceof String  )
		{
			return false;
		}
		if(object instanceof Integer  )
		{
			return false;
		}
		if(object instanceof Long  )
		{
			return false;
		}
		if(object instanceof java.math.BigDecimal  )
		{
			return false;
		}
		if(object instanceof Date  )
		{
			return false;
		}
		if(object instanceof java.util.Collection )
		{
			return false;
		}
		return true;
		
	}
}

MD5Utils.java

package com.itheima.utils;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {
	/**
	 * 使用md5的算法进行加密
	 */
	public static String md5(String plainText) {
		byte[] secretBytes = null;
		try {
			secretBytes = MessageDigest.getInstance("md5").digest(
					plainText.getBytes());
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException("没有md5这个算法!");
		}
		String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
		// 如果生成数字未满32位,需要前面补0
		for (int i = 0; i < 32 - md5code.length(); i++) {
			md5code = "0" + md5code;
		}
		return md5code;
	}

	public static void main(String[] args) {
		System.out.println(md5("123"));
	}

}

UploadUtils.java

package com.itheima.utils;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import org.apache.commons.io.FileUtils;

public class UploadUtils {
	
	/**
	 * 默认上传路径
	 */
	public static final String UPLOAD_PATH="E:/Tomcat/apache-tomcat-8.5.4/webapps/upload/";
	
	public static String getUUIDName(String filename) {
		//截取后缀名
		String lastName=filename.substring(filename.lastIndexOf("."));
		String firstName=UUID.randomUUID().toString().replace("-", "");
		return firstName+lastName;
	}
	
	/**
	  * 整个下载的完全封装  在联系人里自己做
	 * @param uploadFileName 上传文件名
	 * @param upload		  上传的文件
	 * @throws IOException
	 */
	public static void upload(String uploadFileName,File upload) throws IOException {
		String uuidName = getUUIDName(uploadFileName);
		File destFile=new File(UPLOAD_PATH+uuidName);
		FileUtils.copyFile(upload, destFile);
	}
	
	
	public static void main(String[] args) {
		System.out.println(getUUIDName("girl.jpg"));
	}

}

com.itheima.web.action

BaseAction.java

package com.itheima.web.action;

import java.io.File;
import java.lang.reflect.ParameterizedType;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 抽取Action父类  定义成抽象类最好
 * @author 寒面银枪
 * 2019年7月6日-下午6:38:45
 */
public abstract class BaseAction extends ActionSupport implements ModelDriven{
	
	private static final long serialVersionUID = 1L;
	
	/**
	 * Model的抽取
	 */
	private T model;
	public BaseAction() {//必须要new一个实例 没办法
		try {
			//通过反射获取t真实类型
			ParameterizedType pt=(ParameterizedType) this.getClass().getGenericSuperclass();
			Class clazz= (Class) pt.getActualTypeArguments()[0];
			//反射创建t的实例
			model=clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	public T getModel() {
		return model;
	}
	public void setModel(T model) {
		this.model=model;//封装之后取当前model对象麻烦一点了
	}
	
	
	/**
	 * 分页查询的抽取  注意父类里get方法也要提供了
	 */
	private Integer pageCode=1;
	public void setPageCode(Integer pageCode) {
		if(pageCode==null) pageCode=1;
		this.pageCode = pageCode;
	}
	public Integer getPageCode() {
		return pageCode;
	}
	//每页显示的数据的条数  (如果可以让用户选择,那么就不能写死了)
	private Integer pageSize=2;//默认2条
	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}
	public Integer getPageSize() {
		return pageSize;
	}
	
	/**
	  * 上传下载也可以封装了   (前端file的name属性必须写upload了)
	 */
	private File upload;//要上传的文件  关键是这个麻烦的玩意儿 帮你封装好了 太强了
	private String uploadFileName;//要上传的文件名
	private String uploadContentType;//要上传的文件类型
	public void setUpload(File upload) {
		this.upload = upload;
	}
	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	
	
	/**
	 * 向值栈设置值
	 * 调用值栈对象的set方法 一般应用于集合
	 */
	public void setVs(String key,Object obj) {
		ActionContext.getContext().getValueStack().set(key,obj);
	}
	
	
	/**
	 * 向值栈设置值
	 * 调用值栈对象的push方法  一般应用于对象
	 */
	public void pushVs(Object obj) {
		ActionContext.getContext().getValueStack().push(obj);
	}
	
	
	/**
	 * request、response、session的封装
	 */
	public HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}
	
	public HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}
	
	public HttpSession getSession() {
		return ServletActionContext.getRequest().getSession();
	}
	
	
	//最后自己总结  抽取大框架

}

CustomerAction.java

package com.itheima.web.action;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import com.itheima.domain.Customer;
import com.itheima.domain.Dict;
import com.itheima.domain.PageBean;
import com.itheima.service.CustomerService;
import com.itheima.utils.FastJsonUtil;
import com.itheima.utils.UploadUtils;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.util.ValueStack;

/**
 * 客户的控制层(web层)
 * @author 寒面银枪
 * 2019年7月4日-下午2:45:06
 */
public class CustomerAction extends ActionSupport implements ModelDriven{

	private static final long serialVersionUID = 1L;
	
	/**
	 * 以后除非接收的单个参数使用属性驱动 否则都使用模型驱动封装数据 实现ModelDriven接口
	 * 多简单:实现接口 写一个javaBean属性 接口必须实现的方法内返回对象  即可
	 */
	private Customer customer=new Customer();//必须手动实例化
	//类的属性是由get和set方法决定的 与字段无关  所以Action类有一个属性model
	public Customer getModel() {
		return customer;
	}
	
	//注入service 提供service成员属性
	private CustomerService customerService;
	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}//一旦Action给spring管理  Struts的自动注入就失效了  必须手动注入  既然Action在spring的xml中了  那么多配置一个属性就是了


	/**
	 * 保存客户的方法
	 * @return
	 */
	public String add() {
		System.out.println("web层保存客户...");
		customerService.save(customer);
		return NONE;
	}
	
	//属性驱动的方式封装当前页  默认值是1
	private Integer pageCode=1;
	public void setPageCode(Integer pageCode) {
		if(pageCode==null) pageCode=1;
		this.pageCode = pageCode;
	}
	
	//每页显示的数据的条数  (如果可以让用户选择,那么就不能写死了)
	private Integer pageSize=2;//默认2条
	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}


	/**
	 * 分页查询
	 */
	public String findByPage() {
		//调用service  web层可以提前拼条件了
		DetachedCriteria criteria=DetachedCriteria.forClass(Customer.class);//注意不是写PageBean.class 查询谁写谁
		//条件查询 多加几行拼条件的代码就行了
		//拼接客户名称
		String cust_name = customer.getCust_name();
		if(cust_name!=null&&!cust_name.trim().isEmpty()) {
			criteria.add(Restrictions.like("cust_name", "%"+cust_name+"%"));
		}
		//拼接客户级别
		Dict level = customer.getLevel();
		if(level!=null&&!level.getDict_id().trim().isEmpty()) {
			criteria.add(Restrictions.eq("level.dict_id",level.getDict_id()));//后台也可以直接写level.dict_id  框架就是好啊
		}
		//拼接客户来源
		Dict source = customer.getSource();
		if(source!=null&&!source.getDict_id().trim().isEmpty()) {
			criteria.add(Restrictions.eq("source.dict_id",source.getDict_id()));
		}
		
		//查询  默认不封装条件 就是查询所有
		PageBean page = customerService.findByPage(pageCode,pageSize,criteria);
		//压栈  
		//先获取值栈
		ValueStack vs = ActionContext.getContext().getValueStack();
		//栈顶是map<"page",page>
		vs.set("page", page);
		/**
		 * 若是对象用push方法,因为在栈顶,对象名都可以省略不写最简单
		 * 若是集合用set方法 ,最为方便  list[0].username   jstl:foreach表达式一循环  u.username更简单了
		 */
		return "page";
	}
	
	/**
	   * 初始化到添加的页面
	 * @return
	 */
	public String initAddUI() {
		return "initAddUI";
	}
	
	
	/**
	 * 文件的上传,需要在Action类中提供成员属性,属性的命名是有规则的!!
	 * private File upload;  //类型File固定的  属性名必须和前端的name属性值一模一样    此属性表示要上传的文件
	 * private String uploadFileName; //前一半"upload"是前端的name值 后一半的"FileName"固定  表示上传文件的名称,且不会出现中文乱码
	 * private String uploadContentType;//前一半"upload"是前端的name值 后一半"ContentType"固定  表示上传文件的MIME类型
	 * 最后提供set方法 拦截器就会自动帮你注入值了 多好
	 */
	private File upload;//要上传的文件  关键是这个麻烦的玩意儿 帮你封装好了 太强了
	private String uploadFileName;//要上传的文件名
	private String uploadContentType;//要上传的文件类型
	public void setUpload(File upload) {
		this.upload = upload;
	}
	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	/**
	 * 保存客户的方法
	 * @return
	 * @throws IOException 
	 */
	public String save() throws IOException {
		//处理文件上传
		if(uploadFileName!=null) {
			//说明用户选择了要上传的文件
			/*System.out.println("文件名:"+uploadFileName);
			System.out.println("文件类型:"+uploadContentType);*/
			
			//把名称处理下 获得唯一名称  传入filename为了获取后缀名
			String uuidname=UploadUtils.getUUIDName(uploadFileName);
			
			//把文件上传到"E:\\Tomcat\\apache-tomcat-8.5.4\\webapps\\upload"
			//默认上传路径以静态常量的形式放在上传工具类中了
			//简单方式 新建一个文件 然后将封装的File upload文件copy到此新文件内
			File file=new File(UploadUtils.UPLOAD_PATH+uuidname);//上面加了"//" 此处拼接时就不用加了
			FileUtils.copyFile(upload, file);//导Apache.commons.io包
			
			/*三行可以封装成一行*/
			UploadUtils.upload(uploadFileName, upload);
			
			
			//上传文件路径记录在数据库
			customer.setFilepath(UploadUtils.UPLOAD_PATH+uuidname);
			
			
			//如果一直用这个模板 可以全部封装成工具类 一行代码实现上传  当然3行也不多
		}
		
		customerService.save(customer);
		return "save";
	}
	
	/**
	 * 删除客户
	 */
	public String delete() {
		//删除客户
		//先获取客户上传文件的路径 将客户上传的文件全删了
		customer=customerService.findById(customer.getCust_id());
		//获取上传文件的路径
		String filepath=customer.getFilepath();
		//删除客户
		customerService.delete(customer);
		//再删除文件  很简单
		File file=new File(filepath);//先获取文件
		if(file.exists()) {
			file.delete();
		}
		return "delete";
	}
	
	/**
	 * 跳转到初始修改页面
	 */
	public String initUpdate() {
		customer = customerService.findById(customer.getCust_id());//customer多例的 直接赋给customer没事   一次请求新new一个action
		/*压栈  但是注意 返回值赋给了customer 而customer是setModel方法的返回值 
		也即Action属性  而Action默认压栈 所以customer就在值栈内了,eg: model.cust_name就可以取得客户姓名*/
		return "initUpdate";
	}
	
	/**
	 * 修改客户功能
	 * @return
	 * @throws IOException 
	 */
	public String update() throws IOException {
		//判断是否上传新图片  
		if(uploadFileName!=null) {
			//先删除旧图片
			//上面upload是上传组件file传过来的  下面的旧的路径名是隐藏域传递过来的
			String oldFilepath=customer.getFilepath();
			if(oldFilepath!=null&&!oldFilepath.trim().isEmpty()) {
				//说明旧的文件存在
				File oldfile=new File(oldFilepath);
				 oldfile.delete();
			}
			//上传新图片
			String uuidName = UploadUtils.getUUIDName(uploadFileName);
			File file = new File(UploadUtils.UPLOAD_PATH+uuidName);
			FileUtils.copyFile(upload, file);//这个复制工具类是Apache的
			//把客户新图片的路径更新到数据库
			customer.setFilepath(UploadUtils.UPLOAD_PATH+uuidName);
		}
		//上面的{}内的逻辑应该是原子性的 所以应该封装到service层去做 (万一删完出错了..咋办) 不应该在web层做的  
		//任务 进一步封装上传工具类  封装edit方法 (update方法留着 因为通用)
		
		
		//更新客户的信息就ok了
		customerService.update(customer);
		
		return "update";
	}
	
	/**
	 * 查询所有客户   Adjx请求  不用跳转
	 * @return
	 */
	public String findAll() {
		List list=customerService.findAll();
		//转换成json
		String jsonString = FastJsonUtil.toJSONString(list);
		FastJsonUtil.write_json(ServletActionContext.getResponse(), jsonString);
		return NONE;
	}
	
	/**
	 * 统计来源客户的数量
	 * @return
	 */
	public String findBySource() {
		List list=customerService.findBySource();
		//压栈
		ValueStack vs = ActionContext.getContext().getValueStack();
		//栈顶是map<"page",page>
		vs.set("sourcelist", list);
		return "findBySource";
	}
	
	
}

DictAction.java

package com.itheima.web.action;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.itheima.domain.Dict;
import com.itheima.service.DictService;
import com.itheima.utils.FastJsonUtil;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 字典控制器0
 * @author 寒面银枪
 * 2019年7月4日-下午7:12:59
 */
public class DictAction extends ActionSupport implements ModelDriven{

	private Dict dict=new Dict();
	public Dict getModel() {
		return dict;
	}
	
	private DictService dictService;
	public void setDictService(DictService dictService) {
		this.dictService = dictService;
	}
	
	
	/**
	 * 通过字段的type_code值查询客户级别或者客户来源
	 */
	public String findByCode() {
		//调用业务层去查
		List list = (List)dictService.findByCode(dict.getDict_type_code());
		
		//使用fastJson把list转成json字符串
		String jsonString = FastJsonUtil.toJSONString(list);
		
		//把json字符串写浏览器
		HttpServletResponse response = ServletActionContext.getResponse();
		FastJsonUtil.write_json(response, jsonString);
		return NONE;
	}
	
	

}

LinkmanAction.java

package com.itheima.web.action;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import com.itheima.domain.Customer;
import com.itheima.domain.Linkman;
import com.itheima.domain.PageBean;
import com.itheima.service.LinkmanService;

public class LinkmanAction extends BaseAction{

	private static final long serialVersionUID = 1L;
	
	private LinkmanService linkmanService;
	public void setLinkmanService(LinkmanService linkmanService) {
		this.linkmanService = linkmanService;
	}
	
	/**
	 * 分页查询
	 * @return
	 */
	public String findByPage() {
		//调用业务层分页查询
		DetachedCriteria criteria = DetachedCriteria.forClass(Linkman.class);
		//封装查询条件  "名称"和"所属客户"
		//先获取然后判断null,去空格 ,养成习惯
		String lkm_name = getModel().getLkm_name();
		if(lkm_name!=null&&!lkm_name.trim().isEmpty()) {
			criteria.add(Restrictions.like("lkm_name", "%"+lkm_name+"%"));
		}
		//Long cust_id = getModel().getCustomer().getCust_id();//注意写法
		Customer c = getModel().getCustomer();
		if(c!=null&&c.getCust_id()!=null) {
			criteria.add(Restrictions.eq("customer.cust_id", c.getCust_id()));
		}
		//调用service查询
		PageBean page = linkmanService.findByPage(this.getPageCode(),this.getPageSize(),criteria);
		//压栈
		this.setVs("page", page);
		return "page";
	}
	
	/**
	 * 新增联系人UI
	 */
	public String initAddUI() {
		return "initAddUI";
	}
	
	/**
	 * 新增联系人
	 */
	public String save() {
		linkmanService.save(getModel());
		return "save";
	}
	
	/**
	 * 删除联系人
	 */
	public String delete() {
		//先查再删
		setModel(linkmanService.findById(getModel().getLkm_id()));
		//肯定有 就不判断了
		linkmanService.delete(getModel());
		return "delete";
	}
	
	/**
	 * 修改联系人UI
	 */
	public String initUpdate() {
		setModel(linkmanService.findById(getModel().getLkm_id()));//设置到model的好处 默认压栈
		return "initUpdate";
	}
	
	/**
	 * 修改联系人
	 */
	public String update() {
		linkmanService.update(getModel());
		return "update";
	}

}

UserAction.java

package com.itheima.web.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.itheima.domain.User;
import com.itheima.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 用户的控制器
 * @author 寒面银枪
 * 2019年7月3日-下午8:19:21
 */
public class UserAction extends ActionSupport implements ModelDriven{

	//模型驱动: 实现接口 提供对象属性 实现接口方法内返回对象属性 即可帮你封装数据
	private User user=new User();
	public User getModel() {
		return user;
	}
	
	//Action写好后及时到applicationContext.xml配置-》然后到struts.xml配置
	
	//注入service
	private UserService userService;
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public String regist() {
		userService.save(user);
		return LOGIN;
	}
	
	/**
	 * 通过登录名判断登录名是否存在
	 * @return
	 */
	public String checkCode() { 
		//已经有model了 user对象里也有user_code了 那么肯定也自动封装到user对象里了 直接查即可   json格式,但是框架肯定也能封装 毕竟也是key-value呀
		User u=userService.checkCode(user.getUser_code());
		//获取request对象  用Struts2一个强大的类 ServletActionContext
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/html;charset=UTF-8");
		try {
			//获得输出流
			PrintWriter writer = response.getWriter();
			//判断
			if(u!=null) {
				//登录名被查到了  已经被占用了
				writer.print("no");
			}else {
				//登录名是新的未注册过的
				writer.print("yes");
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return NONE;//adjx不用跳  直接输出流写即可
	}
	
	/**
	 * 登录功能
	 * @return
	 */
	public String login() {
		User existUser = userService.login(user);
		if(user==null) {
			//登录失败
			return LOGIN;
		}else {
			//登录成功
			ServletActionContext.getRequest().getSession().setAttribute("user", existUser);
			return "loginOK";
		}
	}
	
	/**
	 * 安全退出登录
	 */
	public String logOut() {
		ServletActionContext.getRequest().getSession().removeAttribute("user");
		return LOGIN;
	}

}

VisitAction.java

package com.itheima.web.action;

import javax.annotation.Resource;
import javax.annotation.Resources;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.itheima.domain.PageBean;
import com.itheima.domain.User;
import com.itheima.domain.Visit;
import com.itheima.service.VisitService;

/**
 * 客户拜访的控制器
 * @author 寒面银枪
 * 2019年7月7日-下午2:38:30
 */
/*
 下面两行配置等价于
 
*/
@Controller(value="visitAction")
@Scope(value="prototype")
public class VisitAction extends BaseAction{

	private static final long serialVersionUID = -139853886677968072L;

	@Resource(name="visitService")  //按名称注入
	private VisitService visitService;
	
	//条件查询的起止日期
	private String beginDate;
	private String endDate;
	public void setBeginDate(String beginDate) {
		this.beginDate = beginDate;
	}
	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}
	//也提供get方法 方便前台获取值
	public String getBeginDate() {
		return beginDate;
	}
	public String getEndDate() {
		return endDate;
	}
	
	
	/**
	 * 分页查询:
	 * 查询客户的拜访记录,根据用户的主键查询 (客户Customer拜访用户user)
	 * select * from sale_visit where visit_user_id = ?
	 * @return
	 */
	public String findByPage() {
		//先获取当前登录的用户
		User user= (User) getSession().getAttribute("user");
		//判断 虽然..但是养成好习惯呗
		if(user==null) {
			return LOGIN;
		}
		
		
		//查询该用户(其实是公司负责人)下所有拜访记录
		DetachedCriteria criteria=DetachedCriteria.forClass(Visit.class);
		
		//条件查询 筛选条件的拼接
		if(beginDate!=null&&!beginDate.trim().isEmpty()) {
			criteria.add(Restrictions.ge("visit_time", beginDate));
		}
		if(endDate!=null&&!endDate.trim().isEmpty()) {
			criteria.add(Restrictions.le("visit_time", endDate));
		}
		
		//添加查询的其他条件
		criteria.add(Restrictions.eq("user.user_id", user.getUser_id()));
		
		//分页查询
		PageBean page = visitService.findByPage(this.getPageCode(),this.getPageSize(),criteria);
		this.setVs("page", page);
		return "page";
	}
	
	/**
	 * 新增拜访UI
	 * @return
	 */
	public String initSave() {
		return "initSave";
	}
	
	
	/**
	 * 保存拜访记录
	 */
	public String save() {
		//需要查到当前用户 一同存入数据库
		User user= (User) getSession().getAttribute("user");
		if(user==null) {
			return LOGIN;
		}
		getModel().setUser(user);
		
		//保存数据
		visitService.save(getModel());
		
		return "save";
	}

}

com.itheima.web.interceptor

UserInterceptor.java

package com.itheima.web.interceptor;

import org.apache.struts2.ServletActionContext;

import com.itheima.domain.User;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

/**
 * 用户拦截器 过滤没有登录的	
 * 判断用户是否登录
 * 	若登录:执行下一个拦截器
 * 	否则:返回到登录页面(注意有些页面要放行,login和regist)
 * 
 * 继承指定拦截器
 * @author 寒面银枪
 * 2019年7月7日-下午6:02:19
 */
public class UserInterceptor extends MethodFilterInterceptor{

	private static final long serialVersionUID = -733814691331866464L;

	/**
	 * 拦截目标Action方法
	 */
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		//获取session
		User user=(User)ServletActionContext.getRequest().getSession().getAttribute("user");
		if(user==null) {
			return "login";
		}
		//执行下一个拦截器
		return invocation.invoke();
	}
	
}

核心xml

applicationContext.xml



	
	
	
	
		
		
		
		
	
	
	
	
	
	
	
	
	
	 
	 
		
		
		
		
			
				org.hibernate.dialect.MySQLDialect
				true
				true
				update 
			
		
		
		
			
				com/itheima/domain/User.hbm.xml
				com/itheima/domain/Customer.hbm.xml 
				com/itheima/domain/Dict.hbm.xml
				com/itheima/domain/Linkman.hbm.xml
				com/itheima/domain/Visit.hbm.xml
			
		
		
		
	
	
	
	
	
		
		
	
	
	
	
	
	
		
	
	
		
	
	
		
	 
	
	
	
	
		
	
	
		
	
	
		
	
	
	 
	
	
		
	
	
		
	
	
		
	
	
	
	
	
	
	
		
	
	
		
	
	
		
	
	
	


struts.xml







	

	
	
	 

	
	
	
		
			
		
	
		
		
			/login.jsp
		
	
		
		
			
			/jsp/customer/list.jsp
			/jsp/customer/add.jsp
			
			customer_findByPage
			
			/jsp/error.jsp
			customer_findByPage.action
			
			/jsp/customer/edit.jsp
			customer_findByPage.action
			/jsp/totals/sources.jsp
			
			
			
			
			
				
				.jpg,.txt
				
				209715200
			
			
		
		
		
		
			/index.jsp
			
				
				login,regist,checkCode
			
			
		
		
		
		
			
			
		
		
		
		
			/jsp/linkman/list.jsp
			/jsp/linkman/add.jsp
			linkman_findByPage.action
			linkman_findByPage.action
			/jsp/linkman/edit.jsp
			linkman_findByPage.action
			
			
			
			
		
		
		
		
			/jsp/visit/list.jsp
			/jsp/visit/add.jsp
			visit_findByPage.action
			
			
			
			
		
		
	
    


web.xml



	crm_28

	
	
		org.springframework.web.context.ContextLoaderListener
	
	
		contextConfigLocation
		classpath:applicationContext.xml
	

	
	
		OpenSessionInViewFilter
		org.springframework.orm.hibernate5.support.OpenSessionInViewFilter
	
	
		OpenSessionInViewFilter
		/*
	
	

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

	
	
		500
		/jsp/error.jsp
	

	
		login.jsp
	

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

JSP

WebContent

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>



客户关系管理系统 




	
	
		
		
	
	
		<p>This page requires frames, but your browser does not support
			them.</p>
	


login.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>



	
	

	
		
	
	
	



  
登 录 名:
登录密码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>



导航








	
人力资源 -功能菜单

regist.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>



	
	
	
		
	
	
	
	




	
  
登 录 名:
登录密码:
用户姓名:

top.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>



顶部






	
客户关系管理系统v1.0
当前用户:${user.user_name }      修改密码      安全退出

welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>



模板









		

/jsp/customer

add.jsp0

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



添加客户 









	
当前位置:客户管理 > 添加客户
客户名称: 客户级别 :
信息来源 : 联系人:
固定电话 : 移动电话 :
联系地址 : 邮政编码 :
客户传真 : 上传资质 :

edit.jsp0

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



添加客户 











	
	
当前位置:客户管理 > 修改客户
客户名称: 客户级别 :
信息来源 : 联系人:
固定电话 : 移动电话 :
上传资质 :
(未选择保留之前的,选择了会覆盖之前的)

list.jsp0

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



客户列表 









	
当前位置:客户管理 > 客户列表
客户名称: 客户级别: 客户来源:
客户名称 客户级别 客户来源 联系人 电话 手机 操作
${customer.cust_name } ${customer.level.dict_item_name } ${customer.source.dict_item_name } ${customer.cust_linkman } ${customer.cust_phone } ${customer.cust_mobile } 修改    删除
<%@include file="/jsp/page.jsp" %>

/jsp/linkman

add.jsp1

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



添加联系人 









	
当前位置:联系人管理 > 添加联系人
所属客户:
联系人名称: 联系人性别:
联系人办公电话 : 联系人手机 :

edit.jsp1

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



添加联系人 








	
当前位置:联系人管理 > 修改联系人
所属客户:
联系人名称: 联系人性别: checked>男 checked>女
联系人办公电话 : 联系人手机 :

list.jsp1

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



联系人列表 









	
当前位置:联系人管理 > 联系人列表
联系人名称: 所属客户:
联系人名称 所属客户 性别 办公电话 手机 操作
${linkman.lkm_name } ${linkman.customer.cust_name } ${linkman.lkm_phone } ${linkman.lkm_mobile } 修改    删除
<%@include file="/jsp/page.jsp" %>

/jsp/totals

sources.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



统计信息 



<%--  
	高版本的jquery,会使日期控件失效
--%>














	
当前位置:统计管理 > 客户来源统计
客户来源 客户人数
${obj[0]} ${obj[1]}

/jsp/visit

add.jsp3

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



添加客户拜访 















	
当前位置:客户拜访管理 > 添加客户拜访
客户名称: 拜访时间:
被拜访人: 拜访地点:
下次拜访时间 :
拜访详情 :

list.jsp3

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>



添加客户拜访 















	
当前位置:客户拜访管理 > 添加客户拜访
客户名称: 拜访时间:
被拜访人: 拜访地点:
下次拜访时间 :
拜访详情 :

SQL

-- MySQL dump 10.13  Distrib 5.5.49, for Win32 (x86)
--
-- Host: localhost    Database: crm_28
-- ------------------------------------------------------
-- Server version	5.5.49

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `base_dict`
--

DROP TABLE IF EXISTS `base_dict`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_dict` (
  `dict_id` varchar(32) NOT NULL COMMENT '数据字典id(主键)',
  `dict_type_code` varchar(10) NOT NULL COMMENT '数据字典类别代码',
  `dict_type_name` varchar(64) NOT NULL COMMENT '数据字典类别名称',
  `dict_item_name` varchar(64) NOT NULL COMMENT '数据字典项目名称',
  `dict_item_code` varchar(10) DEFAULT NULL COMMENT '数据字典项目(可为空)',
  `dict_sort` int(10) DEFAULT NULL COMMENT '排序字段',
  `dict_enable` char(1) NOT NULL COMMENT '1:使用 0:停用',
  `dict_memo` varchar(64) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`dict_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `base_dict`
--

LOCK TABLES `base_dict` WRITE;
/*!40000 ALTER TABLE `base_dict` DISABLE KEYS */;
INSERT INTO `base_dict` VALUES ('1','001','客户行业','教育培训 ',NULL,1,'1',NULL),('10','003','公司性质','民企',NULL,3,'1',NULL),('12','004','年营业额','1-10万',NULL,1,'1',NULL),('13','004','年营业额','10-20万',NULL,2,'1',NULL),('14','004','年营业额','20-50万',NULL,3,'1',NULL),('15','004','年营业额','50-100万',NULL,4,'1',NULL),('16','004','年营业额','100-500万',NULL,5,'1',NULL),('17','004','年营业额','500-1000万',NULL,6,'1',NULL),('18','005','客户状态','基础客户',NULL,1,'1',NULL),('19','005','客户状态','潜在客户',NULL,2,'1',NULL),('2','001','客户行业','电子商务',NULL,2,'1',NULL),('20','005','客户状态','成功客户',NULL,3,'1',NULL),('21','005','客户状态','无效客户',NULL,4,'1',NULL),('22','006','客户级别','普通客户',NULL,1,'1',NULL),('23','006','客户级别','VIP客户',NULL,2,'1',NULL),('24','007','商机状态','意向客户',NULL,1,'1',NULL),('25','007','商机状态','初步沟通',NULL,2,'1',NULL),('26','007','商机状态','深度沟通',NULL,3,'1',NULL),('27','007','商机状态','签订合同',NULL,4,'1',NULL),('3','001','客户行业','对外贸易',NULL,3,'1',NULL),('30','008','商机类型','新业务',NULL,1,'1',NULL),('31','008','商机类型','现有业务',NULL,2,'1',NULL),('32','009','商机来源','电话营销',NULL,1,'1',NULL),('33','009','商机来源','网络营销',NULL,2,'1',NULL),('34','009','商机来源','推广活动',NULL,3,'1',NULL),('4','001','客户行业','酒店旅游',NULL,4,'1',NULL),('5','001','客户行业','房地产',NULL,5,'1',NULL),('6','002','客户信息来源','电话营销',NULL,1,'1',NULL),('7','002','客户信息来源','网络营销',NULL,2,'1',NULL),('8','003','公司性质','合资',NULL,1,'1',NULL),('9','003','公司性质','国企',NULL,2,'1',NULL);
/*!40000 ALTER TABLE `base_dict` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `cst_customer`
--

DROP TABLE IF EXISTS `cst_customer`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `cst_customer` (
  `cust_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `cust_name` varchar(255) DEFAULT NULL,
  `cust_user_id` bigint(20) DEFAULT NULL,
  `cust_create_id` bigint(20) DEFAULT NULL,
  `cust_source` varchar(255) DEFAULT NULL,
  `cust_industry` varchar(255) DEFAULT NULL,
  `cust_level` varchar(255) DEFAULT NULL,
  `cust_linkman` varchar(255) DEFAULT NULL,
  `cust_phone` varchar(255) DEFAULT NULL,
  `cust_mobile` varchar(255) DEFAULT NULL,
  `filepath` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`cust_id`),
  KEY `FKeh5g36duab8g1h051pdjfwcgd` (`cust_source`),
  KEY `FK2xhr3arwp3tkuae1da4lqv352` (`cust_industry`),
  KEY `FKrty52nvbjg1echf0se39eng49` (`cust_level`),
  CONSTRAINT `FK2xhr3arwp3tkuae1da4lqv352` FOREIGN KEY (`cust_industry`) REFERENCES `base_dict` (`dict_id`),
  CONSTRAINT `FKeh5g36duab8g1h051pdjfwcgd` FOREIGN KEY (`cust_source`) REFERENCES `base_dict` (`dict_id`),
  CONSTRAINT `FKrty52nvbjg1echf0se39eng49` FOREIGN KEY (`cust_level`) REFERENCES `base_dict` (`dict_id`),
  CONSTRAINT `FK_cst_customer_industry` FOREIGN KEY (`cust_industry`) REFERENCES `base_dict` (`dict_id`),
  CONSTRAINT `FK_cst_customer_level` FOREIGN KEY (`cust_level`) REFERENCES `base_dict` (`dict_id`),
  CONSTRAINT `FK_cst_customer_source` FOREIGN KEY (`cust_source`) REFERENCES `base_dict` (`dict_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `cst_customer`
--

LOCK TABLES `cst_customer` WRITE;
/*!40000 ALTER TABLE `cst_customer` DISABLE KEYS */;
INSERT INTO `cst_customer` VALUES (1,'百度公司',NULL,NULL,'6',NULL,'22','','111','111',''),(2,'阿里巴巴',NULL,NULL,'7','3','23',NULL,'120','123',NULL),(3,'九州散人',NULL,NULL,'6','4','23',NULL,'119','110',NULL),(4,'太清真人',NULL,NULL,'7','3','22',NULL,'130','114',NULL),(5,'小明',NULL,NULL,'6','5','23',NULL,'145','002',NULL),(6,'小王',NULL,NULL,'6','4','22',NULL,'110','110',NULL),(7,'小李',NULL,NULL,'7','5','23',NULL,'119','119',NULL),(8,'崔浩',NULL,NULL,'6',NULL,'22','天河','110','13956484521',NULL),(12,'浩哥',NULL,NULL,'7',NULL,'23','天河','110','13956484521','E:/Tomcat/apache-tomcat-8.5.4/webapps/upload/67077f083c8d4f169cbeb9019aaef75a.jpg');
/*!40000 ALTER TABLE `cst_customer` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `cst_linkman`
--

DROP TABLE IF EXISTS `cst_linkman`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
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 `FKh9yp1nql5227xxcopuxqx2e7q` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`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=9 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `cst_linkman`
--

LOCK TABLES `cst_linkman` WRITE;
/*!40000 ALTER TABLE `cst_linkman` DISABLE KEYS */;
INSERT INTO `cst_linkman` VALUES (3,'张思',1,'1','120',NULL,NULL,NULL,NULL,NULL),(5,'张三',1,'1','7489','4564',NULL,NULL,NULL,NULL),(6,'李四',2,'2','146','4154',NULL,NULL,NULL,NULL),(7,'马云',2,'1','110','120',NULL,NULL,NULL,NULL),(8,'崔浩',4,'2','456','789',NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `cst_linkman` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `sale_visit`
--

DROP TABLE IF EXISTS `sale_visit`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
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` varchar(32) DEFAULT NULL COMMENT '拜访时间',
  `visit_interviewee` varchar(32) DEFAULT NULL COMMENT '被拜访人',
  `visit_addr` varchar(128) DEFAULT NULL COMMENT '拜访地点',
  `visit_detail` varchar(256) DEFAULT NULL COMMENT '拜访详情',
  `visit_nexttime` varchar(32) 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 `FKc92iepd26mixxfiris92hccjx` FOREIGN KEY (`visit_user_id`) REFERENCES `sys_user` (`user_id`),
  CONSTRAINT `FKgr4aivocixwcvkwxcmc0b4css` FOREIGN KEY (`visit_cust_id`) REFERENCES `cst_customer` (`cust_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;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `sale_visit`
--

LOCK TABLES `sale_visit` WRITE;
/*!40000 ALTER TABLE `sale_visit` DISABLE KEYS */;
INSERT INTO `sale_visit` VALUES ('297e73ba6bcb89de016bcb8bf3b30000',1,3,'2019-07-03','韩菱纱','淮南王陵','头打爆','2019-07-27'),('297e73ba6bcb89de016bcb8d7d260001',4,3,'2019-07-18','慕容紫英','琼华派','腿打折','2019-07-27'),('297e73ba6bcb89de016bcb8ef0fe0002',6,4,'2019-07-12','韩竹安','青鸾峰','生意谈成','2019-08-08'),('297e73ba6bcb89de016bcb8ffcf00003',8,4,'2019-07-09','韩竹安','琼华派','扯淡','2019-07-25');
/*!40000 ALTER TABLE `sale_visit` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `sys_user`
--

DROP TABLE IF EXISTS `sys_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sys_user` (
  `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_code` varchar(32) NOT NULL COMMENT '用户账号',
  `user_name` varchar(64) NOT NULL COMMENT '用户名称',
  `user_password` varchar(32) NOT NULL COMMENT '用户密码',
  `user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `sys_user`
--

LOCK TABLES `sys_user` WRITE;
/*!40000 ALTER TABLE `sys_user` DISABLE KEYS */;
INSERT INTO `sys_user` VALUES (1,'admin','管理员','admin','1'),(2,'寒面银枪','韩竹安','202cb962ac59075b964b07152d234b70','1'),(3,'hza','韩竹安','202cb962ac59075b964b07152d234b70','1'),(4,'hanzhuan','寒面银枪','202cb962ac59075b964b07152d234b70','1');
/*!40000 ALTER TABLE `sys_user` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2019-07-07 21:38:14

 

你可能感兴趣的:(后端框架-SSH,#,SSH实战)