|
|
@@ -24,6 +24,9 @@ import shop.alien.entity.store.StoreStaffFitnessCertification;
|
|
|
import shop.alien.entity.store.StoreStaffFitnessCourse;
|
|
|
import shop.alien.entity.store.StoreStaffFitnessExperience;
|
|
|
import shop.alien.entity.store.vo.PerformanceScheduleVo;
|
|
|
+import shop.alien.entity.store.StoreComment;
|
|
|
+import shop.alien.entity.store.StoreStaffTitle;
|
|
|
+import shop.alien.entity.store.vo.StaffTitleGroupVo;
|
|
|
import shop.alien.entity.store.vo.StoreStaffDetailVo;
|
|
|
import shop.alien.entity.store.vo.StoreStaffDetailWithPerformanceVo;
|
|
|
import shop.alien.entity.store.vo.StoreStaffFitnessDetailVo;
|
|
|
@@ -43,8 +46,11 @@ import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
import java.util.UUID;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -87,6 +93,10 @@ public class StoreStaffConfigServiceImpl implements StoreStaffConfigService {
|
|
|
|
|
|
private final BarPerformanceMapper barPerformanceMapper;
|
|
|
|
|
|
+ private final StoreStaffTitleMapper storeStaffTitleMapper;
|
|
|
+
|
|
|
+ private final StoreCommentMapper storeCommentMapper;
|
|
|
+
|
|
|
private final StoreStaffFitnessExperienceService storeStaffFitnessExperienceService;
|
|
|
|
|
|
/**
|
|
|
@@ -1848,4 +1858,260 @@ public class StoreStaffConfigServiceImpl implements StoreStaffConfigService {
|
|
|
log.info("查询员工职位统计成功,storeId={},职位数量:{}", storeId, result.size());
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 员工列表查询(按标题分组)(用户端)
|
|
|
+ * <p>
|
|
|
+ * 根据店铺ID查询store_staff_title表中的记录,并通过staff_ids关联出store_staff_config
|
|
|
+ * 返回按标题分组的员工列表,每个标题下包含对应的员工信息
|
|
|
+ * 保留原有逻辑:今日是否有演出、点赞数、好评数等
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param storeId 店铺ID,必须大于0
|
|
|
+ * @return 按标题分组的员工列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<StaffTitleGroupVo> queryStaffListByTitle(Integer storeId) {
|
|
|
+ log.info("查询员工列表(按标题分组),参数:storeId={}", storeId);
|
|
|
+
|
|
|
+ // 参数校验
|
|
|
+ if (storeId == null || storeId <= 0) {
|
|
|
+ log.warn("查询员工列表(按标题分组)失败,店铺ID无效:storeId={}", storeId);
|
|
|
+ throw new IllegalArgumentException("店铺ID不能为空且必须大于0");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 查询store_staff_title表中的记录
|
|
|
+ LambdaQueryWrapper<StoreStaffTitle> titleWrapper = new LambdaQueryWrapper<>();
|
|
|
+ titleWrapper.eq(StoreStaffTitle::getStoreId, storeId)
|
|
|
+ .eq(StoreStaffTitle::getDeleteFlag, CommonConstant.DELETE_FLAG_UNDELETE)
|
|
|
+ .orderByAsc(StoreStaffTitle::getCreatedTime);
|
|
|
+
|
|
|
+ List<StoreStaffTitle> titleList = storeStaffTitleMapper.selectList(titleWrapper);
|
|
|
+
|
|
|
+ if (titleList == null || titleList.isEmpty()) {
|
|
|
+ log.info("查询员工列表(按标题分组)成功,但未找到标题记录,storeId={}", storeId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 收集所有员工ID
|
|
|
+ List<Integer> allStaffIds = new ArrayList<>();
|
|
|
+ for (StoreStaffTitle title : titleList) {
|
|
|
+ if (StringUtils.isNotEmpty(title.getStaffIds())) {
|
|
|
+ List<Integer> staffIds = parseStaffConfigIds(title.getStaffIds());
|
|
|
+ allStaffIds.addAll(staffIds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (allStaffIds.isEmpty()) {
|
|
|
+ log.info("查询员工列表(按标题分组)成功,但未找到员工ID,storeId={}", storeId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 批量查询员工信息
|
|
|
+ List<StoreStaffConfig> allStaffList = storeStaffConfigMapper.selectBatchIds(allStaffIds);
|
|
|
+
|
|
|
+ // 4. 构建员工ID到员工对象的映射
|
|
|
+ Map<Integer, StoreStaffConfig> staffMap = allStaffList.stream()
|
|
|
+ .filter(staff -> staff != null && CommonConstant.DELETE_FLAG_UNDELETE.equals(staff.getDeleteFlag()))
|
|
|
+ .collect(Collectors.toMap(StoreStaffConfig::getId, staff -> staff, (a, b) -> a));
|
|
|
+
|
|
|
+ // 5. 批量查询今日有演出的员工ID集合(性能优化)
|
|
|
+ Set<Integer> staffIdsWithPerformanceToday = queryStaffIdsWithPerformanceToday(allStaffIds);
|
|
|
+
|
|
|
+ // 6. 批量查询员工好评数(business_type=5, score>=4.5, business_id=员工ID)
|
|
|
+ Map<Integer, Integer> positiveCommentsCountMap = queryPositiveCommentsCountMap(allStaffIds, storeId);
|
|
|
+
|
|
|
+ // 7. 按标题分组构建结果
|
|
|
+ List<StaffTitleGroupVo> result = new ArrayList<>();
|
|
|
+ for (StoreStaffTitle title : titleList) {
|
|
|
+ StaffTitleGroupVo groupVo = new StaffTitleGroupVo();
|
|
|
+ groupVo.setTitleId(title.getId());
|
|
|
+ groupVo.setTitleName(title.getTitleName());
|
|
|
+ groupVo.setStaffCount(title.getStaffCount());
|
|
|
+
|
|
|
+ // 解析该标题下的员工ID
|
|
|
+ List<Integer> titleStaffIds = parseStaffConfigIds(title.getStaffIds());
|
|
|
+ List<StoreStaffConfig> titleStaffList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (Integer staffId : titleStaffIds) {
|
|
|
+ StoreStaffConfig staff = staffMap.get(staffId);
|
|
|
+ if (staff != null) {
|
|
|
+ // 填充今日是否有演出
|
|
|
+ Boolean hasPerformanceToday = staffIdsWithPerformanceToday.contains(staffId);
|
|
|
+ staff.setHasPerformanceToday(hasPerformanceToday);
|
|
|
+
|
|
|
+ // 填充好评数
|
|
|
+ Integer positiveCommentsCount = positiveCommentsCountMap.getOrDefault(staffId, 0);
|
|
|
+ staff.setPositiveCommentsCount(positiveCommentsCount);
|
|
|
+
|
|
|
+ titleStaffList.add(staff);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ groupVo.setStaffList(titleStaffList);
|
|
|
+ result.add(groupVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("查询员工列表(按标题分组)成功,storeId={},标题数量:{}", storeId, result.size());
|
|
|
+ return result;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询员工列表(按标题分组)异常,storeId={},异常信息:{}", storeId, e.getMessage(), e);
|
|
|
+ throw new RuntimeException("查询员工列表(按标题分组)失败:" + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量查询员工好评数
|
|
|
+ * <p>
|
|
|
+ * 查询每个员工的好评数量(business_type=5, score>=4.5, business_id=员工ID)
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param staffIds 员工ID列表
|
|
|
+ * @param storeId 店铺ID
|
|
|
+ * @return 员工ID到好评数的映射
|
|
|
+ */
|
|
|
+ private Map<Integer, Integer> queryPositiveCommentsCountMap(List<Integer> staffIds, Integer storeId) {
|
|
|
+ Map<Integer, Integer> countMap = new HashMap<>();
|
|
|
+
|
|
|
+ if (staffIds == null || staffIds.isEmpty()) {
|
|
|
+ return countMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 查询好评(business_type=5, score>=4.5, business_id in staffIds)
|
|
|
+ LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(StoreComment::getStoreId, storeId)
|
|
|
+ .eq(StoreComment::getBusinessType, 5)
|
|
|
+ .eq(StoreComment::getDeleteFlag, CommonConstant.DELETE_FLAG_UNDELETE)
|
|
|
+ .isNull(StoreComment::getReplyId)
|
|
|
+ .ge(StoreComment::getScore, 4.5)
|
|
|
+ .in(StoreComment::getBusinessId, staffIds);
|
|
|
+
|
|
|
+ List<StoreComment> positiveComments = storeCommentMapper.selectList(queryWrapper);
|
|
|
+
|
|
|
+ if (positiveComments != null && !positiveComments.isEmpty()) {
|
|
|
+ // 按business_id分组统计
|
|
|
+ Map<Integer, Long> countMapLong = positiveComments.stream()
|
|
|
+ .collect(Collectors.groupingBy(StoreComment::getBusinessId, Collectors.counting()));
|
|
|
+
|
|
|
+ // 转换为Integer
|
|
|
+ for (Map.Entry<Integer, Long> entry : countMapLong.entrySet()) {
|
|
|
+ countMap.put(entry.getKey(), entry.getValue().intValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量查询员工好评数异常,异常信息:{}", e.getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return countMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据标题ID查询员工列表(用户端)
|
|
|
+ * <p>
|
|
|
+ * 根据店铺ID和标题ID查询store_staff_title表中的记录,并通过staff_ids关联出store_staff_config
|
|
|
+ * 返回该标题下的员工列表
|
|
|
+ * 保留原有逻辑:今日是否有演出、点赞数、好评数等
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param storeId 店铺ID,必须大于0
|
|
|
+ * @param titleId 标题ID,必须大于0
|
|
|
+ * @return 员工列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<StoreStaffConfig> queryStaffListByTitleId(Integer storeId, Integer titleId) {
|
|
|
+ log.info("根据标题ID查询员工列表,参数:storeId={}, titleId={}", storeId, titleId);
|
|
|
+
|
|
|
+ // 参数校验
|
|
|
+ if (storeId == null || storeId <= 0) {
|
|
|
+ log.warn("根据标题ID查询员工列表失败,店铺ID无效:storeId={}", storeId);
|
|
|
+ throw new IllegalArgumentException("店铺ID不能为空且必须大于0");
|
|
|
+ }
|
|
|
+ if (titleId == null || titleId <= 0) {
|
|
|
+ log.warn("根据标题ID查询员工列表失败,标题ID无效:titleId={}", titleId);
|
|
|
+ throw new IllegalArgumentException("标题ID不能为空且必须大于0");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 查询store_staff_title表中的记录
|
|
|
+ LambdaQueryWrapper<StoreStaffTitle> titleWrapper = new LambdaQueryWrapper<>();
|
|
|
+ titleWrapper.eq(StoreStaffTitle::getId, titleId)
|
|
|
+ .eq(StoreStaffTitle::getStoreId, storeId)
|
|
|
+ .eq(StoreStaffTitle::getDeleteFlag, CommonConstant.DELETE_FLAG_UNDELETE);
|
|
|
+
|
|
|
+ StoreStaffTitle title = storeStaffTitleMapper.selectOne(titleWrapper);
|
|
|
+
|
|
|
+ if (title == null) {
|
|
|
+ log.warn("根据标题ID查询员工列表失败,标题记录不存在:storeId={}, titleId={}", storeId, titleId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 解析员工IDs
|
|
|
+ if (StringUtils.isEmpty(title.getStaffIds())) {
|
|
|
+ log.info("根据标题ID查询员工列表成功,但标题下无员工:storeId={}, titleId={}", storeId, titleId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Integer> staffIds = parseStaffConfigIds(title.getStaffIds());
|
|
|
+
|
|
|
+ if (staffIds.isEmpty()) {
|
|
|
+ log.info("根据标题ID查询员工列表成功,但解析员工ID为空:storeId={}, titleId={}", storeId, titleId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 批量查询员工信息
|
|
|
+ List<StoreStaffConfig> staffList = storeStaffConfigMapper.selectBatchIds(staffIds);
|
|
|
+
|
|
|
+ if (staffList == null || staffList.isEmpty()) {
|
|
|
+ log.info("根据标题ID查询员工列表成功,但未找到员工记录:storeId={}, titleId={}", storeId, titleId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 过滤已删除的员工
|
|
|
+ List<StoreStaffConfig> validStaffList = staffList.stream()
|
|
|
+ .filter(staff -> staff != null && CommonConstant.DELETE_FLAG_UNDELETE.equals(staff.getDeleteFlag()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (validStaffList.isEmpty()) {
|
|
|
+ log.info("根据标题ID查询员工列表成功,但有效员工为空:storeId={}, titleId={}", storeId, titleId);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 批量查询今日有演出的员工ID集合(性能优化)
|
|
|
+ List<Integer> validStaffIds = validStaffList.stream()
|
|
|
+ .map(StoreStaffConfig::getId)
|
|
|
+ .filter(id -> id != null && id > 0)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ Set<Integer> staffIdsWithPerformanceToday = queryStaffIdsWithPerformanceToday(validStaffIds);
|
|
|
+
|
|
|
+ // 6. 批量查询员工好评数
|
|
|
+ Map<Integer, Integer> positiveCommentsCountMap = queryPositiveCommentsCountMap(validStaffIds, storeId);
|
|
|
+
|
|
|
+ // 7. 填充字段
|
|
|
+ for (StoreStaffConfig staff : validStaffList) {
|
|
|
+ if (staff.getId() != null) {
|
|
|
+ // 填充今日是否有演出
|
|
|
+ Boolean hasPerformanceToday = staffIdsWithPerformanceToday.contains(staff.getId());
|
|
|
+ staff.setHasPerformanceToday(hasPerformanceToday);
|
|
|
+
|
|
|
+ // 填充好评数
|
|
|
+ Integer positiveCommentsCount = positiveCommentsCountMap.getOrDefault(staff.getId(), 0);
|
|
|
+ staff.setPositiveCommentsCount(positiveCommentsCount);
|
|
|
+ } else {
|
|
|
+ staff.setHasPerformanceToday(false);
|
|
|
+ staff.setPositiveCommentsCount(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("根据标题ID查询员工列表成功,storeId={}, titleId={},员工数量:{}",
|
|
|
+ storeId, titleId, validStaffList.size());
|
|
|
+ return validStaffList;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("根据标题ID查询员工列表异常,storeId={}, titleId={},异常信息:{}",
|
|
|
+ storeId, titleId, e.getMessage(), e);
|
|
|
+ throw new RuntimeException("根据标题ID查询员工列表失败:" + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|