diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java index 343330c2..eb4a4212 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java @@ -1617,7 +1617,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl busProjectTeams = projectTeamService.listByIds(list1); Map teamMap = busProjectTeams.stream().collect(Collectors.toMap(BusProjectTeam::getId, BusProjectTeam::getTeamName)); - ArrayList attendanceTodayUserVos = new ArrayList<>(); + List attendanceTodayUserVos = new ArrayList<>(); for (SubConstructionUser constructionUser : records) { AttendanceTodayUserVo attendanceTodayUserVo = new AttendanceTodayUserVo(); attendanceTodayUserVo.setUserId(constructionUser.getSysUserId()); @@ -1627,6 +1627,6 @@ public class SubConstructionUserServiceImpl extends ServiceImpl(attendanceTodayUserVos, result.getTotal()); + return new TableDataInfo<>(attendanceTodayUserVos, result.getTotal()); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusAttendanceController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusAttendanceController.java index 0db7f45f..90fa504c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusAttendanceController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusAttendanceController.java @@ -6,11 +6,16 @@ import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.contractor.domain.dto.contractor.SubContractorQueryReq; +import org.dromara.contractor.domain.vo.contractor.SubContractorVo; +import org.dromara.contractor.service.ISubContractorService; import org.dromara.project.domain.dto.attendance.*; import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq; import org.dromara.project.domain.vo.attendance.*; import org.dromara.project.domain.vo.projectteam.BusProjectTeamVo; import org.dromara.project.service.IBusProjectTeamService; +import org.dromara.system.domain.dto.FbUserListDto; +import org.dromara.system.domain.vo.SysUserVo; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -43,6 +48,8 @@ public class BusAttendanceController extends BaseController { private final IBusProjectTeamService projectTeamService; + private final ISubContractorService contractorService; + /** * 查询考勤列表 */ @@ -156,4 +163,47 @@ public class BusAttendanceController extends BaseController { return R.ok(projectTeamService.queryList(busProjectTeamQueryReq)); } + + /** + * 查询项目分包人员当天考勤状况 + */ + @GetMapping("/sub/list/clockDate/today") + public R getSubTodayAttendanceData(SubTwoWeekDto dto) { + return R.ok(busAttendanceService.getSubTodayAttendanceData(dto)); + } + + /** + * 查询项目分包人员前14天考勤状况 + */ + @GetMapping("/sub/list/clockDate/twoWeek") + public R> getSubClockDateForTwoWeekList(SubTwoWeekDto dto) { + return R.ok(busAttendanceService.getSubClockDateForTwoWeekList(dto)); + } + + + /** + * 查询项目分包人员当月考勤状况 + */ + @GetMapping("/sub/countList") + public TableDataInfo subCountList(SubUserAttendanceQueryReq dto, PageQuery pageQuery) { + return busAttendanceService.subCountList(dto, pageQuery); + } + + + /** + * 查询分包当天出勤人员 + */ + @GetMapping("/sub/list/attendanceUser") + public TableDataInfo getSubTodayAttendanceUser(SubTodayUserDto dto, PageQuery pageQuery) { + return busAttendanceService.getSubTodayAttendanceUser(dto,pageQuery); + } + + /** + * 查询分包公司 + */ + @GetMapping("/subContractorList") + public TableDataInfo list(SubContractorQueryReq req, PageQuery pageQuery) { + return contractorService.queryPageList(req, pageQuery); + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubTodayUserDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubTodayUserDto.java new file mode 100644 index 00000000..a3f66f23 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubTodayUserDto.java @@ -0,0 +1,38 @@ +package org.dromara.project.domain.dto.attendance; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDate; +import java.util.List; + +@Data +public class SubTodayUserDto { + + /** + * 人员姓名 + */ + private String userName; + + /** + * 分包公司Id + */ + private Long contractorId; + + /** + * 项目id + */ + private Long projectId; + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate date; + + private List userIds; + + /** + * 出勤状态 1-全勤 2-缺勤 3-请假 + */ + private String type; + + private Boolean isToday; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubTwoWeekDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubTwoWeekDto.java new file mode 100644 index 00000000..278443bb --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubTwoWeekDto.java @@ -0,0 +1,22 @@ +package org.dromara.project.domain.dto.attendance; + +import lombok.Data; + +@Data +public class SubTwoWeekDto { + + /** + * 人员姓名 + */ + private String userName; + + /** + * 分包公司Id + */ + private Long contractorId; + + /** + * 项目id + */ + private Long projectId; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubUserAttendanceQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubUserAttendanceQueryReq.java new file mode 100644 index 00000000..5dbe8704 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/SubUserAttendanceQueryReq.java @@ -0,0 +1,40 @@ +package org.dromara.project.domain.dto.attendance; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lilemy + * @date 2025/4/7 10:52 + */ +@Data +public class SubUserAttendanceQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = -6634291825924626633L; + + /** + * 人员姓名 + */ + private String userName; + + /** + * 项目id + */ + @NotNull(message = "项目id不能为空") + private Long projectId; + + /** + * 分包id + */ + private Long contractorId; + + /** + * 打卡月份 + */ + private String clockDate; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/SubAttendanceTodayUserVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/SubAttendanceTodayUserVo.java new file mode 100644 index 00000000..221fb51d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/SubAttendanceTodayUserVo.java @@ -0,0 +1,24 @@ +package org.dromara.project.domain.vo.attendance; + +import lombok.Data; +import org.dromara.common.translation.annotation.Translation; +import org.dromara.common.translation.constant.TransConstant; + +@Data +public class SubAttendanceTodayUserVo { + + private Long userId; + + private String userName; + + /** + * 分包 + */ + private Long contractorId; + + /** + * 分包单位名称 + */ + private String contractorName; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/SubUserAttendanceTotalVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/SubUserAttendanceTotalVo.java new file mode 100644 index 00000000..61050acf --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/SubUserAttendanceTotalVo.java @@ -0,0 +1,64 @@ +package org.dromara.project.domain.vo.attendance; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * @author lilemy + * @date 2025/4/7 10:16 + */ +@Data +public class SubUserAttendanceTotalVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1335094839733429171L; + + /** + * 主键id + */ + private Long id; + + /** + * 人员姓名 + */ + private String userName; + + /** + * 分包 + */ + private Long contractorId; + + /** + * 分包单位名称 + */ + private String contractorName; + + /** + * 出勤天数 + */ + private Integer attendanceDays; + + /** + * 迟到天数 + */ + private Integer lateDays; + + /** + * 早退天数 + */ + private Integer leaveEarlyDays; + + /** + * 缺卡天数 + */ + private Integer unClockDays; + + /** + * 请假天数 + */ + private Integer leaveDays; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceService.java index 58b0f09d..f44760ea 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceService.java @@ -196,5 +196,23 @@ public interface IBusAttendanceService extends IService{ */ void getExportList(AttendanceExportDto dto,HttpServletResponse response); + /** + * 获取分包当天的考勤数据 + */ + BusAttendanceClockDateForTwoWeekVo getSubTodayAttendanceData(SubTwoWeekDto dto); + /** + * 分包近两周打卡统计 + */ + List getSubClockDateForTwoWeekList(SubTwoWeekDto dto); + + /** + * 获取分包打卡统计 + */ + TableDataInfo subCountList(SubUserAttendanceQueryReq dto, PageQuery pageQuery); + + /** + * 查询分包当天出勤人员 + */ + TableDataInfo getSubTodayAttendanceUser(SubTodayUserDto dto, PageQuery pageQuery); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java index eec6acc4..d7462db0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java @@ -47,6 +47,7 @@ import org.dromara.project.domain.vo.attendance.*; import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo; import org.dromara.project.mapper.BusAttendanceMapper; import org.dromara.project.service.*; +import org.dromara.system.domain.SysUser; import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.service.ISysOssService; @@ -60,11 +61,12 @@ import java.io.OutputStream; import java.math.BigDecimal; import java.time.*; import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; -import static org.dromara.project.domain.enums.BusAttendanceClockStatusEnum.ATTENDANCE_LIST; +import static org.dromara.project.domain.enums.BusAttendanceClockStatusEnum.*; /** * 考勤Service业务层处理 @@ -118,7 +120,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl ATTENDANCE_STATUS = new HashSet<>(Arrays.asList(BusAttendanceClockStatusEnum.NORMAL.getValue(), - BusAttendanceClockStatusEnum.LATE.getValue(), BusAttendanceClockStatusEnum.LEAVEEARLY.getValue() + LATE.getValue(), LEAVEEARLY.getValue() , BusAttendanceClockStatusEnum.REISSUE.getValue())); @@ -159,14 +161,14 @@ public class BusAttendanceServiceImpl extends ServiceImpl getTodayAttendanceV1(Long projectId, Long userId) { @@ -1074,7 +1077,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl getAbnormalAttendance(Long projectId,String handle, PageQuery pageQuery) { + public TableDataInfo getAbnormalAttendance(Long projectId, String handle, PageQuery pageQuery) { - List abnormalList = Arrays.asList(BusAttendanceClockStatusEnum.LATE.getValue(), - BusAttendanceClockStatusEnum.LEAVEEARLY.getValue(), + List abnormalList = Arrays.asList(LATE.getValue(), + LEAVEEARLY.getValue(), BusAttendanceClockStatusEnum.UNCLOCK.getValue()); // 获取当前用户ID @@ -1654,8 +1657,8 @@ public class BusAttendanceServiceImpl extends ServiceImpl list = list(Wrappers.lambdaQuery() .eq(BusAttendance::getClockDate, date) .eq(BusAttendance::getProjectId, dto.getProjectId()) @@ -1775,18 +1778,18 @@ public class BusAttendanceServiceImpl extends ServiceImpl list1 = list.stream().map(BusAttendance::getUserId).distinct().toList(); - if(CollectionUtil.isEmpty(list1)){ + if (CollectionUtil.isEmpty(list1)) { return TableDataInfo.build(); } dto.setUserIds(list1); - }else if("2".equals(dto.getType())){ + } else if ("2".equals(dto.getType())) { List list = list(Wrappers.lambdaQuery() .eq(BusAttendance::getClockDate, date) .eq(BusAttendance::getProjectId, dto.getProjectId()) .in(BusAttendance::getClockStatus, ATTENDANCE_LIST) ); List list1 = list.stream().map(BusAttendance::getUserId).distinct().toList(); - if(date.isEqual(LocalDate.now())){ + if (date.isEqual(LocalDate.now())) { String todayStr = date.format(DateTimeFormatter.ISO_LOCAL_DATE); List list2 = leaveService.list(Wrappers.lambdaQuery() .eq(BusLeave::getProjectId, dto.getProjectId()) @@ -1801,7 +1804,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl unlocks = list(Wrappers.lambdaQuery() .eq(BusAttendance::getClockDate, date) .eq(BusAttendance::getProjectId, dto.getProjectId()) @@ -1811,12 +1814,12 @@ public class BusAttendanceServiceImpl extends ServiceImpl list2 = leaveService.list(Wrappers.lambdaQuery() .eq(BusLeave::getProjectId, dto.getProjectId()) @@ -1826,7 +1829,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl= {0}", todayStr)); List list11 = list2.stream().map(BusLeave::getUserId).distinct().toList(); - if(CollectionUtil.isEmpty(list11)){ + if (CollectionUtil.isEmpty(list11)) { return TableDataInfo.build(); } dto.setUserIds(list11); @@ -2222,4 +2225,308 @@ public class BusAttendanceServiceImpl extends ServiceImpl userListBySubDto = userService.getUserListBySubDto(dto); + List allUserIds = userListBySubDto.stream().map(SysUser::getUserId).collect(Collectors.toList()); + + + //当天请假人数 + String todayStr = now.format(DateTimeFormatter.ISO_LOCAL_DATE); // 结果:"2024-10-10" + + // 2. 拼接 SQL 时添加单引号,确保语法正确 + int count = 0; + if (CollectionUtil.isNotEmpty(allUserIds)) { + count = (int) leaveService.count(Wrappers.lambdaQuery() + .eq(BusLeave::getProjectId, dto.getProjectId()) + .in(BusLeave::getUserId, allUserIds) + // 关键:给日期字符串加单引号,避免 SQL 语法错误 + .apply("DATE(start_time) <= {0}", todayStr) + .apply("DATE(end_time) >= {0}", todayStr) + ); + } + + List list; + if (CollectionUtil.isEmpty(allUserIds)) { + list = new ArrayList<>(); + } else { + list = list(Wrappers.lambdaQuery() + .in(CollectionUtil.isNotEmpty(allUserIds), BusAttendance::getUserId, allUserIds) + .eq(BusAttendance::getClockDate, now) + .orderByAsc(BusAttendance::getClockDate) + ); + } + + Map> collect = list.stream().collect(Collectors.groupingBy(BusAttendance::getUserId)); + + int full = 0, half = 0, absent = 0; + + for (Map.Entry> userEntry : collect.entrySet()) { + List records = userEntry.getValue(); + + long validCount = records.stream() + .map(BusAttendance::getClockStatus) + .filter(ATTENDANCE_LIST::contains) + .count(); + + if (validCount >= 2) { + full++; + } else if (validCount == 1) { + half++; + } else { + absent++; + } + } + + BusAttendanceClockDateForTwoWeekVo vo = new BusAttendanceClockDateForTwoWeekVo(); + vo.setClockDate(now); + vo.setAttendance(full); + vo.setHalfAttendance(half); + vo.setAbsenteeism(allUserIds.size() - count - full - half); + //计算考勤率 + vo.setAllUserNum(allUserIds.size() - count); + vo.setLeave(count); + vo.setClockNum(full + half); + vo.setAttendanceRate(BigDecimalUtil.toPercentage(new BigDecimal(full + half), + new BigDecimal(vo.getAllUserNum()))); + return vo; + } + + @Override + public List getSubClockDateForTwoWeekList(SubTwoWeekDto dto) { + LocalDate now = LocalDate.now(); + + //查询所有分包人员 + List userListBySubDto = userService.getUserListBySubDto(dto); + List allUserIds = userListBySubDto.stream().map(SysUser::getUserId).collect(Collectors.toList()); + + // 往前14天,包含今天 + LocalDate startDate = now.minusDays(13); + List list; + if (CollectionUtil.isEmpty(allUserIds)) { + list = new ArrayList<>(); + } else { + list = list(Wrappers.lambdaQuery() + .in(BusAttendance::getUserId, allUserIds) + .between(BusAttendance::getClockDate, startDate, now) + .orderByAsc(BusAttendance::getClockDate) + ); + } + + // 按日期分组 + Map> groupedByDate = list.stream() + .collect(Collectors.groupingBy(BusAttendance::getClockDate)); + + // 按日期和用户ID分组 + Map>> dateUserMap = new HashMap<>(); + for (Map.Entry> entry : groupedByDate.entrySet()) { + LocalDate date = entry.getKey(); + Map> userAttendanceMap = entry.getValue().stream() + .collect(Collectors.groupingBy(BusAttendance::getUserId)); + dateUserMap.put(date, userAttendanceMap); + } + + // 统计全勤、半勤、缺卡人数 + List result = new ArrayList<>(); + + LocalDate currentDate = startDate; + while (!currentDate.isAfter(now)) { + Map> userAttendanceMap = dateUserMap.getOrDefault(currentDate, new HashMap<>()); + + int full = 0, half = 0, absent = 0; + + for (Map.Entry> userEntry : userAttendanceMap.entrySet()) { + List records = userEntry.getValue(); + + long validCount = records.stream() + .map(BusAttendance::getClockStatus) + .filter(ATTENDANCE_LIST::contains) + .count(); + + if (validCount >= 1) { + full++; + } else { + absent++; + } + } + + BusAttendanceClockDateForTwoWeekVo vo = new BusAttendanceClockDateForTwoWeekVo(); + vo.setClockDate(currentDate); + vo.setAttendance(full); + vo.setHalfAttendance(half); + vo.setAbsenteeism(absent); + + String todayStr = currentDate.format(DateTimeFormatter.ISO_LOCAL_DATE); // 结果:"2024-10-10" + + if (currentDate.isEqual(now)) { + vo.setAbsenteeism(allUserIds.size() - full); + } + + int count = 0; + if (CollectionUtil.isNotEmpty(allUserIds)) { + count = (int) leaveService.count(Wrappers.lambdaQuery() + .eq(BusLeave::getProjectId, dto.getProjectId()) + .in(BusLeave::getUserId, allUserIds) + // 关键:给日期字符串加单引号,避免 SQL 语法错误 + .apply("DATE(start_time) <= {0}", todayStr) + .apply("DATE(end_time) >= {0}", todayStr) + ); + } + vo.setLeave(count); + result.add(vo); + currentDate = currentDate.plusDays(1); + } + + return result; + } + + @Override + public TableDataInfo subCountList(SubUserAttendanceQueryReq dto, PageQuery pageQuery) { + + if (dto.getClockDate() == null) { + throw new ServiceException("请选择月份"); + } + + + TableDataInfo sysUserVoTableDataInfo = userService.selectPageFbUserAttendanceList(dto, pageQuery); + List rows = sysUserVoTableDataInfo.getRows(); + List list1 = rows.stream().map(SysUserVo::getUserId).distinct().toList(); + + // 解析输入的年月字符串(拼接-01作为当月第一天) + LocalDate date = LocalDate.parse(dto.getClockDate() + "-01"); + + // 月份开始日期:当月1日 + LocalDate startDate = date.with(TemporalAdjusters.firstDayOfMonth()); + + // 月份结束日期:当月最后一天 + LocalDate endDate = date.with(TemporalAdjusters.lastDayOfMonth()); + List list; + if (CollectionUtil.isEmpty(list1)) { + list = new ArrayList<>(); + }else { + list = list(Wrappers.lambdaQuery() + .in(BusAttendance::getUserId, list1) + .between(BusAttendance::getClockDate, startDate, endDate) + .orderByAsc(BusAttendance::getClockDate) + ); + } + + List list2 = new ArrayList<>(); + + for (SysUserVo sysUserVo : rows) { + SubUserAttendanceTotalVo vo = new SubUserAttendanceTotalVo(); + vo.setUserName(sysUserVo.getUserName()); + vo.setContractorId(sysUserVo.getContractorId()); + vo.setContractorName(sysUserVo.getContractorName()); + List userList = list.stream().filter(attendance -> attendance.getUserId().equals(sysUserVo.getUserId())).toList(); + + //出勤天数 + long count = userList.stream().filter(attendance -> ATTENDANCE_LIST.contains(attendance.getClockStatus())) + .map(BusAttendance::getClockDate).distinct().count(); + vo.setAttendanceDays(Math.toIntExact(count)); + + //迟到次数 + long lateCount = userList.stream().filter(attendance -> attendance.getClockStatus().equals(LATE.getValue())).count(); + vo.setLateDays(Math.toIntExact(lateCount)); + + //早退次数 + long leaveEarlyCount = userList.stream().filter(attendance -> attendance.getClockStatus().equals(LEAVEEARLY.getValue())).count(); + vo.setLeaveEarlyDays(Math.toIntExact(leaveEarlyCount)); + + //缺卡次数 + long unClockCount = userList.stream().filter(attendance -> attendance.getClockStatus().equals(UNCLOCK.getValue())).count(); + vo.setUnClockDays(Math.toIntExact(unClockCount)); + + list2.add(vo); + } + + return new TableDataInfo<>(list2, sysUserVoTableDataInfo.getTotal()); + } + + @Override + public TableDataInfo getSubTodayAttendanceUser(SubTodayUserDto dto, PageQuery pageQuery) { + LocalDate date = dto.getDate(); + if (date == null) { + date = LocalDate.now(); + } + + if ("1".equals(dto.getType())) { + List list = list(Wrappers.lambdaQuery() + .eq(BusAttendance::getClockDate, date) + .eq(BusAttendance::getProjectId, dto.getProjectId()) + .in(BusAttendance::getClockStatus, ATTENDANCE_LIST) + ); + List list1 = list.stream().map(BusAttendance::getUserId).distinct().toList(); + + if (CollectionUtil.isEmpty(list1)) { + return TableDataInfo.build(); + } + dto.setUserIds(list1); + } else if ("2".equals(dto.getType())) { + List list = list(Wrappers.lambdaQuery() + .eq(BusAttendance::getClockDate, date) + .eq(BusAttendance::getProjectId, dto.getProjectId()) + .in(BusAttendance::getClockStatus, ATTENDANCE_LIST) + ); + List list1 = list.stream().map(BusAttendance::getUserId).distinct().toList(); + if (date.isEqual(LocalDate.now())) { + String todayStr = date.format(DateTimeFormatter.ISO_LOCAL_DATE); + List list2 = leaveService.list(Wrappers.lambdaQuery() + .eq(BusLeave::getProjectId, dto.getProjectId()) + // 关键:给日期字符串加单引号,避免 SQL 语法错误 + .apply("DATE(start_time) <= {0}", todayStr) + .apply("DATE(end_time) >= {0}", todayStr)); + + List list11 = list2.stream().map(BusLeave::getUserId).distinct().toList(); + ArrayList longs = new ArrayList<>(); + longs.addAll(list1); + longs.addAll(list11); + dto.setUserIds(longs); + dto.setIsToday(true); + } else { + List unlocks = list(Wrappers.lambdaQuery() + .eq(BusAttendance::getClockDate, date) + .eq(BusAttendance::getProjectId, dto.getProjectId()) + .eq(BusAttendance::getClockStatus, BusAttendanceClockStatusEnum.UNCLOCK.getValue()) + ); + List list11 = new ArrayList<>(unlocks.stream().map(BusAttendance::getUserId).distinct().toList()); + list11.removeAll(list1); + dto.setUserIds(list11); + dto.setIsToday(false); + if (CollectionUtil.isEmpty(list11)) { + return TableDataInfo.build(); + } + } + + } else if ("3".equals(dto.getType())) { + String todayStr = date.format(DateTimeFormatter.ISO_LOCAL_DATE); + List list2 = leaveService.list(Wrappers.lambdaQuery() + .eq(BusLeave::getProjectId, dto.getProjectId()) + // 关键:给日期字符串加单引号,避免 SQL 语法错误 + .apply("DATE(start_time) <= {0}", todayStr) + .apply("DATE(end_time) >= {0}", todayStr)); + + List list11 = list2.stream().map(BusLeave::getUserId).distinct().toList(); + if (CollectionUtil.isEmpty(list11)) { + return TableDataInfo.build(); + } + dto.setUserIds(list11); + } + TableDataInfo sysUserVoTableDataInfo = userService.todayUserList(dto, pageQuery); + + List list = new ArrayList<>(); + + for (SysUserVo sysUserVo : sysUserVoTableDataInfo.getRows()) { + SubAttendanceTodayUserVo subAttendanceTodayUserVo = new SubAttendanceTodayUserVo(); + subAttendanceTodayUserVo.setUserId(sysUserVo.getUserId()); + subAttendanceTodayUserVo.setUserName(sysUserVo.getUserName()); + subAttendanceTodayUserVo.setContractorId(sysUserVo.getContractorId()); + subAttendanceTodayUserVo.setContractorName(sysUserVo.getContractorName()); + list.add(subAttendanceTodayUserVo); + } + return new TableDataInfo<>(list, sysUserVoTableDataInfo.getTotal()); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java index f3e716dd..207d9245 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java @@ -2,6 +2,12 @@ package org.dromara.system.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.project.domain.dto.attendance.SubTodayUserDto; +import org.dromara.project.domain.dto.attendance.SubTwoWeekDto; +import org.dromara.project.domain.dto.attendance.SubUserAttendanceQueryReq; +import org.dromara.project.domain.dto.attendance.TodayUserDto; +import org.dromara.project.domain.vo.attendance.AttendanceTodayUserVo; +import org.dromara.project.domain.vo.attendance.SubUserAttendanceTotalVo; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.dto.FbUserListDto; @@ -286,4 +292,10 @@ public interface ISysUserService { Boolean deletion(); Boolean passwordCompare(String password); + + List getUserListBySubDto(SubTwoWeekDto dto); + + TableDataInfo selectPageFbUserAttendanceList(SubUserAttendanceQueryReq dto, PageQuery pageQuery); + + TableDataInfo todayUserList(SubTodayUserDto dto, PageQuery pageQuery); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 96c24343..81f0174a 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -40,6 +40,11 @@ import org.dromara.design.service.IDesUserService; import org.dromara.design.service.IDesVolumeCatalogService; import org.dromara.design.service.IDesVolumeFileService; import org.dromara.project.domain.BusUserProjectRelevancy; +import org.dromara.project.domain.dto.attendance.SubTodayUserDto; +import org.dromara.project.domain.dto.attendance.SubTwoWeekDto; +import org.dromara.project.domain.dto.attendance.SubUserAttendanceQueryReq; +import org.dromara.project.domain.dto.attendance.TodayUserDto; +import org.dromara.project.domain.vo.attendance.SubUserAttendanceTotalVo; import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo; import org.dromara.project.service.IBusProjectTeamService; import org.dromara.project.service.IBusUserProjectRelevancyService; @@ -1419,4 +1424,89 @@ public class SysUserServiceImpl implements ISysUserService, UserService { List longs = desUserService.selectbySpecialtyAndType(specialty, type,projectId); return longs.stream().map(String::valueOf).toList(); } + + + @Override + public List getUserListBySubDto(SubTwoWeekDto dto) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + wrapper.eq(SysUser::getAppUserType, "2"); + wrapper.like(StringUtils.isNotBlank(dto.getUserName()),SysUser::getUserName, dto.getUserName()); + wrapper.like(dto.getContractorId()!=null,SysUser::getContractorId, dto.getContractorId()); + wrapper.exists("SELECT 1 FROM bus_user_project_relevancy " + + "WHERE bus_user_project_relevancy.user_id = sys_user.user_id " + + "AND project_id = {0}", dto.getProjectId()); + + return baseMapper.selectList(wrapper); + } + + @Override + public TableDataInfo selectPageFbUserAttendanceList(SubUserAttendanceQueryReq dto, PageQuery pageQuery){ + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + wrapper.eq(SysUser::getAppUserType, "2"); + wrapper.eq(dto.getContractorId()!=null,SysUser::getContractorId, dto.getContractorId()); + wrapper.like(StringUtils.isNotBlank(dto.getUserName()),SysUser::getUserName, dto.getUserName()); + wrapper.exists("SELECT 1 FROM bus_user_project_relevancy " + + "WHERE bus_user_project_relevancy.user_id = u.user_id " + + "AND project_id = {0}", dto.getProjectId()); + Page page = baseMapper.selectPageUserList(pageQuery.build(), wrapper); + List userVoList = page.getRecords(); + + if (CollUtil.isNotEmpty(userVoList)) { + + List list1 = userVoList.stream().map(SysUserVo::getContractorId).toList(); + List subContractors = contractorService.listByIds(list1); + Map collect = subContractors.stream().collect(Collectors.toMap(SubContractor::getId, SubContractor::getName)); + + userVoList.forEach(userVo -> { + Long contractorId = userVo.getContractorId(); + userVo.setContractorName(collect.get(contractorId)); + }); + page.setRecords(userVoList); + } + return TableDataInfo.build(page); + } + + @Override + public TableDataInfo todayUserList(SubTodayUserDto dto, PageQuery pageQuery) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + wrapper.eq(SysUser::getAppUserType, "2"); + wrapper.eq(dto.getContractorId()!=null,SysUser::getContractorId, dto.getContractorId()); + wrapper.like(StringUtils.isNotBlank(dto.getUserName()),SysUser::getUserName, dto.getUserName()); + wrapper.exists("SELECT 1 FROM bus_user_project_relevancy " + + "WHERE bus_user_project_relevancy.user_id = u.user_id " + + "AND project_id = {0}", dto.getProjectId()); + + if("1".equals(dto.getType())){ + wrapper.in(SysUser::getUserId, dto.getUserIds()); + }else if("2".equals(dto.getType())){ + if(dto.getIsToday()){ + wrapper.notIn(CollectionUtil.isNotEmpty(dto.getUserIds()),SysUser::getUserId, dto.getUserIds()); + }else { + wrapper.in(SysUser::getUserId, dto.getUserIds()); + } + }else{ + wrapper.in(SysUser::getUserId, dto.getUserIds()); + } + + Page page = baseMapper.selectPageUserList(pageQuery.build(), wrapper); + List userVoList = page.getRecords(); + + if (CollUtil.isNotEmpty(userVoList)) { + + List list1 = userVoList.stream().map(SysUserVo::getContractorId).toList(); + List subContractors = contractorService.listByIds(list1); + Map collect = subContractors.stream().collect(Collectors.toMap(SubContractor::getId, SubContractor::getName)); + + userVoList.forEach(userVo -> { + Long contractorId = userVo.getContractorId(); + userVo.setContractorName(collect.get(contractorId)); + }); + page.setRecords(userVoList); + } + return TableDataInfo.build(page); + } }