diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java index b25fdd3..fbf7d88 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java @@ -4,6 +4,7 @@ import cn.estsh.i3plus.pojo.platform.bean.SysOrderNoRule; import io.swagger.annotations.ApiOperation; import java.util.List; +import java.util.Map; /** * @Description : @@ -23,6 +24,14 @@ public interface ISynchronizedService { SysOrderNoRule nextOrderNo(String code); /** + * 根据单号代码+系统字段,获取单号信息 + * @param code 单号代码 + * @return 单号信息 + */ + @ApiOperation(value = "根据code查询最新单号规则") + SysOrderNoRule nextOrderNo(String code, Map map); + + /** * 根据单号代码获取单号信息 * @param code 单号代码 * @return 单号信息 diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java index ae65bac..fefb446 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java @@ -6,6 +6,7 @@ import cn.estsh.i3plus.pojo.platform.bean.SysOrderNoRule; import io.swagger.annotations.ApiOperation; import java.util.List; +import java.util.Map; /** * @Description : 单号生成规则服务器 @@ -74,6 +75,15 @@ public interface ISysOrderNoRuleService { List doGetSysOrderNoRuleByNum(SysOrderNoRule orderNoRule,String orderNoTemplate,int num); /** + * 根据单号代码获取单号信息 + * @param orderNoRule 单号代码 + * @param orderNoTemplate + * @return 单号信息 + */ + @ApiOperation(value = "根据单号代码+系统字段获取单号信息") + List doGetSysOrderNoRuleByNum(SysOrderNoRule orderNoRule, Map map, String orderNoTemplate, int num); + + /** * 根据id修改单号规则状态 * @param id 单号ID * @param status 单号状态 diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java index aa21d25..ba4961b 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java @@ -27,10 +27,7 @@ import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil; import cn.estsh.i3plus.pojo.base.util.StringUtil; -import cn.estsh.i3plus.pojo.model.common.CloudPagerModel; -import cn.estsh.i3plus.pojo.model.common.ImppEmail; -import cn.estsh.i3plus.pojo.model.common.ImppSmsContent; -import cn.estsh.i3plus.pojo.model.common.UserModel; +import cn.estsh.i3plus.pojo.model.common.*; import cn.estsh.i3plus.pojo.model.license.ImppLicense; import cn.estsh.i3plus.pojo.model.platform.*; import cn.estsh.i3plus.pojo.platform.bean.*; @@ -751,6 +748,21 @@ public class WhiteController extends CoreBaseController { } } + @PostMapping(value = "/sys-order-no-rule/get-order-no") + @ApiOperation(value = "根据单号规则代码+系统字段,生成单号") + public ResultBean getOrderNo(@RequestBody ImppOrderNoRuleModel imppOrderNoRuleModel) { + try { + ValidatorBean.checkNotNull(imppOrderNoRuleModel.getCode(), "code不能为空"); + + SysOrderNoRule sysOrderNoRule = synchronizedService.nextOrderNo(imppOrderNoRuleModel.getCode(), imppOrderNoRuleModel.getFieldMap()); + return ResultBean.success("操作成功").setResultObject(sysOrderNoRule).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); + } catch (ImppBusiException busExcep) { + return ResultBean.fail(busExcep); + } catch (Exception e) { + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } + } + /** * 根据单号规则代码,生成单号 * diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java index 87fd5d2..091ef64 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java @@ -21,6 +21,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; +import java.util.Map; import static cn.estsh.i3plus.platform.common.util.CommonConstWords.REDIS_PREFIX_LOCK_GET_ORDER_NO; @@ -58,6 +59,71 @@ public class SynchronizedService implements ISynchronizedService { return list.stream().findFirst().get(); } + @Override + public SysOrderNoRule nextOrderNo(String code, Map map) { + int num = NumberUtils.INTEGER_ONE; + //先拿规则 + String lockKey = CommonConstWords.REDIS_PREFIX_LOCK_GET_ORDER_NO + ":" + "LOCK" + ":" + code; + RLock rLock = (RLock) redisRes.getLock(lockKey); + rLock.lock(); + try { + SysOrderNoRule codeRole = sysOrderNoRuleService.getSysOrderNoRuleByCode(code); + if (codeRole == null) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode()) + .setErrorDetail("[" + code + "]规则代码不存在存在") + .setErrorSolution("请重新输入规则代码") + .build(); + } else if (codeRole.getOrderNoRuleStatus() == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("[" + code + "]单号规则已禁用") + .setErrorSolution("请重新输入规则代码") + .build(); + } + + sysOrderNoRuleService.detachSysOrderNoRule(codeRole); + + String orderNoTemplate = OrderNoMakeUtil.getOrderNoTemplate(codeRole); + String redisKey = REDIS_PREFIX_LOCK_GET_ORDER_NO + ":" + code + ":" + orderNoTemplate; + + long orginSerialNo = codeRole.getSerialNo(); + if (codeRole.getSerialNo() < 0 || OrderNoMakeUtil.isCycleByPrefix(codeRole, orderNoTemplate)) { + orginSerialNo = 0; + } + long incr = codeRole.getSerialNoIncrement() * num; + + //缓存增加 + //先判断redis是否存在,如果不存在,则用默认初始值+步长*数量,如果存在,则添加步长 * 数量 + codeRole.setSerialNo(redisRes.putObjAdditional(redisKey, orginSerialNo, incr) - incr); + + // 设置缓存有效期 + redisRes.expire(redisKey, PlatformConstWords.REDIS_EXPIRE_SECONDS); + + // 生成单号更缓存 + List orderNoRuleList = sysOrderNoRuleService.doGetSysOrderNoRuleByNum(codeRole, map, orderNoTemplate, num); + +// FIXME 松下推送量太大并且该记录无意义 先注释 +// try { +// rabbitTemplate.convertAndSend(PlatformConstWords.QUEUE_IMPP_ORDER_NO_RECORD, JsonUtilTool.encode(orderNoRuleList)); +// } catch (Exception e) { +// LOGGER.error("单号记录推送异常", e); +// } + + // 生成单号更缓存 + return orderNoRuleList.stream().findFirst().get(); + } catch (Exception e) { + LOGGER.error("生成单号失败,单号代码:{},num:{}", code, num, e); + } finally { + if (rLock.isHeldByCurrentThread()) { + rLock.unlock(); + } + } + return null; + } + /** * 根据单号代码获取单号信息 * diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java index a04bb9b..a1cac91 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java @@ -22,6 +22,7 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @Description : 系统单号生成规则接口实现 @@ -129,6 +130,35 @@ public class SysOrderNoRuleService implements ISysOrderNoRuleService { return resultList; } + /** + * 根据单号代码+系统字段获取单号信息 + * + * @param sysOrderNoRule 单号代码 + * @param orderNoTemplate + * @param num + * @return 单号信息 + */ + @Override + public synchronized List doGetSysOrderNoRuleByNum(SysOrderNoRule sysOrderNoRule, Map map, String orderNoTemplate, int num) { + List resultList = new ArrayList<>(); + try { + for (int i = 0; i < num; i++) { + sysOrderNoRule = OrderNoMakeUtil.next(CloneTool.clone(sysOrderNoRule), map, orderNoTemplate); + resultList.add(sysOrderNoRule); + } + }catch (Exception e){ + LOGGER.error("单号生成异常:",e); + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode()) + .setErrorDetail("单号生成异常 %s",e.getMessage()) + .build(); + } + + sysOrderNoRuleRDao.update(sysOrderNoRule); + return resultList; + } + @Override public void updateSysOrderNoRuleCodeStatusById(Long id, Integer status) { sysOrderNoRuleRDao.updateByProperties("id", id, "orderNoRuleStatus", status); diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/OrderNoMakeUtil.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/OrderNoMakeUtil.java index fc8fb28..a7018b1 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/OrderNoMakeUtil.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/OrderNoMakeUtil.java @@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; import java.text.MessageFormat; import java.text.SimpleDateFormat; +import java.util.Map; import static cn.estsh.i3plus.platform.common.util.PlatformConstWords.SERIAL_NO; @@ -83,6 +84,47 @@ public class OrderNoMakeUtil { } /** + * @param orderNoRule + * @param orderNoTemplate + * @return + */ + public static SysOrderNoRule next(SysOrderNoRule orderNoRule, Map map, String orderNoTemplate) { + int prefixIdx = orderNoTemplate.indexOf(SERIAL_NO); + + // 流水号长度补全表达式 + String serialNoFormatStr = MessageFormat.format(PlatformConstWords.SERIAL_NO_FORMAT, orderNoRule.getSerialNoLength()); + + // 判断是否首次生成(SerialNo初始值-1) + if (orderNoRule.getSerialNo() > 0 && prefixIdx != -1) { + long serialNo = orderNoRule.getSerialNo() + orderNoRule.getSerialNoIncrement(); + BigDecimal maxSerialNo = TEN.pow(orderNoRule.getSerialNoLength()).subtract(BigDecimal.ONE); + if (CommonEnumUtil.TRUE_OR_FALSE.valueOfBoolean(orderNoRule.getIsFixedLength()) + && serialNo > maxSerialNo.longValue()) { + serialNo = new BigDecimal(serialNo).remainder(maxSerialNo).longValue(); + orderNoRule.setSerialNo(serialNo == 0 ? maxSerialNo.longValue() : serialNo); + }else{ + orderNoRule.setSerialNo(serialNo); + } + } else { + orderNoRule.setSerialNo(orderNoRule.getSerialNoSeed() * orderNoRule.getSerialNoIncrement()); + } + +// orderNoRule.setOrderNo(orderNoTemplate.replace(SERIAL_NO, String.format(serialNoFormatStr, orderNoRule.getSerialNo()))); + orderNoTemplate = overlayTemplate(orderNoTemplate, map); + orderNoRule.setOrderNo(orderNoTemplate.replace(SERIAL_NO, String.format(serialNoFormatStr, orderNoRule.getSerialNo()))); + return orderNoRule; + } + + public static String overlayTemplate (String orderNoTemplate, Map map) { + if(!map.isEmpty()) { + for (String temp : map.keySet()) { + orderNoTemplate = orderNoTemplate.replace(temp, map.get(temp)); + } + } + return orderNoTemplate; + } + + /** * * @param orderNoRule * @param orderNoTemplate