

软件项目实践之CRM系统
圈内存在这么一句话:“世上本来没有CRM,大家的生意越来越难做了,才有了CRM。"在同质化竞争时代,顾客资产尤为重要,新时代在呼唤 CRM。
CRM 系统概念
CRM 基本概念

CRM系统即客户关系管理系统,顾名思义就是管理公司与客户之间的关系。是一种以"客户关系一对一理论"为 基础,旨在改善企业与客户之间关系的新型管理机制。客户关系管理的定义是:企业为提高核心竞争力,利用相应的信息技术以及互联网技术来协调企业与顾客间在销售、营销和服务上的交互, 从而提升其管理方式,向客户提供创新式的个性化的客户交互和服务的过程。其最终目标是吸引新客户、保留老客户以及将已有客户转为忠实客户,增加公司市场份额。
CRM的实施目标就是通过全面提升企业业务流程的管理来降低企业成本, 通过提供更快速和周到的优质服务来吸引和保持更多的客户。作为一种新型管理机制, CRM 极大地改善了企业与客户之间的关系,应用于企业的市场营销、销售、服务与技术支持等与客户相关的领域。
CRM 分类
根据客户的类型不同, CRM 可以分为 B to B CRM 及 B to C CRM 。B to B CRM 中管理的客户是企业客户,而 B to C CRM 管理的客户则是个人客户。提供企业产品销售和服务的企业需要的 B to B 的 CRM, 也就是市面上大部分 CRM 的内容。而提供个人及家庭消费的企业需要的是 B to C 的 CRM。
根据 CRM 管理侧重点不同又分为操作性和分析型 CRM 。 大部分 CRM 为操作型 CRM, 支持 CRM 的日常作业流程的每个环节, 而分析型 CRM 则偏重于数据分析。
CRM 系统模块划分
CRM系统模块图

模块功能描述
基础模块
包含系统基本的用户登录,退出,记住我,密码修改等基本操作。
营销管理
营销机会管理:企业客户的质询需求所建立的信息录入功能,方便销售人员进行后续的客户需求跟踪。
营销开发计划:开发计划是根据营销机会而来,对于企业质询的客户,会有相应的销售人员对于该客户进行具体的沟通交流,此时对于整个CRM 系统而言,通过营销开发计划来进行相应的信息管理,提高客户的购买企业产品的可能性。
客户管理
客户信息管理:CRM 系统中完整记录客户信息来源的数据、企业与客户交往、客户订单查询等信息录入功能,方便企业与客户进行相应的信息交流与后续合作。
客户流失管理:CRM 通过一定规则机制所定义的流失客户(无效客户),通过该规则可以有效管理客户信息资源,提高营销开发效率。
服务管理
服务管理是针对客户而开发的功能,针对客户要求,CRM 提供客户相应的信息质询,反馈与投诉功能,提高企业对于客户的服务质量。
数据报表
CRM 提供的数据报表功能能够帮助企业了解客户整体分布,了解客户开发结果整体信息,从而帮助企业整体调整客户开发计划,提高企业的在市场中的竞争力度。
系统管理
系统管理包含常量字典维护工作,以及权限管理模块,CRM 权限管理是基于角色的一种权限控制,基于RBAC实现基于角色的权限控制,通过不同角色的用户登录该系统后展示系统不同的操作功能,从而达到对不同角色完成不同操作功能。
CRM 系统数据库设计
CRM系统根据产品的原型搞以及UI组的设计稿, 接下来就要设计数据库, 一般在大公司通常会有专门的DBA, 这时我们可以不要考虑数据库表设计, 但是也要能够读懂或者了解DBA的设计思路方便在程序开发阶段不会出现问题, 一般关系型数据库表设计满足三范式的设计即可, 表名设计做到见名知意最好。
E-R图表简介
营销管理模块

客户管理模块
客户信息管理

客户流失管理

服务管理

系统管理
权限模块 E-R 模型

字典&日记管理

