PmsSkuServiceImpl.java 4.0 KB
Newer Older
H
hxrui 已提交
1 2
package com.youlai.mall.pms.service.impl;

H
haoxr 已提交
3 4
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
H
haoxr 已提交
5
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
H
hxrui 已提交
6 7
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.common.web.exception.BizException;
H
haoxr 已提交
8
import com.youlai.mall.pms.common.constant.PmsConstants;
H
haoxr 已提交
9 10
import com.youlai.mall.pms.mapper.PmsSkuMapper;
import com.youlai.mall.pms.pojo.domain.PmsSku;
H
haoxr 已提交
11
import com.youlai.mall.pms.pojo.dto.SkuDTO;
H
haoxr 已提交
12
import com.youlai.mall.pms.pojo.dto.InventoryDTO;
H
haoxr 已提交
13
import com.youlai.mall.pms.service.IPmsSkuService;
H
haoxr 已提交
14
import lombok.AllArgsConstructor;
H
hxrui 已提交
15
import lombok.extern.slf4j.Slf4j;
H
haoxr 已提交
16
import org.springframework.data.redis.core.RedisTemplate;
H
hxrui 已提交
17 18 19 20 21 22 23
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
H
haoxr 已提交
24
@AllArgsConstructor
H
haoxr 已提交
25
public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> implements IPmsSkuService {
H
hxrui 已提交
26

H
haoxr 已提交
27 28 29

    private RedisTemplate redisTemplate;

H
hxrui 已提交
30 31
    @Override
    @Transactional(rollbackFor = Exception.class)
H
haoxr 已提交
32
    public boolean lockStock(List<InventoryDTO> inventories) {
H
haoxr 已提交
33 34 35
        log.info("锁定库存: {}", inventories);

        inventories.forEach(item -> {
H
haoxr 已提交
36
            boolean result = this.update(new LambdaUpdateWrapper<PmsSku>()
H
haoxr 已提交
37
                    .eq(PmsSku::getId, item.getSkuId())
H
haoxr 已提交
38
                    .apply("stock >= locked_inventory + {0}", item.getCount())
H
haoxr 已提交
39
                    .setSql("locked_inventory = locked_inventory + " + item.getCount())
H
haoxr 已提交
40 41
            );
            if (!result) {
H
haoxr 已提交
42
                throw new BizException("锁定库存失败,库存ID:" + item.getSkuId() + ",数量:" + item.getCount());
H
hxrui 已提交
43
            }
H
haoxr 已提交
44 45
        });

H
hxrui 已提交
46 47 48 49
        return true;
    }

    @Override
H
haoxr 已提交
50
    public boolean unlockStock(List<InventoryDTO> inventories) {
H
haoxr 已提交
51
        inventories.forEach(item -> {
H
haoxr 已提交
52
            boolean result = this.update(new LambdaUpdateWrapper<PmsSku>()
H
haoxr 已提交
53
                    .eq(PmsSku::getId, item.getSkuId())
H
haoxr 已提交
54
                    .setSql("locked_inventory = locked_inventory - " + item.getCount())
H
haoxr 已提交
55 56
            );
            if (!result) {
H
haoxr 已提交
57
                throw new BizException("解锁库存失败,库存ID:" + item.getSkuId() + ",数量:" + item.getCount());
H
hxrui 已提交
58
            }
H
haoxr 已提交
59
        });
H
hxrui 已提交
60 61
        return true;
    }
H
haoxr 已提交
62 63


H
haoxr 已提交
64
    @Override
H
haoxr 已提交
65
    public boolean deductStock(List<InventoryDTO> inventories) {
H
haoxr 已提交
66 67 68 69
        inventories.forEach(item -> {
            boolean result = this.update(new LambdaUpdateWrapper<PmsSku>()
                    .eq(PmsSku::getId, item.getSkuId())
                    .setSql("locked_inventory = locked_inventory - " + item.getCount())
H
haoxr 已提交
70
                    .setSql("stock = stock - " + item.getCount())
H
haoxr 已提交
71 72 73 74 75 76 77 78 79
            );
            if (!result) {
                throw new BizException("扣减库存失败");
            }
        });
        return false;
    }


H
haoxr 已提交
80 81 82 83
    /**
     * Cache-Aside pattern 缓存、数据库读写模式
     * 1. 读取数据,先读缓存,没有就去读数据库,然后将结果写入缓存
     * 2. 写入数据,先更新数据库,再删除缓存
H
haoxr 已提交
84
     *
H
haoxr 已提交
85
     * @param id 库存ID
H
haoxr 已提交
86 87 88
     * @return
     */
    @Override
H
haoxr 已提交
89 90
    public Integer getStockById(Long id) {
        Integer stock = 0;
H
haoxr 已提交
91
        // 读->缓存
H
haoxr 已提交
92
        Object cacheVal = redisTemplate.opsForValue().get(PmsConstants.PRODUCT_INVENTORY_PREFIX + id);
H
haoxr 已提交
93
        if (cacheVal != null) {
H
haoxr 已提交
94 95
            stock = Convert.toInt(cacheVal);
            return stock;
H
haoxr 已提交
96 97 98
        }

        // 读->数据库
H
haoxr 已提交
99 100 101
        PmsSku pmsSku = this.getOne(new LambdaQueryWrapper<PmsSku>()
                .eq(PmsSku::getId, id)
                .select(PmsSku::getInventory));
H
haoxr 已提交
102

H
haoxr 已提交
103
        if (pmsSku != null) {
H
haoxr 已提交
104
            stock = pmsSku.getInventory();
H
haoxr 已提交
105
            // 写->缓存
H
haoxr 已提交
106
            redisTemplate.opsForValue().set(PmsConstants.PRODUCT_INVENTORY_PREFIX + id, stock);
H
haoxr 已提交
107 108
        }

H
haoxr 已提交
109
        return stock;
H
haoxr 已提交
110 111

    }
H
haoxr 已提交
112 113

    @Override
H
haoxr 已提交
114 115
    public List<SkuDTO> listBySkuIds(List<Long> ids) {
        return this.baseMapper.listBySkuIds(ids);
H
haoxr 已提交
116
    }
H
haoxr 已提交
117 118


H
hxrui 已提交
119
}