From 0941197ca9fdc2b20d59b53f57c5eff19d4bec7f Mon Sep 17 00:00:00 2001 From: zt Date: Tue, 11 Nov 2025 16:41:55 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=83=E5=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ISubConstructionUserService.java | 8 ++ .../impl/SubConstructionUserServiceImpl.java | 51 +++++++++++- .../dromara/job/attendance/AttendanceJob.java | 44 ++++++++++ .../controller/BusAttendanceController.java | 8 ++ .../domain/dto/attendance/TodayUserDto.java | 43 ++++++++++ .../vo/attendance/AttendanceTodayUserVo.java | 27 ++++++ .../service/IBusAttendanceService.java | 6 ++ .../impl/BusAttendanceServiceImpl.java | 82 ++++++++++++++++++- 8 files changed, 263 insertions(+), 6 deletions(-) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/TodayUserDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/AttendanceTodayUserVo.java diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/ISubConstructionUserService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/ISubConstructionUserService.java index fe836c55..01a01a0b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/ISubConstructionUserService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/ISubConstructionUserService.java @@ -9,6 +9,11 @@ import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.contractor.domain.dto.constructionuser.*; import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo; import org.dromara.contractor.domain.vo.constructionuser.*; +import org.dromara.project.domain.bo.BusAttendanceBo; +import org.dromara.project.domain.dto.attendance.TodayUserDto; +import org.dromara.project.domain.dto.attendance.TwoWeekDto; +import org.dromara.project.domain.vo.BusAttendanceVo; +import org.dromara.project.domain.vo.attendance.AttendanceTodayUserVo; import org.dromara.system.domain.vo.SysOssVo; import org.springframework.web.multipart.MultipartFile; @@ -253,4 +258,7 @@ public interface ISubConstructionUserService extends IService todayUserList(TodayUserDto dto, PageQuery pageQuery); } 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 175decfa..343330c2 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 @@ -3,10 +3,7 @@ package org.dromara.contractor.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.DesensitizedUtil; -import cn.hutool.core.util.IdcardUtil; -import cn.hutool.core.util.PhoneUtil; -import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.*; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -49,9 +46,12 @@ import org.dromara.contractor.service.ISubConstructionUserFileService; import org.dromara.contractor.service.ISubConstructionUserService; import org.dromara.contractor.service.ISubContractorService; import org.dromara.project.domain.*; +import org.dromara.project.domain.dto.attendance.TodayUserDto; +import org.dromara.project.domain.dto.attendance.TwoWeekDto; import org.dromara.project.domain.enums.BusAttendanceClockStatusEnum; import org.dromara.project.domain.enums.BusAttendanceCommuterEnum; import org.dromara.project.domain.enums.BusConstructionUserAttendanceStatusEnum; +import org.dromara.project.domain.vo.attendance.AttendanceTodayUserVo; import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo; import org.dromara.project.service.*; import org.dromara.system.domain.SysUser; @@ -1586,4 +1586,47 @@ public class SubConstructionUserServiceImpl extends ServiceImpl todayUserList(TodayUserDto dto, PageQuery pageQuery) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + wrapper.eq(SubConstructionUser::getUserRole, "0") + .eq(SubConstructionUser::getProjectId, dto.getProjectId()) + .eq(dto.getTeamId() != null, SubConstructionUser::getTeamId, dto.getTeamId()) + .eq(StrUtil.isNotBlank(dto.getTypeOfWork()), SubConstructionUser::getTypeOfWork, dto.getTypeOfWork()) + .like(StrUtil.isNotBlank(dto.getUserName()), SubConstructionUser::getUserName, dto.getUserName()) + .isNotNull(SubConstructionUser::getTeamId); + if("1".equals(dto.getType())){ + wrapper.in(SubConstructionUser::getSysUserId, dto.getUserIds()); + }else if("2".equals(dto.getType())){ + if(dto.getIsToday()){ + wrapper.notIn(CollectionUtil.isNotEmpty(dto.getUserIds()),SubConstructionUser::getSysUserId, dto.getUserIds()); + }else { + wrapper.in(SubConstructionUser::getSysUserId, dto.getUserIds()); + } + + }else{ + wrapper.in(SubConstructionUser::getSysUserId, dto.getUserIds()); + } + + Page result = this.page(pageQuery.build(), wrapper); + + List records = result.getRecords(); + List list1 = records.stream().map(SubConstructionUser::getTeamId).toList(); + List busProjectTeams = projectTeamService.listByIds(list1); + Map teamMap = busProjectTeams.stream().collect(Collectors.toMap(BusProjectTeam::getId, BusProjectTeam::getTeamName)); + + ArrayList attendanceTodayUserVos = new ArrayList<>(); + for (SubConstructionUser constructionUser : records) { + AttendanceTodayUserVo attendanceTodayUserVo = new AttendanceTodayUserVo(); + attendanceTodayUserVo.setUserId(constructionUser.getSysUserId()); + attendanceTodayUserVo.setUserName(constructionUser.getUserName()); + attendanceTodayUserVo.setTypeOfWork(constructionUser.getTypeOfWork()); + attendanceTodayUserVo.setTeamName(teamMap.get(constructionUser.getTeamId())); + attendanceTodayUserVos.add(attendanceTodayUserVo); + } + + return new TableDataInfo(attendanceTodayUserVos, result.getTotal()); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJob.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJob.java index 98baffef..894e8ee3 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJob.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJob.java @@ -3,6 +3,10 @@ package org.dromara.job.attendance; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -337,6 +341,10 @@ public class AttendanceJob { if (!list.contains(String.valueOf(number))) { return true; } + //检查是否假期 https://timor.tech/api/holiday/info/2025-12-31 + String format = LocalDateTimeUtil.format(date, "yyyy-MM-dd"); + String s = HttpUtil.get("https://timor.tech/api/holiday/info/" + format); + return false; } @@ -364,4 +372,40 @@ public class AttendanceJob { return workWageByWorkType.getWage(); } + + + public static void main(String[] args) { + // 待查询的日期(格式:yyyy-MM-dd) + String format = "2025-10-01"; + + // 调用API获取结果 + String s = HttpUtil.get("https://timor.tech/api/holiday/info/" + format); + + // 解析JSON + JSONObject json = JSONUtil.parseObj(s); + + // 先判断服务是否正常(code=0) + if (json.getInt("code") == 0) { + // 获取type对象 + JSONObject typeObj = json.getJSONObject("type"); + if (typeObj != null) { + // 获取type字段的值 + int type = typeObj.getInt("type"); + + // 判断是否为节假日(2)或调休(3) + if (type == 2) { + System.out.println(format + " 是节假日:" + typeObj.getStr("name")); + } else if (type == 3) { + System.out.println(format + " 是调休:" + typeObj.getStr("name")); + } else { + System.out.println(format + " 不是节假日或调休(类型:" + type + ")"); + } + } else { + System.out.println("解析type字段失败"); + } + } else { + System.out.println("API调用失败,错误码:" + json.getInt("code")); + } + } + } 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 daf3be56..0db7f45f 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 @@ -134,6 +134,14 @@ public class BusAttendanceController extends BaseController { return R.ok(busAttendanceService.getTodayAttendanceData(dto)); } + /** + * 查询当天出勤人员 + */ + @GetMapping("/list/attendanceUser") + public TableDataInfo getTodayAttendanceUser(TodayUserDto dto, PageQuery pageQuery) { + return busAttendanceService.getTodayAttendanceUser(dto,pageQuery); + } + @PostMapping("/exportList") public void exportList(AttendanceExportDto dto, HttpServletResponse response) { busAttendanceService.getExportList(dto, response); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/TodayUserDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/TodayUserDto.java new file mode 100644 index 00000000..64e08641 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/dto/attendance/TodayUserDto.java @@ -0,0 +1,43 @@ +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 TodayUserDto { + + /** + * 人员姓名 + */ + private String userName; + + /** + * 班组id + */ + private Long teamId; + + /** + * 工种 + */ + private String typeOfWork; + + /** + * 项目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/vo/attendance/AttendanceTodayUserVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/AttendanceTodayUserVo.java new file mode 100644 index 00000000..497f50fb --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/attendance/AttendanceTodayUserVo.java @@ -0,0 +1,27 @@ +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 AttendanceTodayUserVo { + + private Long userId; + + private String userName; + + /** + * 工种(字典type_of_work) + */ + private String typeOfWork; + + @Translation(type = TransConstant.DICT_TYPE_TO_LABEL, mapper = "typeOfWork",other = "type_of_work") + private String typeOfWorkName; + + /** + * 班组名称 + */ + private String teamName; + +} 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 6fbd57d3..58b0f09d 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 @@ -185,6 +185,12 @@ public interface IBusAttendanceService extends IService{ */ BusAttendanceClockDateForTwoWeekVo getTodayAttendanceData(TwoWeekDto dto); + + /** + * 获取项目当天的出勤人员 + */ + TableDataInfo getTodayAttendanceUser(TodayUserDto 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 27daad4c..eec6acc4 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 @@ -1654,6 +1654,10 @@ public class BusAttendanceServiceImpl extends ServiceImpllambdaQuery() @@ -1703,7 +1707,7 @@ public class BusAttendanceServiceImpl extends ServiceImpllambdaQuery() .eq(BusLeave::getProjectId, dto.getProjectId()) .in(BusLeave::getUserId, allUserIds) - .eq(dto.getTeamId() != null, BusLeave::getTeamId, allUserIds) + .eq(dto.getTeamId() != null, BusLeave::getTeamId, dto.getTeamId()) // 关键:给日期字符串加单引号,避免 SQL 语法错误 .apply("DATE(start_time) <= {0}", todayStr) .apply("DATE(end_time) >= {0}", todayStr) @@ -1746,7 +1750,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl getTodayAttendanceUser(TodayUserDto 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()) + .eq(dto.getTeamId() != null, BusLeave::getTeamId, dto.getTeamId()) + // 关键:给日期字符串加单引号,避免 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()) + .eq(dto.getTeamId() != null, BusLeave::getTeamId, dto.getTeamId()) + // 关键:给日期字符串加单引号,避免 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); + } + return constructionUserService.todayUserList(dto, pageQuery); + } + @Override public void getExportList(AttendanceExportDto dto, HttpServletResponse response) { try (OutputStream outputStream = response.getOutputStream()) {