This commit is contained in:
zt
2025-03-06 16:22:37 +08:00
parent 4570788d5e
commit c286edf99f
18 changed files with 208 additions and 163 deletions

View File

@ -6,6 +6,7 @@ import com.ruoyi.bgt.domain.dto.BgtAttendanceDayDTO;
import com.ruoyi.bgt.domain.dto.BgtAttendanceDetailDTO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceDetailVO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceVO;
import com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO;
import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService;
import com.ruoyi.common.core.domain.AjaxResult;
@ -20,6 +21,8 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(value = "App包工头考勤控制器", tags = {"App包工头考勤管理"})
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
@ -31,22 +34,29 @@ public class AppBgtAttendanceController {
private final IBgtProjectRecruitApplyService iBgtProjectRecruitApplyService;
@ApiOperation("App包工头总体考勤情况")
@ApiOperation("App包工头总体考勤情况-统计")
@GetMapping("attendance")
public AjaxResult<BgtAttendanceVO> attendanceDetail(@Validated BgtAttendanceDTO dto) {
return AjaxResult.success(attendanceService.attendanceDetail(dto));
}
@ApiOperation("App包工头总体考勤情况-柱状图")
@GetMapping("attendanceList")
public AjaxResult<List<BgtDayAttendanceCountVO>> attendanceList(@Validated BgtAttendanceDTO dto) {
return AjaxResult.success(attendanceService.attendanceList(dto));
}
@ApiOperation("App包工头总体考勤情况-人员出勤情况")
@GetMapping("/todayAttendanceList")
public TableDataInfo<BgtProjectRecruitApplyVO> todayAttendanceList(@Validated BgtAttendanceDayDTO req) {
return iBgtProjectRecruitApplyService.dayAttendanceList(req);
}
@ApiOperation("App包工头考勤统计详情")
@GetMapping("attendanceDetail")
public AjaxResult<BgtAttendanceDetailVO> attendanceDetail(@Validated BgtAttendanceDetailDTO dto) {
return AjaxResult.success(attendanceService.bgtAttendanceDetail(dto));
}
@ApiOperation("总体考勤情况-人员出勤情况")
@GetMapping("/todayAttendanceList")
public TableDataInfo<BgtProjectRecruitApplyVO> todayAttendanceList(@Validated BgtAttendanceDayDTO req) {
return iBgtProjectRecruitApplyService.dayAttendanceList(req);
}
}

View File

