Просмотр исходного кода

feat: add Cart backend module (entity+mapper+service+controller)

Implement shopping cart CRUD with quantity management.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
liaoxg 2 месяцев назад
Родитель
Сommit
41086ce248

+ 54 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/cart/CartController.java

@@ -0,0 +1,54 @@
+package com.etotem.cfc.controller.cart;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.service.CartService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestAttribute;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+public class CartController {
+
+    @Resource
+    private CartService cartService;
+
+    @PostMapping("/api/cart/list")
+    public Result<List<Map<String, Object>>> list(@RequestAttribute("userId") Long userId) {
+        return cartService.list(userId);
+    }
+
+    @PostMapping("/api/cart/add")
+    public Result<String> add(@RequestAttribute("userId") Long userId, @RequestBody Map<String, Object> body) {
+        Long productId = Long.valueOf(body.get("productId").toString());
+        return cartService.add(userId, productId);
+    }
+
+    @PostMapping("/api/cart/update")
+    public Result<String> update(@RequestAttribute("userId") Long userId, @RequestBody Map<String, Object> body) {
+        Long productId = Long.valueOf(body.get("productId").toString());
+        Integer quantity = Integer.valueOf(body.get("quantity").toString());
+        return cartService.update(userId, productId, quantity);
+    }
+
+    @PostMapping("/api/cart/remove")
+    public Result<String> remove(@RequestAttribute("userId") Long userId, @RequestBody Map<String, Object> body) {
+        Long productId = Long.valueOf(body.get("productId").toString());
+        return cartService.remove(userId, productId);
+    }
+
+    @PostMapping("/api/cart/toggle")
+    public Result<String> toggle(@RequestAttribute("userId") Long userId, @RequestBody Map<String, Object> body) {
+        Long productId = Long.valueOf(body.get("productId").toString());
+        return cartService.toggle(userId, productId);
+    }
+
+    @PostMapping("/api/cart/clearSelected")
+    public Result<String> clearSelected(@RequestAttribute("userId") Long userId) {
+        return cartService.clearSelected(userId);
+    }
+}

+ 21 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/CartItem.java

@@ -0,0 +1,21 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("cart_items")
+public class CartItem implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long userId;
+    private Long productId;
+    private Integer quantity;
+    private Boolean selected;
+    private Date createdAt;
+    private Date updatedAt;
+}

+ 7 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/CartItemMapper.java

@@ -0,0 +1,7 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.CartItem;
+
+public interface CartItemMapper extends BaseMapper<CartItem> {
+}

+ 130 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/CartService.java

@@ -0,0 +1,130 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.CartItem;
+import com.etotem.cfc.entity.Product;
+import com.etotem.cfc.mapper.CartItemMapper;
+import com.etotem.cfc.mapper.ProductMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+@Service
+public class CartService {
+
+    @Resource
+    private CartItemMapper cartItemMapper;
+
+    @Resource
+    private ProductMapper productMapper;
+
+    public Result<List<Map<String, Object>>> list(Long userId) {
+        List<CartItem> items = cartItemMapper.selectList(
+            new LambdaQueryWrapper<CartItem>()
+                .eq(CartItem::getUserId, userId)
+                .orderByDesc(CartItem::getCreatedAt)
+        );
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (CartItem item : items) {
+            Product product = productMapper.selectById(item.getProductId());
+            Map<String, Object> vo = new LinkedHashMap<>();
+            vo.put("productId", item.getProductId());
+            vo.put("quantity", item.getQuantity());
+            vo.put("selected", item.getSelected());
+            if (product != null) {
+                vo.put("productName", product.getName());
+                vo.put("coverImage", product.getCoverImage());
+                vo.put("unitPrice", product.getPrice());
+                vo.put("stock", product.getStock());
+                vo.put("invalid", !"on_shelf".equals(product.getStatus()));
+            } else {
+                vo.put("productName", "商品已删除");
+                vo.put("coverImage", "");
+                vo.put("unitPrice", 0);
+                vo.put("stock", 0);
+                vo.put("invalid", true);
+            }
+            result.add(vo);
+        }
+        return Result.success(result);
+    }
+
+    public Result<String> add(Long userId, Long productId) {
+        Product product = productMapper.selectById(productId);
+        if (product == null) return Result.error("商品不存在");
+        if (!"on_shelf".equals(product.getStatus())) return Result.error("商品已下架");
+
+        CartItem existing = cartItemMapper.selectOne(
+            new LambdaQueryWrapper<CartItem>()
+                .eq(CartItem::getUserId, userId)
+                .eq(CartItem::getProductId, productId)
+        );
+        if (existing != null) {
+            existing.setQuantity(existing.getQuantity() + 1);
+            existing.setUpdatedAt(new Date());
+            cartItemMapper.updateById(existing);
+        } else {
+            CartItem item = new CartItem();
+            item.setUserId(userId);
+            item.setProductId(productId);
+            item.setQuantity(1);
+            item.setSelected(true);
+            item.setCreatedAt(new Date());
+            item.setUpdatedAt(new Date());
+            cartItemMapper.insert(item);
+        }
+        return Result.success("已加入购物车");
+    }
+
+    public Result<String> update(Long userId, Long productId, Integer quantity) {
+        CartItem item = cartItemMapper.selectOne(
+            new LambdaQueryWrapper<CartItem>()
+                .eq(CartItem::getUserId, userId)
+                .eq(CartItem::getProductId, productId)
+        );
+        if (item == null) return Result.error("购物车记录不存在");
+
+        if (quantity <= 0) {
+            cartItemMapper.deleteById(item.getId());
+            return Result.success("已移除");
+        }
+        item.setQuantity(quantity);
+        item.setUpdatedAt(new Date());
+        cartItemMapper.updateById(item);
+        return Result.success("更新成功");
+    }
+
+    public Result<String> remove(Long userId, Long productId) {
+        cartItemMapper.delete(
+            new LambdaQueryWrapper<CartItem>()
+                .eq(CartItem::getUserId, userId)
+                .eq(CartItem::getProductId, productId)
+        );
+        return Result.success("已移除");
+    }
+
+    public Result<String> toggle(Long userId, Long productId) {
+        CartItem item = cartItemMapper.selectOne(
+            new LambdaQueryWrapper<CartItem>()
+                .eq(CartItem::getUserId, userId)
+                .eq(CartItem::getProductId, productId)
+        );
+        if (item == null) return Result.error("购物车记录不存在");
+
+        item.setSelected(!Boolean.TRUE.equals(item.getSelected()));
+        item.setUpdatedAt(new Date());
+        cartItemMapper.updateById(item);
+        return Result.success("操作成功");
+    }
+
+    public Result<String> clearSelected(Long userId) {
+        cartItemMapper.delete(
+            new LambdaQueryWrapper<CartItem>()
+                .eq(CartItem::getUserId, userId)
+                .eq(CartItem::getSelected, true)
+        );
+        return Result.success("已清空");
+    }
+}