|
|
@@ -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);
|
|
|
+ }
|
|
|
+}
|