init
This commit is contained in:
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.seata.order;
|
||||
|
||||
import org.springblade.common.constant.LauncherConstant;
|
||||
import org.springblade.core.cloud.feign.EnableBladeFeign;
|
||||
import org.springblade.core.launch.BladeApplication;
|
||||
import org.springblade.core.transaction.annotation.SeataCloudApplication;
|
||||
|
||||
/**
|
||||
* Order启动器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@EnableBladeFeign
|
||||
@SeataCloudApplication
|
||||
public class SeataOrderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BladeApplication.run(LauncherConstant.APPLICATION_SEATA_ORDER_NAME, SeataOrderApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package org.springblade.seata.order.controller;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.seata.order.service.IOrderService;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* OrderController
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("order")
|
||||
@AllArgsConstructor
|
||||
public class OrderController {
|
||||
|
||||
private final IOrderService orderService;
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param commodityCode 商品代码
|
||||
* @param count 数量
|
||||
* @return boolean
|
||||
*/
|
||||
@RequestMapping("/create")
|
||||
public R createOrder(String userId, String commodityCode, Integer count) {
|
||||
return R.status(orderService.createOrder(userId, commodityCode, count));
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package org.springblade.seata.order.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Order
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName("tb_order")
|
||||
public class Order implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
private String userId;
|
||||
private String commodityCode;
|
||||
private Integer count;
|
||||
private BigDecimal money;
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package org.springblade.seata.order.feign;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* StorageClient
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@FeignClient(name = "blade-seata-storage", fallback = StorageClientFallback.class)
|
||||
public interface IStorageClient {
|
||||
|
||||
/**
|
||||
* 减库存
|
||||
*
|
||||
* @param commodityCode 商品代码
|
||||
* @param count 数量
|
||||
* @return boolean
|
||||
*/
|
||||
@GetMapping("/storage/deduct")
|
||||
int deduct(@RequestParam("commodityCode") String commodityCode, @RequestParam("count") Integer count);
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package org.springblade.seata.order.feign;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* StorageClientFallback
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Component
|
||||
public class StorageClientFallback implements IStorageClient {
|
||||
|
||||
@Override
|
||||
public int deduct(String commodityCode, Integer count) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.springblade.seata.order.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springblade.seata.order.entity.Order;
|
||||
|
||||
/**
|
||||
* OrderMapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface OrderMapper extends BaseMapper<Order> {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.seata.order.mapper.OrderMapper">
|
||||
|
||||
</mapper>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package org.springblade.seata.order.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.seata.order.entity.Order;
|
||||
|
||||
/**
|
||||
* IOrderService
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IOrderService extends IService<Order> {
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param commodityCode 商品代码
|
||||
* @param count 数量
|
||||
* @return boolean
|
||||
*/
|
||||
boolean createOrder(String userId, String commodityCode, Integer count);
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package org.springblade.seata.order.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.seata.order.entity.Order;
|
||||
import org.springblade.seata.order.feign.IStorageClient;
|
||||
import org.springblade.seata.order.mapper.OrderMapper;
|
||||
import org.springblade.seata.order.service.IOrderService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* OrderServiceImpl
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
|
||||
|
||||
private final IStorageClient storageClient;
|
||||
|
||||
@Override
|
||||
@GlobalTransactional
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean createOrder(String userId, String commodityCode, Integer count) {
|
||||
int maxCount = 100;
|
||||
BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
|
||||
Order order = new Order()
|
||||
.setUserId(userId)
|
||||
.setCommodityCode(commodityCode)
|
||||
.setCount(count)
|
||||
.setMoney(orderMoney);
|
||||
int cnt1 = baseMapper.insert(order);
|
||||
int cnt2 = storageClient.deduct(commodityCode, count);
|
||||
if (cnt2 < 0) {
|
||||
throw new ServiceException("创建订单失败");
|
||||
} else if (count > maxCount) {
|
||||
throw new ServiceException("超过订单最大值,创建订单失败");
|
||||
}
|
||||
return cnt1 > 0 && cnt2 > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#服务器端口
|
||||
server:
|
||||
port: 8501
|
||||
|
||||
#数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
|
||||
#常规配置
|
||||
blade:
|
||||
mybatis-plus:
|
||||
tenant-mode: false
|
||||
Reference in New Issue
Block a user