|
@@ -70,6 +70,7 @@ import java.time.ZoneId;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
import java.time.temporal.ChronoUnit;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1197,108 +1198,250 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public List<FsCourseWatchLogListVO> selectFsCourseWatchLogListVOexport(FsCourseWatchLogListParam param) {
|
|
public List<FsCourseWatchLogListVO> selectFsCourseWatchLogListVOexport(FsCourseWatchLogListParam param) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 1. 参数预处理
|
|
|
|
|
+ if (!preprocessPeriodIds(param)) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // 2. 查询主数据
|
|
|
|
|
+ List<FsCourseWatchLogListVO> list = fsCourseWatchLogMapper.selectFsCourseWatchLogListVOexport(param);
|
|
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
|
|
+ return list;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (param.getSendType()==1&& param.getPeriodETime()!=null && param.getPeriodSTime()!=null) {
|
|
|
|
|
- List<Long> periodIds = userCoursePeriodDaysService.selectFsUserCoursePeriodDaysByTime(param.getPeriodSTime(), param.getPeriodETime());
|
|
|
|
|
|
|
+ // 3. 批量处理所有数据
|
|
|
|
|
+ enrichListData(list);
|
|
|
|
|
|
|
|
- if (!periodIds.isEmpty()){
|
|
|
|
|
- List<Long> longs = userCoursePeriodService.selectFsUserCoursePeriodListByPeriodId(periodIds, param.getCompanyId());
|
|
|
|
|
- if (!longs.isEmpty()){
|
|
|
|
|
- param.setPeriodIds(longs);
|
|
|
|
|
- }else {
|
|
|
|
|
- return new ArrayList<>();
|
|
|
|
|
- }
|
|
|
|
|
- }else {
|
|
|
|
|
- return new ArrayList<>();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return list;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("导出课程观看日志列表失败", e);
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 预处理营期ID
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean preprocessPeriodIds(FsCourseWatchLogListParam param) {
|
|
|
|
|
+ if (param.getSendType() != 1 || param.getPeriodETime() == null || param.getPeriodSTime() == null) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ List<Long> periodIds = userCoursePeriodDaysService.selectFsUserCoursePeriodDaysByTime(
|
|
|
|
|
+ param.getPeriodSTime(), param.getPeriodETime());
|
|
|
|
|
+ if (CollectionUtils.isEmpty(periodIds)) {
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- List<FsCourseWatchLogListVO> list = fsCourseWatchLogMapper.selectFsCourseWatchLogListVOexport(param);
|
|
|
|
|
|
|
+ List<Long> filteredPeriodIds = userCoursePeriodService.selectFsUserCoursePeriodListByPeriodId(
|
|
|
|
|
+ periodIds, param.getCompanyId());
|
|
|
|
|
+ if (CollectionUtils.isEmpty(filteredPeriodIds)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- //查询所有营期
|
|
|
|
|
- List<FsUserCoursePeriod> fsUserCoursePeriods = userCoursePeriodService.selectFsUserCoursePeriodList(new FsUserCoursePeriod());
|
|
|
|
|
|
|
+ param.setPeriodIds(filteredPeriodIds);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ private void enrichListData(List<FsCourseWatchLogListVO> list) {
|
|
|
|
|
+ // 批量预加载所有营期
|
|
|
|
|
+ Map<Long, String> periodNameMap = buildPeriodNameMap();
|
|
|
|
|
+
|
|
|
|
|
+ // 收集所有需要查询的ID
|
|
|
|
|
+ Set<Long> userIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> companyIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> companyUserIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> courseIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> videoIds = new HashSet<>();
|
|
|
|
|
+ Set<String> qwUserIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> qwContactIds = new HashSet<>();
|
|
|
|
|
|
|
|
for (FsCourseWatchLogListVO item : list) {
|
|
for (FsCourseWatchLogListVO item : list) {
|
|
|
- //营期名称
|
|
|
|
|
- if (ObjectUtils.isNotNull(item.getPeriodId())) {
|
|
|
|
|
- // 获取匹配的periodName
|
|
|
|
|
- String periodName = fsUserCoursePeriods.stream()
|
|
|
|
|
- .filter(period -> item.getPeriodId().equals(period.getPeriodId()))
|
|
|
|
|
- .map(FsUserCoursePeriod::getPeriodName)
|
|
|
|
|
- .findFirst()
|
|
|
|
|
- .orElse("无营期名称");
|
|
|
|
|
- item.setPeriodIdName(periodName);
|
|
|
|
|
- }else {
|
|
|
|
|
- item.setPeriodIdName("自动发课无营期名称");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (item.getUserId() != null) userIds.add(item.getUserId());
|
|
|
|
|
+ if (item.getCompanyId() != null) companyIds.add(Long.valueOf(item.getCompanyId()));
|
|
|
|
|
+ if (item.getCompanyUserId() != null) companyUserIds.add(item.getCompanyUserId());
|
|
|
|
|
+ if (item.getCourseId() != null) courseIds.add(item.getCourseId());
|
|
|
|
|
+ if (item.getVideoId() != null) videoIds.add(item.getVideoId());
|
|
|
|
|
+ if (StringUtils.isNotBlank(item.getQwUserId())) qwUserIds.add(item.getQwUserId());
|
|
|
|
|
+ if (item.getQwExternalContactId() != null) qwContactIds.add(Long.valueOf(item.getQwExternalContactId()));
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 项目
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getProject())) {
|
|
|
|
|
- String sysCourseProject = DictUtils.getDictLabel("sys_course_project", String.valueOf(item.getProject()));
|
|
|
|
|
- if(StringUtils.isNotBlank(sysCourseProject)){
|
|
|
|
|
- item.setProjectName(sysCourseProject);
|
|
|
|
|
|
|
+ // 批量查询(使用单条查询方法,但减少重复查询)
|
|
|
|
|
+ Map<Long, FsUser> userMap = batchLoadEntities(userIds, fsUserCacheService::selectFsUserById);
|
|
|
|
|
+ Map<Long, Company> companyMap = batchLoadEntities(companyIds, id -> companyCacheService.selectCompanyById(Long.valueOf(id)));
|
|
|
|
|
+ Map<Long, CompanyUser> companyUserMap = batchLoadEntities(companyUserIds, companyUserCacheService::selectCompanyUserById);
|
|
|
|
|
+ Map<Long, FsUserCourse> courseMap = batchLoadEntities(courseIds, fsUserCourseCacheService::selectFsUserCourseByCourseId);
|
|
|
|
|
+ Map<Long, FsUserCourseVideo> videoMap = batchLoadEntities(videoIds, fsUserCourseVideoCacheService::selectFsUserCourseVideoByVideoId);
|
|
|
|
|
+ Map<String, String> qwUserNameMap = batchLoadQwUserNames(qwUserIds);
|
|
|
|
|
+ Map<Long, String> qwExternalContactMap = batchLoadQwExternalContacts(qwContactIds);
|
|
|
|
|
+
|
|
|
|
|
+ // 处理每个条目
|
|
|
|
|
+ for (FsCourseWatchLogListVO item : list) {
|
|
|
|
|
+ enrichItemData(item, periodNameMap, userMap, companyMap, companyUserMap,
|
|
|
|
|
+ courseMap, videoMap, qwUserNameMap, qwExternalContactMap);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量加载实体数据(使用现有的单条查询方法)
|
|
|
|
|
+ */
|
|
|
|
|
+ private <K, V> Map<K, V> batchLoadEntities(Set<K> ids, Function<K, V> loader) {
|
|
|
|
|
+ if (CollectionUtils.isEmpty(ids)) {
|
|
|
|
|
+ return Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Map<K, V> result = new HashMap<>();
|
|
|
|
|
+ for (K id : ids) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ V value = loader.apply(id);
|
|
|
|
|
+ if (value != null) {
|
|
|
|
|
+ result.put(id, value);
|
|
|
}
|
|
}
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("加载数据失败,ID: {}", id, e);
|
|
|
}
|
|
}
|
|
|
- // 用户名
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getUserId())) {
|
|
|
|
|
- FsUser fsUser = fsUserCacheService.selectFsUserById(item.getUserId());
|
|
|
|
|
- if(ObjectUtils.isNotNull(fsUser)){
|
|
|
|
|
- item.setExternalUserName(String.format("%s_%d",fsUser.getNickName(),fsUser.getUserId()));
|
|
|
|
|
- item.setFsNickName(fsUser.getNickName());
|
|
|
|
|
- item.setFsAvatar(fsUser.getAvatar());
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量加载企微用户名
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, String> batchLoadQwUserNames(Set<String> qwUserIds) {
|
|
|
|
|
+ Map<String, String> result = new HashMap<>();
|
|
|
|
|
+ for (String qwUserId : qwUserIds) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ String name = qwUserCacheService.queryQwUserNameByUserId(qwUserId);
|
|
|
|
|
+ if (StringUtils.isNotBlank(name)) {
|
|
|
|
|
+ result.put(qwUserId, name);
|
|
|
}
|
|
}
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("加载企微用户失败,ID: {}", qwUserId, e);
|
|
|
}
|
|
}
|
|
|
- // 公司名
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getCompanyId())){
|
|
|
|
|
- Company company = companyCacheService.selectCompanyById(Long.valueOf(item.getCompanyId()));
|
|
|
|
|
- if(ObjectUtils.isNotNull(company)){
|
|
|
|
|
- item.setCompanyName(String.format("%s_%d", company.getCompanyName(), company.getCompanyId()));
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量加载企微外部联系人
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<Long, String> batchLoadQwExternalContacts(Set<Long> contactIds) {
|
|
|
|
|
+ Map<Long, String> result = new HashMap<>();
|
|
|
|
|
+ for (Long contactId : contactIds) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ String name = qwExternalContactCacheService.selectQwExternalContactById(contactId);
|
|
|
|
|
+ if (StringUtils.isNotBlank(name)) {
|
|
|
|
|
+ result.put(contactId, name);
|
|
|
}
|
|
}
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("加载企微外部联系人失败,ID: {}", contactId, e);
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 销售名
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getCompanyUserId())){
|
|
|
|
|
- CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(item.getCompanyUserId());
|
|
|
|
|
- if(ObjectUtils.isNotNull(companyUser)){
|
|
|
|
|
- item.setCompanyUserName(String.format("%s_%d", companyUser.getNickName(), companyUser.getUserId()));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构建营期名称映射
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<Long, String> buildPeriodNameMap() {
|
|
|
|
|
+ List<FsUserCoursePeriod> periods = userCoursePeriodService.selectFsUserCoursePeriodList(new FsUserCoursePeriod());
|
|
|
|
|
+ return periods.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(
|
|
|
|
|
+ FsUserCoursePeriod::getPeriodId,
|
|
|
|
|
+ FsUserCoursePeriod::getPeriodName,
|
|
|
|
|
+ (v1, v2) -> v1
|
|
|
|
|
+ ));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 处理单个条目的数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private void enrichItemData(FsCourseWatchLogListVO item,
|
|
|
|
|
+ Map<Long, String> periodNameMap,
|
|
|
|
|
+ Map<Long, FsUser> userMap,
|
|
|
|
|
+ Map<Long, Company> companyMap,
|
|
|
|
|
+ Map<Long, CompanyUser> companyUserMap,
|
|
|
|
|
+ Map<Long, FsUserCourse> courseMap,
|
|
|
|
|
+ Map<Long, FsUserCourseVideo> videoMap,
|
|
|
|
|
+ Map<String, String> qwUserNameMap,
|
|
|
|
|
+ Map<Long, String> qwExternalContactMap) {
|
|
|
|
|
+
|
|
|
|
|
+ // 设置营期名称
|
|
|
|
|
+ if (item.getPeriodId() != null) {
|
|
|
|
|
+ String periodName = periodNameMap.get(item.getPeriodId());
|
|
|
|
|
+ item.setPeriodIdName(periodName != null ? periodName : "无营期名称");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ item.setPeriodIdName("自动发课无营期名称");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置项目名称
|
|
|
|
|
+ if (item.getProject() != null) {
|
|
|
|
|
+ String projectName = DictUtils.getDictLabel("sys_course_project",
|
|
|
|
|
+ String.valueOf(item.getProject()));
|
|
|
|
|
+ if (StringUtils.isNotBlank(projectName)) {
|
|
|
|
|
+ item.setProjectName(projectName);
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 课程
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getCourseId())){
|
|
|
|
|
- FsUserCourse course = fsUserCourseCacheService.selectFsUserCourseByCourseId(item.getCourseId());
|
|
|
|
|
- if(ObjectUtils.isNotNull(course)){
|
|
|
|
|
- item.setCourseName(course.getCourseName());
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 设置用户信息
|
|
|
|
|
+ if (item.getUserId() != null) {
|
|
|
|
|
+ FsUser user = userMap.get(item.getUserId());
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ item.setExternalUserName(String.format("%s_%d", user.getNickName(), user.getUserId()));
|
|
|
|
|
+ item.setFsNickName(user.getNickName());
|
|
|
|
|
+ item.setFsAvatar(user.getAvatar());
|
|
|
}
|
|
}
|
|
|
- // 小节
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getVideoId())){
|
|
|
|
|
- FsUserCourseVideo fsUserCourseVideo = fsUserCourseVideoCacheService.selectFsUserCourseVideoByVideoId(item.getVideoId());
|
|
|
|
|
- if(ObjectUtils.isNotNull(fsUserCourseVideo)){
|
|
|
|
|
- item.setVideoName(fsUserCourseVideo.getTitle());
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置公司信息
|
|
|
|
|
+ if (item.getCompanyId() != null) {
|
|
|
|
|
+ Company company = companyMap.get(item.getCompanyId());
|
|
|
|
|
+ if (company != null) {
|
|
|
|
|
+ item.setCompanyName(String.format("%s_%d",
|
|
|
|
|
+ company.getCompanyName(), company.getCompanyId()));
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 企微用户名
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getQwUserId())){
|
|
|
|
|
- String qwUserName = qwUserCacheService.queryQwUserNameByUserId(item.getQwUserId());
|
|
|
|
|
- if(StringUtils.isNotBlank(qwUserName)){
|
|
|
|
|
- item.setQwUserName(qwUserName);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 设置销售信息
|
|
|
|
|
+ if (item.getCompanyUserId() != null) {
|
|
|
|
|
+ CompanyUser companyUser = companyUserMap.get(item.getCompanyUserId());
|
|
|
|
|
+ if (companyUser != null) {
|
|
|
|
|
+ item.setCompanyUserName(String.format("%s_%d",
|
|
|
|
|
+ companyUser.getNickName(), companyUser.getUserId()));
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 企微外部联系人
|
|
|
|
|
- if(ObjectUtils.isNotNull(item.getQwExternalContactId())){
|
|
|
|
|
- String qwExternalContactName = qwExternalContactCacheService.selectQwExternalContactById(Long.valueOf(item.getQwExternalContactId()));
|
|
|
|
|
- if(StringUtils.isNotBlank(qwExternalContactName)){
|
|
|
|
|
- item.setExternalUserName(qwExternalContactName);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 设置课程信息
|
|
|
|
|
+ if (item.getCourseId() != null) {
|
|
|
|
|
+ FsUserCourse course = courseMap.get(item.getCourseId());
|
|
|
|
|
+ if (course != null) {
|
|
|
|
|
+ item.setCourseName(course.getCourseName());
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // 设置视频信息
|
|
|
|
|
+ if (item.getVideoId() != null) {
|
|
|
|
|
+ FsUserCourseVideo video = videoMap.get(item.getVideoId());
|
|
|
|
|
+ if (video != null) {
|
|
|
|
|
+ item.setVideoName(video.getTitle());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置企微用户信息
|
|
|
|
|
+ if (StringUtils.isNotBlank(item.getQwUserId())) {
|
|
|
|
|
+ String qwUserName = qwUserNameMap.get(item.getQwUserId());
|
|
|
|
|
+ if (StringUtils.isNotBlank(qwUserName)) {
|
|
|
|
|
+ item.setQwUserName(qwUserName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置企微外部联系人信息
|
|
|
|
|
+ if (item.getQwExternalContactId() != null) {
|
|
|
|
|
+ String contactName = qwExternalContactMap.get(item.getQwExternalContactId());
|
|
|
|
|
+ if (StringUtils.isNotBlank(contactName)) {
|
|
|
|
|
+ // 注意:这里会覆盖之前设置的外部用户名
|
|
|
|
|
+ item.setExternalUserName(contactName);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- return list;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|