ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SpringBoot+Vue+MySQL实现的客户关系管理系统源码解析

SpringBoot+Vue+MySQL实现的客户关系管理系统源码解析 做毕业设计或者课程设计选C/S还是B/S、单体还是微服务往往是第一道坎。SpringBootVue.jsMySQL这套组合做客户关系管理系统属于那种看着不花哨但五脏俱全的方案后端有Java生态的成熟体系前端有组件化开发数据库有清晰的表关系既能体现工程能力又不会因为技术栈太偏门把自己卡死在环境配置上。这套源码项目的典型形态就是一套可直接运行的客户关系管理平台登录、客户、联系人、跟进记录、商机、合同、统计基本都是这个套路。对准备答辩、赶课程设计或者想完整走一遍前后端分离项目的同学来说它是很好的切入点。1. 项目概览与技术选型1.1 这个CRM系统到底能做什么客户关系管理系统也就是日常说的CRM核心目标很明确把销售手里零散的客户信息集中管理起来减少“人走了客户也跟着走”的尴尬。放在毕设课设背景下它通常包含用户登录、客户信息维护、联系人管理、跟进记录、商机管理、合同回款、数据统计等模块。虽然业务上看着简单但每个模块都能把SpringBoot和Vue.js的常规操作覆盖到位比如CRUD、分页、筛选、表单校验、权限拦截、统计图表这些恰好是面试官和答辩老师最常关注的点。这套源码里的“管理平台”四个字意味着它不是只给开发者看的技术demo而是有登录页、有菜单、有页面跳转、有权限控制的完整系统。拿到源码后你可以把它当成一个半成品先跑起来再根据自己的业务理解去改表、加字段、加页面。很多同学喜欢再添一个数据可视化大屏或者加一个Excel批量导入客户这些都很容易在这套结构上扩展。它适合做毕业设计、课程设计和日常学习也适合那些想快速了解大型项目工程结构的人。1.2 为什么选择SpringBoot Vue.js MySQL这个组合在近几年的课设和毕设里几乎是“标准答案”不是没有原因的。先说后端SpringBoot把Spring的配置简化到了“用就行”的程度内嵌Tomcat打成jar包直接运行不用像传统SSM那样配置一堆XML。Java本身又是一门资料极其丰富的语言遇到报错基本能在网上找到现成答案。再说前端Vue.js上手平缓组件化开发思路清晰配合Element UI/Element Plus这类后台管理组件库半天就能搭出一个像模像样的后台界面。双向绑定让表单处理变得非常直观这让没有太多前端经验的同学也能交出漂亮的操作界面。数据库选MySQL就更好解释了免费、轻量、安装方便、主流云服务器都支持而且市面上关于MySQL的教程数量几乎没有任何数据库能比。你在这个项目里积累的SQL能力以后出去面试甚至处理日常数据都直接用得上。还有一点很关键这套技术栈的职位需求量大无论你未来走Java开发还是全栈方向项目经验都能直接写在简历上。相比用Python写脚本或者用纯静态页面糊弄这套方案的技术含金量更高答辩时也更有东西可讲。2. 系统架构与数据库设计2.1 前后端分离架构与目录规划很多初学同学第一次接触“前后端分离”这个概念会有点懵其实拆开看就是把浏览器里的页面和后端的数据接口当成两个独立项目。前端只负责展示和交互后端只负责处理数据、校验逻辑、返回JSON。这样做的直接好处是两边的开发可以并行部署时也能分开扩缩容哪怕只是一个人写代码边界也比混在一起要清晰得多。这套源码的目录规划可以按下面这种结构去理解实际项目里大同小异crm-backend/ ├── src/main/java/com/example/crm/ │ ├── controller/ # 接收前端请求返回Result │ ├── service/ # 业务逻辑层处理事务 │ ├── mapper/ # 数据库访问层MyBatis/MyBatis-Plus │ ├── entity/ # 数据库实体类 │ ├── config/ # 拦截器、跨域、配置类 │ └── common/ # 统一返回结果、异常处理 └── src/main/resources/ ├── application.yml # 端口、数据库、JWT等配置 └── mapper/ # XML文件复杂SQL在这里写crm-frontend/ ├── src/ │ ├── api/ # axios请求接口封装 │ ├── router/ # 路由配置和权限守卫 │ ├── store/ # 用户状态/全局状态Vuex或Pinia │ ├── views/ # 页面级组件 │ ├── components/ # 复用组件如弹窗、表单 │ └── utils/ # 工具函数token存取、格式化 └── package.json后端用Maven统一管理依赖前端用npm管理依赖两者互不干扰。开发时前端通过代理把请求转发到后端端口生产时把前端打包成静态文件既可以放在SpringBoot的static目录里做成单包部署也可以用Nginx单独接管。第一次接触这种结构最好先画一张请求流程图用户点页面 - 前端API模块发请求 - 后端Controller收到 - Service处理逻辑 - Mapper查库 - 层层返回。顺着这条线去读源码一天就能把核心链路摸透。2.2 核心表结构设计与字段规划数据库设计是整个系统的地基。CRM项目里最常见的核心表包括用户表、客户表、联系人表、跟进记录表、商机表和合同表。它们之间关系不复杂但得符合业务习惯一个客户可以对应多个联系人、多条跟进记录、多个商机一个商机最终可以变成合同。以客户表为例一张典型的表结构可以设计成这样CREATE TABLE sys_user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, real_name VARCHAR(50), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE customer ( id BIGINT PRIMARY KEY AUTO_INCREMENT, customer_name VARCHAR(100) NOT NULL, source VARCHAR(50), level VARCHAR(20), industry VARCHAR(50), phone VARCHAR(20), owner_id BIGINT, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted TINYINT DEFAULT 0 );设计时有几个细节需要注意。第一客户表一定要加owner_id用来标识客户的负责人这样多个用户登录时才不会看到同一堆客户分配和回收客户也好实现。第二存储金额时用DECIMAL而不是FLOAT/DOUBLE避免浮点误差。第三给表加逻辑删除字段deleted不要物理删除这样误删数据还能恢复这也是企业开发里的常见习惯。第四时间字段统一用DATETIME并在连接串里指定serverTimezone避免时区显示混乱。联系人表一般会带上customer_id外键跟进记录表除了关联客户和联系人还要记录跟进方式、内容、下次跟进时间。商机表则会有预计金额、销售阶段、赢率等字段。合同表往往会关联商机ID同时记录合同金额、开始和结束日期、回款状态。统计模块需要的数据基本都可以用这些表按时间段聚合查询出来比如“本月新增客户数”“按来源分组客户数”“销售漏斗金额”。不用一开始设计得特别复杂先把主表和必要的关联表建清楚后面新增模块再增量加表比一口吃成胖子更稳妥。3. 后端核心模块实现3.1 项目结构、JWT认证与统一返回后端项目里最值得先看两个东西一个是统一返回结果另一个是登录认证。先说服口气自己写后端接口如果每个Controller返回的数据格式都不一样前端联调起来会想骂人。所以这套源码里通常会定义一个Result类所有接口都返回结构统一的JSON比如Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(success); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }前端拿到这个结构后只需要判断code是不是200不用猜字段。登录认证方面现在的毕设项目基本都升级到了JWT方案。用户登录成功后后端生成一串带过期时间的token前端存到localStorage里每次请求在HTTP Header里带上token后端拦截器校验通过才放行。拦截器的写法思路是实现HandlerInterceptor在preHandle里从Header取token解析成功就放行失败就返回401。这段逻辑并不复杂但它是权限控制的骨架。需要注意的是JWT的密钥要放在配置文件中不要写死在代码里另外放行路径要单独配置比如/login和静态资源路径必须排除在拦截器外否则连登录都登不进去这个坑我刚写的时候踩过。3.2 客户CRUD、分页查询与事务处理客户管理模块是这套系统的核心也是最能体现基本功的部分。列表页要支持分页、关键字搜索、按来源或级别筛选后端对应一个分页接口。用MyBatis-Plus的话分页写起来非常省事GetMapping(/page) public ResultIPageCustomer page(RequestParam Integer page, RequestParam Integer size, RequestParam(required false) String keyword) { PageCustomer pageParam new Page(page, size); LambdaQueryWrapperCustomer wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(keyword), Customer::getCustomerName, keyword) .eq(Customer::getDeleted, 0) .orderByDesc(Customer::getCreateTime); return Result.success(customerService.page(pageParam, wrapper)); }这里有几个关键点。wrapper里用like和eq方法同时把keyword为空的条件放进去这样前端不传关键字也不会拼出非法SQL。逻辑删除条件一定不要漏否则列表里会出现已删除的数据。新增和修改接口通常合二为一通过实体主键id判断是insert还是update很多源码就是这么干的前端提交表单时id为空就是新增有值就是修改。说到事务CRM里最常见的操作是“新增客户的同时给默认跟进人添加一条跟进记录”或者“把商机阶段改为赢单时同时生成合同记录”。这两步只要其中一步失败数据就会对不上所以必须在Service方法上加Transactional注解。我在实际开发里吃过亏一开始只在Controller层调两个Service方法结果工资表更新成功日志表插入失败数据怎么对都对不上。加上事务之后方法里所有数据库操作才是一个整体要么都成功要么都回滚。3.3 统计报表与导入导出统计报表是答辩展示的加分项。常见的统计接口都是聚合查询比如统计客户来源占比可以这样理解按source字段分组count客户数量再算出百分比。SpringBoot后端可以写一个统计Service返回给前端的是饼图或柱状图需要的数据组合前端用ECharts渲染。这里建议不要写太多复杂SQL把聚合逻辑拆成几个清晰的方法比如查总数、查分组数量、查时间段趋势调起来更容易。导入导出能力在公司业务里几乎是刚需课程设计里加上也非常亮眼。导入可以用EasyExcel或Apache POI前端上传Excel文件后端读每行数据校验后再逐条插入客户表。校验很关键至少要做非空校验和格式校验比如手机号长度否则用户上传一个乱七八糟的Excel批量插入后数据库里全是脏数据。导出就更简单后端查出数据用EasyExcel写出流前端通过blob下载。这里只需要注意一点导出时大字段或者特殊字符可能会让Excel打开报错比如客户名称里有换行符处理一下就好。4. 前端Vue.js实现与联调4.1 前端工程化结构与路由/拦截器前端项目现在基本都是用Vue CLI或者Vite创建依赖用npm安装。页面结构上登录页和主布局是分开的主布局里放侧边栏菜单和内容区。路由配置是理解前端项目的钥匙为什么这么说因为所有的页面跳转关系都写在这里你顺着路由表就能知道系统有哪些功能。登录后访问受保护的页面需要做权限拦截最常见的做法就是路由守卫router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.meta.requiresAuth !token) { next(/login); } else if (to.path /login token) { next(/); } else { next(); } });接口请求的axios封装也值得看它会在请求前自动加token在响应后统一处理错误码axios.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers.Authorization token; } return config; }); axios.interceptors.response.use( res { const data res.data; if (data.code 401) { router.push(/login); return Promise.reject(new Error(登录过期)); } return data; }, err Promise.reject(err) );这样做的好处是业务代码里直接拿到后端返回的data不用每个页面都判断一遍状态码。很多同学不理解为什么要把axios封装成api模块其实就是为了让页面代码不直接依赖axios以后换请求库或加统一处理只改一个文件就够了。4.2 核心页面组件与状态管理客户列表页是前端最典型的一个页面几乎把所有基础组件都串起来了搜索栏、表格、分页、弹窗表单、删除确认。用Element Plus的话页面骨架就是el-form加el-table加el-dialog。新增和编辑共用一个表单组件打开时根据是否有当前行数据决定回显和提交地址。表单校验也别忽略必填项、手机号格式、金额范围这些前端校验能拦住大部分低级错误。我做项目时发现很多同学只注重页面能不能显示数据忽略了校验规则结果只要用户输入一个非法字符接口就报错。这个细节在答辩时很容易被老师问到提前做好能加分。状态管理方面老项目用Vuex新项目倾向Pinia。CRM这种规模的项目其实不一定要全局状态登录用户信息、菜单权限存一下就够了。其他业务数据尽可能放在组件内部或者通过路由参数传递不要啥都往store里塞否则页面刷新后状态丢失反而要多写一行初始化代码。4.3 前后端联调与打包部署开发环境最大的痛点是跨域。前端地址是localhost:5173后端地址是localhost:8080浏览器会拦截跨域请求。解决方案非常简单在Vite或Vue CLI的devServer里开代理// vite.config.ts server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } }这样前端请求 /api/customer/page会被代理转发到后端的对应接口最终看起来是同源请求跨域问题就消失了。生产部署有两种思路一种是前后端完全分离前端打包后给Nginx托管后端单独跑在8080另一种是把前端打包出来的dist目录直接复制进SpringBoot的src/main/resources/static下再重新打包后端这样只部署一个jar包就够了。对毕设来说第二种明显更省事演示时不用额外开Nginx一台机器跑起来就是完整项目。打包时记得先npm run build再把dist里的文件复制过去版本放对位置不要放错层级。5. 环境搭建与部署全流程5.1 本地开发环境准备拿到源码第一件事不是急着打开IDEA而是检查环境版本。CR系统后端如果是基于SpringBoot 2.x写的那就用JDK 8或JDK 11Maven 3.6以上如果基于SpringBoot 3.x那就需要JDK 17。版本不匹配是新手最常见的问题SpringBoot版本太高或太低都会导致依赖解析失败。前端建议Node 16或18npm版本不要太旧。MySQL建议5.7或8.0这个项目对数据库版本要求不高但注意连接驱动要匹配。安装MySQL时可以本地安装也可以直接用Docker跑一个不过Docker如果配置不对很容易失败不爱折腾的直接用本地安装包就好。Windows上装MySQL 8.0时安装向导会让你设置root密码一定要记住MySQL 5.7安装过程里会有一个选字符集的步骤建议直接选utf8后面省很多麻烦。数据库安装完成后用navicat或者命令行登录root然后创建数据库、导入源码里的sql脚本。5.2 配置数据库并启动后端导入SQL之后打开后端的application.yml把数据库连接信息改成你自己的server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/crm_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver这里最容易出问题的就是characterEncoding和serverTimezone。不设置时区你插入的时间会和本地时间差8个小时不设置编码中文会变成问号。启动后端有两种方式用IDEA直接Run启动类或者在项目根目录执行mvn spring-boot:run。如果项目是多模块先确认你当前启动的是web入口模块。后端启动成功的日志最后会看到Tomcat started on port(s): 8080这时候可以用Postman或者浏览器访问一下登录接口看看返回是否是JSON。5.3 启动前端与整体联调后端起来之后进入前端目录依次执行npm install npm run devnpm install在国内偶尔会卡住因为默认镜像源在国外可以用npm config set registry https://registry.npmmirror.com换成国内镜像再重新安装。启动成功后终端会给出一个本地地址浏览器打开就能看到登录页。整套系统的启动顺序有讲究先启动MySQL再启动后端SpringBoot最后启动前端Vue。如果MySQL没起来就启动后端SpringBoot会因为连接不上数据库而启动失败如果前端先起了调接口时也会报网络错误。跑通一遍后最好自己从头再走一遍记住每一步的步骤答辩演示时老师经常问“你怎么把项目跑起来的”你能流利说清楚这个顺序和每步大概做了什么会显得对项目非常熟。6. 常见问题与避坑指南6.1 启动和依赖问题排查速查表我把带学生做项目时最经常遇到的一批问题整理成了表格几乎每天都会有人踩到现象常见原因处理办法后端启动报数据库连接失败MySQL没启动、账号密码不对、库名错误检查MySQL服务核对yml连接信息启动端口被占用8080端口已被其他程序占用用netstat -ano查端口释放或改server.portnpm install超时默认源下载慢换成npmmirror源重试前端打不开页面Node版本太低或依赖树损坏删除node_modules和package-lock.json后重装登录接口401请求没带token或token过期检查axios拦截器是否注入了Authorization日期时间差8小时连接串未指定serverTimezone在url里加上serverTimezoneAsia/Shanghai中文乱码数据库/连接串/前端编码不一致统一使用utf8mb4url加characterEncodingutf8这表格看着简单但每条背后都可能耽误几个小时。比如端口被占用我遇到过一次是电脑后台跑了个tomcat服务一直没关害得SpringBoot一直起不来。检查这类问题的思路是先看控制台报错后看配置最后再看是不是版本问题。不要一上来就怀疑源码有bug实际上大部分情况都是环境。6.2 数据库与中文乱码问题中文乱码这件事我单独拿出来讲是因为它覆盖面特别广。前端显示乱码、导出Excel乱码、导入数据库后乱码原因可能都不一样。最稳妥的做法是在建库时直接指定字符集CREATE DATABASE crm_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;连接串里也要带上useUnicodetruecharacterEncodingutf8这样Java程序读进来的中文才是对的。另外前端页面文件本身要是UTF-8编码如果编辑器默认GBK页面里写死的中文在编译后也会乱。这个在IDEA和VS Code里都能通过右下角编码格式看出来。还有一个容易被忽略的点如果你用Postman测试新增客户返回成功但数据库里的客户名称是问号那多半是连接串编码没设置而不是前端问题。先按这个顺序排查数据库字符集 - 连接串字符集 - 接口入参编码 - 前端展示编码基本能解决。7. 二次开发方向与学习建议7.1 毕设课设的加分项如果想让这个项目在答辩时更有优势有几个改动成本不高但展示效果很好的方向。第一加ECharts数据可视化把统计报表做成折线图和饼图老师看着比数字表格直观得多第二加Excel导入导出这个功能在企业里非常常用答辩时可以现场演示批量导入客户第三加操作日志登录用户每次增删改都被记录下来体现安全审计意识第四用Spring Cache或Redis缓存热点数据比如统计面板数据既能讲缓存又有性能优化点。如果还想再进一步可以把权限模型从简单的用户角色扩展成RBAC用户-角色-权限实现不同角色登录后看到的菜单不一样。这个改动会牵涉前端路由动态生成和后端权限校验工作量大一点但做完后整个项目从“能跑”变成“像样”。答辩老师问的问题经常是“你这个系统有什么亮点”这时候你不用讲一大堆技术名词把权限控制、数据统计、批量操作这些能落地的东西讲清楚反而更打动人。7.2 学习路径建议拿到源码后千万不要一开始就跑起来随便点两下就完事。我建议按这样的顺序去啃第一步跑通项目记录启动步骤和环境配置确保随时能复现第二步对着表结构画ER图理解业务流转从客户到联系人到商机再到合同这条主线要能讲明白第三步跟着一个完整请求链路读代码从点击页面的按钮进入前端方法再到API封装、路由、请求再到后端的Controller、Service、Mapper最后到SQL和返回值完整走一遍第四步自己动手改一个小功能比如给客户表加一个“客户类别”字段从头到脚完整实现一遍。做完这四步这套源码才能真正变成你自己的东西。最后再分享一个小习惯我每次拿到新项目都会先建一个文档专门记录“我改了什么”“遇到了什么问题”。你哪怕只改了一个字段、一个按钮也写下来。这样等过两个月再回来看能想起所有细节写论文和准备答辩时都不至于两眼一抹黑。这套源码本身不是目的通过它把SpringBoot、Vue.js、MySQL这些技能点串起来才是对你最值钱的收获。
返回列表