mirror of
https://gitee.com/coder-xiaomo/flashsale
synced 2025-09-11 22:41:38 +08:00
交易下单1(未完成)
This commit is contained in:
28
README.md
28
README.md
@@ -18,7 +18,7 @@
|
|||||||
| ----------------- | --------------------- | --------------------------------------- | ---------------------------------------- | ------------------------------- |
|
| ----------------- | --------------------- | --------------------------------------- | ---------------------------------------- | ------------------------------- |
|
||||||
| **Controller层** | | | | |
|
| **Controller层** | | | | |
|
||||||
| Controller | controller | 类 class | | controller.UserController |
|
| 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 | service | 接口 interface | | service.UserService |
|
| Service | service | 接口 interface | | service.UserService |
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
| **Dao层** | 对数据库的映射 | | | |
|
| **Dao层** | 对数据库的映射 | | | |
|
||||||
| Mapper | dao | 接口 interface | | dao.UserDOMapper |
|
| Mapper | dao | 接口 interface | | dao.UserDOMapper |
|
||||||
| Mapping | resources/mapping | Mapper接口实现类 | xml格式;SQL语句 | mapping/UserDOMapper.xml |
|
| 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 |
|
| response | response | | 用于处理HTTP请求返回 | response.CommonReturnType |
|
||||||
@@ -41,3 +41,27 @@
|
|||||||
| BusinessException | error | CommonError接口实现类 & 继承自Exception | | error.BusinessException |
|
| BusinessException | error | CommonError接口实现类 & 继承自Exception | | error.BusinessException |
|
||||||
|
|
||||||
**Tips:** Model与Data Object并非完全一一对应,例如UserModel是由ServiceImpl将UserDO和UserPasswordDO组装而成的。
|
**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;
|
package com.cxyxiaomo.flashsale.dao;
|
||||||
|
|
||||||
import com.cxyxiaomo.flashsale.dataobject.ItemStockDO;
|
import com.cxyxiaomo.flashsale.dataobject.ItemStockDO;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
public interface ItemStockDOMapper {
|
public interface ItemStockDOMapper {
|
||||||
/**
|
/**
|
||||||
@@ -52,4 +53,6 @@ public interface ItemStockDOMapper {
|
|||||||
* @mbg.generated Thu Mar 03 13:12:13 CST 2022
|
* @mbg.generated Thu Mar 03 13:12:13 CST 2022
|
||||||
*/
|
*/
|
||||||
int updateByPrimaryKey(ItemStockDO record);
|
int updateByPrimaryKey(ItemStockDO record);
|
||||||
|
|
||||||
|
int decreaseStock(@Param("itemId") Integer itemId, @Param("amount") Integer amount);
|
||||||
}
|
}
|
@@ -1,13 +1,16 @@
|
|||||||
package com.cxyxiaomo.flashsale.error;
|
package com.cxyxiaomo.flashsale.error;
|
||||||
|
|
||||||
public enum EmBusinessError implements CommonError {
|
public enum EmBusinessError implements CommonError {
|
||||||
// 通用错误类型 00001
|
// 通用错误类型 10001
|
||||||
PARAMETER_VALIDATION_ERROR(10001, "参数不合法"),
|
PARAMETER_VALIDATION_ERROR(10001, "参数不合法"),
|
||||||
UNKNOWN_ERROR(10002, "未知错误"),
|
UNKNOWN_ERROR(10002, "未知错误"),
|
||||||
|
|
||||||
// 10000开头为用户信息相关错误定义
|
// 20000开头为用户信息相关错误定义
|
||||||
USER_NOT_EXIST(20001, "用户不存在"),
|
USER_NOT_EXIST(20001, "用户不存在"),
|
||||||
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确");
|
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确"),
|
||||||
|
|
||||||
|
// 30000开头为交易信息错误定义
|
||||||
|
STOCK_NOT_ENOUGH(30001, "库存不足");
|
||||||
|
|
||||||
private EmBusinessError(int errCode, String errMsg) {
|
private EmBusinessError(int errCode, String errMsg) {
|
||||||
this.errCode = errCode;
|
this.errCode = errCode;
|
||||||
|
@@ -14,4 +14,6 @@ public interface ItemService {
|
|||||||
|
|
||||||
// 商品详情浏览
|
// 商品详情浏览
|
||||||
ItemModel getItemById(Integer id);
|
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;
|
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) {
|
private ItemModel convertModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
|
||||||
ItemModel itemModel = new ItemModel();
|
ItemModel itemModel = new ItemModel();
|
||||||
BeanUtils.copyProperties(itemDO, 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
|
from item_stock
|
||||||
where item_id = #{itemId,jdbcType=INTEGER}
|
where item_id = #{itemId,jdbcType=INTEGER}
|
||||||
</select>
|
</select>
|
||||||
|
<update id="decreaseStock">
|
||||||
|
update item_stock
|
||||||
|
set stock = stock - #{amount},
|
||||||
|
item_id = #{itemId}
|
||||||
|
where item_id = #{itemId} and stock >= #{amount}
|
||||||
|
</update>
|
||||||
</mapper>
|
</mapper>
|
Reference in New Issue
Block a user