feat(oms): 业务单号改为yyMMdd+每日序号(每日重置,对齐TMS长度)

对应需求#072703,单号规则:年月日001,后面001每天重置
This commit is contained in:
rcx
2026-08-12 18:17:29 +08:00
parent df51abe33f
commit b37edf7c63
5 changed files with 79 additions and 112 deletions
@@ -37,4 +37,10 @@ public interface BusinessDocumentOrderMapper extends BaseMapper<BusinessDocument
TmsTransportNote getTmsTransportNote(@Param("tmsOrderId") String tmsOrderId);
String getPushVerifyByOrgId(@Param("organizationId") Long organizationId);
/**
* 统计指定日期前缀(yyMMdd)下已生成的新格式业务单号数量
* 仅统计新格式(长度<=12),过滤历史16位旧数据,保证序号每日从001正确累计
*/
int countByGoodsNumberPrefix(@Param("prefix") String prefix);
}
@@ -19,6 +19,7 @@ import com.mhd.oms.domain.businessDocumentOrder.repository.facade.IBusinessDocum
import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper;
import com.mhd.oms.domain.businessDocumentOrder.repository.po.BusinessDocumentOrderPO;
import com.mhd.oms.domain.businessDocumentOrder.repository.todo.BusinessDocumentOrderDO;
import com.mhd.oms.domain.businessDocumentOrder.service.GoodsNumberGenerator;
import com.mhd.oms.domain.executeOrder.entity.ExecuteOrder;
import com.mhd.oms.domain.executeOrder.repository.mapper.ExecuteOrderMapper;
import com.mhd.oms.domain.executeOrder.repository.todo.ExecuteOrderDO;
@@ -88,6 +89,9 @@ public class BusinessDocumentOrderImpl extends ServiceImpl<BusinessDocumentOrder
@Autowired
private WlhyServiceFeign wlhyServiceFeign;
@Autowired
private GoodsNumberGenerator goodsNumberGenerator;
/**
* 查询【请填写功能名称】列表
@@ -173,28 +177,6 @@ public class BusinessDocumentOrderImpl extends ServiceImpl<BusinessDocumentOrder
}
public static String getOrderCodeByDate(Date date){
return new StringBuffer()
.append(getSecondPartByDate(date))
.append(getThreePart())
.toString();
}
private static String getSecondPartByDate(Date date) {
if (date == null) {
date = new Date();
}
String temp_current_time = DateUtil.format(date, datePattern());
return temp_current_time.substring(2, temp_current_time.length());
}
private static String datePattern() {
return "yyyyMMddHHmmss";
}
private static String getThreePart() {
return RandomUtil.randomNumbers(4);
}
@Override
public Boolean audit(List<Long> ids, Long reviewStatus, String SalesManager,String reviewOpinion ) {
LoginUser loginUser = SecurityUtils.getLoginUser();//获取登录人
@@ -225,7 +207,6 @@ public class BusinessDocumentOrderImpl extends ServiceImpl<BusinessDocumentOrder
BeanUtils.copyProperties(businessDocumentOrder, subOrder);
subOrder.setId(null);
subOrder.setGoodsNumber(OrderSequence.getOrderCode()); // 生成新的子单号
// 设置子单的拼单类型和主单关系
subOrder.setSplicingOrderType(3L); // 合单-子单
@@ -255,31 +236,10 @@ public class BusinessDocumentOrderImpl extends ServiceImpl<BusinessDocumentOrder
subOrder.setRecipientName(user.getUserName());
String orderCode = null;
int maxRetryCount = 100;
int retryCount = 0;
while (retryCount < maxRetryCount) {
orderCode = getOrderCodeByDate(subOrder.getDocumentDate());
retryCount++;
List<BusinessDocumentOrder> checkOrderCodes = businessDocumentOrderMapper.selectList(
new QueryWrapper<BusinessDocumentOrder>().eq("goods_number", orderCode)
);
if (CollectionUtils.isEmpty(checkOrderCodes)) {
break;
}
if (retryCount >= maxRetryCount) {
throw new com.aliyun.oss.ServiceException("生成唯一订单编号失败,已达到最大重试次数:" + maxRetryCount);
}
}
//生成货源单号
//生成子单货源单号(yyMMdd + 当日顺序号)
String orderCode = goodsNumberGenerator.generateUniqueGoodsNumber(subOrder.getDocumentDate());
subOrder.setGoodsNumber(orderCode);
businessDocumentOrderMapper.insert(subOrder);
subOrderCount++; // 增加子单计数
@@ -102,6 +102,9 @@ public class BusinessDocumentOrderDomainService {
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
private GoodsNumberGenerator goodsNumberGenerator;
/**
* 分页查询【请填写功能名称】列表
*/
@@ -109,26 +112,6 @@ public class BusinessDocumentOrderDomainService {
return businessDocumentOrderService.queryList(businessDocumentOrderDO);
}
public static String getOrderCodeByDate(Date date){
return new StringBuffer()
.append(getSecondPartByDate(date))
.append(getThreePart())
.toString();
}
private static String getSecondPartByDate(Date date) {
if (date == null) {
date = new Date();
}
String temp_current_time = DateUtil.format(date, datePattern());
return temp_current_time.substring(2, temp_current_time.length());
}
private static String datePattern() {
return "yyyyMMddHHmmss";
}
private static String getThreePart() {
return RandomUtil.randomNumbers(4);
}
/**
* 新增【请填写功能名称】
*/
@@ -302,30 +285,8 @@ public class BusinessDocumentOrderDomainService {
}
}
//生成货源单号
String orderCode = null;
int maxRetryCount = 100;
int retryCount = 0;
while (retryCount < maxRetryCount) {
orderCode = getOrderCodeByDate(tmsOrder.getDocumentDate());
retryCount++;
List<BusinessDocumentOrder> checkOrderCodes = businessDocumentOrderMapper.selectList(
new QueryWrapper<BusinessDocumentOrder>().eq("goods_number", orderCode)
);
if (CollectionUtils.isEmpty(checkOrderCodes)) {
break;
}
if (retryCount >= maxRetryCount) {
throw new ServiceException("生成唯一订单编号失败,已达到最大重试次数:" + maxRetryCount);
}
}
//生成货源单号
//生成货源单号(yyMMdd + 当日顺序号,每日重置)
String orderCode = goodsNumberGenerator.generateUniqueGoodsNumber(tmsOrder.getDocumentDate());
tmsOrder.setGoodsNumber(orderCode);
ReservationStockOutOrder reservationStockOutOrder = reservationStockOutOrderMapper.selectOne(new LambdaQueryWrapper<ReservationStockOutOrder>()
@@ -774,28 +735,8 @@ public class BusinessDocumentOrderDomainService {
// boolean istrue=businessDocumentOrderService.update(businessDocumentOrderDO);
String orderCode = null;
int maxRetryCount = 100;
int retryCount = 0;
while (retryCount < maxRetryCount) {
orderCode = getOrderCodeByDate(tmsOrder.getDocumentDate());
retryCount++;
List<BusinessDocumentOrder> checkOrderCodes = businessDocumentOrderMapper.selectList(
new QueryWrapper<BusinessDocumentOrder>().eq("goods_number", orderCode)
);
if (CollectionUtils.isEmpty(checkOrderCodes)) {
break;
}
if (retryCount >= maxRetryCount) {
throw new ServiceException("生成唯一订单编号失败,已达到最大重试次数:" + maxRetryCount);
}
}
//生成货源单号
//生成货源单号(yyMMdd + 当日顺序号,每日重置) 原更新操作会将 电脑更细为当日的日期。默认和之前的逻辑一样保持不变
String orderCode = goodsNumberGenerator.generateUniqueGoodsNumber(tmsOrder.getDocumentDate());
tmsOrder.setGoodsNumber(orderCode);
ReservationStockOutOrder reservationStockOutOrder = reservationStockOutOrderMapper.selectOne(new LambdaQueryWrapper<ReservationStockOutOrder>()
@@ -0,0 +1,53 @@
package com.mhd.oms.domain.businessDocumentOrder.service;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder;
import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
/**
* 业务单据订单(goodsNumber)单号生成器
* 规则: yyMMdd(取自单据日期) + 当日顺序号(每日重置, 3位起步, 超999自动扩位)
* 示例: 260804001、260804999、2608041000
*/
@Component
public class GoodsNumberGenerator {
private static final int MAX_RETRY = 100;
@Autowired
private BusinessDocumentOrderMapper businessDocumentOrderMapper;
/**
* 生成唯一业务单号
* @param documentDate 单据日期(为空取当前日期)
*/
public String generateUniqueGoodsNumber(Date documentDate) {
Date date = (documentDate == null) ? new Date() : documentDate;
String datePart = DateUtil.format(date, "yyMMdd");
// count 只查一次作为序号基线
long seq = (long) businessDocumentOrderMapper.countByGoodsNumberPrefix(datePart) + 1;
int retryCount = 0;
while (retryCount < MAX_RETRY) {
String orderCode = datePart + String.format("%03d", seq);
retryCount++;
List<BusinessDocumentOrder> exist = businessDocumentOrderMapper.selectList(
new QueryWrapper<BusinessDocumentOrder>().eq("goods_number", orderCode)
);
if (CollectionUtils.isEmpty(exist)) {
return orderCode;
}
seq++; // ← 关键:查重失败,序号往后递增找空位,而不是重新count
}
throw new ServiceException("生成唯一业务单号失败,已达到最大重试次数:" + MAX_RETRY);
}
}
@@ -1272,4 +1272,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select PUSH_VERIFY from NGWL_TEST_PRODUCT.SYS_ORGANIZATION where ORGANIZATION_ID = #{organizationId}
</select>
<select id="countByGoodsNumberPrefix" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM business_document_order
WHERE goods_number LIKE concat(#{prefix}, '%')
AND LENGTH(goods_number) &lt;= 12
</select>
</mapper>