"果蔬到家APP"是一款基于移动互联网的农产品电商平台,旨在解决传统果蔬购买方式中存在的耗时费力、信息不对称等问题。作为一名有多年开发经验的工程师,我在毕业设计中选择了这个项目,因为它不仅具有实际应用价值,还能充分展示全栈开发能力。
这个项目采用了前后端分离的架构,后端使用Spring Boot框架,前端采用Uni-App实现跨平台开发。系统主要包含三个角色:买家用户、商家用户和管理员,实现了从商品展示、下单购买到订单管理的完整电商流程。
提示:在开发类似电商系统时,建议从最小可行产品(MVP)开始,先实现核心功能再逐步扩展,这样可以有效控制开发周期和风险。
买家用户的核心需求集中在便捷购物体验上:
商家用户主要关注店铺运营效率:
管理员负责平台整体运营:
选择Spring Boot作为后端框架主要基于以下考虑:
数据库选用MySQL 8.0,原因包括:
前端采用Uni-App框架实现跨平台开发:
系统采用经典的三层架构:
code复制┌───────────────────────────────────────┐
│ 客户端层 │
│ (iOS/Android/小程序,基于Uni-App) │
└───────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ API网关层 │
│ (路由转发、权限校验、请求限流等) │
└───────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ 业务逻辑层 │
│ (Spring Boot实现核心业务处理) │
└───────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ 数据访问层 │
│ (JPA/Hibernate操作MySQL数据库) │
└───────────────────────────────────────┘
这种分层架构的优势在于:
采用JWT(JSON Web Token)实现无状态认证:
java复制// JWT工具类核心代码
public class JwtUtil {
private static final String SECRET = "your-secret-key";
private static final long EXPIRATION = 86400L; // 24小时
public static String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return Jwts.builder()
.setClaims(claims)
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public static Boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
}
基于Spring Security实现RBAC权限模型:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/buyer/**").hasRole("BUYER")
.antMatchers("/api/seller/**").hasRole("SELLER")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}
}
商品表核心字段设计:
sql复制CREATE TABLE `goods` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`description` text COMMENT '商品描述',
`price` decimal(10,2) NOT NULL COMMENT '现价',
`original_price` decimal(10,2) COMMENT '原价',
`stock` int NOT NULL DEFAULT '0' COMMENT '库存',
`sales` int DEFAULT '0' COMMENT '销量',
`category_id` bigint COMMENT '分类ID',
`seller_id` bigint NOT NULL COMMENT '商家ID',
`status` tinyint DEFAULT '1' COMMENT '状态:1-上架,0-下架',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_seller` (`seller_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
使用Elasticsearch实现高效商品搜索:
java复制@Service
public class ProductSearchServiceImpl implements ProductSearchService {
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Override
public Page<Product> search(String keyword, Pageable pageable) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword, "name", "description"))
.withPageable(pageable)
.build();
return elasticsearchOperations.queryForPage(searchQuery, Product.class);
}
}
下单核心业务流程:
java复制@Transactional
public Order createOrder(OrderDTO orderDTO) {
// 1. 验证商品和库存
List<OrderItem> items = validateProducts(orderDTO.getItems());
// 2. 计算总价
BigDecimal totalAmount = calculateTotal(items);
BigDecimal discountAmount = applyCoupon(orderDTO.getCouponId(), totalAmount);
BigDecimal actualAmount = totalAmount.subtract(discountAmount);
// 3. 创建订单
Order order = new Order();
order.setUserId(orderDTO.getUserId());
order.setTotalAmount(totalAmount);
order.setActualAmount(actualAmount);
order.setStatus(OrderStatus.PENDING_PAYMENT);
orderRepository.save(order);
// 4. 创建订单项
createOrderItems(order.getId(), items);
// 5. 扣减库存
reduceStock(items);
return order;
}
使用状态模式管理订单状态流转:
java复制public interface OrderState {
void pay(Order order);
void deliver(Order order);
void receive(Order order);
void cancel(Order order);
}
@Service
@Scope("prototype")
public class PendingPaymentState implements OrderState {
@Override
public void pay(Order order) {
order.setState(new PaidState());
// 更新订单状态为已支付
}
@Override
public void cancel(Order order) {
order.setState(new CancelledState());
// 恢复库存等操作
}
}
推荐部署环境:
生产环境MySQL建议配置:
ini复制[mysqld]
innodb_buffer_pool_size = 1G # 根据服务器内存调整
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2 # 平衡性能与安全性
sync_binlog = 100
max_connections = 200
query_cache_type = 0 # 禁用查询缓存
使用Shell脚本自动化部署:
bash复制#!/bin/bash
# 停止现有服务
sudo systemctl stop fruits-app
# 备份旧版本
TIMESTAMP=$(date +%Y%m%d%H%M%S)
tar -czvf /backup/fruits-app-$TIMESTAMP.tar.gz /opt/fruits-app
# 部署新版本
rm -rf /opt/fruits-app/*
unzip -q fruits-app-latest.zip -d /opt/fruits-app
# 配置环境
cp /opt/fruits-app/config/prod.properties /opt/fruits-app/config/application.properties
# 启动服务
sudo systemctl start fruits-app
# 健康检查
sleep 30
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/actuator/health)
if [ "$STATUS" -eq 200 ]; then
echo "Deployment successful"
else
echo "Deployment failed"
exit 1
fi
数据库优化:
缓存策略:
前端优化:
输入验证:
敏感数据保护:
API安全:
功能扩展:
技术升级:
运营工具:
注意事项:在开发过程中,建议使用Git进行版本控制,保持合理的分支策略,并编写有意义的提交信息,这对团队协作和后期维护都非常重要。