Browse Source

维多利亚

home 2 years ago
parent
commit
fd7acf5745

+ 18 - 0
hx-service-api/victoriatourist-api/src/main/java/com/fjhx/constants/StockJournalTypeConstant.java

@@ -0,0 +1,18 @@
+package com.fjhx.constants;
+
+/**
+ * 出入库类型
+ */
+public interface StockJournalTypeConstant {
+
+    /**
+     * 出库
+     */
+    Integer OUT = 0;
+
+    /**
+     * 入库
+     */
+    Integer IN = 1;
+
+}

+ 19 - 0
hx-service-api/victoriatourist-api/src/main/java/com/fjhx/constants/VLockConstant.java

@@ -0,0 +1,19 @@
+package com.fjhx.constants;
+
+/**
+ * 锁常量
+ */
+public interface VLockConstant {
+
+    /**
+     * 添加前缀,防止其他模块出现共用一把锁的情况
+     */
+    String PREFIX = "library-storage-";
+
+    /**
+     * 保证库存物品数量准确
+     */
+    String STOCK_LOCK = PREFIX + "stock-lock-";
+
+
+}

+ 13 - 0
hx-service/victoriatourist/src/main/java/com/fjhx/service/stock/StockJournalService.java

@@ -5,6 +5,7 @@ import com.fjhx.entity.stock.StockJournal;
 import com.fjhx.params.stock.StockJournalVo;
 import com.fjhx.base.BaseService;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 /**
@@ -25,4 +26,16 @@ public interface StockJournalService extends BaseService<StockJournal> {
 
     void delete(StockJournalVo stockJournalVo);
 
+    /**
+     * 添加流水记录
+     *
+     * @param type           出入库类型 0出库 1入库
+     * @param detailsType    详细类型
+     * @param goodsId        物品id
+     * @param warehouseId    仓库id
+     * @param changeQuantity 变更数量
+     * @param remarks        备注
+     */
+    void add(Integer type, Integer detailsType, Long goodsId, Long warehouseId, BigDecimal changeQuantity, String remarks);
+
 }

+ 13 - 0
hx-service/victoriatourist/src/main/java/com/fjhx/service/stock/StockService.java

@@ -5,6 +5,7 @@ import com.fjhx.entity.stock.Stock;
 import com.fjhx.params.stock.StockVo;
 import com.fjhx.base.BaseService;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 /**
@@ -25,4 +26,16 @@ public interface StockService extends BaseService<Stock> {
 
     void delete(StockVo stockVo);
 
+    /**
+     * 变更数量
+     * 入库正数,出库负数
+     *
+     * @param goodsId     物品id
+     * @param warehouseId 仓库id
+     * @param quantity    数量
+     * @param detailsType 出入库详细类型
+     * @param remarks     备注
+     */
+    void changeQuantity(Long goodsId, Long warehouseId, BigDecimal quantity, Integer detailsType, String remarks);
+
 }

+ 13 - 0
hx-service/victoriatourist/src/main/java/com/fjhx/service/stock/impl/StockJournalServiceImpl.java

