【Java】Crm-客户管理

Crm-客户管理

客户管理表结构设计

客户信息管理模块表结构

这里主要涉及表:

​ t_customer 客户表、t_customer_contact 客户交往记录表、t_customer_linkman 客户联系人表、t_customer_order 客户订单表、t_order_details 订单详情表

t_customer客户信息表
字段字段类型字段限制字段描述
主键idint(11)自增id主键
khnovarchar(20)可空客户编号
namevarchar(20)可空客户姓名
areavarchar(20)可空客户所属地区
cus_managervarchar(20)可空客户经理
levelvarchar(30)可空客户级别
mydvarchar(30)可空客户满意度
xydvarchar(30)可空客户信用度
addressvarchar(500)可空客户地址
post_codevarchar(50)可空邮编
phonevarchar(20)可空联系电话
faxvarchar(20)可空传真
web_sitevarchar(20)可空网址
yyzzzchvarchar(50)可空营业执照注册号
frvarchar(20)可空法人代表
zczjvarchar(20)可空注册资金
nyyevarchar(20)可空年营业额
khyhvarchar(50)可空开户银行
khzhvarchar(50)可空开户账号
dsdjhvarchar(50)可空地税登记号
gsdjhvarchar(50)可空国税登记号
stateint(11)可空流失状态
is_validint(4)可空有效状态
create_datedatetime可空创建时间
update_datedatetime可空更新时间

t_customer_contact客户交往记录表
字段字段类型字段限制字段描述
主键idint(11)自增id主键
cus_idint(11)可空客户id
contact_timedatetime可空交往时间
addressvarchar(500)可空交往地址
overviewvarchar(100)可空地址
create_datedatetime可空创建时间
update_datedatetime可空更新时间
is_validint(4)可空有效状态

t_customer_linkman客户联系人表
字段字段类型字段限制字段描述
主键idint(11)自增id主键
cus_idint(11)可空客户id
link_namevarchar(20)可空联系人姓名
sexvarchar(20)可空性别
zhiweivarchar(50)可空职位
office_phonevarchar(50)可空办公电话
phonevarchar(20)可空手机号
is_validint(4)可空有效状态
ceate_datedatetime可空创建时间
update_datedatetime可空更新时间

t_customer_order客户订单
字段字段类型字段限制字段描述
主键idint(11)自增id主键
cus_idint(11)可空客户id
order_novarchar(40)可空订单编号
order_datedatetime可空下单时间
addressvarchar(200)可空地址
stateint(11)可空状态
create_datedatetime可空创建时间
update_datedatetime可空更新时间
is_validint(4)可空有效状态

t_order_details订单详情表
字段字段类型字段限制字段描述
主键idint(11)自增id主键
order_idint(11)可空订单id
goods_namevarchar(100)可空商品名称
goods_numint(11)可空商品数量
unitvarchar(20)可空商品单位
pricefloat可空单价
sumfloat可空总金额
is_validint(4)可空有效状态
create_datedatetime可空创建时间
update_datedatetime可空更新时间

客户流失管理模块表结构

【Java】Crm-客户管理

这里主要涉及表有

​ t_customer_loss 客户流失表

​ t_customer_reprieve 客户流失暂缓表

t_customer_loss客户流失表
字段字段类型字段限制字段描述
主键idint(11)自增id主键
cus_novarchar(40)可空客户编号
cus_namevarchar(20)可空客户姓名
cus_managervarchar(20)可空客户经理
last_order_timedate可空最后下单时间
confirm_loss_timedate可空确认流失时间
stateint(11)可空流失状态
loss_reasonvarchar(1000)可空流失原因
is_validtinyint(4)可空有效状态
create_datedatetime可空创建时间
update_datedatetime可空更新时间

t_customer_reprieve客户流失暂缓表
字段字段类型字段限制字段描述
主键idint(11)自增id主键
loss_idint(11)可空流失id
measurevarchar(500)可空措施
is_validtinyint(4)可空有效状态
create_datedatetime可空创建时间
update_datedatetime可空更新时间

客户信息查询后端代码实现

layui 框架通过表格展示后端表数据,数据格式见官网测试数据地址。

CustomerMapper 接口定义与Sql配置

  • CustomerMapper .java

