1. 项目背景与需求分析
在当今数字化商业环境中,客户关系管理(CRM)系统已成为中小企业提升运营效率的关键工具。传统CRM系统往往存在部署成本高、功能冗余等问题,而基于SpringBoot的轻量级解决方案正好填补了这一市场空白。
这个毕业设计项目的核心目标是构建一个面向中小企业的客户资源与售后统一管理平台。与大型企业级CRM不同,我们更注重:
- 快速部署:利用SpringBoot的嵌入式容器特性
- 成本控制:采用开源技术栈
- 功能聚焦:只保留中小企业最需要的核心模块
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术选型决策
后端技术栈:
- SpringBoot 2.7.x(平衡稳定性和新特性)
- Spring Data JPA(简化数据访问层)
- Spring Security(基础认证授权)
- Lombok(减少样板代码)
前端技术栈:
- Thymeleaf(服务端渲染,降低前端复杂度)
- Bootstrap 5(响应式布局)
- jQuery(基础交互)
选择理由:这套组合在保证功能完整性的同时,最大程度降低了学习曲线和运维成本,特别适合作为毕业设计的技术基础。
2.2 模块划分
系统采用经典的三层架构,主要模块包括:
code复制src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── crm/
│ │ ├── config/ # 配置类
│ │ ├── controller/ # 控制器
│ │ ├── model/ # 实体类
│ │ ├── repository/ # 数据访问
│ │ ├── service/ # 业务逻辑
│ │ └── CrmApplication.java # 启动类
│ └── resources/
│ ├── static/ # 静态资源
│ ├── templates/ # 模板文件
│ └── application.yml # 配置文件
3. 核心功能实现
3.1 客户信息管理模块
实体类设计示例:
java复制@Entity
@Data
@NoArgsConstructor
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String name;
@Pattern(regexp = "^1[3-9]\\d{9}$")
private String phone;
@Email
private String email;
@Enumerated(EnumType.STRING)
private CustomerLevel level; // VIP/普通/潜在
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
private List<ServiceRecord> serviceRecords;
}
典型业务场景实现:
java复制@Service
@RequiredArgsConstructor
public class CustomerService {
private final CustomerRepository customerRepo;
@Transactional(readOnly = true)
public Page<Customer> searchCustomers(String keyword, Pageable pageable) {
Specification<Customer> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.hasText(keyword)) {
String pattern = "%" + keyword + "%";
predicates.add(cb.or(
cb.like(root.get("name"), pattern),
cb.like(root.get("phone"), pattern),
cb.like(root.get("email"), pattern)
));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
return customerRepo.findAll(spec, pageable);
}
}
3.2 售后工单系统
采用状态机模式管理工单生命周期:
java复制public enum TicketStatus {
OPEN, ASSIGNED, PROCESSING,
RESOLVED, CLOSED, REOPENED
}
@Entity
@Data
public class ServiceTicket {
@Id @GeneratedValue
private Long id;
@ManyToOne
private Customer customer;
private String title;
private String description;
@Enumerated(EnumType.STRING)
private TicketStatus status;
@CreationTimestamp
private LocalDateTime createTime;
@UpdateTimestamp
private LocalDateTime updateTime;
public void changeStatus(TicketStatus newStatus) {
// 实现状态转换校验逻辑
this.status = newStatus;
}
}
4. 关键技术难点与解决方案
4.1 性能优化实践
缓存策略实现:
java复制@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(
"customers", "tickets", "stats"
);
}
}
@Service
@RequiredArgsConstructor
public class CustomerServiceImpl implements CustomerService {
private final CustomerRepository repo;
@Cacheable(value = "customers", key = "#id")
public Customer getById(Long id) {
return repo.findById(id).orElseThrow();
}
@CacheEvict(value = "customers", key = "#customer.id")
public Customer update(Customer customer) {
return repo.save(customer);
}
}
4.2 安全防护措施
基础安全配置:
java复制@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final UserDetailsService userDetailsService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/js/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.rememberMe()
.key("uniqueAndSecret")
.userDetailsService(userDetailsService);
return http.build();
}
}
5. 项目部署与测试
5.1 多环境配置
application.yml配置示例:
yaml复制spring:
profiles:
active: dev
---
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:h2:mem:crmdb
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
path: /h2-console
---
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:mysql://localhost:3306/crm_prod
username: crm_user
password: ${DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: validate
5.2 测试策略
集成测试示例:
java复制@SpringBootTest
@AutoConfigureMockMvc
class CustomerControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
void shouldCreateCustomer() throws Exception {
Customer customer = new Customer();
customer.setName("测试客户");
customer.setPhone("13800138000");
mockMvc.perform(post("/api/customers")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(customer)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("测试客户"));
}
}
6. 项目扩展方向
在实际部署后,可以考虑以下增强方案:
- 微信集成:通过微信公众号接口实现客户自助服务
java复制@RestController
@RequestMapping("/wechat")
public class WechatController {
@GetMapping("/auth")
public String auth(@RequestParam String signature,
@RequestParam String timestamp,
@RequestParam String nonce,
@RequestParam String echostr) {
// 实现微信验证逻辑
return echostr;
}
}
- 数据分析模块:使用Spring Batch定期生成客户行为报告
java复制@Configuration
@RequiredArgsConstructor
public class ReportJobConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job monthlyReportJob() {
return jobBuilderFactory.get("monthlyReport")
.start(generateReportStep())
.next(sendEmailStep())
.build();
}
@Bean
public Step generateReportStep() {
return stepBuilderFactory.get("generateReport")
.tasklet((contribution, chunkContext) -> {
// 生成报表逻辑
return RepeatStatus.FINISHED;
})
.build();
}
}
- 微服务改造:将系统拆分为客户服务、工单服务等独立模块,使用Spring Cloud实现服务治理
在开发过程中,我特别建议关注以下几点经验:
- 使用Flyway管理数据库变更,避免手动执行SQL脚本
- 对敏感操作添加@Transactional注解时,注意设置合适的隔离级别
- 前端表单验证要和服务端验证双重保障
- 定期备份H2数据库文件(开发环境)
