首先创建交易模型,然后根据模型创建表,生成实体。然后创建service,写创建订单的方法。
创建订单
1校验下单状态 商品存在?用户合法?购买数量正确?
@Override
public ItemModel getItemById(Integer id) {
ItemDO itemDO = itemDOMapper.selectByPrimaryKey(id);
if (itemDO==null){
return null;
}
ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
ItemModel itemModel = convertItemModelFromItemDO(itemDO,itemStockDO);
return itemModel;
}
@Override
public UserModel getUserById(Integer id) {
userDO userDO = userDOMapper.selectByPrimaryKey(id);
if (userDO == null){
return null;
}
UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(id);
return converFronDataObject(userDO,userPasswordDO);
}
2落单减库存(下单就锁库存),支付减库存(支付才去减库存)这里使用落单减库存
在itemservice中创建一个减库存的方法decreaseStock,接收商品id和数量的参数。然后在库存的mapper.xml中新增
<update id="decreaseStock">
update item_stock
set stock = stock - #{amount}
where item_id = #{itemId} and stock >= #{amount}
</update>
ItemStockDOMapper.Java中
int decreaseStock(@Param("itemId") Integer itemId,@Param("amount") Integer amount);
然后在decreaseStock中调用itemStockDOMapper的decreaseStock,接收返回值,根据返回值来确定修改结果
@Override
public boolean decreaseStock(Integer itemId,Integer amount) throws BusinessException {
int affectedRow = itemStockDOMapper.decreaseStock(itemId,amount);
if (affectedRow>0){
return true;
}else {
return false;
}
}
3.生成交易流水号
自增序列:在数据库中建一张表,包含name,currentValue,step。step是步长。在使用时每次都根据name来取对应的currentValue,并且取出来之后要更新currentValue,使它加上它的一个步长,这样就可以保证每次的自增序列不会重复
根据name获取tSequence:
<select id="getSequenceByName" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sequence_info
where name = #{name,jdbcType=VARCHAR} for update
</select>
生成流水号:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public String generateOderNo(){
//订单号16位
StringBuilder stringBuilder = new StringBuilder();
//前8位是年月日
LocalDateTime now = LocalDateTime.now();
String nowDate = now.format(DateTimeFormatter.ISO_DATE).replace("-","");
stringBuilder.append(nowDate);
//中间6位为自增序列
int sequence = 0;
SequenceDO sequenceDO = sequenceDOMapper.getSequenceByName("order_info");
sequence = sequenceDO.getCurrentValue();
sequenceDO.setCurrentValue(sequenceDO.getCurrentValue()+sequenceDO.getStep());
sequenceDOMapper.updateByPrimaryKeySelective(sequenceDO);
String sequencestr = String.valueOf(sequence);
for (int i=0;i<6-sequencestr.length();i++){
stringBuilder.append(0);
}
stringBuilder.append(sequencestr);
//最后2位为分库分表位 暂时写死
stringBuilder.append("00");
return stringBuilder.toString();
}
private OrderInfoDO convertDOFromModel(orderModel orderModel){
if (orderModel==null){
return null;
}
OrderInfoDO orderInfoDO = new OrderInfoDO();
orderInfoDO.setId(orderModel.getId());
orderInfoDO.setAmount(orderModel.getAmount());
orderInfoDO.setItemid(orderModel.getItemId());
orderInfoDO.setItemprice(orderModel.getItemPrice().doubleValue());
orderInfoDO.setOrderprice(orderModel.getOrderPrice().doubleValue());
orderInfoDO.setUserid(orderModel.getUserId());
return orderInfoDO;
}
4订单入库
5加上商品销量
在xml中增加一个方法然后在itemservice中调用
<update id="increaseSales" parameterType="com.miaosha3.dataobject.ItemDO">
update item
set sales = sales + #{amount},
where id = #{id,jdbcType=INTEGER}
</update>
@Override
@Transactional
public void increaseSales(Integer itemId, Integer amount) {
itemDOMapper.increaseSales(itemId,amount);
}
6返回前端
@Override
@Transactional
public orderModel createOrder(Integer userId, Integer itemId, Integer amount) throws BusinessException {
//校验下单状态 商品存在?用户合法?购买数量正确?
ItemModel itemModel = itemService.getItemById(itemId);
if (itemModel==null){
throw new BusinessException(EmBusinessError.PAEAMETER_VALIDATION_ERROR,"商品信息不合法");
}
if (itemModel.getStock()<amount){
throw new BusinessException(EmBusinessError.PAEAMETER_VALIDATION_ERROR,"商品数量不足");
}
UserModel userModel = userService.getUserById(userId);
if (userModel==null){
throw new BusinessException(EmBusinessError.PAEAMETER_VALIDATION_ERROR,"用户信息不存在");
}
if (amount <= 0 ||amount > 99){
throw new BusinessException(EmBusinessError.PAEAMETER_VALIDATION_ERROR,"数量信息不正确");
}
//落单减库存(下单就锁库存),支付减库存(支付才去减库存)这里使用落单减库存
boolean result = itemService.decreaseStock(itemId,amount);
if (!result){
throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH);
}
//订单入库
orderModel orderModel = new orderModel();
orderModel.setUserId(userId);
orderModel.setItemId(itemId);
orderModel.setAmount(amount);
orderModel.setItemPrice(itemModel.getPrice());
orderModel.setOrderPrice(orderModel.getItemPrice().multiply(
new BigDecimal(amount)
));
//生成交易流水号
orderModel.setId(generateOderNo());
OrderInfoDO orderInfoDO = convertDOFromModel(orderModel);
orderInfoDOMapper.insertSelective(orderInfoDO);
//加上商品销量
itemService.increaseSales(itemId,amount);
//返回前端
return null;
}
封装下单请求
在控制器接收请求,在封装请求调用service
@RequestMapping(value = "/createorder",method = {RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType createOrder(@RequestParam(name = "itemId")Integer itemId,
@RequestParam(name = "amount")Integer amount) throws BusinessException {
//获取用户登录信息
Boolean isLogin = (Boolean) httpServletRequest.getSession().getAttribute("IS_LOGIN");//登录成功保存的session
if (isLogin == null || !isLogin.booleanValue()){
throw new BusinessException(EmBusinessError.NOT_LOGIN);
}
UserModel userModel = (UserModel) httpServletRequest.getSession().getAttribute("LOGIN_USER");
orderModel orderModel = orderService.createOrder(userModel.getId(),itemId,amount);
return CommonReturnType.create(null);
}