修复订单系统多项问题:Token认证、购物车、订单创建、发货功能等
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package com.meiruo.cosmetics.config;
|
||||
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.jwt.SaJwtManager;
|
||||
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/order")
|
||||
@@ -22,13 +23,36 @@ public class OrderController {
|
||||
@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
Long userId = StpUtil.getLoginIdAsLong();
|
||||
List<Long> cartIds = (List<Long>) params.get("cartIds");
|
||||
|
||||
String receiverName = (String) params.get("receiverName");
|
||||
String receiverPhone = (String) params.get("receiverPhone");
|
||||
String receiverAddress = (String) params.get("receiverAddress");
|
||||
String remark = (String) params.get("remark");
|
||||
|
||||
Order order = orderService.create(userId, cartIds, receiverName, receiverPhone, receiverAddress, remark);
|
||||
|
||||
// 处理 cartIds 类型转换(前端传来的是 Integer,需要转为 Long)
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> rawCartIds = (List<Object>) params.get("cartIds");
|
||||
List<Long> cartIds = (rawCartIds == null || rawCartIds.isEmpty())
|
||||
? new ArrayList<>()
|
||||
: rawCartIds.stream()
|
||||
.map(id -> Long.valueOf(id.toString()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 处理直接购买(不传cartIds,传items)
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> items = (List<Map<String, Object>>) params.get("items");
|
||||
|
||||
Order order;
|
||||
if (cartIds != null && !cartIds.isEmpty()) {
|
||||
order = orderService.create(userId, cartIds, receiverName, receiverPhone, receiverAddress, remark);
|
||||
} else if (items != null && !items.isEmpty()) {
|
||||
order = orderService.createDirect(userId, items, receiverName, receiverPhone, receiverAddress, remark);
|
||||
} else {
|
||||
result.put("code", 400);
|
||||
result.put("msg", "购物车为空,无法创建订单");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.put("code", 200);
|
||||
result.put("msg", "下单成功");
|
||||
result.put("data", order);
|
||||
@@ -72,6 +96,30 @@ public class OrderController {
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/ship/{id}")
|
||||
public Map<String, Object> shipOrder(@PathVariable Long id, @RequestBody Map<String, String> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
String logisticsCompany = params.get("logisticsCompany");
|
||||
String trackingNo = params.get("trackingNo");
|
||||
|
||||
if (logisticsCompany == null || logisticsCompany.trim().isEmpty() ||
|
||||
trackingNo == null || trackingNo.trim().isEmpty()) {
|
||||
result.put("code", 400);
|
||||
result.put("msg", "物流公司和物流单号不能为空");
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean success = orderService.shipOrder(id, logisticsCompany, trackingNo);
|
||||
if (success) {
|
||||
result.put("code", 200);
|
||||
result.put("msg", "发货成功");
|
||||
} else {
|
||||
result.put("code", 500);
|
||||
result.put("msg", "发货失败,订单状态可能不正确");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@GetMapping("/revenue/{type}")
|
||||
public Map<String, Object> getRevenueStatistics(@PathVariable String type) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
@@ -25,12 +25,14 @@ public class UserController {
|
||||
result.put("msg", "用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
String token = StpUtil.getTokenInfo().getTokenValue();
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("id", loginUser.getId());
|
||||
data.put("username", loginUser.getUsername());
|
||||
data.put("nickname", loginUser.getNickname());
|
||||
data.put("avatar", loginUser.getAvatar());
|
||||
data.put("role", loginUser.getRole());
|
||||
data.put("token", token);
|
||||
result.put("code", 200);
|
||||
result.put("msg", "登录成功");
|
||||
result.put("data", data);
|
||||
|
||||
@@ -14,6 +14,8 @@ public class Order {
|
||||
private String receiverName;
|
||||
private String receiverPhone;
|
||||
private String receiverAddress;
|
||||
private String logisticsCompany;
|
||||
private String trackingNo;
|
||||
private String remark;
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime payTime;
|
||||
|
||||
@@ -13,5 +13,6 @@ public class OrderItem {
|
||||
private String productImage;
|
||||
private BigDecimal price;
|
||||
private Integer quantity;
|
||||
private BigDecimal totalPrice;
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,16 @@ import com.meiruo.cosmetics.entity.Cart;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface CartMapper {
|
||||
|
||||
Cart selectById(@Param("id") Long id);
|
||||
|
||||
Cart selectByUserAndProduct(@Param("userId") Long userId, @Param("productId") Long productId);
|
||||
|
||||
List<Cart> selectByUserId(@Param("userId") Long userId);
|
||||
List<Map<String, Object>> selectByUserId(@Param("userId") Long userId);
|
||||
|
||||
int insert(Cart cart);
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ public interface OrderMapper {
|
||||
|
||||
int updateStatus(@Param("id") Long id, @Param("status") Integer status);
|
||||
|
||||
int shipOrder(@Param("id") Long id, @Param("logisticsCompany") String logisticsCompany, @Param("trackingNo") String trackingNo);
|
||||
|
||||
List<Map<String, Object>> selectRevenueStatistics(@Param("type") String type);
|
||||
|
||||
List<Map<String, Object>> selectTopProducts(@Param("limit") Integer limit);
|
||||
|
||||
@@ -8,6 +8,8 @@ public interface OrderService {
|
||||
|
||||
Order create(Long userId, List<Long> cartIds, String receiverName, String receiverPhone, String receiverAddress, String remark);
|
||||
|
||||
Order createDirect(Long userId, List<Map<String, Object>> items, String receiverName, String receiverPhone, String receiverAddress, String remark);
|
||||
|
||||
Order getById(Long id);
|
||||
|
||||
Order getByOrderNo(String orderNo);
|
||||
@@ -18,6 +20,8 @@ public interface OrderService {
|
||||
|
||||
void updateStatus(Long id, Integer status);
|
||||
|
||||
boolean shipOrder(Long id, String logisticsCompany, String trackingNo);
|
||||
|
||||
Map<String, Object> getRevenueStatistics(String type);
|
||||
|
||||
List<Map<String, Object>> getTopProducts(Integer limit);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.meiruo.cosmetics.service.impl;
|
||||
|
||||
import com.meiruo.cosmetics.entity.Cart;
|
||||
import com.meiruo.cosmetics.entity.Order;
|
||||
import com.meiruo.cosmetics.entity.OrderItem;
|
||||
import com.meiruo.cosmetics.entity.Product;
|
||||
import com.meiruo.cosmetics.mapper.CartMapper;
|
||||
import com.meiruo.cosmetics.mapper.OrderItemMapper;
|
||||
import com.meiruo.cosmetics.mapper.OrderMapper;
|
||||
import com.meiruo.cosmetics.mapper.ProductMapper;
|
||||
@@ -11,6 +14,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -25,6 +29,8 @@ public class OrderServiceImpl implements OrderService {
|
||||
private OrderItemMapper orderItemMapper;
|
||||
@Autowired
|
||||
private ProductMapper productMapper;
|
||||
@Autowired
|
||||
private CartMapper cartMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@@ -42,9 +48,29 @@ public class OrderServiceImpl implements OrderService {
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
|
||||
for (Long cartId : cartIds) {
|
||||
Cart cart = cartMapper.selectById(cartId);
|
||||
if (cart == null || !cart.getUserId().equals(userId)) {
|
||||
continue;
|
||||
}
|
||||
Product product = productMapper.selectById(cart.getProductId());
|
||||
if (product == null || product.getStatus() != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OrderItem item = new OrderItem();
|
||||
item.setProductId(product.getId());
|
||||
item.setProductName(product.getName());
|
||||
item.setProductImage(product.getImage());
|
||||
item.setPrice(product.getPrice());
|
||||
item.setQuantity(cart.getQuantity());
|
||||
item.setTotalPrice(product.getPrice().multiply(new BigDecimal(cart.getQuantity())));
|
||||
orderItems.add(item);
|
||||
|
||||
totalAmount = totalAmount.add(item.getTotalPrice());
|
||||
}
|
||||
|
||||
order.setTotalAmount(totalAmount);
|
||||
order.setCreateTime(LocalDateTime.now());
|
||||
orderMapper.insert(order);
|
||||
|
||||
for (OrderItem item : orderItems) {
|
||||
@@ -54,6 +80,11 @@ public class OrderServiceImpl implements OrderService {
|
||||
productMapper.incrementSales(item.getProductId(), item.getQuantity());
|
||||
}
|
||||
|
||||
// 删除购物车中的商品
|
||||
for (Long cartId : cartIds) {
|
||||
cartMapper.delete(cartId);
|
||||
}
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@@ -77,11 +108,67 @@ public class OrderServiceImpl implements OrderService {
|
||||
return orderMapper.selectList(keyword, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Order createDirect(Long userId, List<Map<String, Object>> items, String receiverName, String receiverPhone, String receiverAddress, String remark) {
|
||||
Order order = new Order();
|
||||
order.setOrderNo(UUID.randomUUID().toString().replace("-", ""));
|
||||
order.setUserId(userId);
|
||||
order.setReceiverName(receiverName);
|
||||
order.setReceiverPhone(receiverPhone);
|
||||
order.setReceiverAddress(receiverAddress);
|
||||
order.setRemark(remark);
|
||||
order.setStatus(1);
|
||||
|
||||
List<OrderItem> orderItems = new ArrayList<>();
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
|
||||
for (Map<String, Object> itemData : items) {
|
||||
Long productId = Long.valueOf(itemData.get("productId").toString());
|
||||
Integer quantity = Integer.valueOf(itemData.get("quantity").toString());
|
||||
|
||||
Product product = productMapper.selectById(productId);
|
||||
if (product == null || product.getStatus() != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OrderItem item = new OrderItem();
|
||||
item.setProductId(product.getId());
|
||||
item.setProductName(product.getName());
|
||||
item.setProductImage(product.getImage());
|
||||
item.setPrice(product.getPrice());
|
||||
item.setQuantity(quantity);
|
||||
item.setTotalPrice(product.getPrice().multiply(new BigDecimal(quantity)));
|
||||
orderItems.add(item);
|
||||
|
||||
totalAmount = totalAmount.add(item.getTotalPrice());
|
||||
}
|
||||
|
||||
order.setTotalAmount(totalAmount);
|
||||
order.setCreateTime(LocalDateTime.now());
|
||||
orderMapper.insert(order);
|
||||
|
||||
for (OrderItem item : orderItems) {
|
||||
item.setOrderId(order.getId());
|
||||
orderItemMapper.insert(item);
|
||||
productMapper.updateStock(item.getProductId(), item.getQuantity());
|
||||
productMapper.incrementSales(item.getProductId(), item.getQuantity());
|
||||
}
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatus(Long id, Integer status) {
|
||||
orderMapper.updateStatus(id, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shipOrder(Long id, String logisticsCompany, String trackingNo) {
|
||||
int result = orderMapper.shipOrder(id, logisticsCompany, trackingNo);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRevenueStatistics(String type) {
|
||||
List<Map<String, Object>> statistics = orderMapper.selectRevenueStatistics(type);
|
||||
|
||||
@@ -4,9 +4,13 @@ server:
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/meiruo_cosmetics?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://localhost:3307/meiruo_cosmetics?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
password: qq5211314
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
|
||||
mybatis:
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
<result column="product_image" property="productImage"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectById" resultMap="BaseResultMap">
|
||||
SELECT * FROM cart WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectByUserAndProduct" resultMap="BaseResultMap">
|
||||
SELECT * FROM cart WHERE user_id = #{userId} AND product_id = #{productId}
|
||||
</select>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<result column="product_image" property="productImage"/>
|
||||
<result column="price" property="price"/>
|
||||
<result column="quantity" property="quantity"/>
|
||||
<result column="total_price" property="totalPrice"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
</resultMap>
|
||||
|
||||
@@ -18,15 +19,15 @@
|
||||
</select>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
|
||||
INSERT INTO order_item (order_id, product_id, product_name, product_image, price, quantity, create_time)
|
||||
VALUES (#{orderId}, #{productId}, #{productName}, #{productImage}, #{price}, #{quantity}, NOW())
|
||||
INSERT INTO order_item (order_id, product_id, product_name, product_image, price, quantity, total_price, create_time)
|
||||
VALUES (#{orderId}, #{productId}, #{productName}, #{productImage}, #{price}, #{quantity}, #{totalPrice}, NOW())
|
||||
</insert>
|
||||
|
||||
<insert id="insertBatch">
|
||||
INSERT INTO order_item (order_id, product_id, product_name, product_image, price, quantity, create_time)
|
||||
INSERT INTO order_item (order_id, product_id, product_name, product_image, price, quantity, total_price, create_time)
|
||||
VALUES
|
||||
<foreach collection="items" item="item" separator=",">
|
||||
(#{item.orderId}, #{item.productId}, #{item.productName}, #{item.productImage}, #{item.price}, #{item.quantity}, NOW())
|
||||
(#{item.orderId}, #{item.productId}, #{item.productName}, #{item.productImage}, #{item.price}, #{item.quantity}, #{item.totalPrice}, NOW())
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<result column="receiver_name" property="receiverName"/>
|
||||
<result column="receiver_phone" property="receiverPhone"/>
|
||||
<result column="receiver_address" property="receiverAddress"/>
|
||||
<result column="logistics_company" property="logisticsCompany"/>
|
||||
<result column="tracking_no" property="trackingNo"/>
|
||||
<result column="remark" property="remark"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="pay_time" property="payTime"/>
|
||||
@@ -78,6 +80,15 @@
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="shipOrder">
|
||||
UPDATE `order`
|
||||
SET status = 3,
|
||||
ship_time = NOW(),
|
||||
logistics_company = #{logisticsCompany},
|
||||
tracking_no = #{trackingNo}
|
||||
WHERE id = #{id} AND status = 2
|
||||
</update>
|
||||
|
||||
<select id="selectRevenueStatistics" resultType="java.util.Map">
|
||||
SELECT
|
||||
<choose>
|
||||
|
||||
Reference in New Issue
Block a user