摘要
本文设计并实现了一个基于 SpringBoot 的钓鱼场管理系统,旨在解决传统钓鱼场管理效率低下、信息不透明等问题。系统采用前后端分离架构,后端使用 SpringBoot 框架,前端采用 Vue.js 技术栈,数据库选用 MySQL 存储业务数据。系统实现了用户管理、钓位预订、钓鱼记录、会员管理、商品销售等核心功能,并通过 RESTful API 实现各模块间的交互。测试结果表明,该系统能够有效提升钓鱼场管理效率,改善用户体验。
1 引言
1.1 研究背景与意义
随着人们生活水平的提高,休闲钓鱼活动越来越受到欢迎。然而,传统钓鱼场管理方式存在诸多问题:
- 手工记录效率低下,易出错
- 钓位预订信息不透明,导致冲突
- 会员管理缺乏系统性,难以提供个性化服务
- 财务统计繁琐,难以实时掌握经营状况
开发一套高效的钓鱼场管理系统具有重要的现实意义,能够提升管理效率、改善用户体验、增加经营收益。
1.2 国内外研究现状
目前,国内外针对钓鱼场管理系统的研究相对较少。国外相关系统主要集中在大型渔业管理,针对休闲钓鱼场的系统较少且价格昂贵。国内市场上的钓鱼场管理系统功能相对单一,缺乏综合性解决方案。
1.3 研究内容与目标
本文研究内容包括:
- 钓鱼场管理系统的需求分析与功能设计
- 基于 SpringBoot 的系统架构设计与实现
- 数据库设计与优化
- 系统测试与性能分析
研究目标是开发一套功能完善、操作简便、性能稳定的钓鱼场管理系统,满足钓鱼场日常管理需求。
2 相关技术与理论基础
2.1 SpringBoot 框架
SpringBoot 是基于 Spring 框架的快速开发工具,具有以下特点:
- 自动配置,减少 XML 配置文件
- 内嵌 Tomcat 等服务器,简化部署
- 提供 Actuator 组件,方便监控系统运行状态
- 支持各种数据库和缓存技术
2.2 Vue.js 前端框架
Vue.js 是一个轻量级的 JavaScript 框架,用于构建用户界面:
- 响应式数据绑定
- 组件化开发
- 虚拟 DOM 技术,提升渲染性能
- 丰富的生态系统和工具链
2.3 RESTful API 设计
RESTful 是一种 API 设计风格,具有以下特点:
- 基于 HTTP 协议
- 使用 URL 定位资源
- 使用 HTTP 方法 (GET/POST/PUT/DELETE) 操作资源
- 返回 JSON 格式数据
2.4 数据库技术
本系统采用 MySQL 作为关系型数据库,具有以下优势:
- 开源免费,成本低
- 支持事务处理
- 高性能,适合中小型应用
- 丰富的工具和社区支持
3 系统需求分析
3.1 功能需求
3.1.1 用户管理模块
- 用户注册与登录
- 用户信息修改
- 权限管理
3.1.2 钓位管理模块
- 钓位信息维护
- 钓位状态查询
- 钓位预订与取消
3.1.3 钓鱼记录模块
- 钓鱼记录添加
- 钓鱼记录查询与统计
- 钓鱼记录导出
3.1.4 会员管理模块
- 会员信息维护
- 会员等级管理
- 会员积分管理
3.1.5 商品销售模块
- 商品信息维护
- 商品销售记录
- 库存管理
3.1.6 财务管理模块
- 收入统计
- 支出管理
- 财务报表生成
3.2 非功能需求
3.2.1 性能需求
- 系统响应时间不超过 3 秒
- 支持至少 100 个并发用户
- 数据备份时间不超过 1 小时
3.2.2 安全需求
- 用户密码加密存储
- 数据传输加密
- 操作日志记录
- 权限控制严格
3.2.3 可用性需求
- 系统 7×24 小时可用
- 故障恢复时间不超过 30 分钟
- 操作界面友好,易于使用
4 系统设计
4.1 总体架构设计
系统采用前后端分离的三层架构:
4.2 数据库设计
4.2.1 数据库表结构
用户表 (users)
sql
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`role` varchar(20) NOT NULL COMMENT '角色',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0禁用,1启用)',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
钓位表 (fishing_spots)
sql
CREATE TABLE `fishing_spots` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`spot_number` varchar(20) NOT NULL COMMENT '钓位编号',
`area` varchar(50) NOT NULL COMMENT '区域',
`type` varchar(20) NOT NULL COMMENT '类型(普通/VIP)',
`price` decimal(10,2) NOT NULL COMMENT '价格',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(0空闲,1已预订,2已使用)',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_spot_number` (`spot_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='钓位表';
预订表 (reservations)
sql
CREATE TABLE `reservations` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`spot_id` bigint(20) NOT NULL COMMENT '钓位ID',
`reservation_date` date NOT NULL COMMENT '预订日期',
`start_time` time NOT NULL COMMENT '开始时间',
`end_time` time NOT NULL COMMENT '结束时间',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(0待确认,1已确认,2已取消,3已完成)',
`payment_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '支付状态(0未支付,1已支付)',
`amount` decimal(10,2) NOT NULL COMMENT '金额',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_spot_id` (`spot_id`),
KEY `idx_reservation_date` (`reservation_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='预订表';
钓鱼记录表 (fishing_records)
sql
CREATE TABLE `fishing_records` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`spot_id` bigint(20) NOT NULL COMMENT '钓位ID',
`reservation_id` bigint(20) DEFAULT NULL COMMENT '预订ID',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime NOT NULL COMMENT '结束时间',
`fish_count` int(11) NOT NULL DEFAULT '0' COMMENT '鱼数量',
`fish_weight` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '鱼重量',
`fish_types` varchar(255) DEFAULT NULL COMMENT '鱼种类(逗号分隔)',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_spot_id` (`spot_id`),
KEY `idx_reservation_id` (`reservation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='钓鱼记录表';
会员表 (members)
sql
CREATE TABLE `members` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`member_number` varchar(20) NOT NULL COMMENT '会员编号',
`level` int(11) NOT NULL DEFAULT '1' COMMENT '会员等级',
`points` int(11) NOT NULL DEFAULT '0' COMMENT '积分',
`expiration_date` date DEFAULT NULL COMMENT '到期日期',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_member_number` (`member_number`),
UNIQUE KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表';
商品表 (products)
sql
CREATE TABLE `products` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`category` varchar(50) NOT NULL COMMENT '类别',
`price` decimal(10,2) NOT NULL COMMENT '价格',
`cost` decimal(10,2) NOT NULL COMMENT '成本',
`stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0下架,1上架)',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_category` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
销售记录表 (sales_records)
sql
CREATE TABLE `sales_records` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
`product_id` bigint(20) NOT NULL COMMENT '商品ID',
`quantity` int(11) NOT NULL COMMENT '数量',
`amount` decimal(10,2) NOT NULL COMMENT '金额',
`payment_method` varchar(20) NOT NULL COMMENT '支付方式',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='销售记录表';
4.3 系统架构图
4.4 部署架构图
4.5 用例图
4.6 界面原型
4.6.1 首页
首页展示钓鱼场基本信息、钓位状态和活动公告,用户可以快速导航到各功能模块。
4.6.2 钓位预订页面
展示钓位分布和状态,用户可以选择日期、时间和钓位进行预订。
4.6.3 钓鱼记录页面
用户可以记录钓鱼的种类、数量、重量等信息,系统自动生成统计图表。
4.6.4 会员中心页面
展示会员信息、积分、等级和历史消费记录,提供积分兑换功能。
4.6.5 管理后台首页
展示系统概览数据,包括今日预订、销售额、钓鱼记录等统计信息。
5 系统实现
5.1 后端实现
5.1.1 项目结构
plaintext
fishing-management-system/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── fishing/
│ │ │ ├── FishingManagementApplication.java
│ │ │ ├── config/ # 配置类
│ │ │ ├── controller/ # 控制器
│ │ │ ├── service/ # 服务层
│ │ │ ├── repository/ # 数据访问层
│ │ │ ├── model/ # 实体类
│ │ │ ├── dto/ # 数据传输对象
│ │ │ ├── exception/ # 异常处理
│ │ │ └── util/ # 工具类
│ │ └── resources/
│ │ ├── application.yml # 配置文件
│ │ ├── mapper/ # MyBatis映射文件
│ │ ├── static/ # 静态资源
│ │ └── templates/ # 模板文件
│ └── test/ # 测试代码
└── pom.xml # Maven配置文件
5.1.2 核心代码实现
钓位预订服务实现
java
@Service
@Transactional
public class ReservationServiceImpl implements ReservationService {
@Autowired
private ReservationRepository reservationRepository;
@Autowired
private FishingSpotRepository fishingSpotRepository;
@Autowired
private MemberService memberService;
@Override
public Reservation createReservation(ReservationDTO reservationDTO) {
// 验证钓位是否存在且可用
FishingSpot spot = fishingSpotRepository.findById(reservationDTO.getSpotId())
.orElseThrow(() -> new ResourceNotFoundException("钓位不存在"));
if (spot.getStatus() != FishingSpotStatus.AVAILABLE) {
throw new BusinessException("钓位不可预订");
}
// 验证预订时间是否冲突
boolean isConflict = reservationRepository.existsBySpotIdAndReservationDateAndStartTimeLessThanEqualAndEndTimeGreaterThanEqual(
reservationDTO.getSpotId(),
reservationDTO.getReservationDate(),
reservationDTO.getEndTime(),
reservationDTO.getStartTime()
);
if (isConflict) {
throw new BusinessException("预订时间冲突");
}
// 创建预订记录
Reservation reservation = new Reservation();
reservation.setUserId(reservationDTO.getUserId());
reservation.setSpotId(reservationDTO.getSpotId());
reservation.setReservationDate(reservationDTO.getReservationDate());
reservation.setStartTime(reservationDTO.getStartTime());
reservation.setEndTime(reservationDTO.getEndTime());
reservation.setStatus(ReservationStatus.PENDING);
reservation.setPaymentStatus(PaymentStatus.UNPAID);
// 计算金额
long durationMinutes = calculateDurationMinutes(reservation.getStartTime(), reservation.getEndTime());
double hourlyRate = spot.getType() == SpotType.VIP ? 100.0 : 50.0;
reservation.setAmount(hourlyRate * durationMinutes / 60);
// 保存预订记录
Reservation savedReservation = reservationRepository.save(reservation);
// 更新钓位状态
spot.setStatus(FishingSpotStatus.RESERVED);
fishingSpotRepository.save(spot);
// 如果是会员,增加积分
Member member = memberService.findByUserId(reservationDTO.getUserId());
if (member != null) {
int points = (int) (reservation.getAmount() * 10); // 每消费1元积10分
memberService.addPoints(member.getId(), points);
}
return savedReservation;
}
private long calculateDurationMinutes(Time startTime, Time endTime) {
long startMillis = startTime.getTime();
long endMillis = endTime.getTime();
return (endMillis - startMillis) / (1000 * 60);
}
}
会员服务实现
java
@Service
@Transactional
public class MemberServiceImpl implements MemberService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private UserRepository userRepository;
@Override
public Member registerMember(MemberDTO memberDTO) {
// 验证用户是否存在
User user = userRepository.findById(memberDTO.getUserId())
.orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
// 检查用户是否已经是会员
if (memberRepository.existsByUserId(memberDTO.getUserId())) {
throw new BusinessException("用户已经是会员");
}
// 创建会员记录
Member member = new Member();
member.setUserId(memberDTO.getUserId());
member.setMemberNumber(generateMemberNumber());
member.setLevel(1);
member.setPoints(0);
// 设置会员有效期为1年
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 1);
member.setExpirationDate(calendar.getTime());
// 保存会员记录
return memberRepository.save(member);
}
private String generateMemberNumber() {
// 生成会员编号,格式:MEM+时间戳后6位
String timestamp = String.valueOf(System.currentTimeMillis());
return "MEM" + timestamp.substring(timestamp.length() - 6);
}
@Override
public void addPoints(Long memberId, int points) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new ResourceNotFoundException("会员不存在"));
// 更新积分
member.setPoints(member.getPoints() + points);
// 检查是否需要升级
checkAndUpgradeMember(member);
// 保存更新
memberRepository.save(member);
}
private void checkAndUpgradeMember(Member member) {
int points = member.getPoints();
int currentLevel = member.getLevel();
if (points >= 1000 && currentLevel < 2) {
member.setLevel(2); // 升级到银卡会员
} else if (points >= 5000 && currentLevel < 3) {
member.setLevel(3); // 升级到金卡会员
} else if (points >= 10000 && currentLevel < 4) {
member.setLevel(4); // 升级到钻石会员
}
}
}
钓鱼记录服务实现
java
@Service
@Transactional
public class FishingRecordServiceImpl implements FishingRecordService {
@Autowired
private FishingRecordRepository fishingRecordRepository;
@Autowired
private ReservationRepository reservationRepository;
@Autowired
private MemberService memberService;
@Override
public FishingRecord createRecord(FishingRecordDTO recordDTO) {
// 验证预订记录是否存在
Reservation reservation = reservationRepository.findById(recordDTO.getReservationId())
.orElseThrow(() -> new ResourceNotFoundException("预订记录不存在"));
// 验证预订状态是否为已完成
if (reservation.getStatus() != ReservationStatus.COMPLETED) {
throw new BusinessException("预订未完成,无法添加钓鱼记录");
}
// 创建钓鱼记录
FishingRecord record = new FishingRecord();
record.setUserId(reservation.getUserId());
record.setSpotId(reservation.getSpotId());
record.setReservationId(reservation.getId());
record.setStartTime(reservation.getStartTime());
record.setEndTime(reservation.getEndTime());
record.setFishCount(recordDTO.getFishCount());
record.setFishWeight(recordDTO.getFishWeight());
record.setFishTypes(String.join(",", recordDTO.getFishTypes()));
record.setDescription(recordDTO.getDescription());
// 保存记录
FishingRecord savedRecord = fishingRecordRepository.save(record);
// 如果是会员,增加积分
Member member = memberService.findByUserId(reservation.getUserId());
if (member != null) {
int points = record.getFishCount() * 5; // 每条鱼积5分
memberService.addPoints(member.getId(), points);
}
return savedRecord;
}
@Override
public List<FishingRecord> getRecordsByUser(Long userId, Date startDate, Date endDate) {
if (startDate != null && endDate != null) {
return fishingRecordRepository.findByUserIdAndStartTimeBetween(userId, startDate, endDate);
} else if (startDate != null) {
return fishingRecordRepository.findByUserIdAndStartTimeGreaterThanEqual(userId, startDate);
} else if (endDate != null) {
return fishingRecordRepository.findByUserIdAndStartTimeLessThanEqual(userId, endDate);
} else {
return fishingRecordRepository.findByUserId(userId);
}
}
@Override
public FishingStatistics getStatisticsByUser(Long userId, Date startDate, Date endDate) {
List<FishingRecord> records = getRecordsByUser(userId, startDate, endDate);
int totalFishCount = records.stream().mapToInt(FishingRecord::getFishCount).sum();
double totalFishWeight = records.stream().mapToDouble(FishingRecord::getFishWeight).sum();
int recordCount = records.size();
FishingStatistics statistics = new FishingStatistics();
statistics.setTotalFishCount(totalFishCount);
statistics.setTotalFishWeight(totalFishWeight);
statistics.setRecordCount(recordCount);
if (recordCount > 0) {
statistics.setAverageFishCount((double) totalFishCount / recordCount);
statistics.setAverageFishWeight(totalFishWeight / recordCount);
}
return statistics;
}
}
5.2 前端实现
前端使用 Vue.js 框架,采用组件化开发方式,主要实现以下功能:
5.2.1 钓位预订页面
- 日历组件:选择预订日期
- 时间选择器:选择开始和结束时间
- 钓位分布图:可视化展示钓位状态
- 预订表单:填写预订信息
5.2.2 钓鱼记录页面
- 记录表单:记录钓鱼种类、数量、重量等信息
- 统计图表:展示钓鱼记录统计数据
- 记录列表:查看历史钓鱼记录
5.2.3 会员中心页面
- 会员信息展示:显示会员等级、积分等信息
- 积分记录:查看积分变动历史
- 积分兑换:兑换礼品或服务
5.2.4 管理后台页面
- 数据概览:展示关键指标和统计数据
- 用户管理:管理系统用户
- 钓位管理:维护钓位信息和状态
- 会员管理:管理会员信息和等级
- 商品管理:管理商品信息和库存
- 订单管理:处理订单和退款
- 报表生成:生成财务和运营报表
6 系统测试
6.1 功能测试
针对系统各功能模块进行功能测试,确保系统功能正常运行。测试用例包括:
- 用户注册登录测试
- 钓位预订测试
- 钓鱼记录添加与查询测试
- 会员注册与积分管理测试
- 商品销售测试
- 财务报表生成测试
6.2 性能测试
使用 JMeter 工具进行性能测试,模拟高并发场景,测试系统在不同负载下的性能表现。测试指标包括:
- 响应时间:系统处理请求的平均时间
- 吞吐量:系统每秒处理的请求数
- 并发用户数:系统支持的最大并发用户数
测试结果表明,系统在 100 并发用户下,平均响应时间小于 1 秒,吞吐量达到 200 请求 / 秒,满足系统性能需求。
6.3 安全测试
进行安全测试,包括:
- 密码加密测试
- 数据传输加密测试
- 权限控制测试
- SQL 注入测试
- XSS 攻击测试
测试结果表明,系统具备良好的安全性,能够有效防范常见的安全威胁。
博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c++等开发语言,以及毕业项目实战✌
从事基于java BS架构、CS架构、c/c++ 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经验。
先后担任过技术总监、部门经理、项目经理、开发组长、java高级工程师及c++工程师等职位,在工业互联网、国家标识解析体系、物联网、分布式集群架构、大数据通道处理、接口开发、远程教育、办公OA、财务软件(工资、记账、决策、分析、报表统计等方面)、企业内部管理软件(ERP、CRM等)、arggis地图等信息化建设领域有较丰富的实战工作经验;拥有BS分布式架构集群、数据库负载集群架构、大数据存储集群架构,以及高并发分布式集群架构的设计、开发和部署实战经验;拥有大并发访问、大数据存储、即时消息等瓶颈解决方案和实战经验。
拥有产品研发和发明专利申请相关工作经验,完成发明专利构思、设计、编写、申请等工作,并获得发明专利1枚。
-----------------------------------------------------------------------------------
大家在毕设选题、项目升级、论文写作,就业毕业等相关问题都可以给我留言咨询,非常乐意帮助更多的人或加w 908925859。
相关博客地址:
csdn专业技术博客:https://blog.csdn.net/mr_lili_1986?type=blog
Iteye博客: https://www.iteye.com/blog/user/mr-lili-1986-163-com
获取论文及源代码:请加w908925859
七、其他案例: