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