资讯详情

SpringBoot+Vue+MySQL商铺管理系统源码剖析与本地运行指南

📅 2026/10/13 3:42:50 | 华诺云谱 👁 阅读
SpringBoot+Vue+MySQL商铺管理系统源码剖析与本地运行指南
做校园信息化项目这些年我经手过不少类似“XX学院商铺管理系统”的实训项目。说实话这类系统单看名字容易让人觉得“不就是增删改查嘛”但真正上手跑一遍你会发现里面藏着的业务逻辑、前后端联调细节、数据库设计思路足够让一个初学者忙活好几天。这篇文章就以这个经典的 SpringBoot Vue MySQL 三件套组合为例完整拆解一套商铺管理系统源码它到底管理什么、源码该怎么看、本地怎么从零跑起来、运行中常见的坑有哪些以及从“能运行”到“能上线”之间还差了哪几步。无论你是要拿去做课程设计、毕业设计还是刚接触前后端分离项目想找一套完整代码练手这篇文章都值得你花十分钟读完。我默认你看过 Java 基础和基本的 SQL但没怎么碰过完整项目。所以文中每一步都会解释“为什么这样做”而不是只丢给你命令。1. 校园商铺管理从纸质台账到信息系统的痛点转移1.1 这个系统服务的真实场景先别急着打开代码想清楚业务场景比什么都重要。一般高校的校园商业区里少则几十家、多则上百家商铺和摊位管理方是学校的后勤部门。过去的管理方式很原始一份份纸质租赁合同散落在文件柜里租金收缴记录靠 Excel哪个合同快到期、哪个商户欠租全凭管理员脑子记。商户换了联系方式、营业执照到期没年检这些信息想查的时候翻半天。这套商铺管理系统要解决的就是把上述信息全部结构化。它面向的角色主要有两个管理员后勤人员和商户。管理员负责铺位信息、合同签订、租金账单、公告发布商户登录后基本只能查看自己的合同和缴费记录。所以系统在模块设计上通常是这么一套商铺管理记录每个铺位的位置、面积、租金标准、当前状态空闲、已出租、装修中商户管理维护商户名称、法人、联系电话、证照信息合同管理存储合同编号、关联的商铺和商户、租赁起止日期、租金金额租金管理按月或按季度生成缴费记录标记已缴、待缴、逾期公告管理发布停水停电、临时施工、政策类通知系统管理用户账号、角色、菜单权限。把这个清单和源代码里的菜单一对比你就能很快定位每个模块对应的代码位置。1.2 这类项目适合谁来参考如果你正处在下面某个阶段这套源码的参考价值会很大准备课程设计或毕业设计需要一个功能完整、技术栈主流的后端管理系统刚学完 SpringBoot 和 Vue 基础想看一个真实项目里 controller、service、mapper 是怎么分层协作的工作需要搭建一个轻量级的内部管理后台用这套结构当脚手架直接改造想看明白“前后端分离”模式下接口怎么设计、跨域怎么处理、登录状态怎么保持。当然这里也要说清楚这类系统本质上是“信息管理系统”核心操作是增删改查加权限控制。它不包含复杂的支付、电商购物车、推荐算法等逻辑但正因为业务边界清晰反而非常适合用来建立对完整项目结构的整体认知。2. SpringBoot Vue MySQL这个技术组合为什么是校园项目的稳妥选择2.1 三件套各自承担的角色用一句话概括这三个组件的关系Vue 负责用户看到和操作的页面SpringBoot 负责处理业务逻辑和提供数据接口MySQL 负责把数据持久化存下来。展开来说SpringBoot 之所以是后端首选是因为它把 Spring 家族最繁琐的配置自动化了。以前用 SSMSpring SpringMVC MyBatis搭一个项目要写一堆 XML 配置光“配置文件地狱”就能劝退新人。SpringBoot 的起步依赖把常用的库打包好了内嵌 Tomcat 让部署变成一个 java -jar 命令搞定。再加上校园课程体系普遍以 Java 为主线SpringBoot 几乎是 Java 后端项目的默认选择。前端方面Vue 的学习曲线比 React 平滑数据双向绑定让表单操作非常直观。更重要的是 Vue 生态里有 Element UI 这套现成的后台组件库表格、表单、弹窗、分页都封装好了开发效率极高。校园管理类系统的界面要求不高“干净、清晰、能点能用”就达标Element UI 刚好满足。MySQL 更不用多说开源免费、文档海量、主流云厂商都支持InnoDB 引擎下事务和行锁能力足以支撑这种日常并发量不大的管理系统。2.2 相比其他方案的取舍逻辑有人会问都什么年代了为什么不用微服务、不用 Docker、不用 Redis答案是没必要。一个商铺管理系统的并发量撑死了几十个人同时操作远没到需要分布式架构的地步。微服务拆分、消息队列、缓存集群这些技术在这里只会把简单问题复杂化反而让新手迷失在框架里找不到业务主线。另一个常见对比是 JSP 老项目和前后端分离的区别。JSP 是服务端渲染页面和后端代码耦合在一个工程里改造和维护都比较笨重。前后端分离后后端只输出 JSON 数据前端负责渲染职责清晰也方便以后给移动端或小程序复用同一套接口。这套源码采用的就是前后端分离这也是当前企业项目的主流形态。我在实际带项目时见过不少同学上来就纠结“要不要加 Redis 缓存、要不要上 Docker 部署”我的建议始终是先跑通、先理解再考虑引入更多组件。为学习加复杂度是加法为解决问题加复杂度才是加法——两者方向完全不同。3. 拿到源码后的第一件事读懂目录结构再动手3.1 后端项目的标准分层源码解压后一般会看到两个根目录比如 backend或 server和 frontend或 web。先看后端。一个典型的 SpringBoot 后端工程包名以 com.xxx.shop 这类形式组织核心包结构如下controller接收 HTTP 请求做参数初步校验调用 service 层返回统一响应对象service业务逻辑层事务边界基本在这一层比如“签订合同时同时更新商铺状态”这种跨表操作mapper数据访问层负责和 MySQL 交互常见的是继承 MyBatis-Plus 的 BaseMapper自带常用的增删改查方法entity或 pojo实体类一张表对应一个 Java 类字段与表结构一一对应config配置类比如跨域配置、MyBatis-Plus 分页插件、登录拦截器或 JWT 拦截器common或 common/response统一返回结果类 R以及全局异常处理器。拿到代码后我建议你先打开 pom.xml 看依赖再打开 application.yml 看配置。这两个文件能让你快速判断项目的版本信息——是 SpringBoot 2.x 还是 3.xJDK 是 8 还是 17数据库连接信息是什么。版本问题直接决定你本机环境该怎么装后文会专门讲。3.2 前端页面的模块组织前端如果是 Vue CLI 工程目录结构一般长这样src/api接口调用层每个模块一个 JS 文件把 axios 请求封装成函数src/router路由表定义登录页、首页、各个管理页面的路径src/store全局状态管理通常存登录用户信息和 tokensrc/views页面组件按模块分文件夹比如 shop、merchant、contract、rent、systemsrc/utils工具函数比如 axios 实例的封装、请求拦截器、响应拦截器vue.config.js开发环境配置重点是 devServer 的代理设置。前端这块比较关键的是理解“请求是怎么发出去的”。页面里的按钮事件触发 api 目录下的函数函数用 axios 发起 HTTP 请求到后端接口拿到 JSON 数据后渲染到表格里。所以排查前端问题时打开浏览器 F12 的 Network 面板看请求有没有发出去、返回什么状态码是最直接的思路。3.3 核心数据表关系预览数据库脚本里通常包含几张核心表先理清表间关系后面的代码就很好懂了sys_user系统用户表字段包括用户名、密码一般是加密后的密文、状态等sys_role角色表区分管理员和商户sys_user_role用户和角色的关联表多对多关系shop商铺表记录铺位信息merchant商户表记录商户主体信息contract合同表关联 shop_id 和 merchant_idrent_payment租金缴费表记录每期账单的金额和状态notice公告表。重点理解 shop、merchant、contract 三者之间的关系一个商铺在不同时期可以被不同商户承租一份合同对应一个商铺和一个商户所以商铺和商户不直接建立外键而是通过合同间接关联。这个设计在业务上更严谨也避免了“一家商店只能对应一个商户”这种死板的绑定。这个关系看懂了你再看 controller 里的新增合同接口就会发现它内部往往要同时更新商铺状态这就是典型的 service 层事务逻辑。4. 本地直接运行的完整操作流从 MySQL 建库到前端联调4.1 环境版本对照JDK、Node、数据库一个都不能错项目标题里写着“可直接运行”但“直接”是有前提的——你的本机环境必须和项目版本匹配。我根据这类项目的常见配置整理了一张版本对照表你可以先核对自己的环境。组件推荐版本说明JDK1.88u202 以上SpringBoot 2.x 项目最稳的版本Maven3.6.3建议配好阿里云镜像否则依赖下载会疯掉MySQL5.7 或 8.0注意两个版本的驱动名不同见下文Node.js12.x 或 14.xVue 2 Vue CLI 项目用太新的 Node 容易出兼容问题IDEIDEA 或 VSCode后端用 IDEA前端用 VSCode 即可这里特别提醒两个“版本刺客”。第一个是 MySQL 8 的驱动类名变了MySQL 5.x 时代用的是 com.mysql.jdbc.Driver8.x 之后变成了 com.mysql.cj.jdbc.Driver。如果项目配置里写的是老驱动而你本地装的是 MySQL 8启动时就会报 ClassNotFoundException。第二个是 node-sass很多 Vue 2 项目依赖 node-sass它和 Node 版本强绑定Node 版本过新大概率安装失败。遇到这种情况优先换用 Node 14而不是盲目升级项目。4.2 数据库初始化与配置文件修改打开项目里的 sql 文件夹通常会有一个 .sql 文件名称类似 shop_db.sql。用 Navicat 或命令行执行前先看一下文件开头如果包含 CREATE DATABASE 语句直接整体导入即可如果只有建表和插入数据的语句就要先手动建库再选择库执行。注意导入时如果中文注释或数据乱码多半是文件编码和连接字符集不一致。建议建库时显式指定字符集CREATE DATABASE shop_db DEFAULT CHARACTER SET utf8mb4;导入前确认连接选项里选了 utf8mb4。导入完成后打开后端 application.yml或 application-dev.yml核对这几项spring: datasource: url: jdbc:mysql://localhost:3306/shop_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的数据库密码url 里那串参数不是装饰品useUnicode 和 characterEncoding 解决中文乱码serverTimezone 解决 MySQL 8 的时区报错。经验之谈后两者缺一不可否则你会在启动日志里看到各种诡异的 SQL 时间错误。4.3 后端启动步骤与验证用 IDEA 打开 backend 目录首次加载要等 Maven 把依赖拉完这个过程取决于网络可能三五分钟也可能更久。依赖下载慢的去 settings.xml 里配阿里云镜像这是最有效的提速方式。依赖就绪后找到带有 SpringBootApplication 注解的主启动类右键运行。观察控制台日志看到类似 “Started Application in X.XXX seconds” 的字样说明后端启动成功。默认端口一般是 8080浏览器直接访问 http://localhost:8080 如果返回一个错误页或空页面是正常的因为后端没有页面只有接口。你可以试着访问一个具体的接口路径来验证比如 /api/shop/list能返回 JSON 就说明接口通了。4.4 前端启动与跨域联调配置接着打开 frontend 目录在终端执行 npm install。如果报错优先看是不是 node-sass 相关问题解决方案上面说过了。依赖装好后关键一步来了检查 vue.config.js或 config/index.js里的代理配置。开发环境下的典型代理配置长这样module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }这个配置的意思是前端开发服务器跑在 8081 端口凡是请求路径以 /api 开头的都转发到后端的 8080 端口。为什么需要代理因为浏览器有同源策略前端页面在 8081后端接口在 8080端口不同就是跨域。通过代理浏览器看到的所有请求都来自 8081跨域问题就绕开了。配置没问题后执行 npm run serve具体命令看 package.json 里的 scripts看到 “App running at” 的提示就是启动成功。浏览器访问 http://localhost:8081此时前端页面和后端接口已经打通输入管理员的默认账号密码就能登录系统。默认账号是什么项目里各不相同常见组合是 admin / 123456 或者 admin / admin123SQL 脚本里一般都有注释说明。4.5 运行期常见报错与处理速查把我在实际运行这类项目时遇到的高频问题整理成了一个速查表建议截图收藏。现象根因处理方式Maven 依赖一直卡住或下载失败中央仓库访问慢配置阿里云镜像仓库启动报 ClassNotFoundException: com.mysql.jdbc.DriverMySQL 8 驱动类名变化在 pom.xml 或配置中改为 com.mysql.cj.jdbc.Driver启动报时区异常 SQLExceptionMySQL 8 默认时区问题url 中加 serverTimezoneAsia/Shanghai连接数据库失败Access denied for user密码错误或权限不足核对 application.yml 中用户名密码连接数据库失败Cant connect to MySQL serverMySQL 服务未启动检查服务状态确认端口 3306后端端口被占用8080 被其他进程占用修改 server.port或结束占用进程前端 npm install 报 node-sass 相关错误Node 版本和 node-sass 不兼容换 Node 14删除 node_modules 后重装页面能打开但登录提示接口错误代理配置未生效或后端未启动检查 vue.config.js 代理确认后端运行中登录成功但列表数据为空数据库没有初始化数据或接口报错被前端吞掉检查 SQL 导入结果看 F12 网络请求返回这些坑单个看都不难难的是它们经常同时出现。我的建议是严格按照“先装环境 → 再导数据 → 再启动后端 → 最后启动前端”的顺序来每完成一步就验证一步别一次性把前后端加数据库全部启动再排查那样出了问题很难定位。5. 商铺管理系统的核心业务逻辑拆解5.1 商铺与商户的“一对多”关系设计前文提到商铺和商户通过合同间接关联这里展开讲一下为什么。假设一个校园商铺租给商户 A 两年合同到期后又租给了商户 B。如果直接在 shop 表里加一个 merchant_id 字段租约变更时就得把商铺记录里的商户字段改掉旧的历史信息完全丢失。而通过 contract 表记录每一段租赁关系就能保留完整的历史这个铺位曾经租给谁、什么时间段、租金多少一目了然。实际编码中实体字段大概是这种感觉shop: id, shop_no, name, location, area, monthly_rent, status merchant: id, merchant_name, legal_person, phone, license_no contract: id, contract_no, shop_id, merchant_id, start_date, end_date, monthly_rent, deposit这里有个细节值得注意合同里的 monthly_rent 是冗余存了一份的为什么不直接取 shop 表的租金标准因为租金可能随合同谈判浮动或者逐年递增。合同生效期间以后勤管理员的视角看“该收多少钱”应该以合同约定为准而不是商铺的挂牌价。所以每次签合同时把谈好的最终租金写进合同记录才是正确做法。这类“看似冗余、实为必要”的字段设计是最容易在实际业务里踩坑的地方。5.2 合同与租金最容易出业务 bug 的地方租金模块是整个系统里和钱相关的部分逻辑必须严谨。一张租金表 rent_payment 的典型字段包括id, contract_id, period_month账期年月, amount, status待缴/已缴/逾期, pay_time, operator_id。生成账单的逻辑通常是管理员录入合同时系统根据合同起止日期自动按月拆分成多条租金记录或者由管理员在“租金管理”页面手动选择合同、指定账期来生成。无论哪种方式核心要保证一条铁律一条合同的一个账期只能存在一条缴费记录不能重复生成。实现上一般靠数据库唯一索引contract_id period_month来兜底而不是只靠代码逻辑判断——因为并发操作时代码判断会有漏网之鱼。欠费和到期提醒也属于这个模块的延伸功能。到期提醒的本质就是一条 SQL查 end_date 距离当前日期小于 30 天且状态正常的合同。很多同学一开始想不到这些“隐藏功能”其实它们在管理场景里才是高频刚需。你可以在阅读源码时留意一下项目里是否已经实现了类似的查询如果没有这正好是二次开发的切入点。5.3 权限与公告管理后台的基本功既然是管理系统权限控制就绕不开。这类项目最通用的模型是 RBAC基于角色的访问控制用户属于角色角色拥有菜单权限。管理员能看系统管理菜单商户登录后只能看到合同查询和缴费记录。前端的路由守卫会判断当前用户角色没有权限的页面直接跳回首页后端的拦截器或注解会校验接口权限双重保护。这里要提醒一点前端隐藏入口≠安全。真正决定权限的是后端的接口校验。一个合格的商户如果直接构造请求去调用管理员的接口后端必须能拒绝他。你可以打开项目的拦截器配置看看如果它只处理了登录状态校验、没做角色授权校验那说明这套源码的安全模型还有待完善——这恰恰是你可以动手改造成简历亮点的方向。公告模块逻辑上相对独立就是发布、编辑、下架。但它也承担着“系统内通知”的职责比如合同到期、租金逾期时管理员在首页看到的提醒列表很多情况下就是通过查询公告或者其他表的统计来完成的。首页的数据统计卡片出租率、本月应收、已收、逾期金额看起来很唬人本质上也就是几条聚合 SQL。6. 直接运行不等于直接上线安全与部署建议6.1 默认账号密码风险项目能跑起来只是第一步。很多同学从网上下载的源码SQL 脚本里默认账号密码都是公开的比如 admin/123456。如果这个系统真的用于办公环境默认密码不换无异于把大门钥匙挂在门上。第一件事就是登录系统在用户管理里修改管理员密码或者直接改数据库里的密码字段。另一个容易被忽略的点是密码的存储方式。如果项目里用的是明文存储那必须在数据库里手动改成加密后的值。常见的做法是 MD5 加盐或 BCrypt。Spring Security 的 BCryptPasswordEncoder 是比较推荐的选择因为它自带随机盐同样的明文每次加密结果都不同抗彩虹表攻击能力更强。校园项目里最常见的是 MD5 固定盐安全性一般但至少比明文强得多。如果源码用的是明文建议你至少改造这一步。6.2 配置文件中敏感信息处理application.yml 里直接写数据库密码在本地开发没问题但要上线就非常危险。一旦代码仓库被分享、或者服务器配置文件被误读数据库就等于裸奔。稳妥的做法是使用环境变量spring: datasource: password: ${DB_PASSWORD}部署时在服务器上设置 DB_PASSWORD 环境变量代码里不再出现真实密码。同理如果项目里使用了 JWT 作为登录令牌jwt.secret 这种密钥也绝对不能硬编码必须从环境变量或配置中心读取。还有一点上线时把 SpringBoot 的默认错误页面改成自定义的避免异常堆栈直接暴露在响应里这些细节虽然小但都是真实项目评审时会问到的点。6.3 前后端生产构建与部署开发环境下 npm run serve 启动的是开发服务器只适合调试不适合对外提供服务。生产环境的标准做法是后端执行 mvn clean package -DskipTests在 target 目录生成可执行的 jar 包然后 java -jar xxx.jar 运行前端执行 npm run build生成 dist 静态目录把 dist 目录放到 Nginx 的 html 目录下Nginx 配置里把 /api 开头的请求反向代理到后端端口。一个最简的 Nginx 配置片段供参考server { listen 80; server_name your-domain; location / { root /usr/share/nginx/html; index index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; } }这样外部用户访问 80 端口获得前端页面请求 /api 时被转发到 SpringBoot 进程。数据库层面生产机上要设置更复杂的密码避免把数据库端口暴露在公网尽量只允许应用服务器访问。定时备份用 mysqldump 做即可命令可以写成 shell 脚本配合 crontab 定期执行数据量不大时这是最省事的方案。6.4 这个项目还能往哪个方向扩展如果你打算在这套系统的基础上做二次开发我按优先级给你几个方向增加登录验证码和失败次数限制这是安全评审里常见的加分项租金账单的 Excel 导入导出用 EasyExcel 实现后勤人员导出每月账单做账务核销是刚需到期提醒从“系统内公告”升级为邮件或企业微信消息推送首页数据看板用 ECharts 画出租率趋势图和租金收入统计视觉冲击力强答辩效果好给商户开放一个简单的小程序入口查合同、看账单、在线缴费申请这个扩展能直接把项目从“管理系统”推向“服务平台”。这些方向不是乱加功能而是顺着业务痛点自然生长出来的。做完任何一个都比单纯复述“我实现了增删改查”要有说服力得多。我在实际带项目过程中的体会是拿到一套二手源码跑通它只能算“会用”真正有价值的动作是拆开它——把数据表关系画出来、把登录鉴权的链路走一遍、把合同和租金的字段设计琢磨透。这套商铺管理系统就是很好的教材难度适中业务真实技术栈主流。你花一个周末把它彻底吃透收获的绝对不只是一个能运行的项目而是一整套“拿到新项目如何快速上手”的方法论。最后再送一个小技巧复制任何项目前先读 SQL 脚本里的注释和数据那是作者留给你的最容易读到的业务说明书。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