package com.tcm.training.admin.app.home.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.tcm.training.admin.app.home.vo.AppHomeFeaturedContentVO;
|
import com.tcm.training.admin.app.home.vo.AppHomeFeaturedHealthCourseVO;
|
import com.tcm.training.admin.app.home.vo.AppHomeFeaturedHealthPopularizationVO;
|
import com.tcm.training.admin.live.entity.HealthCourse;
|
import com.tcm.training.admin.live.entity.HealthPopularization;
|
import com.tcm.training.admin.live.entity.LiveCourseCategory;
|
import com.tcm.training.admin.live.mapper.HealthCourseMapper;
|
import com.tcm.training.admin.live.mapper.HealthPopularizationMapper;
|
import com.tcm.training.admin.live.mapper.LiveCourseCategoryMapper;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* APP 首页精选课程介绍模块聚合服务。
|
*/
|
@Service
|
public class AppHomeFeaturedContentService {
|
|
private static final int STATUS_ENABLED = 1;
|
private static final int HOME_RECOMMEND_ENABLED = 1;
|
private final HealthCourseMapper healthCourseMapper;
|
private final HealthPopularizationMapper healthPopularizationMapper;
|
private final LiveCourseCategoryMapper liveCourseCategoryMapper;
|
|
/**
|
* 注入首页精选模块所需的课程、科普与分类查询能力。
|
*/
|
public AppHomeFeaturedContentService(HealthCourseMapper healthCourseMapper,
|
HealthPopularizationMapper healthPopularizationMapper,
|
LiveCourseCategoryMapper liveCourseCategoryMapper) {
|
this.healthCourseMapper = healthCourseMapper;
|
this.healthPopularizationMapper = healthPopularizationMapper;
|
this.liveCourseCategoryMapper = liveCourseCategoryMapper;
|
}
|
|
/**
|
* 查询 APP 首页精选课程介绍模块数据。
|
*/
|
public AppHomeFeaturedContentVO getFeaturedContent() {
|
AppHomeFeaturedContentVO vo = new AppHomeFeaturedContentVO();
|
List<HealthCourse> healthCourses = loadHomeRecommendedHealthCourses();
|
vo.setHealthCourses(toHealthCourseCards(healthCourses));
|
vo.setHealthPopularizations(toPopularizationCards(loadHomeRecommendedPopularizations()));
|
return vo;
|
}
|
|
/**
|
* 查询首页推荐的养生课程。
|
*/
|
private List<HealthCourse> loadHomeRecommendedHealthCourses() {
|
List<HealthCourse> records = healthCourseMapper.selectList(new LambdaQueryWrapper<HealthCourse>()
|
.eq(HealthCourse::getDeleted, 0)
|
.eq(HealthCourse::getStatus, STATUS_ENABLED)
|
.eq(HealthCourse::getIsHomeRecommend, HOME_RECOMMEND_ENABLED)
|
.orderByDesc(HealthCourse::getSort)
|
.orderByDesc(HealthCourse::getId));
|
return records == null ? Collections.<HealthCourse>emptyList() : records;
|
}
|
|
/**
|
* 查询首页推荐的健康科普内容。
|
*/
|
private List<HealthPopularization> loadHomeRecommendedPopularizations() {
|
List<HealthPopularization> records = healthPopularizationMapper.selectList(new LambdaQueryWrapper<HealthPopularization>()
|
.eq(HealthPopularization::getDeleted, 0)
|
.eq(HealthPopularization::getStatus, STATUS_ENABLED)
|
.eq(HealthPopularization::getIsHomeRecommend, HOME_RECOMMEND_ENABLED)
|
.orderByDesc(HealthPopularization::getSort)
|
.orderByDesc(HealthPopularization::getId));
|
return records == null ? Collections.<HealthPopularization>emptyList() : records;
|
}
|
|
/**
|
* 将首页推荐养生课程转换为首页卡片响应。
|
*/
|
private List<AppHomeFeaturedHealthCourseVO> toHealthCourseCards(List<HealthCourse> courses) {
|
if (courses == null || courses.isEmpty()) {
|
return Collections.emptyList();
|
}
|
Map<Long, String> categoryNameMap = loadCategoryNameMap(courses);
|
List<AppHomeFeaturedHealthCourseVO> result =
|
new ArrayList<AppHomeFeaturedHealthCourseVO>(courses.size());
|
for (HealthCourse course : courses) {
|
AppHomeFeaturedHealthCourseVO vo = new AppHomeFeaturedHealthCourseVO();
|
vo.setId(course.getId());
|
vo.setTitle(trimToEmpty(course.getTitle()));
|
vo.setCoverImage(trimToEmpty(course.getCoverImg()));
|
vo.setLevelName(categoryNameMap.get(course.getLevelCategoryId()));
|
vo.setDifficultyName(categoryNameMap.get(course.getDifficultyCategoryId()));
|
vo.setSalePrice(course.getSalePrice() == null ? BigDecimal.ZERO : course.getSalePrice());
|
vo.setLearnUserCount(defaultNumber(course.getLearnUserCount()));
|
vo.setStudyingCount(defaultNumber(course.getStudyingCount()));
|
result.add(vo);
|
}
|
return result;
|
}
|
|
/**
|
* 批量加载首页课程卡片需要展示的分类名称。
|
*/
|
private Map<Long, String> loadCategoryNameMap(List<HealthCourse> courses) {
|
List<Long> categoryIds = new ArrayList<Long>(courses.size() * 2);
|
for (HealthCourse course : courses) {
|
addCategoryId(categoryIds, course.getLevelCategoryId());
|
addCategoryId(categoryIds, course.getDifficultyCategoryId());
|
}
|
if (categoryIds.isEmpty()) {
|
return Collections.emptyMap();
|
}
|
List<LiveCourseCategory> categories = liveCourseCategoryMapper.selectList(new LambdaQueryWrapper<LiveCourseCategory>()
|
.in(LiveCourseCategory::getId, categoryIds)
|
.eq(LiveCourseCategory::getDeleted, 0));
|
Map<Long, String> nameMap = new HashMap<Long, String>(categories.size());
|
for (LiveCourseCategory category : categories) {
|
nameMap.put(category.getId(), trimToEmpty(category.getName()));
|
}
|
return nameMap;
|
}
|
|
/**
|
* 向分类主键列表中追加有效主键,避免空值干扰批量查询。
|
*/
|
private void addCategoryId(List<Long> categoryIds, Long categoryId) {
|
if (categoryId != null && !categoryIds.contains(categoryId)) {
|
categoryIds.add(categoryId);
|
}
|
}
|
|
/**
|
* 将首页推荐健康科普转换为首页宫格卡片响应。
|
*/
|
private List<AppHomeFeaturedHealthPopularizationVO> toPopularizationCards(List<HealthPopularization> items) {
|
if (items == null || items.isEmpty()) {
|
return Collections.emptyList();
|
}
|
List<AppHomeFeaturedHealthPopularizationVO> result =
|
new ArrayList<AppHomeFeaturedHealthPopularizationVO>(items.size());
|
for (HealthPopularization item : items) {
|
AppHomeFeaturedHealthPopularizationVO vo = new AppHomeFeaturedHealthPopularizationVO();
|
vo.setId(item.getId());
|
vo.setTitle(trimToEmpty(item.getTitle()));
|
vo.setCoverImage(trimToEmpty(item.getCoverImg()));
|
vo.setContentType(item.getContentType());
|
vo.setClickCount(defaultNumber(item.getClickCount()));
|
result.add(vo);
|
}
|
return result;
|
}
|
|
/**
|
* 兜底空数字字段,避免前端展示出现空值。
|
*/
|
private Integer defaultNumber(Integer value) {
|
return value == null ? 0 : value;
|
}
|
|
/**
|
* 将可空文本转换为前端可直接消费的空字符串。
|
*/
|
private String trimToEmpty(String value) {
|
if (value == null) {
|
return "";
|
}
|
String trimmed = value.trim();
|
return trimmed.isEmpty() ? "" : trimmed;
|
}
|
}
|