Explorar el Código

1.无用类删除

2.添加修改考勤历史功能
3.考勤历史 查询日期和状态同时检索失效的bug处理
4.考勤历史添加考勤组查询
5.导出国内模板加班计算规则修改
main
wangqiang hace 4 días
padre
commit
f9d1537407

+ 10
- 13
zs-manager/src/main/java/com/ruoyi/zhushi/controller/DkRecordController.java Ver fichero

@@ -2,6 +2,7 @@ package com.ruoyi.zhushi.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.zhushi.entity.DkCheckInRecordDTO;
@@ -10,10 +11,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
@@ -39,15 +37,6 @@ public class DkRecordController extends BaseController {
return dkRecordService.queryPageList(dkCheckInRecordDTO, pageQuery);
}

/**
* 导出结果列表
*/
@PostMapping("/export")
public void export(DkCheckInRecordDTO bo, HttpServletResponse response) {
List<DkCheckInRecordDTO> list = dkRecordService.queryList(bo);
ExcelUtil.exportExcel(list, "打卡结果", DkCheckInRecordDTO.class, response);
}


/**
* 导出结果列表
@@ -56,4 +45,12 @@ public class DkRecordController extends BaseController {
public void exportNew(DkCheckInRecordDTO bo, HttpServletResponse response) {
dkRecordService.exportNew(bo, response);
}

/**
* 修改打卡记录信息
*/
@PutMapping()
public R<Integer> updateDkRecord(@RequestBody DkCheckInRecordDTO bo) {
return R.ok(dkRecordService.updateDkRecord(bo));
}
}

+ 0
- 94
zs-manager/src/main/java/com/ruoyi/zhushi/entity/AttendanceData.java Ver fichero

@@ -1,94 +0,0 @@
package com.ruoyi.zhushi.entity;

import java.util.List;

public class AttendanceData {

// 模拟的考勤数据,实际可从数据库等获取

private int day;
private String week;
private String actualWorkTimeIn;
private String actualWorkTimeOut;
private String attendanceStatus;
private List<String> leaveStatus;
private double overtimeHours;
private String remark;

public AttendanceData(int day, String week, String actualWorkTimeIn, String actualWorkTimeOut, String attendanceStatus, List<String> leaveStatus, double overtimeHours, String remark) {
this.day = day;
this.week = week;
this.actualWorkTimeIn = actualWorkTimeIn;
this.actualWorkTimeOut = actualWorkTimeOut;
this.attendanceStatus = attendanceStatus;
this.leaveStatus = leaveStatus;
this.overtimeHours = overtimeHours;
this.remark = remark;
}

// getter和setter方法省略

public int getDay() {
return day;
}

public void setDay(int day) {
this.day = day;
}

public String getWeek() {
return week;
}

public void setWeek(String week) {
this.week = week;
}

public String getActualWorkTimeIn() {
return actualWorkTimeIn;
}

public void setActualWorkTimeIn(String actualWorkTimeIn) {
this.actualWorkTimeIn = actualWorkTimeIn;
}

public String getActualWorkTimeOut() {
return actualWorkTimeOut;
}

public void setActualWorkTimeOut(String actualWorkTimeOut) {
this.actualWorkTimeOut = actualWorkTimeOut;
}

public String getAttendanceStatus() {
return attendanceStatus;
}

public void setAttendanceStatus(String attendanceStatus) {
this.attendanceStatus = attendanceStatus;
}

public List<String> getLeaveStatus() {
return leaveStatus;
}

public void setLeaveStatus(List<String> leaveStatus) {
this.leaveStatus = leaveStatus;
}

public double getOvertimeHours() {
return overtimeHours;
}

public void setOvertimeHours(double overtimeHours) {
this.overtimeHours = overtimeHours;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}
}

+ 4
- 3
zs-manager/src/main/java/com/ruoyi/zhushi/entity/DkCheckInRecord.java Ver fichero

