CRM 客户关系管理系统设计
一、系统概述
1.1 系统简介
CRM(Customer Relationship Management)客户关系管理系统是一个以客户为中心的企业管理系统,帮助企业管理客户信息、销售机会、营销活动、客户服务等,提升客户满意度和企业销售业绩。
1.2 核心价值
| 价值点 | 说明 | 预期效果 |
|---|---|---|
| 🎯 客户洞察 | 360度客户画像分析 | 客户转化率提升 35% |
| 📊 销售提效 | 销售漏斗自动化管理 | 销售效率提升 40% |
| 🔄 营销自动化 | 智能营销活动管理 | 营销 ROI 提升 50% |
| 📈 数据驱动 | 实时数据分析决策 | 决策效率提升 45% |
| 🚀 服务升级 | 智能工单系统 | 客户满意度提升 30% |
1.3 业务需求
核心功能
- 客户管理:客户信息、联系人、客户标签、客户分级
- 销售管理:商机管理、销售漏斗、报价单、合同管理
- 营销管理:营销活动、营销自动化、营销线索
- 服务管理:工单管理、客户投诉、售后服务
- 数据分析:销售报表、客户分析、业绩统计
- 协作管理:任务管理、日程安排、团队协作
非功能需求
- 高可用性:系统可用性 99.9%
- 数据安全:客户数据加密存储,权限严格控制
- 易用性:界面友好,操作简单
- 移动端支持:支持移动端 APP
二、系统架构
2.1 技术架构
2.2 销售漏斗流程
2.3 微服务划分
1. 客户服务 (crm-customer-service)
java
1- 客户管理 (Customer)2- 联系人管理 (Contact)3- 客户标签 (CustomerTag)4- 客户跟进记录 (FollowUp)5- 客户分级 (CustomerLevel)2. 销售服务 (crm-sales-service)
java
1- 商机管理 (Opportunity)2- 销售线索 (Lead)3- 报价单管理 (Quotation)4- 合同管理 (Contract)5- 订单管理 (Order)3. 营销服务 (crm-marketing-service)
java
1- 营销活动 (Campaign)2- 营销自动化 (Marketing Automation)3- 邮件营销 (Email Marketing)4- 短信营销 (SMS Marketing)5- 营销效果分析 (Marketing Analytics)4. 服务工单 (crm-service-service)
java
1- 工单管理 (Ticket)2- 客户投诉 (Complaint)3- 售后服务 (After-sales Service)4- 知识库 (Knowledge Base)5. 数据分析服务 (crm-analytics-service)
java
1- 销售报表 (Sales Report)2- 客户分析 (Customer Analytics)3- 业绩统计 (Performance Statistics)4- 漏斗分析 (Funnel Analysis)数据模型设计
核心表结构
1. 客户表 (customer)
sql
1CREATE TABLE customer (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 customer_no VARCHAR(50) NOT NULL UNIQUE COMMENT '客户编号',4 customer_name VARCHAR(200) NOT NULL COMMENT '客户名称',5 customer_type TINYINT NOT NULL COMMENT '客户类型:1-企业,2-个人',6 industry VARCHAR(50) COMMENT '所属行业',7 level TINYINT DEFAULT 1 COMMENT '客户等级:1-A类,2-B类,3-C类',8 source TINYINT COMMENT '客户来源:1-线上,2-线下,3-转介绍,4-其他',9 status TINYINT DEFAULT 1 COMMENT '状态:1-潜在客户,2-意向客户,3-成交客户,4-流失客户',10 province VARCHAR(50) COMMENT '省份',11 city VARCHAR(50) COMMENT '城市',12 address VARCHAR(200) COMMENT '详细地址',13 phone VARCHAR(20) COMMENT '电话',14 email VARCHAR(100) COMMENT '邮箱',15 website VARCHAR(200) COMMENT '网站',16 company_size VARCHAR(20) COMMENT '公司规模',17 annual_revenue DECIMAL(15,2) COMMENT '年营收',18 owner_user_id BIGINT COMMENT '负责人ID',19 create_user_id BIGINT COMMENT '创建人ID',20 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,21 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,22 INDEX idx_customer_no (customer_no),23 INDEX idx_owner (owner_user_id),24 INDEX idx_status (status),25 INDEX idx_level (level)26) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户表';2. 联系人表 (contact)
sql
1CREATE TABLE contact (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 customer_id BIGINT NOT NULL COMMENT '客户ID',4 contact_name VARCHAR(100) NOT NULL COMMENT '联系人姓名',5 gender TINYINT COMMENT '性别:1-男,2-女',6 position VARCHAR(50) COMMENT '职位',7 department VARCHAR(50) COMMENT '部门',8 mobile VARCHAR(20) COMMENT '手机',9 phone VARCHAR(20) COMMENT '电话',10 email VARCHAR(100) COMMENT '邮箱',11 wechat VARCHAR(50) COMMENT '微信',12 qq VARCHAR(20) COMMENT 'QQ',13 is_primary TINYINT DEFAULT 0 COMMENT '是否主联系人:0-否,1-是',14 birthday DATE COMMENT '生日',15 remark VARCHAR(500) COMMENT '备注',16 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,17 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,18 INDEX idx_customer (customer_id),19 INDEX idx_mobile (mobile)20) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='联系人表';3. 商机表 (opportunity)
sql
1CREATE TABLE opportunity (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 opportunity_no VARCHAR(50) NOT NULL UNIQUE COMMENT '商机编号',4 opportunity_name VARCHAR(200) NOT NULL COMMENT '商机名称',5 customer_id BIGINT NOT NULL COMMENT '客户ID',6 contact_id BIGINT COMMENT '联系人ID',7 amount DECIMAL(15,2) COMMENT '预计金额',8 stage TINYINT NOT NULL DEFAULT 1 COMMENT '阶段:1-初步接触,2-需求分析,3-方案报价,4-谈判,5-成交,6-失败',9 probability INT DEFAULT 0 COMMENT '赢单概率(%)',10 expected_close_date DATE COMMENT '预计成交日期',11 actual_close_date DATE COMMENT '实际成交日期',12 source TINYINT COMMENT '商机来源:1-线上,2-线下,3-转介绍,4-其他',13 competitor VARCHAR(200) COMMENT '竞争对手',14 priority TINYINT DEFAULT 0 COMMENT '优先级:0-普通,1-重要,2-紧急',15 status TINYINT DEFAULT 1 COMMENT '状态:1-进行中,2-已成交,3-已失败',16 owner_user_id BIGINT NOT NULL COMMENT '负责人ID',17 lose_reason VARCHAR(500) COMMENT '失败原因',18 remark VARCHAR(500) COMMENT '备注',19 create_user_id BIGINT COMMENT '创建人ID',20 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,21 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,22 INDEX idx_opportunity_no (opportunity_no),23 INDEX idx_customer (customer_id),24 INDEX idx_owner (owner_user_id),25 INDEX idx_stage (stage),26 INDEX idx_status (status)27) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商机表';4. 销售线索表 (lead)
sql
1CREATE TABLE lead (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 lead_no VARCHAR(50) NOT NULL UNIQUE COMMENT '线索编号',4 company_name VARCHAR(200) COMMENT '公司名称',5 contact_name VARCHAR(100) NOT NULL COMMENT '联系人',6 mobile VARCHAR(20) COMMENT '手机',7 email VARCHAR(100) COMMENT '邮箱',8 province VARCHAR(50) COMMENT '省份',9 city VARCHAR(50) COMMENT '城市',10 industry VARCHAR(50) COMMENT '行业',11 source TINYINT COMMENT '来源:1-网站,2-广告,3-活动,4-转介绍,5-其他',12 campaign_id BIGINT COMMENT '营销活动ID',13 status TINYINT DEFAULT 1 COMMENT '状态:1-未处理,2-跟进中,3-已转化,4-无效',14 score INT DEFAULT 0 COMMENT '线索评分',15 owner_user_id BIGINT COMMENT '负责人ID',16 converted_customer_id BIGINT COMMENT '转化客户ID',17 converted_time DATETIME COMMENT '转化时间',18 remark VARCHAR(500) COMMENT '备注',19 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,20 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,21 INDEX idx_lead_no (lead_no),22 INDEX idx_mobile (mobile),23 INDEX idx_status (status),24 INDEX idx_owner (owner_user_id)25) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='销售线索表';5. 跟进记录表 (follow_up)
sql
1CREATE TABLE follow_up (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 related_type TINYINT NOT NULL COMMENT '关联类型:1-客户,2-商机,3-线索',4 related_id BIGINT NOT NULL COMMENT '关联ID',5 follow_up_type TINYINT NOT NULL COMMENT '跟进方式:1-电话,2-邮件,3-拜访,4-会议,5-其他',6 follow_up_time DATETIME NOT NULL COMMENT '跟进时间',7 content TEXT NOT NULL COMMENT '跟进内容',8 next_follow_up_time DATETIME COMMENT '下次跟进时间',9 attachment_url VARCHAR(500) COMMENT '附件URL',10 create_user_id BIGINT NOT NULL COMMENT '创建人ID',11 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,12 INDEX idx_related (related_type, related_id),13 INDEX idx_create_user (create_user_id),14 INDEX idx_create_time (create_time)15) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='跟进记录表';6. 合同表 (contract)
sql
1CREATE TABLE contract (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 contract_no VARCHAR(50) NOT NULL UNIQUE COMMENT '合同编号',4 contract_name VARCHAR(200) NOT NULL COMMENT '合同名称',5 customer_id BIGINT NOT NULL COMMENT '客户ID',6 opportunity_id BIGINT COMMENT '商机ID',7 contract_type TINYINT NOT NULL COMMENT '合同类型:1-销售合同,2-服务合同,3-其他',8 amount DECIMAL(15,2) NOT NULL COMMENT '合同金额',9 start_date DATE NOT NULL COMMENT '开始日期',10 end_date DATE NOT NULL COMMENT '结束日期',11 sign_date DATE COMMENT '签订日期',12 status TINYINT DEFAULT 1 COMMENT '状态:1-草稿,2-待审批,3-审批中,4-已生效,5-已终止',13 owner_user_id BIGINT NOT NULL COMMENT '负责人ID',14 contract_file_url VARCHAR(500) COMMENT '合同文件URL',15 remark VARCHAR(500) COMMENT '备注',16 create_user_id BIGINT COMMENT '创建人ID',17 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,18 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,19 INDEX idx_contract_no (contract_no),20 INDEX idx_customer (customer_id),21 INDEX idx_status (status)22) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合同表';7. 营销活动表 (campaign)
sql
1CREATE TABLE campaign (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 campaign_no VARCHAR(50) NOT NULL UNIQUE COMMENT '活动编号',4 campaign_name VARCHAR(200) NOT NULL COMMENT '活动名称',5 campaign_type TINYINT NOT NULL COMMENT '活动类型:1-线上活动,2-线下活动,3-邮件营销,4-短信营销',6 channel VARCHAR(50) COMMENT '营销渠道',7 budget DECIMAL(15,2) COMMENT '预算',8 actual_cost DECIMAL(15,2) COMMENT '实际花费',9 start_time DATETIME NOT NULL COMMENT '开始时间',10 end_time DATETIME NOT NULL COMMENT '结束时间',11 target_audience VARCHAR(500) COMMENT '目标受众',12 target_count INT COMMENT '目标人数',13 actual_count INT DEFAULT 0 COMMENT '实际触达人数',14 lead_count INT DEFAULT 0 COMMENT '产生线索数',15 conversion_count INT DEFAULT 0 COMMENT '转化数',16 status TINYINT DEFAULT 1 COMMENT '状态:1-计划中,2-进行中,3-已结束,4-已取消',17 owner_user_id BIGINT NOT NULL COMMENT '负责人ID',18 description TEXT COMMENT '活动描述',19 create_user_id BIGINT COMMENT '创建人ID',20 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,21 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,22 INDEX idx_campaign_no (campaign_no),23 INDEX idx_status (status),24 INDEX idx_time (start_time, end_time)25) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='营销活动表';8. 工单表 (ticket)
sql
1CREATE TABLE ticket (2 id BIGINT PRIMARY KEY AUTO_INCREMENT,3 ticket_no VARCHAR(50) NOT NULL UNIQUE COMMENT '工单编号',4 title VARCHAR(200) NOT NULL COMMENT '标题',5 customer_id BIGINT NOT NULL COMMENT '客户ID',6 contact_id BIGINT COMMENT '联系人ID',7 ticket_type TINYINT NOT NULL COMMENT '工单类型:1-咨询,2-投诉,3-售后,4-其他',8 priority TINYINT DEFAULT 0 COMMENT '优先级:0-普通,1-重要,2-紧急',9 status TINYINT DEFAULT 1 COMMENT '状态:1-待处理,2-处理中,3-待回复,4-已解决,5-已关闭',10 channel TINYINT COMMENT '渠道:1-电话,2-邮件,3-在线客服,4-其他',11 description TEXT COMMENT '问题描述',12 solution TEXT COMMENT '解决方案',13 assign_user_id BIGINT COMMENT '处理人ID',14 create_user_id BIGINT COMMENT '创建人ID',15 close_time DATETIME COMMENT '关闭时间',16 satisfaction TINYINT COMMENT '满意度:1-5分',17 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,18 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,19 INDEX idx_ticket_no (ticket_no),20 INDEX idx_customer (customer_id),21 INDEX idx_status (status),22 INDEX idx_assign_user (assign_user_id)23) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工单表';核心业务流程
1. 销售线索转化流程
1线索获取 → 线索评分 → 线索分配 → 跟进 → 线索转化 → 创建客户/商机2 ↓ ↓ ↓ ↓ ↓3(未处理) (评分完成) (跟进中) (持续跟进) (已转化)关键步骤:
- 获取线索(网站表单、营销活动、广告等)
- 线索评分(根据行业、职位、公司规模等打分)
- 线索分配(自动/手动分配给销售人员)
- 销售跟进(电话、邮件、拜访等)
- 线索转化(创建客户和商机)
2. 销售商机管理流程
1创建商机 → 需求分析 → 方案报价 → 谈判签约 → 成交/失败2 ↓ ↓ ↓ ↓ ↓3(初步接触) (需求分析) (方案报价) (谈判) (结束)关键步骤:
- 创建商机(从线索转化或直接创建)
- 需求分析(了解客户需求,评估商机价值)
- 方案报价(制定解决方案,提供报价)
- 谈判签约(商务谈判,签订合同)
- 成交或失败(记录结果和原因)
3. 客户服务工单流程
1创建工单 → 工单分配 → 处理中 → 待回复 → 已解决 → 关闭 → 满意度评价2 ↓ ↓ ↓ ↓ ↓ ↓3(待处理) (已分配) (处理中) (待回复) (已解决) (已关闭)技术实现方案
1. 客户搜索(Elasticsearch)
使用 Elasticsearch 实现客户全文搜索:
java
1@Service2public class CustomerSearchService {3 4 @Autowired5 private ElasticsearchRestTemplate elasticsearchTemplate;6 7 /**8 * 搜索客户9 */10 public PageResult<CustomerVO> searchCustomers(String keyword, int pageNum, int pageSize) {11 // 构建搜索条件12 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();13 14 // 多字段搜索15 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();16 boolQuery.should(QueryBuilders.matchQuery("customerName", keyword))17 .should(QueryBuilders.matchQuery("phone", keyword))18 .should(QueryBuilders.matchQuery("email", keyword))19 .should(QueryBuilders.matchQuery("address", keyword));20 21 queryBuilder.withQuery(boolQuery);22 queryBuilder.withPageable(PageRequest.of(pageNum - 1, pageSize));23 24 // 执行搜索25 SearchHits<CustomerDocument> searchHits = elasticsearchTemplate.search(26 queryBuilder.build(), 27 CustomerDocument.class28 );29 30 // 转换结果31 List<CustomerVO> customers = searchHits.stream()32 .map(hit -> convertToVO(hit.getContent()))33 .collect(Collectors.toList());34 35 return new PageResult<>(customers, searchHits.getTotalHits(), pageNum, pageSize);36 }37}2. 线索评分系统
使用 规则引擎 实现线索自动评分:
java
1@Service2public class LeadScoringService {3 4 /**5 * 计算线索评分6 */7 public int calculateLeadScore(Lead lead) {8 int score = 0;9 10 // 行业评分11 score += getIndustryScore(lead.getIndustry());12 13 // 公司规模评分14 score += getCompanySizeScore(lead.getCompanySize());15 16 // 职位评分17 score += getPositionScore(lead.getPosition());18 19 // 来源评分20 score += getSourceScore(lead.getSource());21 22 // 行为评分(访问页面、下载资料等)23 score += getBehaviorScore(lead.getId());24 25 return Math.min(score, 100); // 最高100分26 }27 28 /**29 * 行业评分30 */31 private int getIndustryScore(String industry) {32 // 根据目标行业打分33 Map<String, Integer> industryScores = Map.of(34 "互联网", 30,35 "金融", 25,36 "制造业", 20,37 "其他", 1038 );39 return industryScores.getOrDefault(industry, 10);40 }41 42 /**43 * 公司规模评分44 */45 private int getCompanySizeScore(String companySize) {46 Map<String, Integer> sizeScores = Map.of(47 "1000人以上", 30,48 "500-1000人", 25,49 "100-500人", 20,50 "100人以下", 1051 );52 return sizeScores.getOrDefault(companySize, 10);53 }54}3. 销售漏斗分析
java
1@Service2public class SalesFunnelService {3 4 @Autowired5 private OpportunityMapper opportunityMapper;6 7 /**8 * 获取销售漏斗数据9 */10 public SalesFunnelVO getSalesFunnel(Long userId, LocalDate startDate, LocalDate endDate) {11 // 查询各阶段的商机数量和金额12 List<OpportunityStageStats> stageStats = opportunityMapper.countByStage(13 userId, startDate, endDate14 );15 16 SalesFunnelVO funnel = new SalesFunnelVO();17 18 for (OpportunityStageStats stats : stageStats) {19 switch (stats.getStage()) {20 case 1: // 初步接触21 funnel.setInitialContactCount(stats.getCount());22 funnel.setInitialContactAmount(stats.getAmount());23 break;24 case 2: // 需求分析25 funnel.setNeedsAnalysisCount(stats.getCount());26 funnel.setNeedsAnalysisAmount(stats.getAmount());27 break;28 case 3: // 方案报价29 funnel.setProposalCount(stats.getCount());30 funnel.setProposalAmount(stats.getAmount());31 break;32 case 4: // 谈判33 funnel.setNegotiationCount(stats.getCount());34 funnel.setNegotiationAmount(stats.getAmount());35 break;36 case 5: // 成交37 funnel.setWonCount(stats.getCount());38 funnel.setWonAmount(stats.getAmount());39 break;40 }41 }42 43 // 计算转化率44 funnel.calculateConversionRates();45 46 return funnel;47 }48}4. 营销自动化
使用 定时任务 + 消息队列 实现营销自动化:
java
1@Component2public class MarketingAutomationTask {3 4 @Autowired5 private LeadService leadService;6 7 @Autowired8 private EmailService emailService;9 10 @Autowired11 private RabbitTemplate rabbitTemplate;12 13 /**14 * 自动跟进未处理的线索15 */16 @Scheduled(cron = "0 0 9 * * ?") // 每天9点执行17 public void autoFollowUpLeads() {18 // 查询未处理的线索(创建时间超过24小时)19 LocalDateTime yesterday = LocalDateTime.now().minusDays(1);20 List<Lead> unprocessedLeads = leadService.findUnprocessedLeads(yesterday);21 22 for (Lead lead : unprocessedLeads) {23 // 发送提醒邮件给负责人24 rabbitTemplate.convertAndSend(25 "crm.marketing.exchange",26 "lead.follow.up.reminder",27 new LeadFollowUpEvent(lead.getId(), lead.getOwnerUserId())28 );29 }30 }31 32 /**33 * 自动发送生日祝福34 */35 @Scheduled(cron = "0 0 8 * * ?") // 每天8点执行36 public void sendBirthdayGreetings() {37 // 查询今天生日的联系人38 List<Contact> birthdayContacts = leadService.findBirthdayContacts(LocalDate.now());39 40 for (Contact contact : birthdayContacts) {41 // 发送生日祝福邮件42 emailService.sendBirthdayEmail(contact);43 }44 }45}5. 客户标签系统
java
1@Service2public class CustomerTagService {3 4 @Autowired5 private CustomerMapper customerMapper;6 7 @Autowired8 private CustomerTagMapper customerTagMapper;9 10 /**11 * 自动打标签12 */13 @Transactional14 public void autoTagCustomer(Long customerId) {15 Customer customer = customerMapper.selectById(customerId);16 17 List<String> tags = new ArrayList<>();18 19 // 根据行业打标签20 if ("互联网".equals(customer.getIndustry())) {21 tags.add("互联网行业");22 }23 24 // 根据客户等级打标签25 if (customer.getLevel() == 1) {26 tags.add("重点客户");27 }28 29 // 根据成交金额打标签30 BigDecimal totalAmount = customerMapper.getTotalOrderAmount(customerId);31 if (totalAmount.compareTo(new BigDecimal("100000")) > 0) {32 tags.add("大客户");33 }34 35 // 根据购买频率打标签36 int orderCount = customerMapper.getOrderCount(customerId);37 if (orderCount > 10) {38 tags.add("老客户");39 }40 41 // 保存标签42 for (String tagName : tags) {43 customerTagMapper.addTag(customerId, tagName);44 }45 }46}6. 权限控制(数据权限)
java
1@Service2public class CustomerPermissionService {3 4 /**5 * 检查用户是否有权限访问客户6 */7 public boolean hasPermission(Long userId, Long customerId) {8 Customer customer = customerMapper.selectById(customerId);9 10 if (customer == null) {11 return false;12 }13 14 // 负责人有权限15 if (customer.getOwnerUserId().equals(userId)) {16 return true;17 }18 19 // 管理员有权限20 if (isAdmin(userId)) {21 return true;22 }23 24 // 同部门有权限(根据配置)25 if (isSameDepartment(userId, customer.getOwnerUserId())) {26 return true;27 }28 29 return false;30 }31}API 接口设计
1. 客户接口
java
1@RestController2@RequestMapping("/api/crm/customer")3public class CustomerController {4 5 @Autowired6 private CustomerService customerService;7 8 /**9 * 创建客户10 */11 @PostMapping("")12 public Result<Long> createCustomer(@RequestBody @Valid CustomerDTO dto) {13 Long customerId = customerService.createCustomer(dto);14 return Result.success(customerId);15 }16 17 /**18 * 客户列表19 */20 @GetMapping("")21 public Result<PageResult<CustomerVO>> listCustomers(22 @RequestParam(required = false) String keyword,23 @RequestParam(required = false) Integer level,24 @RequestParam(required = false) Integer status,25 @RequestParam(defaultValue = "1") Integer pageNum,26 @RequestParam(defaultValue = "20") Integer pageSize) {27 28 PageResult<CustomerVO> result = customerService.listCustomers(29 keyword, level, status, pageNum, pageSize30 );31 return Result.success(result);32 }33 34 /**35 * 客户详情36 */37 @GetMapping("/{customerId}")38 public Result<CustomerDetailVO> getCustomerDetail(@PathVariable Long customerId) {39 CustomerDetailVO vo = customerService.getCustomerDetail(customerId);40 return Result.success(vo);41 }42 43 /**44 * 添加跟进记录45 */46 @PostMapping("/{customerId}/follow-up")47 public Result<Void> addFollowUp(48 @PathVariable Long customerId,49 @RequestBody @Valid FollowUpDTO dto) {50 51 customerService.addFollowUp(customerId, dto);52 return Result.success();53 }54}2. 商机接口
java
1@RestController2@RequestMapping("/api/crm/opportunity")3public class OpportunityController {4 5 @Autowired6 private OpportunityService opportunityService;7 8 /**9 * 创建商机10 */11 @PostMapping("")12 public Result<Long> createOpportunity(@RequestBody @Valid OpportunityDTO dto) {13 Long opportunityId = opportunityService.createOpportunity(dto);14 return Result.success(opportunityId);15 }16 17 /**18 * 更新商机阶段19 */20 @PutMapping("/{opportunityId}/stage")21 public Result<Void> updateStage(22 @PathVariable Long opportunityId,23 @RequestParam Integer stage) {24 25 opportunityService.updateStage(opportunityId, stage);26 return Result.success();27 }28 29 /**30 * 商机成交31 */32 @PostMapping("/{opportunityId}/win")33 public Result<Void> winOpportunity(34 @PathVariable Long opportunityId,35 @RequestBody @Valid WinOpportunityDTO dto) {36 37 opportunityService.winOpportunity(opportunityId, dto);38 return Result.success();39 }40 41 /**42 * 商机失败43 */44 @PostMapping("/{opportunityId}/lose")45 public Result<Void> loseOpportunity(46 @PathVariable Long opportunityId,47 @RequestParam String loseReason) {48 49 opportunityService.loseOpportunity(opportunityId, loseReason);50 return Result.success();51 }52 53 /**54 * 销售漏斗55 */56 @GetMapping("/funnel")57 public Result<SalesFunnelVO> getSalesFunnel(58 @RequestParam(required = false) Long userId,59 @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,60 @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {61 62 SalesFunnelVO vo = opportunityService.getSalesFunnel(userId, startDate, endDate);63 return Result.success(vo);64 }65}3. 销售线索接口
java
1@RestController2@RequestMapping("/api/crm/lead")3public class LeadController {4 5 @Autowired6 private LeadService leadService;7 8 /**9 * 创建线索10 */11 @PostMapping("")12 public Result<Long> createLead(@RequestBody @Valid LeadDTO dto) {13 Long leadId = leadService.createLead(dto);14 return Result.success(leadId);15 }16 17 /**18 * 线索转化19 */20 @PostMapping("/{leadId}/convert")21 public Result<ConvertResultVO> convertLead(22 @PathVariable Long leadId,23 @RequestBody @Valid LeadConvertDTO dto) {24 25 ConvertResultVO result = leadService.convertLead(leadId, dto);26 return Result.success(result);27 }28 29 /**30 * 批量分配线索31 */32 @PostMapping("/batch-assign")33 public Result<Void> batchAssignLeads(34 @RequestBody @Valid BatchAssignDTO dto) {35 36 leadService.batchAssignLeads(dto.getLeadIds(), dto.getUserId());37 return Result.success();38 }39}4. 数据分析接口
java
1@RestController2@RequestMapping("/api/crm/analytics")3public class AnalyticsController {4 5 @Autowired6 private AnalyticsService analyticsService;7 8 /**9 * 销售报表10 */11 @GetMapping("/sales-report")12 public Result<SalesReportVO> getSalesReport(13 @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,14 @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,15 @RequestParam(required = false) Long userId) {16 17 SalesReportVO report = analyticsService.getSalesReport(startDate, endDate, userId);18 return Result.success(report);19 }20 21 /**22 * 客户分析23 */24 @GetMapping("/customer-analytics")25 public Result<CustomerAnalyticsVO> getCustomerAnalytics() {26 CustomerAnalyticsVO analytics = analyticsService.getCustomerAnalytics();27 return Result.success(analytics);28 }29 30 /**31 * 销售业绩排行32 */33 @GetMapping("/sales-ranking")34 public Result<List<SalesRankingVO>> getSalesRanking(35 @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,36 @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {37 38 List<SalesRankingVO> ranking = analyticsService.getSalesRanking(startDate, endDate);39 return Result.success(ranking);40 }41}性能优化方案
1. 数据库优化
- 合理建立索引(客户编号、负责人、状态等)
- 使用读写分离
- 对历史数据进行分区
- 定期归档历史数据
2. 缓存优化
- 缓存客户基础信息
- 缓存用户权限数据
- 缓存统计数据(短时缓存)
3. 搜索优化
- 使用 Elasticsearch 实现全文搜索
- 异步更新搜索索引
4. 大数据分析
- 使用 ClickHouse 存储分析数据
- 定时同步数据到 ClickHouse
- 复杂报表查询走 ClickHouse
扩展功能
1. AI 智能推荐
- 智能线索分配(根据销售特长、历史成交率等)
- 智能商机预测(预测成交概率)
- 智能客户画像
2. 移动端支持
- 移动端 APP(React Native / Flutter)
- 外勤签到
- 移动审批
3. 集成第三方系统
- 邮件系统集成(发送/接收邮件)
- 短信平台集成
- 企业微信/钉钉集成
- 财务系统集成
4. 高级分析
- 客户流失预警
- RFM 客户分析
- 客户生命周期价值分析
- 销售预测
总结
CRM 系统的核心在于:
- 以客户为中心:所有功能围绕客户展开
- 销售流程规范化:通过系统规范销售流程,提高销售效率
- 数据驱动决策:通过数据分析为决策提供支持
- 营销自动化:提高营销效率,降低营销成本
- 客户满意度提升:通过优质服务提升客户满意度
本设计方案基于 Spring Cloud 微服务架构,采用主流技术栈,可满足中大型企业的客户关系管理需求。
评论