package com.vci.web.service.impl; import com.vci.frameworkcore.constant.FrameWorkDefaultValueConstant; import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus; import com.vci.starter.web.enumpck.BooleanEnum; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.pagemodel.DataGrid; import com.vci.starter.web.pagemodel.PageHelper; import com.vci.starter.web.util.BeanUtil; import com.vci.starter.web.util.LangBaseUtil; import com.vci.starter.web.util.VciBaseUtil; import com.vci.starter.web.util.VciDateUtil; import com.vci.web.bo.OsCodeSerialBuildBO; import com.vci.web.dao.*; import com.vci.web.dto.OsCodeEnumDTO; import com.vci.web.dto.OsCodeRuleDTO; import com.vci.web.dto.OsCodeRuleElementDTO; import com.vci.web.dto.OsCodeRuleProduceDTO; import com.vci.web.enumpck.OsCodeDateValueTypeEnum; import com.vci.web.enumpck.OsCodeElementTypeEnum; import com.vci.web.enumpck.OsCodeFillTypeEnum; import com.vci.web.enumpck.OsCodeProductTypeEnum; import com.vci.web.model.*; import com.vci.web.pageModel.OsCodeEnumVO; import com.vci.web.pageModel.OsCodeResultVO; import com.vci.web.pageModel.OsCodeRuleElementVO; import com.vci.web.pageModel.OsCodeRuleVO; import com.vci.web.service.OsCodeRuleServiceI; import com.vci.web.util.WebUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.*; import static com.vci.frameworkcore.constant.FrameWorkBusLangCodeConstant.DATA_ID_NOT_EXIST; import static com.vci.frameworkcore.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST; /** * 编码规则的服务 * * @author weidy * @date 2020/9/2 14:28 */ @Service public class OsCodeRuleServiceImpl implements OsCodeRuleServiceI { /** * 编码规则的数据操作层 */ @Resource private OsCodeRuleDaoI codeRuleDao; /** * 编码规则明细的数据操作层 */ @Resource private OsCodeRuleElementDaoI codeRuleElementDao; /** * 枚举的映射数据操作层 */ @Resource private OsCodeEnumDaoI codeEnumDao; /** * 流水号存储的信息 */ @Resource private OsCodeSerialNumberDaoI serialNumberDao; /** * 断码的数据操作层 */ @Resource private OsCodeBreakCodeDaoI breakCodeDao; /** * 枚举是空的时候的映射值 */ public static final String EMPTY = "${empty}"; /** * 空的流水依据 */ public static final String EMPTY_SERIAL_ACCORDING = "${nullSerialAccordingString}"; /** * 使用数据传输对象获取规则的对象 * @param codeRuleProduceDTO 生成编码的数据传输对象 * @return 规则的内容 */ private OsCodeRuleDO getRuleByDTO(OsCodeRuleProduceDTO codeRuleProduceDTO){ //查询编码规则,和相应的明细内容 OsCodeRuleDO ruleDO = null; if (StringUtils.isNotBlank(codeRuleProduceDTO.getOwnbizBtm()) && StringUtils.isNotBlank(codeRuleProduceDTO.getUseRuleFlag())) { ruleDO = selectByRuleFlag(codeRuleProduceDTO.getOwnbizBtm(), codeRuleProduceDTO.getUseRuleFlag()); } else if (StringUtils.isNotBlank(codeRuleProduceDTO.getCodeRuleId())) { ruleDO = selectById(codeRuleProduceDTO.getCodeRuleId()); } else { ruleDO = selectByOid(codeRuleProduceDTO.getCodeRuleOid()); } return ruleDO; } /** * 使用编码规则生成编码 * * @param codeRuleProduceDTO 编码生成所属数据传输对象,规则编号优先级大于主键,传递的数据优先级大于业务数据 * @return 生成的编码的值 * @throws VciBaseException 参数错误,规则不存在,数据不支持编码的生成等会抛出异常 */ @Override public String produceCode(OsCodeRuleProduceDTO codeRuleProduceDTO) throws VciBaseException { //判断规则的编号或者规则的主键 VciBaseUtil.alertNotNull(codeRuleProduceDTO, "编码生成来源数据"); if (StringUtils.isBlank(codeRuleProduceDTO.getCodeRuleId()) && StringUtils.isBlank(codeRuleProduceDTO.getCodeRuleOid()) && (StringUtils.isBlank(codeRuleProduceDTO.getUseRuleFlag()) || StringUtils.isBlank(codeRuleProduceDTO.getOwnbizBtm()))) { throw new VciBaseException("编码规则主键和编号为空,无法生成编码"); } OsCodeRuleDO ruleDO = getRuleByDTO(codeRuleProduceDTO); List ruleItemDOs = listItemsByRuleOidOrderByRuleOrderNubmer(ruleDO.getOid()); VciBaseUtil.alertNotNull(ruleItemDOs,"规则的明细"); //查询生成编码的数据 Map businessDataMap = codeRuleProduceDTO.getOwnbizDataMap(); //每一个元素产生的内容 List tempCode = new ArrayList(); //流水号的元素 Map serialItemMap = new HashMap(); Map serialAccordingMap = new HashMap(); wrapperRuleElement(ruleItemDOs,codeRuleProduceDTO,tempCode,businessDataMap,serialItemMap,serialAccordingMap); if (!CollectionUtils.isEmpty(serialItemMap)) { //生成一条流水号 wrapperSerial(serialItemMap, serialAccordingMap, tempCode, ruleDO.getBreakReUseFlag()); } String resultCode = ""; for (String code : tempCode) { resultCode += code; } return resultCode; } /** * 封装响应的内容 * @param ruleItemDOs 规则的明细 * @param codeRuleProduceDTO 创建编码的数据传输对象 * @param tempCode 临时的码段内容 * @param businessDataMap 业务数据的映射 * @param serialItemMap 序列号的明细 * @param serialAccordingMap 流水依据的内容 */ private void wrapperRuleElement(List ruleItemDOs,OsCodeRuleProduceDTO codeRuleProduceDTO, List tempCode,Map businessDataMap, Map serialItemMap, Map serialAccordingMap){ for (int i = 0; i < ruleItemDOs.size(); i++) { OsCodeRuleElementDO item = ruleItemDOs.get(i); OsCodeElementTypeEnum elementTypeEnum = OsCodeElementTypeEnum.forValue(item.getCodeElementType()); switch (elementTypeEnum) { case INPUT: if (CollectionUtils.isEmpty(codeRuleProduceDTO.getInputValueMap()) && !codeRuleProduceDTO.getInputValueMap().containsKey(item.getId())) { throw new VciBaseException("手动输入的值"); } String inputValue = codeRuleProduceDTO.getInputValueMap().get(item.getId()); if (inputValue.trim().length() < item.getMinLength() && OsCodeFillTypeEnum.NONE.getValue().equalsIgnoreCase(item.getCodeFillType())) { throw new VciBaseException("【{0}】输入的内容长度小于了{1},实际为{2}", new String[]{item.getName(), item.getMinLength() + "", inputValue.length() + ""}); } tempCode.add(i, fillCode(item, inputValue)); break; case STATIC: tempCode.add(i, item.getStaticCode() == null ? "" : item.getStaticCode()); break; case DATE: Date date = null; OsCodeDateValueTypeEnum codeDateValueTypeEnum = OsCodeDateValueTypeEnum.forValue(item.getCodeDateValueType()); switch (codeDateValueTypeEnum) { case BUSINESS: if (CollectionUtils.isEmpty(businessDataMap) || !businessDataMap.containsKey(item.getCodeDateUseField())) { throw new VciBaseException("[{0}]需要业务数据中的时间属性,但是未查询到业务数据的信息", new String[]{item.getName()}); } try { date = VciDateUtil.str2Date(businessDataMap.get(item.getCodeDateUseField()).toString(), VciDateUtil.DateTimeMillFormat); } catch (Exception e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[0], e); } default: date = new Date(); break; } tempCode.add(i, VciDateUtil.date2Str(date, item.getCodeDateFormat())); break; case FIELD: if (CollectionUtils.isEmpty(businessDataMap) || !businessDataMap.containsKey(item.getCodeUseField())) { throw new VciBaseException("[{0}]需要业务数据中的属性信息,但是未查询到业务数据的信息", new String[]{item.getName()}); } String fieldValue = businessDataMap.get(item.getCodeUseField()).toString(); tempCode.add(i, fillCode(item, fieldValue)); break; case ENUM: VciBaseUtil.alertNotNull(item.getCodeUseField(), "使用业务数据的属性名称"); if (CollectionUtils.isEmpty(businessDataMap) || !businessDataMap.containsKey(item.getCodeUseField())) { throw new VciBaseException("[{0}]需要业务数据中的属性信息,但是未查询到业务数据的信息", new String[]{item.getName()}); } String enumValue = businessDataMap.get(item.getCodeUseField()).toString(); if (StringUtils.isBlank(enumValue)) { enumValue = EMPTY; } String enumMapValue = codeEnumDao.selectMapValueByRuleOidAndValue(item.getOid(), enumValue); if (EMPTY.equalsIgnoreCase(enumMapValue)) { enumMapValue = ""; } tempCode.add(i, fillCode(item, enumMapValue)); break; case EXPRESSION: VciBaseUtil.alertNotNull(item.getCodeExpression(), "公式表达式"); String expressionValue = ""; //TODO 等待添加公式的内容 tempCode.add(i, fillCode(item, expressionValue)); break; case SERIAL: // 流水号 tempCode.add(i, ""); serialItemMap.put(i, item); default: //防止后面加别的内容 break; } if (BooleanEnum.TRUE.getValue().equalsIgnoreCase(item.getSerialAccording())) { serialAccordingMap.put(i, tempCode.get(i)); } } } /** * 使用编码规则生成编码 * * @param codeRuleProduceDTO 编码生成所属数据传输对象,规则编号优先级大于主键,传递的数据优先级大于业务数据 * @return 生成的编码的值 * @throws VciBaseException 参数错误,规则不存在,数据不支持编码的生成等会抛出异常 */ @Override public List batchProduceCode(OsCodeRuleProduceDTO codeRuleProduceDTO, Integer needAddQuantity) { //判断规则的编号或者规则的主键 VciBaseUtil.alertNotNull(codeRuleProduceDTO, "编码生成来源数据"); if (StringUtils.isBlank(codeRuleProduceDTO.getCodeRuleId()) && StringUtils.isBlank(codeRuleProduceDTO.getCodeRuleOid()) && (StringUtils.isBlank(codeRuleProduceDTO.getUseRuleFlag()) || StringUtils.isBlank(codeRuleProduceDTO.getOwnbizBtm()))) { throw new VciBaseException("编码规则主键和编号为空,无法生成编码"); } //查询编码规则,和相应的明细内容 OsCodeRuleDO ruleDO =getRuleByDTO(codeRuleProduceDTO); List ruleItemDOs = listItemsByRuleOidOrderByRuleOrderNubmer(ruleDO.getOid()); VciBaseUtil.alertNotNull(ruleItemDOs,"规则的明细"); //查询生成编码的数据 Map businessDataMap = codeRuleProduceDTO.getOwnbizDataMap(); //每一个元素产生的内容 List tempCode = new ArrayList(); //用来存储流水号的元素 Map serialItemMap = new HashMap(); //用来存储流水依据的元素 Map serialAccordingMap = new HashMap(); wrapperRuleElement(ruleItemDOs,codeRuleProduceDTO,tempCode,businessDataMap,serialItemMap,serialAccordingMap); List resultVOList = new ArrayList(); if (!CollectionUtils.isEmpty(serialItemMap)) { //生成多条流水号 Map serialReturnMap = batchWrapperSerial(serialItemMap, serialAccordingMap, ruleDO.getBreakReUseFlag(), needAddQuantity); for (Integer i = 0; i < needAddQuantity; i++) { OsCodeResultVO resultVO = new OsCodeResultVO(); List codeCopy = new ArrayList(tempCode); OsCodeSerialBuildBO serialBuildBO= null; for(Integer serialIndex : serialReturnMap.keySet()){ serialBuildBO = serialReturnMap.get(serialIndex); if(!CollectionUtils.isEmpty(serialBuildBO.getSerialCodeList()) && serialBuildBO.getSerialCodeList().size()>i){ codeCopy.set(serialIndex,serialBuildBO.getSerialCodeList().get(i)); } } resultVO.setSerialNo(serialBuildBO.getSerialNoList().get(i)); resultVO.setSerialCode(serialBuildBO.getSerialCodeList().get(i)); resultVO.setSerialUnit(serialBuildBO.getSerialUnit()); StringBuilder sb = new StringBuilder(); for(int j = 0 ; j < codeCopy.size(); j++){ String s = codeCopy.get(j); if(s == null){ s = ""; } sb.append(s); } resultVO.setCode(sb.toString()); resultVOList.add(resultVO); } } return resultVOList; } /** * 使用规则主键获取明细,并且按照排序号进行排序 * @param ruleOid 规则的主键 * @return 元素的内容 */ private List listItemsByRuleOidOrderByRuleOrderNubmer(String ruleOid) { VciBaseUtil.alertNotNull(ruleOid, "规则的主键"); List codeRuleElementDOS = codeRuleElementDao.selectByRuleOidOrderByRuleOrderNumber(ruleOid.trim()); return codeRuleElementDOS; } /** * 是否存在编码规则 * * @param codeRuleProduceDTO 编码生成所属数据传输对象,规则编号优先级大于主键,传递的数据优先级大于业务数据 * @return 是否包含 */ @Override public boolean existRule(OsCodeRuleProduceDTO codeRuleProduceDTO) { VciBaseUtil.alertNotNull(codeRuleProduceDTO, "编码生成来源数据"); if (StringUtils.isBlank(codeRuleProduceDTO.getCodeRuleId()) && StringUtils.isBlank(codeRuleProduceDTO.getCodeRuleOid()) && (StringUtils.isBlank(codeRuleProduceDTO.getUseRuleFlag()) || StringUtils.isBlank(codeRuleProduceDTO.getOwnbizBtm()))) { throw new VciBaseException("编码规则主键和编号为空,无法生成编码"); } //查询编码规则,和相应的明细内容 try { OsCodeRuleDO ruleDO = getRuleByDTO(codeRuleProduceDTO); return ruleDO!=null&&StringUtils.isNotBlank(ruleDO.getOid()); }catch (Throwable e){ return false; } } /** * 上移 * * @param codeRuleElementOid 元素的主键 */ @Override public void upIndex(String codeRuleElementOid) { VciBaseUtil.alertNotNull(codeRuleElementOid,"元素的主键"); OsCodeRuleElementDO elementDO = codeRuleElementDao.selectByPrimaryKey(codeRuleElementOid); if(elementDO == null || StringUtils.isBlank(elementDO.getOid())){ throw new VciBaseException(DATA_OID_NOT_EXIST,new String[]{codeRuleElementOid}); } //查询比它小一个的 if(elementDO.getRuleOrderNumber() ==0){ return;//已经到头了 } List lastElementDOList = codeRuleElementDao.selectByRuleOidAndIndex(elementDO.getPkCodeRule(),elementDO.getRuleOrderNumber()-1); if(!CollectionUtils.isEmpty(lastElementDOList)){ OsCodeRuleElementDO elementDO1 = lastElementDOList.get(0); Integer index = elementDO1.getRuleOrderNumber(); elementDO1.setRuleOrderNumber(elementDO.getRuleOrderNumber()); elementDO.setRuleOrderNumber(index); codeRuleElementDao.updateByPrimaryKey(elementDO1); codeRuleElementDao.updateByPrimaryKey(elementDO); } } /** * 下移 * * @param codeRuleElementOid 元素的主键 */ @Override public void downIndex(String codeRuleElementOid) { VciBaseUtil.alertNotNull(codeRuleElementOid,"元素的主键"); OsCodeRuleElementDO elementDO = codeRuleElementDao.selectByPrimaryKey(codeRuleElementOid); if(elementDO == null || StringUtils.isBlank(elementDO.getOid())){ throw new VciBaseException(DATA_OID_NOT_EXIST,new String[]{codeRuleElementOid}); } List lastElementDOList = codeRuleElementDao.selectByRuleOidAndIndex(elementDO.getPkCodeRule(),elementDO.getRuleOrderNumber()+1); if(!CollectionUtils.isEmpty(lastElementDOList)){ OsCodeRuleElementDO elementDO1 = lastElementDOList.get(0); Integer index = elementDO1.getRuleOrderNumber(); elementDO1.setRuleOrderNumber(elementDO.getRuleOrderNumber()); elementDO.setRuleOrderNumber(index); codeRuleElementDao.updateByPrimaryKey(elementDO1); codeRuleElementDao.updateByPrimaryKey(elementDO); } } /** * 获取流程依据 * * @param ruleDTO 创建内容的数据传输对象 * @return 流水依据 */ @Override public String getSerialUnit(OsCodeRuleProduceDTO ruleDTO) { //判断规则的编号或者规则的主键 VciBaseUtil.alertNotNull(ruleDTO, "编码生成来源数据"); if (StringUtils.isBlank(ruleDTO.getCodeRuleId()) && StringUtils.isBlank(ruleDTO.getCodeRuleOid()) && (StringUtils.isBlank(ruleDTO.getUseRuleFlag()) || StringUtils.isBlank(ruleDTO.getOwnbizBtm()))) { throw new VciBaseException("编码规则主键和编号为空,无法生成编码"); } //查询编码规则,和相应的明细内容 OsCodeRuleDO ruleDO =getRuleByDTO(ruleDTO); List ruleItemDOs = listItemsByRuleOidOrderByRuleOrderNubmer(ruleDO.getOid()); VciBaseUtil.alertNotNull(ruleItemDOs,"规则的明细"); //查询生成编码的数据 Map businessDataMap = ruleDTO.getOwnbizDataMap(); //每一个元素产生的内容 List tempCode = new ArrayList(); //用来存储流水号的元素 Map serialItemMap = new HashMap(); //用来存储流水依据的元素 Map serialAccordingMap = new HashMap(); wrapperRuleElement(ruleItemDOs,ruleDTO,tempCode,businessDataMap,serialItemMap,serialAccordingMap); String serialAccordingString = ""; for (String value : serialAccordingMap.values()) { serialAccordingString += value; } if (StringUtils.isBlank(serialAccordingString)) { serialAccordingString = EMPTY_SERIAL_ACCORDING; } return serialAccordingString; } /** * 流水号生成 * * @param serialItemMap 需要生成流水号的元素 * @param serialAccordingMap 流水依据的元素映射 * @param breakReUseFlag 是否补码 * @param needAddQuantity 生成编码条数 * @throws VciBaseException 执行出错的时候会抛出异常 */ private synchronized Map batchWrapperSerial(Map serialItemMap, Map serialAccordingMap, String breakReUseFlag, Integer needAddQuantity) { String serialAccordingString = ""; Map returnMap = new HashMap(); for (String value : serialAccordingMap.values()) { serialAccordingString += value; } if (StringUtils.isBlank(serialAccordingString)) { serialAccordingString = EMPTY_SERIAL_ACCORDING; } String finalSerialAccordingString = serialAccordingString; //遍历生成对应位置的流水号元素 Set keySet = serialItemMap.keySet(); for (Integer tempIndex : keySet) { OsCodeRuleElementDO item = serialItemMap.get(tempIndex); String serialValue = ""; if (BooleanEnum.TRUE.getValue().equalsIgnoreCase(breakReUseFlag)) { //说明是支持断码来补的 OsCodeBreakCodeDO codeBreakCodeDO = breakCodeDao.selectByAccordingAndRuleOid(item.getPkCodeRule(), finalSerialAccordingString); if (codeBreakCodeDO != null || StringUtils.isBlank(codeBreakCodeDO.getOid())) { serialValue = codeBreakCodeDO.getBreakSerial() + ""; } } boolean persistence = WebUtil.isPersistence(); WebUtil.setPersistence(true); if (StringUtils.isBlank(serialValue)) { //找这个规则,当前流水号下的内容 OsCodeSerialNumberDO serialNumberDO = serialNumberDao.selectByAccordingAndRuleOid(item.getPkCodeRule(), finalSerialAccordingString); if (serialNumberDO == null || StringUtils.isBlank(serialNumberDO.getOid())) { //说明是第一个,需要添加 serialNumberDO = new OsCodeSerialNumberDO(); serialNumberDO.setPkCodeRule(item.getPkCodeRule()); serialNumberDO.setSerialUnit(finalSerialAccordingString); serialNumberDO.setMaxSerial(VciBaseUtil.getInt(item.getSerialStart()) + item.getSerialStep() * needAddQuantity); serialNumberDao.insert(serialNumberDO); serialValue = item.getSerialStart(); } else { //不是第一个,则重新计算起始值和最大值 serialValue = String.valueOf(serialNumberDO.getMaxSerial()); serialNumberDO.setMaxSerial(serialNumberDO.getMaxSerial() + item.getSerialStep() * needAddQuantity); serialNumberDao.updateByPrimaryKey(serialNumberDO); } } WebUtil.setPersistence(persistence); OsCodeSerialBuildBO serialBuildBO = new OsCodeSerialBuildBO(); serialBuildBO.setSerialUnit(serialAccordingString); serialBuildBO.setSerialNoList(new ArrayList()); serialBuildBO.setSerialCodeList(new ArrayList()); for (Integer i = 0; i < needAddQuantity; i++) { String serialNo = String.valueOf(Integer.parseInt(serialValue) + i * item.getSerialStep()); serialBuildBO.getSerialNoList().add(serialNo); serialBuildBO.getSerialCodeList().add(fillCode(item,serialNo)); } /* TODO 暂时取消,这个地方老出问题,需要再研究逻辑。 if (serialAccordingMap.containsKey(tempIndex) || serialAccordingMap.size() == 0) { returnMap.put(tempIndex,serialBuildBO); }*/ returnMap.put(tempIndex,serialBuildBO); } return returnMap; } /** * 列表查询 * * @param conditionMap 查询条件 * @param pageHelper 分页的对象 * @return 数据显示对象 */ @Override public DataGrid dataGrid(Map conditionMap, PageHelper pageHelper) { if (pageHelper == null) { pageHelper = new PageHelper(-1); } List ruleDOS = codeRuleDao.selectByWrapper(conditionMap, pageHelper); DataGrid dataGrid = new DataGrid(); if (!CollectionUtils.isEmpty(ruleDOS)) { dataGrid.setData(codeRuleDO2VOs(ruleDOS)); dataGrid.setTotal(VciBaseUtil.getInt(codeRuleDao.countByWrapper(conditionMap))); } return dataGrid; } /** * 数据对象批量转换为显示对象 * * @param ruleDOCollection 规则的数据对象 * @return 规则的显示对象 */ @Override public List codeRuleDO2VOs(Collection ruleDOCollection) { List ruleVOS = new ArrayList(); if (ruleDOCollection != null) { for (OsCodeRuleDO ruleDO : ruleDOCollection) { OsCodeRuleVO vo = codeRuleDO2VO(ruleDO); if (vo != null) { ruleVOS.add(vo); } } } return ruleVOS; } /** * 规则的元素的数据对象转换为显示对象 * * @param elementDOCollection 元素的数据对象 * @return 元素的显示对象 */ @Override public List codeRuleElementDO2VOs(Collection elementDOCollection) { List ruleElementVOS = new ArrayList(); if (elementDOCollection != null) { List oidList = new ArrayList(); for (OsCodeRuleElementDO elementDO : elementDOCollection) { OsCodeRuleElementVO vo = codeRuleElementDO2VO(elementDO); if (vo != null) { ruleElementVOS.add(vo); oidList.add(vo.getOid()); } } List existEnumDOs = codeEnumDao.selectByElementOidCollection(oidList); Map> enumVOMap = new HashMap>(); for(OsCodeEnumDO enumDO : existEnumDOs){ OsCodeEnumVO enumVO = new OsCodeEnumVO(); BeanUtil.convert(enumDO,enumVO); String pkCodeRuleElement = enumVO.getPkCodeRuleElement(); List enumVOS = enumVOMap.containsKey(pkCodeRuleElement) ? enumVOMap.get(pkCodeRuleElement) : new ArrayList(); enumVOS.add(enumVO); enumVOMap.put(pkCodeRuleElement, enumVOS); } for(OsCodeRuleElementVO elementVO : ruleElementVOS){ elementVO.setEnumMapList(enumVOMap.get(elementVO.getOid())); } } return ruleElementVOS; } /** * 数据对象转换为显示对象 * * @param ruleDO 规则的数据对象 * @return 规则的显示对象 */ @Override public OsCodeRuleVO codeRuleDO2VO(OsCodeRuleDO ruleDO) { OsCodeRuleVO ruleVO = new OsCodeRuleVO(); if (ruleDO != null) { BeanUtil.convert(ruleDO, ruleVO); ruleVO.setLcStatusText(FrameworkDataLCStatus.getTextByValue(ruleVO.getLcStatus())); ruleVO.setCodeProductTypeText(OsCodeProductTypeEnum.getTextByValue(ruleVO.getCodeProductType())); } return ruleVO; } /** * 明细的数据对象转换为显示对象 * * @param elementDO 明细的数据对象 * @return 显示对象 */ @Override public OsCodeRuleElementVO codeRuleElementDO2VO(OsCodeRuleElementDO elementDO) { OsCodeRuleElementVO elementVO = new OsCodeRuleElementVO(); if (elementDO != null) { BeanUtil.convert(elementDO, elementVO); elementVO.setCodeElementTypeText(OsCodeElementTypeEnum.getTextByValue(elementVO.getCodeElementType())); elementVO.setCodeFillTypeText(OsCodeFillTypeEnum.getTextByValue(elementVO.getCodeFillType())); elementVO.setCodeDateValueTypeText(OsCodeDateValueTypeEnum.getTextByValue(elementVO.getCodeDateValueType())); } return elementVO; } /** * 列表的明细查询 * * @param pkRule 规则的主键 * @param conditionMap 查询条件 * @param pageHelper 分页的对象 * @return 数据显示对象 */ @Override public DataGrid dataGridElement(String pkRule, Map conditionMap, PageHelper pageHelper) { if (pageHelper == null) { pageHelper = new PageHelper(-1); } if (conditionMap == null) { conditionMap = new HashMap(); } if (StringUtils.isBlank(pkRule)) { return new DataGrid(); } conditionMap.put("pkCodeRule", pkRule); List ruleDOS = codeRuleElementDao.selectByWrapper(conditionMap, pageHelper); DataGrid dataGrid = new DataGrid(); if (!CollectionUtils.isEmpty(ruleDOS)) { dataGrid.setData(codeRuleElementDO2VOs(ruleDOS)); dataGrid.setTotal(VciBaseUtil.getInt(codeRuleElementDao.countByWrapper(conditionMap))); } return dataGrid; } /** * 添加规则 * * @param ruleDTO 规则的数据传输对象,需要将明细也传递 * @return 显示对象 */ @Override public OsCodeRuleVO addRule(OsCodeRuleDTO ruleDTO) { VciBaseUtil.alertNotNull(ruleDTO, "数据传输对象", ruleDTO.getElements(), "规则的元素"); OsCodeRuleDO ruleDO = new OsCodeRuleDO(); BeanUtil.convert(ruleDTO, ruleDO); ruleDO.setOid(VciBaseUtil.getPk()); List elementDOS = new ArrayList(); List enumMapDOs = new ArrayList(); wrapperElementDOs(ruleDO.getOid(), ruleDTO.getElements(),elementDOS,enumMapDOs); //这个不可能超过1000个 codeRuleElementDao.batchInsert(elementDOS); if(!CollectionUtils.isEmpty(enumMapDOs)){ codeEnumDao.batchInsert(enumMapDOs); } codeRuleDao.insert(ruleDO); return codeRuleDO2VO(ruleDO); } /** * 封装元素的对象 * * @param pkRule 规则的主键 * @param elementDTOS 元素的数据传输对象 * @return 元素的数据对象 */ private List wrapperElementDOs(String pkRule, List elementDTOS, List elementDOS, List enumMapDOs) { if (elementDTOS != null) { for (OsCodeRuleElementDTO elementDTO : elementDTOS) { OsCodeRuleElementDO elementDO = new OsCodeRuleElementDO(); BeanUtil.convert(elementDTO, elementDO); elementDO.setPkCodeRule(pkRule); elementDO.setOid(VciBaseUtil.getPk()); //需要每个类型做处理 VciBaseUtil.alertNotNull(elementDO.getCodeElementType(), "元素类型"); OsCodeElementTypeEnum elementEn = OsCodeElementTypeEnum.forValue(elementDO.getCodeElementType()); if (elementEn == null) { throw new VciBaseException("元素的类型不符合要求"); } switch (elementEn) { case INPUT: //没有什么需要控制 break; case STATIC: VciBaseUtil.alertNotNull(elementDO.getStaticCode(), "常量值"); elementDO.setMaxLength(elementDO.getStaticCode().trim().length()); elementDO.setMinLength(elementDO.getStaticCode().trim().length()); elementDO.setCodeFillType(OsCodeFillTypeEnum.NONE.getValue()); elementDO.setCodeFillSeparator(""); break; case DATE: VciBaseUtil.alertNotNull(elementDO.getCodeDateFormat(), "日期格式", elementDO.getCodeDateValueType(), "日期的取值类型 "); if (OsCodeDateValueTypeEnum.BUSINESS.getValue().endsWith(elementDO.getCodeDateValueType())) { VciBaseUtil.alertNotNull(elementDO.getCodeDateUseField(), "日期值对应的属性名称"); } break; case FIELD: case ENUM: VciBaseUtil.alertNotNull(elementDO.getCodeUseField(), "所需属性名称",elementDO.getEnumId(),"枚举的编号",elementDTO.getEnumMapList(),"枚举的映射内容"); //处理枚举的内容 List enumMaps = elementDTO.getEnumMapList(); for(OsCodeEnumDTO enumDTO : enumMaps){ VciBaseUtil.alertNotNull(enumDTO.getEnumItemKey(),"枚举映射中枚举的值",enumDTO.getCodeMapValue(),"枚举映射的枚举对应的映射值"); OsCodeEnumDO enumDO = new OsCodeEnumDO(); BeanUtil.convert(enumDTO,enumDO); enumDO.setPkCodeRuleElement(elementDO.getOid()); enumMapDOs.add(enumDO); } break; case EXPRESSION: VciBaseUtil.alertNotNull(elementDO.getCodeExpression(), "公式表达式"); break; case SERIAL: VciBaseUtil.alertNotNull(elementDO.getSerialStart(), "流水起始值", elementDO.getSerialStep(), "流水步长", elementDO.getSerialPriority(), "流水优先级"); break; } elementDOS.add(elementDO); } } return elementDOS; } /** * 修改规则 * * @param ruleDTO 规则的数据传输对象,需要将明细也传递 * @return 显示对象 */ @Override public OsCodeRuleVO editRule(OsCodeRuleDTO ruleDTO) { VciBaseUtil.alertNotNull(ruleDTO, "数据传输对象", ruleDTO.getElements(), "规则的元素", ruleDTO.getOid(), "规则的主键"); OsCodeRuleDO ruleDO = selectByOid(ruleDTO.getOid()); BeanUtil.convert(ruleDTO,ruleDO); List existElementDOs = codeRuleElementDao.selectByRuleOid(ruleDO.getOid()); //找enum的明细内容,也是要删除的 List existEnumDOs = codeEnumDao.selectByRuleOid(ruleDO.getOid()); List elementDOS = new ArrayList(); List enumMapDOs = new ArrayList(); wrapperElementDOs(ruleDO.getOid(), ruleDTO.getElements(),elementDOS,enumMapDOs); if(!CollectionUtils.isEmpty(existElementDOs)) { List existElementOidList = new ArrayList(); for(OsCodeRuleElementDO elementDO : existElementDOs){ existElementOidList.add(elementDO.getOid()); } codeRuleElementDao.batchDeleteByOids(existElementOidList); } if(!CollectionUtils.isEmpty(existEnumDOs)){ List existEnumOidList = new ArrayList(); for(OsCodeEnumDO enumDO : existEnumDOs){ existEnumOidList.add(enumDO.getOid()); } codeEnumDao.batchDeleteByOids(existEnumOidList); } //这个不可能超过1000个 codeRuleElementDao.batchInsert(elementDOS); if(!CollectionUtils.isEmpty(enumMapDOs)){ codeEnumDao.batchInsert(enumMapDOs); } codeRuleDao.updateByPrimaryKey(ruleDO); return codeRuleDO2VO(ruleDO); } /** * 删除规则,有流水号的时候不能删除 * * @param ruleDTO 规则的数据传输对象,必须有ts和oid */ @Override public void deleteRule(OsCodeRuleDTO ruleDTO) { VciBaseUtil.alertNotNull(ruleDTO, "数据传输对象"); OsCodeRuleDO ruleDO = selectByOid(ruleDTO.getOid()); String ruleOid = ruleDO.getOid(); if (serialNumberDao.countByRuleOid(ruleOid) > 0) { throw new VciBaseException("编码规则已经产生了流水号,不能删除"); } codeRuleDao.deleteByPrimaryKey(ruleOid); List existElementDOs = codeRuleElementDao.selectByRuleOid(ruleOid); List existEnumDOs = codeEnumDao.selectByRuleOid(ruleDO.getOid()); if(!CollectionUtils.isEmpty(existElementDOs)) { List existElementOidList = new ArrayList(); for(OsCodeRuleElementDO elementDO : existElementDOs){ existElementOidList.add(elementDO.getOid()); } codeRuleElementDao.batchDeleteByOids(existElementOidList); } if(!CollectionUtils.isEmpty(existEnumDOs)){ List existEnumOidList = new ArrayList(); for(OsCodeEnumDO enumDO : existEnumDOs){ existEnumOidList.add(enumDO.getOid()); } codeEnumDao.batchDeleteByOids(existEnumOidList); } } /** * 停用规则 * * @param ruleDTO 规则的数据传输对象,必须有ts和oid */ @Override public void disableRule(OsCodeRuleDTO ruleDTO) { VciBaseUtil.alertNotNull(ruleDTO, "数据传输对象"); OsCodeRuleDO ruleDO = selectByOid(ruleDTO.getOid()); ruleDO.setLcStatus(FrameWorkDefaultValueConstant.FRAMEWORK_DATA_DISABLED); codeRuleDao.updateByPrimaryKey(ruleDO); } /** * 启用规则 * * @param ruleDTO 规则的数据传输对象,必须有ts和oid */ @Override public void enableRule(OsCodeRuleDTO ruleDTO) { VciBaseUtil.alertNotNull(ruleDTO, "数据传输对象"); OsCodeRuleDO ruleDO = selectByOid(ruleDTO.getOid()); ruleDO.setLcStatus(FrameWorkDefaultValueConstant.FRAMEWORK_DATA_ENABLED); codeRuleDao.updateByPrimaryKey(ruleDO); } /** * 使用规则标识查询 * * @param ownbizBtm 业务类型 * @param useRuleFlag 规则标识 * @return 规则的对象 * @throws VciBaseException 参数为空,规则不存在的会抛出异常 */ private OsCodeRuleDO selectByRuleFlag(String ownbizBtm, String useRuleFlag) throws VciBaseException { VciBaseUtil.alertNotNull(ownbizBtm, "业务类型", useRuleFlag, "使用标识"); OsCodeRuleDO ruleDO = codeRuleDao.selectByRuleFlag(ownbizBtm, useRuleFlag); if (ruleDO == null || StringUtils.isBlank(ruleDO.getOid())) { throw new VciBaseException("{0}业务类型中不存在{1}标识的编码规则", new String[]{ownbizBtm, useRuleFlag}); } return ruleDO; } /** * 流水号生成 * * @param serialItemMap 需要生成流水号的元素 * @param serialAccordingMap 流水依据的元素映射 * @param tempCode 已经生成的编码的内容 * @param breakReUseFlag 是否补码 * @throws VciBaseException 执行出错的时候会抛出异常 */ private synchronized void wrapperSerial(Map serialItemMap, Map serialAccordingMap, List tempCode, String breakReUseFlag) throws VciBaseException { Map buildBOMap = batchWrapperSerial(serialItemMap, serialAccordingMap, breakReUseFlag, 1); for(Integer serialIndex : buildBOMap.keySet()){ OsCodeSerialBuildBO buildBO = buildBOMap.get(serialIndex); tempCode.set(serialIndex,buildBO.getSerialCodeList().get(0)); } //批量和单个也得统一,weidy } /** * 补位 * * @param item 元素对象 * @param tempCode 生成的临时编码 * @return 补位后的字符串 */ private String fillCode(OsCodeRuleElementDO item, String tempCode) { if (tempCode == null) { tempCode = ""; } if (tempCode.trim().length() < item.getMaxLength()) { int needFillLength = item.getMaxLength() - tempCode.length(); for (int i = 0; i < needFillLength; i++) { String fillSepartor = item.getCodeFillSeparator(); if (VciBaseUtil.isNull(fillSepartor)) { fillSepartor = "0"; } OsCodeFillTypeEnum fillTypeEnum = OsCodeFillTypeEnum.forValue(item.getCodeFillType()); switch (fillTypeEnum) { case LEFT: tempCode = fillSepartor + tempCode; break; case RIGHT: tempCode = tempCode + fillSepartor; break; default: break; } } return tempCode; } else if (tempCode.length() > item.getMaxLength()) {//长度超长了要减去掉 tempCode = tempCode.substring(0, item.getMaxLength()); return tempCode; } else { return tempCode; } } /** * 规则的明细 * * @param ruleOid 规则的主键 * @return 规则的明细内容 * @throws VciBaseException 参数错误会抛出异常 */ private List listItemsByRuleOid(String ruleOid) throws VciBaseException { VciBaseUtil.alertNotNull(ruleOid, "规则的主键"); List codeRuleElementDOS = codeRuleElementDao.selectByRuleOid(ruleOid.trim()); return codeRuleElementDOS; } /** * 使用主键获取编码规则对象 * * @param oid 主键 * @return 编码规则对象 * @throws VciBaseException 参数错误,规则不存在时会抛出异常 */ private OsCodeRuleDO selectByOid(String oid) throws VciBaseException { VciBaseUtil.alertNotNull(oid, "编码规则主键"); OsCodeRuleDO codeRuleDO = codeRuleDao.selectByPrimaryKey(oid.trim()); if (codeRuleDO == null || StringUtils.isBlank(codeRuleDO.getOid())) { throw new VciBaseException(DATA_OID_NOT_EXIST); } return codeRuleDO; } /** * 使用编号获取编码规则对象 * * @param id 编号 * @return 编码规则对象 * @throws VciBaseException 参数错误,规则不存在时会抛出异常 */ @Override public OsCodeRuleDO selectById(String id) throws VciBaseException { VciBaseUtil.alertNotNull(id, "编码规则编号"); OsCodeRuleDO codeRuleDO = codeRuleDao.selectById(id.trim()); if (codeRuleDO == null || StringUtils.isBlank(codeRuleDO.getId())) { throw new VciBaseException(DATA_ID_NOT_EXIST); } return codeRuleDO; } }