1
0
mirror of https://gitee.com/coder-xiaomo/flashsale synced 2025-01-10 11:48:14 +08:00
Code Issues Projects Releases Wiki Activity GitHub Gitee

交易下单1(未完成)

This commit is contained in:
程序员小墨 2022-03-03 22:59:32 +08:00
parent 640105972e
commit d44db6d5be
8 changed files with 166 additions and 5 deletions

View File

@ -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接口实现Implservice/implclass打上 `Service` 标注;方法上打上 `@Transactional` 标签保证是在同一事务中)
6. 思考ServiceImpl中需要哪几步并逐步实现
> - 如果需要修改自动生成的数据库语句,先改 resources/mapping 下的xml映射SQL语句然后修改 dao 下的DOMapper接口
>
> - 可以用 `org.springframework.beans` 包中的 `BeanUtils.copyProperties` 进行DO转Model或Model转DO要字段和类型完全一致的字段才能拷贝其他不对应字段的需要手动设置
7.
8. Service返回Controller前将DO

View File

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

View File

@ -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;

View File

@ -14,4 +14,6 @@ public interface ItemService {
// 商品详情浏览
ItemModel getItemById(Integer id);
boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException;
}

View File

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

View File

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

View File

@ -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位为分库分表位
}
}

View File

@ -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>