package jnpf.elnService.formula.impl; import cn.hutool.core.util.IdUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import jnpf.elnEntity.formula.ElnFormulaVersionEntity; import jnpf.elnEntity.formula.ElnTemplateFormulaBindingEntity; import jnpf.elnEntity.template.ElnTemplateVersionEntity; import jnpf.elnMapper.ElnTemplateMapper; import jnpf.elnMapper.ElnFormulaVersionMapper; import jnpf.elnMapper.ElnTemplateFormulaBindingMapper; import jnpf.elnService.template.ElnTemplateVersionCopyParticipant; import jnpf.exception.DataException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Supplier; @Service public class FormulaTemplateVersionCopyParticipant implements ElnTemplateVersionCopyParticipant { private final Store store; private final Supplier idSupplier; @Autowired public FormulaTemplateVersionCopyParticipant(ElnTemplateMapper templateMapper, ElnTemplateFormulaBindingMapper bindingMapper, ElnFormulaVersionMapper formulaVersionMapper) { this(new MyBatisStore(templateMapper, bindingMapper, formulaVersionMapper), IdUtil::getSnowflakeNextIdStr); } public FormulaTemplateVersionCopyParticipant(Store store, Supplier idSupplier) { this.store = store; this.idSupplier = idSupplier; } @Override public void afterBindingsActivated(String tenantId, String sourceTemplateId, String targetTemplateId, Map bindingIdMap) { ElnTemplateVersionEntity target = store.findTemplate(tenantId, targetTemplateId); if (target == null || !StringUtils.hasText(target.getShengbanCaozuoBianma())) throw new DataException("目标模板升版操作不存在"); for (ElnTemplateFormulaBindingEntity source : store.listActive(tenantId, sourceTemplateId)) { ElnFormulaVersionEntity formulaVersion = store.findFormulaVersion( tenantId, source.getGongshiBanbenId()); boolean published = formulaVersion != null && "PUBLISHED".equals(formulaVersion.getBizStatus()); boolean draftTargetPreRelease = formulaVersion != null && "DRAFT".equals(target.getBizStatus()) && "PRE_RELEASE".equals(formulaVersion.getBizStatus()); if ((!published && !draftTargetPreRelease) || !source.getGongshiDingyiId().equals(formulaVersion.getGongshiDingyiId())) throw new DataException("模板升版只能继承已发布公式版本或由草稿模板继承预发布公式版本"); String operation = target.getShengbanCaozuoBianma() + ":" + source.getId(); ElnTemplateFormulaBindingEntity existing = store.findByOperation( tenantId, targetTemplateId, operation); Map parameters = new LinkedHashMap<>(); for (Map.Entry item : source.getCanshuYingshe().entrySet()) { String mapped = bindingIdMap.get(item.getValue()); if (!StringUtils.hasText(mapped)) throw new DataException("模板升版字段映射不完整"); parameters.put(item.getKey(), mapped); } String resultBinding = bindingIdMap.get(source.getJieguoBangdingId()); if (!StringUtils.hasText(resultBinding)) throw new DataException("模板升版结果字段映射缺失"); ElnTemplateFormulaBindingEntity copied = new ElnTemplateFormulaBindingEntity(); copied.setId(idSupplier.get()); copied.setFTenantId(tenantId); copied.setMubanId(targetTemplateId); copied.setGongshiDingyiId(source.getGongshiDingyiId()); copied.setGongshiBanbenId(source.getGongshiBanbenId()); copied.setCanshuYingshe(parameters); copied.setJieguoBangdingId(resultBinding); copied.setBangdingZhuangtai("PENDING"); copied.setCaozuoBianma(operation); copied.setLaiyuanGongshiBangdingId(source.getId()); copied.setDaoqiShijian(null); copied.setFVersion(1); copied.setFCreatorTime(new Date()); copied.setFDeleteMark(0); if (existing != null) { if (!sameCopy(existing, copied)) throw new DataException("操作码已用于其他公式映射请求"); continue; } if (!store.insertIfAbsent(copied)) { ElnTemplateFormulaBindingEntity concurrent = store.findByOperation( tenantId, targetTemplateId, operation); if (concurrent == null || !sameCopy(concurrent, copied)) throw new DataException("操作码已用于其他公式映射请求"); } } } private static boolean sameCopy(ElnTemplateFormulaBindingEntity actual, ElnTemplateFormulaBindingEntity planned) { return Objects.equals(actual.getFTenantId(), planned.getFTenantId()) && Objects.equals(actual.getMubanId(), planned.getMubanId()) && Objects.equals(actual.getLaiyuanGongshiBangdingId(), planned.getLaiyuanGongshiBangdingId()) && Objects.equals(actual.getGongshiDingyiId(), planned.getGongshiDingyiId()) && Objects.equals(actual.getGongshiBanbenId(), planned.getGongshiBanbenId()) && Objects.equals(actual.getCanshuYingshe(), planned.getCanshuYingshe()) && Objects.equals(actual.getJieguoBangdingId(), planned.getJieguoBangdingId()) && Objects.equals(actual.getCaozuoBianma(), planned.getCaozuoBianma()) && actual.getDaoqiShijian() == null && ("PENDING".equals(actual.getBangdingZhuangtai()) || "ACTIVE".equals(actual.getBangdingZhuangtai())); } public interface Store { ElnTemplateVersionEntity findTemplate(String tenantId, String templateId); List listActive(String tenantId, String sourceTemplateId); ElnFormulaVersionEntity findFormulaVersion(String tenantId, String versionId); ElnTemplateFormulaBindingEntity findByOperation( String tenantId, String targetTemplateId, String operationCode); boolean insertIfAbsent(ElnTemplateFormulaBindingEntity binding); } private static final class MyBatisStore implements Store { private final ElnTemplateMapper templates; private final ElnTemplateFormulaBindingMapper bindings; private final ElnFormulaVersionMapper formulaVersions; private MyBatisStore(ElnTemplateMapper templates, ElnTemplateFormulaBindingMapper bindings, ElnFormulaVersionMapper formulaVersions) { this.templates = templates; this.bindings = bindings; this.formulaVersions = formulaVersions; } @Override public ElnTemplateVersionEntity findTemplate(String tenantId, String templateId) { return templates.selectOne(Wrappers.lambdaQuery() .eq(ElnTemplateVersionEntity::getFTenantId, tenantId) .eq(ElnTemplateVersionEntity::getId, templateId) .and(q -> q.isNull(ElnTemplateVersionEntity::getFDeleteMark) .or().eq(ElnTemplateVersionEntity::getFDeleteMark, 0))); } @Override public List listActive( String tenantId, String sourceTemplateId) { return bindings.selectList(Wrappers.lambdaQuery() .eq(ElnTemplateFormulaBindingEntity::getFTenantId, tenantId) .eq(ElnTemplateFormulaBindingEntity::getMubanId, sourceTemplateId) .eq(ElnTemplateFormulaBindingEntity::getBangdingZhuangtai, "ACTIVE") .and(q -> q.isNull(ElnTemplateFormulaBindingEntity::getFDeleteMark) .or().eq(ElnTemplateFormulaBindingEntity::getFDeleteMark, 0)) .orderByAsc(ElnTemplateFormulaBindingEntity::getId)); } @Override public ElnFormulaVersionEntity findFormulaVersion( String tenantId, String versionId) { return formulaVersions.selectOne(Wrappers.lambdaQuery() .eq(ElnFormulaVersionEntity::getFTenantId, tenantId) .eq(ElnFormulaVersionEntity::getId, versionId) .and(q -> q.isNull(ElnFormulaVersionEntity::getFDeleteMark) .or().eq(ElnFormulaVersionEntity::getFDeleteMark, 0))); } @Override public ElnTemplateFormulaBindingEntity findByOperation( String tenantId, String targetTemplateId, String operationCode) { return bindings.selectOne(Wrappers.lambdaQuery() .eq(ElnTemplateFormulaBindingEntity::getFTenantId, tenantId) .eq(ElnTemplateFormulaBindingEntity::getMubanId, targetTemplateId) .eq(ElnTemplateFormulaBindingEntity::getCaozuoBianma, operationCode) .and(q -> q.isNull(ElnTemplateFormulaBindingEntity::getFDeleteMark) .or().eq(ElnTemplateFormulaBindingEntity::getFDeleteMark, 0))); } @Override public boolean insertIfAbsent(ElnTemplateFormulaBindingEntity binding) { return bindings.insertIfAbsent(binding) == 1; } } }