@@ -11,6 +11,7 @@ import com.fjhx.service.stock.StockJournalService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 /**
@@ -51,4 +52,16 @@ public class StockJournalServiceImpl extends ServiceImpl<StockJournalMapper, Sto
         removeById(stockJournalVo.getId());
     }
 
+    @Override
+    public void add(Integer type, Integer detailsType, Long goodsId, Long warehouseId, BigDecimal changeQuantity, String remarks) {
+        StockJournal stockJournal = new StockJournal();
+        stockJournal.setType(type);
+        stockJournal.setDetailsType(detailsType);
+        stockJournal.setGoodsId(goodsId);
+        stockJournal.setWarehouseId(warehouseId);
+        stockJournal.setChangeQuantity(changeQuantity);
+        stockJournal.setRemarks(remarks);
+        save(stockJournal);
+    }
+
 }

+ 62 - 0
hx-service/victoriatourist/src/main/java/com/fjhx/service/stock/impl/StockServiceImpl.java

@@ -4,13 +4,24 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.constants.ErrorMsgConstant;
+import com.fjhx.constants.StockJournalTypeConstant;
+import com.fjhx.constants.VLockConstant;
 import com.fjhx.entity.stock.Stock;
 import com.fjhx.mapper.stock.StockMapper;
 import com.fjhx.params.stock.StockVo;
 import com.fjhx.service.stock.StockService;
+import com.fjhx.utils.Assert;
 import com.fjhx.utils.WrapperUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.redis.lock.RedisLockClient;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.Map;
 
 /**
@@ -24,6 +35,12 @@ import java.util.Map;
 @Service
 public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements StockService {
 
+    @Resource
+    private RedisLockClient redisLockClient;
+
+    @Autowired
+    private StockJournalServiceImpl stockJournalService;
+
     @Override
     public Page<Stock> getPage(Map<String, Object> condition) {
 
@@ -51,4 +68,49 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
         removeById(stockVo.getId());
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void changeQuantity(Long goodsId, Long warehouseId, BigDecimal quantity, Integer detailsType, String remarks) {
+        // 分布式锁,粒度为物品id + 仓库id
+        Boolean flag = redisLockClient.lockFair(VLockConstant.STOCK_LOCK + goodsId + warehouseId,
+                () -> {
+                    Stock stock = getOne(Wrappers.<Stock>lambdaQuery()
+                            .eq(Stock::getGoodsId, goodsId)
+                            .eq(Stock::getWarehouseId, warehouseId));
+
+                    // 没有物料存储记录,则创建物料
+                    if (stock == null) {
+                        stock = new Stock();
+                        stock.setGoodsId(goodsId);
+                        stock.setQuantity(quantity);
+                        stock.setWarehouseId(warehouseId);
+                        stock.setTenantId(AuthUtil.getTenantId());
+                        return save(stock);
+                    }
+
+                    BigDecimal newQuantity = stock.getQuantity().add(quantity);
+
+                    int compareTo = newQuantity.compareTo(BigDecimal.ZERO);
+                    if (compareTo < 0) {
+                        throw new ServiceException("库存不足,出库失败");
+                    }
+
+                    stock.setQuantity(newQuantity);
+                    return updateById(stock);
+                });
+
+        Assert.eqTrue(flag, ErrorMsgConstant.SYSTEM_BUSY_ERROR);
+
+
+        // 添加出入库明细
+        stockJournalService.add(
+                quantity.compareTo(BigDecimal.ZERO) > 0 ? StockJournalTypeConstant.IN : StockJournalTypeConstant.OUT,
+                detailsType,
+                goodsId,
+                warehouseId,
+                quantity.compareTo(BigDecimal.ZERO) > 0 ? quantity : BigDecimal.ZERO.subtract(quantity),
+                remarks
+        );
+    }
+
 }

+ 7 - 5
hx-service/victoriatourist/src/main/java/com/fjhx/uitl/code/CodeEnum.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.fjhx.service.material.MaterialService;
 import com.fjhx.service.product.ProductSpuService;
 import com.fjhx.service.supplier.SupplierService;
+import com.fjhx.utils.Assert;
 import lombok.Getter;
 
 import java.util.Date;
@@ -20,7 +21,7 @@ public enum CodeEnum {
     SUPPLIER("GY", null, "code", 5, SupplierService.class),
     // 物料code
     MATERIAL("M", null, "code", 5, MaterialService.class),
-    // 物料code
+    // spu code
     SPU("SPU", null, "code", 5, ProductSpuService.class);
 
     CodeEnum(String prefix, String dateFormat, String codeFieldName, Integer length, Class<? extends IService<?>> serviceCls) {
@@ -63,22 +64,23 @@ public enum CodeEnum {
                 .one();
 
         if (obj == null) {
-            return itemPrefix + autoGenericCode(0, length);
+            return itemPrefix + autoGenericCode(length, 0);
         }
 
         Map<String, Object> map = Convert.toMap(String.class, Object.class, obj);
 
         String code = Convert.toStr(map.get(codeFieldName));
         Integer codeNum = Convert.toInt(code.substring(itemPrefix.length()));
+        Assert.notEmpty(codeNum, "自定义编码与系统编码生成规则冲突,暂时无法生成编码,请联系管理员");
 
-        return itemPrefix + autoGenericCode(codeNum, length);
+        return itemPrefix + autoGenericCode(length, codeNum);
     }
 
     /**
      * 不够位数的在前面补0,保留num的长度位数字
      */
-    private static String autoGenericCode(Integer code, int num) {
-        return String.format("%0" + num + "d", code + 1);
+    private static String autoGenericCode(int length, Integer codeNum) {
+        return String.format("%0" + length + "d", codeNum + 1);
     }
 
 }