package jnpf.elnService.formula.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import jnpf.elnEntity.field.ElnFieldVersionEntity; import jnpf.elnEntity.formula.ElnFormulaDefEntity; import jnpf.elnEntity.formula.ElnFormulaParameterSlotEntity; import jnpf.elnEntity.formula.ElnFormulaVersionEntity; import jnpf.elnEntity.formula.ElnTemplateFormulaBindingEntity; import jnpf.elnEntity.template.ElnTemplateBindingEntity; import jnpf.elnEntity.template.ElnTemplateVos; import jnpf.elnMapper.ElnFieldVersionMapper; import jnpf.elnMapper.ElnFormulaDefMapper; import jnpf.elnMapper.ElnFormulaParameterSlotMapper; import jnpf.elnMapper.ElnFormulaVersionMapper; import jnpf.elnMapper.ElnTemplateBindingMapper; import jnpf.elnMapper.ElnTemplateFormulaBindingMapper; import jnpf.elnService.template.ElnTemplateBindingDependencyValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @Service public class FormulaFieldBindingDependencyValidator implements ElnTemplateBindingDependencyValidator { private final Store store; @Autowired public FormulaFieldBindingDependencyValidator(ElnTemplateFormulaBindingMapper formulas, ElnTemplateBindingMapper fields, ElnFieldVersionMapper fieldVersions, ElnFormulaVersionMapper formulaVersions, ElnFormulaDefMapper definitions, ElnFormulaParameterSlotMapper slots) { this(new MyBatisStore(formulas, fields, fieldVersions, formulaVersions, definitions, slots)); } public FormulaFieldBindingDependencyValidator(Store store) { this.store = store; } @Override public List validateUpgrade(String tenantId, String templateId, Set bindingIds, String targetFieldVersionId) { ElnFieldVersionEntity target = store.findFieldVersion(tenantId, targetFieldVersionId); if (target == null) return Collections.singletonList(diagnostic( "FORMULA_FIELD_TYPE_MISMATCH", "目标字段版本不存在", null)); List result = new ArrayList<>(); for (ElnTemplateFormulaBindingEntity formula : live(tenantId, templateId)) { ElnFormulaVersionEntity version = store.findFormulaVersion( tenantId, formula.getGongshiBanbenId()); if (version == null) continue; if (bindingIds.contains(formula.getJieguoBangdingId()) && !compatible(version.getJieguoLeixing(), target.getShujuLeixing())) result.add(diagnostic("FORMULA_FIELD_TYPE_MISMATCH", "字段升级后与公式结果类型不兼容", formula.getJieguoBangdingId())); Map mapped = formula.getCanshuYingshe(); for (ElnFormulaParameterSlotEntity slot : store.listSlots(tenantId, version.getId())) { String fieldBindingId = mapped.get(slot.getCanshuBianma()); if (bindingIds.contains(fieldBindingId) && !compatible(slot.getShujuLeixing(), target.getShujuLeixing())) result.add(diagnostic("FORMULA_FIELD_TYPE_MISMATCH", "字段升级后与公式参数类型不兼容", fieldBindingId)); } } return result; } @Override public List validateRemoval(String tenantId, String templateId, Set bindingIds) { List result = new ArrayList<>(); for (ElnTemplateFormulaBindingEntity formula : live(tenantId, templateId)) { for (String id : bindingIds) { if (id.equals(formula.getJieguoBangdingId()) || formula.getCanshuYingshe().containsValue(id)) result.add(diagnostic("FORMULA_FIELD_IN_USE", "字段仍被活动或待确认公式映射引用", id)); } } return result; } @Override public List validatePromotion(String tenantId, String templateId, String primaryBindingId, String referenceBindingId) { return validateRemoval(tenantId, templateId, Collections.singleton(primaryBindingId)); } @Override public List validateCheckboxGroup( String tenantId, String templateId, String bindingId) { for (ElnTemplateFormulaBindingEntity formula : live(tenantId, templateId)) { if (bindingId != null && bindingId.equals(formula.getJieguoBangdingId())) { return Collections.singletonList(diagnostic( "CHECKBOX_GROUP_FORMULA_RESULT_READ_ONLY", "公式结果字段不能加入选择组", bindingId)); } } return Collections.emptyList(); } private List live(String tenantId, String templateId) { List result = new ArrayList<>(); for (ElnTemplateFormulaBindingEntity item : store.listFormulaBindings(tenantId, templateId)) if ("ACTIVE".equals(item.getBangdingZhuangtai()) || "PENDING".equals(item.getBangdingZhuangtai())) result.add(item); return result; } static boolean compatible(String formulaType, String fieldType) { return "DECIMAL".equals(formulaType) && "DECIMAL".equals(fieldType) || "TEXT".equals(formulaType) && ("TEXT".equals(fieldType) || "TEXTAREA".equals(fieldType) || "SELECT".equals(fieldType)) || "BOOLEAN".equals(formulaType) && "CHECKBOX".equals(fieldType); } private static ElnTemplateVos.Diagnostic diagnostic(String code, String message, String id) { ElnTemplateVos.Diagnostic result = new ElnTemplateVos.Diagnostic(); result.setSeverity("ERROR"); result.setCode(code); result.setMessage(message); result.setBindingId(id); return result; } public interface Store { List listFormulaBindings(String tenantId, String templateId); ElnTemplateBindingEntity findFieldBinding(String tenantId, String id); List listFieldBindings(String tenantId, String templateId); ElnFieldVersionEntity findFieldVersion(String tenantId, String id); ElnFormulaVersionEntity findFormulaVersion(String tenantId, String id); ElnFormulaDefEntity findFormulaDefinition(String tenantId, String id); List listSlots(String tenantId, String versionId); } static class MyBatisStore implements Store { final ElnTemplateFormulaBindingMapper formulas; final ElnTemplateBindingMapper fields; final ElnFieldVersionMapper fieldVersions; final ElnFormulaVersionMapper formulaVersions; final ElnFormulaDefMapper definitions; final ElnFormulaParameterSlotMapper slots; MyBatisStore(ElnTemplateFormulaBindingMapper formulas, ElnTemplateBindingMapper fields, ElnFieldVersionMapper fieldVersions, ElnFormulaVersionMapper formulaVersions, ElnFormulaDefMapper definitions, ElnFormulaParameterSlotMapper slots) { this.formulas=formulas;this.fields=fields;this.fieldVersions=fieldVersions; this.formulaVersions=formulaVersions;this.definitions=definitions;this.slots=slots; } @Override public List listFormulaBindings(String t,String m){return formulas.selectList(Wrappers.lambdaQuery().eq(ElnTemplateFormulaBindingEntity::getFTenantId,t).eq(ElnTemplateFormulaBindingEntity::getMubanId,m).and(q->q.isNull(ElnTemplateFormulaBindingEntity::getFDeleteMark).or().eq(ElnTemplateFormulaBindingEntity::getFDeleteMark,0)));} @Override public ElnTemplateBindingEntity findFieldBinding(String t,String id){return fields.selectOne(Wrappers.lambdaQuery().eq(ElnTemplateBindingEntity::getFTenantId,t).eq(ElnTemplateBindingEntity::getId,id).and(q->q.isNull(ElnTemplateBindingEntity::getFDeleteMark).or().eq(ElnTemplateBindingEntity::getFDeleteMark,0)));} @Override public List listFieldBindings(String t,String m){return fields.selectList(Wrappers.lambdaQuery().eq(ElnTemplateBindingEntity::getFTenantId,t).eq(ElnTemplateBindingEntity::getMubanId,m).and(q->q.isNull(ElnTemplateBindingEntity::getFDeleteMark).or().eq(ElnTemplateBindingEntity::getFDeleteMark,0)));} @Override public ElnFieldVersionEntity findFieldVersion(String t,String id){return fieldVersions.selectOne(Wrappers.lambdaQuery().eq(ElnFieldVersionEntity::getFTenantId,t).eq(ElnFieldVersionEntity::getId,id).and(q->q.isNull(ElnFieldVersionEntity::getFDeleteMark).or().eq(ElnFieldVersionEntity::getFDeleteMark,0)));} @Override public ElnFormulaVersionEntity findFormulaVersion(String t,String id){return formulaVersions.selectOne(Wrappers.lambdaQuery().eq(ElnFormulaVersionEntity::getFTenantId,t).eq(ElnFormulaVersionEntity::getId,id).and(q->q.isNull(ElnFormulaVersionEntity::getFDeleteMark).or().eq(ElnFormulaVersionEntity::getFDeleteMark,0)));} @Override public ElnFormulaDefEntity findFormulaDefinition(String t,String id){return definitions.selectOne(Wrappers.lambdaQuery().eq(ElnFormulaDefEntity::getFTenantId,t).eq(ElnFormulaDefEntity::getId,id).and(q->q.isNull(ElnFormulaDefEntity::getFDeleteMark).or().eq(ElnFormulaDefEntity::getFDeleteMark,0)));} @Override public List listSlots(String t,String id){return slots.selectList(Wrappers.lambdaQuery().eq(ElnFormulaParameterSlotEntity::getFTenantId,t).eq(ElnFormulaParameterSlotEntity::getGongshiBanbenId,id).and(q->q.isNull(ElnFormulaParameterSlotEntity::getFDeleteMark).or().eq(ElnFormulaParameterSlotEntity::getFDeleteMark,0)));} } }