1. 项目背景与核心需求
汽车4S店作为集整车销售(Sale)、零配件(Sparepart)、售后服务(Service)、信息反馈(Survey)于一体的综合服务商,客户关系管理(CRM)系统的建设直接关系到经销商的核心竞争力。传统Excel表格+纸质档案的管理方式存在三大痛点:
- 客户信息分散在各销售顾问手中,离职导致客户资源流失
- 服务过程缺乏标准化记录,难以追踪历史服务记录
- 营销活动效果无法量化评估,决策依赖经验判断
我们设计的系统需要实现三个核心目标:
- 客户生命周期数字化管理(从潜客跟进到老客户维系)
- 服务流程标准化(预约→接待→施工→质检→回访)
- 数据驱动的决策支持(转化率分析、客户价值分层)
实际开发中发现:4S店员工平均年龄偏大,系统必须兼顾功能完备性与操作简便性,这是商业软件与学术项目的本质区别。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 基础技术栈组合
选择SpringBoot 2.7 + MyBatis-Plus + MySQL 8.0的组合主要基于:
- 开发效率:SpringBoot的starter机制快速集成常用组件
- 数据安全:MySQL的binlog实现操作留痕(合规要求)
- 扩展性:预留Dubbo接口支持未来与DMS系统对接
java复制// 典型的多租户数据隔离配置示例
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(
new TenantLineHandler() {
@Override
public String getTenantIdColumn() {
return "dealer_id"; // 按经销商ID隔离
}
@Override
public Expression getTenantId() {
return new LongValue(1); // 实际从Shiro获取
}
}
));
return interceptor;
}
}
2.2 微服务拆分策略
虽然单体架构也能满足毕业设计要求,但考虑到真实业务场景,采用模块化设计:
| 模块 | 技术要点 | 通信方式 |
|---|---|---|
| crm-core | 客户主数据管理 | REST |
| service-app | 预约/工单/配件管理 | Feign |
| data-report | 可视化分析(集成ECharts) | WebSocket |
| wechat-api | 对接微信公众号消息模板 | HTTP |
3. 核心业务逻辑实现
3.1 客户画像构建
通过HanLP分词技术处理客户咨询记录(实际开发使用阿里云NLP服务更稳定):
java复制public Map<String, Integer> extractKeywords(String text) {
List<Term> termList = HanLP.segment(text);
return termList.stream()
.filter(t -> t.nature.toString().startsWith("n")) // 提取名词
.collect(Collectors.groupingBy(
Term::word,
Collectors.summingInt(e -> 1)
));
}
3.2 工单状态机设计
维修工单涉及多部门协作,采用状态模式避免if-else嵌套:
mermaid复制stateDiagram
[*] --> PENDING_APPOINTMENT
PENDING_APPOINTMENT --> CONFIRMED: 客户确认
CONFIRMED --> IN_SERVICE: 接待开单
IN_SERVICE --> WAITING_PARTS: 需订购配件
WAITING_PARTS --> IN_SERVICE: 配件到货
IN_SERVICE --> QUALITY_CHECK: 施工完成
QUALITY_CHECK --> PAYMENT: 质检通过
PAYMENT --> COMPLETED: 结算完成
COMPLETED --> [*]
实际项目中需处理异常流:客户取消(触发退款)、增项确认(短信签名验证)、紧急救援(自动派单)
4. 典型功能实现细节
4.1 预约冲突检测
使用时间重叠算法防止同一工位重复预约:
sql复制SELECT COUNT(*) FROM appointment
WHERE mechanic_id = #{mechanicId}
AND #{startTime} < end_time
AND #{endTime} > start_time
AND status NOT IN ('CANCELED','COMPLETED')
4.2 配件库存预警
基于移动加权平均法的库存成本计算:
java复制public void updateInventoryCost(Long partId, Integer quantity, BigDecimal price) {
Inventory inventory = inventoryMapper.selectById(partId);
BigDecimal totalCost = inventory.getTotalCost()
.add(price.multiply(new BigDecimal(quantity)));
int totalQuantity = inventory.getQuantity() + quantity;
inventory.setAverageCost(totalCost.divide(
new BigDecimal(totalQuantity), 2, RoundingMode.HALF_UP));
inventoryMapper.updateById(inventory);
}
5. 性能优化实践
5.1 热数据缓存策略
客户基本信息使用Redis Hash存储,键设计示例:
code复制customer:10086 -> {
"name": "张三",
"mobile": "138****1234",
"lastServiceDate": "2023-08-15"
}
5.2 批量导入优化
使用MyBatis的BatchExecutor提升数据初始化效率:
java复制@Transactional
public void batchImport(List<Customer> customers) {
SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory()
.openSession(ExecutorType.BATCH, false);
CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);
customers.forEach(mapper::insert);
sqlSession.commit();
sqlSession.clearCache();
}
6. 安全防护措施
6.1 敏感数据加密
手机号实现AES加密存储(需考虑模糊查询问题):
java复制@Column
@Convert(converter = CryptoConverter.class)
private String mobile;
6.2 操作日志审计
基于Spring AOP记录关键操作:
java复制@AfterReturning(pointcut = "@annotation(auditLog)", returning = "result")
public void afterReturning(JoinPoint jp, AuditLog auditLog, Object result) {
String operation = auditLog.value();
String params = Arrays.toString(jp.getArgs());
logService.save(new SysLog(
ShiroUtils.getUserId(),
operation,
params,
Result.SUCCESS
));
}
7. 部署与监控方案
7.1 多环境配置
使用Profile区分开发/测试/生产环境:
yaml复制# application-prod.yml
spring:
datasource:
url: jdbc:mysql://master.db:3306/crm?useSSL=false&serverTimezone=Asia/Shanghai
username: ${DB_USER}
password: ${DB_PWD}
redis:
host: redis-cluster
7.2 健康检查端点
自定义健康检查指标:
java复制@Component
public class DbHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
DataSource ds = SpringUtils.getBean(DataSource.class);
ds.getConnection().close();
return Health.up().build();
} catch (Exception e) {
return Health.down(e).build();
}
}
}
8. 毕业设计扩展建议
- 数据可视化:集成Apache ECharts展示客户转化漏斗
- 智能推荐:基于协同过滤算法实现保养套餐推荐
- 移动端适配:使用Uniapp开发微信小程序版本
- 压力测试:使用JMeter模拟200并发预约请求
实际答辩时建议准备:ER图(PowerDesigner)、用例图(StarUML)、系统架构图(Draw.io)三种不同维度的设计素材
