|
|
@@ -10,12 +10,18 @@ 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.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.StoreImgMapper;
|
|
|
+import shop.alien.store.service.FitnessEquipmentInfoService;
|
|
|
import shop.alien.store.service.SportsEquipmentFacilityService;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
@@ -37,16 +43,67 @@ public class SportsEquipmentFacilityServiceImpl extends ServiceImpl<SportsEquipm
|
|
|
|
|
|
private final SportsEquipmentFacilityMapper facilityMapper;
|
|
|
private final StoreImgMapper storeImgMapper;
|
|
|
+ private final FitnessEquipmentInfoService fitnessEquipmentInfoService;
|
|
|
|
|
|
/**
|
|
|
* 运动器材设施图片类型
|
|
|
*/
|
|
|
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) {
|
|
|
@@ -140,61 +197,626 @@ public class SportsEquipmentFacilityServiceImpl extends ServiceImpl<SportsEquipm
|
|
|
return this.removeById(id);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 查询指定店铺按分类汇总的设备信息(用户端)
|
|
|
+ * 包含每个分类的设备数量、图片列表和设备列表
|
|
|
+ * 通过fitnessEquipmentIds关联FitnessEquipmentInfo信息
|
|
|
+ * 按facility_category_name分组查询,支持商户自定义分类名称
|
|
|
+ *
|
|
|
+ * @param storeId 门店ID,不能为空且必须大于0
|
|
|
+ * @return 分类汇总列表,不会返回null
|
|
|
+ */
|
|
|
@Override
|
|
|
- public List<SportsEquipmentFacilityCategoryVo> getCategorySummary(Integer storeId) {
|
|
|
- List<SportsEquipmentFacilityCategoryVo> result = new ArrayList<>();
|
|
|
+ public List<SportsEquipmentFacilityCategorySummaryVo> getCategorySummary(Integer storeId) {
|
|
|
+ log.info("查询指定店铺按分类汇总的设备信息(用户端),storeId={}", storeId);
|
|
|
|
|
|
- // 遍历所有分类(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]);
|
|
|
+ // 参数验证
|
|
|
+ if (storeId == null || storeId <= 0) {
|
|
|
+ log.warn("查询分类汇总失败,门店ID无效:{}", storeId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<SportsEquipmentFacilityCategorySummaryVo> result = new ArrayList<>();
|
|
|
|
|
|
- // 查询该分类下的设备列表(不分页)
|
|
|
- LambdaQueryWrapper<SportsEquipmentFacility> facilityWrapper = new LambdaQueryWrapper<>();
|
|
|
- facilityWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
|
|
|
- .eq(SportsEquipmentFacility::getFacilityCategory, category);
|
|
|
- facilityWrapper.orderByDesc(SportsEquipmentFacility::getCreatedTime);
|
|
|
- List<SportsEquipmentFacility> facilityList = facilityMapper.selectList(facilityWrapper);
|
|
|
+ // 查询该店铺下所有不同的设施分类名称(专门用于categorySummary)
|
|
|
+ List<String> categoryNameList = queryDistinctCategoryNamesForCategorySummary(storeId);
|
|
|
|
|
|
- // 设置设备数量
|
|
|
- categoryVo.setFacilityCount(facilityList != null ? facilityList.size() : 0);
|
|
|
+ if (CollectionUtils.isEmpty(categoryNameList)) {
|
|
|
+ log.info("查询指定店铺按分类汇总的设备信息完成,storeId={},未找到分类数据", storeId);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- // 转换为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 ? "显示" : "隐藏");
|
|
|
+ // 按分类名称分组查询
|
|
|
+ for (String categoryName : categoryNameList) {
|
|
|
+ SportsEquipmentFacilityCategorySummaryVo categoryVo = buildCategorySummaryVoByCategoryNameForCategorySummary(
|
|
|
+ storeId, categoryName);
|
|
|
+ // 只添加有设备数据的分类
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询指定店铺下所有不同的设施分类名称(专门用于categorySummary接口,不与其他接口共用)
|
|
|
+ *
|
|
|
+ * @param storeId 门店ID
|
|
|
+ * @return 分类名称列表,不会返回null
|
|
|
+ */
|
|
|
+ private List<String> queryDistinctCategoryNamesForCategorySummary(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("查询设施分类名称列表异常(categorySummary专用),storeId={},异常信息:{}", storeId, e.getMessage(), e);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据分类名称构建分类汇总VO对象(专门用于categorySummary接口,不与其他接口共用)
|
|
|
+ *
|
|
|
+ * @param storeId 门店ID
|
|
|
+ * @param categoryName 分类名称
|
|
|
+ * @return 分类汇总VO对象
|
|
|
+ */
|
|
|
+ private SportsEquipmentFacilityCategorySummaryVo buildCategorySummaryVoByCategoryNameForCategorySummary(Integer storeId, String categoryName) {
|
|
|
+ SportsEquipmentFacilityCategorySummaryVo categoryVo = new SportsEquipmentFacilityCategorySummaryVo();
|
|
|
+ categoryVo.setStoreId(storeId);
|
|
|
+ categoryVo.setFacilityCategoryName(categoryName);
|
|
|
+
|
|
|
+ // 查询该分类名称下的设备列表(专门用于categorySummary)
|
|
|
+ List<SportsEquipmentFacility> facilityList = queryFacilityListByCategoryNameForCategorySummary(storeId, categoryName);
|
|
|
+
|
|
|
+ // 收集并解析fitnessEquipmentIds(专门用于categorySummary)
|
|
|
+ List<Integer> fitnessEquipmentIdList = collectFitnessEquipmentIdsForCategorySummary(facilityList, storeId);
|
|
|
+
|
|
|
+ // 查询FitnessEquipmentInfo列表(专门用于categorySummary)
|
|
|
+ List<FitnessEquipmentInfo> fitnessEquipmentInfoList = queryFitnessEquipmentInfoListForCategorySummary(fitnessEquipmentIdList, storeId);
|
|
|
+
|
|
|
+ // 设置设备列表
|
|
|
+ categoryVo.setFacilityList(fitnessEquipmentInfoList);
|
|
|
+ categoryVo.setFacilityCount(fitnessEquipmentInfoList.size());
|
|
|
+
|
|
|
+ // 查询并设置图片列表(专门用于categorySummary)
|
|
|
+ // 兼容处理:图片存储时business_id存储的是facility_category编号
|
|
|
+ // 需要从该分类名称下的设备中获取facility_category值来查询图片
|
|
|
+ List<String> imageList = queryCategoryImageListByCategoryNameForCategorySummary(storeId, categoryName, facilityList);
|
|
|
+ categoryVo.setImageList(imageList);
|
|
|
+
|
|
|
+ return categoryVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据分类名称查询设备列表(专门用于categorySummary接口,不与其他接口共用)
|
|
|
+ *
|
|
|
+ * @param storeId 门店ID
|
|
|
+ * @param categoryName 分类名称
|
|
|
+ * @return 设备列表
|
|
|
+ */
|
|
|
+ private List<SportsEquipmentFacility> queryFacilityListByCategoryNameForCategorySummary(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);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从设备列表中收集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);
|
|
|
}
|
|
|
- facilityVoList.add(vo);
|
|
|
}
|
|
|
}
|
|
|
- categoryVo.setFacilityList(facilityVoList);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据分类名称查询图片列表(专门用于categorySummary接口,不与其他接口共用)
|
|
|
+ * 兼容处理:图片存储时business_id存储的是facility_category编号
|
|
|
+ * 需要从该分类名称下的设备中获取facility_category值来查询图片
|
|
|
+ *
|
|
|
+ * @param storeId 门店ID
|
|
|
+ * @param categoryName 分类名称
|
|
|
+ * @param facilityList 该分类下的设备列表
|
|
|
+ * @return 图片URL列表
|
|
|
+ */
|
|
|
+ private List<String> queryCategoryImageListByCategoryNameForCategorySummary(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)
|
|
|
- .eq(StoreImg::getBusinessId, category)
|
|
|
- .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
|
|
|
- imageWrapper.orderByAsc(StoreImg::getImgSort);
|
|
|
+ .in(StoreImg::getBusinessId, categoryIdList)
|
|
|
+ .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT)
|
|
|
+ .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<>());
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(imageList)) {
|
|
|
+ return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
- result.add(categoryVo);
|
|
|
+ return imageList.stream()
|
|
|
+ .map(StoreImg::getImgUrl)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询分类图片列表异常(categorySummary专用),storeId={},categoryName={},异常信息:{}",
|
|
|
+ storeId, categoryName, 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);
|
|
|
|
|
|
- return result;
|
|
|
+ // 查询该分类名称下的设备列表
|
|
|
+ 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<>();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -333,5 +955,369 @@ public class SportsEquipmentFacilityServiceImpl extends ServiceImpl<SportsEquipm
|
|
|
|
|
|
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;
|
|
|
+ }
|
|
|
}
|
|
|
|