@@ -68,15 +68,16 @@ public class DkCheckInRecord extends BaseEntity {
@TableField(value = "`check_in_type`")
private String checkInType;

/** 打卡状态 0正常 1迟到 2缺卡 */
/** 打卡状态 0未打卡 1上班已打卡 2下班已打卡 3 迟到打卡 4 早退打卡 5 更新打卡
* 这个状态会被后面的操作覆盖 比如上班迟到 是 3 但是下班正常 就变成2了 */
@TableField(value = "`check_in_status`")
private String checkInStatus;

/** 上班打卡状态 */
/** 上班打卡状态 0未打卡 1正常打卡 3迟到 */
@TableField(value = "`clock_in_status`")
private String clockInStatus;

/** 下班打卡状态 */
/** 下班打卡状态 0未打卡 2正常打卡 4早退*/
@TableField(value = "`clock_out_status`")
private String clockOutStatus;


+ 2
- 5
zs-manager/src/main/java/com/ruoyi/zhushi/service/DkRecordService.java Ver fichero

@@ -2,11 +2,7 @@ package com.ruoyi.zhushi.service;

import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.bo.ZsOperationWarnresultBo;
import com.ruoyi.system.domain.vo.ZsOperationWarnresultVo;
import com.ruoyi.zhushi.entity.DkCheckInRecord;
import com.ruoyi.zhushi.entity.DkCheckInRecordDTO;
import com.ruoyi.zhushi.entity.ProductRanking;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
@@ -15,8 +11,9 @@ public interface DkRecordService {

TableDataInfo<DkCheckInRecordDTO> queryPageList(DkCheckInRecordDTO dkCheckInRecordDTO, PageQuery pageQuery);

List<DkCheckInRecordDTO> queryList(DkCheckInRecordDTO bo);

void exportNew(DkCheckInRecordDTO dkCheckInRecordDTO, HttpServletResponse response);

int updateDkRecord(DkCheckInRecordDTO dkCheckInRecordDTO);

}

+ 142
- 43
zs-manager/src/main/java/com/ruoyi/zhushi/service/impl/DkRecordServiceImpl.java Ver fichero

@@ -1,8 +1,8 @@
package com.ruoyi.zhushi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
@@ -12,10 +12,10 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.zhushi.entity.*;
import com.ruoyi.zhushi.mapper.DkAttendanceGroupAndUserMapper;
import com.ruoyi.zhushi.mapper.DkAttendanceGroupMapper;
import com.ruoyi.zhushi.mapper.DkRecordMapper;
import com.ruoyi.zhushi.mapper.NjBalanceManageDetailMapper;
import com.ruoyi.zhushi.service.DkRecordService;
import com.ruoyi.zhushi.service.NjBalanceManageDetailService;
import com.ruoyi.zhushi.util.CalendarGenerator;
import com.ruoyi.zhushi.util.Constans;
import com.ruoyi.zhushi.util.TimeUtils;
@@ -34,7 +34,7 @@ import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.*;
@SuppressWarnings("all")
@Service
public class DkRecordServiceImpl implements DkRecordService {
@Autowired
@@ -46,6 +46,9 @@ public class DkRecordServiceImpl implements DkRecordService {
@Autowired
private DkAttendanceGroupAndUserMapper dkAttendanceGroupAndUserMapper;

@Autowired
private DkAttendanceGroupMapper dkAttendanceGroupMapper;

public String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date currentDate = new Date();
@@ -83,48 +86,43 @@ public class DkRecordServiceImpl implements DkRecordService {
queryWrapper.eq(null != dkCheckInRecordDTO.getSysUserName() ,DkCheckInRecord::getSysUserName, dkCheckInRecordDTO.getSysUserName());
queryWrapper.eq(null != dkCheckInRecordDTO.getCheckInTime(), DkCheckInRecord::getCheckInTime, dkCheckInRecordDTO.getCheckInTime());
if (null != dkCheckInRecordDTO.getCheckInStatus()) {
queryWrapper.eq(null != dkCheckInRecordDTO.getCheckInStatus(), DkCheckInRecord::getClockInStatus,
dkCheckInRecordDTO.getCheckInStatus()).or().eq(null != dkCheckInRecordDTO.getCheckInStatus(),
DkCheckInRecord::getClockOutStatus, dkCheckInRecordDTO.getCheckInStatus());
}
//未打卡
if ("0".equals(dkCheckInRecordDTO.getCheckInStatus())) {
queryWrapper.eq( DkCheckInRecord::getClockInStatus,dkCheckInRecordDTO.getCheckInStatus());
queryWrapper.eq( DkCheckInRecord::getClockOutStatus,dkCheckInRecordDTO.getCheckInStatus());
}
//上班打卡 迟到
if ("1".equals(dkCheckInRecordDTO.getCheckInStatus())||"3".equals(dkCheckInRecordDTO.getCheckInStatus())) {
queryWrapper.eq( DkCheckInRecord::getClockInStatus,dkCheckInRecordDTO.getCheckInStatus());
}
//下班打卡 早退
if ("2".equals(dkCheckInRecordDTO.getCheckInStatus())||"4".equals(dkCheckInRecordDTO.getCheckInStatus())) {
queryWrapper.eq( DkCheckInRecord::getClockOutStatus,dkCheckInRecordDTO.getCheckInStatus());
}
//更新打卡
if ("5".equals(dkCheckInRecordDTO.getCheckInStatus())) {

// queryWrapper.eq(null != dkCheckInRecordDTO.getExportRange(), DkCheckInRecord::getExportRange, dkCheckInRecordDTO.getExportRange());
if(dkCheckInRecordDTO.getStrDay() != null){
}
}
//考勤日期 查询
if(StringUtils.isNotBlank(dkCheckInRecordDTO.getStrDay())){
queryWrapper.between(DkCheckInRecord::getCheckInTime, TimeUtils.getStartTime(dkCheckInRecordDTO.getStrDay()),
TimeUtils.getEndTime(dkCheckInRecordDTO.getStrDay()));
}
if(dkCheckInRecordDTO.getStrMonth() != null){
//导出excel 考勤月
if(StringUtils.isNotBlank(dkCheckInRecordDTO.getStrMonth())){
queryWrapper.between(DkCheckInRecord::getCheckInTime, TimeUtils.getFirstDayOfMonth(dkCheckInRecordDTO.getStrMonth()),
TimeUtils.getLastDayOfMonth(dkCheckInRecordDTO.getStrMonth()));
}

//考勤组查询
if (dkCheckInRecordDTO.getAttendanceGroupIds()!=null&&dkCheckInRecordDTO.getAttendanceGroupIds().size()>0) {
queryWrapper.in(DkCheckInRecord::getAttendanceGroupId,dkCheckInRecordDTO.getAttendanceGroupIds());
}
queryWrapper.orderByDesc(DkCheckInRecord::getSysUserName).orderByDesc(DkCheckInRecord::getCheckInTime);

return queryWrapper;
}


/**
* 查询预警结果列表
*/
@Override
public List<DkCheckInRecordDTO> queryList(DkCheckInRecordDTO dkCheckInRecordDTO) {
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO);
List<DkCheckInRecordDTO> dkCheckInRecordDTOS = dkMapper.selectVoList(queryWrapper);
dkCheckInRecordDTOS.forEach(dk -> {
if("0".equals(dk.getCheckInStatus())){
dk.setCheckInStatus("正常");
}
if("1".equals(dk.getCheckInStatus())){
dk.setCheckInStatus("迟到");
}
if("2".equals(dk.getCheckInStatus())){
dk.setCheckInStatus("缺卡");
}
});
return dkCheckInRecordDTOS;
}

/**
* 导出考勤 excel
* @param dkCheckInRecordDTO
@@ -200,6 +198,7 @@ public class DkRecordServiceImpl implements DkRecordService {
if(Constans.GUONEI.equals(dkCheckInRecordDTO.getModelType())){
// 构造导出数据
EmployeeAttendance attendanceData = prepareSampleData(dkCheckInRecordDTO);
//计算总共 迟到 早退次数
if(attendanceData.getChidaocishu() > 0){
latePersonCount ++;
lateCount = lateCount + attendanceData.getChidaocishu();
@@ -212,6 +211,7 @@ public class DkRecordServiceImpl implements DkRecordService {
/* if (attendanceData.getDayRecords().size() == 0){
continue;
}*/
//excel内容构建
fillTemplate(newSheet, attendanceData,dkCheckInRecordDTO.getStrMonth(),user);
}
// 日本模版
@@ -233,6 +233,97 @@ public class DkRecordServiceImpl implements DkRecordService {
}
}

@Override
public int updateDkRecord(DkCheckInRecordDTO dkCheckInRecordDTO) {
AppDTO appDTO = dkAttendanceGroupMapper.queryAttendanceGroupBYUserId(dkCheckInRecordDTO.getSysUserId());












UpdateWrapper<DkCheckInRecord> updateWrapper =new UpdateWrapper();
updateWrapper.eq("id",dkCheckInRecordDTO.getId());
updateWrapper.eq("sys_user_id",dkCheckInRecordDTO.getSysUserId());
//备注
updateWrapper.set("description",dkCheckInRecordDTO.getDescription());
updateWrapper.set("update_time",LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
updateWrapper.set("update_by",LoginHelper.getUsername());

//上班时间
if (dkCheckInRecordDTO.getClockIn()!=null) {
//规定上班时间
String workStartTime = appDTO.getWorkStartTime();
if (isLate(workStartTime,dkCheckInRecordDTO.getClockIn())) {
updateWrapper.set("clock_in_status","3");
updateWrapper.set("check_in_status","3");

} else {
updateWrapper.set("clock_in_status","1");
updateWrapper.set("check_in_status","1");

}

updateWrapper.set("clock_in",dkCheckInRecordDTO.getClockIn());
//考勤时间跟随变化
updateWrapper.set("check_in_time",dkCheckInRecordDTO.getClockIn());

}
//下班时间
if (dkCheckInRecordDTO.getClockOut()!=null) {
//规定下班时间
String workEndTime = appDTO.getWorkEndTime();
if (isEarlyLeave(workEndTime,dkCheckInRecordDTO.getClockOut())) {
updateWrapper.set("clock_out_status","4");
updateWrapper.set("check_in_status","4");
} else {
updateWrapper.set("clock_out_status","2");
updateWrapper.set("check_in_status","2");
}

updateWrapper.set("clock_out",dkCheckInRecordDTO.getClockOut());
//考勤时间跟随变化
updateWrapper.set("check_in_time",dkCheckInRecordDTO.getClockOut());
}
return dkMapper.update(null,updateWrapper);
}
/**
* 判断是否迟到
*
* @param ruleStartTime 规定上班时间(格式:HH:mm,例如 "08:30")
* @param clockIn 实际上班打卡时间
* @return true = 迟到,false = 正常
*/
public static boolean isLate(String ruleStartTime, LocalDateTime clockIn) {
// 解析成 LocalTime
LocalTime startTime = LocalTime.parse(ruleStartTime);
// 获取当天规定的上班时间点
LocalDateTime startDateTime = LocalDateTime.of(clockIn.toLocalDate(), startTime);
// 如果打卡时间在规定上班时间之后,就迟到
return clockIn.isAfter(startDateTime);
}

/**
* 判断是否早退
*
* @param ruleEndTime 规定下班时间(格式:HH:mm,例如 "17:30")
* @param clockOut 实际下班打卡时间
* @return true = 早退,false = 正常
*/
public static boolean isEarlyLeave(String ruleEndTime, LocalDateTime clockOut) {
// 解析成 LocalTime
LocalTime endTime = LocalTime.parse(ruleEndTime);
// 获取当天规定的下班时间点
LocalDateTime endDateTime = LocalDateTime.of(clockOut.toLocalDate(), endTime);
// 如果打卡时间在规定下班时间之前,就早退
return clockOut.isBefore(endDateTime);
}
/*--------------------------------------------------国内汇总信息 --------------------------*/
private void fillTemplateHuiZong(Sheet sheet, int latePersonCount, int earlyPersonCount, int lateCount,
int earlyCount) {
@@ -353,14 +444,14 @@ public class DkRecordServiceImpl implements DkRecordService {
if (dk.getClockIn().isBefore(lunchStartTime1)) {
// 午休之前 打卡时间在规定上班时间后 使用打卡时间 否则使用规定上班时间 计算
Overtime = calculateOvertime(dk.getClockIn().isAfter(workStartTime1)?dk.getClockIn():workStartTime1,
dk.getClockOut(),Double.valueOf(lunchTime));
dk.getClockOut(),Double.valueOf(lunchTime),true);

}else if (dk.getClockIn().isAfter(lunchStartTime1)){
//午休之后 打卡时间计算
Overtime = calculateOvertime(dk.getClockIn(),dk.getClockOut(),0);
Overtime = calculateOvertime(dk.getClockIn(),dk.getClockOut(),0,false);
} else {
//午休中 使用午休结束时间计算
Overtime = calculateOvertime(lunchEndTime1,dk.getClockOut(),0);
Overtime = calculateOvertime(lunchEndTime1,dk.getClockOut(),0,false);
}
//转换时间格式
dayRecord.setXiuxiri(formatOvertime(Overtime));
@@ -372,7 +463,7 @@ public class DkRecordServiceImpl implements DkRecordService {
if(dk.getClockOut() != null){
if(dk.getClockOut().isAfter(workEndTime1)){
// 计算时间差 规定的下班打卡时间 和下班打卡时间差值
double Overtime = calculateOvertime(workEndTime1,dk.getClockOut(),0.5);
double Overtime = calculateOvertime(workEndTime1,dk.getClockOut(),0.5,false);
dayRecord.setGongzuori(formatOvertime(Overtime));
//工作日加班合计
workOverTime = workOverTime.add(new BigDecimal(Overtime));
@@ -637,24 +728,32 @@ public class DkRecordServiceImpl implements DkRecordService {
* 计算加班时间,返回格式为 HH:mm:ss。如果加班时间为0则返回空字符串。
* @param start 开始时间
* @param end 结束时间
* @param baseWorkHours 标准工作时长(比如 9.5)
* @param deductHours 扣除时间(比如 0.5)
* @param isCalculateDeduct 计算扣除时间
* @return 加班时长,格式为 "1:30:00",若无加班则返回 ""
*/
public static double calculateOvertime(LocalDateTime start, LocalDateTime end, double baseWorkHours) {
public static double calculateOvertime(LocalDateTime start, LocalDateTime end, double deductHours,boolean isCalculateDeduct) {
// 计算时间差(分钟)
long minutes = Duration.between(start, end).toMinutes();

// 转换为小时(带小数)
double totalHours = minutes / 60.0;

// 减去标准工时 小时
double overtime = totalHours - baseWorkHours;
//扣除时间
double overtime = totalHours - deductHours;

// 如果没超出,直接返回 0
// 如果加班时间没有超过 deductHours 返回0
if (overtime <= 0) {
return 0d;
}
double floored = Math.floor(overtime * 2) / 2.0;

double floored = 0d;

if (isCalculateDeduct) {
floored = Math.floor(overtime * 2) / 2.0;
} else {
floored = Math.floor(totalHours * 2) / 2.0;
}
return floored;
}
public static String formatOvertime(double Overtime) {

Cargando…
Cancelar
Guardar