|
|
@@ -5,15 +5,25 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.sqx.modules.firstLogin.dao.WorkExpDao;
|
|
|
import com.sqx.modules.firstLogin.dto.WorkExpDetailDto;
|
|
|
import com.sqx.modules.firstLogin.dto.WorkExpDto;
|
|
|
+import com.sqx.modules.firstLogin.dto.WorkExpTime;
|
|
|
import com.sqx.modules.firstLogin.entity.WorkExp;
|
|
|
+import com.sqx.modules.firstLogin.entity.WorkExpDetail;
|
|
|
+import com.sqx.modules.firstLogin.service.WorkExpDetailService;
|
|
|
import com.sqx.modules.firstLogin.service.WorkExpService;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
|
|
|
@Service
|
|
|
public class WorkExpServiceImpl extends ServiceImpl<WorkExpDao, WorkExp>implements WorkExpService {
|
|
|
+ @Autowired
|
|
|
+ private WorkExpDetailService workExpDetailService;
|
|
|
|
|
|
private final WorkExpDao workExpDao;
|
|
|
|
|
|
@@ -26,6 +36,7 @@ public class WorkExpServiceImpl extends ServiceImpl<WorkExpDao, WorkExp>implemen
|
|
|
return workExpDao.selectWorkExpList(userId);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
@Override
|
|
|
public List<Object> selectWorkExpOne(Integer workExpId) {
|
|
|
return workExpDao.selectWorkExpOne(workExpId);
|
|
|
@@ -34,7 +45,110 @@ public class WorkExpServiceImpl extends ServiceImpl<WorkExpDao, WorkExp>implemen
|
|
|
@Override
|
|
|
public List<WorkExp> selectWorkExpOnly(Long userId) {
|
|
|
QueryWrapper<WorkExp> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.eq("user_id",userId).eq("is_use",1);
|
|
|
+ queryWrapper.eq("user_id", userId).eq("is_use", 1);
|
|
|
return baseMapper.selectList(queryWrapper);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object getWorkExpDetailOne(Long workExpId) {
|
|
|
+ WorkExpDto workExpDto = new WorkExpDto();
|
|
|
+ workExpDto.setWorkExp(baseMapper.selectById(workExpId));
|
|
|
+ QueryWrapper<WorkExpDetail> workExpDetailQueryWrapper = new QueryWrapper<>();
|
|
|
+ workExpDetailQueryWrapper.eq("work_exp_id", workExpId);
|
|
|
+ workExpDto.setWorkExpDetails(workExpDetailService.getBaseMapper().selectList(workExpDetailQueryWrapper));
|
|
|
+ return workExpDto;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+@Override
|
|
|
+public Integer getWorkTime(Long userId) {
|
|
|
+ List<WorkExpTime> sortedWorkExpTimes = workExpDao.getTime(userId);
|
|
|
+ if (sortedWorkExpTimes == null || sortedWorkExpTimes.isEmpty()) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 解析并过滤有效时间区间
|
|
|
+ List<Interval> validIntervals = new ArrayList<>();
|
|
|
+ for (WorkExpTime workExp : sortedWorkExpTimes) {
|
|
|
+ Interval interval = parseInterval(workExp.getStartTime(), workExp.getEndTime());
|
|
|
+ if (interval != null) {
|
|
|
+ validIntervals.add(interval);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 合并重叠/相邻区间(已排序,直接线性合并)
|
|
|
+ List<Interval> mergedIntervals = mergeSortedIntervals(validIntervals);
|
|
|
+
|
|
|
+ // 3. 计算总天数并转换为年(按365.25天/年,兼容闰年)
|
|
|
+ long totalDays = 0;
|
|
|
+ for (Interval interval : mergedIntervals) {
|
|
|
+ totalDays += ChronoUnit.DAYS.between(interval.start, interval.end);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (int) (Math.round((totalDays / 365.25) * 100.0) / 100.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析单条工作经历时间为Interval对象(验证有效性)
|
|
|
+ */
|
|
|
+ private static Interval parseInterval(String startStr, String endStr) {
|
|
|
+ // 过滤空值
|
|
|
+ if (startStr == null || endStr == null || startStr.trim().isEmpty() || endStr.trim().isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 解析时间(去除空格,防止格式错误)
|
|
|
+ LocalDateTime start = LocalDateTime.parse(startStr.trim(), FORMATTER);
|
|
|
+ LocalDateTime end = LocalDateTime.parse(endStr.trim(), FORMATTER);
|
|
|
+
|
|
|
+ // 确保start <= end(若颠倒则交换)
|
|
|
+ if (start.isAfter(end)) {
|
|
|
+ LocalDateTime temp = start;
|
|
|
+ start = end;
|
|
|
+ end = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ return new Interval(start, end);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 忽略解析失败的记录(如格式不匹配)
|
|
|
+ System.err.println("解析失败:start=" + startStr + ", end=" + endStr);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 合并已按start升序排列的区间(核心逻辑)
|
|
|
+ */
|
|
|
+ private static List<Interval> mergeSortedIntervals(List<Interval> sortedIntervals) {
|
|
|
+ if (sortedIntervals.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Interval> merged = new ArrayList<>();
|
|
|
+ // 初始化当前区间为第一个有效区间
|
|
|
+ Interval current = sortedIntervals.get(0);
|
|
|
+
|
|
|
+ // 从第二个区间开始遍历
|
|
|
+ for (int i = 1; i < sortedIntervals.size(); i++) {
|
|
|
+ Interval next = sortedIntervals.get(i);
|
|
|
+
|
|
|
+ // 若下一个区间的start <= 当前区间的end → 重叠或相邻,合并
|
|
|
+ if (!next.start.isAfter(current.end)) {
|
|
|
+ // 合并后的end取两者中较晚的时间
|
|
|
+ LocalDateTime newEnd = next.end.isAfter(current.end) ? next.end : current.end;
|
|
|
+ current = new Interval(current.start, newEnd);
|
|
|
+ } else {
|
|
|
+ // 不重叠,将当前区间加入结果,更新current为下一个区间
|
|
|
+ merged.add(current);
|
|
|
+ current = next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加入最后一个区间
|
|
|
+ merged.add(current);
|
|
|
+ return merged;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+
|