package jnpf.elnService.cross.impl;
|
|
import cn.hutool.core.util.IdUtil;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import jnpf.elnEntity.field.ElnFieldDefEntity;
|
import jnpf.elnEntity.field.ElnFieldVersionEntity;
|
import jnpf.elnEntity.template.ElnTemplateBindingEntity;
|
import jnpf.elnEntity.template.ElnTemplateCrossReferenceEntity;
|
import jnpf.elnEntity.template.ElnTemplateForms;
|
import jnpf.elnEntity.template.ElnTemplateVersionEntity;
|
import jnpf.elnEntity.template.ElnTemplateVos;
|
import jnpf.elnMapper.ElnFieldDefMapper;
|
import jnpf.elnMapper.ElnFieldVersionMapper;
|
import jnpf.elnMapper.ElnTemplateBindingMapper;
|
import jnpf.elnMapper.ElnTemplateCrossReferenceMapper;
|
import jnpf.elnMapper.ElnTemplateMapper;
|
import jnpf.elnService.cross.ElnCrossTemplateScalarReferencePolicy;
|
import jnpf.elnService.cross.ElnCrossTemplateScalarReferenceService;
|
import jnpf.elnService.template.ElnTemplateBindingService;
|
import jnpf.elnService.template.TemplateAnnotationAuthorization;
|
import jnpf.exception.DataException;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.LinkedHashSet;
|
import java.util.List;
|
import java.util.Set;
|
|
@Service
|
public class ElnCrossTemplateScalarReferenceServiceImpl implements ElnCrossTemplateScalarReferenceService {
|
private final ElnTemplateMapper templateMapper;
|
private final ElnTemplateBindingMapper bindingMapper;
|
private final ElnFieldDefMapper fieldMapper;
|
private final ElnFieldVersionMapper versionMapper;
|
private final ElnTemplateCrossReferenceMapper referenceMapper;
|
private final ElnTemplateBindingService bindingService;
|
|
public ElnCrossTemplateScalarReferenceServiceImpl(ElnTemplateMapper templateMapper,
|
ElnTemplateBindingMapper bindingMapper, ElnFieldDefMapper fieldMapper,
|
ElnFieldVersionMapper versionMapper, ElnTemplateCrossReferenceMapper referenceMapper,
|
ElnTemplateBindingService bindingService) {
|
this.templateMapper = templateMapper;
|
this.bindingMapper = bindingMapper;
|
this.fieldMapper = fieldMapper;
|
this.versionMapper = versionMapper;
|
this.referenceMapper = referenceMapper;
|
this.bindingService = bindingService;
|
}
|
|
@Override
|
public List<ElnTemplateVos.CrossTemplateSourceTemplate> sourceTemplates(
|
TemplateAnnotationAuthorization authorization) {
|
String tenantId = authorization.getTenantId();
|
String targetId = authorization.getTemplateId();
|
String targetTemplateCode = targetTemplateCode(tenantId, targetId);
|
List<ElnTemplateVos.CrossTemplateSourceTemplate> result = new ArrayList<>();
|
List<ElnTemplateVersionEntity> templates = templateMapper.selectList(
|
Wrappers.<ElnTemplateVersionEntity>lambdaQuery().eq(ElnTemplateVersionEntity::getFTenantId, tenantId)
|
.eq(ElnTemplateVersionEntity::getBizStatus, "PUBLISHED")
|
.eq(ElnTemplateVersionEntity::getBizEnabled, "enabled")
|
.and(q -> q.isNull(ElnTemplateVersionEntity::getFDeleteMark)
|
.or().eq(ElnTemplateVersionEntity::getFDeleteMark, 0)));
|
for (ElnTemplateVersionEntity template : templates == null ? Collections.<ElnTemplateVersionEntity>emptyList() : templates) {
|
if (!eligibleSourceTemplate(tenantId, targetId, targetTemplateCode, template, null)) continue;
|
ElnTemplateVos.CrossTemplateSourceTemplate item =
|
new ElnTemplateVos.CrossTemplateSourceTemplate();
|
item.setSourceTemplateId(template.getId());
|
item.setSourceTemplateCode(template.getMubanBianhao());
|
result.add(item);
|
}
|
return result;
|
}
|
|
@Override
|
public List<ElnTemplateVos.CrossTemplateScalarCandidate> candidates(
|
TemplateAnnotationAuthorization authorization, String sourceTemplateId) {
|
if (!StringUtils.hasText(sourceTemplateId)) return Collections.emptyList();
|
String tenantId = authorization.getTenantId();
|
String targetId = authorization.getTemplateId();
|
String targetTemplateCode = targetTemplateCode(tenantId, targetId);
|
String actualSourceTemplateId = sourceTemplateId.trim();
|
ElnTemplateVersionEntity template = templateMapper.selectOne(
|
Wrappers.<ElnTemplateVersionEntity>lambdaQuery()
|
.eq(ElnTemplateVersionEntity::getFTenantId, tenantId)
|
.eq(ElnTemplateVersionEntity::getId, actualSourceTemplateId)
|
.eq(ElnTemplateVersionEntity::getBizStatus, "PUBLISHED")
|
.eq(ElnTemplateVersionEntity::getBizEnabled, "enabled")
|
.and(q -> q.isNull(ElnTemplateVersionEntity::getFDeleteMark)
|
.or().eq(ElnTemplateVersionEntity::getFDeleteMark, 0)));
|
if (!eligibleSourceTemplate(tenantId, targetId, targetTemplateCode, template, actualSourceTemplateId)) {
|
return Collections.emptyList();
|
}
|
List<ElnTemplateVos.CrossTemplateScalarCandidate> result = new ArrayList<>();
|
List<ElnTemplateBindingEntity> bindings = bindingMapper.selectList(
|
Wrappers.<ElnTemplateBindingEntity>lambdaQuery()
|
.eq(ElnTemplateBindingEntity::getFTenantId, tenantId)
|
.eq(ElnTemplateBindingEntity::getMubanId, actualSourceTemplateId)
|
.eq(ElnTemplateBindingEntity::getBangdingZhuangtai, "ACTIVE")
|
.eq(ElnTemplateBindingEntity::getKongjianJuese, "PRIMARY")
|
.and(q -> q.isNull(ElnTemplateBindingEntity::getFDeleteMark)
|
.or().eq(ElnTemplateBindingEntity::getFDeleteMark, 0)));
|
for (ElnTemplateBindingEntity binding
|
: bindings == null ? Collections.<ElnTemplateBindingEntity>emptyList() : bindings) {
|
ElnFieldDefEntity field = fieldMapper.selectById(binding.getZiduanDingyiId());
|
ElnFieldVersionEntity version = versionMapper.selectById(binding.getZiduanBanbenId());
|
if (field == null || version == null || !tenantId.equals(binding.getFTenantId())
|
|| !tenantId.equals(field.getFTenantId()) || !tenantId.equals(version.getFTenantId())
|
|| deleted(binding.getFDeleteMark()) || deleted(field.getFDeleteMark())
|
|| deleted(version.getFDeleteMark()) || !"enabled".equals(field.getBizEnabled())
|
|| !binding.getZiduanDingyiId().equals(version.getZiduanDingyiId())
|
|| !ElnCrossTemplateScalarReferencePolicy.isEligible(targetId, template.getId(), template.getBizStatus(),
|
field.getZuoyongFanwei(), version, binding)) continue;
|
ElnTemplateVos.CrossTemplateScalarCandidate item = new ElnTemplateVos.CrossTemplateScalarCandidate();
|
item.setSourceTemplateId(template.getId());
|
item.setSourceTemplateCode(template.getMubanBianhao());
|
item.setSourceFieldId(field.getId());
|
item.setSourceFieldCode(field.getZiduanBianma());
|
item.setSourceFieldVersionId(version.getId());
|
item.setSourceFieldName(version.getZiduanMingcheng());
|
item.setSourceFieldType(version.getShujuLeixing());
|
result.add(item);
|
}
|
return result;
|
}
|
|
private String targetTemplateCode(String tenantId, String targetId) {
|
ElnTemplateVersionEntity target = templateMapper.selectById(targetId);
|
return target != null && tenantId.equals(target.getFTenantId())
|
? target.getMubanBianhao() : null;
|
}
|
|
private static boolean eligibleSourceTemplate(String tenantId, String targetId,
|
String targetTemplateCode, ElnTemplateVersionEntity template, String expectedId) {
|
return template != null && tenantId.equals(template.getFTenantId())
|
&& (expectedId == null || expectedId.equals(template.getId()))
|
&& !targetId.equals(template.getId())
|
&& (!StringUtils.hasText(targetTemplateCode)
|
|| !targetTemplateCode.equals(template.getMubanBianhao()))
|
&& "PUBLISHED".equals(template.getBizStatus())
|
&& "enabled".equals(template.getBizEnabled()) && !deleted(template.getFDeleteMark())
|
&& StringUtils.hasText(template.getMubanBianhao());
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public ElnTemplateVos.Binding reserve(TemplateAnnotationAuthorization authorization,
|
ElnTemplateForms.ReserveCrossTemplateScalarBinding form) {
|
if (form != null && StringUtils.hasText(form.getCheckboxGroupCode())) {
|
throw new DataException("跨模板只读字段不能加入选择组");
|
}
|
if (form == null || !StringUtils.hasText(form.getSourceTemplateId()) || !StringUtils.hasText(form.getSourceTemplateCode())
|
|| !StringUtils.hasText(form.getSourceFieldId()) || !StringUtils.hasText(form.getSourceFieldVersionId())) {
|
throw new DataException("跨模板字段来源不能为空");
|
}
|
ElnTemplateVos.CrossTemplateScalarCandidate selected = null;
|
for (ElnTemplateVos.CrossTemplateScalarCandidate item
|
: candidates(authorization, form.getSourceTemplateId())) {
|
if (form.getSourceTemplateId().trim().equals(item.getSourceTemplateId())
|
&& form.getSourceTemplateCode().trim().equals(item.getSourceTemplateCode())
|
&& form.getSourceFieldId().trim().equals(item.getSourceFieldId())
|
&& form.getSourceFieldVersionId().trim().equals(item.getSourceFieldVersionId())) {
|
selected = item;
|
break;
|
}
|
}
|
if (selected == null) throw new DataException("跨模板文本字段来源无效或已失效");
|
form.setFieldId(selected.getSourceFieldId());
|
form.setFieldVersionId(selected.getSourceFieldVersionId());
|
form.setRepeatRequest(false);
|
ElnTemplateVos.Binding binding = bindingService.reservePrimary(authorization, form);
|
ElnTemplateCrossReferenceEntity existing = referenceMapper.selectOne(
|
Wrappers.<ElnTemplateCrossReferenceEntity>lambdaQuery().eq(ElnTemplateCrossReferenceEntity::getFTenantId, authorization.getTenantId())
|
.eq(ElnTemplateCrossReferenceEntity::getMubanBangdingId, binding.getId()));
|
if (existing != null) {
|
if (!selected.getSourceTemplateCode().equals(existing.getLaiyuanMubanBianhao())
|
|| !selected.getSourceFieldVersionId().equals(existing.getLaiyuanZiduanBanbenId())) {
|
throw new DataException("绑定操作码已用于其他跨模板来源");
|
}
|
markReadOnly(binding);
|
return binding;
|
}
|
ElnTemplateCrossReferenceEntity reference = new ElnTemplateCrossReferenceEntity();
|
reference.setId(IdUtil.getSnowflakeNextIdStr());
|
reference.setMubanBangdingId(binding.getId());
|
reference.setLaiyuanMubanId(selected.getSourceTemplateId());
|
reference.setLaiyuanMubanBianhao(selected.getSourceTemplateCode());
|
reference.setLaiyuanZiduanDingyiId(selected.getSourceFieldId());
|
reference.setLaiyuanZiduanBanbenId(selected.getSourceFieldVersionId());
|
reference.setFTenantId(authorization.getTenantId());
|
reference.setFDeleteMark(0);
|
if (referenceMapper.insert(reference) != 1) throw new DataException("跨模板字段规则保存失败");
|
markReadOnly(binding);
|
return binding;
|
}
|
|
@Override
|
public ElnTemplateVos.AnnotationContext decorate(
|
TemplateAnnotationAuthorization authorization,
|
ElnTemplateVos.AnnotationContext context) {
|
if (context == null || context.getBindings() == null || context.getBindings().isEmpty()) {
|
return context;
|
}
|
Set<String> bindingIds = new LinkedHashSet<>();
|
for (ElnTemplateVos.Binding binding : context.getBindings()) {
|
if (binding != null && StringUtils.hasText(binding.getId())) bindingIds.add(binding.getId());
|
}
|
if (bindingIds.isEmpty()) return context;
|
List<ElnTemplateCrossReferenceEntity> references = referenceMapper.selectList(
|
Wrappers.<ElnTemplateCrossReferenceEntity>lambdaQuery()
|
.eq(ElnTemplateCrossReferenceEntity::getFTenantId,
|
authorization.getTenantId())
|
.in(ElnTemplateCrossReferenceEntity::getMubanBangdingId, bindingIds)
|
.eq(ElnTemplateCrossReferenceEntity::getFDeleteMark, 0));
|
Set<String> crossBindingIds = new LinkedHashSet<>();
|
for (ElnTemplateCrossReferenceEntity reference
|
: references == null
|
? Collections.<ElnTemplateCrossReferenceEntity>emptyList() : references) {
|
if (reference != null) crossBindingIds.add(reference.getMubanBangdingId());
|
}
|
for (ElnTemplateVos.Binding binding : context.getBindings()) {
|
if (binding != null && crossBindingIds.contains(binding.getId())) markReadOnly(binding);
|
}
|
return context;
|
}
|
|
private static void markReadOnly(ElnTemplateVos.Binding binding) {
|
binding.setValueSource("CROSS_TEMPLATE");
|
binding.setReadOnly(true);
|
}
|
|
private static boolean deleted(Integer deleteMark) {
|
return deleteMark != null && deleteMark != 0;
|
}
|
}
|