尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+Vue+MySQL汽车销售系统全栈实战解析

SpringBoot+Vue+MySQL汽车销售系统全栈实战解析 项目标题给得很明确“web汽车销售系统信息管理系统源码-SpringBoot后端Vue前端MySQL【可直接运行】”。这类前后端分离的管理系统近几年在毕业设计、个人项目、中小企业信息化改造里出现频率相当高。作为一个完整跑通的实战项目它覆盖面其实很广SpringBoot负责接口层Vue负责页面交互MySQL存业务数据三步下来就是一个标准的企业级Web应用雏形。这篇文章我打算完全站在“自己刚从零把这个系统做出来并跑通”的角度来写把整个系统的设计思路、核心模块、数据库表关系、前后端联调细节以及最容易踩坑的地方全部整理出来。无论你是准备拿它当毕设还是想找个项目练手熟悉全栈开发流程又或者公司正好需要一个简单的汽车销售管理后台这文章都能给你一个可以照做的完整路径。1. 系统整体设计与思路拆解1.1 为什么选SpringBootVueMySQL这套组合先说选型。市面上做管理系统的方案非常多老一点的用JSPServlet后来流行过SSHStrutsSpringHibernate、SSMSpringSpringMVCMyBatis再往后就是SpringBoot一统天下。前端也从jQueryHTML混着写进化到Vue、React这类组件化框架。为什么这套系统选SpringBootVueMySQL不是没有理由的。SpringBoot解决的是后端开发效率问题。它把Spring生态里繁琐的XML配置全部干掉通过自动配置让你专注写业务代码。你可以理解成以前做饭要先砌灶台、砍柴、生火现在直接打开燃气灶就能下锅。对于汽车销售系统这种业务逻辑并不算极端复杂、但要快速交付的信息管理系统SpringBoot的默认约定能省掉大量时间。Vue解决的是前端交互体验问题。汽车销售管理涉及大量列表查询、表单填写、弹窗确认这类操作如果用传统方式刷新页面体验会很割裂。Vue的双向数据绑定、组件化开发配合Element UI这类组件库可以快速搭建出响应快、操作流畅的后台界面。MySQL解决的是数据可靠存储问题。汽车销售数据包括车辆信息、客户资料、订单流水、成交金额这些都是典型的二维结构化数据用关系型数据库存储最合适。MySQL在中小体量项目里的性能、稳定性、生态支持都是经过验证的而且完全免费部署成本极低。这套技术栈真正流行还有一个隐蔽原因招聘市场需求大。你会发现很多公司的Java开发岗位都写着“熟悉SpringBoot、Vue、MySQL”因为这三个东西基本组成了一套通用业务系统的最小技术闭环。学习这套组合的性价比非常高。1.2 汽车销售系统的核心业务闭环这个系统到底要解决什么问题我先梳理一下汽车销售业务的基本流程。一个典型的4S店或者汽车销售公司的日常运营大致是这么个环路车辆入库采购/调拨 - 车辆展示库存管理 - 客户看车线索管理 - 销售跟进 - 签单成交订单管理 - 车辆出库 - 售后跟进。信息系统要管的就是把这些线下流程搬到线上让管理者能够实时看到车辆库存状态、客户跟进情况、销售业绩数据。所以汽车销售系统的核心模块基本固定为这几个系统管理员工账号、角色权限、客户管理客户信息、跟进记录、车辆管理车辆档案、库存状态、订单管理购车订单、合同信息、统计报表销售数据、库存数据。一个完整的系统源码这五个模块是底线少了任何一个业务闭环就不完整。1.3 项目目录结构拿到源码先看哪里很多朋友拿到源码第一反应是直接运行跑不起来就一头雾水。我的建议是先看目录结构搞清楚每个文件夹是干什么的然后再启动也不迟。一个标准的前后端分离项目通常会分成backend后端和frontend前端两个大目录有些还会带一个sql目录存放数据库脚本。以这套汽车销售系统为例结构大概是这样的web-car-sales-system/ ├── backend/ # SpringBoot后端 │ ├── src/main/java/ # Java源码 │ │ └── com/xxx/carsales/ │ │ ├── controller/ # 接口层 │ │ ├── service/ # 业务逻辑层 │ │ ├── mapper/ # 数据访问层 │ │ ├── entity/ # 实体类 │ │ ├── config/ # 配置类 │ │ └── common/ # 公共工具、统一返回对象、异常处理 │ ├── src/main/resources/ # 配置文件 │ │ ├── application.yml # 核心配置 │ │ └── mapper/ # MyBatis XML文件 │ └── pom.xml # Maven依赖管理 ├── frontend/ # Vue前端 │ ├── src/ │ │ ├── api/ # 接口请求封装 │ │ ├── views/ # 页面组件车辆管理、客户管理等 │ │ ├── router/ # 路由配置 │ │ ├── store/ # 状态管理 │ │ ├── components/ # 公共组件 │ │ └── utils/ # 工具类如request.js │ ├── package.json # 前端依赖 │ └── vue.config.js # Vue配置文件 └── sql/ └── car_sales.sql # 数据库初始化脚本拿到源码后先对照这个目录找到对应的文件夹在脑子里把前后端的关系梳理清楚前端页面通过axios发请求后端Controller接收走Service层处理业务逻辑再通过Mapper操作MySQL数据库数据返回后由前端渲染到页面上。整个链路理解了剩下的事情就是让代码跑起来。2. 数据库设计与核心表结构解析2.1 数据表规划从业务到建表的思路数据库设计是这套系统最见功力的地方。我见过很多新手拿到需求就急着建表结果表建到一半发现字段不够用或者表与表之间的关联关系乱成一团最后只能在代码里拼凑逻辑。正确的做法是先梳理业务实体再确定实体之间的关系最后落到表结构上。汽车销售系统里有几个核心实体用户/员工系统登录账号关联角色权限客户购车人信息可能是潜在客户也可能是已成交客户车辆车辆档案包含品牌、型号、颜色、售价、库存状态订单客户购车交易记录关联客户和车辆公告/新闻部分系统会有资讯发布模块用于内部通知或对外展示实体之间的关系一个客户可以下多个订单一对多一个订单包含至少一辆车一对一或一对多一个用户归属一个角色多对一一个角色拥有多个权限多对多。2.2 核心表结构详细说明我用这套系统实际用到的主要表结构来做说明。用户表sys_user这张表存的是登录账号和基本信息。字段设计上有几个关键点需要注意密码一定不能明文存储至少用MD5加盐或者BCrypt加密状态字段用于控制账号是否启用实现账号锁定功能创建时间由数据库自动维护便于后续审计。CREATE TABLE sys_user ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户ID, username varchar(50) NOT NULL COMMENT 用户名, password varchar(100) NOT NULL COMMENT 密码加密存储, real_name varchar(50) DEFAULT NULL COMMENT 真实姓名, phone varchar(20) DEFAULT NULL COMMENT 手机号, role_id int(11) DEFAULT NULL COMMENT 角色ID, status tinyint(1) DEFAULT 1 COMMENT 状态1启用0禁用, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表;车辆信息表car_info车辆信息表是汽车销售系统最重要的表之一。除了品牌、型号这些常规字段颜色、售价、库存状态需要单独列出来因为它们是销售业务中的筛选条件和决策依据。我在实际设计时还加了vin_code字段作为车辆唯一识别码相当于车架号。细心一点还会加上上架状态区分“在售”和“已下架”的车辆。CREATE TABLE car_info ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 车辆ID, brand varchar(50) NOT NULL COMMENT 品牌, model varchar(50) NOT NULL COMMENT 车型, color varchar(20) DEFAULT NULL COMMENT 颜色, price decimal(10,2) DEFAULT NULL COMMENT 售价, vin_code varchar(50) DEFAULT NULL COMMENT 车架号, stock_status tinyint(1) DEFAULT 1 COMMENT 库存状态1在库0已售, shelf_status tinyint(1) DEFAULT 1 COMMENT 上架状态1上架0下架, remark varchar(500) DEFAULT NULL COMMENT 备注, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT车辆信息表;客户表customer客户表记录的是购车人或潜在客户的联系信息。字段上除了姓名、电话这类基本信息我加了customer_level字段区分客户意向度这在销售业务里非常实用。比如A类客户是近期购车意向强烈的B类是还在观望的销售可以根据级别分配精力。还有跟进状态字段用于标记客户是否已成交。订单表sales_order订单表是业务核心关联了客户和车辆。这里有个设计上的取舍是把车辆信息直接冗余在订单表里还是通过外键关联车辆表我的做法是两者结合关联vehicle_id保证数据一致性同时冗余一份车辆品牌型号和成交价格在订单表里。原因很简单车辆信息后续可能调整比如改售价但历史订单必须保留成交那一刻的快照否则财务对账会出问题。CREATE TABLE sales_order ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 订单ID, order_no varchar(50) NOT NULL COMMENT 订单编号, customer_id int(11) NOT NULL COMMENT 客户ID, car_id int(11) NOT NULL COMMENT 车辆ID, car_brand varchar(50) DEFAULT NULL COMMENT 车辆品牌快照, car_model varchar(50) DEFAULT NULL COMMENT 车型快照, sale_price decimal(10,2) NOT NULL COMMENT 成交价格, salesman_id int(11) DEFAULT NULL COMMENT 销售员ID, order_status tinyint(1) DEFAULT 0 COMMENT 订单状态0待付款1已付款2已完成, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 下单时间, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT销售订单表;2.3 表关系设计经验谈表之间怎么建立关系是全栈项目里最容易纠结的地方。外键到底要不要建我的建议是项目初期可以不建物理外键只用逻辑关联通过字段关联查询。理由有两个一是物理外键会影响插入和删除性能大数据量下尤为明显二是后期业务调整表结构时外键约束容易成为阻碍。但这不代表可以随便乱关联逻辑外键必须靠代码保证一致性比如删除客户前要检查是否有关联订单。另外一个经验是时间字段统一用datetime类型金额字段统一用decimal(10,2)状态字段统一用tinyint并写注释字符串统一用varchar并设置合理的长度。这些看起来是细节但到了后期查数据、写统计报表的时候规范化的表结构会让人省心很多。3. 后端SpringBoot核心实现细节3.1 Maven依赖与配置文件讲解后端的pom.xml是整个项目依赖的地基。核心依赖无外乎这几个spring-boot-starter-web提供Web能力mybatis-spring-boot-starter负责数据库操作mysql-connector-java是MySQL驱动lombok可以减少实体类的样板代码。另外如果要做权限校验spring-boot-starter-security可以做登录认证不过为了降低上手难度很多项目也会用简单的拦截器实现。配置文件application.yml里最核心的是数据源配置和MyBatis配置。数据源配置要注意几个坑时区参数serverTimezoneAsia/Shanghai一定不能省否则数据库连接会报时区错误url里的useSSLfalse建议加上本地环境不需要SSL加密否则会有告警提示。MyBatis配置里要注意把mapper-locations指到正确路径并开启驼峰命名映射这样数据库的字段名下划线风格可以自动映射到Java的驼峰属性。server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/car_sales?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.carsales.entity configuration: map-underscore-to-camel-case: true3.2 Controller层设计统一返回结构与接口规范前后端分离项目里接口返回的数据格式一定要统一否则前端处理起来会非常痛苦。我在这套系统里定义了一个统一的Result类包含code、message、data三个字段。code为200表示成功500表示服务器错误401表示未登录或登录过期。不管哪个接口返回的都是这个结构。Controller层要注意的点接口路径命名要规范比如车辆管理模块用/car/list、/car/add、/car/update、/car/delete这种Restful风格接收参数用RequestBody接收JSON对象用RequestParam接收查询参数分页查询统一接收pageNum和pageSize返回给前端时携带总记录数。RestController RequestMapping(/car) public class CarController { Autowired private CarService carService; GetMapping(/list) public Result list(RequestParam Integer pageNum, RequestParam Integer pageSize, RequestParam(required false) String brand) { PageResult pageResult carService.getCarList(pageNum, pageSize, brand); return Result.success(pageResult); } PostMapping(/add) public Result add(RequestBody CarInfo carInfo) { carService.addCar(carInfo); return Result.success(); } }3.3 Service层业务逻辑的正确打开方式Service层住着系统的业务规则。很多人写代码时容易犯一个毛病把业务逻辑全堆在Controller里结果Controller几百行Service空空如也。正确的做法是Controller只负责参数接收和结果封装具体的判断、计算、数据组装都放在Service里。以新增订单为例Service层要做的事情包括校验客户是否存在校验车辆是否存在且处于在库状态生成唯一订单编号创建订单记录将车辆库存状态改为已售。任何一个环节失败都要抛出异常并回滚事务。这就是事务管理的典型应用场景用Transactional注解标记方法任何一步出错前面所有数据操作都会回滚保证数据一致性。Service public class OrderServiceImpl implements OrderService { Autowired private OrderMapper orderMapper; Autowired private CarMapper carMapper; Transactional(rollbackFor Exception.class) Override public void createOrder(SalesOrder order) { CarInfo car carMapper.selectById(order.getCarId()); if (car null || car.getStockStatus() ! 1) { throw new BusinessException(车辆不存在或已售出); } order.setOrderNo(generateOrderNo()); order.setCarBrand(car.getBrand()); order.setCarModel(car.getModel()); orderMapper.insert(order); // 更新车辆状态为已售 car.setStockStatus(0); carMapper.updateById(car); } }3.4 登录认证与权限控制的实现方案管理系统必须有登录功能也必须有权限控制。这套系统的权限模型是RBAC基于角色的访问控制也就是用户属于某个角色角色拥有若干权限权限控制到菜单/按钮级别。实现上常见有两种方案一是用Spring SecurityJWT功能强大但学习曲线陡峭二是自己写拦截器自定义注解轻量直接适合中小项目。如果项目时间紧建议用第二种。具体实现思路用户登录成功后返回一个token前端把token存在localStorage里每次请求在Header中携带。后端写一个拦截器拦截需要认证的请求路径从Header里取出token并解析如果token无效或过期直接返回401。权限控制上可以在拦截器里校验当前用户角色是否拥有访问该接口的权限。需要说明的是代码层面最好把拦截器放行路径和维护接口路径区分开登录接口、静态资源、验证码接口放行其余全部拦截。我见过一个项目漏配了放行路径导致登录接口也被拦截前端怎么也登不进去查了半天才发现是这个问题。4. 前端Vue核心实现与页面拆解4.1 前端项目结构和依赖说明Vue前端部分我建议直接基于Vue CLI创建项目配合Element UI组件库来做后台管理界面。这套组合是当前最成熟的中后台解决方案表格、表单、弹窗、菜单这些管理系统的标配组件Element UI都帮你封装好了开箱即用。前端目录里最需要理解的是几个核心部分router目录定义页面路由每个路由映射一个组件store目录做全局状态管理主要存用户信息和登录状态utils/request.js是axios封装统一处理请求头、响应拦截、错误提示api目录按模块封装接口请求函数比如car.js里就是车辆增删改查的请求方法。package.json里的依赖通常包括vue、vue-router、axios、element-ui、vuex、sass等。装依赖的时候有个常见问题就是npm install速度慢或者报错后面第5部分我会细说。4.2 登录页面与token处理逻辑登录页是整个系统的入口。登录流程很简单用户输入用户名密码点击登录前端把数据POST到后端/login接口后端验证成功后返回token和用户信息前端把token存到localStorage并把用户信息存入Vuex然后跳转到首页。这里的核心细节在于axios请求拦截和响应拦截。请求拦截器负责给每个请求自动加上Authorization请求头值为当前用户的token响应拦截器负责统一处理返回结果当后端返回401时自动清除本地token并跳回登录页。这样前端每一个页面都不需要重复写登录校验逻辑。// request.js核心代码 service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] token } return config }) service.interceptors.response.use( response { const res response.data if (res.code 401) { localStorage.removeItem(token) router.push(/login) return Promise.reject(new Error(未登录)) } return res }, error { Message.error(网络请求异常) return Promise.reject(error) } )4.3 车辆管理页面列表查询与分页实现车辆管理模块是前端最典型的CRUD页面包含了列表展示、条件查询、分页、新增、编辑、删除、状态切换这些功能一整页代码写下来基本就把Element UI常用组件都练了一遍。列表查询使用el-table组件列字段和后端返回的字段一一对应。库存状态列用el-tag标签展示在库显示绿色已售显示灰色。操作列放编辑、删除按钮。分页用el-pagination组件current-page和page-size与后端接口参数对应。条件查询区放一个el-input输入品牌关键字和一个搜索按钮点击搜索重新加载第一页数据。新增和编辑共用一个弹窗表单。数据回显的逻辑是点击编辑时根据当前行数据给表单赋值提交时判断是否有ID字段有就是更新操作没有就是新增操作。这块写熟练了以后任何管理模块的CRUD页面都能套用这个模板。4.4 订单管理页面关联数据展示与状态流转订单管理页面比车辆管理稍微复杂因为订单数据关联了客户和车辆。前端列表展示时要同时显示客户姓名、车辆品牌车型、销售员姓名、订单状态这些数据要么后端接口返回一个组装好的VO对象要么前端循环里根据ID去查对应表。我推荐后端直接返回组装好的订单VO视图对象包含订单本身字段和关联的客户名、车辆名、销售员名。前端不需要做多次请求页面加载快代码也简洁。订单状态是数字前端需要用formatter或者计算属性把它转成文字。状态流转可以设计为待付款 - 已付款 - 已完成管理后台提供一个“确认收款”按钮点击后把订单状态从待付款改成已付款车辆状态也同步变为已售整个操作链路就完整了。5. 环境搭建与项目启动全流程5.1 本地开发环境准备JDK、Node、MySQL安装要点先把环境搞定。后端需要JDK 8以上推荐JDK 8或者JDK 11稳定兼容性最好。如果你机器上装的是JDK 17甚至更高版本大概率会遇到SpringBoot版本和JDK版本不匹配的问题比如javax到jakarta的命名空间变更所以别盲目追求高版本够用就行。Node.js建议装14以上的LTS版本前端跑得动Vue项目即可。npm是自带包管理工具不过国内网络环境经常会遇到安装依赖超时的问题建议一行命令给npm配淘宝镜像npm config set registry https://registry.npmmirror.comMySQL安装分两种方式官方安装包和免安装解压版。官方安装包图形化操作直观一路Next即可但要记得自定义端口和数据目录免安装版需要自己配置my.ini文件并手动初始化稍微麻烦一点。无论哪种方式安装完第一件事是确认root账号密码能正常登录因为后端配置文件的数据库密码必须和实际一致。5.2 初始化数据库导入SQL脚本的两种方式拿到源码中的car_sales.sql文件后需要把它导入MySQL。这里有两种操作方式命令行导入和Navicat可视化导入。命令行导入适合熟悉终端操作的同学mysql -u root -p car_sales.sql输入root密码后回车脚本会自动执行。Navicat方式更直观新建连接右键点击数据库选择运行SQL文件选中car_sales.sql执行即可。导入完成后刷新一下数据库就能看到sys_user、car_info、customer、sales_order这些表初始数据一般会带一个admin账号和几条测试车辆记录。5.3 后端启动步骤与常见启动失败排查后端启动相对简单这里分IDE和命令行两种方式说明。使用IDEA的话直接File - Open选中backend目录等待Maven自动下载依赖然后找到主启动类类名带SpringBootApplication注解的那个右键Run即可。如果你更习惯命令行可以在backend目录下执行mvn spring-boot:run或者先打包再启动mvn clean package -DskipTests java -jar target/car-sales-0.0.1-SNAPSHOT.jar启动过程中最常见的报错无非几种端口被占用把server.port改成8081或者杀掉占用进程就能解决数据库连不上检查MySQL服务是否启动、用户名密码是否正确、数据库名是否存在Maven依赖下载失败换阿里云镜像或者检查网络。5.4 前端启动步骤与跨域问题解决前端启动更简单在frontend目录下依次执行npm install npm run servenpm install如果失败多半是网络问题检查镜像配置、清缓存重装。npm run serve成功后终端会显示一个本地访问地址一般是http://localhost:8081之类的端口。如果终端提示端口被占用可以用npm run serve -- --port 8082指定新端口。前端启动后访问页面大概率会遇到跨域问题。浏览器控制台会报CORS错误这是因为前端运行在localhost:8081后端接口在localhost:8080端口不同浏览器认为这是跨域请求。解决方案有两种一是在后端加CORS配置类允许所有来源访问二是在前端vue.config.js里配置devServer的proxy代理把/api开头的请求转发到后端地址。我推荐第二种方案它不修改后端代码而且上线时配置灵活。// vue.config.js module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }6. 常见问题与排错技巧实录6.1 数据库连接失败从url到权限的排查路径“数据库连接失败”是这套系统里出现频率最高的报错之一。完整报错信息通常长这样Cannot create PoolableConnectionFactory或者Access denied for user。排查路径我总结成了四步第一步查MySQL服务是否启动Windows下可以在服务管理器里查看mysql服务状态第二步查application.yml里的连接参数url里的数据库名是否存在账号密码是否正确第三步查url参数时区参数、编码参数是否齐全第四步查防火墙和端口3306端口是否被占用或屏蔽。实际项目里罪魁祸首基本是密码不一致或者数据库名不存在。很多人安装MySQL时设置的root密码和后端配置文件里的“123456”对不上一改密码就通了。还有个隐藏坑是MySQL 8以上版本的认证插件和旧驱动不兼容解决方法是确保pom.xml里用的是mysql-connector-java 8.0以上版本。6.2 前端接口404或500联调排查思路页面能打开但数据加载不出来这是前后端联调阶段最常见的现象。404和500要分开排查404说明接口路径没对上大概率是前端api文件里的url和后端Controller的RequestMapping路径不一致逐个字符对比一下就能发现500说明请求到后端了但代码执行出错去后端控制台看异常堆栈重点看是SQL语法问题还是空指针。这里有一个非常实用的技巧打开浏览器F12开发者工具切到Network面板查看失败请求的状态码和响应内容。响应体里后端返回的异常信息往往是排查问题最直接的线索。前端控制台打印的报错也要仔细看axios封装的错误信息里一般会包含后端返回的message字段内容。6.3 分页查询显示异常参数传递与返回格式分页功能是管理系统的高频功能也很容易出问题。常见表现有三种点击下一页没反应、总条数显示0、数据没有正确更新。排查思路确认前端传给后端的pageNum和pageSize参数名是否一致业界常用pageNum从1开始pageSize默认10确认后端返回的结构是不是total和records两个字段如果命名对不上前端就拿不到数据或者渲染异常。另外提醒一个容易被忽略的点搜索条件和分页状态是联动的。点击搜索以后页码要重置为1否则你可能正在看第5页搜索后还在第5页结果就是“搜索后没有数据”其实是数据在满足条件的结果集只有3页以下。这个逻辑在搜索按钮的点击事件里加上pageNum 1即可。6.4 Element UI表格渲染问题字段名与数据格式表格渲染不出来或者某一列是空的这个问题的排查方向主要有两个数据有没有到前端字段名对不对。数据有没有到前端可以打开Network看接口返回的JSON结构如果一切正常那就是字段名不匹配。Element UI的el-table-column通过prop属性绑定字段名如果后端返回的是createTime前端写成create_time数组就是空的。另外后端LocalDateTime类型的数据默认序列化格式是“2024-01-01T12:00:00”如果前端想显示成“2024-01-01 12:00:00”需要后端配置Jackson的date-format或者在前端写formatter格式化。6.5 登录失效与token过期问题登录状态丢失是管理系统运营过程中用户反馈最多的问题。原因通常是token过期时间设置太短或者后端返回401后前端错误处理逻辑没写对。实际项目里token有效期建议设置4到8小时太短了用户频繁重新登录影响体验太长了有安全隐患。如果你用自定义token方案需要在前端响应拦截器里对401做统一处理清除本地token弹出“登录已过期请重新登录”的提示然后跳转到登录页。还有一个细节页面刷新后Vuex里的用户信息会丢失因为Vuex默认是内存存储。解决方案是在页面刷新前把用户信息存到localStorage或者在App.vue的created钩子里重新从后端获取当前用户信息。6.6 项目扩展思路这个系统后续能往上加什么这个项目跑通以后你不妨想想还能加什么功能。从业务角度可以增加客户跟进记录模块记录每次和客户的沟通内容方便销售交接增加车辆图片上传功能让车辆展示更直观增加销售提成计算模块根据订单金额自动算销售员提成。从技术角度可以引入Redis做验证码存储和缓存引入Spring Security做更细粒度的权限控制部署时用Docker打包前后端用Nginx做反向代理。这些都是面试时可以拿出来讲的点比单纯说“我做过一个管理系统”要有说服力得多。我自己的体会是这类全栈项目最有价值的地方不在于用了多高深的技术而在于它把一个业务的完整链路打通了。你从前端页面写到后端接口再从后端接口写到数据库表任何一个环节出了问题都会在联调阶段暴露出来。把这些暴露出来的问题一个个解决掉你对SpringBoot、Vue、MySQL这套技术栈的理解就已经超过绝大多数只写过demo的人了。
返回列表