package cn.iocoder.yudao.module.archive.service.category;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.module.archive.controller.admin.category.vo.ArchiveCategoryListReqVO;
|
import cn.iocoder.yudao.module.archive.controller.admin.category.vo.ArchiveCategorySaveReqVO;
|
import cn.iocoder.yudao.module.archive.dal.dataobject.category.ArchiveCategoryDO;
|
import cn.iocoder.yudao.module.archive.dal.mysql.category.ArchiveCategoryMapper;
|
import cn.iocoder.yudao.module.archive.dal.mysql.document.ArchiveDocumentMapper;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Set;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.archive.enums.ErrorCodeConstants.*;
|
|
/**
|
* 档案分类 Service 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class ArchiveCategoryServiceImpl implements ArchiveCategoryService {
|
|
/** 顶级分类的父分类编号 */
|
private static final Long ROOT_PARENT_ID = 0L;
|
|
@Resource
|
private ArchiveCategoryMapper categoryMapper;
|
|
@Resource
|
private ArchiveDocumentMapper documentMapper;
|
|
@Override
|
public Long createCategory(ArchiveCategorySaveReqVO createReqVO) {
|
// 1.1 校验父分类存在
|
validateParentCategory(createReqVO.getParentId(), createReqVO.getName());
|
// 1.2 校验同级分类名称不重复、分类编码不重复
|
validateNameUnique(createReqVO.getName(), createReqVO.getParentId(), null);
|
validateCodeUnique(createReqVO.getCode(), null);
|
|
// 2. 插入(补默认值)
|
ArchiveCategoryDO category = BeanUtils.toBean(createReqVO, ArchiveCategoryDO.class);
|
category.setId(null);
|
if (category.getSort() == null) {
|
category.setSort(0);
|
}
|
if (category.getDefaultSecretLevel() == null) {
|
category.setDefaultSecretLevel(1);
|
}
|
if (category.getStatus() == null) {
|
category.setStatus(0);
|
}
|
categoryMapper.insert(category);
|
return category.getId();
|
}
|
|
@Override
|
public void updateCategory(ArchiveCategorySaveReqVO updateReqVO) {
|
// 1.1 校验分类存在
|
ArchiveCategoryDO oldCategory = validateCategoryExists(updateReqVO.getId());
|
// 1.2 校验父分类存在,且不能把分类挂到自身或其子孙下(避免形成环)
|
validateParentCategory(updateReqVO.getParentId(), updateReqVO.getName());
|
validateParentNotSelfOrDescendant(oldCategory, updateReqVO.getParentId());
|
// 1.3 校验同级名称不重复、编码不重复
|
validateNameUnique(updateReqVO.getName(), updateReqVO.getParentId(), updateReqVO.getId());
|
validateCodeUnique(updateReqVO.getCode(), updateReqVO.getId());
|
|
// 2. 更新
|
ArchiveCategoryDO updateObj = BeanUtils.toBean(updateReqVO, ArchiveCategoryDO.class);
|
categoryMapper.updateById(updateObj);
|
}
|
|
@Override
|
public void deleteCategory(Long id) {
|
// 1.1 校验分类存在
|
ArchiveCategoryDO category = validateCategoryExists(id);
|
// 1.2 存在子分类时不允许删除
|
List<ArchiveCategoryDO> children = categoryMapper.selectListByParentId(id);
|
if (CollUtil.isNotEmpty(children)) {
|
throw exception(CATEGORY_HAS_CHILDREN, category.getName(), children.size());
|
}
|
// 1.3 分类下存在档案时不允许删除
|
Long documentCount = documentMapper.selectCountByCategoryId(id);
|
if (documentCount != null && documentCount > 0) {
|
throw exception(CATEGORY_HAS_DOCUMENT, category.getName(), documentCount);
|
}
|
|
categoryMapper.deleteById(id);
|
}
|
|
@Override
|
public ArchiveCategoryDO getCategory(Long id) {
|
return categoryMapper.selectById(id);
|
}
|
|
@Override
|
public List<ArchiveCategoryDO> getCategoryList(ArchiveCategoryListReqVO reqVO) {
|
return categoryMapper.selectList(new LambdaQueryWrapperX<ArchiveCategoryDO>()
|
.likeIfPresent(ArchiveCategoryDO::getName, reqVO.getName())
|
.eqIfPresent(ArchiveCategoryDO::getStatus, reqVO.getStatus())
|
.orderByAsc(ArchiveCategoryDO::getSort)
|
.orderByAsc(ArchiveCategoryDO::getId));
|
}
|
|
@Override
|
public List<ArchiveCategoryDO> getCategoryList() {
|
return categoryMapper.selectListOrdered();
|
}
|
|
@Override
|
public ArchiveCategoryDO getCategoryByCode(String code) {
|
if (StrUtil.isBlank(code)) {
|
return null;
|
}
|
return categoryMapper.selectByCode(code);
|
}
|
|
// ==================== 校验逻辑 ====================
|
|
/** 校验分类存在,不存在时抛出精确提示 */
|
private ArchiveCategoryDO validateCategoryExists(Long id) {
|
ArchiveCategoryDO category = id != null ? categoryMapper.selectById(id) : null;
|
if (category == null) {
|
throw exception(CATEGORY_NOT_EXISTS);
|
}
|
return category;
|
}
|
|
/** 校验父分类:0 表示顶级;非 0 时必须存在 */
|
private void validateParentCategory(Long parentId, String categoryName) {
|
if (parentId == null) {
|
throw exception(CATEGORY_PARENT_INVALID, categoryName);
|
}
|
if (Objects.equals(parentId, ROOT_PARENT_ID)) {
|
return;
|
}
|
if (categoryMapper.selectById(parentId) == null) {
|
throw exception(CATEGORY_PARENT_INVALID, categoryName);
|
}
|
}
|
|
/** 校验父分类不能是自身,也不能是自己的子孙分类 */
|
private void validateParentNotSelfOrDescendant(ArchiveCategoryDO category, Long parentId) {
|
if (Objects.equals(category.getId(), parentId)) {
|
throw exception(CATEGORY_PARENT_INVALID, category.getName());
|
}
|
Set<Long> descendantIds = collectDescendantIds(category.getId());
|
if (descendantIds.contains(parentId)) {
|
throw exception(CATEGORY_PARENT_INVALID, category.getName());
|
}
|
}
|
|
/** 收集分类的全部子孙分类编号(含自身) */
|
private Set<Long> collectDescendantIds(Long id) {
|
List<ArchiveCategoryDO> all = categoryMapper.selectListOrdered();
|
Set<Long> result = new HashSet<>();
|
result.add(id);
|
boolean changed = true;
|
while (changed) {
|
changed = false;
|
for (ArchiveCategoryDO category : all) {
|
if (result.contains(category.getParentId()) && result.add(category.getId())) {
|
changed = true;
|
}
|
}
|
}
|
return result;
|
}
|
|
private void validateNameUnique(String name, Long parentId, Long excludeId) {
|
Long count = categoryMapper.selectCountByName(name, parentId, excludeId);
|
if (count != null && count > 0) {
|
throw exception(CATEGORY_NAME_DUPLICATE, name);
|
}
|
}
|
|
private void validateCodeUnique(String code, Long excludeId) {
|
Long count = categoryMapper.selectCountByCode(code, excludeId);
|
if (count != null && count > 0) {
|
ArchiveCategoryDO exists = categoryMapper.selectByCode(code);
|
throw exception(CATEGORY_CODE_DUPLICATE, code, exists != null ? exists.getName() : code);
|
}
|
}
|
|
}
|