CategoryServiceImpl.java

package org.darkroomlibrary.service.impl;

import org.darkroomlibrary.mapper.BookMapper;
import org.darkroomlibrary.mapper.CategoryMapper;
import org.darkroomlibrary.web.response.ApiResponse;
import org.darkroomlibrary.web.response.PageResponse;
import org.darkroomlibrary.web.dto.query.CategoryPageQuery;
import org.darkroomlibrary.domain.model.Category;
import org.darkroomlibrary.service.CategoryService;
import org.darkroomlibrary.service.support.RecommendationSourceVersionService;
import org.darkroomlibrary.utils.IdListUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分类服务实现
 */
@Service
public class CategoryServiceImpl implements CategoryService {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private BookMapper bookMapper;

    @Resource
    private RecommendationSourceVersionService recommendationSourceVersionService;

    @Override
    @Transactional
    public ApiResponse<Void> save(Category category) {
        String validationError = validate(category, false);
        if (validationError != null) {
            return ApiResponse.error(validationError);
        }
        category.setName(category.getName().trim());
        category.setCreateTime(LocalDateTime.now());
        try {
            if (categoryMapper.insert(category) != 1) {
                return ApiResponse.error("分类新增失败,请重试");
            }
        } catch (DuplicateKeyException e) {
            return ApiResponse.error("分类名称已存在");
        }
        return ApiResponse.success("新增分类成功");
    }

    @Override
    @Transactional
    public ApiResponse<Void> update(Category category) {
        String validationError = validate(category, true);
        if (validationError != null) {
            return ApiResponse.error(validationError);
        }
        Category existing = categoryMapper.findByIdForUpdate(category.getId());
        if (existing == null) {
            return ApiResponse.error("分类不存在");
        }
        String newName = category.getName().trim();
        category.setName(newName);
        try {
            if (categoryMapper.update(category) == 0) {
                return ApiResponse.error("分类状态已变化,请刷新后重试");
            }
        } catch (DuplicateKeyException e) {
            return ApiResponse.error("分类名称已存在");
        }
        if (!existing.getName().equals(newName)) {
            bookMapper.updateCategoryName(existing.getName(), newName);
            recommendationSourceVersionService.invalidateGlobalAfterCommit();
        }
        return ApiResponse.success("修改分类成功");
    }

    @Override
    @Transactional
    public ApiResponse<Void> batchDelete(List<Integer> ids) {
        List<Integer> normalizedIds = IdListUtils.normalize(ids);
        if (normalizedIds.isEmpty()) {
            return ApiResponse.error("请选择要删除的分类");
        }
        if (IdListUtils.exceedsBatchLimit(normalizedIds)) {
            return ApiResponse.error("单次最多删除" + IdListUtils.MAX_BATCH_SIZE + "个分类");
        }
        List<Category> categories = categoryMapper.findByIdsForUpdate(normalizedIds);
        if (categories.size() != normalizedIds.size()) {
            return ApiResponse.error("部分分类不存在");
        }
        List<String> names = categories.stream()
                .map(Category::getName)
                .collect(Collectors.toList());
        if (bookMapper.countByCategories(names) > 0) {
            return ApiResponse.error("分类仍被图书使用,请先调整相关图书");
        }
        if (categoryMapper.batchDelete(normalizedIds) != normalizedIds.size()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ApiResponse.error("分类状态已变化,请刷新后重试");
        }
        return ApiResponse.success("删除分类成功");
    }

    @Override
    public ApiResponse<List<Category>> query(CategoryPageQuery dto) {
        List<Category> list = categoryMapper.query(dto);
        Integer total = categoryMapper.queryCount(dto);
        return PageResponse.success(list, total);
    }

    @Override
    public ApiResponse<List<Category>> queryAll() {
        return ApiResponse.success(categoryMapper.queryAll());
    }

    private String validate(Category category, boolean requireId) {
        if (category == null) {
            return "分类参数不能为空";
        }
        if (requireId && category.getId() == null) {
            return "分类编号不能为空";
        }
        if (category.getName() == null || category.getName().trim().isEmpty()) {
            return "分类名称不能为空";
        }
        if (category.getName().trim().length() > 50) {
            return "分类名称不能超过50个字符";
        }
        return null;
    }
}