首页 / 资讯中心 / 文章详情

SpringBoot+Vue+MySQL企业客户管理系统毕设全流程实战解析

SpringBoot+Vue+MySQL企业客户管理系统毕设全流程实战解析 ★ FEATURED ARTICLE
毕业设计选了SpringBootVueMySQL 企业客户管理系统这条路子的同学我建议你先沉住气把这篇文章看完。这个题目表面上听起来就是一套“增删改查”但真正动手你就会发现客户管理、联系人、跟进记录、合同、统计看板、登录鉴权、前后端联调、部署上线、论文答辩……一环扣一环任何一个环节掉了链子整个项目的完成度都会被拉低。这篇文章就是我完整做完这个项目之后的经验总结从技术选型、数据库设计、后端接口、前端页面到部署和论文答辩全流程拆开讲适合准备做类似毕设、或者刚接触前后端分离项目想找一个完整参考的同学。1. 项目整体设计思路与技术选型1.1 企业客户管理系统的核心需求解析先别急着写代码无论题目是“企业客户管理系统”还是“客户关系管理系统”本质都绕不开几个核心场景企业里需要有一份“客户的档案”营销人员需要记录“和客户聊了什么、下次什么时候跟进”管理层需要看到“有多少潜在客户、跟进成功了多少、合同签了多少钱”。把这些场景抽象成功能模块基本就是系统登录与权限、客户信息管理、联系人管理、跟进记录管理、合同管理、统计看板、系统用户管理。我在正式动手之前把这些模块画了一张思维导图客户信息作为主数据联系人挂在客户下面跟进记录又挂在联系人或者客户下面合同再关联客户和商品金额环环相扣。这样画完以后数据库表怎么建、接口怎么设计都会清楚很多后面写论文画业务流程图也顺手。千万别一上来就建表那是给自己挖坑。1.2 技术选型为什么是SpringBootVueMySQL这套组合在本科毕业设计里属于“标准答案”但选它不光是图省事背后有几层实际考虑。后端用SpringBoot最大的好处是内嵌了Tomcat配置极简不用像传统SSM那样写一堆XML。Spring Boot的自动配置让MyBatis、数据库连接池、拦截器这些东西都能通过注解和配置文件搞定开发节奏快很多。而且Spring家族生态成熟写到论文里“基于Spring Boot的自动配置机制”这句话就能引出不少可写的点答辩时老师也认可。前端用Vue看中的是组件化和前后端分离。Vue 2搭配Element UI组件写起来直观列表页、弹窗、表单、分页这类后台管理系统的常见场景都有现成组件一个页面几十行关键代码就能拼出来。Vue 3配Element Plus也完全可以如果你的电脑配置和网速允许建议直接用Vue 3毕竟新的东西长远看更值钱。数据库用MySQL这个不用多解释关系型数据模型贴合客户、联系人、合同这类强结构化业务事务和SQL聚合查询也方便。MySQL 5.7或者8.0都行字符集记得统一utf8mb4不然存不了生僻字和特殊符号。这里顺便提一句有同学会纠结用不用若依框架、用不用JSP。若依确实快但框架自带的东西太多答辩时容易讲不清楚哪些是你写的JSP又偏传统体现不出前后端分离的现代思路而且前端页面写起来比Vue繁琐得多。所以拿SpringBootVueMySQL自己做一遍既是学习路线也是稳妥的毕设路线。1.3 项目结构规划与开发顺序前后端分离项目目录结构从一开始就要规划好。后端我习惯按controller、service、mapper、entity、config、common这样的包结构来分所有返回结果统一用Result对象包一层后面接口对接会省很多事。前端则是views、components、api、router、utils这么几个目录views放页面components放复用组件api把请求单独抽出来。开发顺序有讲究。建议先做数据库设计再做后端的登录和用户管理然后做客户增删改查再做联系人和跟进记录接着是合同和统计最后统一调前端。这个顺序的特点是每个阶段都能独立验证“能跑通”而不是最后一次性联调发现一堆问题。我见过太多同学把所有代码写完才开始调试结果一天24小时都花在找不到的Bug上。2. 数据库设计与核心表结构2.1 基础表规划与字段设计整个系统我设计了五张核心表系统用户表sys_user、客户表customer、联系人表contact、跟进记录表follow_record、合同表contract。下面把关键的字段列出来这是可以直接抄作业的版本。sys_user表id、username、password、real_name、role管理员/销售/普通员工、status启用/停用、create_time、update_time。密码字段注意长度要留够BCrypt加密出来的字符串有60位长度定到100更稳妥。customer表id、customer_name、customer_phone、customer_level潜在/意向/成交/流失、industry所属行业、source客户来源、address、remark、owner_id负责人ID、status逻辑删除标记、create_time、update_time。owner_id关联sys_user这是后面做“只看我的客户”功能的基础。contact表id、customer_id、contact_name、contact_phone、position、wechat、is_main_contact是否主要联系人、create_time。一个客户底下可以挂多个联系人这样数据模型才贴合真实业务。follow_record表id、customer_id、contact_id、content跟进内容、follow_date、next_follow_date、creator_id、create_time。这张表最关键的是next_follow_date统计看板要按它计算“待跟进客户”。contract表id、contract_no、customer_id、contract_amount、start_date、end_date、status草稿/已签订/已完成/已终止、create_time。合同金额用DECIMAL(10,2)别用FLOAT浮点数算钱会有精度问题。2.2 外键建不建索引怎么加关于外键我的建议是表结构里不建物理外键只保留逻辑外键。什么意思呢就是customer_id这种字段正常保留但不创建FOREIGN KEY约束。原因很实在物理外键会影响插入和删除的效率也会让联表查询的SQL在某些场景下出现预料之外的行为更重要的是毕业设计在你本机跑没问题导入到服务器上一旦数据顺序不对外键约束就会让初始化脚本直接报错。索引方面用户表的username必须建唯一索引这是登录查询的高频字段。客户表的customer_name、customer_phone建普通索引跟进记录表的customer_id、next_follow_date建组合索引统计看板按日期范围查询的时候效果很明显。我在实际使用中体会到数据量到几万条以后有没有索引的区别非常明显没有索引的模糊查询能把接口拖到好几秒。2.3 初始化数据与密码加密建好表之后要写初始化SQL至少插入一个管理员账号。有个细节容易被忽略管理员密码绝对不能明文存用BCrypt加密后再插入。项目启动后第一次登录用Spring Security或者hutool的BCrypt工具手动生成一段加密字符串然后INSERT进去。这样的话数据脚本里不会裸露密码答辩演示的时候也更体面。数据库脚本文件我习惯分成schema.sql和data.sql两份一份建库建表一份初始化数据。这样论文附录里放脚本时结构清晰部署文档里也让使用者可以分步执行遇到报错更好排查。3. 后端核心实现与接口设计3.1 登录鉴权JWT还是Session登录鉴权是这个项目的门面也是答辩时被问得最多的地方。主流做法有两种JWT和Session。毕设项目我推荐JWT因为前后端分离下它天然适合后端不需要存会话状态前端拿到token放在请求头里就行。实现起来也不复杂用户登录成功以后后端用JJWT库生成一个token里面放userId和role设置过期时间比如24小时。前端拿到token存到localStorage然后axios请求拦截器每次把token放到Authorization头里。后端写一个拦截器或者过滤器统一校验token校验通过就把用户信息放进ThreadLocal后续业务代码里直接取。核心代码大致是这个样子// 登录接口 String token Jwts.builder() .setSubject(user.getId().toString()) .claim(role, user.getRole()) .setExpiration(new Date(System.currentTimeMillis() 86400000)) .signWith(SignatureAlgorithm.HS256, secretKey) .compact();拦截器里校验时注意白名单要放行登录接口其他接口都要校验。我第一次写的时候忘了放行登录接口结果登录接口自己被拦截了前端报401排查了半天才反应过来。权限控制不需要做得太重用角色的字符串判断就够了。管理员可以访问用户管理接口普通销售只能操作自己负责的客户这个在前端可以用路由守卫控制按钮显隐在后端接口里再判断一次双保险。答辩的时候一定要能说清楚“为什么前端要控制、后端也要控制”因为前端控制只是用户体验后端控制才是真正的安全。3.2 客户管理模块的增删改查与分页客户管理是整个系统的核心增删改查加分页加条件查询是重点。MyBatis-Plus在这方面非常好用BaseMapper已经帮我们实现了单表CRUD分页用它的Page对象加一个分页拦截器配置就行。条件查询我推荐用LambdaQueryWrapper代码可读性高也不会出现字符串硬编码的魔法值。比如客户列表接口要支持按客户名称模糊查询、按客户级别筛选、按负责人筛选最后按创建时间倒序LambdaQueryWrapperCustomer wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(customerName), Customer::getCustomerName, customerName) .eq(StringUtils.hasText(customerLevel), Customer::getCustomerLevel, customerLevel) .eq(ownerId ! null, Customer::getOwnerId, ownerId) .orderByDesc(Customer::getCreateTime); PageCustomer page customerMapper.selectPage(new Page(pageNum, pageSize), wrapper);这里有个细节需要注意like和eq方法的第一参数是个boolean条件不成立时这个条件自动不拼进去。这样前端传不传参数都能正常工作代码里也不用堆一堆if判断。接口设计遵循RESTful风格GET /customer/list 查询列表、GET /customer/{id} 查询详情、POST /customer 新增、PUT /customer 修改、DELETE /customer/{id} 删除。删除这里我用的是逻辑删除也就是更新status字段而不是物理DELETE。这样做的理由很多哪怕毕设数据量小也能体现你已经具备企业级开发的意识答辩时这是一个加分点。MyBatis-Plus开启逻辑删除只需要在实体字段上加TableLogic注解然后在application.yml里配置一下。3.3 批量导入导出和统计看板的实现客户数据的导入导出用EasyExcel来做比POI手写节省大量时间。导出就是把查询结果列表直接输出为Excel文件用EasyExcel的write方法一行代码的事。导入则麻烦一点要处理文件上传、解析、数据校验、重复数据去重。我写的时候遇到一个比较典型的坑Excel里的日期字段是字符串格式直接用实体类的LocalDateTime去接收会解析失败。解决办法是在实体字段上写ExcelProperty注解并结合字符串接收再手动做格式转换。这个坑建议你们提前规避。统计看板是给管理层看的我做了三个核心指标客户总数、本月新增客户数、本月成交合同金额。还有两个图表按客户级别分布的饼图、近六个月新增客户趋势的折线图。这些数据接口的SQL思路不复杂但一定要用聚合函数和日期分组SELECT DATE_FORMAT(create_time, %Y-%m) AS month, COUNT(*) AS cnt FROM customer WHERE create_time DATE_SUB(CURDATE(), INTERVAL 6 MONTH) GROUP BY month ORDER BY month如果写成这样前端拿到数据可以直接喂给ECharts几乎不用二次加工。把SQL先写完、先验证数据对不对再写接口这是我反复踩坑后总结出来的顺序。4. 前端页面实现与前后端联调4.1 前端项目搭建与登录流程前端用Vue脚手架创建项目后第一件事是封装axios而不是急着写页面。统一封装axios的好处是所有请求自动带token统一处理错误状态码和会话过期返回结果自动解包。我在utils/request.js里做了一件事把后端返回的code等于200时直接返回data实体不等于200时弹提示并返回Promise.reject这样业务代码里写起来非常简洁。登录页面本身没什么难度一个表单、一个按钮、一个loading状态。但登录成功后的跳转逻辑要注意判断用户的角色管理员跳到管理首页普通销售跳到客户列表不要所有人都是同一个首页。这个用简单的if判断就能实现却会让答辩demo看起来专业很多。路由守卫也要配套写好。在全局前置守卫里检查有没有token没有就跳登录页。同时meta里标上哪些路由需要哪种角色权限不满足就拒绝访问。这部分代码量不大但作用很大它保证了用户关掉浏览器再打开时页面不会直接灰屏。4.2 客户列表页面与新增弹窗的实现客户列表页是整个前端最有代表性的页面包含顶部的搜索条件区、中间的表格区、底部的分页器再加上右上角的新增、导出、批量导入按钮。表格用Element UI的el-table列定义里注意格式化显示比如客户级别、客户来源这些字段存的是字典值要转换成中文显示。这里有一个我踩过的小坑后端返回的日期时间字段是带时区的ISO字符串表格里直接显示会多出一个字母T。解决方法是后端实体类字段上用JsonFormat注解统一成yyyy-MM-dd HH:mm:ss或者前端做格式化处理两边统一用其中一个方案别各做各的。新增和编辑我共用一个弹窗组件打开弹窗时根据是否有id判断是新增还是编辑编辑时先把表单数据回显再让用户改。表单校验用Element UI自带的rules客户名称必填、手机号格式校验这些都给用户即时反馈。保存时要特别注意调接口成功后记得刷新列表并且重置表单不然下一次打开弹窗会残留上一次的数据。4.3 前后端联调与接口对接实用技巧联调阶段最常见的三个问题跨域、字段对不上、返回结构不一致。本地开发时大概率会遇到跨域最简单的方案是在vue.config.js里配置devServer的proxy代理前端请求以/api开头代理把请求转发到localhost:8080这样浏览器看到的是同源的既解决了跨域又不影响后端接口路径。等上线部署时再由Nginx做一层反向代理职责相同。字段对不上这个问题根因是前后端各自定义字段名比如后端叫customerName前端却写成customerName或name导致所有接口看起来都通了、数据显示却全为空。我在实际项目中养成一个习惯先把后端实体类打印成Swagger文档前端写页面前先对照接口文档把字段名一个不落地先列出来。有条件的话接口文档用springdoc-openapi自动生成前端对着它写字段对齐效率高很多。统一的返回结构也很重要。我后端的Result对象结构是{ code: 200, message: success, data: {...} }所有接口都返回这个结构前端axios封装里统一判断code业务代码里永远只处理data。这样联调时基本不会出现“这个接口返回格式不一样”的混乱情况。5. 部署上线与部署文档编写5.1 后端打包与服务器部署部署分为开发环境部署和生产环境部署两种我都走通过。开发环境最简单的做法是后端直接用IDEA运行前端用npm run dev前端通过proxy代理访问后端适合自己电脑上调试演示。生产环境部署后端用Maven打包成jar包命令是mvn clean package -DskipTests。打包前确认application-prod.yml里的数据库地址、端口、文件上传路径都改成了正式环境的配置。jar包传到服务器以后用java -jar xxx.jar --spring.profiles.activeprod启动如果想后台运行用nohup java -jar xxx.jar logs/run.log 21 。我建议你至少会用这种方式因为Docker虽然方便但答辩环境不一定支持传统方式反而最稳也最容易被理解。5.2 前端打包与Nginx配置前端部署前先执行npm run build产物是dist目录里面是静态文件。把这些文件放到Nginx的html目录下然后配置Nginx。这里有个非常经典的坑前端是history路由模式刷新一个子路由比如/customer/list时Nginx会去真实的文件路径找找不到就会404。解决办法是在Nginx配置里加一个try_fileslocation / { root html; index index.html; try_files $uri $uri/ /index.html; }同时要把/api的请求反向代理到后端的jar端口上配置大概是location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }这里特别注意proxy_pass的路径写法结尾带不带斜杠请求路径的拼接结果完全不同这个细节我吃过亏。如果带斜杠proxy_pass会把location前缀去掉再拼接不带斜杠则保留完整路径。最好自己动手测一次看后端接收到的实际请求路径是什么。5.3 数据库迁移与备份策略部署时数据库初始化直接把schema.sql和data.sql按顺序执行就行。但要注意服务器的MySQL版本和字符集建库语句必须带utf8mb4和排序规则不然中文乱码问题能让你怀疑人生。数据备份我建议写一行命令就行mysqldump -u账号 -p密码 数据库名 备份文件.sql作为部署文档的附录写进去虽然简单但看起来项目专业程度直接不一样。部署文档本身怎么组织也是有讲究的。一个合格的部署文档至少包含环境要求JDK版本、MySQL版本、Node版本、后端配置说明、前端配置说明、数据库导入步骤、启动步骤、常见问题。我见过很多同学写的部署文档只有几行“怎么启动”一旦换一台电脑跟着步骤走根本跑不起来。文档的价值体现在“让一个从没跑过这个项目的人也能顺利启动”你在写的时候要有这个代入感。6. 论文结构安排与答辩实战准备6.1 论文各章节怎么组织毕设论文的结构比较固定但不代表可以随便拼凑。我建议核心章节这样分配绪论里重点写“企业客户管理的信息化背景”和“现有系统的不足”需求分析章节把用例图画出来把功能需求和非功能需求分开写系统设计章节拿出数据库ER图、表结构说明、接口设计系统实现章节按功能模块讲每一节配合核心页面截图和核心代码片段测试章节用表格列测试用例写清楚测试步骤、预期结果、实际结果。论文最容易被导师挑毛病的地方是“系统实现写得像代码说明书”。我的经验是每一节不要贴大段代码而是贴一段关键代码然后讲清楚“这段代码解决了什么问题、为什么这样写”。比如讲JWT拦截器时重点是“为什么需要校验、token失效后前面怎么处理”这比贴两百行代码有价值得多。图表也要提前准备ER图、用例图、系统架构图、时序图各两三张不需要花里胡哨清晰即可。6.2 答辩老师最爱问的几个方向答辩提问基本围绕几类问题展开提前准备就不慌。第一类为什么选这个技术栈你只需回答清楚“Spring Boot简化配置、Vue做前后端分离、MySQL适合业务数据结构”这三点即可。第二类权限控制是怎么做的要能画出本次请求从浏览器到后端Controller再到拦截器的流程。第三类日志、异常、并发怎么处理的哪怕做得很简单也要说清楚全局异常处理类的逻辑和分页查询在高数据量下的意义。还有一个高频问题是“你这个系统和别的管理系统有什么区别”。这个问题其实不是在为难你而是想听你有没有思考系统的特殊性。客户管理系统的特色在于客户状态流转、跟进记录的时间线、待办提醒、统计分析这些点你把这几个点讲透这个题目才真正立得住。我当时在客户列表里加了一个“即将跟进提醒”的小功能数据模型和接口都是现成的只要用SQL查一下next_follow_date小于当前时间的数据就行却成了答辩现场最有记忆点的功能。7. 实操过程中的典型问题与避坑总结7.1 前后端联调阶段的高频故障我排查了一整天最后发现是Nginx代理的路径多了一层/api导致的。因为在请求后台时前端的baseURL已经写了/apiNginx转发时又拼了一次后端所有接口都收到双写前缀自然全部404。这个问题的排查思路是先用浏览器开发者工具看Network找到真实请求地址再去比对后端日志很快就能定位。提前养成的习惯是启动后端时看接口访问日志前端发什么请求、后端收到什么请求两边一对比问题一目了然。另一个高频故障是跨域配置。本地开发用proxy代理之后理论上不会再有跨域问题但如果你同时打开了多个前端进程或者proxy配置写错也会看到浏览器报CORS错误。记住一点跨域是浏览器层面的限制后端加CrossOrigin虽然能做但更推荐在开发环境用proxy在生产环境用Nginx两种方式都不用在后端代码里写CORS相关东西。7.2 数据库与后端之间的隐蔽坑有一个看起来非常怪异的问题前端联调时所有字段都能正常读写唯独金额字段传过去以后变成0。查了半天发现是实体类字段类型用了Integer而前端传的是小数MyBatis-Plus自动转换的时候把小数部分截掉了。解决办法是把金额字段统一用BigDecimal类型前后端都用字符串传递。这类问题在毕业设计里非常常见因为大家的字段类型一开始往往没有严格规范。还有一个小坑是时区问题。MySQL连接串里如果没有追加serverTimezoneAsia/Shanghai在高版本MySQL驱动下默认时区是UTC存进去的时间会差8个小时。我后来统一在application.yml的数据库连接串后面加上这个参数再配合日期字段使用LocalDateTime时间问题就再没出现过。7.3 论文与演示环境准备的经验答辩之前一定要做一次全流程的演示预演从浏览器打开系统、登录、新增客户、录入跟进记录、生成统计报表一个环节都不能省。演示的时候不要用自己电脑的localhost最好把项目完整部署到一台Linux服务器上浏览器里输入IP访问这种演示方式在视觉上可信度更高。我答辩前最后一周才把项目从本机搬到服务器结果发现前端打包后图片路径丢失、后端日志目录权限不对等问题幸好还来得及处理你们千万别卡在这个时间点上。论文排版上目录、图表编号、参考文献格式这些细节要提前按学校模板处理。图表不要截图模糊不清代码片段要标注清晰。我在论文里统一使用同一款中文字体代码用等宽字体这样整体版式会专业很多。8. 后记整个项目做下来我最深的体会是毕业设计真正锻炼人的不是某个技术栈用得有多花哨而是你能否把一个完整业务场景从头到尾拆解、设计、实现并交付。SpringBootVueMySQL这套组合本质上给你提供了一个可以快速上手的底座但让你成长的是每一个模块背后的业务思考、每一张表结构的设计取舍、每一次联调排错的过程。最后分享一个小技巧给客户的列表加一个“我负责的客户”和“全部客户”的切换筛选这个功能在后端只是加一个ownerId条件前端只有一个按钮成本极低但它在答辩现场能直观展示你对业务权限的理解。技术实现永远服务于业务价值这个认知才是毕设项目带给你最大的收获。如果你也在做这个题目建议按文章里的顺序一步步来先表结构、再后端、再前端、再部署每完成一个阶段就整体跑一遍稳扎稳打剩下的就交给时间。
阅读完成 · 觉得有帮助?
咨询建站