基于Vue与SpringBoot的植物种植管理平台 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQLSpringboot框架使用Vue
2026-02-101 浏览

文章摘要

植物种植管理平台是一个面向现代农业种植者与园艺爱好者的综合性管理系统,旨在解决传统种植过程中数据记录零散、管理效率低下、生长周期难以追溯的核心痛点。该系统通过数字化手段整合植物从选种、育苗到成熟的全生命周期数据,帮助用户实现精准化、科学化的种植管理,有效提升作物产量与品质,降低因管理不当导致的资源浪...

在现代农业数字化转型的浪潮中,传统种植管理方式面临着数据分散、效率低下、追溯困难等核心挑战。针对这一行业痛点,我们设计并实现了一套智能植物种植管理平台,通过前后端分离架构和模块化设计,为种植者提供全生命周期的数字化管理解决方案。

系统架构与技术栈

平台采用典型的前后端分离架构,前端基于Vue.js框架构建用户界面,后端使用SpringBoot提供RESTful API服务。这种架构模式实现了关注点分离,提高了系统的可维护性和扩展性。

前端技术栈采用Vue 3.0组合式API,配合Vue Router实现路由管理,Axios处理HTTP请求。UI组件库选用Element Plus,为系统提供了统一的设计语言和交互体验。前端工程使用Webpack进行模块打包,支持热重载开发模式。

// 前端API请求封装示例
import axios from 'axios'
import { ElMessage } from 'element-plus'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 10000
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token')
    if (token) {
      config.headers['Authorization'] = 'Bearer ' + token
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code !== 200) {
      ElMessage.error(res.message || '请求失败')
      return Promise.reject(new Error(res.message || 'Error'))
    }
    return res
  },
  error => {
    ElMessage.error(error.message || '网络异常')
    return Promise.reject(error)
  }
)

export default service

后端技术栈基于SpringBoot 2.7.x,数据持久层使用MyBatis-Plus增强MyBatis功能,数据库连接池采用HikariCP。安全认证使用Spring Security配合JWT令牌机制。配置文件采用YAML格式,支持多环境配置。

# application.yml 核心配置
spring:
  datasource:
    url: jdbc:mysql://www.csbishe.cn:3306/vue_zhongzhisys?useSSL=false&serverTimezone=Asia/Shanghai
    username: vue_zhongzhisys
    password: vue_zhongzhisys
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      
  redis:
    host: www.csbishe.cn
    port: 6379
    password: 1234
    database: 0
    
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB

server:
  port: 8080
  servlet:
    context-path: /vue_zhongzhisys

mybatis-plus:
  global-config:
    db-config:
      table-prefix: t_
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

数据库设计亮点

数据库设计采用关系型数据库MySQL,通过合理的表结构设计和索引优化,确保系统数据的一致性和查询性能。

权限管理模块设计

用户角色权限模型采用经典的三表结构:用户表、角色表、用户角色关联表。这种设计支持灵活的权限分配和角色管理。

-- 角色管理表
CREATE TABLE `t_role` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(50) DEFAULT NULL COMMENT '角色名称',
  `role_desc` varchar(100) DEFAULT NULL COMMENT '角色描述',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='角色管理'

