1. 项目概述与技术栈选型
这个前后端分离的客户关系管理系统采用了当前企业级开发中最主流的全栈技术组合。后端基于SpringBoot 2.7.x构建,前端使用Vue3+TypeScript实现,数据持久层采用MyBatis-Plus增强,数据库选用MySQL 8.0。这种技术组合在2023年企业级应用开发中已经成为事实上的标准配置,尤其适合需要快速迭代的中大型业务系统。
为什么选择这样的技术栈?SpringBoot的自动配置和起步依赖能极大简化后端服务搭建,Vue3的Composition API相比Options API更适合复杂前端状态管理,而MyBatis-Plus在保留MyBatis灵活性的同时,通过内置通用Mapper大幅减少了样板代码。MySQL作为最成熟的关系型数据库之一,在事务处理和复杂查询场景下表现稳定。
提示:实际开发中建议锁定具体版本号,如SpringBoot 2.7.15、Vue3 3.3.x,避免自动升级带来的兼容性问题
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计与核心模块
2.1 前后端分离架构实现
系统采用典型的前后端分离架构,通过RESTful API进行数据交互。前端部署在Nginx服务器,后端使用内嵌Tomcat容器,两者通过HTTPS协议通信。这种架构的优势在于:
- 开发解耦:前后端可以并行开发,只需约定好接口规范
- 部署独立:前端静态资源可部署在CDN,后端服务可水平扩展
- 技术栈灵活:前后端可以分别选择最适合的技术
关键通信配置示例(SpringBoot端):
java复制@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://your-frontend-domain.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true)
.maxAge(3600);
}
}
2.2 核心功能模块划分
系统主要包含以下业务模块:
- 客户管理:客户信息CRUD、标签管理、跟进记录
- 销售管理:商机跟踪、合同管理、业绩统计
- 服务管理:工单系统、满意度评价
- 报表中心:销售漏斗、客户分布、服务响应分析
- 系统管理:用户权限、角色配置、操作日志
每个模块都遵循领域驱动设计(DDD)原则,采用分层架构:
- 表现层:Vue3组件+Pinia状态管理
- 应用层:SpringBoot Controller
- 领域层:Service业务逻辑
- 基础设施层:MyBatis Mapper+MySQL
3. 关键技术实现细节
3.1 后端核心实现
3.1.1 SpringBoot应用配置
采用多环境配置方案,通过application-{profile}.yml管理不同环境参数。关键配置包括:
- 数据源配置(连接池使用HikariCP)
- MyBatis-Plus分页插件
- 全局异常处理
- 接口文档(Swagger+Knife4j)
示例数据源配置:
yaml复制spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/crm_db?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: yourpassword
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
3.1.2 MyBatis-Plus高级应用
系统充分利用了MyBatis-Plus的特性:
- 通用Mapper:减少90%的单表CRUD代码
- Lambda查询:类型安全的查询条件构造
- 自动填充:创建时间、更新时间等通用字段处理
- 乐观锁:解决并发更新问题
示例Service实现:
java复制@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer>
implements ICustomerService {
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateCustomer(CustomerDTO dto) {
LambdaUpdateWrapper<Customer> wrapper = Wrappers.lambdaUpdate();
wrapper.eq(Customer::getId, dto.getId())
.set(Customer::getName, dto.getName())
.set(Customer::getStatus, dto.getStatus());
return update(wrapper);
}
}
3.2 前端核心实现
3.2.1 Vue3组合式API应用
前端采用Vue3的setup语法糖,配合TypeScript实现类型安全。状态管理使用Pinia替代Vuex,模块化设计更清晰。
典型组件示例:
vue复制<script setup lang="ts">
import { ref, computed } from 'vue'
import { useCustomerStore } from '@/stores/customer'
const store = useCustomerStore()
const searchQuery = ref('')
const filteredCustomers = computed(() => {
return store.customers.filter(c =>
c.name.includes(searchQuery.value) ||
c.phone.includes(searchQuery.value)
)
})
function loadCustomers() {
store.fetchCustomers()
}
</script>
3.2.2 前端工程化配置
项目基于Vite构建,配置了:
- 路径别名(@指向src目录)
- 代理配置(解决开发环境跨域)
- 按需自动导入(组件、Composables等)
- ESLint+Prettier代码规范
vite.config.ts关键片段:
typescript复制export default defineConfig({
plugins: [
vue(),
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: 'src/auto-imports.d.ts',
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
})
4. 数据库设计与优化
4.1 核心表结构设计
系统采用符合第三范式的数据库设计,主要包含以下表:
- sys_user(系统用户)
- sys_role(角色)
- customer(客户)
- customer_contact(联系人)
- sales_opportunity(销售机会)
- service_ticket(服务工单)
示例建表语句(MySQL):
sql复制CREATE TABLE `customer` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '客户名称',
`type` tinyint NOT NULL COMMENT '客户类型',
`industry` varchar(50) DEFAULT NULL COMMENT '所属行业',
`level` tinyint DEFAULT '1' COMMENT '客户等级',
`status` tinyint DEFAULT '0' COMMENT '状态',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`),
KEY `idx_industry` (`industry`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
4.2 查询性能优化
针对CRM系统常见的复杂查询场景,我们采取了以下优化措施:
- 合理设计索引:为高频查询字段建立组合索引
- 分页查询优化:使用MyBatis-Plus的Page对象配合MySQL LIMIT
- 大表关联查询:使用JOIN优化替代子查询
- 定期执行ANALYZE TABLE更新统计信息
分页查询示例:
java复制// Service层
public PageResult<CustomerVO> queryCustomers(CustomerQuery query) {
Page<Customer> page = new Page<>(query.getPageNum(), query.getPageSize());
LambdaQueryWrapper<Customer> wrapper = Wrappers.lambdaQuery();
wrapper.like(StringUtils.isNotBlank(query.getName()), Customer::getName, query.getName())
.eq(query.getLevel() != null, Customer::getLevel, query.getLevel());
Page<Customer> result = customerMapper.selectPage(page, wrapper);
return PageResult.of(result, this::convertToVO);
}
5. 系统安全与部署
5.1 安全防护措施
系统实现了多层安全防护:
- 认证授权:JWT+Spring Security
- 数据安全:敏感字段AES加密
- XSS防护:前端DOMPurify+后端Jackson转义
- CSRF防护:SameSite Cookie+自定义Header校验
- SQL注入防护:MyBatis参数绑定
Spring Security配置核心代码:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
}
5.2 部署方案
系统支持多种部署方式:
- 传统部署:前端Nginx+后端Docker
- 云原生部署:Kubernetes集群
- 全栈Docker:使用docker-compose编排
docker-compose.yml示例:
yaml复制version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: crm_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/crm_db
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: rootpass
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
volumes:
mysql_data:
6. 开发经验与最佳实践
6.1 前后端协作规范
- 接口文档:使用Swagger+Knife4j生成实时文档
- 数据格式:统一采用JSON,日期字段使用ISO8601格式
- 状态码:遵循RESTful规范,自定义业务状态码
- 错误处理:全局异常处理+错误码枚举
6.2 性能优化技巧
- 前端懒加载:路由级和组件级懒加载
- 接口缓存:Spring Cache+Redis
- 批量操作:MyBatis批量插入/更新
- 异步处理:@Async注解处理非核心流程
批量插入示例:
java复制@Transactional
public void batchImportCustomers(List<Customer> customers) {
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH);
CustomerMapper mapper = session.getMapper(CustomerMapper.class);
customers.forEach(mapper::insert);
session.commit();
session.clearCache();
session.close();
}
6.3 常见问题解决
- Vue3响应式丢失问题:使用toRefs保持响应式
- MyBatis更新null值问题:使用动态SQL或全局配置
- SpringBoot事务失效:检查代理模式和异常捕获
- 跨域问题:确保Nginx和后端配置一致
MyBatis-Plus全局配置示例:
yaml复制mybatis-plus:
global-config:
db-config:
logic-not-delete-value: 0
logic-delete-value: 1
insert-strategy: not_null
update-strategy: not_null
7. 项目扩展与二次开发
7.1 功能扩展方向
- 集成工作流引擎(如Activiti)实现审批流程
- 添加即时通讯模块(WebSocket)
- 对接第三方平台(微信、支付宝、企业微信)
- 实现数据大屏可视化(ECharts)
7.2 技术升级路径
- 微服务化:Spring Cloud Alibaba
- 前端架构升级:微前端(qiankun)
- 数据库扩展:读写分离+分库分表
- 监控体系:Prometheus+Grafana
Spring Cloud集成示例:
java复制// 在application.yml中新增
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
dashboard: 127.0.0.1:8088
// 主类添加注解
@SpringBootApplication
@EnableDiscoveryClient
public class CrmApplication {
public static void main(String[] args) {
SpringApplication.run(CrmApplication.class, args);
}
}
在实际开发中,我们团队发现TypeScript的类型系统能有效减少前后端联调时的数据类型错误,建议在复杂项目中全面采用。另外,MyBatis-Plus的Lambda表达式写法虽然直观,但在复杂动态SQL场景下,传统的XML映射文件可能更易维护,需要根据具体场景权衡选择
