1. 项目概述与背景
在当前的电商浪潮中,手机作为高频消费电子产品,其线上销售渠道的重要性日益凸显。传统电商平台虽然功能完备,但往往存在系统臃肿、定制化程度低的问题。这个基于SpringBoot+Vue的手机销售平台,正是为解决这些问题而设计的轻量级解决方案。
这个项目采用前后端分离架构,后端使用SpringBoot提供RESTful API接口,前端采用Vue.js构建响应式用户界面。系统不仅实现了基础的电商功能(商品展示、购物车、订单管理等),还针对手机销售场景做了特别优化,比如:
- 高性能的商品搜索和筛选
- 简洁高效的支付流程
- 完善的库存预警机制
- 响应式的移动端适配
2. 技术架构解析
2.1 后端技术栈
SpringBoot作为后端核心框架,带来了诸多优势:
- 自动配置:通过spring-boot-starter-web等starter依赖,自动配置了Web MVC、Tomcat等组件
- 简化部署:内嵌Tomcat服务器,打包成单一可执行JAR
- 生产就绪:集成Actuator提供健康检查、指标监控等运维功能
核心配置类示例:
java复制@SpringBootApplication
@MapperScan("com.dao") // MyBatis mapper扫描
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);
}
}
2.2 前端技术栈
Vue.js + Element UI的组合提供了:
- 响应式数据绑定:基于Vue的响应式系统,数据变化自动更新视图
- 组件化开发:单文件组件(SFC)将模板、脚本和样式封装在一起
- 路由管理:Vue Router实现前端路由,支持懒加载
- 状态管理:Vuex集中管理应用状态
典型组件结构:
vue复制<template>
<el-table :data="products">
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
products: []
}
},
async created() {
this.products = await this.$http.get('/api/products')
}
}
</script>
3. 数据库设计与实现
3.1 核心表结构
用户表(user_profile)
sql复制CREATE TABLE `user_profile` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`account_name` varchar(50) NOT NULL,
`encrypted_pwd` varchar(100) NOT NULL,
`mobile_number` varchar(20) DEFAULT NULL,
`email_address` varchar(100) DEFAULT NULL,
`register_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_login` datetime DEFAULT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `idx_account` (`account_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
商品表(product_details)
sql复制CREATE TABLE `product_details` (
`product_id` bigint NOT NULL AUTO_INCREMENT,
`product_name` varchar(100) NOT NULL,
`category_code` varchar(20) NOT NULL,
`retail_price` decimal(10,2) NOT NULL,
`stock_quantity` int NOT NULL DEFAULT '0',
`description` text,
`publish_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`product_id`),
KEY `idx_category` (`category_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
订单表(order_records)
sql复制CREATE TABLE `order_records` (
`order_id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`order_number` varchar(50) NOT NULL,
`total_amount` decimal(10,2) NOT NULL,
`payment_status` tinyint NOT NULL DEFAULT '0',
`shipping_address` varchar(200) NOT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`order_id`),
UNIQUE KEY `idx_order_no` (`order_number`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.2 性能优化设计
-
索引策略:
- 为所有主键设置自增ID
- 为常用查询字段建立索引(如用户账号、商品分类等)
- 订单号设置唯一索引避免重复
-
缓存方案:
- 使用Redis缓存热门商品信息
- 实现多级缓存策略(本地缓存+分布式缓存)
4. 核心功能实现
4.1 用户认证模块
采用JWT(JSON Web Token)实现无状态认证:
java复制@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private UserService userService;
@Autowired
private JwtTokenProvider tokenProvider;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
User user = userService.authenticate(request.getUsername(), request.getPassword());
String token = tokenProvider.generateToken(user);
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
@GetMapping("/me")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<UserProfile> getCurrentUser(@CurrentUser UserPrincipal currentUser) {
UserProfile profile = userService.getUserProfile(currentUser.getId());
return ResponseEntity.ok(profile);
}
}
安全配置:
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/products/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
4.2 商品管理模块
商品CRUD接口示例:
java复制@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public Page<Product> getProducts(
@RequestParam(required = false) String keyword,
@RequestParam(required = false) String category,
@PageableDefault(size = 10) Pageable pageable) {
return productService.searchProducts(keyword, category, pageable);
}
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
public Product createProduct(@Valid @RequestBody ProductRequest request) {
return productService.createProduct(request);
}
@PutMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public Product updateProduct(@PathVariable Long id, @Valid @RequestBody ProductRequest request) {
return productService.updateProduct(id, request);
}
}
4.3 购物车与订单系统
购物车实现逻辑:
java复制@Service
public class CartServiceImpl implements CartService {
@Autowired
private ProductRepository productRepo;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public Cart getCart(Long userId) {
String key = "cart:" + userId;
Cart cart = (Cart) redisTemplate.opsForValue().get(key);
return cart != null ? cart : new Cart(userId);
}
@Override
public Cart addItem(Long userId, CartItem item) {
Product product = productRepo.findById(item.getProductId())
.orElseThrow(() -> new ResourceNotFoundException("Product not found"));
item.setUnitPrice(product.getRetailPrice());
item.setProductName(product.getProductName());
Cart cart = getCart(userId);
cart.addItem(item);
redisTemplate.opsForValue().set("cart:" + userId, cart, 7, TimeUnit.DAYS);
return cart;
}
}
订单创建流程:
java复制@Transactional
public Order createOrder(Long userId, OrderRequest request) {
// 1. 验证用户
User user = userRepo.findById(userId)
.orElseThrow(() -> new ResourceNotFoundException("User not found"));
// 2. 获取购物车
Cart cart = cartService.getCart(userId);
if (cart.isEmpty()) {
throw new BusinessException("Cart is empty");
}
// 3. 创建订单
Order order = new Order();
order.setUser(user);
order.setShippingAddress(request.getAddress());
order.setTotalAmount(cart.getTotal());
// 4. 转换购物车项为订单项
List<OrderItem> items = cart.getItems().stream()
.map(cartItem -> {
OrderItem item = new OrderItem();
item.setProductId(cartItem.getProductId());
item.setQuantity(cartItem.getQuantity());
item.setUnitPrice(cartItem.getUnitPrice());
return item;
}).collect(Collectors.toList());
order.setItems(items);
// 5. 扣减库存
items.forEach(item -> {
productRepo.decreaseStock(item.getProductId(), item.getQuantity());
});
// 6. 清空购物车
cartService.clearCart(userId);
return orderRepo.save(order);
}
5. 部署与运维
5.1 后端部署
- 打包应用:
bash复制mvn clean package -DskipTests
- 运行应用:
bash复制java -jar target/mobile-shop-0.0.1-SNAPSHOT.jar \
--spring.profiles.active=prod \
--spring.datasource.url=jdbc:mysql://localhost:3306/mobile_shop \
--spring.datasource.username=root \
--spring.datasource.password=yourpassword
- 生产环境建议:
- 使用Nginx作为反向代理
- 配置HTTPS证书
- 启用Spring Boot Actuator监控
- 设置JVM内存参数
5.2 前端部署
- 构建生产版本:
bash复制npm run build
- Nginx配置示例:
nginx复制server {
listen 80;
server_name yourdomain.com;
location / {
root /path/to/dist;
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;
}
}
6. 常见问题与解决方案
6.1 跨域问题
问题现象:前端访问API时出现CORS错误
解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
6.2 接口性能优化
慢查询优化步骤:
- 启用Spring Boot的JPA/Hibernate SQL日志:
properties复制spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
- 使用JPA的@NamedEntityGraph解决N+1查询问题:
java复制@Entity
@NamedEntityGraph(
name = "Order.withItems",
attributeNodes = @NamedAttributeNode("items")
)
public class Order {
// ...
}
public interface OrderRepository extends JpaRepository<Order, Long> {
@EntityGraph(value = "Order.withItems", type = EntityGraphType.LOAD)
Optional<Order> findWithItemsById(Long id);
}
6.3 支付集成问题
支付流程关键点:
- 支付状态机设计:
java复制public enum PaymentStatus {
PENDING, // 待支付
PROCESSING, // 处理中
COMPLETED, // 已完成
FAILED, // 已失败
REFUNDED // 已退款
}
@Service
public class PaymentServiceImpl implements PaymentService {
@Transactional
public void processPaymentCallback(PaymentCallbackRequest request) {
Order order = orderRepo.findByOrderNumber(request.getOrderNo())
.orElseThrow(() -> new BusinessException("Order not found"));
if (order.getPaymentStatus() != PaymentStatus.PENDING) {
throw new BusinessException("Invalid payment status");
}
if (request.isSuccess()) {
order.setPaymentStatus(PaymentStatus.COMPLETED);
order.setPaidTime(LocalDateTime.now());
// 触发订单履约流程
fulfillmentService.processOrder(order);
} else {
order.setPaymentStatus(PaymentStatus.FAILED);
}
orderRepo.save(order);
}
}
7. 项目扩展方向
-
微服务化改造:
- 将单体应用拆分为商品服务、订单服务、用户服务等
- 使用Spring Cloud Alibaba实现服务治理
- 引入分布式事务解决方案(Seata)
-
多端适配:
- 开发微信小程序版本
- 实现PWA(Progressive Web App)支持
- 适配各种移动设备
-
数据分析增强:
- 集成ELK日志分析系统
- 实现用户行为分析
- 构建商品推荐系统
-
国际化支持:
- 多语言资源文件管理
- 地区化定价策略
- 跨境支付集成
这个项目不仅适合作为毕业设计,也可以作为实际电商项目的起点。通过这个项目,开发者可以掌握现代Java Web开发的全套技术栈,包括Spring Boot、Vue.js、MySQL、Redis等主流技术的实战应用。