表结构详情
t_sale_chance | 营销机会表 | |||
---|---|---|---|---|
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | id主键 |
chance_source | varchar(300) | 可空 | 机会来源 | |
customer_name | varchar(100) | 可空 | 客户名称 | |
cgjl | int(11) | 可空 | 成功几率 | |
overview | varchar(300) | 可空 | 概要 | |
link_man | varchar(100) | 可空 | 联系人 | |
link_phone | varchar(100) | 可空 | 手机号 | |
description | varchar(1000) | 可空 | 描述 | |
create_man | varchar(100) | 可空 | 创建人 | |
assign_man | varchar(100) | 可空 | 分配人 | |
assign_time | datetime | 可空 | 分配时间 | |
state | int(11) | 可空 | 分配状态 | |
dev_result | int(11) | 可空 | 开发结果 | |
is_valid | int(4) | 可空 | 有效状态 | |
create_date | datetime | 可空 | 创建时间 | |
update_date | datetime | 可空 | 更新时间 | |
t_cus_dev_plan | 客户开发计划表 | |||
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | id |
sale_chance_id | int(11) | 可空 | 营销机会id | |
plan_item | varchar(100) | 可空 | 计划内容 | |
plan_date | datetime | 可空 | 计划日期 | |
exe_affect | varchar(100) | 可空 | 执行效果 | |
create_date | datetime | 可空 | 创建时间 | |
update_date | datetime | 可空 | 更新时间 | |
is_valid | int(4) | 可空 | 有效状态 | |
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_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_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_reprieve | 客户流失暂缓表 | |||
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | id主键 |
loss_id | int(11) | 可空 | 流失id | |
measure | varchar(500) | 可空 | 措施 | |
is_valid | tinyint(4) | 可空 | 有效状态 | |
create_date | datetime | 可空 | 创建时间 | |
update_date | datetime | 可空 | 更新时间 | |
t_customer_serve | 客户服务 | |||
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | id主键 |
serve_type | varchar(30) | 可空 | 服务类型 | |
overview | varchar(500) | 可空 | 概要 | |
customer | varchar(30) | 可空 | 客户 | |
state | varchar(20) | 可空 | 服务状态 | |
service_request | varchar(500) | 可空 | 服务请求 | |
create_people | varchar(100) | 可空 | 服务创建人 | |
assigner | varchar(100) | 可空 | 服务分配人 | |
assign_time | datetime | 可空 | 分配时间 | |
service_proce | varchar(500) | 可空 | 服务处理 | |
service_proce_people | varchar(20) | 可空 | 服务处理人 | |
service_proce_time | datetime | 可空 | 服务处理时间 | |
service_proce_result | varchar(500) | 可空 | 处理结果 | |
myd | varchar(50) | 可空 | 满意度 | |
is_valid | int(4) | 可空 | 是否有效 | |
update_date | datetime | 可空 | 更新时间 | |
create_date | datetime | 可空 | 创建时间 | |
t_datadic | 字典表 | |||
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | id主键 |
data_dic_name | varchar(50) | 可空 | 字典名 | |
data_dic_value | varchar(50) | 可空 | 字典值 | |
is_valid | tinyint(4) | 可空 | 是否有效 | |
create_date | datetime | 可空 | 创建时间 | |
update_date | datetime | 可空 | 更新时间 | |
t_user | 用户表 | |||
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | 字段描述 |
user_name | varchar(20) | 可空 | 用户名 | |
user_pwd | varchar(100) | 可空 | 用户密码 | |
true_name | varchar(20) | 可空 | 真实姓名 | |
varchar(30) | 可空 | 邮箱 | ||
phone | varchar(20) | 可空 | 电话 | |
is_valid | int(4) | 可空 | 有效状态 | |
create_date | datetime | 可空 | 创建时间 | |
update_date | datetime | 可空 | 更新时间 | |
t_role | 角色表 | |||
字段 | 字段类型 | 字段限制 | 字段描述 | |
主键 | id | int(11) | 自增 | 字段描述 |
role_name | varchar(255) | 可空 | 角色名 | |
role_remarker | varchar(255) | 可空 | 角色备注 | |
create_date | datetime | 可空 | 创建时间 | |
update_date | datetime | 更新时间 | ||
is_valid | int(11) | 非空 | 是否有效 |
项目环境搭建与测试
项目技术栈

环境搭建与测试
在 IDEA 中新建 SpringBoot 项目 - CRM