-- 用户角色关联表
CREATE TABLE `t_user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL COMMENT '用户ID',
  `role_id` int(11) DEFAULT NULL COMMENT '角色ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户角色关联表'

设计亮点

  • 使用自增主键提高插入性能
  • 角色名称字段长度限制为50字符,避免数据冗余
  • 关联表使用复合索引优化多表连接查询
  • 字符集采用utf8mb4支持全字符集存储

水果种植管理模块设计

水果管理涉及多个实体间的复杂关系,通过外键约束确保数据完整性。

CREATE TABLE `t_fruittype` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL COMMENT '类型',
  `bz` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='水果类型管理'

CREATE TABLE `t_fruit` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '水果名称',
  `dksize` varchar(255) DEFAULT NULL COMMENT '地块大小',
  `fzr` varchar(255) DEFAULT NULL COMMENT '负责人姓名',
  `tel` varchar(255) DEFAULT NULL COMMENT '负责人电话',
  `count` double DEFAULT NULL COMMENT '水果存量(kg)',
  `info` varchar(255) DEFAULT NULL COMMENT '简介',
  `fruitType_id` int(11) DEFAULT NULL COMMENT '水果类型',
  `location_id` int(11) DEFAULT NULL COMMENT '种植地块',
  PRIMARY KEY (`id`),
  KEY `FK3234328439908808766` (`fruitType_id`),
  KEY `FK8261771316999636604` (`location_id`),
  CONSTRAINT `FK3234328439908808766` FOREIGN KEY (`fruitType_id`) REFERENCES `t_fruittype` (`id`),
  CONSTRAINT `FK8261771316999636604` FOREIGN KEY (`location_id`) REFERENCES `t_location` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='水果管理'

设计优化点

  • 使用double类型存储存量数据,支持小数精度
  • 建立外键索引优化关联查询性能
  • 电话号码字段采用varchar类型,支持格式灵活性
  • 通过外键约束确保类型和地块数据的引用完整性

水果类型管理

核心功能实现

肥料采购管理模块

肥料采购模块实现了从采购计划到入库管理的完整业务流程。前端采用表格和表单结合的方式展示数据,支持条件查询和分页显示。

@RestController
@RequestMapping("/feiBuy")
public class FeiBuyController {

    @Resource
    FeiBuyService feiBuyService;

    @RequestMapping("/list")
    public Result list(FeiBuy feiBuy,
    @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
    @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        // 创建分页对象
        Page<FeiBuy> pagination = new Page<>(pageNo, pageSize);
        MPJLambdaWrapper<FeiBuy> wrapper = new MPJLambdaWrapper<FeiBuy>()
            .selectAll(FeiBuy.class)
            .selectAssociation(Fei.class, FeiBuy::getFei)
            .leftJoin(Fei.class,Fei::getId, FeiBuy::getFeiId)
            .like(!StringUtils.isBlank(feiBuy.getFei()==null?"":feiBuy.getFei().getName()),
                Fei::getName,feiBuy.getFei()==null?"":feiBuy.getFei().getName())
            .like(!StringUtils.isBlank(feiBuy.getCode()),FeiBuy::getCode,  feiBuy.getCode())
            .like(!StringUtils.isBlank(feiBuy.getStime()),FeiBuy::getStime,  feiBuy.getStime())
            .like(!StringUtils.isBlank(feiBuy.getFcount()),FeiBuy::getFcount,  feiBuy.getFcount())
            .like(!StringUtils.isBlank(feiBuy.getPrice()),FeiBuy::getPrice,  feiBuy.getPrice())
            .like(!StringUtils.isBlank(feiBuy.getTotal()),FeiBuy::getTotal,  feiBuy.getTotal())
            .like(!StringUtils.isBlank(feiBuy.getBz()),FeiBuy::getBz,  feiBuy.getBz());
        Page<FeiBuy> pdatas = feiBuyService.selectJoinListPage(pagination,FeiBuy.class, wrapper);
        return Result.success(pdatas);
    }

    @RequestMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id){
        feiBuyService.removeById(id);
        return list(new FeiBuy(),1,10);
    }

    @RequestMapping("/get/{id}")
    public Result get(@PathVariable Integer id){
        MPJLambdaWrapper<FeiBuy> wrapper = new MPJLambdaWrapper<FeiBuy>()
        .selectAll(FeiBuy.class)
        .selectAssociation(Fei.class, FeiBuy::getFei)
        .leftJoin(Fei.class,Fei::getId, FeiBuy::getFeiId)
        .eq(FeiBuy::getId,id);
        FeiBuy feiBuy = feiBuyService.selectJoinOne(FeiBuy.class,wrapper);
        if(feiBuy == null){
            return Result.failure(ResultCode.DATA_NOT_EXIST);
        }
        return Result.success(feiBuy);
    }
}

技术实现亮点

  • 使用MyBatis-Plus的MPJLambdaWrapper实现类型安全的联表查询
  • 支持动态条件查询,提高查询灵活性
  • 分页查询优化大数据量下的性能表现
  • 统一的Result对象封装响应数据

肥料采购管理

角色权限管理模块

系统采用基于角色的访问控制模型,实现精细化的权限管理。前端通过Vue的动态路由和组件权限控制实现界面级权限管理。

// 权限拦截器实现
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    
    @Autowired
    private UserDetailsService userDetailsService;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                  HttpServletResponse response, 
                                  FilterChain chain) throws ServletException, IOException {
        
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String authToken = authHeader.substring(7);
            try {
                String username = JwtUtil.getUsernameFromToken(authToken);
                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                    if (JwtUtil.validateToken(authToken, userDetails)) {
                        UsernamePasswordAuthenticationToken authentication = 
                            new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                }
            } catch (Exception e) {
                logger.error("JWT令牌验证失败", e);
            }
        }
        chain.doFilter(request, response);
    }
}

权限控制特性

  • JWT无状态认证,支持分布式部署
  • 基于注解的方法级权限控制
  • 前后端统一的权限验证机制
  • 支持权限的动态更新和生效

角色管理界面

水果生产管理模块

水果生产管理涵盖从种植到采收的全过程跟踪,通过数据可视化展示生产趋势和分析结果。

<template>
  <div class="fruit-production">
    <el-card class="search-card">
      <el-form :model="queryParams" ref="queryForm" :inline="true">
        <el-form-item label="水果类型">
          <el-select v-model="queryParams.fruitTypeId" placeholder="请选择">
            <el-option v-for="item in fruitTypes" :key="item.id" 
                       :label="item.title" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card>
      <div ref="chart" style="height: 400px;"></div>
    </el-card>
  </div>
</template>

<script>
import * as echarts from 'echarts'

export default {
  name: 'FruitProduction',
  data() {
    return {
      queryParams: {
        fruitTypeId: null,
        startDate: null,
        endDate: null
      },
      fruitTypes: [],
      chart: null
    }
  },
  mounted() {
    this.initChart()
    this.loadFruitTypes()
    this.loadProductionData()
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$refs.chart)
    },
    async loadProductionData() {
      try {
        const response = await this.$http.post('/fruit/production/statistics', this.queryParams)
        this.updateChart(response.data)
      } catch (error) {
        this.$message.error('数据加载失败')
      }
    },
    updateChart(data) {
      const option = {
        title: { text: '水果产量趋势分析' },
        tooltip: { trigger: 'axis' },
        legend: { data: data.legends },
        xAxis: { type: 'category', data: data.categories },
        yAxis: { type: 'value' },
        series: data.series
      }
      this.chart.setOption(option)
    }
  }
}
</script>

水果生产管理

实体模型设计

系统采用面向对象的领域模型设计,通过JPA注解实现对象关系映射。

// 肥料采购实体类
@Data
@TableName("t_feibuy")
public class FeiBuy {
    
    @TableId(type = IdType.AUTO)
    private Integer id;
    
    @TableField("code")
    private String code;
    
    @TableField("stime")
    private String stime;
    
    @TableField("fcount")
    private String fcount;
    
    @TableField("price")
    private String price;
    
    @TableField("total")
    private String total;
    
    @TableField("bz")
    private String bz;
    
    @TableField("fei_id")
    private Integer feiId;
    
    // 关联实体
    @TableField(exist = false)
    private Fei fei;
}

// 水果类型实体类
@Data
@TableName("t_fruittype")
public class FruitType {
    
    @TableId(type = IdType.AUTO)
    private Integer id;
    
    @TableField("title")
    private String title;
    
    @TableField("bz")
    private String bz;
    
    // 一对多关系:一种类型对应多种水果
    @TableField(exist = false)
    private List<Fruit> fruits;
}

模型设计特点

  • 使用Lombok注解简化代码编写
  • 明确的字段映射关系,避免歧义
  • 支持实体间的关联关系映射
  • 符合Java Bean规范,便于序列化

功能展望与优化

基于当前系统架构和业务需求,提出以下优化方向:

1. 引入Redis缓存层

当前系统主要依赖MySQL数据库,对于高频访问的数据如水果类型、用户信息等,可以引入Redis作为缓存层。

// Redis缓存配置示例
@Configuration
@EnableCaching
public class RedisConfig {
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), 
                                   ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
}

2. 微服务架构改造

随着业务复杂度的增加,可以将单体应用拆分为多个微服务,如用户服务、种植服务、库存服务等。

# Spring Cloud微服务配置示例
spring:
  application:
    name: planting-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**

3. 移动端适配与PWA支持

开发响应式界面,支持PWA技术,使系统在移动设备上有更好的使用体验。

<template>
  <div class="mobile-layout">
    <nav class="mobile-nav">
      <button @click="toggleMenu">☰</button>
      <h1>智能种植管理</h1>
    </nav>
    <main class="mobile-content">
      <router-view />
    </main>
  </div>
</template>

<script>
export default {
  methods: {
    toggleMenu() {
      // 移动端菜单切换逻辑
    }
  }
}
</script>

<style>
@media
本文关键词
VueSpringBoot植物种植管理平台源码解析前后端分离

上下篇

上一篇
没有更多文章
下一篇
没有更多文章