项目背景
本项目旨在为旅游景区打造轻量化服务平台,解决游客信息获取滞后、入园排队拥挤、服务预约不便等痛点,同时提升景区运营效率,实现线上线下服务闭环。
核心功能模块
- 栏目浏览:景区资讯、游玩攻略、景区介绍、服务指南(支持搜索、分享、详情查看)。
- 用户注册/登录:微信一键登录,绑定个人信息(姓名、年龄、兴趣)。
- 服务预约:入园预约、讲解服务预约、停车预约(时段选择、名额显示)。
- 个人中心:我的预约(核销码展示、取消预约)、资料修改、浏览历史、我的收藏。
数据库设计 (Database Design)
概念模型
- 用户 (User) 与 预约记录 (Reservation):1对多关系(一个用户可有多条预约)。
- 用户 (User) 与 收藏 (Favorite):1对多关系。
- 管理员 (Admin) 与 栏目内容 (Content):1对多关系(管理员发布内容)。
- 预约项目 (Project) 与 预约记录 (Reservation):1对多关系。
- 预约项目 (Project) 与 时段规则 (TimeSlot):1对多关系。
| 字段名 | 类型 | 长度 | 说明 | 主键 |
|---|---|---|---|---|
| id | BIGINT | 20 | 内容ID | YES |
| category | VARCHAR | 20 | 分类(资讯/攻略/介绍/指南) | NO |
| title | VARCHAR | 100 | 标题 | NO |
| content | TEXT | - | 正文(支持HTML/富文本) | NO |
| cover_image | VARCHAR | 255 | 封面图URL | NO |
| view_count | INT | 11 | 浏览次数 | NO |
| publish_time | DATETIME | - | 发布时间 | NO |
| 字段名 | 类型 | 长度 | 说明 | 主键 |
|---|---|---|---|---|
| id | BIGINT | 20 | 记录ID | YES |
| user_id | BIGINT | 20 | 关联用户ID | NO |
| project_id | BIGINT | 20 | 关联项目ID | NO |
| reserve_date | DATE | - | 预约日期 | NO |
| time_slot | VARCHAR | 20 | 预约时段(上午/下午) | NO |
| verify_code | VARCHAR | 64 | 核销二维码内容 | NO |
| status | TINYINT | 1 | 状态(0待核销/1已核销/2已取消) | NO |
| create_time | DATETIME | - | 下单时间 | NO |
| 字段名 | 类型 | 长度 | 说明 | 主键 |
|---|---|---|---|---|
| id | BIGINT | 20 | 管理员ID | YES |
| username | VARCHAR | 50 | 账号 | NO |
| password | VARCHAR | 100 | 密码(加密) | NO |
| role | VARCHAR | 20 | 角色(admin/verifier) | NO |
| status | TINYINT | 1 | 启用状态 | NO |
核心代码片段
@RestController
@RequestMapping("/api/reservation")
public class ReservationController {
@Autowired
private ReservationService reservationService;
/**
* 创建预约
*/
@PostMapping("/create")
public Result createReservation(@RequestBody ReservationDTO dto, @RequestHeader("X-User-Id") Long userId) {
// 校验库存和时段逻辑
boolean success = reservationService.createReservation(userId, dto);
if (success) {
return Result.success("预约成功,请前往个人中心查看核销码");
} else {
return Result.error("该时段名额已满或参数错误");
}
}
/**
* 扫码核销
*/
@PostMapping("/verify")
public Result verifyTicket(@RequestParam String code, @RequestHeader("X-Admin-Id") Long adminId) {
// 仅核销员角色可调用
String msg = reservationService.verifyCode(code, adminId);
if ("SUCCESS".equals(msg)) {
return Result.success("核销成功");
}
return Result.error(msg);
}
}
@Service
public class ReservationServiceImpl implements ReservationService {
@Override
@Transactional
public boolean createReservation(Long userId, ReservationDTO dto) {
// 1. 检查该时段剩余名额 (需查询 res_project 和当前已预约数量)
int count = reservationMapper.countBySlot(dto.getProjectId(), dto.getDate(), dto.getTimeSlot());
if (count >= dto.getMaxCapacity()) {
return false;
}
// 2. 生成核销码 (UUID或特定规则)
String verifyCode = UUID.randomUUID().toString();
// 3. 插入数据库
Reservation record = new Reservation();
record.setUserId(userId);
record.setProjectId(dto.getProjectId());
record.setReserveDate(dto.getDate());
record.setTimeSlot(dto.getTimeSlot());
record.setVerifyCode(verifyCode);
record.setStatus(0); // 待核销
reservationMapper.insert(record);
return true;
}
}
UI设计
后台管理系统设计