1. 项目概述:SSM+Vue全栈旅游网站开发实录
去年指导过一位学生的毕业设计,恰好就是基于SSM和Vue的中原旅游文化平台。这个技术组合在高校毕设中非常典型——后端用Spring+SpringMVC+MyBatis处理业务逻辑和数据持久化,前端用Vue构建交互界面,最终实现一个具备完整CRUD功能的旅游信息管理系统。这类项目看似简单,但实际开发时会遇到前后端联调、地图集成、大文件上传等具体问题,今天我就结合实战经验,把整个开发流程和关键实现细节梳理成文。
这个系统本质上是一个区域文化旅游资源的数字化展示平台,核心功能模块包括:
- 旅游景点管理(增删改查+多条件筛选)
- 用户评论互动系统
- 旅游路线规划工具
- 后台数据统计分析看板
- 基于第三方API的天气/交通查询服务
技术选型方面,后端采用SSM框架组合而非Spring Boot,主要是考虑到教学场景下需要学生手动配置更多组件以理解原理。前端选用Vue 2.x版本(虽然现在Vue 3已普及),因为学校教学进度通常滞后于业界,且Element UI等配套组件库对2.x支持更完善。
关键提示:实际开发前建议先用Axure或墨刀制作低保真原型,明确各模块间的数据流转关系,这对后期接口设计至关重要。很多同学跳过这步直接编码,导致后期频繁返工。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计与环境搭建
2.1 后端SSM框架整合
创建Maven项目时建议采用如下pom.xml核心依赖配置:
xml复制<!-- Spring核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
<!-- MyBatis整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
配置文件结构应遵循分层原则:
code复制src/main/resources
├── spring
│ ├── applicationContext-dao.xml
│ ├── applicationContext-service.xml
│ └── applicationContext-tx.xml
├── mybatis
│ ├── mybatis-config.xml
│ └── mapper/*.xml
└── jdbc.properties
数据库设计有几个易错点需要特别注意:
- 景点表(scenic_spot)与图片表(scenic_image)应建立一对多关系
- 用户评论需要记录IP属地(符合最新网络实名要求)
- 路线规划表(route)应包含GeoJSON字段存储地理坐标
2.2 前端Vue工程化配置
使用Vue CLI创建项目时推荐选择以下配置:
- Babel(ES6转译)
- Router(前端路由)
- Vuex(状态管理)
- CSS Pre-processors(选用Less)
- Linter(代码规范检查)
安装Element UI时要注意版本兼容性:
bash复制# 针对Vue 2.x的正确安装方式
npm install element-ui@2.15.9 -S
axios封装示例(需处理跨域和权限校验):
javascript复制// src/utils/request.js
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000,
headers: { 'X-Requested-With': 'XMLHttpRequest' }
})
// 请求拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['Auth-Token'] = getToken()
}
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
3. 核心功能模块实现细节
3.1 景点信息管理模块
后端Controller层典型代码结构:
java复制@RestController
@RequestMapping("/api/scenic")
public class ScenicSpotController {
@Autowired
private ScenicService scenicService;
@GetMapping
public Result list(@RequestParam Map<String,Object> params) {
PageUtils page = scenicService.queryPage(params);
return Result.ok().put("data", page);
}
@PostMapping("/{id}/like")
public Result like(@PathVariable Long id) {
scenicService.addLikeCount(id);
return Result.ok();
}
}
前端实现景点卡片组件时要注意:
- 使用懒加载优化图片性能
vue复制<el-image
:src="item.coverUrl"
lazy
:preview-src-list="previewList">
</el-image>
- 收藏功能需要防抖处理
javascript复制methods: {
handleCollect: _.debounce(function(id) {
collectScenic(id).then(res => {
this.$message.success(res.msg)
})
}, 500)
}
3.2 旅游路线规划实现
集成高德地图API的关键步骤:
- 在public/index.html引入SDK
html复制<script src="https://webapi.amap.com/maps?v=2.0&key=您申请的key"></script>
- 创建地图容器组件
vue复制<template>
<div id="map-container"></div>
</template>
<script>
export default {
mounted() {
this.initMap()
},
methods: {
initMap() {
const map = new AMap.Map('map-container', {
zoom: 11,
center: [113.625, 34.746]
})
// 添加路线规划插件
AMap.plugin('AMap.Driving', () => {
const driving = new AMap.Driving({
map: map,
panel: "route-panel"
})
})
}
}
}
</script>
数据库存储路线数据建议采用GeoJSON格式:
sql复制CREATE TABLE travel_route (
id BIGINT PRIMARY KEY,
name VARCHAR(100),
path GEOGRAPHY(LINESTRING),
created_at TIMESTAMP
);
4. 系统部署与性能优化
4.1 前后端分离部署方案
Nginx配置示例(解决跨域和路由问题):
nginx复制server {
listen 80;
server_name www.lyzy.com;
# 前端静态资源
location / {
root /home/vue-project/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# 后端API代理
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
4.2 常见性能问题解决方案
- 图片加载慢:使用WebP格式+CDN加速
java复制// 图片处理工具类
public class ImageUtils {
public static void convertToWebP(File src, File dest) {
try (InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest)) {
Thumbnails.of(is)
.outputFormat("webp")
.scale(1)
.toOutputStream(os);
}
}
}
- 列表页查询慢:添加复合索引
sql复制ALTER TABLE scenic_spot
ADD INDEX idx_region_grade (region_code, grade);
- 高并发点赞:Redis计数器+异步落库
java复制@Transactional
public void addLikeCount(Long scenicId) {
String key = "scenic:like:" + scenicId;
redisTemplate.opsForValue().increment(key);
// 异步任务将计数同步到数据库
threadPoolTaskExecutor.execute(() -> {
Integer count = Integer.parseInt(redisTemplate.opsForValue().get(key));
scenicMapper.updateLikeCount(scenicId, count);
});
}
5. 毕设论文写作要点
技术类毕业论文通常包含以下核心章节:
- 绪论(研究背景+意义)
- 相关技术综述(SSM/Vue技术栈分析)
- 系统需求分析(用例图+功能模块图)
- 系统设计(E-R图+类图+架构图)
- 系统实现(核心代码片段+界面截图)
- 系统测试(单元测试+压力测试结果)
特别提醒几个易扣分点:
- 所有图表必须要有编号和标题,如"图3-1 系统架构图"
- 参考文献需要包含近3年的学术文献(至少5篇)
- 代码截图应使用等宽字体(如Consolas),避免模糊
- 性能测试建议使用JMeter,记录并发量-响应时间曲线
测试用例表示例:
| 测试项 | 测试方法 | 预期结果 | 实际结果 |
|---|---|---|---|
| 用户登录 | 输入正确账号密码 | 跳转到首页 | 符合预期 |
| 景点搜索 | 输入"少林寺" | 显示相关景点 | 符合预期 |
| 路线规划 | 选择两个景点 | 生成最优路线 | 地图加载超时 |
我在指导过程中发现,优秀毕设往往在以下方面有突出表现:
- 引入可视化图表(如ECharts展示游客来源地分布)
- 实现非功能性需求(如SEO优化、PWA离线访问)
- 包含创新性功能(如AR景点识别、智能推荐算法)
- 完善的测试报告(单元测试覆盖率>70%)
最后给正在做类似项目的同学三个实用建议:
- 每天提交代码到GitHub私有仓库,避免毕业季电脑故障导致代码丢失
- 数据库变更使用Flyway管理,方便回滚和迁移
- 使用Swagger生成API文档,节省论文写作时间
