1. 项目概述与背景
乐享田园系统是面向现代都市人群设计的综合性农业服务平台,旨在解决城市化进程中人们对田园生活的需求痛点。作为一个全栈项目,它采用了当前主流的SpringBoot+Vue技术栈,实现了农产品交易、田园活动预约、土地租赁等核心功能模块。
在项目架构设计上,我们采用了经典的三层架构模式:
- 表现层:Vue.js + ElementUI构建响应式前端界面
- 业务逻辑层:SpringBoot实现RESTful API
- 数据访问层:MyBatis + MySQL进行数据持久化
这种架构选择主要基于以下考量:
- 开发效率:SpringBoot的约定优于配置原则大幅减少了XML配置,Vue的组件化开发提升了前端复用性
- 性能表现:MyBatis的SQL优化能力配合MySQL索引策略,可支撑万级用户并发
- 维护成本:前后端分离架构使得团队可以并行开发,降低耦合度
提示:在实际部署时,建议将前端项目编译为静态资源后与后端一起打包为JAR,这样可以简化部署流程。我们团队在生产环境中使用这种方案,部署时间从原来的30分钟缩短到5分钟以内。
2. 核心功能模块设计
2.1 用户管理子系统
用户模块采用RBAC(基于角色的访问控制)模型设计,主要包含以下核心功能:
- 多因素认证(账号密码+手机验证码)
- JWT令牌的无状态认证
- 细粒度的权限控制(基于Spring Security实现)
用户表设计特别注意了安全规范:
sql复制CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '用户名',
`password_hash` varchar(100) COLLATE utf8mb4_bin NOT NULL COMMENT '加密密码',
`salt` varchar(20) COLLATE utf8mb4_bin NOT NULL COMMENT '加密盐值',
`email` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '手机号',
`status` tinyint DEFAULT '0' COMMENT '状态(0-正常 1-冻结)',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`user_id`),
UNIQUE KEY `idx_username` (`username`),
KEY `idx_phone` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='用户表';
密码存储采用PBKDF2WithHmacSHA256算法进行加密,核心代码如下:
java复制public class PasswordUtil {
private static final int ITERATIONS = 10000;
private static final int KEY_LENGTH = 256;
public static String encrypt(String password, String salt) {
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
salt.getBytes(StandardCharsets.UTF_8),
ITERATIONS,
KEY_LENGTH
);
// ... 加密实现
}
}
2.2 农产品交易模块
农产品交易采用电商平台的典型设计模式,包含:
- 商品发布系统(支持多图上传、富文本描述)
- 购物车与订单系统
- 支付对接(支持微信/支付宝)
- 物流跟踪接口
订单表设计考虑了分布式场景下的ID生成:
sql复制CREATE TABLE `product_order` (
`order_id` varchar(32) NOT NULL COMMENT '订单号(时间戳+随机数)',
`product_id` bigint NOT NULL COMMENT '商品ID',
`buyer_id` bigint NOT NULL COMMENT '买家ID',
`seller_id` bigint NOT NULL COMMENT '卖家ID',
`quantity` int NOT NULL DEFAULT '1' COMMENT '购买数量',
`unit_price` decimal(10,2) NOT NULL COMMENT '单价',
`total_price` decimal(10,2) NOT NULL COMMENT '总金额',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '状态',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`order_id`),
KEY `idx_buyer` (`buyer_id`),
KEY `idx_seller` (`seller_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='农产品订单表';
注意:订单状态变更时务必使用乐观锁机制,避免超卖问题。我们实际项目中遇到过因未加锁导致的库存负数情况。
3. 技术实现细节
3.1 后端SpringBoot配置
应用入口类配置了MyBatis扫描和Servlet支持:
java复制@SpringBootApplication
@MapperScan("com.letian.dao")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
关键配置项(application.yml):
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/letian?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 20
minimum-idle: 5
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
3.2 Vue前端工程结构
采用Vue CLI创建的典型项目结构:
code复制src/
├── api/ # 接口定义
├── assets/ # 静态资源
├── components/ # 公共组件
├── router/ # 路由配置
├── store/ # Vuex状态管理
├── utils/ # 工具函数
├── views/ # 页面组件
└── main.js # 入口文件
axios请求拦截器示例(处理Token自动注入):
javascript复制axios.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}, error => {
return Promise.reject(error)
})
4. 部署与优化实践
4.1 生产环境部署方案
我们推荐使用Docker Compose进行容器化部署:
dockerfile复制# backend/Dockerfile
FROM openjdk:11-jre
COPY target/letian.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
# frontend/Dockerfile
FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
Nginx配置关键点(处理Vue路由的history模式):
nginx复制server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:8080;
}
}
4.2 性能优化技巧
-
数据库层面:
- 为常用查询字段建立复合索引
- 大表采用分库分表策略(我们按用户ID哈希分片)
- 使用Redis缓存热点数据
-
前端优化:
- 路由懒加载
- 组件按需引入
- 使用Webpack的SplitChunks插件拆分代码
-
接口优化:
- 采用GraphQL替代部分RESTful接口
- 使用Hystrix实现服务熔断
- 接口响应时间监控(通过Spring Boot Actuator)
5. 常见问题解决方案
5.1 跨域问题处理
SpringBoot后端配置CORS:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true)
.maxAge(3600);
}
}
5.2 文件上传大小限制
调整SpringBoot默认配置:
yaml复制spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
5.3 定时任务实现
使用Spring Scheduled实现每日统计:
java复制@Component
public class DailyStatsJob {
private static final Logger logger = LoggerFactory.getLogger(DailyStatsJob.class);
@Autowired
private OrderService orderService;
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
public void generateDailyReport() {
logger.info("开始生成每日统计报告...");
orderService.generateDailyStats();
}
}
6. 扩展与二次开发建议
-
微服务改造:
- 将用户服务、订单服务拆分为独立模块
- 使用Spring Cloud Alibaba实现服务治理
- 引入Sentinel进行流量控制
-
大数据分析:
- 集成ELK日志分析系统
- 使用Flink实现实时数据分析
- 构建用户行为画像系统
-
移动端适配:
- 开发微信小程序版本
- 使用Uniapp实现多端统一
- 增加PWA支持提升移动体验
在实际开发过程中,我们团队发现ElementUI的表格组件在处理万级数据时存在性能瓶颈,最终通过以下方案解决:
- 采用虚拟滚动技术(vue-virtual-scroller)
- 实现后端分页(每次只查询当前页数据)
- 对复杂计算列使用Web Worker处理