
1. 项目背景与意义随着人们生活水平的提升和旅游消费观念的转变自由行逐渐成为主流出行方式。与跟团游相比自由行更强调个性化、灵活性和深度体验但同时也面临行程规划复杂、信息分散、攻略质量参差不齐等痛点。传统旅游平台多以标准化产品售卖为核心难以满足用户对真实、新鲜、个性化攻略内容的需求。本系统基于 Spring Boot 构建一个自由行攻略分享平台旨在解决以下问题信息聚合将分散在各社交平台、论坛的攻略内容集中管理提供结构化检索。经验共享鼓励旅行者发布真实攻略形成高质量内容社区。智能推荐基于标签和浏览行为为用户推荐匹配的攻略与目的地。互动交流支持评论、点赞、收藏增强用户参与感和内容活跃度。从实际意义来看该系统一方面帮助出行者降低信息搜集成本、提升行程规划效率另一方面为内容创作者提供展示平台也为旅游目的地和商家带来精准流量入口具有一定的社会价值和经济价值。2. 系统技术栈本系统采用前后端分离架构后端基于 Spring Boot 生态构建前端使用 Vue 框架数据库选用 MySQL缓存层使用 Redis。整体技术选型兼顾开发效率、运行稳定性和后期可维护性。层次技术选型说明后端框架Spring Boot 2.7快速构建 RESTful 服务自动装配简化配置持久层MyBatis-Plus简化 CRUD 操作内置分页与条件构造器数据库MySQL 8.0存储用户、攻略、评论、收藏等核心业务数据缓存Redis热点攻略缓存、验证码存储、点赞计数安全认证Spring Security JWT无状态登录认证与接口权限控制前端框架Vue 3 Element Plus组件化开发提供丰富的后台管理界面组件接口文档Knife4jSwagger自动生成在线接口文档便于前后端联调构建工具Maven依赖管理与项目构建3. 系统功能模块设计系统按用户角色划分为前台用户端和后台管理端两大模块具体功能结构如下3.1 用户端功能用户注册与登录支持邮箱注册、JWT 登录认证、个人信息维护。攻略浏览与搜索按目的地、标签、发布时间等条件筛选攻略支持关键词全文检索。攻略发布与编辑支持富文本编辑、图片上传、行程天数与预算标注。互动功能对攻略进行点赞、收藏、评论关注其他旅行者。个人中心管理自己发布的攻略、收藏列表、粉丝与关注。3.2 管理端功能用户管理查看用户列表、禁用违规账号、重置密码。攻略审核审核新发布的攻略支持通过、驳回与下架处理。标签与分类管理维护目的地、主题标签等基础数据。数据统计统计用户增长、攻略发布量、热门目的地排行。4. 数据库设计系统核心数据表包括用户表、攻略表、评论表、收藏表、点赞表和标签表。以下为主要表结构说明表名主要字段说明userid, username, password, email, avatar, role用户基本信息与角色strategyid, user_id, title, content, destination, days, budget, cover_image, status攻略主体内容与审核状态commentid, strategy_id, user_id, content, create_time攻略评论favoriteid, user_id, strategy_id, create_time用户收藏记录like_recordid, user_id, strategy_id, create_time点赞记录防止重复点赞tagid, name, type目的地或主题标签5. 核心代码实现本节选取系统中最具代表性的几个核心模块进行代码说明包括 JWT 登录认证、攻略发布接口、点赞功能以及基于 Redis 的缓存策略。5.1 JWT 登录认证系统采用 Spring Security 结合 JWT 实现无状态认证。用户登录成功后后端生成包含用户信息的 Token 返回给前端前端在后续请求中携带该 Token 访问受保护接口。Service public class UserServiceImpl implements UserService { Autowired private UserMapper userMapper; Autowired private StringRedisTemplate stringRedisTemplate; Override public String login(LoginDTO dto) { // 1. 根据用户名查询用户 User user userMapper.selectByUsername(dto.getUsername()); if (user null) { throw new BusinessException(用户名或密码错误); } // 2. 校验密码BCrypt 加密存储 if (!BCrypt.checkpw(dto.getPassword(), user.getPassword())) { throw new BusinessException(用户名或密码错误); } // 3. 生成 JWT Token String token JwtUtil.generateToken(user.getId(), user.getUsername(), user.getRole()); // 4. 将 Token 存入 Redis设置过期时间便于统一管理会话 stringRedisTemplate.opsForValue().set( login:token: user.getId(), token, 7, TimeUnit.DAYS ); return token; } }5.2 攻略发布接口攻略发布是系统的核心业务。用户提交攻略内容后系统保存攻略主体信息同时建立攻略与标签的关联关系并将攻略 ID 写入 Redis 待审核队列便于管理员审核。Service public class StrategyServiceImpl implements StrategyService { Autowired private StrategyMapper strategyMapper; Autowired private StrategyTagMapper strategyTagMapper; Override Transactional(rollbackFor Exception.class) public Long publish(StrategyPublishDTO dto, Long userId) { // 1. 保存攻略主体信息 Strategy strategy new Strategy(); strategy.setUserId(userId); strategy.setTitle(dto.getTitle()); strategy.setContent(dto.getContent()); strategy.setDestination(dto.getDestination()); strategy.setDays(dto.getDays()); strategy.setBudget(dto.getBudget()); strategy.setCoverImage(dto.getCoverImage()); strategy.setStatus(0); // 0 待审核 strategyMapper.insert(strategy); // 2. 保存攻略与标签的关联关系 if (dto.getTagIds() ! null !dto.getTagIds().isEmpty()) { for (Long tagId : dto.getTagIds()) { StrategyTag st new StrategyTag(); st.setStrategyId(strategy.getId()); st.setTagId(tagId); strategyTagMapper.insert(st); } } return strategy.getId(); } }5.3 点赞功能实现点赞功能采用 Redis 计数器加数据库持久化的双写策略。用户点赞时先更新 Redis 中的计数再异步写入点赞记录表既保证了接口响应速度又避免了数据库压力过大。Service public class LikeServiceImpl implements LikeService { Autowired private StringRedisTemplate stringRedisTemplate; Autowired private LikeRecordMapper likeRecordMapper; Override public boolean like(Long strategyId, Long userId) { String likeKey strategy:like: strategyId; String userKey strategy:like:user: strategyId : userId; // 1. 判断用户是否已点赞Redis Set 去重 Boolean isLiked stringRedisTemplate.opsForSet().isMember(userKey, userId.toString()); if (Boolean.TRUE.equals(isLiked)) { // 已点赞则取消 stringRedisTemplate.opsForSet().remove(userKey, userId.toString()); Long count stringRedisTemplate.opsForValue().decrement(likeKey); likeRecordMapper.deleteByStrategyIdAndUserId(strategyId, userId); return false; } else { // 未点赞则新增 stringRedisTemplate.opsForSet().add(userKey, userId.toString()); Long count stringRedisTemplate.opsForValue().increment(likeKey); LikeRecord record new LikeRecord(); record.setStrategyId(strategyId); record.setUserId(userId); likeRecordMapper.insert(record); return true; } } }5.4 基于 Redis 的攻略缓存对于访问量高的热门攻略系统采用 Redis 缓存策略减少数据库查询压力。查询攻略详情时优先读取缓存缓存未命中再查询数据库并回填缓存。Service public class StrategyQueryServiceImpl implements StrategyQueryService { Autowired private StringRedisTemplate stringRedisTemplate; Autowired private StrategyMapper strategyMapper; Autowired private ObjectMapper objectMapper; Override public StrategyVO getStrategyDetail(Long id) { String cacheKey strategy:detail: id; // 1. 优先从缓存读取 String cached stringRedisTemplate.opsForValue().get(cacheKey); if (cached ! null) { try { return objectMapper.readValue(cached, StrategyVO.class); } catch (Exception e) { // 缓存解析失败则回源数据库 } } // 2. 缓存未命中查询数据库 Strategy strategy strategyMapper.selectById(id); if (strategy null) { throw new BusinessException(攻略不存在); } StrategyVO vo new StrategyVO(); vo.setId(strategy.getId()); vo.setTitle(strategy.getTitle()); vo.setDestination(strategy.getDestination()); vo.setContent(strategy.getContent()); // 3. 回填缓存设置过期时间 30 分钟 try { stringRedisTemplate.opsForValue().set( cacheKey, objectMapper.writeValueAsString(vo), 30, TimeUnit.MINUTES ); } catch (Exception e) { // 缓存写入失败不影响主流程 } return vo; } }6. 系统测试与总结系统开发完成后对用户注册登录、攻略发布、点赞收藏、评论互动、后台审核等核心功能进行了功能测试和接口压力测试。测试结果表明各模块功能运行正常接口响应时间满足预期Redis 缓存策略有效降低了数据库负载。本系统基于 Spring Boot 实现了自由行攻略分享平台的核心功能具备用户管理、攻略发布、互动交流和后台审核等完整业务闭环。后续可从以下方向继续优化引入 Elasticsearch 实现更高效的全文检索与攻略推荐。增加基于用户行为的个性化推荐算法提升内容分发效率。接入地图 API实现行程路线可视化展示。完善消息通知机制支持评论回复提醒和关注动态推送。