施工人员考勤列表、考勤记录相关接口
This commit is contained in:
@ -1,18 +0,0 @@
|
|||||||
package org.dromara.common.core.constant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用常量
|
|
||||||
*/
|
|
||||||
public interface CommonConstant {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 升序
|
|
||||||
*/
|
|
||||||
String SORT_ORDER_ASC = "ascend";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 降序
|
|
||||||
*/
|
|
||||||
String SORT_ORDER_DESC = " descend";
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,14 @@
|
|||||||
|
package org.dromara.common.core.constant;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 17:12
|
||||||
|
*/
|
||||||
|
public interface DateConstant {
|
||||||
|
|
||||||
|
// 匹配 "yyyy-MM",年四位,月 01~12
|
||||||
|
Pattern YEAR_MONTH_PATTERN = Pattern.compile("^\\d{4}-(0[1-9]|1[0-2])$");
|
||||||
|
|
||||||
|
}
|
@ -2,22 +2,18 @@ package org.dromara.project.controller;
|
|||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
import org.dromara.common.core.validate.AddGroup;
|
|
||||||
import org.dromara.common.core.validate.EditGroup;
|
|
||||||
import org.dromara.common.excel.utils.ExcelUtil;
|
import org.dromara.common.excel.utils.ExcelUtil;
|
||||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
|
||||||
import org.dromara.common.log.annotation.Log;
|
import org.dromara.common.log.annotation.Log;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceCreateReq;
|
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceQueryReq;
|
import org.dromara.project.domain.req.attendance.AttendanceQueryReq;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceUpdateReq;
|
import org.dromara.project.domain.req.attendance.AttendanceQueryTwoWeekReq;
|
||||||
|
import org.dromara.project.domain.resp.attendance.AttendanceClockDateForTwoWeekResp;
|
||||||
import org.dromara.project.domain.vo.BusAttendanceVo;
|
import org.dromara.project.domain.vo.BusAttendanceVo;
|
||||||
import org.dromara.project.service.IBusAttendanceService;
|
import org.dromara.project.service.IBusAttendanceService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -29,7 +25,7 @@ import java.util.List;
|
|||||||
* 考勤
|
* 考勤
|
||||||
*
|
*
|
||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-26
|
* @date 2025-04-07
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -48,6 +44,15 @@ public class BusAttendanceController extends BaseController {
|
|||||||
return busAttendanceService.queryPageList(req, pageQuery);
|
return busAttendanceService.queryPageList(req, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询近两周考勤列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("project:attendance:list")
|
||||||
|
@GetMapping("/list/clockDate/twoWeek")
|
||||||
|
public R<List<AttendanceClockDateForTwoWeekResp>> listClockDateForTwoWeek(AttendanceQueryTwoWeekReq req) {
|
||||||
|
return R.ok(busAttendanceService.listClockDateForTwoWeek(req));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出考勤列表
|
* 导出考勤列表
|
||||||
*/
|
*/
|
||||||
@ -71,38 +76,4 @@ public class BusAttendanceController extends BaseController {
|
|||||||
return R.ok(busAttendanceService.queryById(id));
|
return R.ok(busAttendanceService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增考勤
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("project:attendance:add")
|
|
||||||
@Log(title = "考勤", businessType = BusinessType.INSERT)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PostMapping()
|
|
||||||
public R<Long> add(@Validated(AddGroup.class) @RequestBody AttendanceCreateReq req) {
|
|
||||||
return R.ok(busAttendanceService.insertByBo(req));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改考勤
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("project:attendance:edit")
|
|
||||||
@Log(title = "考勤", businessType = BusinessType.UPDATE)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PutMapping()
|
|
||||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody AttendanceUpdateReq req) {
|
|
||||||
return toAjax(busAttendanceService.updateByBo(req));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除考勤
|
|
||||||
*
|
|
||||||
* @param ids 主键串
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("project:attendance:remove")
|
|
||||||
@Log(title = "考勤", businessType = BusinessType.DELETE)
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
|
||||||
@PathVariable Long[] ids) {
|
|
||||||
return toAjax(busAttendanceService.deleteWithValidByIds(List.of(ids), true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.project.domain.exportvo.BusConstructionUserExportVo;
|
import org.dromara.project.domain.exportvo.BusConstructionUserExportVo;
|
||||||
import org.dromara.project.domain.req.constructionuser.*;
|
import org.dromara.project.domain.req.constructionuser.*;
|
||||||
|
import org.dromara.project.domain.resp.constructionuser.ConstructionUserAttendanceMonthResp;
|
||||||
|
import org.dromara.project.domain.resp.constructionuser.ConstructionUserAttendanceTotalResp;
|
||||||
import org.dromara.project.domain.vo.BusConstructionUserVo;
|
import org.dromara.project.domain.vo.BusConstructionUserVo;
|
||||||
import org.dromara.project.service.IBusConstructionUserService;
|
import org.dromara.project.service.IBusConstructionUserService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -47,6 +49,25 @@ public class BusConstructionUserController extends BaseController {
|
|||||||
return busConstructionUserService.queryPageList(req, pageQuery);
|
return busConstructionUserService.queryPageList(req, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询每个施工人员总的考勤列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("project:attendance:list")
|
||||||
|
@GetMapping("/list/attendance/total")
|
||||||
|
public TableDataInfo<ConstructionUserAttendanceTotalResp> listAttendanceTotal(ConstructionUserAttendanceQueryReq req,
|
||||||
|
PageQuery pageQuery) {
|
||||||
|
return busConstructionUserService.queryPageAttendanceList(req, pageQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询施工人员月份考勤列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("project:constructionUser:list")
|
||||||
|
@GetMapping("/list/attendance/month")
|
||||||
|
public R<List<ConstructionUserAttendanceMonthResp>> listAttendanceMonth(ConstructionUserAttendanceMonthReq req) {
|
||||||
|
return R.ok(busConstructionUserService.queryAttendanceMonthList(req));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出施工人员列表
|
* 导出施工人员列表
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@ import java.util.Date;
|
|||||||
* 考勤对象 bus_attendance
|
* 考勤对象 bus_attendance
|
||||||
*
|
*
|
||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-26
|
* @date 2025-04-07
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ -51,19 +51,24 @@ public class BusAttendance extends BaseEntity {
|
|||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打卡时间
|
* 上班打卡时间
|
||||||
*/
|
*/
|
||||||
private String clockTime;
|
private Date clockTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1正常,2迟到,3早退,4缺勤,5补卡
|
* 打卡日期
|
||||||
|
*/
|
||||||
|
private Date clockDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡状态(1正常,2迟到,3早退,4缺勤,5补卡)
|
||||||
*/
|
*/
|
||||||
private String clockStatus;
|
private String clockStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代打人员id
|
* 代打人员id
|
||||||
*/
|
*/
|
||||||
private String pinchUserId;
|
private Long pinchUserId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多次打卡时间记录
|
* 多次打卡时间记录
|
||||||
@ -75,6 +80,26 @@ public class BusAttendance extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private String commuter;
|
private String commuter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡范围
|
||||||
|
*/
|
||||||
|
private String punchRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日薪
|
||||||
|
*/
|
||||||
|
private Long dailyWage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经度
|
||||||
|
*/
|
||||||
|
private String lng;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 纬度
|
||||||
|
*/
|
||||||
|
private String lat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package org.dromara.project.domain.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 11:31
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ConstructionUserAttendanceClockStatusEnum {
|
||||||
|
|
||||||
|
NORMAL("正常", "1"),
|
||||||
|
LATE("迟到", "2"),
|
||||||
|
LEAVEEARLY("早退", "3"),
|
||||||
|
UNCLOCK("缺卡", "4"),
|
||||||
|
REISSUE("补卡", "5");
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
ConstructionUserAttendanceClockStatusEnum(String text, String value) {
|
||||||
|
this.text = text;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 value 获取枚举
|
||||||
|
*
|
||||||
|
* @param value 项目成员岗位枚举值
|
||||||
|
* @return 项目成员岗位枚举
|
||||||
|
*/
|
||||||
|
public static ConstructionUserAttendanceClockStatusEnum getEnumByValue(String value) {
|
||||||
|
if (ObjectUtils.isEmpty(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (ConstructionUserAttendanceClockStatusEnum anEnum : ConstructionUserAttendanceClockStatusEnum.values()) {
|
||||||
|
if (anEnum.value.equals(value)) {
|
||||||
|
return anEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package org.dromara.project.domain.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 12:29
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ConstructionUserAttendanceCommuterEnum {
|
||||||
|
|
||||||
|
CLOCKIN("上班", "1"),
|
||||||
|
CLOCKOUT("下班", "2");
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
ConstructionUserAttendanceCommuterEnum(String text, String value) {
|
||||||
|
this.text = text;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 value 获取枚举
|
||||||
|
*
|
||||||
|
* @param value 项目成员岗位枚举值
|
||||||
|
* @return 项目成员岗位枚举
|
||||||
|
*/
|
||||||
|
public static ConstructionUserAttendanceCommuterEnum getEnumByValue(String value) {
|
||||||
|
if (ObjectUtils.isEmpty(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (ConstructionUserAttendanceCommuterEnum anEnum : ConstructionUserAttendanceCommuterEnum.values()) {
|
||||||
|
if (anEnum.value.equals(value)) {
|
||||||
|
return anEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package org.dromara.project.domain.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 15:38
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ConstructionUserAttendanceStatusEnum {
|
||||||
|
|
||||||
|
NORMAL("全天考勤正常", "1"),
|
||||||
|
ERROR("当天存在异常迟到、早退、缺卡", "2"),
|
||||||
|
REISSUE("当天提交过补卡申请", "3");
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
ConstructionUserAttendanceStatusEnum(String text, String value) {
|
||||||
|
this.text = text;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 value 获取枚举
|
||||||
|
*
|
||||||
|
* @param value 项目成员岗位枚举值
|
||||||
|
* @return 项目成员岗位枚举
|
||||||
|
*/
|
||||||
|
public static ConstructionUserAttendanceStatusEnum getEnumByValue(String value) {
|
||||||
|
if (ObjectUtils.isEmpty(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (ConstructionUserAttendanceStatusEnum anEnum : ConstructionUserAttendanceStatusEnum.values()) {
|
||||||
|
if (anEnum.value.equals(value)) {
|
||||||
|
return anEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,57 +0,0 @@
|
|||||||
package org.dromara.project.domain.req.attendance;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lcj
|
|
||||||
* @date 2025/3/26 9:46
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class AttendanceCreateReq implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1906706006468828948L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 人员id
|
|
||||||
*/
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 人脸照
|
|
||||||
*/
|
|
||||||
private String facePic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目id
|
|
||||||
*/
|
|
||||||
private Long projectId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1正常,2迟到,3早退,4缺勤,5补卡
|
|
||||||
*/
|
|
||||||
private String clockStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 代打人员id
|
|
||||||
*/
|
|
||||||
private String pinchUserId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多次打卡时间记录
|
|
||||||
*/
|
|
||||||
private String clockRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上下班(1上班,2下班)
|
|
||||||
*/
|
|
||||||
private String commuter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
private String remark;
|
|
||||||
}
|
|
@ -1,9 +1,12 @@
|
|||||||
package org.dromara.project.domain.req.attendance;
|
package org.dromara.project.domain.req.attendance;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lcj
|
* @author lcj
|
||||||
@ -15,16 +18,6 @@ public class AttendanceQueryReq implements Serializable {
|
|||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = -7188085233824968862L;
|
private static final long serialVersionUID = -7188085233824968862L;
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键id
|
|
||||||
*/
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 人员id
|
|
||||||
*/
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 人员姓名
|
* 人员姓名
|
||||||
*/
|
*/
|
||||||
@ -33,26 +26,23 @@ public class AttendanceQueryReq implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 项目id
|
* 项目id
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "项目id不能为空")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1正常,2迟到,3早退,4缺勤,5补卡
|
* 班组id
|
||||||
|
*/
|
||||||
|
private Long teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡状态(1正常,2迟到,3早退,4缺勤,5补卡)
|
||||||
*/
|
*/
|
||||||
private String clockStatus;
|
private String clockStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代打人员id
|
* 打卡日期
|
||||||
*/
|
*/
|
||||||
private String pinchUserId;
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date clockDate;
|
||||||
/**
|
|
||||||
* 上下班(1上班,2下班)
|
|
||||||
*/
|
|
||||||
private String commuter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.dromara.project.domain.req.attendance;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 9:53
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AttendanceQueryTwoWeekReq implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 3193787736889938829L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "项目id不能为空")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
}
|
@ -1,72 +0,0 @@
|
|||||||
package org.dromara.project.domain.req.attendance;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lcj
|
|
||||||
* @date 2025/3/26 9:47
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class AttendanceUpdateReq implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 3159243618168476248L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键id
|
|
||||||
*/
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 人员id
|
|
||||||
*/
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 人员姓名
|
|
||||||
*/
|
|
||||||
private String userName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 人脸照
|
|
||||||
*/
|
|
||||||
private String facePic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目id
|
|
||||||
*/
|
|
||||||
private Long projectId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打卡时间
|
|
||||||
*/
|
|
||||||
private String clockTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1正常,2迟到,3早退,4缺勤,5补卡
|
|
||||||
*/
|
|
||||||
private String clockStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 代打人员id
|
|
||||||
*/
|
|
||||||
private String pinchUserId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多次打卡时间记录
|
|
||||||
*/
|
|
||||||
private String clockRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上下班(1上班,2下班)
|
|
||||||
*/
|
|
||||||
private String commuter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
private String remark;
|
|
||||||
}
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package org.dromara.project.domain.req.constructionuser;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 15:04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ConstructionUserAttendanceMonthReq implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -1496942176392426636L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "用户主键不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡月份
|
||||||
|
*/
|
||||||
|
private String clockMonth;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.dromara.project.domain.req.constructionuser;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 10:52
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ConstructionUserAttendanceQueryReq implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -6634291825924626633L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人员姓名
|
||||||
|
*/
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "项目id不能为空")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班组id
|
||||||
|
*/
|
||||||
|
private Long teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工种
|
||||||
|
*/
|
||||||
|
private String typeOfWork;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡月份
|
||||||
|
*/
|
||||||
|
private String clockMonth;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package org.dromara.project.domain.resp.attendance;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 9:55
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AttendanceClockDateForTwoWeekResp implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -2762312533060742243L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡日期
|
||||||
|
*/
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING,
|
||||||
|
pattern = "yyyy-MM-dd",
|
||||||
|
timezone = "GMT+8")
|
||||||
|
private Date clockDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出勤人数
|
||||||
|
*/
|
||||||
|
private Integer attendance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 半勤人数
|
||||||
|
*/
|
||||||
|
private Integer halfAttendance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缺勤人数
|
||||||
|
*/
|
||||||
|
private Integer absenteeism;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.dromara.project.domain.resp.attendance;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.dromara.project.domain.BusAttendance;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 15:27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class AttendanceListByDay {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上下班(1上班,2下班)
|
||||||
|
*/
|
||||||
|
private String commuter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡时间
|
||||||
|
*/
|
||||||
|
private Date clockTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡状态(1正常,2迟到,3早退,4缺勤,5补卡)
|
||||||
|
*/
|
||||||
|
private String clockStatus;
|
||||||
|
|
||||||
|
public static AttendanceListByDay build(BusAttendance attendance) {
|
||||||
|
if (attendance == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AttendanceListByDay attendanceListByDay = new AttendanceListByDay();
|
||||||
|
attendanceListByDay.setCommuter(attendance.getCommuter());
|
||||||
|
attendanceListByDay.setClockTime(attendance.getClockTime());
|
||||||
|
attendanceListByDay.setClockStatus(attendance.getClockStatus());
|
||||||
|
return attendanceListByDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.dromara.project.domain.resp.constructionuser;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.dromara.project.domain.resp.attendance.AttendanceListByDay;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 15:06
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ConstructionUserAttendanceMonthResp implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -413447291128760025L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡日期
|
||||||
|
*/
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING,
|
||||||
|
pattern = "yyyy-MM-dd",
|
||||||
|
timezone = "GMT+8")
|
||||||
|
private Date clockDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当天打卡状态
|
||||||
|
*/
|
||||||
|
private String Status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当天打卡记录
|
||||||
|
*/
|
||||||
|
private List<AttendanceListByDay> attendanceList;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package org.dromara.project.domain.resp.constructionuser;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/4/7 10:16
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ConstructionUserAttendanceTotalResp implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1335094839733429171L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人员姓名
|
||||||
|
*/
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班组id
|
||||||
|
*/
|
||||||
|
private Long teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班组名称
|
||||||
|
*/
|
||||||
|
private String teamName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工种
|
||||||
|
*/
|
||||||
|
private String typeOfWork;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出勤天数
|
||||||
|
*/
|
||||||
|
private Integer attendanceDays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到天数
|
||||||
|
*/
|
||||||
|
private Integer lateDays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 早退天数
|
||||||
|
*/
|
||||||
|
private Integer leaveEarlyDays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缺卡天数
|
||||||
|
*/
|
||||||
|
private Integer unClockDays;
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ package org.dromara.project.domain.vo;
|
|||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
@ -10,13 +11,14 @@ import org.dromara.project.domain.BusAttendance;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 考勤视图对象 bus_attendance
|
* 考勤视图对象 bus_attendance
|
||||||
*
|
*
|
||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-26
|
* @date 2025-04-07
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
@ -29,13 +31,11 @@ public class BusAttendanceVo implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 主键id
|
* 主键id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "主键id")
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 人员id
|
* 人员id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "人员id")
|
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,10 +44,21 @@ public class BusAttendanceVo implements Serializable {
|
|||||||
@ExcelProperty(value = "人员姓名")
|
@ExcelProperty(value = "人员姓名")
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班组id
|
||||||
|
*/
|
||||||
|
private Long teamId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工种
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "工种", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(dictType = "type_of_work")
|
||||||
|
private String typeOfWork;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 人脸照
|
* 人脸照
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "人脸照")
|
|
||||||
private String facePic;
|
private String facePic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,20 +71,28 @@ public class BusAttendanceVo implements Serializable {
|
|||||||
* 打卡时间
|
* 打卡时间
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "打卡时间")
|
@ExcelProperty(value = "打卡时间")
|
||||||
private String clockTime;
|
private Date clockTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1正常,2迟到,3早退,4缺勤,5补卡
|
* 打卡日期
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "1正常,2迟到,3早退,4缺勤,5补卡", converter = ExcelDictConvert.class)
|
@JsonFormat(shape = JsonFormat.Shape.STRING,
|
||||||
|
pattern = "yyyy-MM-dd",
|
||||||
|
timezone = "GMT+8")
|
||||||
|
@ExcelProperty(value = "打卡日期")
|
||||||
|
private Date clockDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡状态(1正常,2迟到,3早退,4缺勤,5补卡)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "打卡状态", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(dictType = "clock_status_type")
|
@ExcelDictFormat(dictType = "clock_status_type")
|
||||||
private String clockStatus;
|
private String clockStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代打人员id
|
* 代打人员id
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "代打人员id")
|
private Long pinchUserId;
|
||||||
private String pinchUserId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多次打卡时间记录
|
* 多次打卡时间记录
|
||||||
@ -88,11 +107,34 @@ public class BusAttendanceVo implements Serializable {
|
|||||||
@ExcelDictFormat(dictType = "commuter_type")
|
@ExcelDictFormat(dictType = "commuter_type")
|
||||||
private String commuter;
|
private String commuter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡范围
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "打卡范围")
|
||||||
|
private String punchRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日薪
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "日薪")
|
||||||
|
private Long dailyWage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经度
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "经度")
|
||||||
|
private String lng;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 纬度
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "纬度")
|
||||||
|
private String lat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "备注")
|
@ExcelProperty(value = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|||||||
* 考勤Mapper接口
|
* 考勤Mapper接口
|
||||||
*
|
*
|
||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-26
|
* @date 2025-04-07
|
||||||
*/
|
*/
|
||||||
public interface BusAttendanceMapper extends BaseMapperPlus<BusAttendance, BusAttendanceVo> {
|
public interface BusAttendanceMapper extends BaseMapperPlus<BusAttendance, BusAttendanceVo> {
|
||||||
|
|
||||||
|
@ -6,19 +6,18 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.project.domain.BusAttendance;
|
import org.dromara.project.domain.BusAttendance;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceCreateReq;
|
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceQueryReq;
|
import org.dromara.project.domain.req.attendance.AttendanceQueryReq;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceUpdateReq;
|
import org.dromara.project.domain.req.attendance.AttendanceQueryTwoWeekReq;
|
||||||
|
import org.dromara.project.domain.resp.attendance.AttendanceClockDateForTwoWeekResp;
|
||||||
import org.dromara.project.domain.vo.BusAttendanceVo;
|
import org.dromara.project.domain.vo.BusAttendanceVo;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 考勤Service接口
|
* 考勤Service接口
|
||||||
*
|
*
|
||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-26
|
* @date 2025-04-07
|
||||||
*/
|
*/
|
||||||
public interface IBusAttendanceService extends IService<BusAttendance> {
|
public interface IBusAttendanceService extends IService<BusAttendance> {
|
||||||
|
|
||||||
@ -39,6 +38,14 @@ public interface IBusAttendanceService extends IService<BusAttendance> {
|
|||||||
*/
|
*/
|
||||||
TableDataInfo<BusAttendanceVo> queryPageList(AttendanceQueryReq req, PageQuery pageQuery);
|
TableDataInfo<BusAttendanceVo> queryPageList(AttendanceQueryReq req, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询两周内的考勤列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 考勤列表
|
||||||
|
*/
|
||||||
|
List<AttendanceClockDateForTwoWeekResp> listClockDateForTwoWeek(AttendanceQueryTwoWeekReq req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合条件的考勤列表
|
* 查询符合条件的考勤列表
|
||||||
*
|
*
|
||||||
@ -47,31 +54,6 @@ public interface IBusAttendanceService extends IService<BusAttendance> {
|
|||||||
*/
|
*/
|
||||||
List<BusAttendanceVo> queryList(AttendanceQueryReq req);
|
List<BusAttendanceVo> queryList(AttendanceQueryReq req);
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增考勤
|
|
||||||
*
|
|
||||||
* @param req 考勤
|
|
||||||
* @return 新增考勤id
|
|
||||||
*/
|
|
||||||
Long insertByBo(AttendanceCreateReq req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改考勤
|
|
||||||
*
|
|
||||||
* @param req 考勤
|
|
||||||
* @return 是否修改成功
|
|
||||||
*/
|
|
||||||
Boolean updateByBo(AttendanceUpdateReq req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验并批量删除考勤信息
|
|
||||||
*
|
|
||||||
* @param ids 待删除的主键集合
|
|
||||||
* @param isValid 是否进行有效性校验
|
|
||||||
* @return 是否删除成功
|
|
||||||
*/
|
|
||||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取考勤视图对象
|
* 获取考勤视图对象
|
||||||
*
|
*
|
||||||
@ -95,4 +77,5 @@ public interface IBusAttendanceService extends IService<BusAttendance> {
|
|||||||
* @return 考勤分页对象视图
|
* @return 考勤分页对象视图
|
||||||
*/
|
*/
|
||||||
Page<BusAttendanceVo> getVoPage(Page<BusAttendance> attendancePage);
|
Page<BusAttendanceVo> getVoPage(Page<BusAttendance> attendancePage);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|||||||
import org.dromara.project.domain.BusConstructionUser;
|
import org.dromara.project.domain.BusConstructionUser;
|
||||||
import org.dromara.project.domain.exportvo.BusConstructionUserExportVo;
|
import org.dromara.project.domain.exportvo.BusConstructionUserExportVo;
|
||||||
import org.dromara.project.domain.req.constructionuser.*;
|
import org.dromara.project.domain.req.constructionuser.*;
|
||||||
|
import org.dromara.project.domain.resp.constructionuser.ConstructionUserAttendanceMonthResp;
|
||||||
|
import org.dromara.project.domain.resp.constructionuser.ConstructionUserAttendanceTotalResp;
|
||||||
import org.dromara.project.domain.vo.BusConstructionUserVo;
|
import org.dromara.project.domain.vo.BusConstructionUserVo;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -38,6 +40,23 @@ public interface IBusConstructionUserService extends IService<BusConstructionUse
|
|||||||
*/
|
*/
|
||||||
TableDataInfo<BusConstructionUserVo> queryPageList(ConstructionUserQueryReq req, PageQuery pageQuery);
|
TableDataInfo<BusConstructionUserVo> queryPageList(ConstructionUserQueryReq req, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询施工人员考勤列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @param pageQuery 分页参数
|
||||||
|
* @return 施工人员考勤分页列表
|
||||||
|
*/
|
||||||
|
TableDataInfo<ConstructionUserAttendanceTotalResp> queryPageAttendanceList(ConstructionUserAttendanceQueryReq req, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询施工人员月考勤列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 施工人员考勤月列表
|
||||||
|
*/
|
||||||
|
List<ConstructionUserAttendanceMonthResp> queryAttendanceMonthList(ConstructionUserAttendanceMonthReq req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合条件的施工人员列表
|
* 查询符合条件的施工人员列表
|
||||||
*
|
*
|
||||||
@ -134,4 +153,14 @@ public interface IBusConstructionUserService extends IService<BusConstructionUse
|
|||||||
* @return 施工人员分页对象视图
|
* @return 施工人员分页对象视图
|
||||||
*/
|
*/
|
||||||
Page<BusConstructionUserVo> getVoPage(Page<BusConstructionUser> constructionUserPage);
|
Page<BusConstructionUserVo> getVoPage(Page<BusConstructionUser> constructionUserPage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取施工人员考勤分页对象视图
|
||||||
|
*
|
||||||
|
* @param req 施工人员考勤分页查询条件
|
||||||
|
* @return 施工人员考勤分页对象视图
|
||||||
|
*/
|
||||||
|
Page<ConstructionUserAttendanceTotalResp> getAttendanceTotalVoPage(ConstructionUserAttendanceQueryReq req,
|
||||||
|
PageQuery pageQuery);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.dromara.common.core.constant.HttpStatus;
|
import org.dromara.common.core.constant.HttpStatus;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.ObjectUtils;
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
@ -11,29 +12,41 @@ import org.dromara.common.core.utils.StringUtils;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.project.domain.BusAttendance;
|
import org.dromara.project.domain.BusAttendance;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceCreateReq;
|
import org.dromara.project.domain.BusProjectTeamMember;
|
||||||
|
import org.dromara.project.domain.enums.ConstructionUserAttendanceClockStatusEnum;
|
||||||
|
import org.dromara.project.domain.enums.ConstructionUserAttendanceCommuterEnum;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceQueryReq;
|
import org.dromara.project.domain.req.attendance.AttendanceQueryReq;
|
||||||
import org.dromara.project.domain.req.attendance.AttendanceUpdateReq;
|
import org.dromara.project.domain.req.attendance.AttendanceQueryTwoWeekReq;
|
||||||
|
import org.dromara.project.domain.resp.attendance.AttendanceClockDateForTwoWeekResp;
|
||||||
import org.dromara.project.domain.vo.BusAttendanceVo;
|
import org.dromara.project.domain.vo.BusAttendanceVo;
|
||||||
import org.dromara.project.mapper.BusAttendanceMapper;
|
import org.dromara.project.mapper.BusAttendanceMapper;
|
||||||
import org.dromara.project.service.IBusAttendanceService;
|
import org.dromara.project.service.IBusAttendanceService;
|
||||||
|
import org.dromara.project.service.IBusProjectService;
|
||||||
|
import org.dromara.project.service.IBusProjectTeamMemberService;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.time.ZoneId;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 考勤Service业务层处理
|
* 考勤Service业务层处理
|
||||||
*
|
*
|
||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025-03-26
|
* @date 2025-04-07
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, BusAttendance>
|
public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, BusAttendance>
|
||||||
implements IBusAttendanceService {
|
implements IBusAttendanceService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IBusProjectService projectService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IBusProjectTeamMemberService projectTeamMemberService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询考勤
|
* 查询考勤
|
||||||
*
|
*
|
||||||
@ -62,6 +75,75 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
return TableDataInfo.build(this.getVoPage(result));
|
return TableDataInfo.build(this.getVoPage(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询两周内的考勤列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 考勤列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<AttendanceClockDateForTwoWeekResp> listClockDateForTwoWeek(AttendanceQueryTwoWeekReq req) {
|
||||||
|
Long projectId = req.getProjectId();
|
||||||
|
if (projectService.getById(projectId) == null) {
|
||||||
|
throw new ServiceException("项目信息不存在", HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 获取两周前的日期
|
||||||
|
LocalDate twoWeeksAgoLocal = LocalDate.now().minusWeeks(2);
|
||||||
|
// 2. 转成Date(时分秒会被置为 00:00:00)
|
||||||
|
Date twoWeeksDate = Date.from(twoWeeksAgoLocal.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
|
// 获取两周内的考勤记录
|
||||||
|
LambdaQueryWrapper<BusAttendance> lqw = new LambdaQueryWrapper<>();
|
||||||
|
lqw.eq(BusAttendance::getProjectId, projectId)
|
||||||
|
.ge(BusAttendance::getClockDate, twoWeeksDate)
|
||||||
|
.orderByDesc(BusAttendance::getClockDate);
|
||||||
|
Map<Date, List<BusAttendance>> dateListMap = this.list(lqw)
|
||||||
|
.stream().collect(Collectors.groupingBy(BusAttendance::getClockDate));
|
||||||
|
// 遍历每个日期,计算考勤状态
|
||||||
|
List<AttendanceClockDateForTwoWeekResp> respList = new ArrayList<>();
|
||||||
|
dateListMap.forEach((date, attendanceList) -> {
|
||||||
|
AttendanceClockDateForTwoWeekResp resp = new AttendanceClockDateForTwoWeekResp();
|
||||||
|
resp.setClockDate(date);
|
||||||
|
// 统计考勤状态数量
|
||||||
|
int attendance = 0;
|
||||||
|
int halfAttendance = 0;
|
||||||
|
int absenteeism = 0;
|
||||||
|
// 遍历每个用户,统计考勤状态数量
|
||||||
|
Map<Long, List<BusAttendance>> userAttendanceMap = attendanceList.stream()
|
||||||
|
.collect(Collectors.groupingBy(BusAttendance::getUserId));
|
||||||
|
if (CollUtil.isNotEmpty(userAttendanceMap)) {
|
||||||
|
for (List<BusAttendance> userAttendanceList : userAttendanceMap.values()) {
|
||||||
|
String clockInStatus = null;
|
||||||
|
String clockOutStatus = null;
|
||||||
|
// 获取上下班状态
|
||||||
|
for (BusAttendance a : userAttendanceList) {
|
||||||
|
if (ConstructionUserAttendanceCommuterEnum.CLOCKIN.getValue().equals(a.getCommuter())) {
|
||||||
|
clockInStatus = a.getClockStatus();
|
||||||
|
} else if (ConstructionUserAttendanceCommuterEnum.CLOCKOUT.getValue().equals(a.getCommuter())) {
|
||||||
|
clockOutStatus = a.getClockStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 统计考勤状态
|
||||||
|
if (ConstructionUserAttendanceClockStatusEnum.NORMAL.getValue().equals(clockInStatus)
|
||||||
|
&& ConstructionUserAttendanceClockStatusEnum.NORMAL.getValue().equals(clockOutStatus)) {
|
||||||
|
attendance++;
|
||||||
|
} else if (ConstructionUserAttendanceClockStatusEnum.UNCLOCK.getValue().equals(clockInStatus)
|
||||||
|
&& ConstructionUserAttendanceClockStatusEnum.UNCLOCK.getValue().equals(clockOutStatus)) {
|
||||||
|
absenteeism++;
|
||||||
|
} else {
|
||||||
|
halfAttendance++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp.setAttendance(attendance);
|
||||||
|
resp.setHalfAttendance(halfAttendance);
|
||||||
|
resp.setAbsenteeism(absenteeism);
|
||||||
|
respList.add(resp);
|
||||||
|
});
|
||||||
|
// 按打卡日期正序排列
|
||||||
|
respList.sort(Comparator.comparing(AttendanceClockDateForTwoWeekResp::getClockDate));
|
||||||
|
return respList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合条件的考勤列表
|
* 查询符合条件的考勤列表
|
||||||
*
|
*
|
||||||
@ -74,75 +156,6 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
return this.list(lqw).stream().map(this::getVo).toList();
|
return this.list(lqw).stream().map(this::getVo).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增考勤
|
|
||||||
*
|
|
||||||
* @param req 考勤
|
|
||||||
* @return 新增考勤id
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Long insertByBo(AttendanceCreateReq req) {
|
|
||||||
// 将实体类和 DTO 进行转换
|
|
||||||
BusAttendance attendance = new BusAttendance();
|
|
||||||
BeanUtils.copyProperties(req, attendance);
|
|
||||||
// 数据校验
|
|
||||||
validEntityBeforeSave(attendance, true);
|
|
||||||
// 操作数据库
|
|
||||||
boolean save = this.save(attendance);
|
|
||||||
if (!save) {
|
|
||||||
throw new ServiceException("新增考勤失败,数据库异常", HttpStatus.ERROR);
|
|
||||||
}
|
|
||||||
return attendance.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改考勤
|
|
||||||
*
|
|
||||||
* @param req 考勤
|
|
||||||
* @return 是否修改成功
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Boolean updateByBo(AttendanceUpdateReq req) {
|
|
||||||
// 将实体类和 DTO 进行转换
|
|
||||||
BusAttendance attendance = new BusAttendance();
|
|
||||||
BeanUtils.copyProperties(req, attendance);
|
|
||||||
// 数据校验
|
|
||||||
validEntityBeforeSave(attendance, false);
|
|
||||||
// 判断是否存在
|
|
||||||
BusAttendance oldBusAttendance = this.getById(attendance.getId());
|
|
||||||
if (oldBusAttendance == null) {
|
|
||||||
throw new ServiceException("修改考勤失败,数据不存在", HttpStatus.NOT_FOUND);
|
|
||||||
}
|
|
||||||
// 操作数据库
|
|
||||||
return this.updateById(attendance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存前的数据校验
|
|
||||||
*/
|
|
||||||
private void validEntityBeforeSave(BusAttendance entity, Boolean create) {
|
|
||||||
// TODO 做一些数据校验,如唯一约束
|
|
||||||
if (create) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验并批量删除考勤信息
|
|
||||||
*
|
|
||||||
* @param ids 待删除的主键集合
|
|
||||||
* @param isValid 是否进行有效性校验
|
|
||||||
* @return 是否删除成功
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
||||||
if (isValid) {
|
|
||||||
// TODO 做一些业务上的校验,判断是否需要校验
|
|
||||||
}
|
|
||||||
return this.removeBatchByIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取考勤视图对象
|
* 获取考勤视图对象
|
||||||
*
|
*
|
||||||
@ -172,24 +185,24 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
if (req == null) {
|
if (req == null) {
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
Long id = req.getId();
|
|
||||||
Long userId = req.getUserId();
|
|
||||||
String userName = req.getUserName();
|
String userName = req.getUserName();
|
||||||
Long projectId = req.getProjectId();
|
Long projectId = req.getProjectId();
|
||||||
|
Long teamId = req.getTeamId();
|
||||||
String clockStatus = req.getClockStatus();
|
String clockStatus = req.getClockStatus();
|
||||||
String pinchUserId = req.getPinchUserId();
|
Date clockDate = req.getClockDate();
|
||||||
String commuter = req.getCommuter();
|
// 联表查询
|
||||||
String remark = req.getRemark();
|
if (ObjectUtils.isNotEmpty(teamId)) {
|
||||||
|
List<BusProjectTeamMember> projectTeamMemberList = projectTeamMemberService.lambdaQuery()
|
||||||
|
.eq(BusProjectTeamMember::getTeamId, teamId).list();
|
||||||
|
List<Long> userIdList = projectTeamMemberList.stream().map(BusProjectTeamMember::getMemberId).toList();
|
||||||
|
lqw.in(BusAttendance::getUserId, userIdList);
|
||||||
|
}
|
||||||
// 模糊查询
|
// 模糊查询
|
||||||
lqw.like(StringUtils.isNotBlank(userName), BusAttendance::getUserName, userName);
|
lqw.like(StringUtils.isNotBlank(userName), BusAttendance::getUserName, userName);
|
||||||
lqw.like(StringUtils.isNotBlank(remark), BusAttendance::getRemark, remark);
|
|
||||||
// 精确查询
|
// 精确查询
|
||||||
lqw.eq(ObjectUtils.isNotEmpty(id), BusAttendance::getId, id);
|
|
||||||
lqw.eq(ObjectUtils.isNotEmpty(userId), BusAttendance::getUserId, userId);
|
|
||||||
lqw.eq(ObjectUtils.isNotEmpty(projectId), BusAttendance::getProjectId, projectId);
|
lqw.eq(ObjectUtils.isNotEmpty(projectId), BusAttendance::getProjectId, projectId);
|
||||||
lqw.eq(StringUtils.isNotBlank(clockStatus), BusAttendance::getClockStatus, clockStatus);
|
lqw.eq(StringUtils.isNotBlank(clockStatus), BusAttendance::getClockStatus, clockStatus);
|
||||||
lqw.eq(StringUtils.isNotBlank(pinchUserId), BusAttendance::getPinchUserId, pinchUserId);
|
lqw.eq(ObjectUtils.isNotEmpty(clockDate), BusAttendance::getClockDate, clockDate);
|
||||||
lqw.eq(StringUtils.isNotBlank(commuter), BusAttendance::getCommuter, commuter);
|
|
||||||
return lqw;
|
return lqw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,4 +227,5 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
attendanceVoPage.setRecords(attendanceVoList);
|
attendanceVoPage.setRecords(attendanceVoList);
|
||||||
return attendanceVoPage;
|
return attendanceVoPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.dromara.common.core.constant.DateConstant;
|
||||||
import org.dromara.common.core.constant.HttpStatus;
|
import org.dromara.common.core.constant.HttpStatus;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.common.core.utils.DateUtils;
|
||||||
import org.dromara.common.core.utils.ObjectUtils;
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
@ -16,9 +18,15 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.project.constant.ConstructionUserConstant;
|
import org.dromara.project.constant.ConstructionUserConstant;
|
||||||
import org.dromara.project.domain.*;
|
import org.dromara.project.domain.*;
|
||||||
|
import org.dromara.project.domain.enums.ConstructionUserAttendanceClockStatusEnum;
|
||||||
|
import org.dromara.project.domain.enums.ConstructionUserAttendanceCommuterEnum;
|
||||||
|
import org.dromara.project.domain.enums.ConstructionUserAttendanceStatusEnum;
|
||||||
import org.dromara.project.domain.enums.ConstructionUserFileStatusEnum;
|
import org.dromara.project.domain.enums.ConstructionUserFileStatusEnum;
|
||||||
import org.dromara.project.domain.exportvo.BusConstructionUserExportVo;
|
import org.dromara.project.domain.exportvo.BusConstructionUserExportVo;
|
||||||
import org.dromara.project.domain.req.constructionuser.*;
|
import org.dromara.project.domain.req.constructionuser.*;
|
||||||
|
import org.dromara.project.domain.resp.attendance.AttendanceListByDay;
|
||||||
|
import org.dromara.project.domain.resp.constructionuser.ConstructionUserAttendanceMonthResp;
|
||||||
|
import org.dromara.project.domain.resp.constructionuser.ConstructionUserAttendanceTotalResp;
|
||||||
import org.dromara.project.domain.vo.BusConstructionUserVo;
|
import org.dromara.project.domain.vo.BusConstructionUserVo;
|
||||||
import org.dromara.project.domain.vo.BusContractorVo;
|
import org.dromara.project.domain.vo.BusContractorVo;
|
||||||
import org.dromara.project.domain.vo.BusProjectTeamVo;
|
import org.dromara.project.domain.vo.BusProjectTeamVo;
|
||||||
@ -31,6 +39,7 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.YearMonth;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -76,6 +85,10 @@ public class BusConstructionUserServiceImpl extends ServiceImpl<BusConstructionU
|
|||||||
@Resource
|
@Resource
|
||||||
private ISysDictTypeService dictTypeService;
|
private ISysDictTypeService dictTypeService;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Resource
|
||||||
|
private IBusAttendanceService attendanceService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询施工人员
|
* 查询施工人员
|
||||||
*
|
*
|
||||||
@ -105,6 +118,93 @@ public class BusConstructionUserServiceImpl extends ServiceImpl<BusConstructionU
|
|||||||
return TableDataInfo.build(getVoPage(result));
|
return TableDataInfo.build(getVoPage(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询施工人员考勤列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @param pageQuery 分页参数
|
||||||
|
* @return 施工人员考勤分页列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TableDataInfo<ConstructionUserAttendanceTotalResp> queryPageAttendanceList(ConstructionUserAttendanceQueryReq req,
|
||||||
|
PageQuery pageQuery) {
|
||||||
|
return TableDataInfo.build(getAttendanceTotalVoPage(req, pageQuery));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询施工人员月考勤列表
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 施工人员考勤月列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<ConstructionUserAttendanceMonthResp> queryAttendanceMonthList(ConstructionUserAttendanceMonthReq req) {
|
||||||
|
Long id = req.getId();
|
||||||
|
String clockMonth = req.getClockMonth();
|
||||||
|
if (this.getById(id) == null) {
|
||||||
|
throw new ServiceException("施工人员信息不存在", HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 解析月份
|
||||||
|
YearMonth yearMonth;
|
||||||
|
if (StringUtils.isNotBlank(clockMonth)) {
|
||||||
|
// 校验月份格式
|
||||||
|
if (!DateConstant.YEAR_MONTH_PATTERN.matcher(clockMonth).matches()) {
|
||||||
|
throw new ServiceException("月份格式不正确", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
yearMonth = YearMonth.parse(clockMonth);
|
||||||
|
} else {
|
||||||
|
// 如果月份为空,则默认查询当前月份
|
||||||
|
yearMonth = YearMonth.now();
|
||||||
|
}
|
||||||
|
// 计算当月第一天 / 最后一天
|
||||||
|
Date start = DateUtils.toDate(yearMonth.atDay(1));
|
||||||
|
Date end = DateUtils.toDate(yearMonth.atEndOfMonth());
|
||||||
|
// 查询当月考勤记录
|
||||||
|
Map<Date, List<BusAttendance>> dateListMap = attendanceService.lambdaQuery()
|
||||||
|
.eq(BusAttendance::getUserId, id)
|
||||||
|
.between(BusAttendance::getClockDate, start, end)
|
||||||
|
.list()
|
||||||
|
.stream().collect(Collectors.groupingBy(BusAttendance::getClockDate));
|
||||||
|
// 遍历每天,计算考勤状态
|
||||||
|
List<ConstructionUserAttendanceMonthResp> respList = new ArrayList<>();
|
||||||
|
dateListMap.forEach((date, attendanceList) -> {
|
||||||
|
ConstructionUserAttendanceMonthResp resp = new ConstructionUserAttendanceMonthResp();
|
||||||
|
resp.setId(id);
|
||||||
|
resp.setClockDate(date);
|
||||||
|
List<AttendanceListByDay> attendanceListByDayList = new ArrayList<>();
|
||||||
|
String clockInStatus = null;
|
||||||
|
String clockOutStatus = null;
|
||||||
|
String status;
|
||||||
|
for (BusAttendance attendance : attendanceList) {
|
||||||
|
// 获取考勤记录
|
||||||
|
AttendanceListByDay day = AttendanceListByDay.build(attendance);
|
||||||
|
attendanceListByDayList.add(day);
|
||||||
|
// 获取上下班状态
|
||||||
|
if (ConstructionUserAttendanceCommuterEnum.CLOCKIN.getValue().equals(attendance.getCommuter())) {
|
||||||
|
clockInStatus = attendance.getClockStatus();
|
||||||
|
} else if (ConstructionUserAttendanceCommuterEnum.CLOCKOUT.getValue().equals(attendance.getCommuter())) {
|
||||||
|
clockOutStatus = attendance.getClockStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 统计当天考勤状态
|
||||||
|
if (ConstructionUserAttendanceClockStatusEnum.NORMAL.getValue().equals(clockInStatus)
|
||||||
|
&& ConstructionUserAttendanceClockStatusEnum.NORMAL.getValue().equals(clockOutStatus)) {
|
||||||
|
status = ConstructionUserAttendanceStatusEnum.NORMAL.getValue();
|
||||||
|
} else if (ConstructionUserAttendanceClockStatusEnum.REISSUE.getValue().equals(clockInStatus)
|
||||||
|
|| ConstructionUserAttendanceClockStatusEnum.REISSUE.getValue().equals(clockOutStatus)) {
|
||||||
|
status = ConstructionUserAttendanceStatusEnum.REISSUE.getValue();
|
||||||
|
} else {
|
||||||
|
status = ConstructionUserAttendanceStatusEnum.ERROR.getValue();
|
||||||
|
}
|
||||||
|
resp.setStatus(status);
|
||||||
|
resp.setAttendanceList(attendanceListByDayList);
|
||||||
|
respList.add(resp);
|
||||||
|
});
|
||||||
|
// 按打卡日期正序排列
|
||||||
|
respList.sort(Comparator.comparing(ConstructionUserAttendanceMonthResp::getClockDate));
|
||||||
|
return respList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合条件的施工人员列表
|
* 查询符合条件的施工人员列表
|
||||||
*
|
*
|
||||||
@ -653,4 +753,141 @@ public class BusConstructionUserServiceImpl extends ServiceImpl<BusConstructionU
|
|||||||
constructionUserVoPage.setRecords(constructionUserVoList);
|
constructionUserVoPage.setRecords(constructionUserVoList);
|
||||||
return constructionUserVoPage;
|
return constructionUserVoPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取施工人员考勤分页对象视图
|
||||||
|
*
|
||||||
|
* @param req 施工人员考勤分页查询条件
|
||||||
|
* @return 施工人员考勤分页对象视图
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Page<ConstructionUserAttendanceTotalResp> getAttendanceTotalVoPage(ConstructionUserAttendanceQueryReq req,
|
||||||
|
PageQuery pageQuery) {
|
||||||
|
LambdaQueryWrapper<BusConstructionUser> lqw = Wrappers.lambdaQuery();
|
||||||
|
// 从对象中取值
|
||||||
|
String userName = req.getUserName();
|
||||||
|
Long projectId = req.getProjectId();
|
||||||
|
Long teamId = req.getTeamId();
|
||||||
|
String typeOfWork = req.getTypeOfWork();
|
||||||
|
String clockMonth = req.getClockMonth();
|
||||||
|
// 联表查询
|
||||||
|
LambdaQueryWrapper<BusAttendance> attendanceLqw = Wrappers.lambdaQuery(BusAttendance.class)
|
||||||
|
.eq(BusAttendance::getProjectId, projectId);
|
||||||
|
if (ObjectUtils.isNotEmpty(clockMonth)) {
|
||||||
|
// 校验月份格式
|
||||||
|
if (!DateConstant.YEAR_MONTH_PATTERN.matcher(clockMonth).matches()) {
|
||||||
|
throw new ServiceException("月份格式不正确", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
// 解析月份
|
||||||
|
YearMonth yearMonth = YearMonth.parse(clockMonth);
|
||||||
|
// 计算当月第一天 / 最后一天
|
||||||
|
Date start = DateUtils.toDate(yearMonth.atDay(1));
|
||||||
|
Date end = DateUtils.toDate(yearMonth.atEndOfMonth());
|
||||||
|
attendanceLqw.between(BusAttendance::getClockDate, start, end);
|
||||||
|
List<Long> userIdList = attendanceService.list(attendanceLqw)
|
||||||
|
.stream().map(BusAttendance::getUserId).toList();
|
||||||
|
if (CollUtil.isNotEmpty(userIdList)) {
|
||||||
|
lqw.in(BusConstructionUser::getId, userIdList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 模糊查询
|
||||||
|
lqw.like(StringUtils.isNotBlank(userName), BusConstructionUser::getUserName, userName);
|
||||||
|
// 精确查询
|
||||||
|
lqw.eq(ObjectUtils.isNotEmpty(projectId), BusConstructionUser::getProjectId, projectId);
|
||||||
|
lqw.eq(ObjectUtils.isNotEmpty(teamId), BusConstructionUser::getTeamId, teamId);
|
||||||
|
lqw.eq(StringUtils.isNotBlank(typeOfWork), BusConstructionUser::getTypeOfWork, typeOfWork);
|
||||||
|
// 查询当前项目下的黑名单人员
|
||||||
|
List<Long> blackUserIdList = constructionBlacklistService.lambdaQuery()
|
||||||
|
.eq(BusConstructionBlacklist::getProjectId, projectId).list()
|
||||||
|
.stream().map(BusConstructionBlacklist::getUserId).toList();
|
||||||
|
// 查询结果移除黑名单人员
|
||||||
|
if (CollUtil.isNotEmpty(blackUserIdList)) {
|
||||||
|
lqw.notIn(BusConstructionUser::getId, blackUserIdList);
|
||||||
|
}
|
||||||
|
// 分页查询获取数据
|
||||||
|
Page<BusConstructionUser> constructionUserPage = this.page(pageQuery.build(), lqw);
|
||||||
|
List<BusConstructionUser> constructionUserList = constructionUserPage.getRecords();
|
||||||
|
Page<ConstructionUserAttendanceTotalResp> constructionUserAttendanceTotalPage = new Page<>(
|
||||||
|
constructionUserPage.getCurrent(),
|
||||||
|
constructionUserPage.getSize(),
|
||||||
|
constructionUserPage.getTotal());
|
||||||
|
if (CollUtil.isEmpty(constructionUserList)) {
|
||||||
|
return constructionUserAttendanceTotalPage;
|
||||||
|
}
|
||||||
|
// 获取施工人员id列表
|
||||||
|
List<Long> userIdList = constructionUserList.stream().map(BusConstructionUser::getId).toList();
|
||||||
|
// 关联查询施工人员考勤列表
|
||||||
|
attendanceLqw.in(BusAttendance::getUserId, userIdList);
|
||||||
|
Map<Long, List<BusAttendance>> userIdBusAttendanceListMap = attendanceService.list(attendanceLqw)
|
||||||
|
.stream().collect(Collectors.groupingBy(BusAttendance::getUserId));
|
||||||
|
// 关联查询班组列表
|
||||||
|
List<Long> teamIdList = constructionUserList.stream().map(BusConstructionUser::getTeamId).toList();
|
||||||
|
Map<Long, List<BusProjectTeam>> teamIdProjectTeamListMap = projectTeamService.lambdaQuery()
|
||||||
|
.in(BusProjectTeam::getId, teamIdList).list()
|
||||||
|
.stream().collect(Collectors.groupingBy(BusProjectTeam::getId));
|
||||||
|
// 填充信息
|
||||||
|
List<ConstructionUserAttendanceTotalResp> userAttendanceTotalList = constructionUserList.stream().map(constructionUser -> {
|
||||||
|
ConstructionUserAttendanceTotalResp constructionUserAttendanceTotalResp = new ConstructionUserAttendanceTotalResp();
|
||||||
|
Long id = constructionUser.getId();
|
||||||
|
constructionUserAttendanceTotalResp.setId(id);
|
||||||
|
constructionUserAttendanceTotalResp.setUserName(constructionUser.getUserName());
|
||||||
|
constructionUserAttendanceTotalResp.setTypeOfWork(constructionUser.getTypeOfWork());
|
||||||
|
// 关联施工人员考勤信息
|
||||||
|
int attendanceDays = 0;
|
||||||
|
int lateDays = 0;
|
||||||
|
int leaveEarlyDays = 0;
|
||||||
|
int unClockDays = 0;
|
||||||
|
if (userIdBusAttendanceListMap.containsKey(id)) {
|
||||||
|
List<BusAttendance> attendanceList = userIdBusAttendanceListMap.get(id);
|
||||||
|
if (CollUtil.isNotEmpty(attendanceList)) {
|
||||||
|
// 1. 按打卡日期分组
|
||||||
|
Map<Date, List<BusAttendance>> dailyMap = attendanceList.stream()
|
||||||
|
.collect(Collectors.groupingBy(BusAttendance::getClockDate));
|
||||||
|
// 2. 对每一天的记录计算状态
|
||||||
|
for (List<BusAttendance> dailyList : dailyMap.values()) {
|
||||||
|
String clockInStatus = null;
|
||||||
|
String clockOutStatus = null;
|
||||||
|
// 获取上下班状态
|
||||||
|
for (BusAttendance attendance : dailyList) {
|
||||||
|
if (ConstructionUserAttendanceCommuterEnum.CLOCKIN.getValue().equals(attendance.getCommuter())) {
|
||||||
|
clockInStatus = attendance.getClockStatus();
|
||||||
|
} else if (ConstructionUserAttendanceCommuterEnum.CLOCKOUT.getValue().equals(attendance.getCommuter())) {
|
||||||
|
clockOutStatus = attendance.getClockStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 统计考勤状态
|
||||||
|
if (ConstructionUserAttendanceClockStatusEnum.LATE.getValue().equals(clockInStatus)) {
|
||||||
|
lateDays++;
|
||||||
|
}
|
||||||
|
if (ConstructionUserAttendanceClockStatusEnum.LEAVEEARLY.getValue().equals(clockOutStatus)) {
|
||||||
|
leaveEarlyDays++;
|
||||||
|
}
|
||||||
|
if (clockInStatus == null || ConstructionUserAttendanceClockStatusEnum.UNCLOCK.getValue().equals(clockInStatus)) {
|
||||||
|
unClockDays++;
|
||||||
|
}
|
||||||
|
if (clockOutStatus == null || ConstructionUserAttendanceClockStatusEnum.UNCLOCK.getValue().equals(clockOutStatus)) {
|
||||||
|
unClockDays++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attendanceDays = dailyMap.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constructionUserAttendanceTotalResp.setAttendanceDays(attendanceDays);
|
||||||
|
constructionUserAttendanceTotalResp.setLateDays(lateDays);
|
||||||
|
constructionUserAttendanceTotalResp.setLeaveEarlyDays(leaveEarlyDays);
|
||||||
|
constructionUserAttendanceTotalResp.setUnClockDays(unClockDays);
|
||||||
|
// 关联班组信息
|
||||||
|
Long userTeamId = constructionUser.getTeamId();
|
||||||
|
String teamName = null;
|
||||||
|
if (teamIdProjectTeamListMap.containsKey(userTeamId)) {
|
||||||
|
teamName = teamIdProjectTeamListMap.get(userTeamId).get(0).getTeamName();
|
||||||
|
}
|
||||||
|
constructionUserAttendanceTotalResp.setTeamId(userTeamId);
|
||||||
|
constructionUserAttendanceTotalResp.setTeamName(teamName);
|
||||||
|
return constructionUserAttendanceTotalResp;
|
||||||
|
}).toList();
|
||||||
|
constructionUserAttendanceTotalPage.setRecords(userAttendanceTotalList);
|
||||||
|
return constructionUserAttendanceTotalPage;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -450,12 +450,16 @@ CREATE TABLE `bus_attendance`
|
|||||||
`user_name` varchar(32) null comment '人员姓名',
|
`user_name` varchar(32) null comment '人员姓名',
|
||||||
`face_pic` varchar(512) null comment '人脸照',
|
`face_pic` varchar(512) null comment '人脸照',
|
||||||
`project_id` bigint null comment '项目id',
|
`project_id` bigint null comment '项目id',
|
||||||
`on_clock_time` varchar(64) null comment '上班打卡时间',
|
`clock_time` datetime null comment '打卡时间',
|
||||||
`off_clock_time` varchar(64) null comment '下班打卡时间',
|
`clock_date` date null comment '打卡日期',
|
||||||
`clock_status` varchar(20) null comment '1正常,2迟到,3早退,4缺勤,5补卡',
|
`clock_status` varchar(20) null comment '打卡状态(1正常,2迟到,3早退,4缺勤,5补卡)',
|
||||||
`pinch_user_Id` varchar(64) null comment '代打人员id',
|
`pinch_user_id` bigint null comment '代打人员id',
|
||||||
`clock_record` varchar(500) null comment '多次打卡时间记录',
|
`clock_record` varchar(500) null comment '多次打卡时间记录',
|
||||||
`commuter` char(1) null comment '上下班(1上班,2下班)',
|
`commuter` char(1) null comment '上下班(1上班,2下班)',
|
||||||
|
`punch_range` varchar(64) null comment '打卡范围',
|
||||||
|
`daily_wage` decimal(10, 2) null comment '日薪',
|
||||||
|
`lng` varchar(255) null comment '经度',
|
||||||
|
`lat` varchar(255) null comment '纬度',
|
||||||
`remark` varchar(512) null comment '备注',
|
`remark` varchar(512) null comment '备注',
|
||||||
`create_by` varchar(64) null comment '创建者',
|
`create_by` varchar(64) null comment '创建者',
|
||||||
`update_by` varchar(64) null comment '更新者',
|
`update_by` varchar(64) null comment '更新者',
|
||||||
@ -465,7 +469,8 @@ CREATE TABLE `bus_attendance`
|
|||||||
`is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)',
|
`is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '人员id',
|
INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '人员id',
|
||||||
INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id'
|
INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id',
|
||||||
|
INDEX `idx_clock_date` (`clock_date` ASC) USING BTREE comment '打卡日期'
|
||||||
) comment = '考勤表' COLLATE = utf8mb4_unicode_ci;
|
) comment = '考勤表' COLLATE = utf8mb4_unicode_ci;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `bus_work_wage`;
|
DROP TABLE IF EXISTS `bus_work_wage`;
|
||||||
|
Reference in New Issue
Block a user