Merge remote-tracking branch 'origin/0.8.X' into 0.8.X
This commit is contained in:
@@ -0,0 +1,58 @@
|
|||||||
|
package com.klp.controller;
|
||||||
|
|
||||||
|
import com.klp.common.annotation.Log;
|
||||||
|
import com.klp.common.core.controller.BaseController;
|
||||||
|
import com.klp.common.core.domain.PageQuery;
|
||||||
|
import com.klp.common.core.domain.R;
|
||||||
|
import com.klp.common.core.page.TableDataInfo;
|
||||||
|
import com.klp.common.enums.BusinessType;
|
||||||
|
import com.klp.domain.bo.AttendanceCheckBo;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceCheckBo;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceCheckVo;
|
||||||
|
import com.klp.service.IWmsAttendanceCheckService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/wms/attendanceCheck")
|
||||||
|
public class WmsAttendanceCheckController extends BaseController {
|
||||||
|
|
||||||
|
private final IWmsAttendanceCheckService iWmsAttendanceCheckService;
|
||||||
|
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo<WmsAttendanceCheckVo> list(WmsAttendanceCheckBo bo, PageQuery pageQuery) {
|
||||||
|
return iWmsAttendanceCheckService.queryPageList(bo, pageQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{checkId}")
|
||||||
|
public R<WmsAttendanceCheckVo> getInfo(@PathVariable Long checkId) {
|
||||||
|
return R.ok(iWmsAttendanceCheckService.queryById(checkId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "考勤比对", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{checkIds}")
|
||||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] checkIds) {
|
||||||
|
return toAjax(iWmsAttendanceCheckService.deleteWithValidByIds(Arrays.asList(checkIds), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "考勤比对", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/check")
|
||||||
|
public R<Void> checkAttendance(@Validated @RequestBody AttendanceCheckBo bo) {
|
||||||
|
iWmsAttendanceCheckService.checkAttendance(bo);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package com.klp.controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import com.klp.common.annotation.RepeatSubmit;
|
||||||
|
import com.klp.common.annotation.Log;
|
||||||
|
import com.klp.common.core.controller.BaseController;
|
||||||
|
import com.klp.common.core.domain.PageQuery;
|
||||||
|
import com.klp.common.core.domain.R;
|
||||||
|
import com.klp.common.core.validate.AddGroup;
|
||||||
|
import com.klp.common.core.validate.EditGroup;
|
||||||
|
import com.klp.common.enums.BusinessType;
|
||||||
|
import com.klp.common.utils.poi.ExcelUtil;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceRuleVo;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceRuleBo;
|
||||||
|
import com.klp.service.IWmsAttendanceRuleService;
|
||||||
|
import com.klp.common.core.page.TableDataInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/wms/attendanceRule")
|
||||||
|
public class WmsAttendanceRuleController extends BaseController {
|
||||||
|
|
||||||
|
private final IWmsAttendanceRuleService iWmsAttendanceRuleService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo<WmsAttendanceRuleVo> list(WmsAttendanceRuleBo bo, PageQuery pageQuery) {
|
||||||
|
return iWmsAttendanceRuleService.queryPageList(bo, pageQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出考勤规则(迟到/早退/旷工规则配置)列表
|
||||||
|
*/
|
||||||
|
@Log(title = "考勤规则(迟到/早退/旷工规则配置)", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(WmsAttendanceRuleBo bo, HttpServletResponse response) {
|
||||||
|
List<WmsAttendanceRuleVo> list = iWmsAttendanceRuleService.queryList(bo);
|
||||||
|
ExcelUtil.exportExcel(list, "考勤规则(迟到/早退/旷工规则配置)", WmsAttendanceRuleVo.class, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取考勤规则(迟到/早退/旷工规则配置)详细信息
|
||||||
|
*
|
||||||
|
* @param ruleId 主键
|
||||||
|
*/
|
||||||
|
@GetMapping("/{ruleId}")
|
||||||
|
public R<WmsAttendanceRuleVo> getInfo(@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable Long ruleId) {
|
||||||
|
return R.ok(iWmsAttendanceRuleService.queryById(ruleId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
@Log(title = "考勤规则(迟到/早退/旷工规则配置)", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping()
|
||||||
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsAttendanceRuleBo bo) {
|
||||||
|
return toAjax(iWmsAttendanceRuleService.insertByBo(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
@Log(title = "考勤规则(迟到/早退/旷工规则配置)", businessType = BusinessType.UPDATE)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PutMapping()
|
||||||
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WmsAttendanceRuleBo bo) {
|
||||||
|
return toAjax(iWmsAttendanceRuleService.updateByBo(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*
|
||||||
|
* @param ruleIds 主键串
|
||||||
|
*/
|
||||||
|
@Log(title = "考勤规则(迟到/早退/旷工规则配置)", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ruleIds}")
|
||||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ruleIds) {
|
||||||
|
return toAjax(iWmsAttendanceRuleService.deleteWithValidByIds(Arrays.asList(ruleIds), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -103,8 +103,8 @@ public class WmsAttendanceScheduleController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@Log(title = "生成排班", businessType = BusinessType.INSERT)
|
@Log(title = "生成排班", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/generate")
|
@PostMapping("/generate")
|
||||||
public R<Void> generateSchedule(@Validated @RequestBody GenerateScheduleBo bo) {
|
public R<Void> generateSchedule(@Validated @RequestBody List<GenerateScheduleBo> boList) {
|
||||||
iWmsAttendanceScheduleService.generateSchedule(bo);
|
iWmsAttendanceScheduleService.generateSchedule(boList);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
klp-wms/src/main/java/com/klp/domain/WmsAttendanceCheck.java
Normal file
54
klp-wms/src/main/java/com/klp/domain/WmsAttendanceCheck.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package com.klp.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.klp.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("wms_attendance_check")
|
||||||
|
public class WmsAttendanceCheck extends BaseEntity {
|
||||||
|
|
||||||
|
@TableId
|
||||||
|
private Long checkId;
|
||||||
|
private Long scheduleId;
|
||||||
|
private Long userId;
|
||||||
|
private String employeeName;
|
||||||
|
private Date workDate;
|
||||||
|
private Long shiftId;
|
||||||
|
private String shiftName;
|
||||||
|
private String shiftType;
|
||||||
|
|
||||||
|
private Date p1StartTime;
|
||||||
|
private Date p1EndTime;
|
||||||
|
private Date p1FirstCheck;
|
||||||
|
private Date p1LastCheck;
|
||||||
|
private Integer p1LateMinutes;
|
||||||
|
private Integer p1EarlyMinutes;
|
||||||
|
private String p1Status;
|
||||||
|
private BigDecimal p1Deduct;
|
||||||
|
|
||||||
|
private Date p2StartTime;
|
||||||
|
private Date p2EndTime;
|
||||||
|
private Date p2FirstCheck;
|
||||||
|
private Date p2LastCheck;
|
||||||
|
private Integer p2LateMinutes;
|
||||||
|
private Integer p2EarlyMinutes;
|
||||||
|
private String p2Status;
|
||||||
|
private BigDecimal p2Deduct;
|
||||||
|
|
||||||
|
private String absentType;
|
||||||
|
private Integer continuousAbsentDays;
|
||||||
|
private BigDecimal totalDeduct;
|
||||||
|
private String overallStatus;
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@TableLogic
|
||||||
|
private Integer delFlag;
|
||||||
|
}
|
||||||
66
klp-wms/src/main/java/com/klp/domain/WmsAttendanceRule.java
Normal file
66
klp-wms/src/main/java/com/klp/domain/WmsAttendanceRule.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package com.klp.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.klp.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)对象 wms_attendance_rule
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("wms_attendance_rule")
|
||||||
|
public class WmsAttendanceRule extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID=1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "rule_id")
|
||||||
|
private Long ruleId;
|
||||||
|
/**
|
||||||
|
* 迟到警告阈值(分钟内仅警告,不扣款)
|
||||||
|
*/
|
||||||
|
private Long lateWarn;
|
||||||
|
/**
|
||||||
|
* 迟到一级阈值(分钟)
|
||||||
|
*/
|
||||||
|
private Long lateOne;
|
||||||
|
/**
|
||||||
|
* 迟到二级阈值(分钟)
|
||||||
|
*/
|
||||||
|
private Long lateTwo;
|
||||||
|
/**
|
||||||
|
* 迟到一级扣款(元/次)
|
||||||
|
*/
|
||||||
|
private BigDecimal deductOne;
|
||||||
|
/**
|
||||||
|
* 迟到二级扣款(元/次)
|
||||||
|
*/
|
||||||
|
private BigDecimal deductTwo;
|
||||||
|
/**
|
||||||
|
* 超过多少分钟按旷工半天处理
|
||||||
|
*/
|
||||||
|
private Long absentHalfDay;
|
||||||
|
/**
|
||||||
|
* 连续旷工多少天自动离职
|
||||||
|
*/
|
||||||
|
private Long continuousAbsentDays;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
/**
|
||||||
|
* 删除标记(0正常 1删除)
|
||||||
|
*/
|
||||||
|
@TableLogic
|
||||||
|
private Long delFlag;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.klp.domain.bo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AttendanceCheckBo {
|
||||||
|
|
||||||
|
@NotNull(message = "开始日期不能为空")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date startDate;
|
||||||
|
|
||||||
|
@NotNull(message = "结束日期不能为空")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date endDate;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.klp.domain.bo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WmsAttendanceCheckBo {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
private String employeeName;
|
||||||
|
private Long shiftId;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date startDate;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date endDate;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.klp.domain.bo;
|
||||||
|
|
||||||
|
import com.klp.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)业务对象 wms_attendance_rule
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WmsAttendanceRuleBo extends BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long ruleId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到警告阈值(分钟内仅警告,不扣款)
|
||||||
|
*/
|
||||||
|
private Long lateWarn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到一级阈值(分钟)
|
||||||
|
*/
|
||||||
|
private Long lateOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到二级阈值(分钟)
|
||||||
|
*/
|
||||||
|
private Long lateTwo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到一级扣款(元/次)
|
||||||
|
*/
|
||||||
|
private BigDecimal deductOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到二级扣款(元/次)
|
||||||
|
*/
|
||||||
|
private BigDecimal deductTwo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 超过多少分钟按旷工半天处理
|
||||||
|
*/
|
||||||
|
private Long absentHalfDay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连续旷工多少天自动离职
|
||||||
|
*/
|
||||||
|
private Long continuousAbsentDays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.klp.domain.vo;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class WmsAttendanceCheckVo {
|
||||||
|
|
||||||
|
private Long checkId;
|
||||||
|
private Long scheduleId;
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "员工姓名")
|
||||||
|
private String employeeName;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@ExcelProperty(value = "日期")
|
||||||
|
private Date workDate;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "班次")
|
||||||
|
private String shiftName;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "HH:mm")
|
||||||
|
private Date p1StartTime;
|
||||||
|
@JsonFormat(pattern = "HH:mm")
|
||||||
|
private Date p1EndTime;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
|
||||||
|
private Date p1FirstCheck;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
|
||||||
|
private Date p1LastCheck;
|
||||||
|
@ExcelProperty(value = "上午迟到(分钟)")
|
||||||
|
private Integer p1LateMinutes;
|
||||||
|
@ExcelProperty(value = "上午早退(分钟)")
|
||||||
|
private Integer p1EarlyMinutes;
|
||||||
|
@ExcelProperty(value = "上午状态")
|
||||||
|
private String p1Status;
|
||||||
|
@ExcelProperty(value = "上午扣款")
|
||||||
|
private BigDecimal p1Deduct;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "HH:mm")
|
||||||
|
private Date p2StartTime;
|
||||||
|
@JsonFormat(pattern = "HH:mm")
|
||||||
|
private Date p2EndTime;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
|
||||||
|
private Date p2FirstCheck;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
|
||||||
|
private Date p2LastCheck;
|
||||||
|
@ExcelProperty(value = "下午迟到(分钟)")
|
||||||
|
private Integer p2LateMinutes;
|
||||||
|
@ExcelProperty(value = "下午早退(分钟)")
|
||||||
|
private Integer p2EarlyMinutes;
|
||||||
|
@ExcelProperty(value = "下午状态")
|
||||||
|
private String p2Status;
|
||||||
|
@ExcelProperty(value = "下午扣款")
|
||||||
|
private BigDecimal p2Deduct;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "旷工类型")
|
||||||
|
private String absentType;
|
||||||
|
@ExcelProperty(value = "连续旷工天数")
|
||||||
|
private Integer continuousAbsentDays;
|
||||||
|
@ExcelProperty(value = "总扣款")
|
||||||
|
private BigDecimal totalDeduct;
|
||||||
|
@ExcelProperty(value = "总体状态")
|
||||||
|
private String overallStatus;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.klp.domain.vo;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.klp.common.annotation.ExcelDictFormat;
|
||||||
|
import com.klp.common.convert.ExcelDictConvert;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)视图对象 wms_attendance_rule
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class WmsAttendanceRuleVo {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "主键ID")
|
||||||
|
private Long ruleId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到警告阈值(分钟内仅警告,不扣款)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "迟到警告阈值", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(readConverterExp = "分=钟内仅警告,不扣款")
|
||||||
|
private Long lateWarn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到一级阈值(分钟)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "迟到一级阈值", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(readConverterExp = "分=钟")
|
||||||
|
private Long lateOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到二级阈值(分钟)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "迟到二级阈值", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(readConverterExp = "分=钟")
|
||||||
|
private Long lateTwo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到一级扣款(元/次)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "迟到一级扣款", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(readConverterExp = "元=/次")
|
||||||
|
private BigDecimal deductOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到二级扣款(元/次)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "迟到二级扣款", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(readConverterExp = "元=/次")
|
||||||
|
private BigDecimal deductTwo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 超过多少分钟按旷工半天处理
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "超过多少分钟按旷工半天处理")
|
||||||
|
private Long absentHalfDay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连续旷工多少天自动离职
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "连续旷工多少天自动离职")
|
||||||
|
private Long continuousAbsentDays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -102,6 +102,19 @@ public class WmsAttendanceScheduleVo {
|
|||||||
@ExcelProperty(value = "结束时间")
|
@ExcelProperty(value = "结束时间")
|
||||||
private java.util.Date shiftEndTime;
|
private java.util.Date shiftEndTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班次开始时间2
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "HH:mm")
|
||||||
|
@ExcelProperty(value = "开始时间2")
|
||||||
|
private java.util.Date shiftStartTime2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班次结束时间2
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "HH:mm")
|
||||||
|
@ExcelProperty(value = "结束时间2")
|
||||||
|
private java.util.Date shiftEndTime2;
|
||||||
/**
|
/**
|
||||||
* 工时
|
* 工时
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.klp.mapper;
|
||||||
|
|
||||||
|
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||||
|
import com.klp.domain.WmsAttendanceCheck;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceCheckVo;
|
||||||
|
|
||||||
|
public interface WmsAttendanceCheckMapper extends BaseMapperPlus<WmsAttendanceCheckMapper, WmsAttendanceCheck, WmsAttendanceCheckVo> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.klp.mapper;
|
||||||
|
|
||||||
|
import com.klp.domain.WmsAttendanceRule;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceRuleVo;
|
||||||
|
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)Mapper接口
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
public interface WmsAttendanceRuleMapper extends BaseMapperPlus<WmsAttendanceRuleMapper, WmsAttendanceRule, WmsAttendanceRuleVo> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.klp.service;
|
||||||
|
|
||||||
|
import com.klp.common.core.page.TableDataInfo;
|
||||||
|
import com.klp.common.core.domain.PageQuery;
|
||||||
|
import com.klp.domain.bo.AttendanceCheckBo;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceCheckBo;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceCheckVo;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface IWmsAttendanceCheckService {
|
||||||
|
|
||||||
|
WmsAttendanceCheckVo queryById(Long checkId);
|
||||||
|
|
||||||
|
TableDataInfo<WmsAttendanceCheckVo> queryPageList(WmsAttendanceCheckBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
List<WmsAttendanceCheckVo> queryList(WmsAttendanceCheckBo bo);
|
||||||
|
|
||||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
|
void checkAttendance(AttendanceCheckBo bo);
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.klp.service;
|
||||||
|
|
||||||
|
import com.klp.domain.WmsAttendanceRule;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceRuleVo;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceRuleBo;
|
||||||
|
import com.klp.common.core.page.TableDataInfo;
|
||||||
|
import com.klp.common.core.domain.PageQuery;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)Service接口
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
public interface IWmsAttendanceRuleService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
WmsAttendanceRuleVo queryById(Long ruleId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)列表
|
||||||
|
*/
|
||||||
|
TableDataInfo<WmsAttendanceRuleVo> queryPageList(WmsAttendanceRuleBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)列表
|
||||||
|
*/
|
||||||
|
List<WmsAttendanceRuleVo> queryList(WmsAttendanceRuleBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
Boolean insertByBo(WmsAttendanceRuleBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
Boolean updateByBo(WmsAttendanceRuleBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并批量删除考勤规则(迟到/早退/旷工规则配置)信息
|
||||||
|
*/
|
||||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
}
|
||||||
@@ -51,5 +51,5 @@ public interface IWmsAttendanceScheduleService {
|
|||||||
/**
|
/**
|
||||||
* 生成排班
|
* 生成排班
|
||||||
*/
|
*/
|
||||||
void generateSchedule(GenerateScheduleBo bo);
|
void generateSchedule(List<GenerateScheduleBo> boList);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,398 @@
|
|||||||
|
package com.klp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.klp.common.core.domain.PageQuery;
|
||||||
|
import com.klp.common.core.page.TableDataInfo;
|
||||||
|
import com.klp.common.utils.StringUtils;
|
||||||
|
import com.klp.domain.AttendanceRecords;
|
||||||
|
import com.klp.domain.WmsAttendanceCheck;
|
||||||
|
import com.klp.domain.WmsAttendanceRule;
|
||||||
|
import com.klp.domain.bo.AttendanceCheckBo;
|
||||||
|
import com.klp.domain.bo.AttendanceRecordsBo;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceCheckBo;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceScheduleBo;
|
||||||
|
import com.klp.domain.vo.AttendanceRecordsVo;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceCheckVo;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceScheduleVo;
|
||||||
|
import com.klp.mapper.WmsAttendanceCheckMapper;
|
||||||
|
import com.klp.mapper.WmsAttendanceRuleMapper;
|
||||||
|
import com.klp.service.IAttendanceRecordsService;
|
||||||
|
import com.klp.service.IWmsAttendanceCheckService;
|
||||||
|
import com.klp.service.IWmsAttendanceScheduleService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService {
|
||||||
|
|
||||||
|
private final WmsAttendanceCheckMapper baseMapper;
|
||||||
|
private final IWmsAttendanceScheduleService scheduleService;
|
||||||
|
private final IAttendanceRecordsService attendanceRecordsService;
|
||||||
|
private final WmsAttendanceRuleMapper ruleMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WmsAttendanceCheckVo queryById(Long checkId) {
|
||||||
|
return baseMapper.selectVoById(checkId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableDataInfo<WmsAttendanceCheckVo> queryPageList(WmsAttendanceCheckBo bo, PageQuery pageQuery) {
|
||||||
|
LambdaQueryWrapper<WmsAttendanceCheck> lqw = buildQueryWrapper(bo);
|
||||||
|
Page<WmsAttendanceCheckVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||||
|
return TableDataInfo.build(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<WmsAttendanceCheckVo> queryList(WmsAttendanceCheckBo bo) {
|
||||||
|
LambdaQueryWrapper<WmsAttendanceCheck> lqw = buildQueryWrapper(bo);
|
||||||
|
return baseMapper.selectVoList(lqw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||||
|
return baseMapper.deleteBatchIds(ids) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<WmsAttendanceCheck> buildQueryWrapper(WmsAttendanceCheckBo bo) {
|
||||||
|
LambdaQueryWrapper<WmsAttendanceCheck> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(bo.getUserId() != null, WmsAttendanceCheck::getUserId, bo.getUserId());
|
||||||
|
lqw.like(StringUtils.isNotBlank(bo.getEmployeeName()), WmsAttendanceCheck::getEmployeeName, bo.getEmployeeName());
|
||||||
|
lqw.eq(bo.getShiftId() != null, WmsAttendanceCheck::getShiftId, bo.getShiftId());
|
||||||
|
lqw.ge(bo.getStartDate() != null, WmsAttendanceCheck::getWorkDate, bo.getStartDate());
|
||||||
|
lqw.le(bo.getEndDate() != null, WmsAttendanceCheck::getWorkDate, bo.getEndDate());
|
||||||
|
lqw.orderByDesc(WmsAttendanceCheck::getWorkDate);
|
||||||
|
return lqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void checkAttendance(AttendanceCheckBo bo) {
|
||||||
|
WmsAttendanceScheduleBo scheduleBo = new WmsAttendanceScheduleBo();
|
||||||
|
scheduleBo.setStartDate(bo.getStartDate());
|
||||||
|
scheduleBo.setEndDate(bo.getEndDate());
|
||||||
|
List<WmsAttendanceScheduleVo> schedules = scheduleService.queryList(scheduleBo);
|
||||||
|
|
||||||
|
if (schedules.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WmsAttendanceRule rule = getActiveRule();
|
||||||
|
|
||||||
|
LocalDate startLocal = toLocalDate(bo.getStartDate());
|
||||||
|
LocalDate endLocal = toLocalDate(bo.getEndDate());
|
||||||
|
|
||||||
|
for (WmsAttendanceScheduleVo schedule : schedules) {
|
||||||
|
if (schedule.getEmployeeName() == null || schedule.getShiftStartTime() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取该员工该日期的所有打卡记录
|
||||||
|
List<AttendanceRecords> records = getRecords(schedule.getEmployeeName(), schedule.getWorkDate());
|
||||||
|
|
||||||
|
WmsAttendanceCheck check = buildCheck(schedule, rule, records);
|
||||||
|
|
||||||
|
// 删除已有的比对结果
|
||||||
|
baseMapper.delete(Wrappers.<WmsAttendanceCheck>lambdaQuery()
|
||||||
|
.eq(WmsAttendanceCheck::getScheduleId, schedule.getScheduleId()));
|
||||||
|
|
||||||
|
baseMapper.insert(check);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新连续旷工天数
|
||||||
|
updateContinuousAbsent(startLocal, endLocal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WmsAttendanceRule getActiveRule() {
|
||||||
|
LambdaQueryWrapper<WmsAttendanceRule> wrapper = Wrappers.lambdaQuery();
|
||||||
|
wrapper.eq(WmsAttendanceRule::getDelFlag, 0);
|
||||||
|
wrapper.last("LIMIT 1");
|
||||||
|
WmsAttendanceRule rule = ruleMapper.selectOne(wrapper);
|
||||||
|
if (rule == null) {
|
||||||
|
rule = new WmsAttendanceRule();
|
||||||
|
rule.setLateWarn(3L);
|
||||||
|
rule.setLateOne(5L);
|
||||||
|
rule.setLateTwo(15L);
|
||||||
|
rule.setDeductOne(new BigDecimal("10"));
|
||||||
|
rule.setDeductTwo(new BigDecimal("30"));
|
||||||
|
rule.setAbsentHalfDay(15L);
|
||||||
|
rule.setContinuousAbsentDays(3L);
|
||||||
|
}
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AttendanceRecords> getRecords(String employeeName, Date workDate) {
|
||||||
|
AttendanceRecordsBo recordsBo = new AttendanceRecordsBo();
|
||||||
|
recordsBo.setEname(employeeName);
|
||||||
|
LocalDate ld = toLocalDate(workDate);
|
||||||
|
recordsBo.setChecktimeStart(toDate(ld.atStartOfDay()));
|
||||||
|
recordsBo.setChecktimeEnd(toDate(ld.atTime(LocalTime.of(23, 59, 59))));
|
||||||
|
List<AttendanceRecordsVo> voList = attendanceRecordsService.queryList(recordsBo);
|
||||||
|
return voList.stream()
|
||||||
|
.map(v -> {
|
||||||
|
AttendanceRecords r = new AttendanceRecords();
|
||||||
|
r.setId(v.getId());
|
||||||
|
r.setEname(v.getEname());
|
||||||
|
r.setChecktime(v.getChecktime());
|
||||||
|
return r;
|
||||||
|
})
|
||||||
|
.sorted(Comparator.comparing(AttendanceRecords::getChecktime))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WmsAttendanceCheck buildCheck(WmsAttendanceScheduleVo schedule, WmsAttendanceRule rule, List<AttendanceRecords> records) {
|
||||||
|
WmsAttendanceCheck check = new WmsAttendanceCheck();
|
||||||
|
check.setScheduleId(schedule.getScheduleId());
|
||||||
|
check.setUserId(schedule.getUserId());
|
||||||
|
check.setEmployeeName(schedule.getEmployeeName());
|
||||||
|
check.setWorkDate(schedule.getWorkDate());
|
||||||
|
check.setShiftId(schedule.getShiftId());
|
||||||
|
check.setShiftName(schedule.getShiftName());
|
||||||
|
check.setShiftType(schedule.getShiftType());
|
||||||
|
|
||||||
|
boolean hasPeriod2 = schedule.getShiftStartTime2() != null && schedule.getShiftEndTime2() != null;
|
||||||
|
|
||||||
|
if (records.isEmpty()) {
|
||||||
|
check.setOverallStatus("absent_full");
|
||||||
|
check.setAbsentType("full_day");
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<LocalTime> checkTimes = records.stream()
|
||||||
|
.map(r -> toLocalDateTime(r.getChecktime()).toLocalTime())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (hasPeriod2) {
|
||||||
|
// 正常班次:按时间中点划分上下午
|
||||||
|
LocalTime p1End = toLocalTime(schedule.getShiftEndTime());
|
||||||
|
LocalTime p2Start = toLocalTime(schedule.getShiftStartTime2());
|
||||||
|
LocalTime split = LocalTime.of(
|
||||||
|
(p1End.getHour() + p2Start.getHour()) / 2,
|
||||||
|
(p1End.getMinute() + p2Start.getMinute()) / 2);
|
||||||
|
|
||||||
|
List<LocalTime> period1Times = new ArrayList<>();
|
||||||
|
List<LocalTime> period2Times = new ArrayList<>();
|
||||||
|
for (LocalTime t : checkTimes) {
|
||||||
|
if (t.isBefore(split)) {
|
||||||
|
period1Times.add(t);
|
||||||
|
} else {
|
||||||
|
period2Times.add(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check.setP1StartTime(schedule.getShiftStartTime());
|
||||||
|
check.setP1EndTime(schedule.getShiftEndTime());
|
||||||
|
checkPeriod(check, rule, 1, period1Times, schedule.getShiftStartTime(), schedule.getShiftEndTime(), records);
|
||||||
|
|
||||||
|
check.setP2StartTime(schedule.getShiftStartTime2());
|
||||||
|
check.setP2EndTime(schedule.getShiftEndTime2());
|
||||||
|
checkPeriod(check, rule, 2, period2Times, schedule.getShiftStartTime2(), schedule.getShiftEndTime2(), records);
|
||||||
|
} else {
|
||||||
|
// 倒班:全天一个时段
|
||||||
|
check.setP1StartTime(schedule.getShiftStartTime());
|
||||||
|
check.setP1EndTime(schedule.getShiftEndTime());
|
||||||
|
checkPeriod(check, rule, 1, checkTimes, schedule.getShiftStartTime(), schedule.getShiftEndTime(), records);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 总体判定
|
||||||
|
calculateOverall(check, rule);
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPeriod(WmsAttendanceCheck check, WmsAttendanceRule rule, int period,
|
||||||
|
List<LocalTime> periodTimes, Date expectedStart, Date expectedEnd,
|
||||||
|
List<AttendanceRecords> allRecords) {
|
||||||
|
if (periodTimes.isEmpty()) {
|
||||||
|
if (period == 1) {
|
||||||
|
check.setP1Status("missed");
|
||||||
|
} else {
|
||||||
|
check.setP2Status("missed");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalTime expStart = toLocalTime(expectedStart);
|
||||||
|
LocalTime expEnd = toLocalTime(expectedEnd);
|
||||||
|
LocalTime firstCheck = periodTimes.get(0);
|
||||||
|
LocalTime lastCheck = periodTimes.get(periodTimes.size() - 1);
|
||||||
|
|
||||||
|
int lateMinutes = 0;
|
||||||
|
int earlyMinutes = 0;
|
||||||
|
BigDecimal deduct = BigDecimal.ZERO;
|
||||||
|
String status = "normal";
|
||||||
|
|
||||||
|
// 迟到判定:最早打卡 vs 理论上班时间
|
||||||
|
if (firstCheck.isAfter(expStart)) {
|
||||||
|
lateMinutes = (int) Duration.between(expStart, firstCheck).toMinutes();
|
||||||
|
if (lateMinutes > rule.getAbsentHalfDay()) {
|
||||||
|
status = "absent_half";
|
||||||
|
} else if (lateMinutes > rule.getLateTwo()) {
|
||||||
|
status = "absent_half";
|
||||||
|
} else if (lateMinutes > rule.getLateOne()) {
|
||||||
|
status = "late_two";
|
||||||
|
deduct = deduct.add(rule.getDeductTwo());
|
||||||
|
} else if (lateMinutes > rule.getLateWarn()) {
|
||||||
|
status = "late_one";
|
||||||
|
deduct = deduct.add(rule.getDeductOne());
|
||||||
|
} else {
|
||||||
|
status = "late_warn";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 早退判定:最晚打卡 vs 理论下班时间
|
||||||
|
if (lastCheck.isBefore(expEnd)) {
|
||||||
|
int min = (int) Duration.between(lastCheck, expEnd).toMinutes();
|
||||||
|
if (min > rule.getAbsentHalfDay()) {
|
||||||
|
status = maxSeverity(status, "absent_half");
|
||||||
|
earlyMinutes = min;
|
||||||
|
} else if (min > rule.getLateTwo()) {
|
||||||
|
status = maxSeverity(status, "absent_half");
|
||||||
|
earlyMinutes = min;
|
||||||
|
} else if (min > rule.getLateOne()) {
|
||||||
|
status = maxSeverity(status, "early_2");
|
||||||
|
deduct = deduct.add(rule.getDeductTwo());
|
||||||
|
earlyMinutes = min;
|
||||||
|
} else if (min > rule.getLateWarn()) {
|
||||||
|
status = maxSeverity(status, "early_1");
|
||||||
|
deduct = deduct.add(rule.getDeductOne());
|
||||||
|
earlyMinutes = min;
|
||||||
|
} else {
|
||||||
|
if ("normal".equals(status)) {
|
||||||
|
status = "early_warn";
|
||||||
|
}
|
||||||
|
earlyMinutes = min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找到对应的打卡时间
|
||||||
|
for (AttendanceRecords r : allRecords) {
|
||||||
|
LocalTime ct = toLocalDateTime(r.getChecktime()).toLocalTime();
|
||||||
|
if (ct.equals(firstCheck)) {
|
||||||
|
if (period == 1) check.setP1FirstCheck(r.getChecktime());
|
||||||
|
else check.setP2FirstCheck(r.getChecktime());
|
||||||
|
}
|
||||||
|
if (ct.equals(lastCheck)) {
|
||||||
|
if (period == 1) check.setP1LastCheck(r.getChecktime());
|
||||||
|
else check.setP2LastCheck(r.getChecktime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (period == 1) {
|
||||||
|
check.setP1LateMinutes(lateMinutes);
|
||||||
|
check.setP1EarlyMinutes(earlyMinutes);
|
||||||
|
check.setP1Status(status);
|
||||||
|
check.setP1Deduct(deduct);
|
||||||
|
} else {
|
||||||
|
check.setP2LateMinutes(lateMinutes);
|
||||||
|
check.setP2EarlyMinutes(earlyMinutes);
|
||||||
|
check.setP2Status(status);
|
||||||
|
check.setP2Deduct(deduct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String maxSeverity(String a, String b) {
|
||||||
|
List<String> severity = java.util.Arrays.asList("normal", "late_warn", "early_warn", "late_one", "early_1", "late_two", "early_2", "absent_half");
|
||||||
|
int ai = severity.indexOf(a);
|
||||||
|
int bi = severity.indexOf(b);
|
||||||
|
return severity.get(Math.max(ai, bi));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateOverall(WmsAttendanceCheck check, WmsAttendanceRule rule) {
|
||||||
|
BigDecimal total = BigDecimal.ZERO;
|
||||||
|
boolean hasAbsentHalf = false;
|
||||||
|
|
||||||
|
if (check.getP1Deduct() != null) total = total.add(check.getP1Deduct());
|
||||||
|
if (check.getP2Deduct() != null) total = total.add(check.getP2Deduct());
|
||||||
|
|
||||||
|
check.setTotalDeduct(total);
|
||||||
|
|
||||||
|
if ("absent_half".equals(check.getP1Status()) || "absent_half".equals(check.getP2Status())) {
|
||||||
|
hasAbsentHalf = true;
|
||||||
|
}
|
||||||
|
if ("missed".equals(check.getP1Status()) && check.getP2StartTime() != null && "missed".equals(check.getP2Status())) {
|
||||||
|
check.setAbsentType("full_day");
|
||||||
|
check.setOverallStatus("absent_full");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (check.getP1StartTime() == null && check.getP2StartTime() == null) {
|
||||||
|
check.setAbsentType("full_day");
|
||||||
|
check.setOverallStatus("absent_full");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (hasAbsentHalf) {
|
||||||
|
check.setAbsentType("half_day");
|
||||||
|
check.setOverallStatus("absent_half");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean abnormal = !"normal".equals(check.getP1Status()) || (check.getP2Status() != null && !"normal".equals(check.getP2Status()));
|
||||||
|
check.setOverallStatus(abnormal ? "abnormal" : "normal");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateContinuousAbsent(LocalDate startDate, LocalDate endDate) {
|
||||||
|
List<WmsAttendanceCheck> checks = baseMapper.selectList(Wrappers.<WmsAttendanceCheck>lambdaQuery()
|
||||||
|
.ge(WmsAttendanceCheck::getWorkDate, toDate(startDate.atStartOfDay()))
|
||||||
|
.le(WmsAttendanceCheck::getWorkDate, toDate(endDate.atTime(LocalTime.of(23, 59, 59))))
|
||||||
|
.eq(WmsAttendanceCheck::getDelFlag, 0));
|
||||||
|
|
||||||
|
for (WmsAttendanceCheck check : checks) {
|
||||||
|
if (check.getAbsentType() != null) {
|
||||||
|
int continuous = countContinuousAbsent(check.getUserId(), toLocalDate(check.getWorkDate()));
|
||||||
|
check.setContinuousAbsentDays(continuous);
|
||||||
|
baseMapper.updateById(check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countContinuousAbsent(Long userId, LocalDate workDate) {
|
||||||
|
int count = 0;
|
||||||
|
LocalDate date = workDate.minusDays(1);
|
||||||
|
while (true) {
|
||||||
|
WmsAttendanceCheck prev = baseMapper.selectOne(Wrappers.<WmsAttendanceCheck>lambdaQuery()
|
||||||
|
.eq(WmsAttendanceCheck::getUserId, userId)
|
||||||
|
.eq(WmsAttendanceCheck::getWorkDate, toDate(date.atStartOfDay()))
|
||||||
|
.eq(WmsAttendanceCheck::getDelFlag, 0));
|
||||||
|
if (prev != null && prev.getAbsentType() != null) {
|
||||||
|
count++;
|
||||||
|
date = date.minusDays(1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalDate toLocalDate(Date date) {
|
||||||
|
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalTime toLocalTime(Date date) {
|
||||||
|
if (date == null) return null;
|
||||||
|
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalDateTime toLocalDateTime(Date date) {
|
||||||
|
if (date == null) return null;
|
||||||
|
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Date toDate(LocalDateTime ldt) {
|
||||||
|
return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package com.klp.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import com.klp.common.core.page.TableDataInfo;
|
||||||
|
import com.klp.common.core.domain.PageQuery;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import com.klp.domain.bo.WmsAttendanceRuleBo;
|
||||||
|
import com.klp.domain.vo.WmsAttendanceRuleVo;
|
||||||
|
import com.klp.domain.WmsAttendanceRule;
|
||||||
|
import com.klp.mapper.WmsAttendanceRuleMapper;
|
||||||
|
import com.klp.service.IWmsAttendanceRuleService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤规则(迟到/早退/旷工规则配置)Service业务层处理
|
||||||
|
*
|
||||||
|
* @author klp
|
||||||
|
* @date 2026-05-12
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class WmsAttendanceRuleServiceImpl implements IWmsAttendanceRuleService {
|
||||||
|
|
||||||
|
private final WmsAttendanceRuleMapper baseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public WmsAttendanceRuleVo queryById(Long ruleId){
|
||||||
|
return baseMapper.selectVoById(ruleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TableDataInfo<WmsAttendanceRuleVo> queryPageList(WmsAttendanceRuleBo bo, PageQuery pageQuery) {
|
||||||
|
LambdaQueryWrapper<WmsAttendanceRule> lqw = buildQueryWrapper(bo);
|
||||||
|
Page<WmsAttendanceRuleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||||
|
return TableDataInfo.build(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询考勤规则(迟到/早退/旷工规则配置)列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<WmsAttendanceRuleVo> queryList(WmsAttendanceRuleBo bo) {
|
||||||
|
LambdaQueryWrapper<WmsAttendanceRule> lqw = buildQueryWrapper(bo);
|
||||||
|
return baseMapper.selectVoList(lqw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<WmsAttendanceRule> buildQueryWrapper(WmsAttendanceRuleBo bo) {
|
||||||
|
Map<String, Object> params = bo.getParams();
|
||||||
|
LambdaQueryWrapper<WmsAttendanceRule> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(bo.getLateWarn() != null, WmsAttendanceRule::getLateWarn, bo.getLateWarn());
|
||||||
|
lqw.eq(bo.getLateOne() != null, WmsAttendanceRule::getLateOne, bo.getLateOne());
|
||||||
|
lqw.eq(bo.getLateTwo() != null, WmsAttendanceRule::getLateTwo, bo.getLateTwo());
|
||||||
|
lqw.eq(bo.getDeductOne() != null, WmsAttendanceRule::getDeductOne, bo.getDeductOne());
|
||||||
|
lqw.eq(bo.getDeductTwo() != null, WmsAttendanceRule::getDeductTwo, bo.getDeductTwo());
|
||||||
|
lqw.eq(bo.getAbsentHalfDay() != null, WmsAttendanceRule::getAbsentHalfDay, bo.getAbsentHalfDay());
|
||||||
|
lqw.eq(bo.getContinuousAbsentDays() != null, WmsAttendanceRule::getContinuousAbsentDays, bo.getContinuousAbsentDays());
|
||||||
|
return lqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean insertByBo(WmsAttendanceRuleBo bo) {
|
||||||
|
WmsAttendanceRule add = BeanUtil.toBean(bo, WmsAttendanceRule.class);
|
||||||
|
validEntityBeforeSave(add);
|
||||||
|
boolean flag = baseMapper.insert(add) > 0;
|
||||||
|
if (flag) {
|
||||||
|
bo.setRuleId(add.getRuleId());
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean updateByBo(WmsAttendanceRuleBo bo) {
|
||||||
|
WmsAttendanceRule update = BeanUtil.toBean(bo, WmsAttendanceRule.class);
|
||||||
|
validEntityBeforeSave(update);
|
||||||
|
return baseMapper.updateById(update) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存前的数据校验
|
||||||
|
*/
|
||||||
|
private void validEntityBeforeSave(WmsAttendanceRule entity){
|
||||||
|
//TODO 做一些数据校验,如唯一约束
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除考勤规则(迟到/早退/旷工规则配置)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||||
|
if(isValid){
|
||||||
|
//TODO 做一些业务上的校验,判断是否需要校验
|
||||||
|
}
|
||||||
|
return baseMapper.deleteBatchIds(ids) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,7 +134,8 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void generateSchedule(GenerateScheduleBo bo) {
|
public void generateSchedule(List<GenerateScheduleBo> boList) {
|
||||||
|
for (GenerateScheduleBo bo : boList) {
|
||||||
LocalDate startDate = bo.getStartDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
|
LocalDate startDate = bo.getStartDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
|
||||||
LocalDate endDate = bo.getEndDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
|
LocalDate endDate = bo.getEndDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
|
||||||
|
|
||||||
@@ -150,6 +151,7 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS
|
|||||||
generateShiftSchedule(bo, startDate, endDate);
|
generateShiftSchedule(bo, startDate, endDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成正常排班
|
* 生成正常排班
|
||||||
@@ -228,7 +230,8 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS
|
|||||||
|
|
||||||
// 判断是否为倒班日
|
// 判断是否为倒班日
|
||||||
long cycleDays = rule.getCycleDays() != null ? rule.getCycleDays() : 10;
|
long cycleDays = rule.getCycleDays() != null ? rule.getCycleDays() : 10;
|
||||||
boolean isChangeDay = (daysFromStart + 1) % cycleDays == 0;
|
// boolean isChangeDay = (daysFromStart + 1) % cycleDays == 0;
|
||||||
|
boolean isChangeDay = daysFromStart > 0 && daysFromStart % cycleDays == 0;
|
||||||
|
|
||||||
if (isChangeDay) {
|
if (isChangeDay) {
|
||||||
// 倒班日
|
// 倒班日
|
||||||
@@ -241,24 +244,24 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS
|
|||||||
schedule.setShiftId(rule.getShiftB());
|
schedule.setShiftId(rule.getShiftB());
|
||||||
schedule.setShiftName(shiftB.getShiftName());
|
schedule.setShiftName(shiftB.getShiftName());
|
||||||
}
|
}
|
||||||
// 下一天也使用倒班班次(工作18小时)
|
// // 下一天也使用倒班班次(工作18小时)
|
||||||
LocalDate nextDay = currentDate.plusDays(1);
|
// LocalDate nextDay = currentDate.plusDays(1);
|
||||||
if (!nextDay.isAfter(endDate) && !isScheduleExists(bo.getUserId(), nextDay)) {
|
// if (!nextDay.isAfter(endDate) && !isScheduleExists(bo.getUserId(), nextDay)) {
|
||||||
WmsAttendanceSchedule nextSchedule = new WmsAttendanceSchedule();
|
// WmsAttendanceSchedule nextSchedule = new WmsAttendanceSchedule();
|
||||||
nextSchedule.setUserId(bo.getUserId());
|
// nextSchedule.setUserId(bo.getUserId());
|
||||||
nextSchedule.setWorkDate(java.sql.Date.valueOf(nextDay));
|
// nextSchedule.setWorkDate(java.sql.Date.valueOf(nextDay));
|
||||||
if (changeShiftB != null) {
|
// if (changeShiftB != null) {
|
||||||
nextSchedule.setShiftId(rule.getChangeShiftBId());
|
// nextSchedule.setShiftId(rule.getChangeShiftBId());
|
||||||
nextSchedule.setShiftName(changeShiftB.getShiftName());
|
// nextSchedule.setShiftName(changeShiftB.getShiftName());
|
||||||
} else {
|
// } else {
|
||||||
nextSchedule.setShiftId(rule.getShiftB());
|
// nextSchedule.setShiftId(rule.getShiftB());
|
||||||
nextSchedule.setShiftName(shiftB.getShiftName());
|
// nextSchedule.setShiftName(shiftB.getShiftName());
|
||||||
}
|
// }
|
||||||
schedules.add(nextSchedule);
|
// schedules.add(nextSchedule);
|
||||||
}
|
// }
|
||||||
isCurrentShiftA = false;
|
isCurrentShiftA = false;
|
||||||
currentDate = currentDate.plusDays(1); // 跳过下一天,因为已经处理了
|
// currentDate = currentDate.plusDays(1); // 跳过下一天,因为已经处理了
|
||||||
daysFromStart++;
|
// daysFromStart++;
|
||||||
} else {
|
} else {
|
||||||
// 夜班转白班
|
// 夜班转白班
|
||||||
if (changeShiftA != null) {
|
if (changeShiftA != null) {
|
||||||
@@ -289,8 +292,9 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS
|
|||||||
|
|
||||||
// 批量插入
|
// 批量插入
|
||||||
if (!schedules.isEmpty()) {
|
if (!schedules.isEmpty()) {
|
||||||
for (WmsAttendanceSchedule schedule : schedules) {
|
boolean i = baseMapper.insertBatch(schedules);
|
||||||
baseMapper.insert(schedule);
|
if (!i) {
|
||||||
|
throw new RuntimeException("批量插入倒班排班失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.klp.mapper.WmsAttendanceCheckMapper">
|
||||||
|
|
||||||
|
<resultMap type="com.klp.domain.WmsAttendanceCheck" id="WmsAttendanceCheckResult">
|
||||||
|
<result property="checkId" column="check_id"/>
|
||||||
|
<result property="scheduleId" column="schedule_id"/>
|
||||||
|
<result property="userId" column="user_id"/>
|
||||||
|
<result property="employeeName" column="employee_name"/>
|
||||||
|
<result property="workDate" column="work_date"/>
|
||||||
|
<result property="shiftId" column="shift_id"/>
|
||||||
|
<result property="shiftName" column="shift_name"/>
|
||||||
|
<result property="shiftType" column="shift_type"/>
|
||||||
|
<result property="p1StartTime" column="p1_start_time"/>
|
||||||
|
<result property="p1EndTime" column="p1_end_time"/>
|
||||||
|
<result property="p1FirstCheck" column="p1_first_check"/>
|
||||||
|
<result property="p1LastCheck" column="p1_last_check"/>
|
||||||
|
<result property="p1LateMinutes" column="p1_late_minutes"/>
|
||||||
|
<result property="p1EarlyMinutes" column="p1_early_minutes"/>
|
||||||
|
<result property="p1Status" column="p1_status"/>
|
||||||
|
<result property="p1Deduct" column="p1_deduct"/>
|
||||||
|
<result property="p2StartTime" column="p2_start_time"/>
|
||||||
|
<result property="p2EndTime" column="p2_end_time"/>
|
||||||
|
<result property="p2FirstCheck" column="p2_first_check"/>
|
||||||
|
<result property="p2LastCheck" column="p2_last_check"/>
|
||||||
|
<result property="p2LateMinutes" column="p2_late_minutes"/>
|
||||||
|
<result property="p2EarlyMinutes" column="p2_early_minutes"/>
|
||||||
|
<result property="p2Status" column="p2_status"/>
|
||||||
|
<result property="p2Deduct" column="p2_deduct"/>
|
||||||
|
<result property="absentType" column="absent_type"/>
|
||||||
|
<result property="continuousAbsentDays" column="continuous_absent_days"/>
|
||||||
|
<result property="totalDeduct" column="total_deduct"/>
|
||||||
|
<result property="overallStatus" column="overall_status"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
<result property="delFlag" column="del_flag"/>
|
||||||
|
<result property="createBy" column="create_by"/>
|
||||||
|
<result property="updateBy" column="update_by"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
<result property="updateTime" column="update_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.klp.mapper.WmsAttendanceRuleMapper">
|
||||||
|
|
||||||
|
<resultMap type="com.klp.domain.WmsAttendanceRule" id="WmsAttendanceRuleResult">
|
||||||
|
<result property="ruleId" column="rule_id"/>
|
||||||
|
<result property="lateWarn" column="late_warn"/>
|
||||||
|
<result property="lateOne" column="late_one"/>
|
||||||
|
<result property="lateTwo" column="late_two"/>
|
||||||
|
<result property="deductOne" column="deduct_one"/>
|
||||||
|
<result property="deductTwo" column="deduct_two"/>
|
||||||
|
<result property="absentHalfDay" column="absent_half_day"/>
|
||||||
|
<result property="continuousAbsentDays" column="continuous_absent_days"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
<result property="delFlag" column="del_flag"/>
|
||||||
|
<result property="createBy" column="create_by"/>
|
||||||
|
<result property="updateBy" column="update_by"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
<result property="updateTime" column="update_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -33,13 +33,15 @@
|
|||||||
<result property="shiftType" column="shift_type"/>
|
<result property="shiftType" column="shift_type"/>
|
||||||
<result property="shiftStartTime" column="shift_start_time"/>
|
<result property="shiftStartTime" column="shift_start_time"/>
|
||||||
<result property="shiftEndTime" column="shift_end_time"/>
|
<result property="shiftEndTime" column="shift_end_time"/>
|
||||||
|
<result property="shiftStartTime2" column="shift_start_time2"/>
|
||||||
|
<result property="shiftEndTime2" column="shift_end_time2"/>
|
||||||
<result property="workHours" column="work_hours"/>
|
<result property="workHours" column="work_hours"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectScheduleWithDetailsVo">
|
<sql id="selectScheduleWithDetailsVo">
|
||||||
SELECT s.schedule_id, s.user_id, s.work_date, s.shift_id, s.shift_name, s.shift_group, s.remark,
|
SELECT s.schedule_id, s.user_id, s.work_date, s.shift_id, s.shift_name, s.shift_group, s.remark,
|
||||||
e.name as employee_name, e.dept as employee_dept, e.job_type as employee_job_type,
|
e.name as employee_name, e.dept as employee_dept, e.job_type as employee_job_type,
|
||||||
sh.shift_type, sh.start_time as shift_start_time, sh.end_time as shift_end_time, sh.work_hours
|
sh.shift_type, sh.start_time as shift_start_time, sh.end_time as shift_end_time, sh.start_time2 as shift_start_time2, sh.end_time2 as shift_end_time2, sh.work_hours
|
||||||
FROM wms_attendance_schedule s
|
FROM wms_attendance_schedule s
|
||||||
LEFT JOIN wms_employee_info e ON s.user_id = e.info_id AND e.del_flag = 0
|
LEFT JOIN wms_employee_info e ON s.user_id = e.info_id AND e.del_flag = 0
|
||||||
LEFT JOIN wms_attendance_shift sh ON s.shift_id = sh.shift_id AND sh.del_flag = 0
|
LEFT JOIN wms_attendance_shift sh ON s.shift_id = sh.shift_id AND sh.del_flag = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user