mirror of
https://gitee.com/coder-xiaomo/flashsale
synced 2025-01-10 11:48:14 +08:00
交易下单1(未完成)
This commit is contained in:
parent
640105972e
commit
d44db6d5be
28
README.md
28
README.md
@ -18,7 +18,7 @@
|
||||
| ----------------- | --------------------- | --------------------------------------- | ---------------------------------------- | ------------------------------- |
|
||||
| **Controller层** | | | | |
|
||||
| Controller | controller | 类 class | | controller.UserController |
|
||||
| View Object | controller/viewobject | 类 class | 将用户Model转化为可供UI使用的View Object | controller.UserController |
|
||||
| View Object (VO) | controller/viewobject | 类 class | 将用户Model转化为可供UI使用的View Object | controller.UserController |
|
||||
| | | | | |
|
||||
| **Service层** | 转换成业务模型 | | | |
|
||||
| Service | service | 接口 interface | | service.UserService |
|
||||
@ -28,7 +28,7 @@
|
||||
| **Dao层** | 对数据库的映射 | | | |
|
||||
| Mapper | dao | 接口 interface | | dao.UserDOMapper |
|
||||
| Mapping | resources/mapping | Mapper接口实现类 | xml格式;SQL语句 | mapping/UserDOMapper.xml |
|
||||
| Data Object | dataobject | 类 class | | dataobject.UserDO |
|
||||
| Data Object (DO) | dataobject | 类 class | | dataobject.UserDO |
|
||||
| | | | | |
|
||||
| **其他** | | | | |
|
||||
| response | response | | 用于处理HTTP请求返回 | response.CommonReturnType |
|
||||
@ -41,3 +41,27 @@
|
||||
| BusinessException | error | CommonError接口实现类 & 继承自Exception | | error.BusinessException |
|
||||
|
||||
**Tips:** Model与Data Object并非完全一一对应,例如UserModel是由ServiceImpl将UserDO和UserPasswordDO组装而成的。
|
||||
|
||||
|
||||
|
||||
代码构建顺序:
|
||||
|
||||
1. 创建Model模型(service/model)
|
||||
|
||||
2. 创建数据库中数据表
|
||||
|
||||
3. 使用mybatis-generator生成数据库映射文件(dao ; dataobject ; resources/mapping)
|
||||
|
||||
4. 创建Service接口(service)
|
||||
|
||||
5. 创建Service接口实现Impl(service/impl)(class打上 `Service` 标注;方法上打上 `@Transactional` 标签保证是在同一事务中)
|
||||
|
||||
6. 思考ServiceImpl中需要哪几步,并逐步实现
|
||||
|
||||
> - 如果需要修改自动生成的数据库语句,先改 resources/mapping 下的xml映射SQL语句,然后修改 dao 下的DOMapper接口
|
||||
>
|
||||
> - 可以用 `org.springframework.beans` 包中的 `BeanUtils.copyProperties` 进行DO转Model或Model转DO(要字段和类型完全一致的字段才能拷贝,其他不对应字段的需要手动设置)
|
||||
|
||||
7.
|
||||
|
||||
8. Service返回Controller前将DO
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.cxyxiaomo.flashsale.dao;
|
||||
|
||||
import com.cxyxiaomo.flashsale.dataobject.ItemStockDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface ItemStockDOMapper {
|
||||
/**
|
||||
@ -52,4 +53,6 @@ public interface ItemStockDOMapper {
|
||||
* @mbg.generated Thu Mar 03 13:12:13 CST 2022
|
||||
*/
|
||||
int updateByPrimaryKey(ItemStockDO record);
|
||||
|
||||
int decreaseStock(@Param("itemId") Integer itemId, @Param("amount") Integer amount);
|
||||
}
|
@ -1,13 +1,16 @@
|
||||
package com.cxyxiaomo.flashsale.error;
|
||||
|
||||
public enum EmBusinessError implements CommonError {
|
||||
// 通用错误类型 00001
|
||||
// 通用错误类型 10001
|
||||
PARAMETER_VALIDATION_ERROR(10001, "参数不合法"),
|
||||
UNKNOWN_ERROR(10002, "未知错误"),
|
||||
|
||||
// 10000开头为用户信息相关错误定义
|
||||
// 20000开头为用户信息相关错误定义
|
||||
USER_NOT_EXIST(20001, "用户不存在"),
|
||||
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确");
|
||||
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确"),
|
||||
|
||||
// 30000开头为交易信息错误定义
|
||||
STOCK_NOT_ENOUGH(30001, "库存不足");
|
||||
|
||||
private EmBusinessError(int errCode, String errMsg) {
|
||||
this.errCode = errCode;
|
||||
|
@ -14,4 +14,6 @@ public interface ItemService {
|
||||
|
||||
// 商品详情浏览
|
||||
ItemModel getItemById(Integer id);
|
||||
|
||||
boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException;
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package com.cxyxiaomo.flashsale.service;
|
||||
|
||||
import com.cxyxiaomo.flashsale.error.BusinessException;
|
||||
import com.cxyxiaomo.flashsale.service.model.OrderModel;
|
||||
|
||||
public interface OrderService {
|
||||
/**
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param itemId 购买商品
|
||||
* @param amount 购买商品数量
|
||||
* @return
|
||||
*/
|
||||
OrderModel createOrder(Integer userId, Integer itemId, Integer amount) throws BusinessException;
|
||||
}
|
@ -103,6 +103,19 @@ public class ItemServiceImpl implements ItemService {
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
|
||||
int affectedRow = itemStockDOMapper.decreaseStock(itemId, amount);
|
||||
if (affectedRow > 0) {
|
||||
// 更新库存成功
|
||||
return true;
|
||||
} else {
|
||||
// 更新库存失败
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private ItemModel convertModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
|
||||
ItemModel itemModel = new ItemModel();
|
||||
BeanUtils.copyProperties(itemDO, itemModel);
|
||||
|
@ -0,0 +1,95 @@
|
||||
package com.cxyxiaomo.flashsale.service.impl;
|
||||
|
||||
import com.cxyxiaomo.flashsale.dao.OrderDOMapper;
|
||||
import com.cxyxiaomo.flashsale.dataobject.OrderDO;
|
||||
import com.cxyxiaomo.flashsale.error.BusinessException;
|
||||
import com.cxyxiaomo.flashsale.error.EmBusinessError;
|
||||
import com.cxyxiaomo.flashsale.service.ItemService;
|
||||
import com.cxyxiaomo.flashsale.service.OrderService;
|
||||
import com.cxyxiaomo.flashsale.service.UserService;
|
||||
import com.cxyxiaomo.flashsale.service.model.ItemModel;
|
||||
import com.cxyxiaomo.flashsale.service.model.OrderModel;
|
||||
import com.cxyxiaomo.flashsale.service.model.UserModel;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private OrderDOMapper orderDOMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public OrderModel createOrder(Integer userId, Integer itemId, Integer amount) throws BusinessException {
|
||||
// 1. 校验下单状态
|
||||
// 下单的商品是否存在;用户是否合法;购买数量是否正确
|
||||
ItemModel itemModel = itemService.getItemById(itemId);
|
||||
if (itemModel == null) {
|
||||
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "商品信息不存在");
|
||||
}
|
||||
|
||||
UserModel userModel = userService.getUserById(userId);
|
||||
if (userModel == null) {
|
||||
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "用户信息不存在");
|
||||
}
|
||||
|
||||
if (amount <= 0 || amount > 99) {
|
||||
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "数量信息不正确");
|
||||
}
|
||||
|
||||
// 2. 落单减库存 / 支付减库存(有可能超卖)
|
||||
boolean result = itemService.decreaseStock(itemId, amount);
|
||||
if (!result) {
|
||||
throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
// 3. 订单入库
|
||||
OrderModel orderModel = new OrderModel();
|
||||
orderModel.setUserId(userId);
|
||||
orderModel.setItemId(itemId);
|
||||
orderModel.setAmount(amount);
|
||||
orderModel.setItemPrice(itemModel.getPrice());
|
||||
orderModel.setOrderPrice(itemModel.getPrice().multiply(new BigDecimal(amount)));
|
||||
|
||||
// 生成交易流水号,订单号
|
||||
|
||||
OrderDO orderDO = convertFromOrderModel(orderModel);
|
||||
orderDOMapper.insertSelective(orderDO);
|
||||
|
||||
// 4. 返回前端
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private OrderDO convertFromOrderModel(OrderModel orderModel) {
|
||||
if (orderModel == null) {
|
||||
return null;
|
||||
}
|
||||
OrderDO orderDO = new OrderDO();
|
||||
BeanUtils.copyProperties(orderModel, orderDO);
|
||||
|
||||
return orderDO;
|
||||
}
|
||||
|
||||
// 生成交易流水号,订单号
|
||||
private String generateOderNo(){
|
||||
// 订单号为16位
|
||||
// 前8位为时间信息(年月日)
|
||||
|
||||
// 中间6位为自增序列
|
||||
|
||||
// 最后2位为分库分表位
|
||||
|
||||
}
|
||||
}
|
@ -114,4 +114,10 @@
|
||||
from item_stock
|
||||
where item_id = #{itemId,jdbcType=INTEGER}
|
||||
</select>
|
||||
<update id="decreaseStock">
|
||||
update item_stock
|
||||
set stock = stock - #{amount},
|
||||
item_id = #{itemId}
|
||||
where item_id = #{itemId} and stock >= #{amount}
|
||||
</update>
|
||||
</mapper>
|
Loading…
Reference in New Issue
Block a user