package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import shop.alien.entity.store.FitnessEquipmentInfo;
import shop.alien.entity.store.SportsEquipmentFacility;
import shop.alien.entity.store.SportsFacilityArea;
import shop.alien.entity.store.StoreImg;
import shop.alien.entity.store.vo.FitnessEquipmentCategoryDetailVo;
import shop.alien.entity.store.vo.FitnessEquipmentTypeSummaryVo;
import shop.alien.entity.store.vo.SportsEquipmentFacilityCategorySummaryVo;
import shop.alien.entity.store.vo.SportsEquipmentFacilityCategoryVo;
import shop.alien.entity.store.vo.SportsEquipmentFacilityVo;
import shop.alien.mapper.SportsEquipmentFacilityMapper;
import shop.alien.mapper.SportsFacilityAreaMapper;
import shop.alien.mapper.StoreImgMapper;
import shop.alien.store.service.FitnessEquipmentInfoService;
import shop.alien.store.service.SportsEquipmentFacilityService;
import shop.alien.store.service.SportsFacilityAreaService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 运动器材设施服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class SportsEquipmentFacilityServiceImpl extends ServiceImpl<SportsEquipmentFacilityMapper, SportsEquipmentFacility>
        implements SportsEquipmentFacilityService {

    private final SportsEquipmentFacilityMapper facilityMapper;
    private final SportsFacilityAreaMapper sportsFacilityAreaMapper;
    private final StoreImgMapper storeImgMapper;
    private final FitnessEquipmentInfoService fitnessEquipmentInfoService;
    private final SportsFacilityAreaService areaService;

    /**
     * 运动器材设施图片类型
     */
    private static final Integer IMG_TYPE_SPORTS_EQUIPMENT = 28;
    
    /**
     * 删除标志：未删除
     */
    private static final int DELETE_FLAG_NOT_DELETED = 0;
    
    /**
     * 状态：启用
     */
    private static final int STATUS_ENABLED = 1;
    
    /**
     * ID分隔符
     */
    private static final String ID_SEPARATOR = ",";
    
    /**
     * 最小分类编号
     */
    private static final int MIN_CATEGORY_NUM = 1;
    
    /**
     * 默认排序号
     */
    private static final int DEFAULT_SORT_ORDER = 0;
    
    /**
     * 最小有效ID
     */
    private static final int MIN_VALID_ID = 1;

    /**
     * 设施分类名称映射
     */
    private static final String[] FACILITY_CATEGORY_NAMES = {"", "有氧区", "力量区", "单功能机械区"};
    
    /**
     * 设备类型名称映射
     */
    private static final String[] EQUIPMENT_TYPE_NAMES = {"", "心肺训练", "核心训练", "臀腿训练", "上肢训练", "全身训练", "其他"};
    
    /**
     * 最大设备类型编号
     */
    private static final int MAX_EQUIPMENT_TYPE = 6;
    
    /**
     * 最小设备类型编号
     */
    private static final int MIN_EQUIPMENT_TYPE = 1;
    
    /**
     * 最大设施分类编号
     */
    private static final int MAX_FACILITY_CATEGORY = 3;

    @Override
    public IPage<SportsEquipmentFacilityVo> getPageList(Integer pageNum, Integer pageSize, Integer storeId, Integer facilityCategory) {
        Page<SportsEquipmentFacility> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsEquipmentFacility::getStoreId, storeId);
        if (facilityCategory != null) {
            queryWrapper.eq(SportsEquipmentFacility::getFacilityCategory, facilityCategory);
        }
        queryWrapper.orderByDesc(SportsEquipmentFacility::getCreatedTime);
        IPage<SportsEquipmentFacility> facilityPage = facilityMapper.selectPage(page, queryWrapper);
        return facilityPage.convert(this::convertToVo);
    }

    @Override
    public List<SportsEquipmentFacilityVo> getList(Integer storeId, Integer facilityCategory) {
        LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsEquipmentFacility::getStoreId, storeId);
        if (facilityCategory != null) {
            queryWrapper.eq(SportsEquipmentFacility::getFacilityCategory, facilityCategory);
        }
        queryWrapper.orderByDesc(SportsEquipmentFacility::getCreatedTime);
        List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(queryWrapper);
        return facilityList.stream().map(this::convertToVo).collect(Collectors.toList());
    }

    @Override
    public List<FitnessEquipmentInfo> getListByAreaId(Integer storeId, Integer areaId) {
        log.info("根据区域ID查询设备列表，storeId={}，areaId={}", storeId, areaId);
        
        // 参数验证
        if (storeId == null || storeId <= 0) {
            log.warn("根据区域ID查询设备列表失败，门店ID无效：{}", storeId);
            throw new IllegalArgumentException("门店ID不能为空且必须大于0");
        }
        
        if (areaId == null || areaId <= 0) {
            log.warn("根据区域ID查询设备列表失败，区域ID无效：{}", areaId);
            throw new IllegalArgumentException("区域ID不能为空且必须大于0");
        }
        
        try {
            // 1. 根据区域ID查询该区域下的所有设施记录
            LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                    .eq(SportsEquipmentFacility::getAreaId, areaId)
                    .eq(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_NOT_DELETED);
            
            List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(queryWrapper);
            
            // 2. 收集所有设备ID（从fitnessEquipmentIds字段中提取），并建立设备ID与设施的映射关系
            List<Integer> equipmentIdList = new ArrayList<>();
            // 设备ID -> 设施对象的映射（用于获取displayInStoreDetail）
            Map<Integer, SportsEquipmentFacility> equipmentIdToFacilityMap = new HashMap<>();
            
            for (SportsEquipmentFacility facility : facilityList) {
                String fitnessEquipmentIds = facility.getFitnessEquipmentIds();
                if (StringUtils.isNotBlank(fitnessEquipmentIds)) {
                    String[] idArray = fitnessEquipmentIds.split(ID_SEPARATOR);
                    for (String idStr : idArray) {
                        String trimmedId = idStr.trim();
                        if (StringUtils.isNotBlank(trimmedId)) {
                            try {
                                Integer equipmentId = Integer.parseInt(trimmedId);
                                if (equipmentId > 0) {
                                    if (!equipmentIdList.contains(equipmentId)) {
                                        equipmentIdList.add(equipmentId);
                                    }
                                    // 如果设备ID还没有映射，或者当前设施的displayInStoreDetail为1（显示），则更新映射
                                    // 优先使用displayInStoreDetail=1的设施
                                    if (!equipmentIdToFacilityMap.containsKey(equipmentId) 
                                            || (facility.getDisplayInStoreDetail() != null 
                                                    && facility.getDisplayInStoreDetail() == 1)) {
                                        equipmentIdToFacilityMap.put(equipmentId, facility);
                                    }
                                }
                            } catch (NumberFormatException e) {
                                log.warn("解析设备ID失败，跳过无效ID：{}，storeId={}，areaId={}", 
                                        trimmedId, storeId, areaId);
                            }
                        }
                    }
                }
            }
            
            // 3. 如果没有设备ID，返回空列表
            if (CollectionUtils.isEmpty(equipmentIdList)) {
                log.info("根据区域ID查询设备列表，未找到设备ID，storeId={}，areaId={}", storeId, areaId);
                return new ArrayList<>();
            }
            
            // 4. 根据设备ID列表查询设备信息
            List<FitnessEquipmentInfo> equipmentList = new ArrayList<>(
                    fitnessEquipmentInfoService.listByIds(equipmentIdList));
            
            // 5. 过滤掉已删除和禁用的设备，设置displayInStoreDetail字段，并按sortOrder排序
            List<FitnessEquipmentInfo> resultList = equipmentList.stream()
                    .filter(equipment -> equipment != null 
                            && equipment.getDeleteFlag() != null 
                            && equipment.getDeleteFlag() == DELETE_FLAG_NOT_DELETED
                            && equipment.getStatus() != null 
                            && equipment.getStatus() == STATUS_ENABLED)
                    .map(equipment -> {
                        // 从设施映射中获取displayInStoreDetail值
                        SportsEquipmentFacility facility = equipmentIdToFacilityMap.get(equipment.getId());
                        if (facility != null && facility.getDisplayInStoreDetail() != null) {
                            equipment.setDisplayInStoreDetail(facility.getDisplayInStoreDetail());
                        } else {
                            // 如果没有找到对应的设施，设置默认值1（显示）
                            equipment.setDisplayInStoreDetail(1);
                        }
                        return equipment;
                    })
                    .sorted((e1, e2) -> {
                        Integer sort1 = e1.getSortOrder() != null ? e1.getSortOrder() : 0;
                        Integer sort2 = e2.getSortOrder() != null ? e2.getSortOrder() : 0;
                        return sort1.compareTo(sort2);
                    })
                    .collect(Collectors.toList());
            
            log.info("根据区域ID查询设备列表成功，storeId={}，areaId={}，设备数量：{}", 
                    storeId, areaId, resultList.size());
            return resultList;
        } catch (Exception e) {
            log.error("根据区域ID查询设备列表异常，storeId={}，areaId={}，异常信息：{}", 
                    storeId, areaId, e.getMessage(), e);
            throw new RuntimeException("查询设备列表失败：" + e.getMessage(), e);
        }
    }

    @Override
    public SportsEquipmentFacilityVo getDetail(Integer id) {
        log.info("查询设备设施详情，id={}", id);
        
        if (id == null || id <= 0) {
            log.warn("查询设备设施详情失败，ID无效：{}", id);
            return null;
        }
        
        // 1. 先尝试根据设施ID查询（sports_equipment_facility表的主键ID）
        SportsEquipmentFacility facility = facilityMapper.selectById(id);
        
        // 2. 如果查询不到，尝试根据设备ID查询（fitness_equipment_info表的主键ID）
        if (facility == null) {
            log.info("根据设施ID查询不到记录，尝试根据设备ID查询，equipmentId={}", id);
            // 根据设备ID查询包含该设备的设施记录
            LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(SportsEquipmentFacility::getFitnessEquipmentIds, id)
                    .orderByDesc(SportsEquipmentFacility::getCreatedTime); // 按创建时间降序，取最新的
            List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(queryWrapper);
            
            if (!CollectionUtils.isEmpty(facilityList)) {
                // 优先取未删除的记录
                for (SportsEquipmentFacility fac : facilityList) {
                    if (fac.getDeleteFlag() == null || fac.getDeleteFlag() == DELETE_FLAG_NOT_DELETED) {
                        facility = fac;
                        break;
                    }
                }
                // 如果没有未删除的记录，取第一个（可能是已删除的）
                if (facility == null) {
                    facility = facilityList.get(0);
                }
                log.info("根据设备ID查询到设施记录，equipmentId={}，facilityId={}，deleteFlag={}", 
                        id, facility.getId(), facility.getDeleteFlag());
            } else {
                // 如果仍然查询不到，尝试查询已删除的记录（绕过逻辑删除）
                facility = facilityMapper.selectByEquipmentIdIncludeDeleted(id);
                if (facility != null) {
                    log.info("根据设备ID查询到已删除的设施记录，equipmentId={}，facilityId={}，deleteFlag={}", 
                            id, facility.getId(), facility.getDeleteFlag());
                } else {
                    log.warn("根据设施ID和设备ID都查询不到记录，id={}", id);
                    return null;
                }
            }
        } else {
            log.info("根据设施ID查询到记录，facilityId={}，deleteFlag={}", id, facility.getDeleteFlag());
        }
        
        return convertToVo(facility);
    }

    @Override
    public SportsEquipmentFacilityVo getStoreDetail(Integer id) {
        SportsEquipmentFacility facility = facilityMapper.selectById(id);
        if (facility == null) {
            return null;
        }
        return convertToVo(facility);
    }

    @Override
    public boolean saveFacility(SportsEquipmentFacility facility, List<String> imageList, SportsEquipmentFacilityVo vo) {
        log.info("保存设备设施，facility={}，imageList大小={}，vo={}", facility, 
                imageList != null ? imageList.size() : 0, vo);
        
        // 参数验证
        if (facility == null) {
            log.warn("保存设备设施失败，设备信息为空");
            throw new IllegalArgumentException("设备信息不能为空");
        }
        
        if (facility.getStoreId() == null || facility.getStoreId() <= 0) {
            log.warn("保存设备设施失败，门店ID无效：{}", facility.getStoreId());
            throw new IllegalArgumentException("门店ID不能为空且必须大于0");
        }
        
        // 校验图片数量（最多9张，根据UI需求）
        if (!CollectionUtils.isEmpty(imageList) && imageList.size() > 9) {
            log.warn("保存设备设施失败，图片数量超过限制：{}", imageList.size());
            throw new RuntimeException("图片最多上传9张");
        }
        
        // 如果提供了areaId，验证区域是否存在且未删除
        if (facility.getAreaId() != null && facility.getAreaId() > 0) {
            SportsFacilityArea area = areaService.getById(facility.getAreaId());
            if (area == null || area.getDeleteFlag() == null || area.getDeleteFlag() != DELETE_FLAG_NOT_DELETED) {
                log.warn("新增设备失败，区域不存在或已删除：areaId={}", facility.getAreaId());
                throw new IllegalArgumentException("区域不存在或已删除");
            }
        }
        
        // 如果facilityCategory为null，设置默认值0（数据库要求不能为空）
        if (facility.getFacilityCategory() == null) {
            facility.setFacilityCategory(0);
            log.info("新增设备时facilityCategory为null，已设置默认值0");
        }
        
        // 如果facilityName为null，设置默认值为空字符串（数据库要求不能为空）
        if (facility.getFacilityName() == null) {
            facility.setFacilityName("");
            log.info("新增设备时facilityName为null，已设置默认值为空字符串");
        }
        
        // 1. 如果提供了设备信息（equipmentName），先创建FitnessEquipmentInfo记录
        Integer equipmentId = null;
        if (vo != null && StringUtils.isNotBlank(vo.getEquipmentName())) {
            FitnessEquipmentInfo equipmentInfo = new FitnessEquipmentInfo();
            equipmentInfo.setEquipmentName(vo.getEquipmentName().trim());
            // 设备类型默认为6（其他），因为UI中没有选择设备类型
            equipmentInfo.setEquipmentType(6); // 6:其他
            if (vo.getEquipmentNums() != null && vo.getEquipmentNums() > 0) {
                equipmentInfo.setEquipmentNums(vo.getEquipmentNums());
            } else {
                equipmentInfo.setEquipmentNums(1); // 默认数量为1
            }
            if (StringUtils.isNotBlank(vo.getEquipmentImage())) {
                equipmentInfo.setEquipmentImage(vo.getEquipmentImage());
            }
            // 设置默认值
            equipmentInfo.setSortOrder(0);
            equipmentInfo.setStatus(STATUS_ENABLED);
            equipmentInfo.setDeleteFlag(DELETE_FLAG_NOT_DELETED);
            
            boolean saveEquipmentResult = fitnessEquipmentInfoService.saveEquipment(equipmentInfo);
            if (saveEquipmentResult && equipmentInfo.getId() != null) {
                equipmentId = equipmentInfo.getId();
                log.info("创建设备信息成功，equipmentId={}，equipmentName={}", equipmentId, vo.getEquipmentName());
            } else {
                log.warn("创建设备信息失败，equipmentName={}", vo.getEquipmentName());
                throw new RuntimeException("创建设备信息失败");
            }
        }
        
        // 2. 保存设施信息
        // 如果创建了设备信息，将设备ID保存到fitnessEquipmentIds字段
        if (equipmentId != null) {
            facility.setFitnessEquipmentIds(String.valueOf(equipmentId));
        }
        
        boolean result = this.save(facility);
        if (!result) {
            log.error("保存设备设施失败，保存数据库失败：facility={}", facility);
            throw new RuntimeException("保存设备设施失败");
        }
        
        // 3. 保存图片，使用facility.id作为business_id
        if (!CollectionUtils.isEmpty(imageList) && facility.getId() != null) {
            // 删除该设备下的旧图片（如果存在）
            LambdaQueryWrapper<StoreImg> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(StoreImg::getStoreId, facility.getStoreId())
                    .eq(StoreImg::getBusinessId, facility.getId())
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
            storeImgMapper.delete(deleteWrapper);
            // 保存新图片，business_id存储facility.id
            saveImagesByFacilityId(facility.getId(), facility.getStoreId(), imageList);
        }
        
        log.info("保存设备设施成功，facilityId={}，storeId={}，areaId={}，equipmentId={}", 
                facility.getId(), facility.getStoreId(), facility.getAreaId(), equipmentId);
        return result;
    }

    @Override
    public boolean updateFacility(SportsEquipmentFacility facility, List<String> imageList, SportsEquipmentFacilityVo vo) {
        log.info("修改设备设施，facility={}，imageList大小={}，vo={}", facility, 
                imageList != null ? imageList.size() : 0, vo);
        
        // 参数验证
        if (facility == null) {
            log.warn("修改设备设施失败，设备信息为空");
            throw new IllegalArgumentException("设备信息不能为空");
        }
        
        // 验证：必须提供设施ID或设备ID之一
        if (facility.getId() == null && (vo == null || vo.getEquipmentId() == null || vo.getEquipmentId() <= 0)) {
            log.warn("修改设备设施失败，设施ID和设备ID都为空");
            throw new IllegalArgumentException("设施ID或设备ID不能为空");
        }
        
        if (facility.getStoreId() == null || facility.getStoreId() <= 0) {
            log.warn("修改设备设施失败，门店ID无效：{}", facility.getStoreId());
            throw new IllegalArgumentException("门店ID不能为空且必须大于0");
        }
        
        // 校验图片数量（最多9张，根据UI需求）
        if (!CollectionUtils.isEmpty(imageList) && imageList.size() > 9) {
            log.warn("修改设备设施失败，图片数量超过限制：{}", imageList.size());
            throw new RuntimeException("图片最多上传9张");
        }
        
        // 如果提供了areaId，验证区域是否存在且未删除
        if (facility.getAreaId() != null && facility.getAreaId() > 0) {
            SportsFacilityArea area = areaService.getById(facility.getAreaId());
            if (area == null || area.getDeleteFlag() == null || area.getDeleteFlag() != DELETE_FLAG_NOT_DELETED) {
                log.warn("修改设备失败，区域不存在或已删除：areaId={}", facility.getAreaId());
                throw new IllegalArgumentException("区域不存在或已删除");
            }
        }
        
        // 查询现有设施记录
        // 如果vo中提供了equipmentId（fitness_equipment_info的ID），则根据设备ID查询设施记录
        SportsEquipmentFacility existingFacility = null;
        if (vo != null && vo.getEquipmentId() != null && vo.getEquipmentId() > 0) {
            // 根据设备ID查询包含该设备的设施记录（包括已删除的记录，因为可能需要恢复）
            // 由于@TableLogic的存在，先查询未删除的记录
            LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(SportsEquipmentFacility::getFitnessEquipmentIds, vo.getEquipmentId())
                    .orderByDesc(SportsEquipmentFacility::getCreatedTime); // 按创建时间降序，取最新的
            List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(queryWrapper);
            
            if (!CollectionUtils.isEmpty(facilityList)) {
                // 找到未删除的记录，取第一个
                existingFacility = facilityList.get(0);
            } else {
                // 如果没有找到未删除的记录，查询已删除的记录（需要绕过@TableLogic）
                // 使用自定义SQL查询包括已删除的记录
                existingFacility = facilityMapper.selectByEquipmentIdIncludeDeleted(vo.getEquipmentId());
                if (existingFacility != null) {
                    log.info("根据设备ID查询到已删除的设施记录，equipmentId={}，facilityId={}，deleteFlag={}", 
                            vo.getEquipmentId(), existingFacility.getId(), existingFacility.getDeleteFlag());
                } else {
                    log.warn("根据设备ID查询设施记录失败（包括已删除的记录），equipmentId={}", vo.getEquipmentId());
                }
            }
            
            if (existingFacility != null) {
                // 更新facility的ID为查询到的设施ID
                facility.setId(existingFacility.getId());
                log.info("根据设备ID查询到设施记录，equipmentId={}，facilityId={}，deleteFlag={}", 
                        vo.getEquipmentId(), existingFacility.getId(), existingFacility.getDeleteFlag());
            }
        } else if (facility.getId() != null) {
            // 如果没有提供equipmentId，则根据设施ID查询
            existingFacility = this.getById(facility.getId());
        }
        
        if (existingFacility == null) {
            log.warn("修改设备设施失败，设施不存在：facilityId={}，equipmentId={}", 
                    facility.getId(), vo != null ? vo.getEquipmentId() : null);
            throw new IllegalArgumentException("设施不存在");
        }
        
        // 如果设施已被删除，恢复它（设置deleteFlag为0）
        if (existingFacility.getDeleteFlag() != null && existingFacility.getDeleteFlag() != DELETE_FLAG_NOT_DELETED) {
            log.info("设施已被删除，恢复设施记录：facilityId={}", existingFacility.getId());
            existingFacility.setDeleteFlag(DELETE_FLAG_NOT_DELETED);
            facility.setDeleteFlag(DELETE_FLAG_NOT_DELETED);
        }
        
        // 如果facilityCategory为null，设置默认值0（数据库要求不能为空）
        if (facility.getFacilityCategory() == null) {
            facility.setFacilityCategory(0);
            log.info("修改设备时facilityCategory为null，已设置默认值0");
        }
        
        // 如果facilityName为null，设置默认值为空字符串（数据库要求不能为空）
        if (facility.getFacilityName() == null) {
            facility.setFacilityName("");
            log.info("修改设备时facilityName为null，已设置默认值为空字符串");
        }
        
        // 1. 如果提供了设备信息（equipmentName），更新或创建FitnessEquipmentInfo记录
        Integer equipmentId = null;
        if (vo != null && StringUtils.isNotBlank(vo.getEquipmentName())) {
            // 如果fitnessEquipmentIds不为空，说明已有设备，更新现有设备
            String existingEquipmentIds = existingFacility.getFitnessEquipmentIds();
            if (StringUtils.isNotBlank(existingEquipmentIds)) {
                // 解析现有设备ID列表，取第一个设备ID进行更新
                String[] equipmentIdArray = existingEquipmentIds.split(ID_SEPARATOR);
                if (equipmentIdArray.length > 0) {
                    try {
                        equipmentId = Integer.parseInt(equipmentIdArray[0].trim());
                        // 更新现有设备信息
                        FitnessEquipmentInfo equipmentInfo = fitnessEquipmentInfoService.getById(equipmentId);
                        if (equipmentInfo != null && equipmentInfo.getDeleteFlag() != null 
                                && equipmentInfo.getDeleteFlag() == DELETE_FLAG_NOT_DELETED) {
                            equipmentInfo.setEquipmentName(vo.getEquipmentName().trim());
                            if (vo.getEquipmentNums() != null && vo.getEquipmentNums() > 0) {
                                equipmentInfo.setEquipmentNums(vo.getEquipmentNums());
                            }
                            if (StringUtils.isNotBlank(vo.getEquipmentImage())) {
                                equipmentInfo.setEquipmentImage(vo.getEquipmentImage());
                            }
                            boolean updateEquipmentResult = fitnessEquipmentInfoService.updateEquipment(equipmentInfo);
                            if (updateEquipmentResult) {
                                log.info("更新设备信息成功，equipmentId={}，equipmentName={}", equipmentId, vo.getEquipmentName());
                            } else {
                                log.warn("更新设备信息失败，equipmentId={}", equipmentId);
                                throw new RuntimeException("更新设备信息失败");
                            }
                        } else {
                            // 设备不存在或已删除，创建新设备
                            equipmentId = null;
                        }
                    } catch (NumberFormatException e) {
                        log.warn("解析设备ID失败，existingEquipmentIds={}，异常信息：{}", existingEquipmentIds, e.getMessage());
                        equipmentId = null;
                    }
                }
            }
            
            // 如果没有现有设备或设备已删除，创建新设备
            if (equipmentId == null) {
                FitnessEquipmentInfo equipmentInfo = new FitnessEquipmentInfo();
                equipmentInfo.setEquipmentName(vo.getEquipmentName().trim());
                // 设备类型默认为6（其他），因为UI中没有选择设备类型
                equipmentInfo.setEquipmentType(6); // 6:其他
                if (vo.getEquipmentNums() != null && vo.getEquipmentNums() > 0) {
                    equipmentInfo.setEquipmentNums(vo.getEquipmentNums());
                } else {
                    equipmentInfo.setEquipmentNums(1); // 默认数量为1
                }
                if (StringUtils.isNotBlank(vo.getEquipmentImage())) {
                    equipmentInfo.setEquipmentImage(vo.getEquipmentImage());
                }
                // 设置默认值
                equipmentInfo.setSortOrder(0);
                equipmentInfo.setStatus(STATUS_ENABLED);
                equipmentInfo.setDeleteFlag(DELETE_FLAG_NOT_DELETED);
                
                boolean saveEquipmentResult = fitnessEquipmentInfoService.saveEquipment(equipmentInfo);
                if (saveEquipmentResult && equipmentInfo.getId() != null) {
                    equipmentId = equipmentInfo.getId();
                    log.info("创建设备信息成功，equipmentId={}，equipmentName={}", equipmentId, vo.getEquipmentName());
                } else {
                    log.warn("创建设备信息失败，equipmentName={}", vo.getEquipmentName());
                    throw new RuntimeException("创建设备信息失败");
                }
            }
        }
        
        // 2. 更新设施信息
        // 如果更新了设备信息，更新fitnessEquipmentIds字段
        if (equipmentId != null) {
            facility.setFitnessEquipmentIds(String.valueOf(equipmentId));
        }
        
        boolean result = this.updateById(facility);
        if (!result) {
            log.error("修改设备设施失败，更新数据库失败：facility={}", facility);
            throw new RuntimeException("修改设备设施失败");
        }
        
        // 3. 保存图片，使用facility.id作为business_id
        if (!CollectionUtils.isEmpty(imageList) && facility.getId() != null) {
            // 删除该设施下的旧图片（如果存在）
            LambdaQueryWrapper<StoreImg> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(StoreImg::getStoreId, facility.getStoreId())
                    .eq(StoreImg::getBusinessId, facility.getId())
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
            storeImgMapper.delete(deleteWrapper);
            // 保存新图片，business_id存储facility.id
            saveImagesByFacilityId(facility.getId(), facility.getStoreId(), imageList);
        }
        
        log.info("修改设备设施成功，facilityId={}，storeId={}，areaId={}，equipmentId={}", 
                facility.getId(), facility.getStoreId(), facility.getAreaId(), equipmentId);
        return result;
    }

    @Override
    public boolean deleteFacility(Integer equipmentId) {
        log.info("删除设备设施，equipmentId={}", equipmentId);
        
        // 参数验证
        if (equipmentId == null || equipmentId <= 0) {
            log.warn("删除设备设施失败，设备ID无效：{}", equipmentId);
            throw new IllegalArgumentException("设备ID不能为空且必须大于0");
        }
        
        // 验证设备是否存在
        FitnessEquipmentInfo equipmentInfo = fitnessEquipmentInfoService.getById(equipmentId);
        if (equipmentInfo == null || equipmentInfo.getDeleteFlag() == null 
                || equipmentInfo.getDeleteFlag() != DELETE_FLAG_NOT_DELETED) {
            log.warn("删除设备设施失败，设备不存在或已删除：equipmentId={}", equipmentId);
            throw new IllegalArgumentException("设备不存在或已删除");
        }
        
        // 1. 查询所有包含该设备ID的设施记录
        LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                .like(SportsEquipmentFacility::getFitnessEquipmentIds, equipmentId);
        List<SportsEquipmentFacility> facilityList = this.list(queryWrapper);
        
        if (CollectionUtils.isEmpty(facilityList)) {
            log.warn("删除设备设施失败，未找到包含该设备ID的设施记录：equipmentId={}", equipmentId);
            // 即使没有找到设施记录，也删除设备信息
            boolean deleteEquipmentResult = fitnessEquipmentInfoService.deleteEquipment(equipmentId);
            return deleteEquipmentResult;
        }
        
        // 2. 对每个设施记录，从fitnessEquipmentIds中移除该设备ID
        for (SportsEquipmentFacility facility : facilityList) {
            String fitnessEquipmentIds = facility.getFitnessEquipmentIds();
            if (StringUtils.isNotBlank(fitnessEquipmentIds)) {
                // 解析设备ID列表
                List<String> equipmentIdList = new ArrayList<>();
                String[] equipmentIdArray = fitnessEquipmentIds.split(ID_SEPARATOR);
                for (String idStr : equipmentIdArray) {
                    String trimmedId = idStr.trim();
                    if (StringUtils.isNotBlank(trimmedId)) {
                        try {
                            Integer id = Integer.parseInt(trimmedId);
                            // 如果不是要删除的设备ID，保留
                            if (!id.equals(equipmentId)) {
                                equipmentIdList.add(trimmedId);
                            }
                        } catch (NumberFormatException e) {
                            log.warn("解析设备ID失败，idStr={}，异常信息：{}", idStr, e.getMessage());
                        }
                    }
                }
                
                // 更新设施的fitnessEquipmentIds
                if (equipmentIdList.isEmpty()) {
                    // 如果移除后设备列表为空，删除该设施
                    boolean deleteFacilityResult = this.removeById(facility.getId());
                    if (deleteFacilityResult) {
                        log.info("删除设施成功（设备列表为空），facilityId={}，equipmentId={}", 
                                facility.getId(), equipmentId);
                    } else {
                        log.warn("删除设施失败（设备列表为空），facilityId={}，equipmentId={}", 
                                facility.getId(), equipmentId);
                    }
                } else {
                    // 如果移除后设备列表不为空，更新设施的设备ID列表
                    String newFitnessEquipmentIds = String.join(ID_SEPARATOR, equipmentIdList);
                    facility.setFitnessEquipmentIds(newFitnessEquipmentIds);
                    boolean updateFacilityResult = this.updateById(facility);
                    if (updateFacilityResult) {
                        log.info("更新设施设备ID列表成功，facilityId={}，equipmentId={}，新设备ID列表：{}", 
                                facility.getId(), equipmentId, newFitnessEquipmentIds);
                    } else {
                        log.warn("更新设施设备ID列表失败，facilityId={}，equipmentId={}", 
                                facility.getId(), equipmentId);
                    }
                }
            }
        }
        
        // 3. 逻辑删除设备信息
        boolean deleteEquipmentResult = fitnessEquipmentInfoService.deleteEquipment(equipmentId);
        if (deleteEquipmentResult) {
            log.info("删除设备信息成功，equipmentId={}", equipmentId);
        } else {
            log.warn("删除设备信息失败，equipmentId={}", equipmentId);
        }
        
        return deleteEquipmentResult;
    }

    /**
     * 查询指定店铺按分类汇总的设备信息（用户端）
     * <p>
     * 从sports_facility_area表获取区域列表，通过area_id关联sports_equipment_facility，
     * 再通过fitness_equipment_ids关联fitness_equipment_info获取设备信息
     * </p>
     *
     * @param storeId 门店ID，不能为空且必须大于0
     * @return 分类汇总列表，不会返回null
     */
    @Override
    public List<SportsEquipmentFacilityCategorySummaryVo> getCategorySummary(Integer storeId) {
        log.info("查询指定店铺按分类汇总的设备信息（用户端），storeId={}", storeId);
        
        // 参数验证
        if (storeId == null || storeId <= 0) {
            log.warn("查询分类汇总失败，门店ID无效：{}", storeId);
            return new ArrayList<>();
        }
        
        try {
            List<SportsEquipmentFacilityCategorySummaryVo> result = new ArrayList<>();
            
            // 1. 从sports_facility_area表查询该店铺下的所有区域
            List<SportsFacilityArea> areaList = queryAreaListByStoreId(storeId);
            
            if (CollectionUtils.isEmpty(areaList)) {
                log.info("查询指定店铺按分类汇总的设备信息完成，storeId={}，未找到区域数据", storeId);
                return result;
            }
            
            // 2. 按区域分组查询设备信息
            for (SportsFacilityArea area : areaList) {
                SportsEquipmentFacilityCategorySummaryVo categoryVo = buildCategorySummaryVoByArea(
                        storeId, area);
                // 添加所有区域，包括没有设备的区域
                result.add(categoryVo);
            }
            
            log.info("查询指定店铺按分类汇总的设备信息完成，storeId={}，区域数量：{}", storeId, result.size());
            return result;
        } catch (Exception e) {
            log.error("查询指定店铺按分类汇总的设备信息异常，storeId={}，异常信息：{}", storeId, e.getMessage(), e);
            throw new RuntimeException("查询分类汇总异常：" + e.getMessage(), e);
        }
    }
    
    /**
     * 根据门店ID查询区域列表（专门用于categorySummary接口）
     *
     * @param storeId 门店ID
     * @return 区域列表，按sort_order升序，相同排序号按创建时间降序，不会返回null
     */
    private List<SportsFacilityArea> queryAreaListByStoreId(Integer storeId) {
        try {
            LambdaQueryWrapper<SportsFacilityArea> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SportsFacilityArea::getStoreId, storeId)
                    .eq(SportsFacilityArea::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                    .orderByAsc(SportsFacilityArea::getSortOrder)
                    .orderByDesc(SportsFacilityArea::getCreatedTime);
            
            List<SportsFacilityArea> areaList = sportsFacilityAreaMapper.selectList(queryWrapper);
            
            if (CollectionUtils.isEmpty(areaList)) {
                return new ArrayList<>();
            }
            
            return areaList;
        } catch (Exception e) {
            log.error("查询区域列表异常（categorySummary专用），storeId={}，异常信息：{}", storeId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 根据区域构建分类汇总VO对象（专门用于categorySummary接口）
     *
     * @param storeId 门店ID
     * @param area    区域对象
     * @return 分类汇总VO对象
     */
    private SportsEquipmentFacilityCategorySummaryVo buildCategorySummaryVoByArea(Integer storeId, SportsFacilityArea area) {
        SportsEquipmentFacilityCategorySummaryVo categoryVo = new SportsEquipmentFacilityCategorySummaryVo();
        categoryVo.setStoreId(storeId);
        categoryVo.setFacilityCategoryName(area.getAreaName());
        
        // 1. 通过area_id查询sports_equipment_facility表中的设备列表
        List<SportsEquipmentFacility> facilityList = queryFacilityListByAreaId(storeId, area.getId());
        
        // 2. 收集并解析fitnessEquipmentIds
        List<Integer> fitnessEquipmentIdList = collectFitnessEquipmentIdsForCategorySummary(facilityList, storeId);
        
        // 3. 通过fitness_equipment_ids关联查询fitness_equipment_info设备记录
        List<FitnessEquipmentInfo> fitnessEquipmentInfoList = queryFitnessEquipmentInfoListForCategorySummary(fitnessEquipmentIdList, storeId);

        // 4. 设置设备列表
        categoryVo.setFacilityList(fitnessEquipmentInfoList);
        categoryVo.setFacilityCount(fitnessEquipmentInfoList.size());

        // 5. 从sports_facility_area表的area_head_url字段获取图片列表（逗号分隔）
        List<String> imageList = parseImageListFromAreaHeadUrl(area.getAreaHeadUrl());
        categoryVo.setImageList(imageList);
        categoryVo.setAreaLogoImg(area.getAreaLogoImg());
        return categoryVo;
    }
    
    /**
     * 根据区域ID查询设备列表（专门用于categorySummary接口）
     *
     * @param storeId 门店ID
     * @param areaId  区域ID
     * @return 设备列表
     */
    private List<SportsEquipmentFacility> queryFacilityListByAreaId(Integer storeId, Integer areaId) {
        LambdaQueryWrapper<SportsEquipmentFacility> facilityWrapper = new LambdaQueryWrapper<>();
        facilityWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                .eq(SportsEquipmentFacility::getAreaId, areaId)
                .eq(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                .orderByDesc(SportsEquipmentFacility::getCreatedTime);
        return facilityMapper.selectList(facilityWrapper);
    }
    
    /**
     * 从设备列表中收集fitnessEquipmentIds并解析为整数列表（专门用于categorySummary接口，不与其他接口共用）
     *
     * @param facilityList 设备列表
     * @param storeId      门店ID（用于日志）
     * @return 去重后的设备ID列表
     */
    private List<Integer> collectFitnessEquipmentIdsForCategorySummary(List<SportsEquipmentFacility> facilityList, Integer storeId) {
        List<Integer> fitnessEquipmentIdList = new ArrayList<>();
        
        if (CollectionUtils.isEmpty(facilityList)) {
            return fitnessEquipmentIdList;
        }
        
        for (SportsEquipmentFacility facility : facilityList) {
            String fitnessEquipmentIds = facility.getFitnessEquipmentIds();
            if (StringUtils.isNotBlank(fitnessEquipmentIds)) {
                List<Integer> parsedIds = parseFitnessEquipmentIdsForCategorySummary(fitnessEquipmentIds, storeId);
                for (Integer id : parsedIds) {
                    if (!fitnessEquipmentIdList.contains(id)) {
                        fitnessEquipmentIdList.add(id);
                    }
                }
            }
        }
        
        return fitnessEquipmentIdList;
    }
    
    /**
     * 解析逗号分隔的ID字符串为整数列表（专门用于categorySummary接口，不与其他接口共用）
     *
     * @param fitnessEquipmentIds ID字符串（逗号分隔）
     * @param storeId             门店ID（用于日志）
     * @return 解析后的ID列表
     */
    private List<Integer> parseFitnessEquipmentIdsForCategorySummary(String fitnessEquipmentIds, Integer storeId) {
        List<Integer> idList = new ArrayList<>();
        
        if (StringUtils.isBlank(fitnessEquipmentIds)) {
            return idList;
        }
        
        String[] idArray = fitnessEquipmentIds.split(ID_SEPARATOR);
        for (String idStr : idArray) {
            String trimmedId = idStr.trim();
            if (StringUtils.isNotBlank(trimmedId)) {
                try {
                    Integer id = Integer.parseInt(trimmedId);
                    if (id >= MIN_VALID_ID) {
                        idList.add(id);
                    } else {
                        log.warn("解析fitnessEquipmentIds失败（categorySummary专用），ID小于最小值：{}，storeId={}", 
                                trimmedId, storeId);
                    }
                } catch (NumberFormatException e) {
                    log.warn("解析fitnessEquipmentIds失败（categorySummary专用），无效的ID格式：{}，storeId={}，异常信息：{}", 
                            trimmedId, storeId, e.getMessage());
                }
            }
        }
        
        return idList;
    }
    
    /**
     * 查询健身设备信息列表（专门用于categorySummary接口，不与其他接口共用）
     *
     * @param fitnessEquipmentIdList 设备ID列表
     * @param storeId                门店ID（用于日志）
     * @return 过滤并排序后的设备信息列表
     */
    private List<FitnessEquipmentInfo> queryFitnessEquipmentInfoListForCategorySummary(List<Integer> fitnessEquipmentIdList, Integer storeId) {
        if (CollectionUtils.isEmpty(fitnessEquipmentIdList)) {
            return new ArrayList<>();
        }
        
        try {
            List<FitnessEquipmentInfo> allEquipmentList = new ArrayList<>(
                    fitnessEquipmentInfoService.listByIds(fitnessEquipmentIdList));
            
            // 过滤掉已删除和禁用的设备，并按sort_order排序
            List<FitnessEquipmentInfo> filteredList = allEquipmentList.stream()
                    .filter(this::isValidFitnessEquipment)
                    .sorted(this::compareBySortOrder)
                    .collect(Collectors.toList());
            
            log.info("查询到FitnessEquipmentInfo设备数量（categorySummary专用）：{}，storeId：{}", 
                    filteredList.size(), storeId);
            
            return filteredList;
        } catch (Exception e) {
            log.error("查询FitnessEquipmentInfo列表异常（categorySummary专用），storeId={}，异常信息：{}", 
                    storeId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 从area_head_url字段解析图片列表（逗号分隔）
     *
     * @param areaHeadUrl 区域头部图片URL字符串（逗号分隔）
     * @return 图片URL列表
     */
    private List<String> parseImageListFromAreaHeadUrl(String areaHeadUrl) {
        try {
            if (StringUtils.isBlank(areaHeadUrl)) {
                return new ArrayList<>();
            }
            
            // 按逗号分隔，去除空白字符，过滤空字符串
            return java.util.Arrays.stream(areaHeadUrl.split(","))
                    .map(String::trim)
                    .filter(StringUtils::isNotBlank)
                    .distinct()
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("解析区域头部图片URL列表异常，areaHeadUrl={}，异常信息：{}", 
                    areaHeadUrl, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 根据区域ID查询图片列表（专门用于categorySummary接口）
     * 图片存储时business_id存储的是区域ID（area_id）
     * 注意：此方法已废弃，现在使用parseImageListFromAreaHeadUrl方法从area_head_url字段获取
     *
     * @param storeId 门店ID
     * @param areaId  区域ID
     * @return 图片URL列表
     */
    @Deprecated
    private List<String> queryCategoryImageListByAreaId(Integer storeId, Integer areaId) {
        try {
            // 查询该区域下的图片
            LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
            imageWrapper.eq(StoreImg::getStoreId, storeId)
                    .eq(StoreImg::getBusinessId, areaId)
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
                    .orderByAsc(StoreImg::getImgSort);
            
            List<StoreImg> imageList = storeImgMapper.selectList(imageWrapper);
            
            if (CollectionUtils.isEmpty(imageList)) {
                return new ArrayList<>();
            }
            
            return imageList.stream()
                    .map(StoreImg::getImgUrl)
                    .distinct()
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询区域图片列表异常（categorySummary专用），storeId={}，areaId={}，异常信息：{}", 
                    storeId, areaId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 查询指定店铺下所有不同的设施分类名称
     *
     * @param storeId 门店ID
     * @return 分类名称列表，不会返回null
     */
    private List<String> queryDistinctCategoryNames(Integer storeId) {
        try {
            LambdaQueryWrapper<SportsEquipmentFacility> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                    .eq(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                    .isNotNull(SportsEquipmentFacility::getFacilityCategoryName)
                    .ne(SportsEquipmentFacility::getFacilityCategoryName, "");
            
            List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(queryWrapper);
            
            if (CollectionUtils.isEmpty(facilityList)) {
                return new ArrayList<>();
            }
            
            // 提取所有不同的分类名称并排序
            return facilityList.stream()
                    .map(SportsEquipmentFacility::getFacilityCategoryName)
                    .filter(StringUtils::isNotBlank)
                    .distinct()
                    .sorted()
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询设施分类名称列表异常，storeId={}，异常信息：{}", storeId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 根据分类名称构建分类汇总VO对象
     *
     * @param storeId      门店ID
     * @param categoryName 分类名称
     * @return 分类汇总VO对象
     */
    private SportsEquipmentFacilityCategorySummaryVo buildCategorySummaryVoByCategoryName(Integer storeId, String categoryName) {
        SportsEquipmentFacilityCategorySummaryVo categoryVo = new SportsEquipmentFacilityCategorySummaryVo();
        categoryVo.setStoreId(storeId);

        categoryVo.setFacilityCategoryName(categoryName);
        
        // 查询该分类名称下的设备列表
        List<SportsEquipmentFacility> facilityList = queryFacilityListByCategoryName(storeId, categoryName);
        
        // 设置设备数量：统计该分类名称下的SportsEquipmentFacility记录数量
//        categoryVo.setFacilityCount(facilityList != null ? facilityList.size() : 0);
        
        // 收集并解析fitnessEquipmentIds
        List<Integer> fitnessEquipmentIdList = collectFitnessEquipmentIds(facilityList, storeId, null);
        
        // 查询FitnessEquipmentInfo列表
        List<FitnessEquipmentInfo> fitnessEquipmentInfoList = queryFitnessEquipmentInfoList(fitnessEquipmentIdList, null, storeId);

        // 设置设备列表
        categoryVo.setFacilityList(fitnessEquipmentInfoList);

        categoryVo.setFacilityCount(fitnessEquipmentInfoList.size());

        // 查询并设置图片列表
        // 兼容处理：图片存储时business_id存储的是facility_category编号
        // 需要从该分类名称下的设备中获取facility_category值来查询图片
        List<String> imageList = queryCategoryImageListByCategoryName(storeId, categoryName, facilityList);
        categoryVo.setImageList(imageList);
        
        return categoryVo;
    }
    
    /**
     * 根据分类名称查询设备列表
     *
     * @param storeId      门店ID
     * @param categoryName 分类名称
     * @return 设备列表
     */
    private List<SportsEquipmentFacility> queryFacilityListByCategoryName(Integer storeId, String categoryName) {
        LambdaQueryWrapper<SportsEquipmentFacility> facilityWrapper = new LambdaQueryWrapper<>();
        facilityWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                .eq(SportsEquipmentFacility::getFacilityCategoryName, categoryName)
                .eq(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                .orderByDesc(SportsEquipmentFacility::getCreatedTime);
        return facilityMapper.selectList(facilityWrapper);
    }
    
    /**
     * 构建分类汇总VO对象（旧方法，已废弃，保留用于兼容）
     *
     * @param storeId  门店ID
     * @param category 分类编号
     * @return 分类汇总VO对象
     * @deprecated 请使用 buildCategorySummaryVoByCategoryName 方法
     */
    @Deprecated
    private SportsEquipmentFacilityCategorySummaryVo buildCategorySummaryVo(Integer storeId, Integer category) {
        SportsEquipmentFacilityCategorySummaryVo categoryVo = new SportsEquipmentFacilityCategorySummaryVo();
        categoryVo.setStoreId(storeId);
        categoryVo.setFacilityCategory(category);
        categoryVo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[category]);
        
        // 查询该分类下的设备列表
        List<SportsEquipmentFacility> facilityList = queryFacilityListByCategory(storeId, category);
        
        // 收集并解析fitnessEquipmentIds
        List<Integer> fitnessEquipmentIdList = collectFitnessEquipmentIds(facilityList, storeId, category);
        
        // 查询FitnessEquipmentInfo列表
        List<FitnessEquipmentInfo> fitnessEquipmentInfoList = queryFitnessEquipmentInfoList(fitnessEquipmentIdList, category, storeId);
        
        // 设置设备信息
        categoryVo.setFacilityCount(fitnessEquipmentInfoList.size());
        categoryVo.setFacilityList(fitnessEquipmentInfoList);
        
        // 查询并设置图片列表
        List<String> imageList = queryCategoryImageList(storeId, category);
        categoryVo.setImageList(imageList);
        
        return categoryVo;
    }
    
    /**
     * 查询指定分类下的设备列表
     *
     * @param storeId  门店ID
     * @param category 分类编号
     * @return 设备列表
     */
    private List<SportsEquipmentFacility> queryFacilityListByCategory(Integer storeId, Integer category) {
        LambdaQueryWrapper<SportsEquipmentFacility> facilityWrapper = new LambdaQueryWrapper<>();
        facilityWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                .eq(SportsEquipmentFacility::getFacilityCategory, category)
                .orderByDesc(SportsEquipmentFacility::getCreatedTime);
        return facilityMapper.selectList(facilityWrapper);
    }
    
    /**
     * 从设备列表中收集fitnessEquipmentIds并解析为整数列表
     *
     * @param facilityList 设备列表
     * @param storeId      门店ID（用于日志）
     * @param category     分类编号（用于日志，可为null）
     * @return 去重后的设备ID列表
     */
    private List<Integer> collectFitnessEquipmentIds(List<SportsEquipmentFacility> facilityList, 
                                                      Integer storeId, Integer category) {
        List<Integer> fitnessEquipmentIdList = new ArrayList<>();
        
        if (CollectionUtils.isEmpty(facilityList)) {
            return fitnessEquipmentIdList;
        }
        
        for (SportsEquipmentFacility facility : facilityList) {
            String fitnessEquipmentIds = facility.getFitnessEquipmentIds();
            if (StringUtils.isNotBlank(fitnessEquipmentIds)) {
                List<Integer> parsedIds = parseFitnessEquipmentIds(fitnessEquipmentIds, storeId, category);
                for (Integer id : parsedIds) {
                    if (!fitnessEquipmentIdList.contains(id)) {
                        fitnessEquipmentIdList.add(id);
                    }
                }
            }
        }
        
        return fitnessEquipmentIdList;
    }
    
    /**
     * 解析逗号分隔的ID字符串为整数列表
     *
     * @param fitnessEquipmentIds ID字符串（逗号分隔）
     * @param storeId             门店ID（用于日志）
     * @param category            分类编号（用于日志）
     * @return 解析后的ID列表
     */
    private List<Integer> parseFitnessEquipmentIds(String fitnessEquipmentIds, Integer storeId, Integer category) {
        List<Integer> idList = new ArrayList<>();
        
        if (StringUtils.isBlank(fitnessEquipmentIds)) {
            return idList;
        }
        
        String[] idArray = fitnessEquipmentIds.split(ID_SEPARATOR);
        for (String idStr : idArray) {
            String trimmedId = idStr.trim();
            if (StringUtils.isNotBlank(trimmedId)) {
                try {
                    Integer id = Integer.parseInt(trimmedId);
                    if (id >= MIN_VALID_ID) {
                        idList.add(id);
                    } else {
                        log.warn("解析fitnessEquipmentIds失败，ID小于最小值：{}，storeId={}，category={}", 
                                trimmedId, storeId, category);
                    }
                } catch (NumberFormatException e) {
                    log.warn("解析fitnessEquipmentIds失败，无效的ID格式：{}，storeId={}，category={}，异常信息：{}", 
                            trimmedId, storeId, category, e.getMessage());
                }
            }
        }
        
        return idList;
    }
    
    /**
     * 查询健身设备信息列表
     *
     * @param fitnessEquipmentIdList 设备ID列表
     * @param category               分类编号（用于日志）
     * @param storeId                门店ID（用于日志）
     * @return 过滤并排序后的设备信息列表
     */
    private List<FitnessEquipmentInfo> queryFitnessEquipmentInfoList(List<Integer> fitnessEquipmentIdList, 
                                                                      Integer category, Integer storeId) {
        if (CollectionUtils.isEmpty(fitnessEquipmentIdList)) {
            return new ArrayList<>();
        }
        
        try {
            List<FitnessEquipmentInfo> allEquipmentList = new ArrayList<>(
                    fitnessEquipmentInfoService.listByIds(fitnessEquipmentIdList));
            
            // 过滤掉已删除和禁用的设备，并按sort_order排序
            List<FitnessEquipmentInfo> filteredList = allEquipmentList.stream()
                    .filter(this::isValidFitnessEquipment)
                    .sorted(this::compareBySortOrder)
                    .collect(Collectors.toList());
            
            log.info("查询到FitnessEquipmentInfo设备数量：{}，分类：{}，storeId：{}", 
                    filteredList.size(), category, storeId);
            
            return filteredList;
        } catch (Exception e) {
            log.error("查询FitnessEquipmentInfo列表异常，category={}，storeId={}，异常信息：{}", 
                    category, storeId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 判断健身设备是否有效（未删除且已启用）
     *
     * @param info 健身设备信息
     * @return true表示有效，false表示无效
     */
    private boolean isValidFitnessEquipment(FitnessEquipmentInfo info) {
        return info.getDeleteFlag() != null 
                && info.getDeleteFlag() == DELETE_FLAG_NOT_DELETED
                && info.getStatus() != null 
                && info.getStatus() == STATUS_ENABLED;
    }
    
    /**
     * 按排序号比较两个健身设备信息
     *
     * @param a 设备A
     * @param b 设备B
     * @return 比较结果
     */
    private int compareBySortOrder(FitnessEquipmentInfo a, FitnessEquipmentInfo b) {
        Integer sortOrderA = a.getSortOrder() != null ? a.getSortOrder() : DEFAULT_SORT_ORDER;
        Integer sortOrderB = b.getSortOrder() != null ? b.getSortOrder() : DEFAULT_SORT_ORDER;
        return sortOrderA.compareTo(sortOrderB);
    }
    
    /**
     * 根据分类名称查询图片列表
     * 兼容处理：图片存储时business_id存储的是facility_category编号
     * 需要从该分类名称下的设备中获取facility_category值来查询图片
     *
     * @param storeId      门店ID
     * @param categoryName 分类名称
     * @param facilityList 该分类下的设备列表
     * @return 图片URL列表
     */
    private List<String> queryCategoryImageListByCategoryName(Integer storeId, String categoryName, 
                                                               List<SportsEquipmentFacility> facilityList) {
        try {
            // 从设备列表中获取所有不同的facility_category值
            List<Integer> categoryIdList = facilityList.stream()
                    .map(SportsEquipmentFacility::getFacilityCategory)
                    .filter(category -> category != null && category > 0)
                    .distinct()
                    .collect(Collectors.toList());
            
            if (CollectionUtils.isEmpty(categoryIdList)) {
                return new ArrayList<>();
            }
            
            // 查询所有相关分类的图片
            LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
            imageWrapper.eq(StoreImg::getStoreId, storeId)
                    .in(StoreImg::getBusinessId, categoryIdList)
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
                    .orderByAsc(StoreImg::getImgSort);
            
            List<StoreImg> imageList = storeImgMapper.selectList(imageWrapper);
            
            if (CollectionUtils.isEmpty(imageList)) {
                return new ArrayList<>();
            }
            
            return imageList.stream()
                    .map(StoreImg::getImgUrl)
                    .distinct()
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询分类图片列表异常，storeId={}，categoryName={}，异常信息：{}", 
                    storeId, categoryName, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 查询分类下的图片列表（旧方法，保留用于兼容）
     *
     * @param storeId  门店ID
     * @param category 分类编号
     * @return 图片URL列表
     */
    private List<String> queryCategoryImageList(Integer storeId, Integer category) {
        try {
            LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
            imageWrapper.eq(StoreImg::getStoreId, storeId)
                    .eq(StoreImg::getBusinessId, category)
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
                    .orderByAsc(StoreImg::getImgSort);
            
            List<StoreImg> imageList = storeImgMapper.selectList(imageWrapper);
            
            if (CollectionUtils.isEmpty(imageList)) {
                return new ArrayList<>();
            }
            
            return imageList.stream()
                    .map(StoreImg::getImgUrl)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询分类图片列表异常，storeId={}，category={}，异常信息：{}", 
                    storeId, category, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 保存图片（使用facility.id作为business_id）
     * 
     * @param facilityId 设施ID
     * @param storeId 门店ID
     * @param imageList 图片列表
     */
    private void saveImagesByFacilityId(Integer facilityId, Integer storeId, List<String> imageList) {
        for (int i = 0; i < imageList.size(); i++) {
            StoreImg storeImg = new StoreImg();
            storeImg.setStoreId(storeId);
            storeImg.setImgType(IMG_TYPE_SPORTS_EQUIPMENT);
            storeImg.setBusinessId(facilityId); // business_id存储facility.id
            storeImg.setImgUrl(imageList.get(i));
            storeImg.setImgSort(i + 1);
            storeImg.setImgDescription("运动器材设施实景图片");
            storeImgMapper.insert(storeImg);
        }
    }
    
    /**
     * 保存图片（旧方法，保留用于兼容，使用facility_category作为business_id）
     * 
     * @param facilityCategory 设施分类
     * @param storeId 门店ID
     * @param imageList 图片列表
     */
    private void saveImages(Integer facilityCategory, Integer storeId, List<String> imageList) {
        for (int i = 0; i < imageList.size(); i++) {
            StoreImg storeImg = new StoreImg();
            storeImg.setStoreId(storeId);
            storeImg.setImgType(IMG_TYPE_SPORTS_EQUIPMENT);
            storeImg.setBusinessId(facilityCategory); // business_id存储facility_category
            storeImg.setImgUrl(imageList.get(i));
            storeImg.setImgSort(i + 1);
            storeImg.setImgDescription("运动器材设施实景图片");
            storeImgMapper.insert(storeImg);
        }
    }

    /**
     * 转换为VO对象
     */
    private SportsEquipmentFacilityVo convertToVo(SportsEquipmentFacility facility) {
        SportsEquipmentFacilityVo vo = new SportsEquipmentFacilityVo();
        BeanUtils.copyProperties(facility, vo);
        // 设置分类名称
        if (facility.getFacilityCategory() != null && facility.getFacilityCategory() > 0
                && facility.getFacilityCategory() < FACILITY_CATEGORY_NAMES.length) {
            vo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[facility.getFacilityCategory()]);
        }
        // 设置显示状态文本
        if (facility.getDisplayInStoreDetail() != null) {
            vo.setDisplayInStoreDetailText(facility.getDisplayInStoreDetail() == 1 ? "显示" : "隐藏");
        }
        
        // 查询图片列表，优先使用facility.id作为business_id，兼容历史数据使用facility_category
        List<String> imageList = new ArrayList<>();
        if (facility.getId() != null) {
            // 优先查询使用facility.id作为business_id的图片（新数据）
            LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
            imageWrapper.eq(StoreImg::getStoreId, facility.getStoreId())
                    .eq(StoreImg::getBusinessId, facility.getId())
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
                    .orderByAsc(StoreImg::getImgSort);
            List<StoreImg> imageListByFacilityId = storeImgMapper.selectList(imageWrapper);
            if (!CollectionUtils.isEmpty(imageListByFacilityId)) {
                imageList = imageListByFacilityId.stream().map(StoreImg::getImgUrl)
                        .collect(Collectors.toList());
            } else if (facility.getFacilityCategory() != null) {
                // 如果没有找到，尝试使用facility_category查询（兼容历史数据）
                LambdaQueryWrapper<StoreImg> imageWrapperByCategory = new LambdaQueryWrapper<>();
                imageWrapperByCategory.eq(StoreImg::getStoreId, facility.getStoreId())
                        .eq(StoreImg::getBusinessId, facility.getFacilityCategory())
                        .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
                        .orderByAsc(StoreImg::getImgSort);
                List<StoreImg> imageListByCategory = storeImgMapper.selectList(imageWrapperByCategory);
                if (!CollectionUtils.isEmpty(imageListByCategory)) {
                    imageList = imageListByCategory.stream().map(StoreImg::getImgUrl)
                            .collect(Collectors.toList());
                }
            }
            // 若仍无图片，尝试按区域ID查询（部分数据以 area_id 作为 business_id 存储）
            if (imageList.isEmpty() && facility.getAreaId() != null && facility.getAreaId() > 0) {
                LambdaQueryWrapper<StoreImg> imageWrapperByArea = new LambdaQueryWrapper<>();
                imageWrapperByArea.eq(StoreImg::getStoreId, facility.getStoreId())
                        .eq(StoreImg::getBusinessId, facility.getAreaId())
                        .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
                        .orderByAsc(StoreImg::getImgSort);
                List<StoreImg> imageListByArea = storeImgMapper.selectList(imageWrapperByArea);
                if (!CollectionUtils.isEmpty(imageListByArea)) {
                    imageList = imageListByArea.stream().map(StoreImg::getImgUrl)
                            .collect(Collectors.toList());
                    log.debug("详情图片从区域维度补齐，facilityId={}，areaId={}，数量={}", facility.getId(), facility.getAreaId(), imageList.size());
                }
            }
        }
        vo.setImageList(imageList);
        
        // 如果fitnessEquipmentIds不为空，查询关联的设备信息
        if (StringUtils.isNotBlank(facility.getFitnessEquipmentIds())) {
            // 解析设备ID列表
            List<Integer> equipmentIdList = new ArrayList<>();
            String[] equipmentIdArray = facility.getFitnessEquipmentIds().split(ID_SEPARATOR);
            for (String equipmentIdStr : equipmentIdArray) {
                try {
                    Integer equipmentId = Integer.parseInt(equipmentIdStr.trim());
                    equipmentIdList.add(equipmentId);
                } catch (NumberFormatException e) {
                    log.warn("解析设备ID失败，equipmentIdStr={}，异常信息：{}", equipmentIdStr, e.getMessage());
                }
            }
            
            if (!CollectionUtils.isEmpty(equipmentIdList)) {
                // 查询设备信息，设置设备相关字段（取第一个设备的信息）
                List<FitnessEquipmentInfo> equipmentList = new ArrayList<>(
                        fitnessEquipmentInfoService.listByIds(equipmentIdList));
                if (!CollectionUtils.isEmpty(equipmentList)) {
                    // 取第一个设备的信息（如果有多个设备，取第一个）
                    FitnessEquipmentInfo firstEquipment = equipmentList.get(0);
                    if (firstEquipment != null) {
                        // 设置设备ID
                        vo.setEquipmentId(firstEquipment.getId());
                        // 设置设备名称
                        vo.setEquipmentName(firstEquipment.getEquipmentName());
                        // 设置设备数量
                        vo.setEquipmentNums(firstEquipment.getEquipmentNums());
                        // 设置设备图片URL
                        vo.setEquipmentImage(firstEquipment.getEquipmentImage());
                        log.info("设置设备信息到VO，equipmentId={}，equipmentName={}，equipmentImage={}", 
                                firstEquipment.getId(), firstEquipment.getEquipmentName(), 
                                firstEquipment.getEquipmentImage());
                    }
                }
            }
        }
        
        return vo;
    }


    @Override
    public List<SportsEquipmentFacilityCategoryVo> getstoreCategorySummary(Integer storeId) {
        List<SportsEquipmentFacilityCategoryVo> result = new ArrayList<>();

        // 遍历所有分类（1:有氧区, 2:力量区, 3:单功能机械区）
        for (int category = 1; category < FACILITY_CATEGORY_NAMES.length; category++) {
            SportsEquipmentFacilityCategoryVo categoryVo = new SportsEquipmentFacilityCategoryVo();
            categoryVo.setFacilityCategory(category);
            categoryVo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[category]);

            // 查询该分类下的设备列表（不分页）
            LambdaQueryWrapper<SportsEquipmentFacility> facilityWrapper = new LambdaQueryWrapper<>();
            facilityWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                    .eq(SportsEquipmentFacility::getFacilityCategory, category);
            facilityWrapper.orderByDesc(SportsEquipmentFacility::getCreatedTime);
            List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(facilityWrapper);

            // 设置设备数量
            categoryVo.setFacilityCount(facilityList != null ? facilityList.size() : 0);

            // 转换为VO列表（不包含图片，避免重复查询）
            List<SportsEquipmentFacilityVo> facilityVoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(facilityList)) {
                for (SportsEquipmentFacility facility : facilityList) {
                    SportsEquipmentFacilityVo vo = new SportsEquipmentFacilityVo();
                    BeanUtils.copyProperties(facility, vo);
                    // 设置分类名称
                    vo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[category]);
                    // 设置显示状态文本
                    if (facility.getDisplayInStoreDetail() != null) {
                        vo.setDisplayInStoreDetailText(facility.getDisplayInStoreDetail() == 1 ? "显示" : "隐藏");
                    }
                    facilityVoList.add(vo);
                }
            }
            categoryVo.setFacilityList(facilityVoList);

            // 查询该分类下的图片列表
            LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
            imageWrapper.eq(StoreImg::getStoreId, storeId)
                    .eq(StoreImg::getBusinessId, category)
                    .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
            imageWrapper.orderByAsc(StoreImg::getImgSort);
            List<StoreImg> imageList = storeImgMapper.selectList(imageWrapper);
            if (!CollectionUtils.isEmpty(imageList)) {
                categoryVo.setImageList(imageList.stream().map(StoreImg::getImgUrl)
                        .collect(Collectors.toList()));
            } else {
                categoryVo.setImageList(new ArrayList<>());
            }

            result.add(categoryVo);
        }

        return result;
    }

    @Override
    public boolean saveCategoryImages(Integer storeId, Integer facilityCategory, List<String> imageList) {
        // 参数校验
        if (storeId == null) {
            throw new RuntimeException("门店ID不能为空");
        }
        if (facilityCategory == null) {
            throw new RuntimeException("设施分类不能为空");
        }

        // 校验图片数量（最多20张）
        if (!CollectionUtils.isEmpty(imageList) && imageList.size() > 20) {
            throw new RuntimeException("实景图片最多上传20张");
        }

        // 1. 删除该分类下的旧图片
        LambdaQueryWrapper<StoreImg> deleteImageWrapper = new LambdaQueryWrapper<>();
        deleteImageWrapper.eq(StoreImg::getStoreId, storeId)
                .eq(StoreImg::getBusinessId, facilityCategory)
                .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
        storeImgMapper.delete(deleteImageWrapper);

        // 2. 保存新图片（如果有）
        if (!CollectionUtils.isEmpty(imageList)) {
            saveImages(facilityCategory, storeId, imageList);
        }

        return true;
    }

    /**
     * 查询分类的设备详情（用户端）
     * 包含图片列表、各子分类的设备数量汇总、设备列表
     * 通过fitnessEquipmentIds关联FitnessEquipmentInfo信息
     * 按facility_category_name查询，支持商户自定义分类名称
     * 如果facilityCategoryName为空，返回所有分类的数据
     * 如果equipmentType为空，返回该分类下所有类型的数据
     *
     * @param storeId            门店ID，不能为空且必须大于0
     * @param facilityCategoryName 设施分类名称（商户自定义），可选，为空时返回所有分类
     * @param equipmentType       设备类型(1:心肺训练, 2:核心训练, 3:臀腿训练, 4:上肢训练, 5:全身训练, 6:其他)，可选，为空时返回所有类型
     * @return 分类详情列表，不会返回null
     */
    @Override
    public List<FitnessEquipmentCategoryDetailVo> getCategoryDetail(Integer storeId, String facilityCategoryName, Integer equipmentType) {
        log.info("查询分类的设备详情（用户端），storeId={}，facilityCategoryName={}，equipmentType={}", 
                storeId, facilityCategoryName, equipmentType);
        
        // 参数验证
        if (!isValidStoreId(storeId)) {
            log.warn("查询分类详情失败，门店ID无效：{}", storeId);
            return new ArrayList<>();
        }
        
        try {
            List<FitnessEquipmentCategoryDetailVo> resultList = new ArrayList<>();
            
            // 如果facilityCategoryName为空，返回所有分类的数据
            if (StringUtils.isBlank(facilityCategoryName)) {
                // 查询该店铺下所有不同的设施分类名称
                List<String> categoryNameList = queryDistinctCategoryNames(storeId);
                
                if (CollectionUtils.isEmpty(categoryNameList)) {
                    log.info("查询分类详情完成，storeId={}，未找到分类数据", storeId);
                    return resultList;
                }
                
                // 遍历所有分类名称
                for (String categoryName : categoryNameList) {
                    FitnessEquipmentCategoryDetailVo detailVo = buildCategoryDetailVoByCategoryName(storeId, categoryName, equipmentType);
                    // 只添加有设备数据的分类
                    if (detailVo.getEquipmentTypeList() != null && !detailVo.getEquipmentTypeList().isEmpty()) {
                        resultList.add(detailVo);
                    }
                }
            } else {
                // 返回指定分类名称的数据
                FitnessEquipmentCategoryDetailVo detailVo = buildCategoryDetailVoByCategoryName(storeId, facilityCategoryName, equipmentType);
                resultList.add(detailVo);
            }
            
            log.info("查询分类详情成功，storeId={}，facilityCategoryName={}，equipmentType={}，返回分类数量：{}", 
                    storeId, facilityCategoryName, equipmentType, resultList.size());
            return resultList;
        } catch (Exception e) {
            log.error("查询分类详情异常，storeId={}，facilityCategoryName={}，equipmentType={}，异常信息：{}", 
                    storeId, facilityCategoryName, equipmentType, e.getMessage(), e);
            throw new RuntimeException("查询分类详情异常：" + e.getMessage(), e);
        }
    }
    
    /**
     * 根据分类名称构建单个分类的详情VO对象
     *
     * @param storeId            门店ID
     * @param facilityCategoryName 设施分类名称
     * @param equipmentType       设备类型，可选，如果传入则只返回该类型的设备列表
     * @return 分类详情VO对象
     */
    private FitnessEquipmentCategoryDetailVo buildCategoryDetailVoByCategoryName(Integer storeId, String facilityCategoryName, Integer equipmentType) {
        FitnessEquipmentCategoryDetailVo detailVo = buildBaseCategoryDetailVoByCategoryName(storeId, facilityCategoryName);
        
        // 查询该分类名称下的设备列表（用于查询图片）
        List<SportsEquipmentFacility> facilityList = queryFacilityListByCategoryName(storeId, facilityCategoryName);
        
        // 查询并设置设备相关信息
        List<FitnessEquipmentInfo> allEquipmentList = queryCategoryEquipmentListByCategoryName(storeId, facilityCategoryName);
        
        // 如果传入了equipmentType，只筛选该类型的设备
        List<FitnessEquipmentInfo> filteredEquipmentList = filterAndSortEquipmentList(allEquipmentList, equipmentType);
        
        // 构建设备类型汇总列表（包含设备列表）
        List<FitnessEquipmentTypeSummaryVo> equipmentTypeList = buildEquipmentTypeSummaryList(filteredEquipmentList);
        detailVo.setEquipmentTypeList(equipmentTypeList);
        
        // 计算所有equipmentList中的设备总数
        int totalEquipmentCount = equipmentTypeList.stream()
                .mapToInt(vo -> vo.getEquipmentList() != null ? vo.getEquipmentList().size() : 0)
                .sum();
        
        // 设置设备数量：所有equipmentTypeList中equipmentList的设备总数
        detailVo.setFacilityCount(totalEquipmentCount);
        
        // 查询并设置图片列表
        List<String> imageList = queryCategoryImageListByCategoryName(storeId, facilityCategoryName, facilityList);
        detailVo.setImageList(imageList);
        
        log.debug("构建分类详情VO完成，storeId={}，facilityCategoryName={}，equipmentType={}，设备数量：{}", 
                storeId, facilityCategoryName, equipmentType, totalEquipmentCount);
        return detailVo;
    }
    
    /**
     * 构建单个分类的详情VO对象（旧方法，已废弃，保留用于兼容）
     *
     * @param storeId          门店ID
     * @param facilityCategory 设施分类
     * @param equipmentType    设备类型，可选，如果传入则只返回该类型的设备列表
     * @return 分类详情VO对象
     * @deprecated 请使用 buildCategoryDetailVoByCategoryName 方法
     */
    @Deprecated
    private FitnessEquipmentCategoryDetailVo buildCategoryDetailVo(Integer storeId, Integer facilityCategory, Integer equipmentType) {
        FitnessEquipmentCategoryDetailVo detailVo = buildBaseCategoryDetailVo(storeId, facilityCategory);
        
        // 查询并设置设备相关信息
        List<FitnessEquipmentInfo> allEquipmentList = queryCategoryEquipmentList(storeId, facilityCategory);
        
        // 如果传入了equipmentType，只筛选该类型的设备
        List<FitnessEquipmentInfo> filteredEquipmentList = filterAndSortEquipmentList(allEquipmentList, equipmentType);
        
        // 构建设备类型汇总列表（包含设备列表）
        List<FitnessEquipmentTypeSummaryVo> equipmentTypeList = buildEquipmentTypeSummaryList(filteredEquipmentList);
        detailVo.setEquipmentTypeList(equipmentTypeList);
        
        // 查询并设置图片列表
        List<String> imageList = queryCategoryImageList(storeId, facilityCategory);
        detailVo.setImageList(imageList);
        
        int totalEquipmentCount = equipmentTypeList.stream()
                .mapToInt(vo -> vo.getEquipmentList() != null ? vo.getEquipmentList().size() : 0)
                .sum();
        log.debug("构建分类详情VO完成，storeId={}，facilityCategory={}，equipmentType={}，设备数量：{}", 
                storeId, facilityCategory, equipmentType, totalEquipmentCount);
        return detailVo;
    }
    
    /**
     * 验证门店ID是否有效
     *
     * @param storeId 门店ID
     * @return true表示有效，false表示无效
     */
    private boolean isValidStoreId(Integer storeId) {
        return storeId != null && storeId >= MIN_VALID_ID;
    }
    
    /**
     * 验证设施分类是否有效
     *
     * @param facilityCategory 设施分类
     * @return true表示有效，false表示无效
     */
    private boolean isValidFacilityCategory(Integer facilityCategory) {
        return facilityCategory != null 
                && facilityCategory >= MIN_CATEGORY_NUM 
                && facilityCategory <= MAX_FACILITY_CATEGORY
                && facilityCategory < FACILITY_CATEGORY_NAMES.length;
    }
    
    /**
     * 根据分类名称构建基础分类详情VO对象
     *
     * @param storeId            门店ID
     * @param facilityCategoryName 设施分类名称
     * @return 基础分类详情VO对象
     */
    private FitnessEquipmentCategoryDetailVo buildBaseCategoryDetailVoByCategoryName(Integer storeId, String facilityCategoryName) {
        FitnessEquipmentCategoryDetailVo detailVo = new FitnessEquipmentCategoryDetailVo();
        detailVo.setStoreId(storeId);
        detailVo.setFacilityCategoryName(facilityCategoryName);
        return detailVo;
    }
    
    /**
     * 构建基础分类详情VO对象（旧方法，已废弃，保留用于兼容）
     *
     * @param storeId          门店ID
     * @param facilityCategory 设施分类
     * @return 基础分类详情VO对象
     * @deprecated 请使用 buildBaseCategoryDetailVoByCategoryName 方法
     */
    @Deprecated
    private FitnessEquipmentCategoryDetailVo buildBaseCategoryDetailVo(Integer storeId, Integer facilityCategory) {
        FitnessEquipmentCategoryDetailVo detailVo = new FitnessEquipmentCategoryDetailVo();
        detailVo.setStoreId(storeId);
        detailVo.setFacilityCategory(facilityCategory);
        if (isValidFacilityCategory(facilityCategory)) {
            detailVo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[facilityCategory]);
        }
        return detailVo;
    }
    
    /**
     * 根据分类名称查询分类下的设备列表
     *
     * @param storeId            门店ID
     * @param facilityCategoryName 设施分类名称
     * @return 设备信息列表
     */
    private List<FitnessEquipmentInfo> queryCategoryEquipmentListByCategoryName(Integer storeId, String facilityCategoryName) {
        // 查询该分类名称下的设备列表
        List<SportsEquipmentFacility> facilityList = queryFacilityListByCategoryName(storeId, facilityCategoryName);
        
        // 收集并解析fitnessEquipmentIds
        List<Integer> fitnessEquipmentIdList = collectFitnessEquipmentIds(facilityList, storeId, null);
        
        // 查询所有有效的FitnessEquipmentInfo列表
        return queryAllFitnessEquipmentInfo(fitnessEquipmentIdList, storeId, null);
    }
    
    /**
     * 查询分类下的设备列表（旧方法，已废弃，保留用于兼容）
     *
     * @param storeId          门店ID
     * @param facilityCategory 设施分类
     * @return 设备信息列表
     * @deprecated 请使用 queryCategoryEquipmentListByCategoryName 方法
     */
    @Deprecated
    private List<FitnessEquipmentInfo> queryCategoryEquipmentList(Integer storeId, Integer facilityCategory) {
        // 查询该分类下的设备列表
        List<SportsEquipmentFacility> facilityList = queryFacilityListByCategory(storeId, facilityCategory);
        
        // 收集并解析fitnessEquipmentIds
        List<Integer> fitnessEquipmentIdList = collectFitnessEquipmentIds(facilityList, storeId, facilityCategory);
        
        // 查询所有有效的FitnessEquipmentInfo列表
        return queryAllFitnessEquipmentInfo(fitnessEquipmentIdList, storeId, facilityCategory);
    }
    
    /**
     * 根据设备类型筛选并排序设备列表
     *
     * @param allEquipmentList 所有设备列表
     * @param equipmentType    设备类型，可选
     * @return 筛选并排序后的设备列表
     */
    private List<FitnessEquipmentInfo> filterAndSortEquipmentList(List<FitnessEquipmentInfo> allEquipmentList, 
                                                                   Integer equipmentType) {
        List<FitnessEquipmentInfo> filteredList;
        
        if (isValidEquipmentType(equipmentType)) {
            // 根据equipmentType筛选设备
            filteredList = allEquipmentList.stream()
                    .filter(info -> equipmentType.equals(info.getEquipmentType()))
                    .sorted(this::compareBySortOrder)
                    .collect(Collectors.toList());
        } else {
            // 如果equipmentType为空或无效，返回所有设备
            filteredList = allEquipmentList.stream()
                    .sorted(this::compareBySortOrder)
                    .collect(Collectors.toList());
        }
        
        return filteredList;
    }
    
    /**
     * 验证设备类型是否有效
     *
     * @param equipmentType 设备类型
     * @return true表示有效，false表示无效
     */
    private boolean isValidEquipmentType(Integer equipmentType) {
        return equipmentType != null 
                && equipmentType >= MIN_EQUIPMENT_TYPE 
                && equipmentType <= MAX_EQUIPMENT_TYPE;
    }
    
    /**
     * 查询所有有效的FitnessEquipmentInfo列表
     *
     * @param fitnessEquipmentIdList 设备ID列表
     * @param storeId                门店ID（用于日志）
     * @param facilityCategory       设施分类（用于日志）
     * @return 过滤后的设备信息列表，不会返回null
     */
    private List<FitnessEquipmentInfo> queryAllFitnessEquipmentInfo(List<Integer> fitnessEquipmentIdList, 
                                                                     Integer storeId, Integer facilityCategory) {
        if (CollectionUtils.isEmpty(fitnessEquipmentIdList)) {
            log.debug("设备ID列表为空，返回空列表，storeId={}，facilityCategory={}", storeId, facilityCategory);
            return new ArrayList<>();
        }
        
        try {
            List<FitnessEquipmentInfo> allEquipmentList = new ArrayList<>(
                    fitnessEquipmentInfoService.listByIds(fitnessEquipmentIdList));
            
            // 过滤掉已删除和禁用的设备
            List<FitnessEquipmentInfo> validList = allEquipmentList.stream()
                    .filter(this::isValidFitnessEquipment)
                    .collect(Collectors.toList());
            
            log.debug("查询FitnessEquipmentInfo列表完成，原始数量：{}，有效数量：{}，storeId={}，facilityCategory={}", 
                    allEquipmentList.size(), validList.size(), storeId, facilityCategory);
            return validList;
        } catch (Exception e) {
            log.error("查询FitnessEquipmentInfo列表异常，facilityCategory={}，storeId={}，异常信息：{}", 
                    facilityCategory, storeId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 构建设备类型汇总列表
     * 按equipmentType分组统计各类型的设备数量，并将设备列表放入对应的汇总项中
     *
     * @param equipmentList 设备列表
     * @return 设备类型汇总列表，不会返回null
     */
    private List<FitnessEquipmentTypeSummaryVo> buildEquipmentTypeSummaryList(List<FitnessEquipmentInfo> equipmentList) {
        List<FitnessEquipmentTypeSummaryVo> typeSummaryList = new ArrayList<>();
        
        if (CollectionUtils.isEmpty(equipmentList)) {
            log.debug("设备列表为空，返回空汇总列表");
            return typeSummaryList;
        }
        
        // 按equipmentType分组统计数量和设备列表
        for (int type = MIN_EQUIPMENT_TYPE; type <= MAX_EQUIPMENT_TYPE; type++) {
            final Integer equipmentType = Integer.valueOf(type);
            
            // 筛选该类型下的设备并排序
            List<FitnessEquipmentInfo> typeEquipmentList = equipmentList.stream()
                    .filter(info -> info.getEquipmentType() != null && equipmentType.equals(info.getEquipmentType()))
                    .sorted(this::compareBySortOrder)
                    .collect(Collectors.toList());
            
            if (!CollectionUtils.isEmpty(typeEquipmentList)) {
                FitnessEquipmentTypeSummaryVo typeSummaryVo = createEquipmentTypeSummaryVo(
                        equipmentType, typeEquipmentList.size(), typeEquipmentList);
                typeSummaryList.add(typeSummaryVo);
            }
        }
        
        log.debug("构建设备类型汇总列表完成，汇总类型数量：{}，总设备数量：{}", 
                typeSummaryList.size(), equipmentList.size());
        return typeSummaryList;
    }
    
    /**
     * 创建设备类型汇总VO对象
     *
     * @param equipmentType    设备类型
     * @param count            设备数量
     * @param equipmentList    设备列表
     * @return 设备类型汇总VO对象
     */
    private FitnessEquipmentTypeSummaryVo createEquipmentTypeSummaryVo(Integer equipmentType, Integer count, 
                                                                       List<FitnessEquipmentInfo> equipmentList) {
        FitnessEquipmentTypeSummaryVo typeSummaryVo = new FitnessEquipmentTypeSummaryVo();
        typeSummaryVo.setEquipmentType(equipmentType);
        
        if (equipmentType >= MIN_EQUIPMENT_TYPE && equipmentType <= MAX_EQUIPMENT_TYPE 
                && equipmentType < EQUIPMENT_TYPE_NAMES.length) {
            typeSummaryVo.setEquipmentTypeName(EQUIPMENT_TYPE_NAMES[equipmentType]);
        }
        
        typeSummaryVo.setEquipmentCount(count);
        typeSummaryVo.setEquipmentList(equipmentList);
        return typeSummaryVo;
    }
}

