
30款热门AI模型一站整合DeepSeek/GLM/Claude 随心用限时 5 折。 点击领海量免费额度1. 先搞清楚这个“旅游分享平台”到底要做什么看到“丽江市旅游分享平台小程序”这个标题很多同学第一反应是这不就是一个带后台的旅游论坛吗但如果你真这么想从毕业设计到实际跑通中间会踩一堆坑。这个项目的核心不是简单地用 SpringBoot 和 Vue 把用户、帖子、评论的增删改查做出来而是要解决一个具体场景下的信息流转问题——如何让游客方便地发布、查找和互动丽江本地的旅游经验。这意味着你的设计必须围绕“丽江”这个地域特色。比如用户发布的“分享”可能需要关联具体的景点玉龙雪山、丽江古城、泸沽湖、美食腊排骨、鸡豆凉粉、住宿区域束河古镇、大研古城。后台管理也不仅仅是审核帖子可能还需要维护一个本地的景点库、标签体系。小程序端则要优先考虑移动场景下的图片上传、定位、轻量级交互。所以在动手写第一行代码之前你得先想清楚几个关键点核心功能边界是纯 UGC用户生成内容的文字图片分享还是需要整合一些 POI兴趣点信息是否需要做简单的路线规划或收藏夹功能技术栈选型确认标题给了javaspringbootvue这是经典的前后端分离架构。后端用 SpringBoot 提供 RESTful API前端用 Vue 构建单页应用而“小程序”则暗示前端可能要用 uni-app 或 Taro 这类跨端框架来编译成微信小程序或者直接用微信小程序原生开发但通过 Vue 的语法如 mpvue 或 uni-app来写。这里最容易混淆需要尽早确定。数据模型设计用户、旅游分享文章、评论、点赞、收藏、景点标签、图片表这些实体之间的关系怎么设计特别是分享与多个景点标签的多对多关系如果设计不好后期查询会非常麻烦。我建议你先别急着找源码而是拿出一张纸画出系统的核心用例图和数据表 ER 图草稿。这是避免你后期返工最关键的一步。2. 环境搭建别在配置上浪费三天确定了方向接下来就是搭环境。对于 Java SpringBoot Vue 的毕业设计我见过太多同学卡在环境配置上一卡就是好几天。下面我按最稳妥的顺序给你一个可复现的清单。2.1 后端 (SpringBoot) 环境准备后端环境相对单纯但版本对齐是重点。JDK统一使用JDK 8或JDK 11。这是 SpringBoot 2.x 系列最兼容的版本。不建议为了“新”而用 JDK 17可能会遇到一些依赖库不兼容的问题。安装后务必确认JAVA_HOME环境变量配置正确。Maven安装 3.6.x 或以上版本。配置好国内镜像源阿里云、华为云等这能让你下载依赖的速度飞起。在~/.m2/settings.xml中配置。IDEIntelliJ IDEA社区版或旗舰版。它对 SpringBoot 的支持最好。用 Eclipse 或 VS Code 也可以但 IDEA 的自动配置和提示能省很多事。数据库MySQL 5.7或8.0。丽江旅游分享平台的数据结构不会太复杂MySQL 完全足够。记得提前安装好并创建一个空的数据库比如lijiang_travel。SpringBoot 版本建议选择SpringBoot 2.7.x的稳定版本例如 2.7.18。这是长期支持版本资料多坑少。避免使用 3.0 的初始版本除非你明确需要其中的新特性。在 IDEA 中创建新项目时选择Spring Initializr勾选以下依赖Web: Spring WebSQL: MyBatis Framework, MySQL DriverNoSQL: (可选) 如果要做缓存可以加 Redis其他: Lombok (极大减少Getter/Setter代码) Validation (参数校验)创建完成后检查pom.xml确保关键依赖版本一致。一个常见的坑是mybatis-spring-boot-starter的版本与 SpringBoot 版本不匹配建议使用 Spring Initializr 默认生成的版本。2.2 前端 (Vue) 与小程序环境抉择这里是第一个分水岭。你有两条路方案AVue 构建管理后台小程序端单独开发管理后台使用 Vue 2.x 或 3.x 配合 Element UI 或 Ant Design Vue 这类组件库快速搭建。通过 Axios 调用后端 API。小程序端使用微信小程序原生开发或者使用uni-app。uni-app 允许你用 Vue 的语法写代码然后编译到微信小程序、H5、App等多个平台。对于毕业设计我强烈推荐 uni-app因为它能让你复用 Vue 的知识一套代码多端发布性价比极高。需要安装Node.js (建议 16.x 或 18.x LTS版本)Vue CLI (npm install -g vue/cli)HBuilderX (uni-app 官方IDE开发体验较好) 或 配置 uni-app 的 Vue CLI 脚手架。方案B纯 Vue 构建 H5并嵌入小程序Web-View这种方式比较取巧整个用户端就是一个 Vue 开发的 H5 页面然后通过微信小程序的web-view组件加载。好处是开发最快完全用 Vue 技术栈。缺点是用户体验不如原生小程序流畅且部分小程序能力受限。对于追求快速完成、功能不太复杂的毕业设计这也不失为一种选择。我的建议如果你的项目要求是“小程序”且希望体验更原生、功能更完整选方案A用 uni-app。如果时间非常紧张或者对小程序原生API需求不高可以考虑方案B。2.3 初始化项目结构一个清晰的项目结构能让你后续开发心明眼亮。lijiang-travel-platform/ ├── backend/ # SpringBoot 后端项目 │ ├── src/main/java/com/lijiang/ │ │ ├── controller/ # 控制器接收前端请求 │ │ ├── service/ # 业务逻辑层 │ │ ├── service/impl/ │ │ ├── mapper/ # MyBatis Mapper 接口 │ │ ├── entity/ # 实体类对应数据库表 │ │ ├── dto/ # 数据传输对象 │ │ └── config/ # 配置类如跨域、Swagger │ ├── src/main/resources/ │ │ ├── application.yml # 主配置文件 │ │ └── mapper/ # MyBatis XML 文件 │ └── pom.xml ├── frontend-admin/ # Vue 管理后台项目 │ ├── public/ │ ├── src/ │ │ ├── api/ # 封装后端接口请求 │ │ ├── views/ # 页面组件 │ │ ├── components/ # 公共组件 │ │ ├── router/ # 路由配置 │ │ └── store/ # Vuex 状态管理可选 │ └── package.json └── frontend-mp/ # uni-app 小程序项目 ├── pages/ # 小程序页面 ├── static/ # 静态资源 ├── components/ # 公共组件 ├── api/ # 封装后端接口请求 └── manifest.json # 小程序配置先把这个架子搭起来哪怕里面是空的。这能帮你理清思路知道代码该往哪里放。3. 从数据库到接口打通核心数据流环境好了接下来就是实现核心功能。我们以“发布一篇旅游分享”这个流程为例把后端到前端的链路跑通。3.1 数据库设计核心表不要设计得太复杂满足核心功能即可。-- 用户表 CREATE TABLE user ( id bigint(20) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 用户名可微信授权后获取, avatar varchar(500) DEFAULT NULL COMMENT 头像URL, openid varchar(100) DEFAULT NULL COMMENT 微信openid用于小程序登录, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; -- 景点标签表预置丽江景点数据 CREATE TABLE scenic_spot ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL COMMENT 景点名称如“玉龙雪山”, description text COMMENT 景点简介, location varchar(200) DEFAULT NULL COMMENT 大致位置, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT景点标签表; -- 旅游分享表核心 CREATE TABLE travel_note ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL COMMENT 发布用户ID, title varchar(200) NOT NULL COMMENT 分享标题, content text NOT NULL COMMENT 分享内容富文本或Markdown, cover_image varchar(500) DEFAULT NULL COMMENT 封面图URL, view_count int(11) DEFAULT 0 COMMENT 浏览量, like_count int(11) DEFAULT 0 COMMENT 点赞数, status tinyint(4) DEFAULT 1 COMMENT 状态0-审核中1-已发布2-已删除, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_create_time (create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT旅游分享表; -- 分享与景点关联表多对多 CREATE TABLE note_spot_relation ( id bigint(20) NOT NULL AUTO_INCREMENT, note_id bigint(20) NOT NULL, spot_id int(11) NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_note_spot (note_id,spot_id), KEY idx_spot_id (spot_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT分享与景点关联表; -- 评论表 CREATE TABLE comment ( id bigint(20) NOT NULL AUTO_INCREMENT, note_id bigint(20) NOT NULL COMMENT 所属分享ID, user_id bigint(20) NOT NULL COMMENT 评论用户ID, content varchar(1000) NOT NULL COMMENT 评论内容, parent_id bigint(20) DEFAULT 0 COMMENT 父评论ID0表示顶级评论, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_note_id (note_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT评论表;关键点user表的openid字段用于小程序微信登录这是小程序用户体系的基石。travel_note和scenic_spot通过note_spot_relation关联实现了分享可打多个景点标签的功能。所有表都加上create_time方便按时间排序和筛选。3.2 后端SpringBoot核心代码实现我们以实现“发布分享”和“获取分享列表”两个API为例。1. 实体类 (Entity)// TravelNote.java Data TableName(travel_note) // MyBatis-Plus 注解 public class TravelNote { TableId(type IdType.AUTO) private Long id; private Long userId; private String title; private String content; private String coverImage; private Integer viewCount; private Integer likeCount; private Integer status; private Date createTime; private Date updateTime; // 非数据库字段用于接收前端传递的景点ID列表 TableField(exist false) private ListInteger spotIds; }2. Mapper 接口// TravelNoteMapper.java Mapper public interface TravelNoteMapper extends BaseMapperTravelNote { // 分页查询分享列表并关联查询景点信息 ListTravelNoteVO selectNoteListWithSpots(PageTravelNoteVO page, Param(keyword) String keyword); }对应的 XML 文件需要编写联表查询的 SQL将travel_note、user、note_spot_relation、scenic_spot表连接起来返回一个包含用户信息、分享内容和景点标签列表的视图对象 (TravelNoteVO)。3. Service 层// TravelNoteService.java public interface TravelNoteService { // 发布分享需要处理景点标签关联 boolean publishNote(TravelNoteDTO noteDTO, Long userId); // 分页查询分享列表 PageResultTravelNoteVO getNoteList(Integer pageNum, Integer pageSize, String keyword); } // TravelNoteServiceImpl.java Service Transactional public class TravelNoteServiceImpl implements TravelNoteService { Autowired private TravelNoteMapper noteMapper; Autowired private NoteSpotRelationMapper relationMapper; Override public boolean publishNote(TravelNoteDTO noteDTO, Long userId) { // 1. 保存分享主表 TravelNote note new TravelNote(); BeanUtils.copyProperties(noteDTO, note); note.setUserId(userId); note.setStatus(1); // 已发布 int insertResult noteMapper.insert(note); if (insertResult 0) { return false; } // 2. 保存分享与景点的关联关系 if (noteDTO.getSpotIds() ! null !noteDTO.getSpotIds().isEmpty()) { ListNoteSpotRelation relations noteDTO.getSpotIds().stream() .map(spotId - new NoteSpotRelation(note.getId(), spotId)) .collect(Collectors.toList()); // 使用 MyBatis-Plus 的批量插入 relationMapper.insertBatchSomeColumn(relations); } return true; } }注意这里使用了Transactional注解确保保存主表和关联表是一个事务要么都成功要么都失败。4. Controller 层// TravelNoteController.java RestController RequestMapping(/api/note) public class TravelNoteController { Autowired private TravelNoteService noteService; PostMapping(/publish) public Result publish(RequestBody TravelNoteDTO noteDTO, HttpServletRequest request) { // 从请求中获取当前登录用户ID实际应从Token解析 Long userId getCurrentUserId(request); boolean success noteService.publishNote(noteDTO, userId); return success ? Result.success(发布成功) : Result.error(发布失败); } GetMapping(/list) public Result getList(RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 10) Integer pageSize, RequestParam(required false) String keyword) { PageResultTravelNoteVO pageResult noteService.getNoteList(pageNum, pageSize, keyword); return Result.success(pageResult); } }5. 配置文件 (application.yml)spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/lijiang_travel?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: your_password servlet: multipart: max-file-size: 10MB # 设置文件上传大小限制 max-request-size: 20MB mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开发时开启SQL日志 global-config: db-config: logic-delete-field: deleted # 全局逻辑删除字段如果用到 logic-delete-value: 1 logic-not-delete-value: 0 server: port: 80803.3 前端(Vue/uni-app)调用接口管理后台 (Vue Element UI) 在src/api/note.js中封装接口import request from /utils/request // 基于axios封装的请求工具 export function publishNote(data) { return request({ url: /api/note/publish, method: post, data }) } export function getNoteList(params) { return request({ url: /api/note/list, method: get, params }) }在页面组件中调用template el-form submit.native.preventhandlePublish el-form-item label标题 el-input v-modelform.title/el-input /el-form-item el-form-item label内容 el-input typetextarea v-modelform.content rows5/el-input /el-form-item el-form-item label关联景点 el-select v-modelform.spotIds multiple placeholder请选择 el-option v-forspot in spotList :keyspot.id :labelspot.name :valuespot.id/el-option /el-select /el-form-item el-button typeprimary native-typesubmit发布/el-button /el-form /template script import { publishNote } from /api/note export default { data() { return { form: { title: , content: , spotIds: [] } } }, methods: { async handlePublish() { try { await publishNote(this.form) this.$message.success(发布成功) // 跳转或刷新列表 } catch (error) { this.$message.error(发布失败) } } } } /script小程序端 (uni-app) 在frontend-mp/api/note.js中封装注意 uni-app 的网络请求 API 是uni.request。// 封装请求 const baseUrl http://localhost:8080 // 开发环境上线需改为HTTPS域名 export function publishNote(data) { return new Promise((resolve, reject) { uni.request({ url: baseUrl /api/note/publish, method: POST, header: { Content-Type: application/json, Authorization: uni.getStorageSync(token) // 携带登录token }, data, success: (res) resolve(res.data), fail: (err) reject(err) }) }) }在页面中调用与 Vue 类似但模板语法和组件略有不同。4. 关键功能实现与毕业设计亮点打造一个合格的毕业设计除了CRUD还需要一些“亮点”。对于旅游分享平台以下几个点是你可以深入挖掘的。4.1 微信小程序登录与用户绑定这是小程序项目的标配也是难点。小程序端调用wx.login()获取code。发送至后端将code发送到你的后端/api/auth/login接口。后端处理PostMapping(/login) public Result login(RequestParam String code) { // 1. 使用 code 调用微信接口获取 openid 和 session_key String url https://api.weixin.qq.com/sns/jscode2session?appid{appid}secret{secret}js_code{code}grant_typeauthorization_code; // 使用 RestTemplate 或 HttpClient 发送请求 WeixinSessionResponse response ... // 解析微信返回的JSON String openid response.getOpenid(); // 2. 根据 openid 查询本地用户表 User user userService.getUserByOpenid(openid); if (user null) { // 3. 新用户自动注册 user new User(); user.setOpenid(openid); // 可以再调用微信 getUserInfo 接口获取昵称头像需用户授权 userService.save(user); } // 4. 生成自定义 Token (如 JWT) 返回给小程序端 String token JwtUtil.generateToken(user.getId()); return Result.success(token); }后续请求小程序端将 Token 存储在Storage中并在每次请求的 Header 中携带。后端通过拦截器验证 Token 并获取当前用户ID。4.2 图片上传与存储旅游分享离不开图片。不要直接把图片存到数据库而是存路径。方案一简单使用 SpringBoot 的MultipartFile接收文件保存到服务器本地目录如uploads/然后将访问路径如http://your-domain/uploads/filename.jpg存入数据库。注意需要配置静态资源映射。方案二推荐更接近生产集成阿里云 OSS或腾讯云 COS等对象存储服务。后端生成一个预签名上传 URL 给前端前端直接上传到云存储上传成功后将云存储返回的文件 URL 传给后端保存。这能减轻你服务器的带宽和存储压力。小程序端使用uni.chooseImage选择图片uni.uploadFile进行上传。4.3 内容搜索与推荐加分项如果时间充裕可以做一个简单的搜索和推荐。搜索对travel_note表的title和content字段建立全文索引或者使用Elasticsearch实现更强大的搜索。对于毕业设计使用 MySQL 的LIKE语句或MATCH AGAINST全文检索也能满足演示需求。推荐最简单的推荐可以是“热门分享”按浏览量、点赞数排序、“最新分享”。再复杂一点可以基于用户浏览/点赞记录做简单的协同过滤“看了这个的人也看了…”但这需要更复杂的数据分析和算法量力而行。4.4 后台管理系统用 Vue Element UI 快速搭建一个后台至少包含用户管理查看、禁用用户。内容管理审核用户发布的分享status字段控制可进行编辑、删除、置顶等操作。景点标签管理对scenic_spot表进行增删改查。数据统计简单的图表展示每日新增用户数、分享数。可以使用 ECharts 实现。5. 部署、测试与答辩准备代码写完了怎么让它跑起来给别人看5.1 后端部署打包在 SpringBoot 项目根目录执行mvn clean package -DskipTests会在target目录生成xxx.jar文件。运行将jar包和application.yml修改数据库连接为线上地址上传到服务器。使用命令java -jar xxx.jar --spring.profiles.activeprod启动。建议使用nohup或systemd来守护进程。数据库将本地的 SQL 脚本在服务器 MySQL 上执行创建表结构和初始化数据如预置丽江景点。5.2 前端部署管理后台 (Vue)执行npm run build生成dist文件夹。将其中的静态文件部署到 Nginx 或 Apache 等 Web 服务器上。小程序端 (uni-app)在 HBuilderX 中点击“发行” - “小程序-微信”生成微信小程序代码包。然后使用微信开发者工具打开这个包上传代码提交微信审核毕业设计演示通常用体验版即可无需正式发布。5.3 常见问题排查清单在整合和部署过程中你大概率会遇到下面这些问题前后端跨域 (CORS) 问题浏览器控制台报错Access-Control-Allow-Origin。解决在后端 SpringBoot 中配置全局 CORS 过滤器或使用CrossOrigin注解。Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) // 生产环境应指定具体前端地址 .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowCredentials(true) .maxAge(3600); } }小程序网络请求失败检查小程序开发工具是否勾选“不校验合法域名”。上线前必须在微信小程序后台配置request 合法域名你的后端 API 地址必须是 HTTPS。数据库连接失败检查application.yml中的数据库 IP、端口、用户名、密码是否正确。服务器防火墙是否开放了 3306 端口。文件上传失败检查 SpringBoot 配置的max-file-size是否足够。检查上传目录的读写权限。如果使用云存储检查 AccessKey 和 SecretKey 配置。页面刷新 404 (Vue Router History 模式)在 Nginx 配置中将所有非静态文件请求重定向到index.html。location / { try_files $uri $uri/ /index.html; }5.4 毕业设计文档与答辩代码跑通只是第一步文档和答辩同样重要。毕业设计论文/报告结构要清晰。重点写系统分析与设计用例图、ER图、架构图、核心功能实现附上关键代码截图如 Controller、Service、SQL 语句、测试结果界面截图、功能测试表。不要只贴代码。答辩演示准备一个干净的演示环境提前在电脑上启动好后端、前端、数据库。最好录个屏作为备份。讲清楚业务流程从“用户微信登录小程序 - 浏览分享 - 发布一篇带图的丽江游记 - 后台管理员审核”这个主流程走一遍。突出技术难点和解决方案重点讲微信登录集成、图片上传方案、前后端分离架构、数据库设计多对多关系。这是体现你思考深度的地方。准备好问答老师常问“为什么选这个技术栈”SpringBoot 简化配置、Vue 生态好、uni-app 跨端、“用户密码怎么存的”小程序用微信登录无密码后台管理员密码需 MD5/SHA 加盐哈希、“如果用户量大了哪里会是瓶颈”数据库查询、图片服务器带宽可以提到后续可引入缓存、CDN、读写分离等方向。最后记住毕业设计的核心是演示一个完整、可运行、逻辑自洽的系统。不要追求大而全把“旅游分享”这个核心流程做扎实把代码结构写清晰把部署步骤理顺畅你的项目就已经成功了。源码只是参考理解每一步为什么这么做才是你真正学到的东西。 30款热门AI模型一站整合DeepSeek/GLM/Claude 随心用限时 5 折。 点击领海量免费额度