| | |
| | | |
| | | import java.time.Duration; |
| | | import java.time.LocalDateTime; |
| | | import java.util.function.Predicate; |
| | | |
| | | |
| | | /** |
| | |
| | | return noPrefix + String.format("%06d", no); |
| | | } |
| | | |
| | | /** |
| | | * 生成序号,并跳过已存在的单号。 |
| | | * |
| | | * Redis 中的自增计数一旦丢失(如 Redis 重启未持久化、手工清库),计数会从 1 重新开始, |
| | | * 而当天数据库中可能已有同日期后缀的单号,此时逐个递增重试直到取到未占用的序号。 |
| | | * |
| | | * @param prefix 前缀 |
| | | * @param isNoExists 单号是否已存在 |
| | | * @return 未占用的序号 |
| | | */ |
| | | public String generate(String prefix, Predicate<String> isNoExists) { |
| | | for (int i = 0; i < MAX_GENERATE_ATTEMPTS; i++) { |
| | | String no = generate(prefix); |
| | | if (!isNoExists.test(no)) { |
| | | return no; |
| | | } |
| | | } |
| | | throw new IllegalStateException("生成单号失败:连续 " + MAX_GENERATE_ATTEMPTS + " 次尝试均已被占用,请稍后重试"); |
| | | } |
| | | |
| | | private static final int MAX_GENERATE_ATTEMPTS = 10000; |
| | | |
| | | } |