基于SpringBoot+mybatisplus+vueJS的钓鱼场管理系统的设计与实现-7000字论文

发布于:2025-06-12 ⋅ 阅读:(48) ⋅ 点赞:(0)

摘要

本文设计并实现了一个基于 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

  

七、其他案例: 

 

  

 


网站公告

今日签到

点亮在社区的每一天
去签到