1. 项目概述
这个小区疫情购物系统是一个典型的社区电商解决方案,采用前后端分离架构。后端基于SpringBoot框架实现业务逻辑和数据处理,前端使用Vue.js构建用户界面,数据存储则采用MySQL关系型数据库。整套系统设计初衷是为了解决疫情期间社区居民的物资采购难题,实现线上订购、无接触配送的闭环管理。
我在2022年实际参与过类似系统的开发部署,当时为上海某封闭管理小区紧急搭建的购物平台,3天内完成从需求分析到上线的全过程。这种系统最核心的价值在于将传统线下采购流程数字化,既降低交叉感染风险,又提高了物资分配效率。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 后端技术栈
SpringBoot 2.7.x作为后端框架,主要考虑其快速启动和自动配置特性。疫情场景下开发时间紧迫,SpringBoot的starter依赖能大幅减少基础配置时间。关键配置如下:
java复制// 数据库配置示例
spring.datasource.url=jdbc:mysql://localhost:3306/community_mall
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
// MyBatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.entity
系统采用三层架构设计:
- Controller层处理HTTP请求
- Service层实现业务逻辑
- DAO层负责数据持久化
2.2 前端技术选型
Vue 2.x版本(考虑到企业级项目稳定性),配合Element UI组件库。前端工程采用标准结构:
code复制src/
├── api/ # 接口定义
├── assets/ # 静态资源
├── components/ # 公共组件
├── router/ # 路由配置
├── store/ # Vuex状态管理
└── views/ # 页面组件
关键路由配置示例:
javascript复制{
path: '/order',
component: Layout,
children: [{
path: 'list',
component: () => import('@/views/order/list'),
name: 'OrderList',
meta: { title: '订单管理', icon: 'list' }
}]
}
2.3 数据库设计
MySQL 8.0版本,主要表结构包括:
- 用户表(users)
sql复制CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`building_num` varchar(10) NOT NULL COMMENT '楼栋号',
`unit_num` varchar(5) NOT NULL COMMENT '单元号',
`room_num` varchar(10) NOT NULL COMMENT '房间号',
`phone` varchar(20) NOT NULL,
`role` tinyint NOT NULL DEFAULT '0' COMMENT '0-普通用户 1-管理员',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 商品表(products)
sql复制CREATE TABLE `products` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`category_id` int NOT NULL,
`price` decimal(10,2) NOT NULL,
`stock` int NOT NULL DEFAULT '0',
`image_url` varchar(255) DEFAULT NULL,
`description` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 订单表(orders)
sql复制CREATE TABLE `orders` (
`id` int NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) NOT NULL,
`user_id` int NOT NULL,
`total_amount` decimal(10,2) NOT NULL,
`status` tinyint NOT NULL DEFAULT '0' COMMENT '0-待支付 1-已支付 2-已配送 3-已完成',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`address` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `order_no` (`order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心功能实现
3.1 用户认证模块
采用JWT认证方案,关键实现步骤:
- 登录接口生成token:
java复制public String login(String username, String password) {
// 验证用户凭证
User user = userService.validateUser(username, password);
// 生成JWT
return Jwts.builder()
.setSubject(user.getUsername())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET.getBytes())
.compact();
}
- 配置拦截器验证token:
java复制public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Authorization");
try {
Claims claims = Jwts.parser()
.setSigningKey(SECRET.getBytes())
.parseClaimsJws(token.replace("Bearer ", ""))
.getBody();
request.setAttribute("username", claims.getSubject());
return true;
} catch (Exception e) {
throw new UnauthorizedException("无效token");
}
}
}
3.2 商品管理模块
后端接口示例:
java复制@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public PageResult<Product> list(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String keyword) {
return productService.getProducts(page, size, keyword);
}
@PostMapping
public Product create(@RequestBody Product product) {
return productService.createProduct(product);
}
}
前端商品列表组件关键代码:
vue复制<template>
<div>
<el-table :data="products" style="width: 100%">
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格" width="120"></el-table-column>
<el-table-column prop="stock" label="库存" width="100"></el-table-column>
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
products: []
}
},
created() {
this.fetchProducts()
},
methods: {
async fetchProducts() {
const res = await this.$http.get('/api/products')
this.products = res.data
}
}
}
</script>
3.3 订单处理流程
订单状态机设计:
java复制public enum OrderStatus {
PENDING_PAYMENT(0, "待支付"),
PAID(1, "已支付"),
DELIVERING(2, "配送中"),
COMPLETED(3, "已完成"),
CANCELLED(4, "已取消");
// 状态转换校验逻辑
public static boolean canTransfer(OrderStatus from, OrderStatus to) {
switch (from) {
case PENDING_PAYMENT:
return to == PAID || to == CANCELLED;
case PAID:
return to == DELIVERING;
case DELIVERING:
return to == COMPLETED;
default:
return false;
}
}
}
订单创建核心逻辑:
java复制@Transactional
public Order createOrder(OrderDTO orderDTO) {
// 验证库存
List<OrderItem> items = orderDTO.getItems();
for (OrderItem item : items) {
Product product = productRepository.findById(item.getProductId())
.orElseThrow(() -> new BusinessException("商品不存在"));
if (product.getStock() < item.getQuantity()) {
throw new BusinessException(product.getName() + "库存不足");
}
}
// 扣减库存
for (OrderItem item : items) {
productRepository.reduceStock(item.getProductId(), item.getQuantity());
}
// 创建订单
Order order = new Order();
order.setOrderNo(generateOrderNo());
order.setUserId(orderDTO.getUserId());
order.setTotalAmount(calculateTotal(items));
order.setStatus(OrderStatus.PENDING_PAYMENT);
orderRepository.save(order);
// 保存订单项
orderItemRepository.saveAll(
items.stream()
.map(dto -> new OrderItem(order.getId(), dto))
.collect(Collectors.toList())
);
return order;
}
4. 部署与运行指南
4.1 环境准备
基础软件要求:
- JDK 1.8+
- Node.js 14+
- MySQL 8.0+
- Maven 3.6+
建议使用Docker快速搭建环境:
bash复制# MySQL容器
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=yourpassword \
-e MYSQL_DATABASE=community_mall \
mysql:8.0
# Redis容器(用于缓存)
docker run -d \
--name redis \
-p 6379:6379 \
redis:alpine
4.2 后端部署
- 数据库初始化:
bash复制mysql -uroot -p community_mall < db_schema.sql
- 编译打包:
bash复制mvn clean package -DskipTests
- 启动应用:
bash复制java -jar target/community-mall-1.0.0.jar \
--spring.profiles.active=prod \
--spring.datasource.url=jdbc:mysql://localhost:3306/community_mall \
--spring.datasource.username=root \
--spring.datasource.password=yourpassword
4.3 前端部署
- 安装依赖:
bash复制npm install
- 开发模式运行:
bash复制npm run serve
- 生产构建:
bash复制npm run build
- Nginx配置示例:
nginx复制server {
listen 80;
server_name mall.yourdomain.com;
location / {
root /path/to/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
5. 常见问题与解决方案
5.1 跨域问题
开发环境解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
生产环境建议通过Nginx反向代理解决,避免直接开放跨域。
5.2 性能优化建议
- 数据库层面:
- 为常用查询字段添加索引
- 避免全表扫描操作
- 合理使用连接查询
- 缓存策略:
java复制@Cacheable(value = "products", key = "#id")
public Product getProductById(Integer id) {
return productRepository.findById(id).orElse(null);
}
@CacheEvict(value = "products", key = "#product.id")
public Product updateProduct(Product product) {
return productRepository.save(product);
}
- 前端优化:
- 启用Gzip压缩
- 使用CDN加速静态资源
- 实现组件懒加载
5.3 安全防护措施
- SQL注入防护:
- 使用MyBatis预编译语句
- 避免字符串拼接SQL
- XSS防护:
java复制@Bean
public FilterRegistrationBean<XssFilter> xssFilter() {
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new XssFilter());
registration.addUrlPatterns("/*");
return registration;
}
- CSRF防护(Vue端):
javascript复制// 在axios拦截器中添加CSRF Token
axios.interceptors.request.use(config => {
config.headers['X-CSRF-TOKEN'] = getCookie('csrfToken')
return config
})
6. 项目扩展方向
6.1 功能增强建议
- 配送管理模块:
- 配送员分配算法
- 配送路线规划
- 实时位置追踪
- 数据分析看板:
- 销售趋势分析
- 热销商品统计
- 用户购买行为分析
- 消息通知系统:
- 订单状态变更通知
- 促销活动推送
- 系统公告
6.2 技术升级路径
- 微服务化改造:
- 按业务拆分服务(用户服务、商品服务、订单服务)
- 引入Spring Cloud生态
- 服务注册与发现
- 前端架构升级:
- 迁移至Vue 3 + TypeScript
- 引入微前端架构
- 实现PWA特性
- 大数据分析:
- 用户行为数据采集
- 基于Flink的实时计算
- 商品推荐算法
这套系统在实际疫情管控中展现了极高的实用价值。我在部署过程中发现,系统的健壮性和易用性往往比复杂功能更重要。特别是在高并发场景下,合理的缓存策略和数据库索引设计能显著提升系统稳定性
