1. 项目概述:SpringBoot+Vue全栈旅游平台开发实录
去年帮学弟调试毕业设计时,发现市面上很多旅游网站项目存在两个通病:要么是前端用JSP+后端SSM的老旧技术栈,要么是前后端分离但接口文档缺失。这个基于SpringBoot+Vue的全栈项目,不仅包含完整源码和SQL脚本,还特别整理了规范的接口文档,特别适合作为Java Web方向的毕业设计参考。
整套系统采用经典的前后端分离架构,后端基于SpringBoot 2.7提供RESTful API,前端使用Vue 3 + Element Plus构建管理后台,移动端则采用Vant组件库。数据库设计包含用户中心、景点管理、订单系统等6个核心模块,我在原基础上增加了Redis缓存热点数据和分布式Session方案,使项目更贴近企业级应用标准。
2. 技术栈选型与架构设计
2.1 后端技术栈深度解析
SpringBoot 2.7.12版本的选择经过慎重考虑:
- 相比最新3.x版本,2.7系对JDK8的兼容性更好(高校实验室普遍环境)
- 内置Tomcat 9.0容器足够稳定
- 整合MyBatis-Plus 3.5.3实现动态SQL构建
// 典型Service层实现示例 @Service public class ScenicSpotServiceImpl extends ServiceImpl<ScenicSpotMapper, ScenicSpot> implements IScenicSpotService { @Cacheable(value = "spots", key = "#id") public ScenicSpotVO getDetailById(Long id) { return baseMapper.selectDetailById(id); } }数据库选用MySQL 5.7而非8.0,主要考虑:
- 学校机房普遍安装的是5.7版本
- 项目不涉及JSON类型字段等新特性
- 更低的硬件资源占用
2.2 前端架构设计要点
Vue 3的组合式API大幅提升了代码可维护性,但需要注意:
- 使用Pinia替代Vuex进行状态管理
- 路由懒加载优化首屏性能
- 按需引入Element Plus组件(节省打包体积)
// 典型API调用封装 export const getScenicList = (params) => { return request({ url: '/api/scenic/list', method: 'get', params }) }3. 数据库设计与核心业务实现
3.1 数据库ER图与表结构
系统包含12张核心表,关系模型设计特别注意:
- 用户表与订单表采用逻辑外键(避免级联删除问题)
- 景点表包含geo字段存储经纬度(后续扩展LBS功能)
- 评价表采用垂直分表设计(主表存基础信息,扩展表存内容)
CREATE TABLE `t_scenic_spot` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL COMMENT '景点名称', `cover_img` varchar(255) DEFAULT NULL COMMENT '封面图URL', `geo_point` point NOT NULL COMMENT '经纬度坐标', `price` decimal(10,2) DEFAULT '0.00' COMMENT '门票价格', `status` tinyint DEFAULT '1' COMMENT '状态:0-下架 1-上架', PRIMARY KEY (`id`), SPATIAL KEY `idx_geo` (`geo_point`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;3.2 核心业务逻辑实现
订单模块采用状态机模式设计:
public enum OrderStatus { UNPAID(0, "待支付"), PAID(1, "已支付"), COMPLETED(2, "已完成"), CANCELLED(-1, "已取消"); // 状态流转校验逻辑 public static boolean canTransfer(OrderStatus from, OrderStatus to) { // 具体校验规则... } }支付对接支付宝沙箱环境时,特别注意:
- 需要配置应用公钥和支付宝公钥
- 异步通知地址必须为公网可访问(可用内网穿透工具)
- 金额单位是元(不是分)
4. 接口文档规范与API设计
4.1 Swagger与Knife4j整合
在SpringBoot中配置Knife4j增强UI:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.travel.web")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("旅游平台API文档") .version("1.0") .build(); } }接口设计遵循三个原则:
- 资源型URL(如
/api/scenic/{id}) - HTTP动词表示操作类型
- 统一响应格式:
{ "code": 200, "message": "success", "data": {} }4.2 接口安全方案
JWT认证流程:
- 登录接口返回access_token(有效期2小时)
- 前端存储在localStorage
- 每次请求携带在Authorization头
防XSS攻击:
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.headers() .xssProtection() .and() .contentSecurityPolicy("script-src 'self'"); } }5. 项目部署与运维实践
5.1 多环境配置管理
使用Spring Profiles区分环境:
# application-dev.yml server: port: 8080 datasource: url: jdbc:mysql://localhost:3306/travel_dev # application-prod.yml server: port: 80 datasource: url: jdbc:mysql://prod-db:3306/travel_prod前端通过.env文件管理环境变量:
VUE_APP_API_BASE_URL=/api VUE_APP_MAP_KEY=ABCDEFG5.2 常见部署问题排查
- 前端路由History模式404问题:
location / { try_files $uri $uri/ /index.html; }- MySQL连接数不足报错:
# application.properties spring.datasource.hikari.maximum-pool-size=20- 跨域问题解决方案:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .maxAge(3600); } }6. 毕业设计扩展建议
如果想提升项目竞争力,可以考虑:
- 增加Elasticsearch实现景点搜索
- 集成微信小程序端
- 添加Admin监控面板
- 实现简单的推荐算法(基于用户浏览历史)
在实现推荐功能时,基础的协同过滤算法可以参考:
public List<ScenicSpot> recommend(Long userId) { // 1. 获取用户历史行为 List<UserBehavior> behaviors = behaviorMapper.selectByUser(userId); // 2. 找到相似用户 Set<Long> similarUsers = findSimilarUsers(behaviors); // 3. 返回推荐结果 return spotMapper.selectRecommendedSpots(similarUsers); }项目源码中我特别标注了七个关键扩展点,包括支付回调处理、定时任务调度等常见业务场景的实现细节。对于需要答辩演示的同学,建议提前准备好数据库压力测试报告和接口性能指标,这往往是答辩加分项。