skyfffire 2 miesięcy temu
rodzic
commit
e1a1c4b3fc

+ 4 - 0
src/main/java/modules/order/OrderController.java

@@ -1,8 +1,12 @@
 package modules.order;
 
+import com.jfinal.aop.Inject;
 import common.utils.http.MyController;
 
 public class OrderController extends MyController {
+    @Inject
+    private OrderService service;
+    
     // 订单状态枚举 (建议定义在单独的类或枚举中)
     public enum OrderStatus {
         CANCELED(0, "已取消"),

+ 88 - 0
src/main/java/modules/order/OrderService.java

@@ -0,0 +1,88 @@
+package modules.order;
+
+import com.jfinal.plugin.activerecord.Db;
+import com.jfinal.plugin.activerecord.Record;
+import common.model.Order;
+import common.model.OrderLog;
+import common.utils.http.MyRet;
+
+import java.math.BigDecimal;
+
+public class OrderService {
+    public MyRet create(int nfttId, int userId, int orderType) {
+        BigDecimal quantity = BigDecimal.ONE;
+        
+        try {
+            Db.tx(() -> {
+                // 1. SELECT ... FOR UPDATE: 查询商品库存,并对该商品行加排他锁
+                Record item = Db.findFirst("SELECT purchased_quantity, max_quantity, price FROM t_nftt WHERE id = ? FOR UPDATE", nfttId);
+
+                if (item == null) {
+                    throw new RuntimeException("商品不存在: " + nfttId); // 抛出异常触发回滚
+                }
+
+                int stock = item.getInt("max_quantity") - item.getInt("purchased_quantity");
+                if (stock <= 0) {
+                    throw new RuntimeException("库存不足"); // 抛出异常触发回滚
+                }
+
+                // 2. 更新库存(在锁定的行上进行)
+                Db.update("UPDATE purchased_quantity SET purchased_quantity = purchased_quantity + 1 WHERE id = ?", nfttId);
+                
+                // 3. 创建订单
+                Order order = new Order();
+                String orderSn = generateOrderSn();                                         // 生成唯一订单号
+                BigDecimal unit_price = item.getBigDecimal("price");
+
+                order.set("order_sn", orderSn);
+                order.set("user_id", userId);
+                order.set("nftt_id", nfttId);
+                order.set("order_status", OrderController.OrderStatus.PENDING_PAY.code);    // 初始状态:待支付
+                order.set("order_type", orderType);                                         // 订单类型:1=正式购买, 2=预购
+                order.set("quantity", quantity);
+                // ... 获取单价、计算总价 ...
+                order.set("unit_price", unit_price);
+                order.set("total_price", quantity.multiply(unit_price));
+                // ... 支付方式 ...
+                order.set("payment_method", 1);
+                // ... 交付方式 ...
+                order.set("delivery_status", 0);
+                // ... nft铸造状态 ...
+                order.set("nft_mint_status", 0);
+                // 其它
+                order.set("refund_status", 0);
+                // 相关时间戳
+                order.set("create_time", System.currentTimeMillis());
+                order.set("update_time", System.currentTimeMillis());
+                order.set("is_deleted", 0);
+                
+                if (!order.save()) {
+                    throw new RuntimeException("创建订单失败, nftt id=" + nfttId + ", user id=" + userId + ", order type=" + orderType);
+                }
+
+                // 3. 记录订单创建日志
+                OrderLog log = new OrderLog();
+                log.set("order_id", order.getId());
+                log.set("from_status", 0); // 从无状态到待支付
+                log.set("to_status", OrderController.OrderStatus.PENDING_PAY.code);
+                log.set("operator_id", userId); // 由用户创建
+                log.set("operator_type", 1);
+                log.set("change_reason", "订单创建");
+                log.set("create_time", System.currentTimeMillis());
+                if (!log.save()) {
+                    throw new RuntimeException("订单日志创建失败"); // 抛出异常触发回滚
+                }
+
+                return true;
+            });
+
+            return MyRet.ok(orderType == 1 ? "抢购成功" : "预购成功");
+        } catch (Exception e) {
+            return MyRet.fail(e.getMessage());
+        }
+    }
+
+    private String generateOrderSn() {
+        return System.currentTimeMillis() + "" + (int)(Math.random() * 10000);
+    }
+}