1. 项目概述:全栈CRM系统架构解析
这套基于Java技术栈的CRM系统源码采用了当前主流的前后端分离架构,前端使用Vue.js框架开发微信小程序,后端采用SpringBoot构建RESTful API服务,数据存储选用MySQL关系型数据库。这种技术组合在2023年的企业级应用开发中具有典型代表性,既保证了开发效率又兼顾了系统性能。
我在实际部署这套系统时发现,其模块化设计非常清晰:客户管理模块采用树形组织结构,销售漏斗模块内置了可视化分析看板,而合同管理模块则整合了电子签章接口。特别值得一提的是移动端适配方案——通过uni-app框架实现了一套代码同时编译到微信小程序和H5页面,这在需要快速迭代的业务场景中优势明显。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术栈深度剖析
2.1 Vue前端架构设计
前端工程采用Vue 2.6 + Vant Weapp组件库的解决方案,通过自定义webpack配置实现了以下优化:
- 按需加载组件(babel-plugin-import)
- 多环境变量配置(.env.development/.env.production)
- SVG图标雪碧图处理(svg-sprite-loader)
javascript复制// 典型页面结构示例
<template>
<van-cell-group>
<van-field
v-model="searchKey"
placeholder="输入客户名称/电话"
@change="handleSearch"
/>
</van-cell-group>
<van-list
v-model:loading="loading"
:finished="finished"
@load="onLoad"
>
<customer-card
v-for="item in list"
:key="item.id"
:data="item"
/>
</van-list>
</template>
重要提示:Vue 2项目若需要迁移到Vue 3,需特别注意composition API的适配和Vant组件库的版本兼容问题
2.2 SpringBoot后端核心技术
后端工程采用SpringBoot 2.7.x版本,主要技术亮点包括:
- 多数据源动态切换(AbstractRoutingDataSource)
- JWT+Redis实现的无状态认证
- 基于注解的日志切面(@LogOperation)
- 阿里云OSS文件存储集成
java复制// 典型Controller示例
@RestController
@RequestMapping("/api/customer")
public class CustomerController {
@Autowired
private CustomerService customerService;
@GetMapping("/list")
@RequiresPermissions("customer:list")
public R list(@RequestParam Map<String, Object> params) {
PageUtils page = customerService.queryPage(params);
return R.ok().put("data", page);
}
}
数据库设计遵循第三范式,核心表包括:
- sys_user(用户表)
- crm_customer(客户表)
- crm_contact(联系人表)
- crm_contract(合同表)
- crm_follow(跟进记录表)
3. 系统部署实战指南
3.1 开发环境搭建
-
基础软件准备:
- JDK 1.8+(推荐Amazon Corretto 11)
- MySQL 5.7+(注意字符集设置为utf8mb4)
- Redis 6.x
- Node.js 14.x + npm 6.x
-
IDE配置建议:
- IntelliJ IDEA(安装Lombok插件)
- VS Code(配置Vetur和ESLint插件)
- HBuilderX(小程序开发调试)
3.2 数据库初始化
执行项目中的SQL脚本时需注意:
sql复制-- 字符集设置示例
CREATE DATABASE `crm_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 用户表结构示例
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`salt` varchar(20) COMMENT '加密盐',
`mobile` varchar(20) COMMENT '手机号',
`status` tinyint COMMENT '状态',
`create_time` datetime COMMENT '创建时间',
PRIMARY KEY (`user_id`),
UNIQUE INDEX (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户';
3.3 前后端联调要点
- 跨域解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true)
.maxAge(3600);
}
}
- 接口文档生成:
使用Knife4j增强Swagger文档:
xml复制<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
4. 二次开发实战技巧
4.1 扩展客户标签功能
在原有客户管理模块基础上,增加多标签支持:
- 新建标签表:
sql复制CREATE TABLE `crm_tag` (
`tag_id` int NOT NULL AUTO_INCREMENT,
`tag_name` varchar(50) NOT NULL,
`color` varchar(20) DEFAULT '#1890ff',
PRIMARY KEY (`tag_id`)
);
- 建立关联关系表:
sql复制CREATE TABLE `crm_customer_tag` (
`id` int NOT NULL AUTO_INCREMENT,
`customer_id` bigint NOT NULL,
`tag_id` int NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_customer_tag` (`customer_id`,`tag_id`)
);
- 后端实现标签关联逻辑:
java复制public void addTags(Long customerId, List<Long> tagIds) {
// 先删除原有关联
customerTagDao.deleteByCustomerId(customerId);
// 批量插入新关联
List<CustomerTagEntity> list = tagIds.stream()
.map(tagId -> {
CustomerTagEntity entity = new CustomerTagEntity();
entity.setCustomerId(customerId);
entity.setTagId(tagId);
return entity;
}).collect(Collectors.toList());
customerTagDao.insertBatch(list);
}
4.2 移动端性能优化方案
- 图片懒加载:
vue复制<template>
<img v-lazy="item.avatar" alt="客户头像">
</template>
<script>
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
preLoad: 1.3,
loading: require('@/assets/loading.gif'),
attempt: 3
})
</script>
- 接口数据缓存:
javascript复制// 使用localStorage缓存常用数据
export function getDepartmentList() {
const cache = localStorage.getItem('deptCache')
if (cache) {
return Promise.resolve(JSON.parse(cache))
}
return api.get('/api/dept/list').then(res => {
localStorage.setItem('deptCache', JSON.stringify(res.data))
return res.data
})
}
5. 生产环境部署方案
5.1 服务器配置建议
| 组件 | 最低配置 | 推荐配置 |
|---|---|---|
| 应用服务器 | 2核4G | 4核8G |
| MySQL | 4G内存+100G SSD | 8G内存+200G SSD |
| Redis | 1G内存 | 2G内存 |
| Nginx | 1核1G | 2核2G |
5.2 Docker化部署
- 编写Dockerfile:
dockerfile复制# 后端Dockerfile示例
FROM amazoncorretto:11
VOLUME /tmp
ADD target/crm.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
- docker-compose编排:
yaml复制version: '3'
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: crm_db
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- ./redis/data:/data
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
6. 常见问题排查手册
6.1 启动类问题
问题现象:SpringBoot应用启动时报错"Failed to configure a DataSource"
解决方案:
- 检查application.yml中数据库配置
- 确认MySQL服务已启动且网络可达
- 如果不需要数据源,可添加排除:
java复制@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
6.2 权限控制问题
问题现象:接口返回"没有访问权限"
排查步骤:
- 检查Shiro配置中的权限字符串匹配规则
- 确认用户角色是否正确关联权限
- 查看系统日志中的权限验证记录
6.3 移动端兼容问题
问题现象:小程序真机上样式错乱
解决方案:
- 检查是否使用了vw/vh单位(部分安卓机兼容性差)
- 确认Vant组件库版本与基础库版本匹配
- 使用真机调试工具查看具体错误
这套CRM系统在实际部署到生产环境时,我建议特别注意数据备份策略——除了常规的MySQL dump备份外,还应该建立binlog日志归档机制。对于客户跟进记录这类重要数据,可以采用双写机制同时存入MySQL和Elasticsearch,既保证事务一致性又满足检索需求
