package jnpf.elnService.template.impl; import cn.hutool.core.util.IdUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import jnpf.elnEntity.template.ElnTemplateCheckboxGroupEntity; import jnpf.elnEntity.template.ElnTemplateVos; import jnpf.elnMapper.ElnTemplateCheckboxGroupMapper; import jnpf.elnService.template.ElnTemplateCheckboxGroupService; import jnpf.exception.DataException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Supplier; @Service public class ElnTemplateCheckboxGroupServiceImpl implements ElnTemplateCheckboxGroupService { public static final int DEFAULT_MIN_SELECTED = 0; public static final int DEFAULT_MAX_SELECTED = 1; private final Store store; private final Supplier idSupplier; @Autowired public ElnTemplateCheckboxGroupServiceImpl(ElnTemplateCheckboxGroupMapper mapper) { this(new MyBatisStore(mapper), IdUtil::getSnowflakeNextIdStr); } public ElnTemplateCheckboxGroupServiceImpl(Store store, Supplier idSupplier) { this.store = store; this.idSupplier = idSupplier; } @Override public List list(String tenantId, String templateId) { requireIdentity(tenantId, templateId); List result = new ArrayList<>(); for (ElnTemplateCheckboxGroupEntity entity : store.list(tenantId.trim(), templateId.trim())) { result.add(toVo(entity)); } result.sort(Comparator.comparing(ElnTemplateVos.CheckboxGroup::getGroupCode)); return result; } @Override @Transactional public ElnTemplateVos.CheckboxGroup ensureConfigured(String tenantId, String templateId, String groupCode, Integer minSelected, Integer maxSelected, String operatorId) { requireIdentity(tenantId, templateId); String code = requireGroupCode(groupCode); int min = minSelected == null ? DEFAULT_MIN_SELECTED : minSelected; validateRange(min, maxSelected); ElnTemplateCheckboxGroupEntity existing = store.find(tenantId.trim(), templateId.trim(), code); if (existing != null) { ElnTemplateVos.CheckboxGroup current = toVo(existing); if (!Objects.equals(min, current.getMinSelected()) || !Objects.equals(maxSelected, current.getMaxSelected())) { throw new DataException("选择组配置与已有配置不一致"); } return current; } ElnTemplateCheckboxGroupEntity created = new ElnTemplateCheckboxGroupEntity(); created.setId(requireId(idSupplier.get())); created.setFTenantId(tenantId.trim()); created.setMubanId(templateId.trim()); created.setGroupCode(code); created.setMinSelected(min); created.setMaxSelected(maxSelected); created.setFVersion(0); created.setFCreatorUserId(trim(operatorId)); created.setFLastModifyUserId(trim(operatorId)); created.setFCreatorTime(new Date()); created.setFLastModifyTime(new Date()); created.setFDeleteMark(0); store.insert(created); return toVo(created); } @Override @Transactional public ElnTemplateVos.CheckboxGroup change(String tenantId, String templateId, String groupCode, Integer minSelected, Integer maxSelected, Integer expectedVersion, String operatorId) { requireIdentity(tenantId, templateId); String code = requireGroupCode(groupCode); if (expectedVersion == null) throw new DataException("选择组期望版本不能为空"); int min = minSelected == null ? DEFAULT_MIN_SELECTED : minSelected; validateRange(min, maxSelected); ElnTemplateCheckboxGroupEntity current = store.find(tenantId.trim(), templateId.trim(), code); if (current == null) throw new DataException("选择组不存在"); if (!expectedVersion.equals(current.getFVersion())) { throw new DataException("选择组配置已被其他用户更新,请刷新后重试"); } ElnTemplateCheckboxGroupEntity changed = copy(current); changed.setMinSelected(min); changed.setMaxSelected(maxSelected); changed.setFLastModifyUserId(trim(operatorId)); changed.setFLastModifyTime(new Date()); if (!store.update(changed, expectedVersion)) { throw new DataException("选择组配置已被其他用户更新,请刷新后重试"); } return toVo(store.find(tenantId.trim(), templateId.trim(), code)); } @Override @Transactional public void removeUnused(String tenantId, String templateId, Set usedGroupCodes, String operatorId) { requireIdentity(tenantId, templateId); Set used = usedGroupCodes == null ? java.util.Collections.emptySet() : usedGroupCodes; for (ElnTemplateCheckboxGroupEntity current : store.list(tenantId.trim(), templateId.trim())) { if (used.contains(current.getGroupCode())) continue; ElnTemplateCheckboxGroupEntity removed = copy(current); removed.setFLastModifyUserId(trim(operatorId)); removed.setFLastModifyTime(new Date()); if (!store.softDelete(removed, current.getFVersion())) { throw new DataException("选择组配置已被其他用户更新,请刷新后重试"); } } } @Override @Transactional public void afterBindingsActivated(String tenantId, String sourceTemplateId, String targetTemplateId, Map bindingIdMap) { copyForVersion(tenantId, sourceTemplateId, targetTemplateId); } @Override @Transactional public void copyForVersion(String tenantId, String sourceTemplateId, String targetTemplateId) { requireIdentity(tenantId, sourceTemplateId); requireIdentity(tenantId, targetTemplateId); for (ElnTemplateCheckboxGroupEntity source : store.list(tenantId.trim(), sourceTemplateId.trim())) { ElnTemplateVos.CheckboxGroup rule = toVo(source); ElnTemplateCheckboxGroupEntity existing = store.find( tenantId.trim(), targetTemplateId.trim(), rule.getGroupCode()); if (existing != null) { ElnTemplateVos.CheckboxGroup target = toVo(existing); if (!Objects.equals(rule.getMinSelected(), target.getMinSelected()) || !Objects.equals(rule.getMaxSelected(), target.getMaxSelected())) { throw new DataException("目标模板选择组配置与来源版本不一致"); } continue; } ensureConfigured(tenantId, targetTemplateId, rule.getGroupCode(), rule.getMinSelected(), rule.getMaxSelected(), null); } } private static ElnTemplateVos.CheckboxGroup toVo(ElnTemplateCheckboxGroupEntity entity) { if (entity == null) throw new DataException("选择组配置不存在"); String code = requireGroupCode(entity.getGroupCode()); validateRange(entity.getMinSelected(), entity.getMaxSelected()); ElnTemplateVos.CheckboxGroup result = new ElnTemplateVos.CheckboxGroup(); result.setGroupCode(code); result.setMinSelected(entity.getMinSelected()); result.setMaxSelected(entity.getMaxSelected()); result.setVersion(entity.getFVersion()); return result; } private static void validateRange(Integer minSelected, Integer maxSelected) { if (minSelected == null || minSelected < 0 || (maxSelected != null && (maxSelected < 1 || minSelected > maxSelected))) { throw new DataException("选择组数量规则无效"); } } private static String requireGroupCode(String value) { String code = trim(value); if (code == null || !code.matches("[A-Za-z0-9_-]{1,80}")) { throw new DataException("选择组编码无效"); } return code; } private static void requireIdentity(String tenantId, String templateId) { if (!StringUtils.hasText(tenantId) || !StringUtils.hasText(templateId)) { throw new DataException("租户或模板标识无效"); } } private static String requireId(String value) { if (!StringUtils.hasText(value)) throw new DataException("选择组配置标识生成失败"); return value.trim(); } private static String trim(String value) { return StringUtils.hasText(value) ? value.trim() : null; } private static ElnTemplateCheckboxGroupEntity copy(ElnTemplateCheckboxGroupEntity source) { ElnTemplateCheckboxGroupEntity result = new ElnTemplateCheckboxGroupEntity(); result.setId(source.getId()); result.setMubanId(source.getMubanId()); result.setGroupCode(source.getGroupCode()); result.setMinSelected(source.getMinSelected()); result.setMaxSelected(source.getMaxSelected()); result.setFTenantId(source.getFTenantId()); result.setFVersion(source.getFVersion()); result.setFCreatorUserId(source.getFCreatorUserId()); result.setFCreatorTime(source.getFCreatorTime()); result.setFLastModifyUserId(source.getFLastModifyUserId()); result.setFLastModifyTime(source.getFLastModifyTime()); result.setFDeleteMark(source.getFDeleteMark()); return result; } public interface Store { ElnTemplateCheckboxGroupEntity find(String tenantId, String templateId, String groupCode); List list(String tenantId, String templateId); void insert(ElnTemplateCheckboxGroupEntity entity); boolean softDelete(ElnTemplateCheckboxGroupEntity entity, int expectedVersion); boolean update(ElnTemplateCheckboxGroupEntity entity, int expectedVersion); } private static final class MyBatisStore implements Store { private final ElnTemplateCheckboxGroupMapper mapper; private MyBatisStore(ElnTemplateCheckboxGroupMapper mapper) { this.mapper = mapper; } @Override public ElnTemplateCheckboxGroupEntity find(String tenantId, String templateId, String groupCode) { return mapper.selectOne(Wrappers.lambdaQuery() .eq(ElnTemplateCheckboxGroupEntity::getFTenantId, tenantId) .eq(ElnTemplateCheckboxGroupEntity::getMubanId, templateId) .eq(ElnTemplateCheckboxGroupEntity::getGroupCode, groupCode) .and(q -> q.isNull(ElnTemplateCheckboxGroupEntity::getFDeleteMark) .or().eq(ElnTemplateCheckboxGroupEntity::getFDeleteMark, 0))); } @Override public List list(String tenantId, String templateId) { return mapper.selectList(Wrappers.lambdaQuery() .eq(ElnTemplateCheckboxGroupEntity::getFTenantId, tenantId) .eq(ElnTemplateCheckboxGroupEntity::getMubanId, templateId) .and(q -> q.isNull(ElnTemplateCheckboxGroupEntity::getFDeleteMark) .or().eq(ElnTemplateCheckboxGroupEntity::getFDeleteMark, 0)) .orderByAsc(ElnTemplateCheckboxGroupEntity::getGroupCode)); } @Override public void insert(ElnTemplateCheckboxGroupEntity entity) { mapper.insert(entity); } @Override public boolean softDelete(ElnTemplateCheckboxGroupEntity entity, int expectedVersion) { int updated = mapper.update(null, Wrappers.lambdaUpdate() .set(ElnTemplateCheckboxGroupEntity::getFDeleteMark, 1) .set(ElnTemplateCheckboxGroupEntity::getFLastModifyUserId, entity.getFLastModifyUserId()) .set(ElnTemplateCheckboxGroupEntity::getFLastModifyTime, entity.getFLastModifyTime()) .set(ElnTemplateCheckboxGroupEntity::getFVersion, expectedVersion + 1) .eq(ElnTemplateCheckboxGroupEntity::getFTenantId, entity.getFTenantId()) .eq(ElnTemplateCheckboxGroupEntity::getId, entity.getId()) .eq(ElnTemplateCheckboxGroupEntity::getFVersion, expectedVersion) .and(q -> q.isNull(ElnTemplateCheckboxGroupEntity::getFDeleteMark) .or().eq(ElnTemplateCheckboxGroupEntity::getFDeleteMark, 0))); return updated == 1; } @Override public boolean update(ElnTemplateCheckboxGroupEntity entity, int expectedVersion) { int updated = mapper.update(null, Wrappers.lambdaUpdate() .set(ElnTemplateCheckboxGroupEntity::getMinSelected, entity.getMinSelected()) .set(ElnTemplateCheckboxGroupEntity::getMaxSelected, entity.getMaxSelected()) .set(ElnTemplateCheckboxGroupEntity::getFLastModifyUserId, entity.getFLastModifyUserId()) .set(ElnTemplateCheckboxGroupEntity::getFLastModifyTime, entity.getFLastModifyTime()) .set(ElnTemplateCheckboxGroupEntity::getFVersion, expectedVersion + 1) .eq(ElnTemplateCheckboxGroupEntity::getFTenantId, entity.getFTenantId()) .eq(ElnTemplateCheckboxGroupEntity::getId, entity.getId()) .eq(ElnTemplateCheckboxGroupEntity::getFVersion, expectedVersion)); return updated == 1; } } }