crm分类和系统模块设计划分
CRM
crm分类
根据客户的类型不同,CRM 可以分为 B to B CRM 及 B to C CRM。 BtoB CRM 中管理的客户是企业 客户,⽽ B to C CRM 管理的客户则是个⼈客户。提供企业产品销售和服务的企业需要的 B to B 的 CRM,也就是市⾯上⼤部分 CRM 的内容。⽽提供个⼈及家庭消费的企业需要的是 B to C 的 CRM。
CRM系统模块划分
基础模块:
包含系统基本的⽤户登录,退出,记住我,密码修改等基本操
营销管理模块
营销机会管理 :
企业客户的质询需求所建⽴的信息录⼊功能,⽅便销售⼈员进⾏后续的客户需求跟 踪。
营销开发计划 :
开发计划是根据营销机会⽽来,对于企业质询的客户,会有相应的销售⼈员对于该客 户进⾏具体的沟通交流,此时对于整个 Crm 系统⽽⾔,通过营销开发计划来进⾏相应的信息管理,提 ⾼客户的购买企业产品的可能性。
客户客户管理模块
客户信息管理:
Crm 系统中完整记录客户信息来源的数据、企业与客户交往、客户订单查询等信息 录⼊功能,⽅便企业与客户进⾏相应的信息交流与后续合作。
客户流失管理:
Crm 通过⼀定规则机制所定义的流失客户(⽆效客户),通过该规则可以有效管理 客户信息资源,提⾼营销开发的效率。
服务管理
服务管理是针对客户⽽开发的功能,针对客户要求,Crm 提供客户相应的信息质询,反馈与投诉功 能,提⾼企业对于客户的服务质量。
数据报表
Crm 提供的数据报表功能能够帮助企业了解客户整体分布,了解客户开发结果整体信息,从⽽帮助企 业整体调整客户开发计划,提⾼企业的在市场中的竞争⼒度。
系统管理
系统管理包含常量字典维护⼯作,以及权限管理模块,Crm 权限管理是基于⻆⾊的⼀种权限控制,基 于 RBAC 实现基于⻆⾊的权限控制,通过不同⻆⾊的⽤户登录该系统后展示系统不同的操作功能,从⽽ 达到对不同⻆⾊完成不同操作功能。
1.用户管理
1.1用户登录功能实现
1.1.1工具类和自定义异常类
1.1.2逆向工程生成代码
resources下生成generatorConfig.xml配置文件
1.2核心代码
UserModel:
定义UserModel实体类,用来返回登录成功后的用户信息(相当于作用域里的信息)
private Integer userId;
private String userName;
private String trueName
UserService:必须继承extends BaseService<User ,Integer>
方法:userLogin。参数:userName,userPwd
用户登录业务逻辑
①:校验前台传过来的参数(userName,userPwd)。为空就抛出异常
②:调用dao层,根据前台传来的userName查询数据库用户是否存在,不存在则抛出异常
③:用户存在,根据前台传入的密码和(根据查询数据量用户对象的密码)进行校验[校验密码是需要加密或者解密],不一致则抛出异常
④:密码正确则登录成功,返回resultInfo(用户相关信息)
⑤:设置用户,id,userName,userPwd
public UserModel userLogin(String userName,String userPwd){
//将前台传入的账号密码进行判断是否为空,封装校验方法
checkUserParams(userName,userPwd);
//调用dao层判,根据用户名查询数据库,判断账号是否存在
User user = userMapper.selectUserByName(userName);
//判断根据用户名查询的数据是否存在
AssertUtil.isTrue(user==null,"用户不存在");
//校验密码
checkUserPwd(user.getUserPwd(),userPwd);
//登录,返回ResultInfo(封装了UserModel对象,前台需要存入cookie的用户对象)
UserModel userModel=buildUserModexl(user);
return userModel;
}
/**
* 封装了UserModel对象,前台需要存入cookie用户数据,同时给userId加密
* @param user
* @return
*/
private UserModel buildUserModexl(User user) {
UserModel userModel=new UserModel();
//将id加密
String userId = UserIDBase64.encoderUserID(user.getId());
userModel.setUserName(user.getUserName());
userModel.setUserId(userId);
user.setUserPwd(user.getUserPwd());
return userModel;
}
UserMapper:
接口中定义根据用户名查询用户对象的方法
UserMapper.xml
配置相对应的SQL语句
UserController:必须继承BaseController
①:提供前台访问路径 @PostMaping(“login”)
②:返回JSON对象 @ResponseBody
③:调用Service层方法,得到返回对象
④:将返回的对象设置到ResultInfo中
⑤:返回给前台
@RequestMapping("login")
@ResponseBody
public ResultInfo userLogin(String userName,String userPwd){
ResultInfo resultInfo=new ResultInfo();
//调用Service层登录方法,得到返回的对象
UserModel userModel = userService.userLogin(userName, userPwd);
//将要返回的UserModel对象设置到ResultInfo对象中
resultInfo.setResult(userModel);
return resultInfo;
}
添加前台页面
修改cookie的数据
1.2修改密码
1.2.1后台代码
UserService层
方法:updateUserPwd。 参数:id,oldPwd,newPwd,inPwd
①:根据id获取在数据库查询用户,判断用户是否存在
②:旧密码是否为空,原始密码是否和数据库中查询的用户密码是否一致,不一致则抛出异常
③:新密码是否为空,新密码和旧密码是否一致,一致则抛出异常
④:确认密码是否为空,确认密码和新密码是否相同,不一致则抛出异常
⑤:数据校验没有问题,则进行密码的修改,同时用户的更改时间(updateDate)需要改变
⑥:执行操作更改密码操作,同时判断一下是否成功
public void updateUserPwd(Integer id,String oldPwd,String newPwd,String inPwd){
//通过id查询用户,判断用户是否存在
User user = userMapper.selectByPrimaryKey(id);
AssertUtil.isTrue(user==null,"用户未登录");
//校验数据,校验非空,校验数据是否合理
checkUserUpdate(oldPwd,newPwd,inPwd,user.getUserPwd());
//设置新密码
user.setUserPwd(Md5Util.encode(newPwd));
user.setUpdateDate(new Date());
//执行操作,返回信息,ResultInfo
AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"密码修改操作失败");
}
UserConroller
①:提供对外访问地址 @PostMaping(“update”)
②:返回JSON对象 @ResponseBody
③:获取用户id
④:调用Service层的修改密码的方法
@PostMapping("update")
@ResponseBody
public ResultInfo updateUserPwd(HttpServletRequest request,String oldPwd,String newPwd,String inPwd){
ResultInfo resultInfo=new ResultInfo();
//获取用户id
int id = LoginUserUtil.releaseUserIdFromCookie(request);
//调用Service层修改密码方法
userService.updateUserPwd(id,oldPwd,newPwd,inPwd);
return resultInfo;
}
添加前台页面
2.营销管理
2.1营销机会管理功能实现
2.1.1创建SaleChanceQuery查询类
private String customerName; // 客户名称
private String createMan; // 创建人
private String state; // 分配状态
2.1.2设置SQL
SaleChanceMapper.xml
2.1.3接口定义
实现BaseMapper<SaleChance,Integer>接口
2.1.4Service层
多条件分页查询行销机会(BaseService有对应的方法)
方法:querySaleChanceByParams 。参数SaleChanceQuery对象 query
①:定义一个map集合
②:开启分页操作
③:调用到层的查询方法
④:将数据封装到ResultInfo中
public Map<String ,Object> querySaleChanceByParams(SaleChanceQuery query){
Map<String ,Object> map=new HashMap<>();
//分页操作
PageHelper.startPage(query.getPage(),query.getLimit());
//调用dao层查询
List<SaleChance> saleChances=saleChanceMapper.selectByParams(query);
//将数据封装到PageInfo中
PageInfo<SaleChance> pageInfo=new PageInfo<>(saleChances);
map.put("code",0);
map.put("msg","success");
map.put("count",pageInfo.getTotal());
map.put("data",pageInfo.getList());
return map;
}
2.1.5controller层,继承BaseController
方法saleChanceByParams。参数SaleChanceQuery对象 query
①:提供对外访问地址
②:返回JSON对象
③:调用Service层方法
@RequestMapping("list")
@ResponseBody
public Map<String,Object> saleChanceByParams(SaleChanceQuery query){
return saleChanceService.querySaleChanceByParams(query);
}
2.1.6前段代码实现
2.2营销机会数据添加
2.2.1service层
方法:saveSaleChance。参数SaleChance对象 saleChance。
添加事务
@Transactional(propagation = Propagation.REQUIRED)
①:非空校验,参数saleChance.getCustomerName() 客户名称
saleChance.getLinkMan() 联系人
saleChance.getLinkPhone() 联系方式
②:设置默认值
③:判断前台是否选择了分配人
④:未分配分配人
设置默认值 分配时间为空,分配状态为空,开发结果为0
⑤:已分配分配人
设置默认值 分配时间为当前时间 分配状态为1 开发结果为1
⑥:执行添加
@Transactional(propagation = Propagation.REQUIRED)
public void saveSaleChance(SaleChance saleChance){
/*//校验需要添加的营销客户是否存在
SaleChance sale = saleChanceMapper.selectByPrimaryKey(saleChance.getId());
AssertUtil.isTrue(sale!=null,"客户已存在");*/
//非空校验,封装校验方法 checkParams(saleChance.getCustomerName(),saleChance.getLinkMan(),saleChance.getLinkPhone());
//设置默认值
saleChance.setIsValid(1);
saleChance.setCreateDate(new Date());
saleChance.setUpdateDate(new Date());
//判断前台是否选择了分配人
if (Strings.isBlank(saleChance.getAssignMan())){
//如果未分配人员,设置默认数据
//分配时间为空
saleChance.setAssignTime(null);
//分配状态为0
saleChance.setState(0);
//开发结果为未开发
saleChance.setDevResult(0);
}else {
//如果分配l人员,需要改动默认数据
saleChance.setAssignTime(new Date());
saleChance.setState(1);
saleChance.setDevResult(1);
}
//执行添加
AssertUtil.isTrue(saleChanceMapper.insertSelective(saleChance)<1,"营销机会数据添加失败");
}
2.2.2controller层
①:提供对外的访问接口 @PostMapping(“save”)
②:返回JSON对象 @ResponseBody
③:通过cookie获取当前操作用户名称
④:TODO判断当前用户名称是否存在
⑤:调用service方法
⑥:返回ResultInfo对象
@PostMapping("save")
@ResponseBody
public ResultInfo saveSaleChance(HttpServletRequest request, SaleChance saleChance){
//cookie获取当前操作工作人员名称
String userName = CookieUtil.getCookieValue(request, "userName");
//TODO判断当前username是否存在
saleChance.setCreateMan(userName);
saleChanceService.saveSaleChance(saleChance);
return success();
}
2.2.3营销机会数据修改
service层
开启事务
方法:updateSaleChance。参数:SaleChance对象saleChance方法
①:前台传入的数据中id必须存在
②:非空校验,参数saleChance.getCustomerName() 客户名称
saleChance.getLinkMan() 联系人
saleChance.getLinkPhone() 联系方式
③:设置默认值,updateTime为当前时间
④:如果修改前未分配(getAssignMan)为空
修改后也未分配,不做操作
修改后已分配
assignTime为当前时间
state为1
devResult为开发中1
⑤:如果修改前已分配(getAssignMan)不为空
修改后为未分配
assignTime为当前时间
state为1
devResult为开发中1
修改后依然已分配:
分配人已修改:assignTime为当前时间
分配人未变化:不修改,但是要设置setAssignTime默认值为数据库中的默认值
⑥:执行修改
@Transactional(propagation = Propagation.REQUIRED)
public void updateSaleChance(SaleChance saleChance){
//执行前id必须存在
AssertUtil.isTrue(saleChance.getId()==null,"账户异常,请重试");
//校验数据 checkParams(saleChance.getCustomerName(),saleChance.getLinkMan(),saleChance.getLinkPhone());
//查询修改前的数据
SaleChance dbSaleChance= saleChanceMapper.selectByPrimaryKey(saleChance.getId());
//设置默认值
saleChance.setUpdateDate(new Date());
//判断是修改前是否分配了分配人
if (StringUtils.isBlank(dbSaleChance.getAssignMan())){
//修改前未分配
//判断修改后是否分配
if (StringUtils.isNotBlank(saleChance.getAssignMan())){
//修改后已分配,设置默认值
saleChance.setAssignTime(new Date());//分配时间
saleChance.setState(1);
saleChance.setDevResult(1);
}
//分配后为修改,不需要去改变
}else {
//修改前已分配
//判断分配人是否修改
if (!saleChance.getAssignMan().equals(dbSaleChance.getAssignMan())){
//分配人已经修改
saleChance.setAssignTime(new Date());
}else {
//分配人未修改,时间应该也不修改,但是sql语句中,此字段没有非空判断,所以设置原始的分配时间
saleChance.setAssignTime(dbSaleChance.getAssignTime());
}
}
//执行修改 AssertUtil.isTrue(saleChanceMapper.updateByPrimaryKeySelective(saleChance)<1,"营销机会修改失败");
}
controller层
①:提供对外的访问接口 @PostMapping(“update”)
②:返回JSON对象 @ResponseBody
③:调用Service层方法
④:返回结果
@PostMapping("update")
@ResponseBody
public ResultInfo toUpdateSaleChance(SaleChance saleChance){
saleChanceService.updateSaleChance(saleChance);
return success();
}
本文地址:https://blog.csdn.net/weixin_44158590/article/details/110501523