Commit f6d3290426fce784dded91579775a5af244208e0

Authored by YunaiV
1 parent 593e1fd5

✨ ERP:增加入库单号的自动生成

yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
@@ -25,7 +25,7 @@ public interface ErrorCodeConstants { @@ -25,7 +25,7 @@ public interface ErrorCodeConstants {
25 ErrorCode STOCK_IN_DELETE_FAIL_APPROVE = new ErrorCode(1_030_401_001, "其它入库单({})已审核,无法删除"); 25 ErrorCode STOCK_IN_DELETE_FAIL_APPROVE = new ErrorCode(1_030_401_001, "其它入库单({})已审核,无法删除");
26 ErrorCode STOCK_IN_PROCESS_FAIL = new ErrorCode(1_030_401_002, "反审核失败,只有已审核的入库单才能反审核"); 26 ErrorCode STOCK_IN_PROCESS_FAIL = new ErrorCode(1_030_401_002, "反审核失败,只有已审核的入库单才能反审核");
27 ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核"); 27 ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核");
28 - 28 + ErrorCode STOCK_IN_NO_EXISTS = new ErrorCode(1_030_401_004, "生成入库单失败,请重新提交");
29 29
30 // ========== ERP 产品 1-030-500-000 ========== 30 // ========== ERP 产品 1-030-500-000 ==========
31 ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在"); 31 ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在");
yudao-module-erp/yudao-module-erp-biz/pom.xml
@@ -51,6 +51,11 @@ @@ -51,6 +51,11 @@
51 <artifactId>yudao-spring-boot-starter-mybatis</artifactId> 51 <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
52 </dependency> 52 </dependency>
53 53
  54 + <dependency>
  55 + <groupId>cn.iocoder.boot</groupId>
  56 + <artifactId>yudao-spring-boot-starter-redis</artifactId>
  57 + </dependency>
  58 +
54 <!-- 工具类相关 --> 59 <!-- 工具类相关 -->
55 <dependency> 60 <dependency>
56 <groupId>cn.iocoder.boot</groupId> 61 <groupId>cn.iocoder.boot</groupId>
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java
@@ -17,10 +17,6 @@ public class ErpStockInSaveReqVO { @@ -17,10 +17,6 @@ public class ErpStockInSaveReqVO {
17 @Schema(description = "入库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") 17 @Schema(description = "入库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
18 private Long id; 18 private Long id;
19 19
20 - @Schema(description = "入库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "S123")  
21 - @NotEmpty(message = "入库单号不能为空")  
22 - private String no;  
23 -  
24 @Schema(description = "供应商编号", example = "3113") 20 @Schema(description = "供应商编号", example = "3113")
25 private Long supplierId; 21 private Long supplierId;
26 22
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInMapper.java
@@ -40,4 +40,8 @@ public interface ErpStockInMapper extends BaseMapperX&lt;ErpStockInDO&gt; { @@ -40,4 +40,8 @@ public interface ErpStockInMapper extends BaseMapperX&lt;ErpStockInDO&gt; {
40 .eq(ErpStockInDO::getId, id).eq(ErpStockInDO::getStatus, status)); 40 .eq(ErpStockInDO::getId, id).eq(ErpStockInDO::getStatus, status));
41 } 41 }
42 42
  43 + default ErpStockInDO selectByNo(String no) {
  44 + return selectOne(ErpStockInDO::getNo, no);
  45 + }
  46 +
43 } 47 }
44 \ No newline at end of file 48 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/RedisKeyConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.redis;
  2 +
  3 +/**
  4 + * ERP Redis Key 枚举类
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface RedisKeyConstants {
  9 +
  10 + /**
  11 + * 序号的缓存
  12 + *
  13 + * KEY 格式:trade_no:{prefix}
  14 + * VALUE 数据格式:编号自增
  15 + */
  16 + String NO = "seq_no:";
  17 +
  18 +}
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.redis.no;
  2 +
  3 +import cn.hutool.core.date.DatePattern;
  4 +import cn.hutool.core.date.DateUtil;
  5 +import cn.iocoder.yudao.module.erp.dal.redis.RedisKeyConstants;
  6 +import jakarta.annotation.Resource;
  7 +import org.springframework.data.redis.core.StringRedisTemplate;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +import java.time.Duration;
  11 +import java.time.LocalDateTime;
  12 +
  13 +
  14 +/**
  15 + * 订单序号的 Redis DAO
  16 + *
  17 + * @author HUIHUI
  18 + */
  19 +@Repository
  20 +public class ErpNoRedisDAO {
  21 +
  22 + /**
  23 + * 其它入库 STOCK_IN
  24 + */
  25 + public static final String STOCK_IN_NO_PREFIX = "QTRK";
  26 +
  27 + @Resource
  28 + private StringRedisTemplate stringRedisTemplate;
  29 +
  30 + /**
  31 + * 生成序号,使用当前日期,格式为 {PREFIX} + yyyyMMdd + 6 位自增
  32 + * 例如说:QTRK 202109 000001 (没有中间空格)
  33 + *
  34 + * @param prefix 前缀
  35 + * @return 序号
  36 + */
  37 + public String generate(String prefix) {
  38 + // 递增序号
  39 + String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
  40 + String key = RedisKeyConstants.NO + noPrefix;
  41 + Long no = stringRedisTemplate.opsForValue().increment(key);
  42 + // 设置过期时间
  43 + stringRedisTemplate.expire(key, Duration.ofMinutes(1L));
  44 + return noPrefix + String.format("%06d", no);
  45 + }
  46 +
  47 +}
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
11 import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; 11 import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
12 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper; 12 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper;
13 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper; 13 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper;
  14 +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
14 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; 15 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
15 import cn.iocoder.yudao.module.erp.service.product.ErpProductService; 16 import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
16 import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; 17 import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
@@ -45,6 +46,9 @@ public class ErpStockInServiceImpl implements ErpStockInService { @@ -45,6 +46,9 @@ public class ErpStockInServiceImpl implements ErpStockInService {
45 private ErpStockInItemMapper stockInItemMapper; 46 private ErpStockInItemMapper stockInItemMapper;
46 47
47 @Resource 48 @Resource
  49 + private ErpNoRedisDAO noRedisDAO;
  50 +
  51 + @Resource
48 private ErpProductService productService; 52 private ErpProductService productService;
49 @Resource 53 @Resource
50 private ErpWarehouseService warehouseService; 54 private ErpWarehouseService warehouseService;
@@ -58,10 +62,15 @@ public class ErpStockInServiceImpl implements ErpStockInService { @@ -58,10 +62,15 @@ public class ErpStockInServiceImpl implements ErpStockInService {
58 List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems()); 62 List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems());
59 // 1.2 校验供应商 63 // 1.2 校验供应商
60 supplierService.validateSupplier(createReqVO.getSupplierId()); 64 supplierService.validateSupplier(createReqVO.getSupplierId());
  65 + // 1.3
  66 + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_IN_NO_PREFIX);
  67 + if (stockInMapper.selectByNo(no) != null) {
  68 + throw exception(STOCK_IN_NO_EXISTS);
  69 + }
61 70
62 // 2.1 插入入库单 71 // 2.1 插入入库单
63 ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in 72 ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in
64 - .setStatus(ErpAuditStatus.PROCESS.getStatus()) 73 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
65 .setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add)) 74 .setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add))
66 .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); 75 .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
67 stockInMapper.insert(stockIn); 76 stockInMapper.insert(stockIn);