package com.glxp.api.util; import com.glxp.api.constant.Constant; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Random; @Service public class GennerOrderUtils { @Resource RedisUtil redisUtil; /** * 生成单号前缀 */ private static String getFormNoPrefix(OrderNoTypeBean orderNoTypeEnum) { //格式化时间 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(orderNoTypeEnum.getDatePattern()); StringBuffer sb = new StringBuffer(); sb.append(orderNoTypeEnum.getPrefix()); sb.append(formatter.format(LocalDateTime.now())); return sb.toString(); } /** * 构建流水号缓存Key * * @param serialPrefix 流水号前缀 * @return 流水号缓存Key */ private static String getStCacheKey(String serialPrefix) { return Constant.SERIAL_CACHE_PREFIX_ST.concat(serialPrefix); } private static String getScCacheKey(String serialPrefix) { return Constant.SERIAL_CACHE_PREFIX.concat(serialPrefix); } private static String getStatCacheKey(String serialPrefix) { return Constant.SERIAL_CACHE_PREFIX_STAT.concat(serialPrefix); } private static String getInvPlaceCacheKey(String serialPrefix) { return Constant.SERIAL_CACHE_PREFIX_PLACE.concat(serialPrefix); } /** * 补全流水号 * * @param serialPrefix 单号前缀 * @param incrementalSerial 当天自增流水号 * @author mengqiang * @date 2019/1/1 */ private static String completionSerial(String serialPrefix, Long incrementalSerial, OrderNoTypeBean orderNoTypeEnum) { StringBuffer sb = new StringBuffer(serialPrefix); //需要补0的长度=流水号长度 -当日自增计数长度 int length = orderNoTypeEnum.getSerialLength() - String.valueOf(incrementalSerial).length(); //补零 for (int i = 0; i < length; i++) { sb.append("0"); } //redis当日自增数 sb.append(incrementalSerial); return sb.toString(); } private static String completionSerial(String serialPrefix, Long incrementalSerial, int serialLength) { StringBuffer sb = new StringBuffer(serialPrefix); //需要补0的长度=流水号长度 -当日自增计数长度 int length = serialLength - String.valueOf(incrementalSerial).length(); //补零 for (int i = 0; i < length; i++) { sb.append("0"); } //redis当日自增数 sb.append(incrementalSerial); return sb.toString(); } /** * 补全随机数 * * @param serialWithPrefix 当前单号 * @param orderNoTypeEnum 单号生成枚举 * @author mengqiang * @date 2019/1/1 */ private static String completionRandom(String serialWithPrefix, OrderNoTypeBean orderNoTypeEnum) { StringBuilder sb = new StringBuilder(serialWithPrefix); //随机数长度 int length = orderNoTypeEnum.getRandomLength(); if (length > 0) { Random random = new Random(); for (int i = 0; i < length; i++) { //十以内随机数补全 sb.append(random.nextInt(10)); } } return sb.toString(); } /** * @param orderNoTypeEnum: * @Description 基于redis生成单号(时间格式 + 自增数) * @author wangliangzhi * @Date: 2021/12/21 * @time: 14:15 * @return: java.lang.String **/ public String createScOrderNo(OrderNoTypeBean orderNoTypeEnum) { //获得单号前缀 //格式 固定前缀 +时间前缀 示例 String formNoPrefix = getFormNoPrefix(orderNoTypeEnum); //获得缓存key String cacheKey = getScCacheKey(formNoPrefix); //获得当日自增数 Long incrementalSerial = redisUtil.incr(cacheKey, 1); // 设置key过期时间, 保证每天的流水号从1开始 if (incrementalSerial == 1) { //设置失效时间 凌晨过期 redisUtil.expire(cacheKey, getSecondsNextEarlyMorning()); } //组合单号并补全流水号 String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial, orderNoTypeEnum); //补全随机数 return completionRandom(serialWithPrefix, orderNoTypeEnum); } public String createStOrderNo(OrderNoTypeBean orderNoTypeEnum) { //获得单号前缀 //格式 固定前缀 +时间前缀 示例 String formNoPrefix = getFormNoPrefix(orderNoTypeEnum); //获得缓存key String cacheKey = getStCacheKey(formNoPrefix); //获得当日自增数 Long incrementalSerial = redisUtil.incr(cacheKey, 1); // 设置key过期时间, 保证每天的流水号从1开始 if (incrementalSerial == 1) { //设置失效时间 凌晨过期 redisUtil.expire(cacheKey, getSecondsNextEarlyMorning()); } //组合单号并补全流水号 String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial, orderNoTypeEnum); //补全随机数 return completionRandom(serialWithPrefix, orderNoTypeEnum); } public String createPurOrderNo(OrderNoTypeBean orderNoTypeEnum) { //获得单号前缀 //格式 固定前缀 +时间前缀 示例 String formNoPrefix = getFormNoPrefix(orderNoTypeEnum); //获得缓存key String cacheKey = getStCacheKey(formNoPrefix); //获得当日自增数 Long incrementalSerial = redisUtil.incr(cacheKey, 1); // 设置key过期时间, 保证每天的流水号从1开始 if (incrementalSerial == 1) { //设置失效时间 凌晨过期 redisUtil.expire(cacheKey, getSecondsNextEarlyMorning()); } //组合单号并补全流水号 String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial, orderNoTypeEnum); //补全随机数 return completionRandom(serialWithPrefix, orderNoTypeEnum); } private Long getSecondsNextEarlyMorning() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 1); // 改成这样就好了 cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000; } public long getRelId() { Long incrementalSerial = redisUtil.incr("udiRelId", 1); if (incrementalSerial == 1) { redisUtil.expire("udiRelId", getSecondsNextEarlyMorning()); } String curTime = System.currentTimeMillis() + ""; return Long.parseLong(curTime.substring(1, curTime.length() - 3)) + incrementalSerial; } //生成部门编码 public String getDeptCode() { Long incrementalSerial = redisUtil.incr("genDeptCode", 1); return completionSerial("D", incrementalSerial, 4); } /** * 生成物资出入库汇总数据的记录号 * * @param orderNoTypeEnum * @return */ public String createStatOrderNo(OrderNoTypeBean orderNoTypeEnum) { //获得单号前缀 //格式 固定前缀 +时间前缀 示例 String formNoPrefix = getFormNoPrefix(orderNoTypeEnum); //获得缓存key String cacheKey = getStatCacheKey(formNoPrefix); //获得当日自增数 Long incrementalSerial = redisUtil.incr(cacheKey, 1); // 设置key过期时间, 保证每天的流水号从1开始 if (incrementalSerial == 1) { //设置失效时间 凌晨过期 redisUtil.expire(cacheKey, getSecondsNextEarlyMorning()); } //组合单号并补全流水号 String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial, orderNoTypeEnum); //补全随机数 return completionRandom(serialWithPrefix, orderNoTypeEnum); } /** * 生成物资上架记录号 * * @param orderNoTypeEnum * @return */ public String createInvPlaceOrderNo(OrderNoTypeBean orderNoTypeEnum) { //获得单号前缀 //格式 固定前缀 +时间前缀 示例 String formNoPrefix = getFormNoPrefix(orderNoTypeEnum); //获得缓存key String cacheKey = getStatCacheKey(formNoPrefix); //获得当日自增数 Long incrementalSerial = redisUtil.incr(cacheKey, 1); // 设置key过期时间, 保证每天的流水号从1开始 if (incrementalSerial == 1) { //设置失效时间 凌晨过期 redisUtil.expire(cacheKey, getSecondsNextEarlyMorning()); } //组合单号并补全流水号 String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial, orderNoTypeEnum); //补全随机数 return completionRandom(serialWithPrefix, orderNoTypeEnum); } /** * 生成多次出库记录号 * * @param orderNoTypeEnum * @return */ public String createOrderMark(OrderNoTypeBean orderNoTypeEnum) { //获得单号前缀 //格式 固定前缀 +时间前缀 示例 String formNoPrefix = getFormNoPrefix(orderNoTypeEnum); //获得缓存key String cacheKey = getStatCacheKey(formNoPrefix); //获得当日自增数 Long incrementalSerial = redisUtil.incr(cacheKey, 1); // 设置key过期时间, 保证每天的流水号从1开始 if (incrementalSerial == 1) { //设置失效时间 凌晨过期 redisUtil.expire(cacheKey, getSecondsNextEarlyMorning()); } //组合单号并补全流水号 String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial, orderNoTypeEnum); //补全随机数 return completionRandom(serialWithPrefix, orderNoTypeEnum); } }