@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
@Data
@ -17,6 +18,7 @@ import java.time.LocalDate;
public class BgtAttendanceDTO {
@ApiModelProperty("任务ID")
@NotNull(message = "任务ID不能为空")
private Long taskId;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")

View File

@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
@Data
@ -27,9 +28,10 @@ public class BgtAttendanceDayDTO {
@ApiModelProperty("日期")
private LocalDate date;
@ApiModelProperty("考勤类型1出勤 2缺勤 3迟到")
@ApiModelProperty("考勤类型1正常 2异常 3请假")
private Integer attendanceType;
@ApiModelProperty("任务ID")
@NotNull(message = "任务ID不能为空")
private Long taskId;
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.bgt.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -16,6 +17,7 @@ import java.util.List;
public class BgtAttendanceDetailVO {
@ApiModelProperty("务工者Id")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long userId;
@ApiModelProperty("姓名")

View File

@ -1,5 +1,6 @@
package com.ruoyi.bgt.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -25,6 +26,7 @@ public class BgtDailyClockDetailVO {
private String recruitName;
/** 人员ID */
@ApiModelProperty("人员ID")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long userId;
@ApiModelProperty("头像地址")

View File

@ -0,0 +1,33 @@
package com.ruoyi.bgt.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.time.LocalDate;
/**
* 考勤打卡对象 wgz_attendance
*
* @author ruoyi
* @date 2025-02-20
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ApiModel("务工者每天考勤打卡统计对象")
public class BgtDayAttendanceCountVO {
@ApiModelProperty("到岗人数")
private Integer reportToDutyNum;
@ApiModelProperty("日期")
private LocalDate date;
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.bgt.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -30,6 +31,7 @@ public class BgtMessageVO implements Serializable {
private Long tableId;
@ApiModelProperty("发送人")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long senderId;
@ApiModelProperty("标题")

View File

@ -90,6 +90,7 @@ public class BgtProjectRecruitDetailVO implements Serializable {
private String typeOfWork;
@ApiModelProperty("创建者ID")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long userId;
@ApiModelProperty("发布时间")

View File

@ -28,7 +28,7 @@ public interface BgtProjectRecruitApplyMapper extends BaseMapperPlus<BgtProjectR
List<BgtProjectRecruitApplyVO> appQueryList(@Param("dto") BgtProjectRecruitApplyQueryDTO dto);
Page<BgtProjectRecruitApplyVO> dayAttendanceList(@Param("page")Page<BgtAttendanceDayDTO> queryDTOPage,@Param("dto") BgtAttendanceDayDTO dto);
// Page<BgtProjectRecruitApplyVO> dayAttendanceList(@Param("page")Page<BgtAttendanceDayDTO> queryDTOPage,@Param("dto") BgtAttendanceDayDTO dto);
Page<BgtProjectRecruitApplyVO> todayAttendanceList(@Param("page")Page<BgtAttendanceDayDTO> queryDTOPage,@Param("dto") BgtAttendanceDayDTO dto);
// 获取指定项目下的所有成员(分页)

View File

@ -47,7 +47,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
@ -326,20 +325,8 @@ public class BgtProjectRecruitApplyServiceImpl extends ServicePlusImpl<BgtProjec
Page<BgtAttendanceDayDTO> queryDTOPage = new Page<>();
queryDTOPage.setCurrent(dto.getPageNum());
queryDTOPage.setSize(dto.getPageSize());
// 获取当前时间
LocalTime currentTime = LocalTime.now();
// 定义目标时间12:10 12点才会录入当天所有人的考勤数据
LocalTime targetTime = LocalTime.of(12, 10);
// 判断当前时间是否在12:10之后
Page<BgtProjectRecruitApplyVO> queryVOPage;
if (currentTime.isAfter(targetTime)) {
queryVOPage = baseMapper.dayAttendanceList(queryDTOPage, dto);
} else {
queryVOPage = baseMapper.todayAttendanceList(queryDTOPage, dto);
}
Page<BgtProjectRecruitApplyVO> queryVOPage = baseMapper.todayAttendanceList(queryDTOPage, dto);
return PageUtils.buildDataInfo(queryVOPage);
}
@Override

View File

@ -2,6 +2,7 @@ package com.ruoyi.common.util;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO;
import java.math.BigDecimal;
import java.math.RoundingMode;
@ -11,29 +12,29 @@ import java.util.*;
public class DataUtil {
public static List<BgtAttendanceCountVO> fillMissingDates(List<BgtAttendanceCountVO> countVOS, LocalDate startDate, LocalDate endDate) {
public static List<BgtDayAttendanceCountVO> fillMissingDates(List<BgtDayAttendanceCountVO> countVOS, LocalDate startDate, LocalDate endDate) {
// 使用 HashSet 存储已有的日期,方便快速查找
Set<LocalDate> existingDates = new HashSet<>();
for (BgtAttendanceCountVO vo : countVOS) {
for (BgtDayAttendanceCountVO vo : countVOS) {
existingDates.add(vo.getDate());
}
// 创建一个新的列表,用于存储补充后的结果
List<BgtAttendanceCountVO> filledList = new ArrayList<>(countVOS);
List<BgtDayAttendanceCountVO> filledList = new ArrayList<>(countVOS);
// 遍历日期范围,补充缺失的日期
LocalDate currentDate = startDate;
while (!currentDate.isAfter(endDate)) {
if (!existingDates.contains(currentDate)) {
// 如果当前日期不在已有日期集合中,创建一个新的 BgtAttendanceCountVO 对象并添加到结果列表中
filledList.add(new BgtAttendanceCountVO(0,0,currentDate,0,0,0));
filledList.add(new BgtDayAttendanceCountVO(0,currentDate));
}
// 日期递增一天
currentDate = currentDate.plusDays(1);
}
// 对结果列表按日期排序
filledList.sort(Comparator.comparing(BgtAttendanceCountVO::getDate));
filledList.sort(Comparator.comparing(BgtDayAttendanceCountVO::getDate));
return filledList;
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.fbs.domain.vo;
import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -27,7 +28,7 @@ public class AppTaskDetailAttendanceVO {
private Integer reportToDutyRate= 0;
@ApiModelProperty("考勤列表")
List<BgtAttendanceCountVO> countVOS;
List<BgtDayAttendanceCountVO> countVOS;

View File

@ -10,7 +10,7 @@ import com.ruoyi.bgt.bo.BgtProjectRecruitQueryBo;
import com.ruoyi.bgt.domain.BgtProjectRecruit;
import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO;
import com.ruoyi.bgt.domain.dto.BgtWageApplicationQueryDTO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO;
import com.ruoyi.bgt.domain.vo.BgtWageApplicationListVO;
import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService;
@ -209,19 +209,18 @@ public class FbsProjectTaskServiceImpl extends ServicePlusImpl<FbsProjectTaskMap
if (taskBeginTime!=null &&taskBeginTime.isAfter(startTime)){
startTime = taskBeginTime;
}
List<BgtAttendanceCountVO>
countVOS = attendanceService.countByTaskId(id, startTime, date);
if(CollectionUtil.isNotEmpty(countVOS)){
BgtAttendanceCountVO vo = countVOS.get(0);
appTaskDetailVO.setCountVOS(DataUtil.fillMissingDates(countVOS, startTime, date));
appTaskDetailVO.setTotalNum(vo.getTotalNum());
appTaskDetailVO.setReportToDutyNum(vo.getReportToDutyNum());
if(vo.getTotalNum()!=0){
int rate = new BigDecimal(vo.getReportToDutyNum()).divide(new BigDecimal(vo.getTotalNum()), 2, RoundingMode.HALF_UP)
.multiply(new BigDecimal(100)).intValue();
appTaskDetailVO.setReportToDutyRate(rate);
}
List<BgtDayAttendanceCountVO> countVOS = attendanceService.countDayByTaskId(id, startTime, date);
// 补充缺失的天数
List<BgtDayAttendanceCountVO> bgtDayAttendanceCountVOS = DataUtil.fillMissingDates(countVOS, startTime, date);
//查询当天的总人数
Integer totalNum = attendanceService.dayTotalNum(id, date);
appTaskDetailVO.setTotalNum(totalNum);
//计算到岗率
if(totalNum!=0){
BgtDayAttendanceCountVO bgtDayAttendanceCountVO = bgtDayAttendanceCountVOS.get(bgtDayAttendanceCountVOS.size() - 1);
int rate = new BigDecimal(bgtDayAttendanceCountVO.getReportToDutyNum()).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP)
.multiply(new BigDecimal(100)).intValue();
appTaskDetailVO.setReportToDutyRate(rate);
}
return appTaskDetailVO;
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.wgz.mapper;
import com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO;
import com.ruoyi.wgz.domain.WgzAttendance;
import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache;
@ -24,6 +25,9 @@ public interface WgzAttendanceMapper extends BaseMapperPlus<WgzAttendance> {
List<BgtAttendanceCountVO> countByTaskId(@Param("taskId") Long taskId, @Param("beginDate")LocalDate beginDate
, @Param("endDate")LocalDate endDate);
List<BgtDayAttendanceCountVO> countDayByTaskId(@Param("taskId") Long taskId, @Param("beginDate")LocalDate beginDate
, @Param("endDate")LocalDate endDate);
Integer dayTotalNum(@Param("taskId") Long taskId, @Param("date")LocalDate date);
Integer monthTotalNum(@Param("taskId") Long taskId, @Param("beginDate")LocalDate beginDate

View File

@ -5,6 +5,7 @@ import com.ruoyi.bgt.domain.dto.BgtAttendanceDetailDTO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceDetailVO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceVO;
import com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO;
import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.wgz.bo.WgzAttendanceQueryBo;
@ -106,6 +107,11 @@ public interface IWgzAttendanceService extends IServicePlus<WgzAttendance> {
*/
List<BgtAttendanceCountVO> countByTaskId(Long taskId, LocalDate beginDate, LocalDate endDate);
/**
* 统计任务每天打卡情况
*/
List<BgtDayAttendanceCountVO> countDayByTaskId(Long taskId, LocalDate beginDate, LocalDate endDate);
/**
* 统计某天应打卡人数
*/
@ -113,10 +119,12 @@ public interface IWgzAttendanceService extends IServicePlus<WgzAttendance> {
Integer monthTotalNum(Long taskId,LocalDate beginDate, LocalDate endDate);
/**
* 总体考勤情况
* 总体考勤情况-统计
*/
BgtAttendanceVO attendanceDetail(BgtAttendanceDTO dto);
List<BgtDayAttendanceCountVO> attendanceList(BgtAttendanceDTO dto);
/**
* 考勤详情,查询指定用户指定项目的指定天数考勤情况统计如若用户输入20但实际只有2天出勤
* 如若num为0,那么表示查询所有天数的考勤情况统计;

View File

@ -10,14 +10,12 @@ import com.ruoyi.bgt.domain.BgtProjectRecruit;
import com.ruoyi.bgt.domain.BgtProjectRecruitApply;
import com.ruoyi.bgt.domain.dto.BgtAttendanceDTO;
import com.ruoyi.bgt.domain.dto.BgtAttendanceDetailDTO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceDetailVO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceVO;
import com.ruoyi.bgt.domain.vo.WgzAttendanceRecordVO;
import com.ruoyi.bgt.domain.vo.*;
import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService;
import com.ruoyi.bgt.service.IBgtProjectRecruitService;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.util.DataUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
@ -42,8 +40,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
@ -402,6 +398,11 @@ public class WgzAttendanceServiceImpl extends ServicePlusImpl<WgzAttendanceMappe
return baseMapper.countByTaskId(taskId, beginDate, endDate);
}
@Override
public List<BgtDayAttendanceCountVO> countDayByTaskId(Long taskId, LocalDate beginDate, LocalDate endDate){
return baseMapper.countDayByTaskId(taskId, beginDate, endDate);
}
@Override
public Integer dayTotalNum(Long taskId,LocalDate date){
return baseMapper.dayTotalNum(taskId,date);
@ -414,110 +415,83 @@ public class WgzAttendanceServiceImpl extends ServicePlusImpl<WgzAttendanceMappe
@Override
public BgtAttendanceVO attendanceDetail(BgtAttendanceDTO dto) {
BgtAttendanceVO bgtAttendanceVO = new BgtAttendanceVO();
FbsProjectTask task = taskService.getById(dto.getTaskId());
validTaskTime(task, dto.getDate());
bgtAttendanceVO.setTaskId(task.getId());
bgtAttendanceVO.setTaskName(task.getTaskName());
LocalDate date = dto.getDate();
LocalDate startData = null;
LocalDate endData = null;
LocalDate now = LocalDate.now();
//当天总人数
Integer totalNum = dayTotalNum(task.getId(), date);
bgtAttendanceVO.setTotalNum(totalNum);
if (dto.getDateType().equals(DateUtils.DAY)) {
// 获取本月开始日期
startData = date.with(TemporalAdjusters.firstDayOfMonth());
endData = date;
List<BgtAttendanceCountVO> countVOS = countByTaskId(dto.getTaskId(), startData, endData);
List<BgtAttendanceCountVO> bgtAttendanceCountVOS = DataUtil.fillMissingDates(countVOS, startData, endData);
// 因为当天可能还没有生成所有人的考勤数据,所以应到的总人数需要单独查询
// 判断当天是否在开始日期和结束日期之间(包含开始和结束日期)
boolean isBetween = (now.isAfter(startData) || now.isEqual(startData))
&& (now.isBefore(endData) || now.isEqual(endData));
if (isBetween) {
Integer i = dayTotalNum(task.getId(), now);
BgtAttendanceCountVO countVO = bgtAttendanceCountVOS.stream()
.filter(vo -> vo.getDate().isEqual(now))
.findFirst().orElse(null);
countVO.setTotalNum(i);
}
bgtAttendanceVO.setCountVOs(bgtAttendanceCountVOS);
// 找出查询日期的考勤数据
BgtAttendanceCountVO countVO = bgtAttendanceCountVOS.stream()
.filter(vo -> vo.getDate().isEqual(date))
.findFirst().orElse(null);
if (countVO != null) {
bgtAttendanceVO.setReportToDutyNum(countVO.getReportToDutyNum());
bgtAttendanceVO.setTotalNum(countVO.getTotalNum());
bgtAttendanceVO.setAbsenceDutyNum(countVO.getTotalNum() - countVO.getReportToDutyNum());
if (bgtAttendanceVO.getTotalNum() != 0) {
int rate = new BigDecimal(bgtAttendanceVO.getReportToDutyNum()).divide(new BigDecimal(bgtAttendanceVO.getTotalNum()), 2, RoundingMode.HALF_UP)
.multiply(new BigDecimal(100)).intValue();
bgtAttendanceVO.setReportToDutyRate(rate);
}
}
} else if (dto.getDateType().equals(DateUtils.MONTH)) {
// 获取本年开始日期
startData = date.with(TemporalAdjusters.firstDayOfYear());
endData = date.with(TemporalAdjusters.lastDayOfMonth());
if(endData.isAfter(now)){
endData= now;
}
List<BgtAttendanceCountVO> countVOS = countByTaskId(dto.getTaskId(), startData, endData);
// 因为当天可能还没有生成所有人的考勤数据,所以应到的总人数需要单独查询
// 判断当天是否在开始日期和结束日期之间(包含开始和结束日期)
boolean isBetween = (now.isAfter(startData) || now.isEqual(startData))
&& (now.isBefore(endData) || now.isEqual(endData));
if (isBetween) {
Integer i = dayTotalNum(task.getId(), now);
BgtAttendanceCountVO countVO = countVOS.stream()
.filter(vo -> vo.getDate().isEqual(now))
.findFirst().orElse(null);
if (countVO != null) {
countVO.setTotalNum(i);
}else {
BgtAttendanceCountVO bgtAttendanceCountVO = new BgtAttendanceCountVO(0, i, now, 0, 0, 0);
countVOS.add(bgtAttendanceCountVO);
}
}
List<BgtAttendanceCountVO> bgtAttendanceCountVOS = DataUtil.statisticsByMonth(countVOS, startData, endData);
bgtAttendanceVO.setCountVOs(bgtAttendanceCountVOS);
BgtAttendanceCountVO countVO = bgtAttendanceCountVOS.stream()
.filter(vo -> YearMonth.from(vo.getDate()).equals(YearMonth.from(date)))
.findFirst().orElse(null);
if (countVO != null) {
bgtAttendanceVO.setReportToDutyNum(countVO.getReportToDutyNum());
bgtAttendanceVO.setTotalNum(countVO.getTotalNum());
bgtAttendanceVO.setAbsenceDutyNum(countVO.getAbsenceDutyNum());
int rate = new BigDecimal(countVO.getRateSum()).divide(new BigDecimal(countVO.getRateDay()), 2, RoundingMode.HALF_UP).intValue();
bgtAttendanceVO.setReportToDutyRate(rate);
}
//设置本月的总人数
bgtAttendanceVO.setTotalNum(monthTotalNum(task.getId(), date.with(TemporalAdjusters.firstDayOfMonth()), endData));
//今日到岗人数
List<BgtDayAttendanceCountVO> countVOS = countDayByTaskId(dto.getTaskId(), date, date);
if(CollectionUtil.isNotEmpty(countVOS)){
bgtAttendanceVO.setReportToDutyNum(countVOS.get(0).getReportToDutyNum());
}
//缺勤人数
bgtAttendanceVO.setAbsenceDutyNum(totalNum-bgtAttendanceVO.getReportToDutyNum());
//任务拥有的所有招工
List<BgtProjectRecruit> bgtProjectRecruits = iBgtProjectRecruitService.getBaseMapper().selectList(Wrappers.<BgtProjectRecruit>lambdaQuery()
.eq(BgtProjectRecruit::getTaskId, dto.getTaskId()));
List<Long> recruitIds = bgtProjectRecruits.stream().map(BgtProjectRecruit::getId).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(recruitIds)) {
//请假人数
Integer leaveNum = baseMapper.selectCount(Wrappers.<WgzAttendance>lambdaQuery().isNotNull(WgzAttendance::getLeaveMarkId)
.in(WgzAttendance::getRecruitId, recruitIds).eq(WgzAttendance::getDate, date));
bgtAttendanceVO.setLeaveNum(leaveNum);
//迟到人数
Integer lateNum = baseMapper.selectCount(Wrappers.<WgzAttendance>lambdaQuery().eq(WgzAttendance::getLate, 1)
.eq(WgzAttendance::getRecruitId, recruitIds).eq(WgzAttendance::getDate, date));
bgtAttendanceVO.setLateNum(lateNum);
//早退人数
Integer earlyLeaveNum = baseMapper.selectCount(Wrappers.<WgzAttendance>lambdaQuery().eq(WgzAttendance::getEarlyLeave, 1)
.in(WgzAttendance::getRecruitId, recruitIds).eq(WgzAttendance::getDate, date));
bgtAttendanceVO.setEarlyLeaveNum(earlyLeaveNum);
}
getLateAndLeave(bgtAttendanceVO, startData, endData);
return bgtAttendanceVO;
}
public void getLateAndLeave(BgtAttendanceVO vo, LocalDate startDate, LocalDate endDate) {
List<BgtProjectRecruit> bgtProjectRecruits = iBgtProjectRecruitService.getBaseMapper().selectList(Wrappers.<BgtProjectRecruit>lambdaQuery()
.eq(BgtProjectRecruit::getTaskId, vo.getTaskId()));
List<Long> recruitIds = bgtProjectRecruits.stream().map(BgtProjectRecruit::getId).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(recruitIds)) {
Integer late = baseMapper.selectCount(Wrappers.<WgzAttendance>lambdaQuery().eq(WgzAttendance::getLate, 1)
.eq(WgzAttendance::getRecruitId, recruitIds).between(WgzAttendance::getDate, startDate, endDate));
Integer leave = baseMapper.selectCount(Wrappers.<WgzAttendance>lambdaQuery().isNotNull(WgzAttendance::getLeaveMarkId)
.in(WgzAttendance::getRecruitId, recruitIds).between(WgzAttendance::getDate, startDate, endDate));
vo.setLateNum(late);
vo.setLeaveNum(leave);
@Override
public List<BgtDayAttendanceCountVO> attendanceList(BgtAttendanceDTO dto) {
FbsProjectTask task = taskService.getById(dto.getTaskId());
validTaskTime(task, dto.getDate());
LocalDate taskBeginTime = DateUtils.str2Localdate(task.getTaskBeginTime(), DateUtils.YYYY_MM_DD);
LocalDate date = dto.getDate();
LocalDate startTime = date.minusDays(7);
if (taskBeginTime!=null &&taskBeginTime.isAfter(startTime)){
startTime = taskBeginTime;
}
return countDayByTaskId(dto.getTaskId(), startTime, date);
}
public void validTaskTime(FbsProjectTask task,LocalDate date){
LocalDate taskBeginTime = DateUtils.str2Localdate(task.getTaskBeginTime(), DateUtils.YYYY_MM_DD);
LocalDate taskEndTime = DateUtils.str2Localdate(task.getTaskEndTime(), DateUtils.YYYY_MM_DD);
if(taskEndTime == null){
taskEndTime = LocalDate.now();
}
if(date.isBefore(taskBeginTime) || date.isAfter(taskEndTime)){
throw new BaseException("当前日期不在任务时间范围内");
}
}
// @Override
// @Override
// public WgzAttendance findByUserIdWait(Long appUserId, Long recruitId, String date) {
// LambdaQueryWrapper<WgzAttendance> qw = new LambdaQueryWrapper<>();
// qw.eq(WgzAttendance::getRecruitId,recruitId);

View File

@ -98,30 +98,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="todayAttendanceList" resultType="com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO">
SELECT bpra.id,
bpra.entry_time,
wu.user_id,
wu.phone,
wu.score,
wu.avatar_name,
wu.username,
wu.type_of_work,
bpr.recruit_name,
fpt.task_name,
CASE
WHEN wa.leave_mark_id IS NOT NULL THEN '请假'
WHEN wa.late = 1 THEN '迟到'
WHEN wa.early_leave = 1 THEN '早退'
WHEN wa.missed_in = 0 OR wa.missed_out = 0 THEN '出勤'
ELSE '缺勤'
END AS attendance_status
bpra.entry_time,
bpra.user_id,
wu.phone,
wu.score,
wu.avatar_name,
wu.username,
wu.type_of_work,
bpr.recruit_name,
fpt.task_name,
CASE
WHEN wa.leave_mark_id = 1 THEN '请假'
WHEN wa.late = 0 and wa.early_leave = 0 and wa.missed_in = 0 and wa.missed_out = 0 THEN '正常'
WHEN wa.late = 1 or wa.early_leave = 1 or wa.missed_in = 1 or wa.missed_out = 1 THEN '异常'
ELSE '异常'
END AS attendance_status
FROM bgt_project_recruit_apply bpra
LEFT JOIN wgz_user wu ON bpra.user_id = wu.user_id
LEFT JOIN wgz_attendance wa ON wa.user_id = wu.user_id AND wa.recruit_id = bpra.recruit_id AND wa.date = #{dto.date}
LEFT JOIN bgt_project_recruit bpr ON bpr.id = bpra.recruit_id
LEFT JOIN fbs_project_task fpt ON fpt.id = bpr.task_id
WHERE bpra.status = '5' and bpra.recruit_id IN (SELECT id
FROM bgt_project_recruit
WHERE task_id = #{dto.taskId})
LEFT JOIN bgt_project_recruit bpr ON bpr.id = bpra.recruit_id
LEFT JOIN fbs_project_task fpt ON fpt.id = bpr.task_id
LEFT JOIN wgz_user wu ON bpra.user_id = wu.user_id
LEFT JOIN wgz_attendance wa ON wa.user_id = wu.user_id AND wa.recruit_id = bpra.recruit_id AND wa.date = #{dto.date}
WHERE bpra.entry_time &lt;= #{dto.date} and ((bpra.leave_time is null and bpra.status = '5')or leave_time>=#{dto.date})
and bpra.recruit_id IN (SELECT id FROM bgt_project_recruit WHERE task_id = #{dto.taskId})
<if test="dto.attendanceType !=null and dto.attendanceType ==1 ">
and (wa.late = 0 and wa.early_leave = 0 and wa.missed_in = 0 and wa.missed_out = 0) and leave_mark_id is null
</if>
<if test="dto.attendanceType !=null and dto.attendanceType ==2 ">
(wa.late = 1 or wa.early_leave = 1 or wa.missed_in = 1 or wa.missed_out = 1) and leave_mark_id is null
</if>
<if test="dto.attendanceType !=null and dto.attendanceType ==3 ">
and wa.leave_mark_id = 1
</if>
</select>
<select id="underwayPage" resultType="com.ruoyi.wgz.bo.res.WgzAppUnderwayRes">

View File

@ -42,6 +42,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
group by date order by date
</select>
<select id="countDayByTaskId" resultType="com.ruoyi.bgt.domain.vo.BgtDayAttendanceCountVO">
select count(1) as reportToDutyNum,
date
from wgz_attendance
where date between #{beginDate} and #{endDate}
and (clock_in_time is not null or clock_out_time is not null)
and recruit_id in (select id from bgt_project_recruit where task_id = #{taskId} )
group by date order by date
</select>
<select id="dayTotalNum" resultType="Integer">
select count(1) from bgt_project_recruit_apply where entry_time &lt;= #{date} and ((leave_time is null and status = '5')or leave_time>=#{date})