|
|
|
|
@ -1,9 +1,15 @@
|
|
|
|
|
package com.ruoyi.system.service.impl;
|
|
|
|
|
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import com.ruoyi.common.constant.UserConstants;
|
|
|
|
|
import com.ruoyi.common.exception.ServiceException;
|
|
|
|
|
import com.ruoyi.common.utils.DateUtils;
|
|
|
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import com.ruoyi.system.mapper.SysCodeRuleMapper;
|
|
|
|
|
import com.ruoyi.system.domain.SysCodeRule;
|
|
|
|
|
import com.ruoyi.system.service.ISysCodeRuleService;
|
|
|
|
|
@ -18,6 +24,28 @@ import com.ruoyi.common.core.text.Convert;
|
|
|
|
|
@Service
|
|
|
|
|
public class SysCodeRuleServiceImpl implements ISysCodeRuleService
|
|
|
|
|
{
|
|
|
|
|
private static final String ENABLED_YES = "Y";
|
|
|
|
|
|
|
|
|
|
private static final String ENABLED_NO = "N";
|
|
|
|
|
|
|
|
|
|
private static final String DEL_FLAG_NORMAL = "0";
|
|
|
|
|
|
|
|
|
|
private static final String RESET_CYCLE_DAY = "DAY";
|
|
|
|
|
|
|
|
|
|
private static final String RESET_CYCLE_MONTH = "MONTH";
|
|
|
|
|
|
|
|
|
|
private static final String RESET_CYCLE_YEAR = "YEAR";
|
|
|
|
|
|
|
|
|
|
private static final String RESET_CYCLE_NONE = "NONE";
|
|
|
|
|
|
|
|
|
|
private static final String DEFAULT_DATE_FORMAT = "yyyyMMdd";
|
|
|
|
|
|
|
|
|
|
private static final Long DEFAULT_SERIAL_LENGTH = 4L;
|
|
|
|
|
|
|
|
|
|
private static final int MAX_SERIAL_LENGTH = 10;
|
|
|
|
|
|
|
|
|
|
private static final int MAX_BUSINESS_CODE_LENGTH = 64;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private SysCodeRuleMapper sysCodeRuleMapper;
|
|
|
|
|
|
|
|
|
|
@ -45,6 +73,83 @@ public class SysCodeRuleServiceImpl implements ISysCodeRuleService
|
|
|
|
|
return sysCodeRuleMapper.selectSysCodeRuleList(sysCodeRule);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 校验规则编码是否唯一
|
|
|
|
|
*
|
|
|
|
|
* @param sysCodeRule 编码规则
|
|
|
|
|
* @return 结果
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean checkRuleCodeUnique(SysCodeRule sysCodeRule)
|
|
|
|
|
{
|
|
|
|
|
if (StringUtils.isNull(sysCodeRule) || StringUtils.isEmpty(sysCodeRule.getRuleCode()))
|
|
|
|
|
{
|
|
|
|
|
return UserConstants.UNIQUE;
|
|
|
|
|
}
|
|
|
|
|
Long ruleId = StringUtils.isNull(sysCodeRule.getRuleId()) ? -1L : sysCodeRule.getRuleId();
|
|
|
|
|
SysCodeRule info = sysCodeRuleMapper.selectSysCodeRuleByRuleCode(StringUtils.trim(sysCodeRule.getRuleCode()));
|
|
|
|
|
if (StringUtils.isNotNull(info) && info.getRuleId().longValue() != ruleId.longValue())
|
|
|
|
|
{
|
|
|
|
|
return UserConstants.NOT_UNIQUE;
|
|
|
|
|
}
|
|
|
|
|
return UserConstants.UNIQUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成下一个业务编号
|
|
|
|
|
*
|
|
|
|
|
* @param ruleCode 规则编码
|
|
|
|
|
* @return 业务编号
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public String nextCode(String ruleCode)
|
|
|
|
|
{
|
|
|
|
|
String normalizedRuleCode = StringUtils.trim(ruleCode);
|
|
|
|
|
if (StringUtils.isEmpty(normalizedRuleCode))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("编码规则编码不能为空");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysCodeRule rule = sysCodeRuleMapper.selectSysCodeRuleByRuleCodeForUpdate(normalizedRuleCode);
|
|
|
|
|
if (StringUtils.isNull(rule))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException(String.format("编码规则【%1$s】不存在或已删除", normalizedRuleCode));
|
|
|
|
|
}
|
|
|
|
|
if (!StringUtils.equals(ENABLED_YES, rule.getEnabled()))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException(String.format("编码规则【%1$s】已停用", normalizedRuleCode));
|
|
|
|
|
}
|
|
|
|
|
validateRule(rule);
|
|
|
|
|
|
|
|
|
|
Date now = DateUtils.getNowDate();
|
|
|
|
|
String serialKey = buildSerialKey(rule, now);
|
|
|
|
|
long currentSerial = StringUtils.nvl(rule.getCurrentSerial(), 0L);
|
|
|
|
|
long nextSerial = shouldReset(rule, serialKey) ? 1L : currentSerial + 1L;
|
|
|
|
|
long maxSerial = maxSerial(rule.getSerialLength().intValue());
|
|
|
|
|
if (nextSerial > maxSerial)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException(String.format("编码规则【%1$s】流水号已超出%2$s位长度",
|
|
|
|
|
rule.getRuleCode(), rule.getSerialLength()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String datePart = formatDate(rule.getDateFormat(), now);
|
|
|
|
|
String serialPart = String.format("%0" + rule.getSerialLength().intValue() + "d", nextSerial);
|
|
|
|
|
String nextCode = rule.getCodePrefix() + datePart + serialPart;
|
|
|
|
|
if (nextCode.length() > MAX_BUSINESS_CODE_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException(String.format("编码规则【%1$s】生成的编号长度超过%2$s位",
|
|
|
|
|
rule.getRuleCode(), MAX_BUSINESS_CODE_LENGTH));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rows = sysCodeRuleMapper.updateSerialState(rule.getRuleId(), nextSerial, serialKey, now);
|
|
|
|
|
if (rows != 1)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException(String.format("编码规则【%1$s】流水号更新失败", rule.getRuleCode()));
|
|
|
|
|
}
|
|
|
|
|
return nextCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 新增编码规则
|
|
|
|
|
*
|
|
|
|
|
@ -54,6 +159,17 @@ public class SysCodeRuleServiceImpl implements ISysCodeRuleService
|
|
|
|
|
@Override
|
|
|
|
|
public int insertSysCodeRule(SysCodeRule sysCodeRule)
|
|
|
|
|
{
|
|
|
|
|
normalizeRule(sysCodeRule);
|
|
|
|
|
sysCodeRule.setCurrentSerial(0L);
|
|
|
|
|
sysCodeRule.setLastSerialKey(null);
|
|
|
|
|
sysCodeRule.setDelFlag(DEL_FLAG_NORMAL);
|
|
|
|
|
sysCodeRule.setUpdateBy(null);
|
|
|
|
|
sysCodeRule.setUpdateTime(null);
|
|
|
|
|
validateRule(sysCodeRule);
|
|
|
|
|
if (!checkRuleCodeUnique(sysCodeRule))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("规则编码已存在");
|
|
|
|
|
}
|
|
|
|
|
sysCodeRule.setCreateTime(DateUtils.getNowDate());
|
|
|
|
|
return sysCodeRuleMapper.insertSysCodeRule(sysCodeRule);
|
|
|
|
|
}
|
|
|
|
|
@ -65,8 +181,28 @@ public class SysCodeRuleServiceImpl implements ISysCodeRuleService
|
|
|
|
|
* @return 结果
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public int updateSysCodeRule(SysCodeRule sysCodeRule)
|
|
|
|
|
{
|
|
|
|
|
if (StringUtils.isNull(sysCodeRule) || StringUtils.isNull(sysCodeRule.getRuleId()))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("编码规则ID不能为空");
|
|
|
|
|
}
|
|
|
|
|
SysCodeRule current = selectExistingRule(sysCodeRule.getRuleId());
|
|
|
|
|
normalizeRule(sysCodeRule);
|
|
|
|
|
if (isUsed(current) && !StringUtils.equals(current.getRuleCode(), sysCodeRule.getRuleCode()))
|
|
|
|
|
{
|
|
|
|
|
// 规则编码是业务服务调用的稳定标识,已生成过编号后修改会导致后续单据找不到原规则。
|
|
|
|
|
throw new ServiceException("已使用的编码规则不允许修改规则编码");
|
|
|
|
|
}
|
|
|
|
|
sysCodeRule.setCurrentSerial(current.getCurrentSerial());
|
|
|
|
|
sysCodeRule.setLastSerialKey(current.getLastSerialKey());
|
|
|
|
|
sysCodeRule.setDelFlag(current.getDelFlag());
|
|
|
|
|
validateRule(sysCodeRule);
|
|
|
|
|
if (!checkRuleCodeUnique(sysCodeRule))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("规则编码已存在");
|
|
|
|
|
}
|
|
|
|
|
sysCodeRule.setUpdateTime(DateUtils.getNowDate());
|
|
|
|
|
return sysCodeRuleMapper.updateSysCodeRule(sysCodeRule);
|
|
|
|
|
}
|
|
|
|
|
@ -78,9 +214,15 @@ public class SysCodeRuleServiceImpl implements ISysCodeRuleService
|
|
|
|
|
* @return 结果
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public int deleteSysCodeRuleByRuleIds(String ruleIds)
|
|
|
|
|
{
|
|
|
|
|
return sysCodeRuleMapper.deleteSysCodeRuleByRuleIds(Convert.toStrArray(ruleIds));
|
|
|
|
|
String[] ids = Convert.toStrArray(ruleIds);
|
|
|
|
|
for (String id : ids)
|
|
|
|
|
{
|
|
|
|
|
checkDeleteAllowed(Long.valueOf(id));
|
|
|
|
|
}
|
|
|
|
|
return sysCodeRuleMapper.deleteSysCodeRuleByRuleIds(ids);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -90,8 +232,169 @@ public class SysCodeRuleServiceImpl implements ISysCodeRuleService
|
|
|
|
|
* @return 结果
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public int deleteSysCodeRuleByRuleId(Long ruleId)
|
|
|
|
|
{
|
|
|
|
|
checkDeleteAllowed(ruleId);
|
|
|
|
|
return sysCodeRuleMapper.deleteSysCodeRuleByRuleId(ruleId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private SysCodeRule selectExistingRule(Long ruleId)
|
|
|
|
|
{
|
|
|
|
|
SysCodeRule rule = sysCodeRuleMapper.selectSysCodeRuleByRuleIdForUpdate(ruleId);
|
|
|
|
|
if (StringUtils.isNull(rule))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("编码规则不存在或已删除");
|
|
|
|
|
}
|
|
|
|
|
return rule;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void normalizeRule(SysCodeRule rule)
|
|
|
|
|
{
|
|
|
|
|
if (StringUtils.isNull(rule))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("编码规则不能为空");
|
|
|
|
|
}
|
|
|
|
|
rule.setRuleCode(StringUtils.trim(rule.getRuleCode()));
|
|
|
|
|
rule.setRuleName(StringUtils.trim(rule.getRuleName()));
|
|
|
|
|
rule.setCodePrefix(StringUtils.isNull(rule.getCodePrefix()) ? "" : StringUtils.trim(rule.getCodePrefix()));
|
|
|
|
|
rule.setDateFormat(StringUtils.isEmpty(rule.getDateFormat())
|
|
|
|
|
? DEFAULT_DATE_FORMAT : StringUtils.trim(rule.getDateFormat()));
|
|
|
|
|
rule.setSerialLength(StringUtils.isNull(rule.getSerialLength())
|
|
|
|
|
? DEFAULT_SERIAL_LENGTH : rule.getSerialLength());
|
|
|
|
|
rule.setResetCycle(StringUtils.isEmpty(rule.getResetCycle())
|
|
|
|
|
? RESET_CYCLE_DAY : StringUtils.trim(rule.getResetCycle()));
|
|
|
|
|
rule.setEnabled(StringUtils.isEmpty(rule.getEnabled())
|
|
|
|
|
? ENABLED_YES : StringUtils.trim(rule.getEnabled()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void validateRule(SysCodeRule rule)
|
|
|
|
|
{
|
|
|
|
|
if (StringUtils.isEmpty(rule.getRuleCode()))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("规则编码不能为空");
|
|
|
|
|
}
|
|
|
|
|
if (rule.getRuleCode().length() > 64)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("规则编码长度不能超过64个字符");
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isEmpty(rule.getRuleName()))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("规则名称不能为空");
|
|
|
|
|
}
|
|
|
|
|
if (rule.getRuleName().length() > 100)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("规则名称长度不能超过100个字符");
|
|
|
|
|
}
|
|
|
|
|
if (rule.getCodePrefix().length() > 20)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("编码前缀长度不能超过20个字符");
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isEmpty(rule.getDateFormat()) || rule.getDateFormat().length() > 20)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("日期格式不能为空且长度不能超过20个字符");
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isNull(rule.getSerialLength())
|
|
|
|
|
|| rule.getSerialLength() <= 0
|
|
|
|
|
|| rule.getSerialLength() > MAX_SERIAL_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("流水号长度必须在1到10之间");
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isNull(rule.getCurrentSerial()) || rule.getCurrentSerial() < 0)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("当前流水号不能小于0");
|
|
|
|
|
}
|
|
|
|
|
if (rule.getCurrentSerial() > maxSerial(rule.getSerialLength().intValue()))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("当前流水号已超出配置的流水号长度");
|
|
|
|
|
}
|
|
|
|
|
if (!StringUtils.equalsAny(rule.getResetCycle(), RESET_CYCLE_DAY, RESET_CYCLE_MONTH,
|
|
|
|
|
RESET_CYCLE_YEAR, RESET_CYCLE_NONE))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("重置周期不合法");
|
|
|
|
|
}
|
|
|
|
|
if (!StringUtils.equalsAny(rule.getEnabled(), ENABLED_YES, ENABLED_NO))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("启用状态不合法");
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isNotEmpty(rule.getLastSerialKey()) && rule.getLastSerialKey().length() > 20)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("上次流水键长度不能超过20个字符");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String datePart = formatDate(rule.getDateFormat(), DateUtils.getNowDate());
|
|
|
|
|
if (rule.getCodePrefix().length() + datePart.length() + rule.getSerialLength() > MAX_BUSINESS_CODE_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("编码前缀、日期和流水号组成的编号长度不能超过64位");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String formatDate(String pattern, Date date)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return new SimpleDateFormat(pattern).format(date);
|
|
|
|
|
}
|
|
|
|
|
catch (IllegalArgumentException e)
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException("日期格式不合法");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String buildSerialKey(SysCodeRule rule, Date date)
|
|
|
|
|
{
|
|
|
|
|
if (StringUtils.equals(RESET_CYCLE_DAY, rule.getResetCycle()))
|
|
|
|
|
{
|
|
|
|
|
return DateUtils.parseDateToStr("yyyyMMdd", date);
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.equals(RESET_CYCLE_MONTH, rule.getResetCycle()))
|
|
|
|
|
{
|
|
|
|
|
return DateUtils.parseDateToStr("yyyyMM", date);
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.equals(RESET_CYCLE_YEAR, rule.getResetCycle()))
|
|
|
|
|
{
|
|
|
|
|
return DateUtils.parseDateToStr("yyyy", date);
|
|
|
|
|
}
|
|
|
|
|
return rule.getLastSerialKey();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean shouldReset(SysCodeRule rule, String serialKey)
|
|
|
|
|
{
|
|
|
|
|
return !StringUtils.equals(RESET_CYCLE_NONE, rule.getResetCycle())
|
|
|
|
|
&& !StringUtils.equals(serialKey, rule.getLastSerialKey());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long maxSerial(int serialLength)
|
|
|
|
|
{
|
|
|
|
|
if (serialLength >= MAX_SERIAL_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
return Integer.MAX_VALUE;
|
|
|
|
|
}
|
|
|
|
|
long max = 1L;
|
|
|
|
|
for (int i = 0; i < serialLength; i++)
|
|
|
|
|
{
|
|
|
|
|
max *= 10L;
|
|
|
|
|
}
|
|
|
|
|
return max - 1L;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void checkDeleteAllowed(Long ruleId)
|
|
|
|
|
{
|
|
|
|
|
SysCodeRule rule = sysCodeRuleMapper.selectSysCodeRuleByRuleIdForUpdate(ruleId);
|
|
|
|
|
if (StringUtils.isNull(rule))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (isUsed(rule))
|
|
|
|
|
{
|
|
|
|
|
throw new ServiceException(String.format("编码规则【%1$s】已生成过业务编号,不允许删除,可停用保留",
|
|
|
|
|
rule.getRuleName()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isUsed(SysCodeRule rule)
|
|
|
|
|
{
|
|
|
|
|
return StringUtils.nvl(rule.getCurrentSerial(), 0L) > 0L
|
|
|
|
|
|| StringUtils.isNotEmpty(rule.getLastSerialKey());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|