public interface CustomerMapper  extends BaseMapper<Customer,Integer> {

/*

由于考虑到多个模块均涉及多条件查询

这里对于多条件分页查询方法由父接口BaseMapper定义

*/

}

  • CustomerMapper .xml

    <select id="selectByParams" parameterType="com.xxxx.crm.query.CustomerQuery" resultMap="BaseResultMap">

select

<include refid="Base_Column_List"/>

from t_customer

<where>

is_valid=1

<!--

state 流失状态

0 未流失

1 已流失

-->

and state =0

<if test="null !=cusName and cusName !=''">

and name like concat('%',#{cusName},'%')

</if>

<if test="null !=cusNo and cusNo !=''">

and khno =#{cusNo}

</if>

<if test="null !=level and level !=''">

and level =#{level}

</if>

<if test="null !=myd and myd !=''">

and myd =#{myd}

</if>

</where>

</select>

  • CustomerQuery.java

在crm.query 包下创建CustomerQuery.java 查询类,设置查询条件

public class CustomerQuery extends BaseQuery {

private String cusName;

private String cusNo;

private String level;

}

CustomerService 定义

  • CustomerService .java

@Service

public class CustomerService extends BaseService<Customer, Integer> {

/*

由于考虑到多个模块均涉及多条件查询

这里对于多条件分页查询方法由父类BaseService定义并实现

*/

}

  • BaseService.java 分页查询方法定义与实现

    public Map<String, Object> queryByParamsForTable(BaseQuery baseQuery) {

Map<String,Object> result = new HashMap<String,Object>();

PageHelper.startPage(baseQuery.getPage(),baseQuery.getLimit());

PageInfo<T> pageInfo =new PageInfo<T>(selectByParams(baseQuery));

result.put("count",pageInfo.getTotal());

result.put("data",pageInfo.getList());

result.put("code",0);

result.put("msg","");

return result;

}

CustomerController.java

@Controller

@RequestMapping("customer")

public class CustomerController extends BaseController {

@Resource

private CustomerService customerService;

@Resource

private CustomerOrderService orderService;

@RequestMapping("index")

public String index(){

return "customer/customer";

}

@RequestMapping("list")

@ResponseBody

public Map<String,Object> queryCustomersByParams(CustomerQuery customerQuery){

return customerService.queryByParamsForTable(customerQuery);

}

客户信息管理前端核心代码

客户信息管理主页面模板

resources/views/customer目录创建customer.ftl 模块文件,模板内容如下(模板依赖的layui文件由common.ftl 文件提供),layui表格数据展示模板文件实现参考该地址

  • customer.ftl

<!DOCTYPE html>

<html>

<head>

<title>客户管理</title>

<#include "../common.ftl">

</head>

<body class="childrenBody">

<form class="layui-form" >

<blockquote class="layui-elem-quote quoteBox">

<form class="layui-form">

<div class="layui-inline">

<div class="layui-input-inline">

<input type="text" name="name"

class="layui-input

searchVal" placeholder="客户名" />

</div>

<div class="layui-input-inline">

<input type="text" name="khno" class="layui-input

searchVal" placeholder="客户编号" />

</div>

<div class="layui-input-inline">

<select name="level" id="level">

<option value="">请选择...</option>

<option value="战略合作伙伴">战略合作伙伴</option>

<option value="大客户">大客户</option>

<option value="重点开发客户">重点开发客户</option>

</select>

</div>

<a class="layui-btn search_btn" data-type="reload"><i

class="layui-icon"></i> 搜索</a>

</div>

</form>

</blockquote>

<table id="customerList" class="layui-table" lay-filter="customers"></table>

<!--操作-->

<script id="customerListBar" type="text/html">

<a class="layui-btn layui-btn-xs" id="edit" lay-event="edit">编辑</a>

<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>

</script>

</form>

<script type="text/javascript"></script>

</body>

</html>

客户信息管理主页面模板核心js

static/js/customer目录下创建customer.js 文件,初始化layui表格数据,layui表格数据展示模板文件实现参考该地址

  • customer.js

layui.use(['table','layer',"form"],function(){

var layer = parent.layer === undefined ? layui.layer : top.layer,

$ = layui.jquery,

table = layui.table,

form = layui.form;

//客户列表展示

var tableIns = table.render({

elem: '#customerList',

url : ctx+'/customer/list',

cellMinWidth : 95,

page : true,

height : "full-125",

limits : [10,15,20,25],

limit : 10,

toolbar: "#toolbarDemo",

id : "customerListTable",

cols : [[

{type: "checkbox", fixed:"center"},

{field: "id", title:'编号',fixed:"true"},

{field: 'name', title: '客户名',align:"center"},

{field: 'fr', title: '法人', align:'center'},

{field: 'khno', title: '客户编号', align:'center'},

{field: 'area', title: '地区', align:'center'},

{field: 'cusManager', title: '客户经理', align:'center'},

{field: 'myd', title: '满意度', align:'center'},

{field: 'level', title: '客户级别', align:'center'},

{field: 'xyd', title: '信用度', align:'center'},

{field: 'address', title: '详细地址', align:'center'},

{field: 'postCode', title: '邮编', align:'center'},

{field: 'phone', title: '电话', align:'center'},

{field: 'webSite', title: '网站', align:'center'},

{field: 'fax', title: '传真', align:'center'},

{field: 'zczj', title: '注册资金', align:'center'},

{field: 'yyzzzch', title: '营业执照', align:'center'},

{field: 'khyh', title: '开户行', align:'center'},

{field: 'khzh', title: '开户账号', align:'center'},

{field: 'gsdjh', title: '国税', align:'center'},

{field: 'dsdjh', title: '地税', align:'center'},

{field: 'createDate', title: '创建时间', align:'center'},

{field: 'updateDate', title: '更新时间', align:'center'},

{title: '操作', templet:'#customerListBar',fixed:"right",align:"center", minWidth:150}

]]

});

});

客户信息多条件查询事件添加

​ 客户信息数据表格数据展示成功后,接下来考虑添加多条件查询点击事件,这里使用layui表格reload重载基础方法实现,点击这里参考官网介绍。

<script type="text/html" id="toolbarDemo">

<div class="layui-btn-container">

<a class="layui-btn layui-btn-normal addNews_btn" lay-event="add">

<i class="layui-icon"></i>

添加

</a>

<a class="layui-btn layui-btn-normal " lay-event="link">

<i class="layui-icon"></i>

联系人管理

</a>

<a class="layui-btn layui-btn-normal addNews_btn" lay-event="recode">

<i class="layui-icon"></i>

交往记录

</a>

<a class="layui-btn layui-btn-normal addNews_btn" lay-event="order">

<i class="layui-icon"></i>

订单查看

</a>

</div>

</script>

  • customer.js 添加搜索点击事件

    // 多条件搜索

$(".search_btn").on("click",function(){

table.reload("customerListTable",{

page: {

curr: 1 //重新从第 1 页开始

},

where: {

cusName: $("input[name='name']").val(), //客户名

cusNo: $("input[name='khno']").val(), //客户编号

level: $("#level").val() //客户等级

}

})

});

机会数据添加实现思路

/**

* 1.参数校验

* 客户名称 name 非空 不可重复

* phone 联系电话 非空 格式符合规范

* 法人 非空

* 2.默认值设置

* isValid state cteaetDate updadteDate

* khno 系统生成 唯一 (uuid| 时间戳 | 年月日时分秒 雪花算法)

*3.执行添加 判断结果

*/

机会数据添加核心代码

@Transactional(propagation = Propagation.REQUIRED)

public void saveCustomer(Customer customer){

checkParams(customer.getName(),customer.getPhone(),customer.getFr());

AssertUtil.isTrue(null!=customerMapper.queryCustomerByName(customer.getName()),"该客户已存在!");

customer.setIsValid(1);

customer.setState(0);

customer.setCreateDate(new Date());

customer.setUpdateDate(new Date());

String khno = "KH_"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

customer.setKhno(khno);

AssertUtil.isTrue(insertSelective(customer)<1,"客户添加失败!");

}

private void checkParams(String name, String phone, String fr) {

AssertUtil.isTrue(StringUtils.isBlank(name),"请指定客户名称!");

AssertUtil.isTrue(!(PhoneUtil.isMobile(phone)),"手机号格式非法!");

AssertUtil.isTrue(StringUtils.isBlank(fr),"请指定公司法人!");

}

客户管理数据添加后端页面转发&添加方法调用

​ 对于机会数据添加与更新表单页可以实现共享,这里在转发机会数据添加与更新页面时共用一套代码即可(考虑更新时涉及到机会数据显示操作,这里根据机会id查询机会记录并放入到请求域中)。

@RequestMapping("addOrUpdateSaleChancePage")

public String addOrUpdateSaleChancePage(Integer id,Model model){

model.addAttribute("customer",customerService.selectByPrimaryKey(id)) ;

return "customer/add_update";

}

@RequestMapping("save")

@ResponseBody

public ResultInfo saveCustomer(Customer customer){

customerService.saveCustomer(customer);

return success("客户添加成功");

}

客户管理添加前台模板与核心js

客户数据添加工具栏事件

这里对于对话框打开方法代码请参考官网页面

    //头工具栏事件

table.on('toolbar(customers)', function(obj){

var checkStatus = table.checkStatus(obj.config.id);

switch(obj.event){

case "add":

openAddOrUpdateCustomerDialog();

break;

};

});

// 打开添加客户数据页面

function openAddOrUpdateCustomerDialog(id){

var url = ctx+"/customer/addOrUpdateSaleChancePage";

var title="客户管理-添加";

if(id){

url = url+"?id="+id;

title="客户管理-更新";

}

layui.layer.open({

title : title,

type : 2,

area:["700px","500px"],

maxmin:true,

content : url

});

}

add_update.ftl 表单模板文件

views/customer目录下添加add_update.ftl 表单模板

<!DOCTYPE html>

<html>

<head>

<#include "../common.ftl">

</head>

<body class="childrenBody">

<form class="layui-form">

<input name="id" type="hidden" value="${(customer.id)!}"/>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">客户名称</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="name" id="name" lay-verify="required" value="${(customer.name)!}" placeholder="请输入客户名">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">法人</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="fr" id="fr" lay-verify="required" value="${(customer.fr)!}" placeholder="请输入法人">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">区域</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="area" lay-verify="required" value="${(customer.area)!}" placeholder="请输入区域">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">客户经理</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="cusManager" value="${(customer.cusManager)!}" placeholder="请输入客户经理">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">客户级别</label>

<div class="layui-input-block">

<select name="level" id="level">

<option value="" >请选择</option>

<option value="普通客户">普通客户</option>

<option value="重点开发客户" >重点开发客户</option>

<option value="大客户" >大客户</option>

<option value="合作伙伴" >合作伙伴</option>

</select>

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">信用度</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="xyd" value="${(customer.xyd)!}" placeholder="请输入客户信用级别">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">邮编</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="postCode" value="${(customer.postCode)!}" placeholder="请输入客户邮编">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">联系电话</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="phone" value="${(customer.phone)!}" placeholder="请输入客户联系电话">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">客户地址</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="address" value="${(customer.address)!}" placeholder="请输入客户地址">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">传真</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="fax" value="${(customer.fax)!}" placeholder="请输入客户传真">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">网站</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="webSite" value="${(customer.webSite)!}" placeholder="请输入客户网站地址">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">注册资金</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="zczj" value="${(customer.zczj)!}" placeholder="请输入注册资金">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">开户行</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="khyh" value="${(customer.khyh)!}" placeholder="请输入客户开户行">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">开户账号</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="khzh" value="${(customer.khzh)!}" placeholder="请输入开户账号">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">国税</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="gsdjh" value="${(customer.gsdjh)!}" placeholder="请输入国税">

</div>

</div>

<div class="layui-col-xs6">

<label class="layui-form-label">地税</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="dsdjh" value="${(customer.dsdjh)!}" placeholder="请输入地税">

</div>

</div>

</div>

<div class="layui-form-item layui-row">

<div class="layui-col-xs6">

<label class="layui-form-label">年营业额</label>

<div class="layui-input-block">

<input type="text" class="layui-input"

name="nyye" value="${(customer.nyye)!}" placeholder="请输入客户年营业额">

</div>

</div>

</div>

<br/>

<div class="layui-form-item layui-row layui-col-xs12">

<div class="layui-input-block">

<button class="layui-btn layui-btn-lg" lay-submit=""

lay-filter="addOrUpdateCustomer">确认

</button>

<button class="layui-btn layui-btn-lg layui-btn-normal">取消</button>

</div>

</div>

</form>

<script type="text/javascript"></script>

</body>

</html>

add.update.js 文件添加

​ js/customer目录下添加add.update.js 文件,完成机会数据添加与更新表单提交操作

layui.use(['form', 'layer'], function () {

var form = layui.form,

layer = parent.layer === undefined ? layui.layer : top.layer,

$ = layui.jquery;

form.on("submit(addOrUpdateCustomer)", function (data) {

var index = top.layer.msg('数据提交中,请稍候', {icon: 16, time: false, shade: 0.8});

//弹出loading

var url=ctx + "/customer/save";

if($("input[name='id']").val()){

url=ctx + "/customer/update";

}

$.post(url, data.field, function (res) {

if (res.code == 200) {

setTimeout(function () {

top.layer.close(index);

top.layer.msg("操作成功!");

layer.closeAll("iframe");

//刷新父页面

parent.location.reload();

}, 500);

} else {

layer.msg(

res.msg, {

icon: 5

}

);

}

});

return false;

});

});

客户信息数据更新

客户信息数据后端更新

客户信息后端更新实现思路

/**

* 1.参数校验

* 记录存在校验

* 客户名称 name 非空 不可重复

* phone 联系电话 非空 格式符合规范

* 法人 非空

* 2.默认值设置

* updadteDate

*3.执行更新 判断结果

*/

客户信息数据更新核心代码

 @Transactional(propagation = Propagation.REQUIRED)

public void updateCustomer(Customer customer){ AssertUtil.isTrue(null==customer.getId()||null==selectByPrimaryKey(customer.getId()),"待更新记录不存在!");

checkParams(customer.getName(),customer.getPhone(),customer.getFr());

Customer temp =customerMapper.queryCustomerByName(customer.getName());

AssertUtil.isTrue(null !=temp && !(temp.getId().equals(customer.getId())),"该客户已存在!");

customer.setUpdateDate(new Date());

AssertUtil.isTrue(updateByPrimaryKeySelective(customer)<1,"客户更新失败!");

}

客户信息数据更新后端页面转发 & 更新方法调用

这里客户信息数据更新页面视图与添加操作实现视图代码共用。

    @RequestMapping("update")

@ResponseBody

public ResultInfo updateCustomer(Customer customer){

customerService.updateCustomer(customer);

return success("客户更新成功");

}

客户信息数据前端模板与核心js

客户信息数据表格行监听事件添加

  • sale.chance.js

表格添加行监听事件,行监听事件参考这里

 /**

* 行监听

*/

table.on("tool(customers)", function(obj){

var layEvent = obj.event;

if(layEvent === "edit") {

openAddOrUpdateCustomerDialog(obj.data.id);

}

});

// 打开添加客户数据页面

function openAddOrUpdateCustomerDialog(id){

var url = ctx+"/customer/addOrUpdateSaleChancePage";

var title="客户管理-添加";

if(id){

url = url+"?id="+id;

title="客户管理-更新";

}

layui.layer.open({

title : title,

type : 2,

area:["700px","500px"],

maxmin:true,

content : url

});

}

客户信息管理数据删除

客户信息数据后端删除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ErRpREW-1608794638358)(images\image-20200227221545509.png)]

客户信息后端删除核心代码

  • CustomerService.java

@Transactional(propagation = Propagation.REQUIRED)

public void deleteCustomer(Integer cid){

Customer customer= selectByPrimaryKey(cid);

AssertUtil.isTrue(null==cid||null==cid,"待删除记录不存在!");

/**

* 如果客户被删除

* 级联 客户联系人 客户交往记录 客户订单 被删除

*

* 如果客户被删除

* 如果子表存在记录 不支持删除

*/

customer.setIsValid(0);

AssertUtil.isTrue(updateByPrimaryKeySelective(customer)<1,"客户删除失败!");

}

  • CustomerController.java

@RequestMapping("delete")

@ResponseBody

public ResultInfo deleteCustomer(Integer id){

customerService.deleteCustomer(id);

return success("客户删除成功");

}

以上是 【Java】Crm-客户管理 的全部内容, 来源链接: utcz.com/a/88119.html

回到顶部