旧颜。
楼主
发布于 2023-5-28 18:00:45
阅读 2280
查看全部
CRM-客户管理
学习目的
客户管理表构造设计
客户信息管理模块表构造
这里主要涉及表:
t_customer 客户表、t_customer_contact 客户交往记录表、t_customer_linkman 客户联络人表、t_customer_order 客户订单表、t_order_details 订单详情表
t_customer | 客户信息表 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | khno | varchar(20) | 可空 | 客户编号 | name | varchar(20) | 可空 | 客户姓名 | area | varchar(20) | 可空 | 客户所属地区 | cus_manager | varchar(20) | 可空 | 客户经理 | level | varchar(30) | 可空 | 客户级别 | myd | varchar(30) | 可空 | 客户满意度 | xyd | varchar(30) | 可空 | 客户信誉度 | address | varchar(500) | 可空 | 客户地址 | post_code | varchar(50) | 可空 | 邮编 | phone | varchar(20) | 可空 | 联络电话 | fax | varchar(20) | 可空 | 传真 | web_site | varchar(20) | 可空 | 网址 | yyzzzch | varchar(50) | 可空 | 营业执照注册号 | fr | varchar(20) | 可空 | 法人代表 | zczj | varchar(20) | 可空 | 注册资金 | nyye | varchar(20) | 可空 | 年营业额 | khyh | varchar(50) | 可空 | 开户银行 | khzh | varchar(50) | 可空 | 开户账号 | dsdjh | varchar(50) | 可空 | 地税登记号 | gsdjh | varchar(50) | 可空 | 国税登记号 | state | int(11) | 可空 | 流失状态 | is_valid | int(4) | 可空 | 有效状态 | create_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 |
t_customer_contact | 客户交往记录表 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | cus_id | int(11) | 可空 | 客户id | contact_time | datetime | 可空 | 交往时间 | address | varchar(500) | 可空 | 交往地址 | overview | varchar(100) | 可空 | 地址 | create_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 | is_valid | int(4) | 可空 | 有效状态 |
t_customer_linkman | 客户联络人表 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | cus_id | int(11) | 可空 | 客户id | link_name | varchar(20) | 可空 | 联络人姓名 | sex | varchar(20) | 可空 | 性别 | zhiwei | varchar(50) | 可空 | 职位 | office_phone | varchar(50) | 可空 | 办公电话 | phone | varchar(20) | 可空 | 手机号 | is_valid | int(4) | 可空 | 有效状态 | ceate_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 |
t_customer_order | 客户订单 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | cus_id | int(11) | 可空 | 客户id | order_no | varchar(40) | 可空 | 订单编号 | order_date | datetime | 可空 | 下单时间 | address | varchar(200) | 可空 | 地址 | state | int(11) | 可空 | 状态 | create_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 | is_valid | int(4) | 可空 | 有效状态 |
t_order_details | 订单详情表 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | order_id | int(11) | 可空 | 订单id | goods_name | varchar(100) | 可空 | 商品名称 | goods_num | int(11) | 可空 | 商品数量 | unit | varchar(20) | 可空 | 商品单位 | price | flOAt | 可空 | 单价 | sum | float | 可空 | 总金额 | is_valid | int(4) | 可空 | 有效状态 | create_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 | 客户流失管理模块表构造
这里主要涉及表有
t_customer_loss 客户流失表
t_customer_reprieve 客户流失暂缓表
t_customer_loss | 客户流失表 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | cus_no | varchar(40) | 可空 | 客户编号 | cus_name | varchar(20) | 可空 | 客户姓名 | cus_manager | varchar(20) | 可空 | 客户经理 | last_order_time | date | 可空 | 最后下单时间 | confirm_loss_time | date | 可空 | 确认流失时间 | state | int(11) | 可空 | 流失状态 | loss_reason | varchar(1000) | 可空 | 流失原因 | is_valid | tinyint(4) | 可空 | 有效状态 | create_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 |
t_customer_reprieve | 客户流失暂缓表 | 字段 | 字段类型 | 字段限制 | 字段描绘 | 主键 | id | int(11) | 自增 | id主键 | loss_id | int(11) | 可空 | 流失id | measure | varchar(500) | 可空 | 措施 | is_valid | tinyint(4) | 可空 | 有效状态 | create_date | datetime | 可空 | 创建时间 | update_date | datetime | 可空 | 更新时间 | 客户信息管理模块实现
客户信息管理查询
客户信息管理页面效果
客户信息查询后端代码实现
layui 框架通过表格展示后端表数据,数据格式见官网测试数据地址。
CustomerMapper 接口定义与Sql配置
- publicinterfaceCustomerMapperextendsBaseMapper<Customer,Integer>{/*
- 由于考虑到多个模块均涉及多条件查询
- 这里对于多条件分页查询方法由父接口BaseMapper定义
- */}
复制代码- <selectid="selectByParams"parameterType="com.xxxx.crm.query.CustomerQuery"resultMap="BaseResultMap">
- select
- <includerefid="Base_Column_List"/>
- from t_customer
- <where>
- is_valid=1
- <!--
- state 流失状态
- 0 未流失
- 1 已流失
- -->
- and state =0
- <iftest="null !=cusName and cusName !=''">
- and name like concat('%',#{cusName},'%')
- </if><iftest="null !=cusNo and cusNo !=''">
- and khno =#{cusNo}
- </if><iftest="null !=level and level !=''">
- and level =#{level}
- </if><iftest="null !=myd and myd !=''">
- and myd =#{myd}
- </if></where></select>
复制代码 在crm.query 包下创建CustomerQuery.java 查询类,设置查询条件- publicclassCustomerQueryextendsBaseQuery{private String cusName;private String cusNo;private String level;}
复制代码 CustomerService 定义
- @ServicepublicclassCustomerServiceextendsBaseService<Customer, Integer>{/*
- 由于考虑到多个模块均涉及多条件查询
- 这里对于多条件分页查询方法由父类BaseService定义并实现
- */}
复制代码BaseService.java 分页查询方法定义与实现
- public Map<String, Object>queryByParamsForTable(BaseQuery baseQuery){
- Map<String,Object> result =newHashMap<String,Object>();
- PageHelper.startPage(baseQuery.getPage(),baseQuery.getLimit());
- PageInfo<T> pageInfo =newPageInfo<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")publicclassCustomerControllerextendsBaseController{@Resourceprivate CustomerService customerService;@Resourceprivate CustomerOrderService orderService;@RequestMapping("index")public String index(){return"customer/customer";}@RequestMapping("list")@ResponseBodypublic Map<String,Object>queryCustomersByParams(CustomerQuery customerQuery){return customerService.queryByParamsForTable(customerQuery);}
复制代码 客户信息管理前端核心代码
客户信息管理主页面模板
resources/views/customer目录创建customer.ftl 模块文件,模板内容如下(模板依赖的layui文件由common.ftl 文件提供),layui表格数据展示模板文件实现参考该地址
- <!DOCTYPE html><html><head><title>客户管理</title>
- <#include "../common.ftl">
- </head><bodyclass="childrenBody"><formclass="layui-form"><blockquoteclass="layui-elem-quote quoteBox"><formclass="layui-form"><divclass="layui-inline"><divclass="layui-input-inline"><inputtype="text"name="name"class="layui-input
- searchVal"placeholder="客户名"/></div><divclass="layui-input-inline"><inputtype="text"name="khno"class="layui-input
- searchVal"placeholder="客户编号"/></div><divclass="layui-input-inline"><selectname="level"id="level"><optionvalue="">请选择...</option><optionvalue="战略合作伙伴">战略合作伙伴</option><optionvalue="大客户">大客户</option><optionvalue="重点开发客户">重点开发客户</option></select></div><aclass="layui-btn search_btn"data-type="reload"><iclass="layui-icon"></i> 搜索</a></div></form></blockquote><tableid="customerList"class="layui-table"lay-filter="customers"></table><!--操作--><scriptid="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><scripttype="text/javascript"src="${ctx}/static/js/customer/customer.js"></script></body></html>
复制代码 客户信息管理主页面模板核心js
static/js/customer目录下创建customer.js 文件,初始化layui表格数据,layui表格数据展示模板文件实现参考该地址
- 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重载根底方法实现,点击这里参考官网介绍。- <scripttype="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>
复制代码- // 多条件搜索$(".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)publicvoidsaveCustomer(Customer customer){checkParams(customer.getName(),customer.getPhone(),customer.getFr());
- AssertUtil.isTrue(null!=customerMapper.queryCustomerByName(customer.getName()),"该客户已存在!");
- customer.setIsValid(1);
- customer.setState(0);
- customer.setCreateDate(newDate());
- customer.setUpdateDate(newDate());
- String khno ="KH_"+newSimpleDateFormat("yyyyMMddHHmmss").format(newDate());
- customer.setKhno(khno);
- AssertUtil.isTrue(insertSelective(customer)<1,"客户添加失败!");}privatevoidcheckParams(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")@ResponseBodypublic ResultInfo saveCustomer(Customer customer){
- customerService.saveCustomer(customer);returnsuccess("客户添加胜利");}
复制代码 客户管理添加前台模板与核心js
客户数据添加工具栏事件
这里对于对话框翻开方法代码请参考官网页面- //头工具栏事件
- table.on('toolbar(customers)',function(obj){var checkStatus = table.checkStatus(obj.config.id);switch(obj.event){case"add":openAddOrUpdateCustomerDialog();break;};});// 翻开添加客户数据页面functionopenAddOrUpdateCustomerDialog(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><bodyclass="childrenBody"><formclass="layui-form"style="width:80%;"><inputname="id"type="hidden"value="${(customer.id)!}"/><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">客户名称</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="name"id="name"lay-verify="required"value="${(customer.name)!}"placeholder="请输入客户名"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">法人</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="fr"id="fr"lay-verify="required"value="${(customer.fr)!}"placeholder="请输入法人"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">区域</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="area"lay-verify="required"value="${(customer.area)!}"placeholder="请输入区域"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">客户经理</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="cusManager"value="${(customer.cusManager)!}"placeholder="请输入客户经理"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">客户级别</label><divclass="layui-input-block"><selectname="level"id="level"><optionvalue="">请选择</option><optionvalue="普通客户">普通客户</option><optionvalue="重点开发客户">重点开发客户</option><optionvalue="大客户">大客户</option><optionvalue="合作伙伴">合作伙伴</option></select></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">信誉度</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="xyd"value="${(customer.xyd)!}"placeholder="请输入客户信誉级别"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">邮编</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="postCode"value="${(customer.postCode)!}"placeholder="请输入客户邮编"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">联络电话</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="phone"value="${(customer.phone)!}"placeholder="请输入客户联络电话"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">客户地址</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="address"value="${(customer.address)!}"placeholder="请输入客户地址"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">传真</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="fax"value="${(customer.fax)!}"placeholder="请输入客户传真"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">网站</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="webSite"value="${(customer.webSite)!}"placeholder="请输入客户网站地址"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">注册资金</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="zczj"value="${(customer.zczj)!}"placeholder="请输入注册资金"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">开户行</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="khyh"value="${(customer.khyh)!}"placeholder="请输入客户开户行"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">开户账号</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="khzh"value="${(customer.khzh)!}"placeholder="请输入开户账号"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">国税</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="gsdjh"value="${(customer.gsdjh)!}"placeholder="请输入国税"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">地税</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="dsdjh"value="${(customer.dsdjh)!}"placeholder="请输入地税"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">年营业额</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="nyye"value="${(customer.nyye)!}"placeholder="请输入客户年营业额"></div></div></div><br/><divclass="layui-form-item layui-row layui-col-xs12"><divclass="layui-input-block"><buttonclass="layui-btn layui-btn-lg"lay-submit=""lay-filter="addOrUpdateCustomer">确认
- </button><buttonclass="layui-btn layui-btn-lg layui-btn-normal">取消</button></div></div></form><scripttype="text/javascript"src="${ctx}/static/js/customer/add.update.js"></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});//弹出loadingvar 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});}});returnfalse;});});
复制代码 客户信息数据更新
客户信息数据后端更新
客户信息后端更新实现思路
- /**
- * 1.参数校验
- * 记录存在校验
- * 客户名称 name 非空 不可反复
- * phone 联络电话 非空 格式符合规范
- * 法人 非空
- * 2.默认值设置
- * updadteDate
- *3.执行更新 判断结果
- */
复制代码 客户信息数据更新核心代码
- @Transactional(propagation = Propagation.REQUIRED)publicvoidupdateCustomer(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(newDate());
- AssertUtil.isTrue(updateByPrimaryKeySelective(customer)<1,"客户更新失败!");}
复制代码 客户信息数据更新后端页面转发 & 更新方法调用
这里客户信息数据更新页面视图与添加操作实现视图代码共用。- @RequestMapping("update")@ResponseBodypublic ResultInfo updateCustomer(Customer customer){
- customerService.updateCustomer(customer);returnsuccess("客户更新胜利");}
复制代码 客户信息数据前端模板与核心js
客户信息数据表格行监听事件添加
表格添加行监听事件,行监听事件参考这里- /**
- * 行监听
- */
- table.on("tool(customers)",function(obj){var layEvent = obj.event;if(layEvent ==="edit"){openAddOrUpdateCustomerDialog(obj.data.id);}});// 翻开添加客户数据页面functionopenAddOrUpdateCustomerDialog(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-EEjdZB6v-1612166184684)(images\image-20200227221545509.png)]
客户信息后端删除核心代码
- @Transactional(propagation = Propagation.REQUIRED)publicvoiddeleteCustomer(Integer cid){
- Customer customer=selectByPrimaryKey(cid);
- AssertUtil.isTrue(null==cid||null==cid,"待删除记录不存在!");/**
- * 假设客户被删除
- * 级联 客户联络人 客户交往记录 客户订单 被删除
- *
- * 假设客户被删除
- * 假设子表存在记录 不支持删除
- */
- customer.setIsValid(0);
- AssertUtil.isTrue(updateByPrimaryKeySelective(customer)<1,"客户删除失败!");}
复制代码- @RequestMapping("delete")@ResponseBodypublic ResultInfo deleteCustomer(Integer id){
- customerService.deleteCustomer(id);returnsuccess("客户删除胜利");}
复制代码 客户信息删除前端核心js
行监听添加删除事件- /**
- * 行监听
- */
- table.on("tool(customers)",function(obj){var layEvent = obj.event;if(layEvent ==="edit"){openAddOrUpdateCustomerDialog(obj.data.id);}elseif(layEvent ==="del"){
- layer.confirm('确定删除当前数据?',{icon:3, title:"客户管理"},function(index){
- $.post(ctx+"/customer/delete",{id:obj.data.id},function(data){if(data.code==200){
- layer.msg("操作胜利!");
- tableIns.reload();}else{
- layer.msg(data.msg,{icon:5});}});})}});
复制代码 客户订单查看
客户订单数据查询
客户订单页面效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保管下来直接上传(img-rPYIee2m-1612166184685)(images\image-20200227222856436.png)]
客户订单展示前端js 事件添加
当点击订单查看时,此时添加客户信息表头工具栏事件- //头工具栏事件
- table.on('toolbar(customers)',function(obj){var checkStatus = table.checkStatus(obj.config.id);switch(obj.event){case"add":openAddOrUpdateCustomerDialog();break;case"order":openOrderInfoDialog(checkStatus.data);break;};});// 翻开订单查看页面functionopenOrderInfoDialog(datas){if(datas.length==0){
- layer.msg("请选择待查看订单对应客户!",{icon:5});return;}if(datas.length>1){
- layer.msg("暂不支持批量查看!",{icon:5});return;}var url = ctx+"/customer/orderInfoPage?cid="+datas[0].id;
- layui.layer.open({
- title :"客户管理-订单信息展示",
- type :2,
- area:["700px","500px"],
- maxmin:true,
- content : url
- });}
复制代码- @RequestMapping("orderInfoPage")public String showOrderInfo(Integer cid, Model model){
- model.addAttribute("customer",customerService.selectByPrimaryKey(cid));return"customer/customer_order";}
复制代码 客户订单列表查询后端实现
- <selectid="selectByParams"parameterType="com.xxxx.crm.query.CustomerOrderQuery"resultType="com.xxxx.crm.vo.CustomerOrder">
- select
- <includerefid="Base_Column_List"/>
- from t_customer_order
- <where>
- is_valid=1 and cus_id=#{cid}
- <iftest="null != orderNo and orderNo !=''">
- and order_no=#{orderNo}
- </if><iftest="null !=state">
- and state=#{state}
- </if></where></select>
复制代码CustomerOrderController.java
- @RequestMapping("list")@ResponseBodypublic Map<String,Object>queryCustomerOrdersByParams(CustomerOrderQuery customerOrderQuery){return customerOrderService.queryByParamsForTable(customerOrderQuery);
复制代码 客户订单页面展示前端模板 & 核心js
customer_order.ftl 模板文件添加
views/customer 目录下创建customer_order.ftl 文件
- <!DOCTYPE html><html><head><title>客户订单查看</title>
- <#include "../common.ftl">
- </head><bodyclass="childrenBody"><divclass="layui-col-md12"><divclass="layui-card"><divclass="layui-card-body"><formclass="layui-form"><inputname="id"type="hidden"value="${(customer.id)!}"/><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">客户名称</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="name"id="name"value="${(customer.name)!}"readonly="readonly"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">法人</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="fr"id="fr"value="${(customer.fr)!}"readonly="readonly"></div></div></div><divclass="layui-form-item layui-row"><divclass="layui-col-xs6"><labelclass="layui-form-label">客户地址</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="address"value="${(customer.address)!}"readonly="readonly"></div></div><divclass="layui-col-xs6"><labelclass="layui-form-label">联络电话</label><divclass="layui-input-block"><inputtype="text"class="layui-input"name="phone"value="${(customer.customer)!}"id="phone"readonly="readonly"></div></div></div></form></div></div></div><divclass="layui-col-md12"><tableid="customerOrderList"class="layui-table"lay-filter="customerOrders"></table></div><!--操作--><scriptid="customerOrderListBar"type="text/html"><a class="layui-btn layui-btn-xs" lay-event="info">订单详情</a></script><scripttype="text/javascript"src="${ctx}/static/js/customer/customer.order.js"></script></body></html>
复制代码- layui.use(['table','layer'],function(){var layer = parent.layer === undefined ? layui.layer : top.layer,
- $ = layui.jquery,
- table = layui.table;//订单列表展示var tableIns = table.render({
- elem:'#customerOrderList',
- url : ctx+'/order/list?cid='+$("input[name='id']").val(),
- cellMinWidth :95,
- page :true,
- height :"full-125",
- limits :[10,15,20,25],
- limit :10,
- toolbar:"#toolbarDemo",
- id :"customerOrderListTable",
- cols :[[{type:"checkbox", fixed:"center"},{field:"id", title:'编号',fixed:"true"},{field:'orderNo', title:'订单编号',align:"center"},{field:'orderDate', title:'下单日期',align:"center"},{field:'address', title:'收货地址',align:"center"},{field:'state', title:'支付状态',align:"center",templet:function(d){if(d.state==1){return"已支付;"}else{return"未支付";}}},{field:'createDate', title:'创建时间',align:"center"},{field:'updateDate', title:'更新时间',align:"center"},{title:'操作',fixed:"right",align:"center", minWidth:150,templet:"#customerOrderListBar"}]]});});
复制代码 客户订单详情查看
客户订单详情效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保管下来直接上传(img-65aT5Rbe-1612166184687)(images\image-20200227231656266.png)]
订单详情页展示前端js
客户订单页添加行监听事件,customer.order.js- /**
- * 行监听
- */
- table.on("tool(customerOrders)",function(obj){var layEvent = obj.event;if(layEvent =="info"){openOrderDetailDialog(obj.data.id);}});// 翻开添加方案项数据页面functionopenOrderDetailDialog(id){var url = ctx+"/customer/orderDetailPage?orderId="+id;
- layui.layer.open({
- title :"订单详情查看",
- type :2,
- area:["700px","400px"],
- maxmin:true,
- content : url
- });}
复制代码 订单详情模板页面转发与订单详情列表查询后端
- @RequestMapping("orderDetailPage")public String orderDetailPage(Integer orderId, Model model){
- model.addAttribute("order",orderService.queryOrderDetailByOrderId(orderId));return"customer/customer_order_detail";}
复制代码OrderDetailsController.java
- @Controller@RequestMapping("order_details")publicclassOrderDetailsControllerextendsBaseController{@Resourceprivate OrderDetailsService orderDetailsService;@RequestMapping("list")@ResponseBodypublic Map<String,Object>queryOrderDetailsByParams(OrderDetailsQuery orderDetailsQuery){return orderDetailsService.queryByParamsForTable(orderDetailsQuery);}}
复制代码 订单详情前端模板 & 核心js
views/customer 目录下新建customer_order_detail.ftl 文件- <!DOCTYPE html><html><head><title>订单详情查看</title><#include "../common.ftl"></head><body class="childrenBody"><div class="layui-col-md12"><div class="layui-card"><div class="layui-card-body"><form class="layui-form"><input name="id" type="hidden" value="${(order.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="orderNo" id="orderNo" value="${(order.orderNo)!}" readonly="readonly"></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="total" id="total" value="${(order.total)!}" readonly="readonly"></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="${(order.address)!}" readonly="readonly"></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="status" value="${(order.status)!}" readonly="readonly"></div></div></div></form></div></div></div><div class="layui-col-md12"><table id="orderDetailList"class="layui-table" lay-filter="orderDetails"></table></div><script type="text/javascript" src="${ctx}/static/js/customer/customer.order.details.js"></script></body></html>
复制代码 js/customer 目录下新建customer.order.details.js- layui.use(['table','layer',"form"],function(){var layer = parent.layer === undefined ? layui.layer : top.layer,
- $ = layui.jquery,
- table = layui.table;//订单列表展示var tableIns = table.render({
- elem:'#orderDetailList',
- url : ctx+'/order_details/list?orderId='+$("input[name='id']").val(),
- cellMinWidth :95,
- page :true,
- height :"full-125",
- limits :[10,15,20,25],
- limit :10,
- toolbar:"#toolbarDemo",
- id :"customerOrderListTable",
- cols :[[{type:"checkbox", fixed:"center"},{field:"id", title:'编号',fixed:"true"},{field:'goodsName', title:'商品名称',align:"center"},{field:'goodsNum', title:'商品数量',align:"center"},{field:'unit', title:'单位',align:"center"},{field:'price', title:'单价(¥)',align:"center"},{field:'sum', title:'总价(¥)',align:"center"},{field:'createDate', title:'创建时间',align:"center"},{field:'updateDate', title:'更新时间',align:"center"}]]});});
复制代码 对于客户联络人管理,客户交往记录管理两个模块功能实现,这里不再提现,大家可以私下自己模仿前面模块实现。
客户流失管理
客户流失管理页面效果
客户流失管理后端分析 & 实现
客户流失规则定义
客户自创建超越六个月以来未与企业产生任何订单或者客户最后下单日期间隔如今超越六个月的客户定义为流失客户
流失客户数据sql查询分析与实现
这里对于客户流失规则的定义包含两种情况
创建的客户数据间隔当前时间超越了6个月
客户没有下单 或者最后一次下单时间间隔当前时间超越6个月
在实现流失客户数据查询时采用逆向查询方式 先将有效客户查出来然后依照排除法获取无效客户- SELECT*FROM
- t_customer c
- WHERE
- c.is_valid =1AND c.state =0AND DATE_ADD(c.create_date,INTERVAL6MONTH)<NOW()AND c.id NOTIN(SELECT
- o.cus_id
- FROM
- t_customer_order o
- WHERE
- o.state =1AND o.is_valid =1AND DATE_ADD(o.order_date,INTERVAL6MONTH)>NOW())
复制代码 客户流失关系后端service 实现
- @Transactional(propagation = Propagation.REQUIRED)publicvoidupdateCustomerState(){
- List<Customer> lossCutomers = customerMapper.queryLossCustomers();if(null !=lossCutomers && lossCutomers.size()>0){
- List<CustomerLoss> customerLosses=newArrayList<CustomerLoss>();
- List<Integer> lossCusIds=newArrayList<Integer>();
- lossCutomers.forEach(customer->{
- CustomerLoss customerLoss=newCustomerLoss();// 设置最后下单时间
- CustomerOrder lastCustomerOrder = customerOrderMapper.queryLastCustomerOrderByCusId(customer.getId());if(null !=lastCustomerOrder){
- customerLoss.setLastOrderTime(lastCustomerOrder.getOrderDate());}
- customerLoss.setCreateDate(newDate());
- customerLoss.setCusManager(customer.getCusManager());
- customerLoss.setCusName(customer.getName());
- customerLoss.setCusNo(customer.getKhno());
- customerLoss.setIsValid(1);// 设置客户流失状态为暂缓流失状态
- customerLoss.setState(0);
- customerLoss.setUpdateDate(newDate());
- customerLosses.add(customerLoss);
- lossCusIds.add(customer.getId());});
- AssertUtil.isTrue(customerLossMapper.insertBatch(customerLosses)<customerLosses.size(),"客户流失数据流转失败!");
- AssertUtil.isTrue(customerMapper.updateCustomerStateByIds(lossCusIds)<lossCusIds.size(),"客户流失数据流转失败!");}}
复制代码 流失客户定时任务处置添加
当实现了客户数据转移业务逻辑代码后,这里需要考虑一个问题:客户数据量的问题随着时间的积累,流失的客户数据可能就比较大,假设数据的获取在用户查询时停止,此时后端对于数据的查询就会变得很慢,此时可以使用我们之前讲到的定时任务来处置,后台通过定时器来对流失客户数据定时停止转移处置,从而当前端用户查询时只需到客户流失表查询流失数据即可。- @ServicepublicclassTaskService{@Resourceprivate CustomerService customerService;@Scheduled(cron ="0/2 * * * * ?")publicvoidjob(){
- System.out.println("定时任务开端执行-->"+newSimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
- customerService.updateCustomerState();}}
复制代码 Starter开启定时任务环境配置
- @SpringBootApplication@MapperScan("com.xxxx.crm.dao")@EnableSchedulingpublicclassStarter{publicstaticvoidmain(String[] args){
- SpringApplication.run(Starter.class);}}
复制代码 客户流失管理前端页面展示
CustomerLossController.java
- @Controller@RequestMapping("customer_loss")publicclassCustomerLossControllerextendsBaseController{@Resourceprivate CustomerLossService customerLossService;@RequestMapping("index")private String index(){return"customerLoss/customer_loss";}@RequestMapping("list")@ResponseBodypublic Map<String,Object>queryCustomerLossByParams(CustomerLossQuery customerLossQuery){return customerLossService.queryByParamsForTable(customerLossQuery);}
复制代码 views/customerLoss 目录下添加cutomer_loss.ftl文件,显示流失客户记录数据- <!DOCTYPE html><html><head><title>流失客户管理</title>
- <#include "../common.ftl">
- </head><bodyclass="childrenBody"><formclass="layui-form"><blockquoteclass="layui-elem-quote quoteBox"><formclass="layui-form"><divclass="layui-inline"><divclass="layui-input-inline"><inputtype="text"name="cusNo"class="layui-input
- searchVal"placeholder="客户编号"/></div><divclass="layui-input-inline"><inputtype="text"name="cusName"class="layui-input
- searchVal"placeholder="客户名"/></div><divclass="layui-input-inline"><selectname="state"id="state"><optionvalue="">请选择</option><optionvalue="0">暂缓流失</option><optionvalue="1">确认流失</option></select></div><aclass="layui-btn search_btn"data-type="reload"><iclass="layui-icon"></i> 搜索</a></div></form></blockquote><tableid="customerLossList"class="layui-table"lay-filter="customerLosses"></table><scripttype="text/html"id="toolbarDemo"></script><!--操作--><scriptid="op"type="text/html">{{# if(d.state===0){}}<a href="javascript:;"class="layui-btn layui-btn-warm layui-btn-xs" lay-event="add">添加暂缓</a>{{# }else{}}<a href="javascript:;"class="layui-btn layui-btn-normal layui-btn-xs" lay-event="info">详情</a>{{# }}}</script></form><scripttype="text/javascript"src="${ctx}/static/js/customerLoss/customer.loss.js"></script></body></html>
复制代码 js/customerLoss 目录下添加customer.loss.js 文件- layui.use(['table','layer',"form"],function(){var layer = parent.layer === undefined ? layui.layer : top.layer,
- $ = layui.jquery,
- table = layui.table;//用户列表展示var tableIns = table.render({
- elem:'#customerLossList',
- url : ctx+'/customer_loss/list',
- cellMinWidth :95,
- page :true,
- height :"full-125",
- limits :[10,15,20,25],
- limit :10,
- toolbar:"#toolbarDemo",
- id :"customerLossListTable",
- cols :[[{type:"checkbox", fixed:"center"},{field:"id", title:'编号',fixed:"true"},{field:'cusNo', title:'客户编号',align:"center"},{field:'cusName', title:'客户名称',align:"center"},{field:'cusManager', title:'客户经理',align:"center"},{field:'lastOrderTime', title:'最后下单时间',align:"center"},{field:'lossReason', title:'流失原因',align:"center"},{field:'confirmLossTime', title:'确认流失时间',align:"center"},{field:'createDate', title:'创建时间',align:"center"},{field:'updateDate', title:'更新时间',align:"center"},{title:'操作',fixed:"right",align:"center", minWidth:150,templet:"#op"}]]});$(".search_btn").on("click",function(){
- table.reload("customerLossListTable",{
- page:{
- curr:1//重新从第 1 页开端},
- where:{
- cusNo:$("input[name='cusNo']").val(),//用户名
- cusName:$("input[name='cusName']").val(),//邮箱
- state:$("#state").val()//手机号}})});});
复制代码 流失客户暂缓处置
这里流失客户数据展示胜利后,并不代表客户已确认流失,需要作下一步流失暂缓处置,所以这里在展示客户数据时有显示详情展示的,有显示添加暂缓的处置,对流失客户做进一步确认操作实现过程可以参看方案数据开发操作这里不再提供详细实现流程,页面效果如下: |
|