private DkAppService dkAppService; | private DkAppService dkAppService; | ||||
@GetMapping("/queryAttendanceGroupBYUserId") | |||||
@GetMapping("/queryAttendanceGroupByUserId") | |||||
public R<AppDTO> queryAttendanceGroupBYUserId(long userId) { | public R<AppDTO> queryAttendanceGroupBYUserId(long userId) { | ||||
return R.ok(dkAttendanceGroupService.queryAttendanceGroupBYUserId(userId)); | return R.ok(dkAttendanceGroupService.queryAttendanceGroupBYUserId(userId)); | ||||
} | } |
import com.ruoyi.zhushi.service.DkConfigService; | import com.ruoyi.zhushi.service.DkConfigService; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.poi.ss.formula.functions.T; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||
import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||
} | } | ||||
@PostMapping("/add") | @PostMapping("/add") | ||||
public R<Void> add(@RequestBody DkAttendanceGroupDTO dkAttendanceGroupDTO) { | |||||
return toAjax(dkAttendanceGroupService.add(dkAttendanceGroupDTO)); | |||||
public R<String> add(@RequestBody DkAttendanceGroupDTO dkAttendanceGroupDTO) { | |||||
return R.ok(dkAttendanceGroupService.add(dkAttendanceGroupDTO)); | |||||
} | } | ||||
@DeleteMapping("/del/{id}") | @DeleteMapping("/del/{id}") |
@DeleteMapping("/deleteConfig/{id}") | @DeleteMapping("/deleteConfig/{id}") | ||||
public R<Void> remove(@PathVariable Long id) { | |||||
return toAjax(dkConfigService.deleteConfig(id)); | |||||
public R<Integer> remove(@PathVariable Long id) { | |||||
return R.ok(dkConfigService.deleteConfig(id)); | |||||
} | } | ||||
@PutMapping("/updateConfig") | @PutMapping("/updateConfig") |
@Autowired | @Autowired | ||||
private DkRecordService dkService; | |||||
private DkRecordService dkRecordService; | |||||
// 主页面查询 | // 主页面查询 | ||||
@GetMapping("/list") | @GetMapping("/list") | ||||
public TableDataInfo<DkCheckInRecordDTO> list(DkCheckInRecordDTO dkCheckInRecordDTO, PageQuery pageQuery) { | public TableDataInfo<DkCheckInRecordDTO> list(DkCheckInRecordDTO dkCheckInRecordDTO, PageQuery pageQuery) { | ||||
return dkService.queryPageList(dkCheckInRecordDTO, pageQuery); | |||||
return dkRecordService.queryPageList(dkCheckInRecordDTO, pageQuery); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
@PostMapping("/export") | @PostMapping("/export") | ||||
public void export(DkCheckInRecordDTO bo, HttpServletResponse response) { | public void export(DkCheckInRecordDTO bo, HttpServletResponse response) { | ||||
List<DkCheckInRecordDTO> list = dkService.queryList(bo); | |||||
List<DkCheckInRecordDTO> list = dkRecordService.queryList(bo); | |||||
ExcelUtil.exportExcel(list, "打卡结果", DkCheckInRecordDTO.class, response); | ExcelUtil.exportExcel(list, "打卡结果", DkCheckInRecordDTO.class, response); | ||||
} | } | ||||
@PostMapping("/exportNew") | |||||
public void exportNew(DkCheckInRecordDTO bo, HttpServletResponse response) { | |||||
dkRecordService.exportNew(bo, response); | |||||
} | |||||
} | } |
// 是否迟到打卡 | // 是否迟到打卡 | ||||
private String isCheckInLate; | private String isCheckInLate; | ||||
// 上班打卡时间 | |||||
private String clockIn; | |||||
// 下班打卡时间 | |||||
private String clockOut; | |||||
// 打卡类型 | |||||
private String checkInType; | |||||
private int month; | |||||
private String week; | |||||
private int day; | |||||
} | } |
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; | |||||
} | |||||
} |
package com.ruoyi.zhushi.entity; | |||||
import lombok.Data; | |||||
@Data | |||||
public class DayRecord { | |||||
private int day; | |||||
private String weekday; | |||||
private String startTime; | |||||
private String endTime; | |||||
// 迟到 | |||||
private String chidao; | |||||
// 异常 | |||||
private String yichang; | |||||
// 休息 | |||||
private String xiuxi; | |||||
// 调休 | |||||
private String tiaoxiu; | |||||
// 值班 | |||||
private String zhiban; | |||||
// 请假 | |||||
private String qingjia; | |||||
// 年假 | |||||
private String nianjia; | |||||
// 加班 | |||||
private String jiaban; | |||||
// 合计 | |||||
private String heji; | |||||
// 备注 | |||||
private String remark; | |||||
// 工作日 | |||||
private String gongzuori; | |||||
// 休息日 | |||||
private String xiuxiri; | |||||
// 节假日 | |||||
private String fadingjiari; | |||||
} |
@TableName("dk_check_in_attendance_team") | @TableName("dk_check_in_attendance_team") | ||||
public class DkAttendanceGroup extends BaseEntity { | public class DkAttendanceGroup extends BaseEntity { | ||||
@TableId(value = "id", type = IdType.AUTO) | @TableId(value = "id", type = IdType.AUTO) | ||||
private int id; | |||||
private long id; | |||||
@TableField(value = "`name`") | @TableField(value = "`name`") | ||||
private String name; | private String name; | ||||
private Integer earlyRange; | private Integer earlyRange; | ||||
@TableField(value = "area_id") | @TableField(value = "area_id") | ||||
private int areaId; | |||||
private long areaId; | |||||
} | } |
private String id; | private String id; | ||||
@TableField(value = "`sys_user_id`") | @TableField(value = "`sys_user_id`") | ||||
private long sysUserId; | |||||
private Long sysUserId; | |||||
@TableField(value = "`sys_user_name`") | @TableField(value = "`sys_user_name`") | ||||
private String sysUserName; | private String sysUserName; | ||||
@TableField(value = "`check_in_type`") | @TableField(value = "`check_in_type`") | ||||
private String checkInType; | private String checkInType; | ||||
// 上班打卡时间 | |||||
@TableField(value = "`clock_in`") | |||||
private LocalDateTime clockIn; | |||||
// 下班打卡时间 | |||||
@TableField(value = "`clock_out`") | |||||
private LocalDateTime clockOut; | |||||
@TableField(value = "`month`") | |||||
private int month; | |||||
@TableField(value = "`week`") | |||||
private String week; | |||||
@TableField(value = "`day`") | |||||
private int day; | |||||
} | } |
import com.ruoyi.common.core.domain.BaseEntity; | import com.ruoyi.common.core.domain.BaseEntity; | ||||
import lombok.Data; | import lombok.Data; | ||||
import java.time.LocalDate; | |||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
@Data | @Data | ||||
@TableField(value = "`sys_user_id`") | @TableField(value = "`sys_user_id`") | ||||
// @ExcelProperty(value = "用户id") | // @ExcelProperty(value = "用户id") | ||||
private String sysUserId; | |||||
private Long sysUserId; | |||||
@TableField(value = "`sys_user_name`") | @TableField(value = "`sys_user_name`") | ||||
@ExcelProperty(value = "用户姓名") | @ExcelProperty(value = "用户姓名") | ||||
private String exportRange; | private String exportRange; | ||||
private String strDay; | |||||
private String strMonth; | |||||
private LocalDateTime clockIn; | |||||
private LocalDateTime clockOut; | |||||
private String description; | |||||
private int month; | |||||
private String week; | |||||
private int day; | |||||
} | } |
package com.ruoyi.zhushi.entity; | |||||
import java.util.List; | |||||
public class EmployeeAttendance { | |||||
private String employeeName; | |||||
private String department; | |||||
private String dateTime; | |||||
private int year; | |||||
private int month; | |||||
private List<DayRecord> dayRecords; | |||||
// getters and setters | |||||
public String getEmployeeName() { | |||||
return employeeName; | |||||
} | |||||
public void setEmployeeName(String employeeName) { | |||||
this.employeeName = employeeName; | |||||
} | |||||
public String getDepartment() { | |||||
return department; | |||||
} | |||||
public void setDepartment(String department) { | |||||
this.department = department; | |||||
} | |||||
public String getDateTime() { | |||||
return dateTime; | |||||
} | |||||
public void setDateTime(String dateTime) { | |||||
this.dateTime = dateTime; | |||||
} | |||||
public int getYear() { | |||||
return year; | |||||
} | |||||
public void setYear(int year) { | |||||
this.year = year; | |||||
} | |||||
public int getMonth() { | |||||
return month; | |||||
} | |||||
public void setMonth(int month) { | |||||
this.month = month; | |||||
} | |||||
public List<DayRecord> getDayRecords() { | |||||
return dayRecords; | |||||
} | |||||
public void setDayRecords(List<DayRecord> dayRecords) { | |||||
this.dayRecords = dayRecords; | |||||
} | |||||
} |
package com.ruoyi.zhushi.mapper; | package com.ruoyi.zhushi.mapper; | ||||
import com.ruoyi.common.core.mapper.BaseMapperPlus; | import com.ruoyi.common.core.mapper.BaseMapperPlus; | ||||
import com.ruoyi.zhushi.entity.DkAttendanceGroup; | |||||
import com.ruoyi.zhushi.entity.DkCheckInRecord; | import com.ruoyi.zhushi.entity.DkCheckInRecord; | ||||
import com.ruoyi.zhushi.entity.DkCheckInRecordDTO; | import com.ruoyi.zhushi.entity.DkCheckInRecordDTO; | ||||
import org.apache.ibatis.annotations.Mapper; | import org.apache.ibatis.annotations.Mapper; | ||||
public List<DkCheckInRecord> getCurrentDayRecord(@Param("userId") long userId); | public List<DkCheckInRecord> getCurrentDayRecord(@Param("userId") long userId); | ||||
public List<DkCheckInRecord> queryCurrentDayOutRecord(@Param("userId") long userId); | |||||
DkAttendanceGroup queryConfigByUserId(@Param("userId") long userId); | |||||
} | } |
TableDataInfo<DkAttendanceGroupDTO> queryPageList(DkAttendanceGroupDTO dkAttendanceGroupDTO); | TableDataInfo<DkAttendanceGroupDTO> queryPageList(DkAttendanceGroupDTO dkAttendanceGroupDTO); | ||||
public int add(DkAttendanceGroupDTO dkAttendanceGroupDTO); | |||||
public String add(DkAttendanceGroupDTO dkAttendanceGroupDTO); | |||||
public int del(long id); | public int del(long id); | ||||
import com.ruoyi.zhushi.entity.DkCheckInRecordDTO; | import com.ruoyi.zhushi.entity.DkCheckInRecordDTO; | ||||
import com.ruoyi.zhushi.entity.ProductRanking; | import com.ruoyi.zhushi.entity.ProductRanking; | ||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.util.List; | import java.util.List; | ||||
public interface DkRecordService { | public interface DkRecordService { | ||||
List<DkCheckInRecordDTO> queryList(DkCheckInRecordDTO bo); | List<DkCheckInRecordDTO> queryList(DkCheckInRecordDTO bo); | ||||
void exportNew(DkCheckInRecordDTO dkCheckInRecordDTO, HttpServletResponse response); | |||||
} | } |
package com.ruoyi.zhushi.service.impl; | package com.ruoyi.zhushi.service.impl; | ||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.ruoyi.zhushi.entity.AppDTO; | import com.ruoyi.zhushi.entity.AppDTO; | ||||
import com.ruoyi.zhushi.entity.DkCheckInRecord; | import com.ruoyi.zhushi.entity.DkCheckInRecord; | ||||
import com.ruoyi.zhushi.entity.DkCheckInRecordDTO; | |||||
import com.ruoyi.zhushi.mapper.DkAttendanceGroupMapper; | import com.ruoyi.zhushi.mapper.DkAttendanceGroupMapper; | ||||
import com.ruoyi.zhushi.mapper.DkRecordMapper; | import com.ruoyi.zhushi.mapper.DkRecordMapper; | ||||
import com.ruoyi.zhushi.service.DkAppService; | import com.ruoyi.zhushi.service.DkAppService; | ||||
import com.ruoyi.zhushi.util.GeoDistanceUtil; | import com.ruoyi.zhushi.util.GeoDistanceUtil; | ||||
import com.ruoyi.zhushi.util.TimeUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import java.time.Duration; | import java.time.Duration; | ||||
import java.time.LocalDateTime; | |||||
import java.time.LocalTime; | import java.time.LocalTime; | ||||
import java.time.format.DateTimeFormatter; | import java.time.format.DateTimeFormatter; | ||||
import java.time.format.DateTimeParseException; | import java.time.format.DateTimeParseException; | ||||
} | } | ||||
// 根据经纬度计算两点之间的距离 | // 根据经纬度计算两点之间的距离 | ||||
double distanceKm = GeoDistanceUtil.getDistanceKm(appDTO.getLat(), appDTO.getLng(), appDTO1.getLat(), appDTO1.getLng()); | |||||
if (distanceKm > appDTO.getRadius()) { | |||||
return "超出范围"; | |||||
} | |||||
// double distanceKm = GeoDistanceUtil.getDistanceKm(appDTO.getLat(), appDTO.getLng(), appDTO1.getLat(), appDTO1.getLng()); | |||||
// if (distanceKm > appDTO.getRadius()) { | |||||
// return "超出打卡范围"; | |||||
// } | |||||
// 解析给定的时分秒(格式:HH:mm:ss 或 HH:mm) | // 解析给定的时分秒(格式:HH:mm:ss 或 HH:mm) | ||||
boolean result = canSignIn(workStartTime); | boolean result = canSignIn(workStartTime); | ||||
DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | ||||
// true的时候可以签到,false的时候进行是否可以迟到签到 | |||||
if(!result){ | if(!result){ | ||||
boolean b = allowCheckIn(workStartTime, appDTO.getLateRange()); | |||||
if(!b){ | |||||
// 允许迟到打卡 | |||||
if(appDTO1.getAllowLate()){ | |||||
// 根据允许的范围进行是否可以打卡判断 | |||||
boolean b = allowCheckIn(workStartTime, appDTO.getLateRange()); | |||||
// true 表示在可以迟到的时间内,进行正常打卡 | |||||
if(!b){ | |||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | |||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("2"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insert(dkCheckInRecord); | |||||
return "迟到打卡"; | |||||
} | |||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | dkCheckInRecord.setSysUserId(appDTO.getUserId()); | ||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | dkCheckInRecord.setSysUserName(appDTO.getUserName()); | ||||
dkCheckInRecord.setCheckInTime(LocalDateTime.now()); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("1"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insert(dkCheckInRecord); | |||||
return "打卡成功"; | |||||
}else{ | |||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | |||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("2"); | dkCheckInRecord.setCheckInStatus("2"); | ||||
dkCheckInRecord.setCheckInType("startCheckIn"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insert(dkCheckInRecord); | dkRecordMapper.insert(dkCheckInRecord); | ||||
return "迟到打卡"; | return "迟到打卡"; | ||||
} | } | ||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | |||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | |||||
dkCheckInRecord.setCheckInTime(LocalDateTime.now()); | |||||
dkCheckInRecord.setCheckInStatus("1"); | |||||
dkCheckInRecord.setCheckInType("startCheckIn"); | |||||
dkRecordMapper.insert(dkCheckInRecord); | |||||
return "打卡成功"; | |||||
} | } | ||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | dkCheckInRecord.setSysUserId(appDTO.getUserId()); | ||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | dkCheckInRecord.setSysUserName(appDTO.getUserName()); | ||||
dkCheckInRecord.setCheckInTime(LocalDateTime.now()); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockIn())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("1"); | dkCheckInRecord.setCheckInStatus("1"); | ||||
dkCheckInRecord.setCheckInType("startCheckIn"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insert(dkCheckInRecord); | dkRecordMapper.insert(dkCheckInRecord); | ||||
return "打卡成功"; | return "打卡成功"; | ||||
} | } | ||||
public String checkOut(AppDTO appDTO) { | public String checkOut(AppDTO appDTO) { | ||||
AppDTO appDTO1 = dkAttendanceGroupMapper.queryAttendanceGroupBYUserId(appDTO.getUserId()); | AppDTO appDTO1 = dkAttendanceGroupMapper.queryAttendanceGroupBYUserId(appDTO.getUserId()); | ||||
// 根据经纬度计算两点之间的距离 | // 根据经纬度计算两点之间的距离 | ||||
double distanceKm = GeoDistanceUtil.getDistanceKm(appDTO.getLat(), appDTO.getLng(), appDTO1.getLat(), appDTO1.getLng()); | |||||
if (distanceKm > appDTO.getRadius()){ | |||||
return "超出范围"; | |||||
} | |||||
// double distanceKm = GeoDistanceUtil.getDistanceKm(appDTO.getLat(), appDTO.getLng(), appDTO1.getLat(), appDTO1.getLng()); | |||||
// if (distanceKm > appDTO.getRadius()){ | |||||
// return "超出范围"; | |||||
// } | |||||
// 打卡开始时间 | // 打卡开始时间 | ||||
String workEndTime = appDTO1.getWorkEndTime(); | String workEndTime = appDTO1.getWorkEndTime(); | ||||
if(workEndTime == null){ | if(workEndTime == null){ | ||||
return "系统设置错误"; | return "系统设置错误"; | ||||
} | } | ||||
// 获取当前天的下班打卡记录 | |||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = new LambdaQueryWrapper<>(); | |||||
queryWrapper.eq(DkCheckInRecord::getSysUserId, appDTO.getUserId()); | |||||
queryWrapper.eq(DkCheckInRecord::getCheckInType, "clockOut"); | |||||
queryWrapper.orderByDesc(DkCheckInRecord::getCheckInTime); | |||||
List<DkCheckInRecord> dkCheckInRecords = dkRecordMapper.selectList(queryWrapper); | |||||
if(dkCheckInRecords.size() > 0){ | |||||
DkCheckInRecord dkCheckInRecord = dkCheckInRecords.get(0); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setClockOut(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("5"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insertOrUpdate(dkCheckInRecord); | |||||
return "更新打卡成功"; | |||||
} | |||||
// 解析给定的时分秒(格式:HH:mm:ss 或 HH:mm) | // 解析给定的时分秒(格式:HH:mm:ss 或 HH:mm) | ||||
boolean result = canSignIn(workEndTime); | boolean result = canSignIn(workEndTime); | ||||
// true的时候为提前打卡,false的时候正常打卡 | |||||
if(result){ | if(result){ | ||||
// 判断是否允许提前打卡 | |||||
if(appDTO1.getAllowEarly()){ | if(appDTO1.getAllowEarly()){ | ||||
// 根据允许的范围进行是否可以打卡判断 true 在允许的范围内, false 不在允许的范围内 | |||||
boolean b = allowCheckIn(workEndTime, appDTO.getEarlyRange()); | boolean b = allowCheckIn(workEndTime, appDTO.getEarlyRange()); | ||||
if(!b){ | if(!b){ | ||||
return "不允许超出提前打卡范围"; | |||||
DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | |||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | |||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setClockOut(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("4"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insertOrUpdate(dkCheckInRecord); | |||||
return "提前打卡"; | |||||
} | } | ||||
// 签到成功 | // 签到成功 | ||||
DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | ||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | dkCheckInRecord.setSysUserId(appDTO.getUserId()); | ||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | dkCheckInRecord.setSysUserName(appDTO.getUserName()); | ||||
dkCheckInRecord.setCheckInTime(LocalDateTime.now()); | |||||
dkCheckInRecord.setCheckInStatus("0"); | |||||
dkCheckInRecord.setCheckInType("endCheckIn"); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setClockOut(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("1"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insertOrUpdate(dkCheckInRecord); | dkRecordMapper.insertOrUpdate(dkCheckInRecord); | ||||
return "打卡成功"; | return "打卡成功"; | ||||
} | } | ||||
DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | ||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | dkCheckInRecord.setSysUserId(appDTO.getUserId()); | ||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | dkCheckInRecord.setSysUserName(appDTO.getUserName()); | ||||
dkCheckInRecord.setCheckInTime(LocalDateTime.now()); | |||||
dkCheckInRecord.setCheckInStatus("0"); | |||||
dkCheckInRecord.setCheckInType("endCheckIn"); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setClockOut(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("4"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insertOrUpdate(dkCheckInRecord); | dkRecordMapper.insertOrUpdate(dkCheckInRecord); | ||||
return "提前打卡"; | return "提前打卡"; | ||||
}else{ | }else{ | ||||
DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | DkCheckInRecord dkCheckInRecord = new DkCheckInRecord(); | ||||
dkCheckInRecord.setSysUserId(appDTO.getUserId()); | dkCheckInRecord.setSysUserId(appDTO.getUserId()); | ||||
dkCheckInRecord.setSysUserName(appDTO.getUserName()); | dkCheckInRecord.setSysUserName(appDTO.getUserName()); | ||||
dkCheckInRecord.setCheckInTime(LocalDateTime.now()); | |||||
dkCheckInRecord.setCheckInStatus("0"); | |||||
dkCheckInRecord.setCheckInType("endCheckIn"); | |||||
dkCheckInRecord.setCheckInTime(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setClockOut(TimeUtils.parseStr2LocalDateTime(appDTO.getClockOut())); | |||||
dkCheckInRecord.setCheckInType(appDTO.getCheckInType()); | |||||
dkCheckInRecord.setCheckInStatus("1"); | |||||
dkCheckInRecord.setMonth(appDTO.getMonth()); | |||||
dkCheckInRecord.setWeek(appDTO.getWeek()); | |||||
dkCheckInRecord.setDay(appDTO.getDay()); | |||||
dkRecordMapper.insertOrUpdate(dkCheckInRecord); | dkRecordMapper.insertOrUpdate(dkCheckInRecord); | ||||
return "打卡成功"; | return "打卡成功"; | ||||
} | } |
import com.ruoyi.zhushi.mapper.DkAttendanceGroupAndUserMapper; | import com.ruoyi.zhushi.mapper.DkAttendanceGroupAndUserMapper; | ||||
import com.ruoyi.zhushi.mapper.DkAttendanceGroupMapper; | import com.ruoyi.zhushi.mapper.DkAttendanceGroupMapper; | ||||
import com.ruoyi.zhushi.service.DkAttendanceGroupService; | import com.ruoyi.zhushi.service.DkAttendanceGroupService; | ||||
import com.ruoyi.zhushi.util.Constans; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
} | } | ||||
@Override | @Override | ||||
public int add(DkAttendanceGroupDTO dkAttendanceGroupDTO) { | |||||
LambdaQueryWrapper<DkAttendanceGroupAndUser> queryWrapper = Wrappers.lambdaQuery(); | |||||
StringBuffer stringBuffer = new StringBuffer(); | |||||
public String add(DkAttendanceGroupDTO dkAttendanceGroupDTO) { | |||||
StringBuffer stringBuffer = new StringBuffer(); | |||||
List<DkAttendanceGroupAndUser> members = new ArrayList<>(); | |||||
dkAttendanceGroupDTO.getMembers().forEach(e -> { | dkAttendanceGroupDTO.getMembers().forEach(e -> { | ||||
LambdaQueryWrapper<DkAttendanceGroupAndUser> queryWrapper = Wrappers.lambdaQuery(); | |||||
queryWrapper.eq(DkAttendanceGroupAndUser::getUserId, e.getUserId()); | queryWrapper.eq(DkAttendanceGroupAndUser::getUserId, e.getUserId()); | ||||
List<DkAttendanceGroupAndUser> dkAttendanceGroupAndUsers = dkAttendanceGroupAndUserMapper.selectList(queryWrapper); | List<DkAttendanceGroupAndUser> dkAttendanceGroupAndUsers = dkAttendanceGroupAndUserMapper.selectList(queryWrapper); | ||||
if(dkAttendanceGroupAndUsers.size() > 0){ | if(dkAttendanceGroupAndUsers.size() > 0){ | ||||
stringBuffer.append(e.getUserName()+"已加入团队,"); | |||||
if(dkAttendanceGroupAndUsers.get(0).getAttendanceTeamId() != dkAttendanceGroupDTO.getId()){ | |||||
stringBuffer.append(e.getUserName() + "已加入" + dkAttendanceGroupAndUsers.get(0).getDeptName()); | |||||
stringBuffer.append(StringUtils.repeat(" ", 5)); // 添加10个空格 | |||||
} | |||||
}else{ | |||||
members.add(e); | |||||
} | } | ||||
}); | }); | ||||
if(stringBuffer.length() > 0){ | |||||
throw new RuntimeException(stringBuffer.toString()); | |||||
} | |||||
// if(stringBuffer.length() > 0){ | |||||
// throw new RuntimeException(stringBuffer.toString()); | |||||
// } | |||||
DkAttendanceGroup dkAttendanceGroup = BeanUtil.toBean(dkAttendanceGroupDTO, DkAttendanceGroup.class); | DkAttendanceGroup dkAttendanceGroup = BeanUtil.toBean(dkAttendanceGroupDTO, DkAttendanceGroup.class); | ||||
dkAttendanceGroupMapper.insertOrUpdate(dkAttendanceGroup); | dkAttendanceGroupMapper.insertOrUpdate(dkAttendanceGroup); | ||||
if(dkAttendanceGroupDTO.getMembers() != null && dkAttendanceGroupDTO.getMembers().size() > 0){ | |||||
dkAttendanceGroupDTO.getMembers().forEach(e -> { | |||||
if(members.size() > 0){ | |||||
members.forEach(e -> { | |||||
DkAttendanceGroupAndUser dkAttendanceGroupAndUser = new DkAttendanceGroupAndUser(); | DkAttendanceGroupAndUser dkAttendanceGroupAndUser = new DkAttendanceGroupAndUser(); | ||||
dkAttendanceGroupAndUser.setAttendanceTeamId(dkAttendanceGroup.getId()); | dkAttendanceGroupAndUser.setAttendanceTeamId(dkAttendanceGroup.getId()); | ||||
dkAttendanceGroupAndUser.setUserId(e.getUserId()); | dkAttendanceGroupAndUser.setUserId(e.getUserId()); | ||||
dkAttendanceGroupAndUserMapper.insertOrUpdate(dkAttendanceGroupAndUser); | dkAttendanceGroupAndUserMapper.insertOrUpdate(dkAttendanceGroupAndUser); | ||||
}); | }); | ||||
} | } | ||||
return dkAttendanceGroup.getId(); | |||||
if(stringBuffer.length() > 0){ | |||||
return stringBuffer.toString(); | |||||
}else { | |||||
return Constans.SUCCESS; | |||||
} | |||||
} | } | ||||
@Override | @Override |
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.ruoyi.zhushi.entity.*; | import com.ruoyi.zhushi.entity.*; | ||||
import com.ruoyi.zhushi.mapper.DkAttendanceGroupMapper; | |||||
import com.ruoyi.zhushi.mapper.DkConfigMapper; | import com.ruoyi.zhushi.mapper.DkConfigMapper; | ||||
import com.ruoyi.zhushi.service.DkConfigService; | import com.ruoyi.zhushi.service.DkConfigService; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
@Autowired | @Autowired | ||||
private DkConfigMapper dkConfigMapper; | private DkConfigMapper dkConfigMapper; | ||||
@Autowired | |||||
private DkAttendanceGroupMapper dkAttendanceGroupMapper; | |||||
@Override | @Override | ||||
public List<DkCheckInConfigDTO> queryList(DkCheckInConfigDTO dto) { | public List<DkCheckInConfigDTO> queryList(DkCheckInConfigDTO dto) { | ||||
@Override | @Override | ||||
public int deleteConfig(long id) { | public int deleteConfig(long id) { | ||||
// 根据id查询配置是否被使用,如果被使用则不允许删除 | |||||
List<DkAttendanceGroup> dkAttendanceGroups = dkAttendanceGroupMapper.selectList(new LambdaQueryWrapper<DkAttendanceGroup>().eq(DkAttendanceGroup::getAreaId, id)); | |||||
if(dkAttendanceGroups.size() > 0){ | |||||
return -1; | |||||
} | |||||
return dkConfigMapper.deleteById(id); | return dkConfigMapper.deleteById(id); | ||||
} | } | ||||
package com.ruoyi.zhushi.service.impl; | 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.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | 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.ruoyi.common.core.domain.PageQuery; | import com.ruoyi.common.core.domain.PageQuery; | ||||
import com.ruoyi.common.core.page.TableDataInfo; | import com.ruoyi.common.core.page.TableDataInfo; | ||||
import com.ruoyi.zhushi.entity.DkCheckInRecord; | |||||
import com.ruoyi.zhushi.entity.DkCheckInRecordDTO; | |||||
import com.ruoyi.zhushi.entity.*; | |||||
import com.ruoyi.zhushi.mapper.DkConfigMapper; | |||||
import com.ruoyi.zhushi.mapper.DkRecordMapper; | import com.ruoyi.zhushi.mapper.DkRecordMapper; | ||||
import com.ruoyi.zhushi.service.DkRecordService; | import com.ruoyi.zhushi.service.DkRecordService; | ||||
import com.ruoyi.zhushi.util.Constans; | |||||
import com.ruoyi.zhushi.util.TimeUtils; | import com.ruoyi.zhushi.util.TimeUtils; | ||||
import okhttp3.OkHttpClient; | |||||
import okhttp3.Request; | |||||
import okhttp3.Response; | |||||
import org.apache.poi.ss.usermodel.*; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.io.FileInputStream; | |||||
import java.io.FileOutputStream; | |||||
import java.io.IOException; | |||||
import java.math.BigDecimal; | |||||
import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
import java.time.Duration; | |||||
import java.time.LocalDate; | import java.time.LocalDate; | ||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.time.LocalTime; | import java.time.LocalTime; | ||||
import java.time.format.DateTimeFormatter; | |||||
import java.util.ArrayList; | |||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.List; | import java.util.List; | ||||
@Autowired | @Autowired | ||||
private DkRecordMapper dkMapper; | private DkRecordMapper dkMapper; | ||||
@Autowired | |||||
private DkConfigMapper configMapper; | |||||
public String getTime() { | public String getTime() { | ||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||||
@Override | @Override | ||||
public TableDataInfo<DkCheckInRecordDTO> queryPageList(DkCheckInRecordDTO dkCheckInRecordDTO, PageQuery pageQuery) { | public TableDataInfo<DkCheckInRecordDTO> queryPageList(DkCheckInRecordDTO dkCheckInRecordDTO, PageQuery pageQuery) { | ||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO); | |||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO, null); | |||||
Page<DkCheckInRecordDTO> result = dkMapper.selectVoPage(pageQuery.build(), queryWrapper); | Page<DkCheckInRecordDTO> result = dkMapper.selectVoPage(pageQuery.build(), queryWrapper); | ||||
return TableDataInfo.build(result); | return TableDataInfo.build(result); | ||||
} | } | ||||
private LambdaQueryWrapper<DkCheckInRecord> buildQueryWrapper(DkCheckInRecordDTO dkCheckInRecordDTO) { | |||||
private LambdaQueryWrapper<DkCheckInRecord> buildQueryWrapper(DkCheckInRecordDTO dkCheckInRecordDTO, String flag) { | |||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = Wrappers.lambdaQuery(); | LambdaQueryWrapper<DkCheckInRecord> queryWrapper = Wrappers.lambdaQuery(); | ||||
queryWrapper.eq(null != dkCheckInRecordDTO.getSysUserId() ,DkCheckInRecord::getSysUserId, dkCheckInRecordDTO.getSysUserId()); | |||||
queryWrapper.eq(null != dkCheckInRecordDTO.getSysUserName() ,DkCheckInRecord::getSysUserName, dkCheckInRecordDTO.getSysUserName()); | queryWrapper.eq(null != dkCheckInRecordDTO.getSysUserName() ,DkCheckInRecord::getSysUserName, dkCheckInRecordDTO.getSysUserName()); | ||||
queryWrapper.eq(null != dkCheckInRecordDTO.getCheckInTime(), DkCheckInRecord::getCheckInTime, dkCheckInRecordDTO.getCheckInTime()); | queryWrapper.eq(null != dkCheckInRecordDTO.getCheckInTime(), DkCheckInRecord::getCheckInTime, dkCheckInRecordDTO.getCheckInTime()); | ||||
queryWrapper.eq(null != dkCheckInRecordDTO.getCheckInStatus(), DkCheckInRecord::getCheckInStatus, dkCheckInRecordDTO.getCheckInStatus()); | queryWrapper.eq(null != dkCheckInRecordDTO.getCheckInStatus(), DkCheckInRecord::getCheckInStatus, dkCheckInRecordDTO.getCheckInStatus()); | ||||
// queryWrapper.eq(null != dkCheckInRecordDTO.getExportRange(), DkCheckInRecord::getExportRange, dkCheckInRecordDTO.getExportRange()); | // queryWrapper.eq(null != dkCheckInRecordDTO.getExportRange(), DkCheckInRecord::getExportRange, dkCheckInRecordDTO.getExportRange()); | ||||
if("day".equals(dkCheckInRecordDTO.getExportRange())){ | |||||
queryWrapper.between(DkCheckInRecord::getCheckInTime, TimeUtils.getStartTime(), TimeUtils.getEndTime()); | |||||
if(dkCheckInRecordDTO.getStrDay() != null){ | |||||
queryWrapper.between(DkCheckInRecord::getCheckInTime, TimeUtils.getStartTime(dkCheckInRecordDTO.getStrDay()), | |||||
TimeUtils.getEndTime(dkCheckInRecordDTO.getStrDay())); | |||||
} | |||||
if(dkCheckInRecordDTO.getStrMonth() != null){ | |||||
queryWrapper.between(DkCheckInRecord::getCheckInTime, TimeUtils.getFirstDayOfMonth(dkCheckInRecordDTO.getStrMonth()), | |||||
TimeUtils.getLastDayOfMonth(dkCheckInRecordDTO.getStrMonth())); | |||||
} | } | ||||
if("month".equals(dkCheckInRecordDTO.getExportRange())){ | |||||
queryWrapper.between(DkCheckInRecord::getCheckInTime, TimeUtils.getFirstDayOfMonth(), TimeUtils.getLastDayOfMonth()); | |||||
if(flag != null){ | |||||
queryWrapper.groupBy(DkCheckInRecord::getSysUserName); | |||||
} | } | ||||
queryWrapper.orderByDesc(DkCheckInRecord::getSysUserName).orderByDesc(DkCheckInRecord::getCheckInTime); | queryWrapper.orderByDesc(DkCheckInRecord::getSysUserName).orderByDesc(DkCheckInRecord::getCheckInTime); | ||||
*/ | */ | ||||
@Override | @Override | ||||
public List<DkCheckInRecordDTO> queryList(DkCheckInRecordDTO dkCheckInRecordDTO) { | public List<DkCheckInRecordDTO> queryList(DkCheckInRecordDTO dkCheckInRecordDTO) { | ||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO); | |||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO, null); | |||||
List<DkCheckInRecordDTO> dkCheckInRecordDTOS = dkMapper.selectVoList(queryWrapper); | List<DkCheckInRecordDTO> dkCheckInRecordDTOS = dkMapper.selectVoList(queryWrapper); | ||||
dkCheckInRecordDTOS.forEach(dk -> { | dkCheckInRecordDTOS.forEach(dk -> { | ||||
if("0".equals(dk.getCheckInStatus())){ | if("0".equals(dk.getCheckInStatus())){ | ||||
}); | }); | ||||
return dkCheckInRecordDTOS; | return dkCheckInRecordDTOS; | ||||
} | } | ||||
@Override | |||||
public void exportNew(DkCheckInRecordDTO dkCheckInRecordDTO, HttpServletResponse response) { | |||||
// 获取所有人员 | |||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO, "export"); | |||||
List<DkCheckInRecordDTO> dkCheckInRecordDTOS = dkMapper.selectVoList(queryWrapper); | |||||
try { | |||||
FileInputStream templateFile = null; | |||||
Workbook workbook = null; | |||||
// 加载模板文件 | |||||
templateFile = new FileInputStream("template.xlsx"); | |||||
workbook = WorkbookFactory.create(templateFile); | |||||
Sheet templateSheet = workbook.getSheetAt(0); | |||||
for (int i = 0; i < dkCheckInRecordDTOS.size(); i++){ | |||||
DkCheckInRecordDTO dk = dkCheckInRecordDTOS.get(i); | |||||
// 获取每个人员的打卡记录并生成excel | |||||
// 自动检测文件格式并创建对应的 Workbook | |||||
// workbook = WorkbookFactory.create(templateFile); | |||||
// Workbook workbook = new XSSFWorkbook(templateFile); | |||||
// workbook.setSheetName(i, dk.getSysUserName()); | |||||
// Sheet sheet = workbook.getSheetAt(i); // 获取第一个工作表 | |||||
// Sheet sheet = getOrCreateSheet(workbook, i, dk.getSysUserName()); | |||||
// 创建新Sheet,使用原始模板Sheet的名称加上序号 | |||||
String sheetName = templateSheet.getSheetName() + "_" + (i + 1); | |||||
int newSheetIndex = workbook.getNumberOfSheets(); | |||||
workbook.cloneSheet(0); | |||||
workbook.setSheetName(newSheetIndex, dk.getSysUserName()); | |||||
// 获取新创建的Sheet | |||||
Sheet newSheet = workbook.getSheetAt(newSheetIndex); | |||||
// 准备数据 | |||||
dkCheckInRecordDTO.setSysUserId(dk.getSysUserId()); | |||||
dkCheckInRecordDTO.setSysUserName(dk.getSysUserName()); | |||||
EmployeeAttendance attendanceData = prepareSampleData(dkCheckInRecordDTO); | |||||
// 填充数据到模板 | |||||
fillTemplate(newSheet, attendanceData); | |||||
} | |||||
// 保存为新文件 | |||||
// FileOutputStream outputFile = new FileOutputStream("output.xlsx"); | |||||
// workbook.write(outputFile); | |||||
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); | |||||
// response.setHeader("Content-disposition", "attachment;filename=用户数据_模板.xlsx"); | |||||
// 删除原始模板Sheet(如果不需要) | |||||
// workbook.removeSheetAt(0); | |||||
workbook.write(response.getOutputStream()); | |||||
// 关闭资源 | |||||
// outputFile.close(); | |||||
workbook.close(); | |||||
templateFile.close(); | |||||
System.out.println("Excel 导出成功!"); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
// 获取或创建工作表的工具方法 | |||||
private Sheet getOrCreateSheet(Workbook workbook, int sheetIndex, String sheetName) { | |||||
Sheet sheet; | |||||
if (workbook.getNumberOfSheets() > sheetIndex) { | |||||
// 工作表已存在,获取它 | |||||
sheet = workbook.getSheetAt(sheetIndex); | |||||
// 可选:如果需要,重命名现有工作表 | |||||
workbook.setSheetName(sheetIndex, sheetName); | |||||
} else { | |||||
// 工作表不存在,创建它 | |||||
sheet = workbook.createSheet(sheetName); | |||||
} | |||||
return sheet; | |||||
} | |||||
private EmployeeAttendance prepareSampleData(DkCheckInRecordDTO dkCheckInRecordDTO) { | |||||
// 定义员工类对象 | |||||
EmployeeAttendance data = new EmployeeAttendance(); | |||||
// 设置员工的名字 | |||||
data.setEmployeeName(dkCheckInRecordDTO.getSysUserName()); | |||||
// 判断月日是否为空 | |||||
if(dkCheckInRecordDTO.getStrMonth() != null){ | |||||
data.setDateTime(dkCheckInRecordDTO.getStrMonth()); | |||||
} | |||||
if(dkCheckInRecordDTO.getStrDay() != null){ | |||||
data.setDateTime(dkCheckInRecordDTO.getStrDay()); | |||||
} | |||||
//根据userId获取打卡配置信息 | |||||
DkAttendanceGroup dkAttendanceGroup = dkMapper.queryConfigByUserId(dkCheckInRecordDTO.getSysUserId()); | |||||
// 是否允许迟到 | |||||
Boolean allowLate = dkAttendanceGroup.getAllowLate(); | |||||
// 允许迟到的时长 | |||||
dkAttendanceGroup.getAllowLate(); | |||||
// 是否允许早退 | |||||
Boolean allowEarly = dkAttendanceGroup.getAllowEarly(); | |||||
// 允许早退的时长 | |||||
Integer earlyRange = dkAttendanceGroup.getEarlyRange(); | |||||
// 定义集合,用于存储每天打卡记录 | |||||
List<DayRecord> dayRecords = new ArrayList<>(); | |||||
// 根据用户的ID查询该用户所有的打卡记录 | |||||
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO, null); | |||||
List<DkCheckInRecordDTO> dkCheckInRecordDTOS = dkMapper.selectVoList(queryWrapper); | |||||
// 构造excel数据 | |||||
for(DkCheckInRecordDTO dk : dkCheckInRecordDTOS){ | |||||
// 根据打卡时间获取日期 | |||||
LocalDate localDate = dk.getCheckInTime().toLocalDate(); | |||||
// 构造当天开始打卡时间 | |||||
String workStartTime = dkAttendanceGroup.getWorkStartTime(); | |||||
LocalDateTime workStartTime1 = LocalDateTime.of(localDate, LocalTime.parse(workStartTime)); | |||||
// 构造当天结束打卡时间 | |||||
String workEndTime = dkAttendanceGroup.getWorkEndTime(); | |||||
LocalDateTime workEndTime1 = LocalDateTime.of(localDate, LocalTime.parse(workEndTime)); | |||||
// 构造DayRecord | |||||
DayRecord dayRecord = new DayRecord(); | |||||
dayRecord.setDay(dk.getDay()); | |||||
dayRecord.setWeekday(dk.getWeek()); | |||||
dayRecord.setStartTime(null != dk.getClockIn() ? dk.getClockIn().format(DateTimeFormatter.ofPattern("HH:mm")) : ""); | |||||
dayRecord.setEndTime(null != dk.getClockOut() ? dk.getClockOut().format(DateTimeFormatter.ofPattern("HH:mm")) : ""); | |||||
// 打卡异常判断 | |||||
if(dk.getClockIn() != null && dk.getClockOut() != null){ | |||||
if(dk.getClockIn().isAfter(workStartTime1)){ | |||||
dayRecord.setChidao("*"); | |||||
dayRecord.setRemark("迟到1次"); | |||||
} | |||||
} | |||||
if(dk.getClockIn() != null && dk.getClockOut() == null){ | |||||
dayRecord.setYichang("*"); | |||||
dayRecord.setRemark("异常打卡"); | |||||
} | |||||
// 判断是否为工作日加班 | |||||
if(dk.getClockOut() != null){ | |||||
if(dk.getClockOut().isAfter(workEndTime1)){ | |||||
// 计算时间差 | |||||
Duration duration = Duration.between(workEndTime1, dk.getClockOut()); | |||||
// 获取小时差(注意:此方法会舍去分钟和秒部分) | |||||
long hours1 = duration.toMinutes(); // 结果:6 小时(15:45 - 09:30 = 6小时15分钟) | |||||
if(hours1 >= 30){ | |||||
BigDecimal a = new BigDecimal(hours1); | |||||
BigDecimal b = new BigDecimal("60"); | |||||
// 执行除法,指定精度和舍入模式 | |||||
BigDecimal result = a.divide(b, 1, BigDecimal.ROUND_HALF_UP); | |||||
dayRecord.setGongzuori("*"); | |||||
dayRecord.setRemark("加班1次:" + (double)hours1/60 + "小时"); | |||||
} | |||||
} | |||||
} | |||||
// 判断是否为休假日加班 | |||||
if(Constans.ZHOULIU.equals(dk.getWeek()) || Constans.ZHOURI.equals(dk.getWeek())){ | |||||
dayRecord.setXiuxiri("*"); | |||||
dayRecord.setRemark("加班1次"); | |||||
} | |||||
// 判断是否为法定节假日加班 | |||||
// // 获取法定节假日时间 | |||||
// List<LocalDate> holidays = getHolidays(LocalDate.now().getYear()); | |||||
// // 获取打卡日期 | |||||
// int day = dk.getDay(); | |||||
dayRecords.add(dayRecord); | |||||
} | |||||
// dayRecords.add(new DayRecord(1, "金", "09:05", "18:23", "迟到", "", 0.5, "会议")); | |||||
// dayRecords.add(new DayRecord(2, "土", "08:55", "18:30", "正常", "", 1.0, "")); | |||||
// dayRecords.add(new DayRecord(3, "日", "", "", "休息", "年假", 0, "")); | |||||
// 添加更多日期记录... | |||||
data.setDayRecords(dayRecords); | |||||
return data; | |||||
} | |||||
public static List<LocalDate> getHolidays(int year) { | |||||
List<LocalDate> holidays = new ArrayList<>(); | |||||
// 元旦 | |||||
holidays.add(LocalDate.of(year, 1, 1)); | |||||
// 春节(这里简单示例,实际需考虑农历计算,可使用第三方农历库) | |||||
holidays.add(LocalDate.of(year, 1, 22)); | |||||
holidays.add(LocalDate.of(year, 1, 23)); | |||||
holidays.add(LocalDate.of(year, 1, 24)); | |||||
// 清明节 | |||||
holidays.add(LocalDate.of(year, 4, 4)); | |||||
// 劳动节 | |||||
holidays.add(LocalDate.of(year, 5, 1)); | |||||
// 端午节 | |||||
holidays.add(LocalDate.of(year, 6, 22)); | |||||
// 中秋节 | |||||
holidays.add(LocalDate.of(year, 9, 29)); | |||||
// 国庆节 | |||||
holidays.add(LocalDate.of(year, 10, 1)); | |||||
holidays.add(LocalDate.of(year, 10, 2)); | |||||
holidays.add(LocalDate.of(year, 10, 3)); | |||||
return holidays; | |||||
} | |||||
private JSONObject getJjr() { | |||||
String url = "http://timor.tech/api/holiday/year/"; | |||||
OkHttpClient client = new OkHttpClient(); | |||||
Response response; | |||||
//解密数据 | |||||
String rsa = null; | |||||
Request request = new Request.Builder() | |||||
.url(url) | |||||
.get() | |||||
.addHeader("Content-Type", "application/x-www-form-urlencoded") | |||||
.build(); | |||||
try { | |||||
response = client.newCall(request).execute(); | |||||
rsa = response.body().string(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return JSONObject.parseObject(rsa); | |||||
} | |||||
private void fillTemplate(Sheet sheet, EmployeeAttendance data) { | |||||
// 填充标题区域 | |||||
setCellValue(sheet, 6, 10, data.getEmployeeName()); | |||||
setCellValue(sheet, 3, 3, data.getDateTime()); | |||||
// setCellValue(sheet, 2, 0, data.getYear() + "年" + data.getMonth() + "月考勤记录"); | |||||
// 填充数据表格 | |||||
int rowIndex = 10; // 数据起始行(根据模板调整) | |||||
for (DayRecord record : data.getDayRecords()) { | |||||
// setCellValue(sheet, rowIndex, 1, record.getDay()); | |||||
// setCellValue(sheet, rowIndex, 2, record.getWeekday()); | |||||
setCellValue(sheet, rowIndex, 3, record.getStartTime()); | |||||
setCellValue(sheet, rowIndex, 4, record.getEndTime()); | |||||
setCellValue(sheet, rowIndex, 5, record.getChidao()); | |||||
// setCellValue(sheet, rowIndex, 6, record.getEndTime()); | |||||
setCellValue(sheet, rowIndex, 7, record.getYichang()); | |||||
setCellValue(sheet, rowIndex, 8, record.getGongzuori()); | |||||
setCellValue(sheet, rowIndex, 9, record.getXiuxiri()); | |||||
setCellValue(sheet, rowIndex, 10, record.getFadingjiari()); | |||||
setCellValue(sheet, rowIndex, 11, record.getXiuxi()); | |||||
setCellValue(sheet, rowIndex, 12, record.getQingjia()); | |||||
setCellValue(sheet, rowIndex, 13, record.getRemark()); | |||||
rowIndex++; | |||||
} | |||||
} | |||||
private void setCellValue(Sheet sheet, int rowIndex, int colIndex, Object value) { | |||||
Row row = sheet.getRow(rowIndex); | |||||
if (row == null) { | |||||
row = sheet.createRow(rowIndex); | |||||
} | |||||
Cell cell = row.getCell(colIndex); | |||||
if (cell == null) { | |||||
cell = row.createCell(colIndex); | |||||
} | |||||
if (value instanceof String) { | |||||
cell.setCellValue((String) value); | |||||
} else if (value instanceof Integer) { | |||||
cell.setCellValue((Integer) value); | |||||
} else if (value instanceof Double) { | |||||
cell.setCellValue((Double) value); | |||||
} else if (value != null) { | |||||
cell.setCellValue(value.toString()); | |||||
} | |||||
} | |||||
} | } |
package com.ruoyi.zhushi.util; | |||||
/** | |||||
* @author zhouwenhao | |||||
* @date 2025/6/18 | |||||
* @dec 描述 | |||||
*/ | |||||
public class Constans { | |||||
public static final String SUCCESS = "创建成功"; | |||||
public static final String ZHOULIU = "周六"; | |||||
public static final String ZHOURI = "周日"; | |||||
} |
package com.ruoyi.zhushi.util; | package com.ruoyi.zhushi.util; | ||||
import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
import java.time.LocalDate; | |||||
import java.time.LocalDateTime; | |||||
import java.time.LocalTime; | |||||
import java.time.ZoneId; | |||||
import java.time.*; | |||||
import java.time.format.DateTimeFormatter; | import java.time.format.DateTimeFormatter; | ||||
import java.util.Date; | import java.util.Date; | ||||
public class TimeUtils { | public class TimeUtils { | ||||
public static String getStartTime() { | |||||
LocalDate today = LocalDate.now(); | |||||
private static final DateTimeFormatter FORMAT_DEFAULT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||||
public static String getStartTime(String dayDate) { | |||||
// 定义一天的开始和结束时间 | // 定义一天的开始和结束时间 | ||||
LocalDate date = LocalDate.parse(dayDate, DateTimeFormatter.ISO_LOCAL_DATE); | |||||
LocalTime startTime = LocalTime.of(0, 0, 0); // 00:00:00 | LocalTime startTime = LocalTime.of(0, 0, 0); // 00:00:00 | ||||
LocalDateTime startOfDay = today.atTime(startTime); | |||||
LocalDateTime startOfDay = date.atTime(startTime); | |||||
// 格式化输出 | // 格式化输出 | ||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | ||||
String startOfDayStr = startOfDay.format(formatter); | String startOfDayStr = startOfDay.format(formatter); | ||||
return startOfDayStr; | return startOfDayStr; | ||||
} | } | ||||
public static String getEndTime() { | |||||
public static String getEndTime(String dayDate) { | |||||
LocalDate today = LocalDate.now(); | LocalDate today = LocalDate.now(); | ||||
// 定义一天的开始和结束时间 | // 定义一天的开始和结束时间 | ||||
LocalDate date = LocalDate.parse(dayDate, DateTimeFormatter.ISO_LOCAL_DATE); | |||||
LocalTime endTime = LocalTime.of(23, 59, 59); // 23:59:59 | LocalTime endTime = LocalTime.of(23, 59, 59); // 23:59:59 | ||||
LocalDateTime endOfDay = today.atTime(endTime); | |||||
LocalDateTime endOfDay = date.atTime(endTime); | |||||
// 格式化输出 | // 格式化输出 | ||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | ||||
String endOfDayStr = endOfDay.format(formatter); | String endOfDayStr = endOfDay.format(formatter); | ||||
return localDateTime.format(formatter); | return localDateTime.format(formatter); | ||||
} | } | ||||
public static String getFirstDayOfMonth() { | |||||
Date monthStart = getMonthStart(); | |||||
// 格式化输出 | |||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||||
return formatDate(monthStart, formatter); | |||||
public static LocalDateTime getFirstDayOfMonth(String monthDate) { | |||||
// Date monthStart = getMonthStart(); | |||||
// // 格式化输出 | |||||
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||||
// return formatDate(monthStart, formatter); | |||||
// LocalDateTime startOfMonth = monthDate.atStartOfDay(); // 2025-06-01T00:00 | |||||
// monthDate.atStartOfDay(); | |||||
// LocalDate date = LocalDate.parse(monthDate, DateTimeFormatter.ISO_LOCAL_DATE); | |||||
YearMonth yearMonth = YearMonth.parse(monthDate); | |||||
LocalDate localDate = yearMonth.atDay(1); | |||||
int year = localDate.getYear(); | |||||
int month = localDate.getMonthValue(); | |||||
// LocalDateTime startOfMonth = date.atTime(LocalTime.MIN); | |||||
return YearMonth.of(year, month).atDay(1).atStartOfDay(); | |||||
} | } | ||||
public static String getLastDayOfMonth() { | |||||
Date monthEnd = getMonthEnd(); | |||||
// 格式化输出 | |||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||||
return formatDate(monthEnd, formatter); | |||||
public static LocalDateTime getLastDayOfMonth(String monthDate) { | |||||
// Date monthEnd = getMonthEnd(); | |||||
// // 格式化输出 | |||||
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||||
// return formatDate(monthEnd, formatter); | |||||
YearMonth yearMonth = YearMonth.parse(monthDate); | |||||
LocalDate localDate = yearMonth.atEndOfMonth(); | |||||
int year = localDate.getYear(); | |||||
int month = localDate.getMonthValue(); | |||||
return YearMonth.of(year, month).atEndOfMonth().atTime(LocalTime.MAX); | |||||
} | |||||
public static LocalDateTime parseStr2LocalDateTime(String timeStr) { | |||||
return LocalDateTime.parse(timeStr, FORMAT_DEFAULT); | |||||
} | } | ||||
} | } |
<result property="checkInType" column="check_in_type"/> | <result property="checkInType" column="check_in_type"/> | ||||
</resultMap> | </resultMap> | ||||
<select id="getCurrentDayRecord" resultMap="DkRecordResult"> | |||||
select DISTINCT t.`name`, t.description, | |||||
t.work_start_time workStartTime, | |||||
t.work_end_time workEndTime, | |||||
t.allow_early allowEarly, | |||||
t.early_range earlyRange, | |||||
t.allow_late allowLate, | |||||
t.late_range lateRange, | |||||
c.lng lng, c.lat lat, c.radius | |||||
from dk_check_in_attendance_team_and_user u | |||||
LEFT JOIN dk_check_in_attendance_team t on t.id = u.attendance_team_id | |||||
left JOIN dk_check_in_config c on c.id = t.area_id | |||||
<select id="getCurrentDayRecord" resultType="com.ruoyi.zhushi.entity.DkCheckInRecord"> | |||||
select * from dk_check_in_record | |||||
<where> | <where> | ||||
check_in_time >= CURDATE() AND create_time < CURDATE() + INTERVAL 1 DAY | |||||
check_in_time >= CURDATE() AND check_in_time < CURDATE() + INTERVAL 1 DAY | |||||
<if test="userId != null and userId != ''"> | <if test="userId != null and userId != ''"> | ||||
AND u.user_id = #{userId} | |||||
AND sys_user_id = #{userId} | |||||
</if> | </if> | ||||
</where> | </where> | ||||
</select> | </select> | ||||
<select id="queryConfigByUserId" resultType="com.ruoyi.zhushi.entity.DkAttendanceGroup"> | |||||
select DISTINCT t.* from dk_check_in_attendance_team_and_user tu | |||||
left join dk_check_in_attendance_team t on t.id = tu.attendance_team_id | |||||
<where> | |||||
<if test="userId != null and userId != ''"> | |||||
AND tu.user_id = #{userId} | |||||
</if> | |||||
</where> | |||||
</select> | |||||
</mapper> | </mapper> |