在pom.xml引入坐标&插件
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--
mybatis 集成
-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- DevTools 的坐标 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 如果没有该配置,热部署的devtools不生效 -->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
添加配置文件application.yml
src/main/resources 目录下新建application.yml配置文件,内容如下:
\## 端口号 上下文路径
server:
port: 9898
servlet:
context-path: /crm
\## 数据源配置
spring:
datasource:
type: com.mchange.v2.c3p0.ComboPooledDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/crm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
\## freemarker
freemarker:
suffix: .ftl
content-type: text/html
charset: UTF-8
template-loader-path: classpath:/views/
\## 启用热部署
devtools:
restart:
enabled: true
additional-paths: src/main/java
\## mybatis 配置
mybatis:
mapper-locations: classpath:/mappers/*.xml
type-aliases-package: com.xxxx.crm.vo;com.xxxx.crm.query;com.xxxx.crm.dto
configuration:
map-underscore-to-camel-case: true
\## pageHelper 分页
pagehelper:
helper-dialect: mysql
\## 设置 dao 日志打印级别
logging:
level:
com:
xxxx:
crm:
dao: debug
添加视图转发源代码
新建com.xxxx.crm.controller包,添加系统登录,主页面转发代码(这里继承BaseController,具体文件见相关目录)。
package com.xxxx.crm.controller;
import com.xxxx.crm.base.BaseController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController extends BaseController {
/**
* 系统登录页
* @return
*/
@RequestMapping("index")
public String index(){
return "index";
}
// 系统界面欢迎页
@RequestMapping("welcome")
public String welcome(){
return "welcome";
}
/**
* 后端管理主页面
* @return
*/
@RequestMapping("main")
public String main(){
return "main";
}
}
静态资源文件目录添加
在src/main/resources目录下新建public 目录存放系统相关静态资源文件,copy静态文件内容到public 目录。
添加系统登录,主页面视图模板页
在src/main/resources 目录下新建views目录,添加index.ftl,main.ftl 等文件(具体视图文件详见相关目录)
添加SpringBoot应用启动类Starter
在com.xxxx.crm 包下新建Starter.java ,添加启动项目相关代码如下:
package com.xxxx.crm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Starter {
public static void main(String[] args) {
SpringApplication.run(Starter.class);
}
}
项目目录结构

浏览器访问登录页、主页面
Chrome浏览器访问登录页地址:http://localhost:9898/crm/index

Chrome浏览器访问登录页地址:http://localhost:9898/crm/main

用户登录功能实现
用户登录功能核心思路
# 用户登录
## 后端实现
### 整体思路:
1. 参数判断
- 用户姓名 非空判断
- 用户密码 非空判断
2. 通过用户名查询用户记录,返回用户对象
3. 判断用户对象是否为空
4. 如果用户对象不为空,则将前台传递的用户密码与数据库中的密码作比较
5. 判断密码是否正确
6. 如果密码正确,则登录成功,返回结果
**Controller层(控制层:接受请求,响应结果)**
1. 通过形参接收客户端传递的参数
2. 调用业务逻辑层的登录方法,得到登录结果
3. 响应数据给客户端
**Service层(业务逻辑层:非空判断、条件判断等业务逻辑处理)**
1. 参数判断,判断用户名、密码是否非空
- 如果参数为空,抛出异常(异常被控制层捕获并处理)
2. 调用数据访问层,通过用户名查询用户记录,返回用户对象
3. 判断用户对象是否为空
- 如果对象为空,抛出异常(异常被控制层捕获并处理)
- 否则继续
4. 判断用户密码是否正确,比较客户端传递的用户密码与数据库中查询的用户对象中的密码
- 如果密码不相等,抛出异常(异常被控制层捕获并处理)
- 如果密码相等,登录成功,返回结果
**Dao层(数据访问层:数据库中增删改查操作)**
通过用户名查询用户记录,返回用户对象
- 本文作者: 况杨
- 本文链接: https://kuangyang828.github.io/xiang-mu-shi-jian-zhi-crm-xi-tong/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
感谢您的支持,我会继续努力的!


扫码打赏,你说多少就多少
打开微信扫一扫,即可进行扫码打赏哦