完成务工者考勤模块
This commit is contained in:
		@ -2,6 +2,9 @@ package com.ruoyi.wgz.service;
 | 
			
		||||
 | 
			
		||||
import com.ruoyi.common.core.domain.AjaxResult;
 | 
			
		||||
import com.ruoyi.wgz.bo.req.WgzAppSubmitTheClockReq;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppCardReplacementApplicationRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppPunchTheCalendarRecordRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppUserClockingConditionRes;
 | 
			
		||||
import com.ruoyi.wgz.domain.WgzAttendance;
 | 
			
		||||
import com.ruoyi.wgz.bo.WgzAttendanceQueryBo;
 | 
			
		||||
import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 | 
			
		||||
@ -69,8 +72,23 @@ public interface IWgzAttendanceService extends IServicePlus<WgzAttendance> {
 | 
			
		||||
	 */
 | 
			
		||||
	Boolean userSubmitTheClock(@Validated @RequestBody WgzAppSubmitTheClockReq req);
 | 
			
		||||
 | 
			
		||||
//	/**
 | 
			
		||||
//	 * 查看当前人、当前工地、当前日期的打卡记录
 | 
			
		||||
//	 */
 | 
			
		||||
//	WgzAttendance findByUserIdWait(Long appUserId, Long recruitId, String date);
 | 
			
		||||
	/**
 | 
			
		||||
	 * 用户今日打卡状态(0上班 1下班 2请假)
 | 
			
		||||
	 */
 | 
			
		||||
	WgzAppUserClockingConditionRes userClockingCondition();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 打卡日历记录
 | 
			
		||||
	 */
 | 
			
		||||
	WgzAppPunchTheCalendarRecordRes userPunchTheCalendarRecord();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 根据id查询具体的打卡详情
 | 
			
		||||
	 */
 | 
			
		||||
	WgzAttendance findById(Long id);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 补卡申请列表
 | 
			
		||||
	 */
 | 
			
		||||
	WgzAppCardReplacementApplicationRes userCardReplacementApplication();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,79 @@
 | 
			
		||||
package com.ruoyi.wgz.service;
 | 
			
		||||
 | 
			
		||||
import com.ruoyi.wgz.bo.req.WgzAppReplacementCardRecordReq;
 | 
			
		||||
import com.ruoyi.wgz.bo.req.WgzAppCardReplacementApplicationReq;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppCardReplacementApplicationRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzReplacementCardRecordRes;
 | 
			
		||||
import com.ruoyi.wgz.domain.WgzReissueacard;
 | 
			
		||||
import com.ruoyi.wgz.bo.WgzReissueacardQueryBo;
 | 
			
		||||
import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 | 
			
		||||
import com.ruoyi.common.core.page.TableDataInfo;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestBody;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 补卡申请Service接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author ruoyi
 | 
			
		||||
 * @date 2025-02-20
 | 
			
		||||
 */
 | 
			
		||||
public interface IWgzReissueacardService extends IServicePlus<WgzReissueacard> {
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询单个
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    WgzReissueacard queryById(Long id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询列表
 | 
			
		||||
     */
 | 
			
		||||
    TableDataInfo<WgzReissueacard> queryPageList(WgzReissueacardQueryBo bo);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询列表
 | 
			
		||||
     */
 | 
			
		||||
    List<WgzReissueacard> queryList(WgzReissueacardQueryBo bo);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据新增业务对象插入补卡申请
 | 
			
		||||
     * @param bo 补卡申请新增业务对象
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    Boolean insert(WgzReissueacard bo);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据编辑业务对象修改补卡申请
 | 
			
		||||
     * @param bo 补卡申请编辑业务对象
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    Boolean update(WgzReissueacard bo);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 校验并删除数据
 | 
			
		||||
     * @param ids 主键集合
 | 
			
		||||
     * @param isValid 是否校验,true-删除前校验,false-不校验
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * APP相关
 | 
			
		||||
	 * =================================================================================================================
 | 
			
		||||
	 * =================================================================================================================
 | 
			
		||||
	 * =================================================================================================================
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * APP补卡申请
 | 
			
		||||
	 */
 | 
			
		||||
	Boolean userCardReplacementApplication(@Validated @RequestBody WgzAppCardReplacementApplicationReq req);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 补卡记录(分页)
 | 
			
		||||
	 */
 | 
			
		||||
	TableDataInfo<WgzReplacementCardRecordRes> userReplacementCardRecord(@Validated WgzAppReplacementCardRecordReq req);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -13,8 +13,15 @@ import com.ruoyi.common.core.page.PagePlus;
 | 
			
		||||
import com.ruoyi.common.core.page.TableDataInfo;
 | 
			
		||||
import com.ruoyi.common.utils.SecurityUtils;
 | 
			
		||||
import com.ruoyi.wgz.bo.req.WgzAppSubmitTheClockReq;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppCardReplacementApplicationRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppPunchTheCalendarRecordRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppUserClockingConditionRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.rests.WgzAppCardReplacementApplicationTwo;
 | 
			
		||||
import com.ruoyi.wgz.bo.rests.WgzAppPunchTheCalendarRecordThree;
 | 
			
		||||
import com.ruoyi.wgz.bo.rests.WgzAppPunchTheCalendarRecordTwo;
 | 
			
		||||
import com.ruoyi.wgz.domain.WgzLeave;
 | 
			
		||||
import com.ruoyi.wgz.service.IWgzLeaveService;
 | 
			
		||||
import org.aspectj.weaver.ast.Var;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 | 
			
		||||
@ -27,13 +34,11 @@ import com.ruoyi.wgz.service.IWgzAttendanceService;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.springframework.transaction.reactive.TransactionalOperator;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDate;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.LocalTime;
 | 
			
		||||
import java.text.DecimalFormat;
 | 
			
		||||
import java.time.*;
 | 
			
		||||
import java.time.format.DateTimeFormatter;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.time.temporal.TemporalAdjusters;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 考勤打卡Service业务层处理
 | 
			
		||||
@ -143,54 +148,260 @@ public class WgzAttendanceServiceImpl extends ServicePlusImpl<WgzAttendanceMappe
 | 
			
		||||
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
 | 
			
		||||
		//3、根据工地id得到完整的工地信息
 | 
			
		||||
		BgtProjectRecruit appById = iBgtProjectRecruitService.getAppById(by.getId());
 | 
			
		||||
		//4、查看当前用户是否有请假申请,有请假申请并且通过,那就无法进行打卡
 | 
			
		||||
//		//4、查看当前用户是否有请假申请,有请假申请并且通过,那就无法进行打卡------------------>此处代码将改写逻辑为:每天凌晨1分的时候直接找出已请假的人然后定时插入数据到打卡记录中标记为请假
 | 
			
		||||
//		String formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 | 
			
		||||
//		WgzLeave wgzLeave = iWgzLeaveService.FindAskForLeaveOrNotInfo(appUserId, by.getId(), formattedDate);
 | 
			
		||||
//		if (wgzLeave != null) { //表示有请假申请
 | 
			
		||||
//			LocalDateTime startTime = wgzLeave.getStartTime();
 | 
			
		||||
//			LocalDate localDate = startTime.toLocalDate();
 | 
			
		||||
//			throw new RuntimeException("您有已通过的请假申请,请假时间为:"+localDate);
 | 
			
		||||
//		}
 | 
			
		||||
		//5、查看当前人、当前工地、当天的打卡记录
 | 
			
		||||
		String formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 | 
			
		||||
		WgzLeave wgzLeave = iWgzLeaveService.FindAskForLeaveOrNotInfo(appUserId, by.getId(), formattedDate);
 | 
			
		||||
		if (wgzLeave != null) { //表示有请假申请
 | 
			
		||||
			LocalDateTime startTime = wgzLeave.getStartTime();
 | 
			
		||||
			LocalDate localDate = startTime.toLocalDate();
 | 
			
		||||
			throw new RuntimeException("您有已通过的请假申请,请假时间为:"+localDate);
 | 
			
		||||
		WgzAttendance we = publicFindByUserIdWait(appUserId, by.getId(), formattedDate);
 | 
			
		||||
		String exceptionType = we.getExceptionType();
 | 
			
		||||
		if (we.getLeaveMarkId() != null && we.getLeaveMarkId()!= 0) {
 | 
			
		||||
			throw new RuntimeException("您有已通过的请假申请,请假时间为:"+formattedDate);
 | 
			
		||||
		}
 | 
			
		||||
		//5、查看当前人、当前工地、当天是否有打卡记录
 | 
			
		||||
		//4、组装完整的打卡信息
 | 
			
		||||
		//6、组装完整的打卡信息
 | 
			
		||||
		WgzAttendance wgzAttendance = new WgzAttendance().
 | 
			
		||||
			setRecruitId(appById.getId()).
 | 
			
		||||
			setUserId(appUserId).
 | 
			
		||||
			setDailyWage(appById.getRecruitAmount()).
 | 
			
		||||
			setDate(LocalDate.now()).
 | 
			
		||||
			setPnchOsition(req.getPnchOsition()).
 | 
			
		||||
			setDate(LocalDate.now());
 | 
			
		||||
		//设置打卡时间
 | 
			
		||||
			setPnchOsition(req.getPnchOsition());
 | 
			
		||||
		LocalDateTime now = LocalDateTime.now(); //当前完整年月日时分秒
 | 
			
		||||
		LocalTime localTime = now.toLocalTime(); //获取时分秒
 | 
			
		||||
		if (req.getType().equals(Clocking)) {
 | 
			
		||||
		if (Objects.isNull(we)) { //表示当天第一次打卡---上班
 | 
			
		||||
			wgzAttendance.setClockInTime(now);
 | 
			
		||||
			//判断当前打卡时间是否在上班时间之前
 | 
			
		||||
			LocalTime beginWorkTime = appById.getBeginWorkTime(); //上班
 | 
			
		||||
			if (!localTime.isBefore(beginWorkTime)) {
 | 
			
		||||
				wgzAttendance.setLate(1); //迟到
 | 
			
		||||
				wgzAttendance.setLateTime(now);
 | 
			
		||||
				wgzAttendance.setExceptionType("1,");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (req.getType().equals(OffDuty)) {
 | 
			
		||||
		}else{ //表示当天不是第一次打卡---下班
 | 
			
		||||
			wgzAttendance.setClockOutTime(now);
 | 
			
		||||
			//判断当前打卡时间是否在下班时间之后
 | 
			
		||||
			LocalTime endWorkTime = appById.getEndWorkTime(); //下班
 | 
			
		||||
			if (!localTime.isAfter(endWorkTime)) {
 | 
			
		||||
				wgzAttendance.setEarlyLeave(1); //早退
 | 
			
		||||
				wgzAttendance.setEarlyLeaveTime(now);
 | 
			
		||||
				wgzAttendance.setExceptionType("2,");
 | 
			
		||||
				wgzAttendance.setExceptionType(exceptionType+"2,");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return baseMapper.insert(wgzAttendance) > 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public WgzAppUserClockingConditionRes userClockingCondition() {
 | 
			
		||||
		WgzAppUserClockingConditionRes res = new WgzAppUserClockingConditionRes();
 | 
			
		||||
		//1、获取打卡信息
 | 
			
		||||
		Long appUserId = SecurityUtils.getAppUserId();
 | 
			
		||||
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
 | 
			
		||||
		String formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 | 
			
		||||
		WgzAttendance wgzAttendance = publicFindByUserIdWait(appUserId, by.getId(), formattedDate);
 | 
			
		||||
		//2、获取今日用户打卡状态
 | 
			
		||||
		if (Objects.isNull(wgzAttendance)) {
 | 
			
		||||
			res.setClockingCondition(0); //上班
 | 
			
		||||
		}else{
 | 
			
		||||
			res.setClockingCondition(1); //下班
 | 
			
		||||
			if (wgzAttendance.getLeaveMarkId()!= null && wgzAttendance.getLeaveMarkId()!= 0) {
 | 
			
		||||
				res.setClockingCondition(2); //请假
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return res;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public WgzAppPunchTheCalendarRecordRes userPunchTheCalendarRecord() {
 | 
			
		||||
		Long appUserId = SecurityUtils.getAppUserId();
 | 
			
		||||
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
 | 
			
		||||
		//1、获取当月的所有日期
 | 
			
		||||
		LocalDate currentDate = LocalDate.now();
 | 
			
		||||
		LocalDate firstDayOfMonth = currentDate.with(TemporalAdjusters.firstDayOfMonth());
 | 
			
		||||
		LocalDate lastDayOfMonth = currentDate.with(TemporalAdjusters.lastDayOfMonth());
 | 
			
		||||
		List<LocalDate> dates = new ArrayList<>();
 | 
			
		||||
		LocalDate tempDate = firstDayOfMonth;
 | 
			
		||||
		while (!tempDate.isAfter(lastDayOfMonth)) {
 | 
			
		||||
			dates.add(tempDate);
 | 
			
		||||
			tempDate = tempDate.plusDays(1);
 | 
			
		||||
		}
 | 
			
		||||
		String format = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
 | 
			
		||||
		//2、获取当前人、当前工地、当前月的所有考勤记录
 | 
			
		||||
		LambdaQueryWrapper<WgzAttendance> apply = new LambdaQueryWrapper<WgzAttendance>().
 | 
			
		||||
			eq(WgzAttendance::getUserId, appUserId).
 | 
			
		||||
			eq(WgzAttendance::getRecruitId, by.getId()).
 | 
			
		||||
			apply("DATE_FORMAT(date, '%Y-%m') = {0}", format);
 | 
			
		||||
		List<WgzAttendance> wgzAttendances = baseMapper.selectList(apply);
 | 
			
		||||
		//3、组装返回数据
 | 
			
		||||
		Map<LocalDate, WgzAppPunchTheCalendarRecordTwo> mp = new HashMap<>();
 | 
			
		||||
		for (LocalDate date : dates) {
 | 
			
		||||
			for (WgzAttendance wa : wgzAttendances) {
 | 
			
		||||
				WgzAppPunchTheCalendarRecordTwo two = new WgzAppPunchTheCalendarRecordTwo().setId(wa.getId());
 | 
			
		||||
				LocalDate clockDate = wa.getDate();
 | 
			
		||||
				if (clockDate.equals(date)) {
 | 
			
		||||
					//上班
 | 
			
		||||
					if (wa.getClockInTime() != null) {
 | 
			
		||||
						two.setNum(1);
 | 
			
		||||
						two.setSb(sbOrXb(wa, 1));
 | 
			
		||||
					}
 | 
			
		||||
					//下班
 | 
			
		||||
					if (wa.getClockOutTime() != null) {
 | 
			
		||||
						two.setNum(2);
 | 
			
		||||
						two.setManHour(calculateWorkingHours(wa.getClockInTime(), wa.getClockOutTime()));
 | 
			
		||||
						two.setSb(sbOrXb(wa, 2));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				mp.put(date, two);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return  new WgzAppPunchTheCalendarRecordRes().setMp(mp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public WgzAttendance findById(Long id) {
 | 
			
		||||
		return getById(id);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public WgzAppCardReplacementApplicationRes userCardReplacementApplication() {
 | 
			
		||||
		//1、获取当前用户信息
 | 
			
		||||
		Long appUserId = SecurityUtils.getAppUserId();
 | 
			
		||||
		//2、获取当前用户所在的工地id
 | 
			
		||||
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
 | 
			
		||||
		//3、根据工地id得到完整的工地信息
 | 
			
		||||
		BgtProjectRecruit appById = iBgtProjectRecruitService.getAppById(by.getId());
 | 
			
		||||
		//4、查询所有缺卡、迟到、早退的打卡记录
 | 
			
		||||
		LambdaQueryWrapper<WgzAttendance> apply = new LambdaQueryWrapper<WgzAttendance>().
 | 
			
		||||
			eq(WgzAttendance::getUserId, appUserId).
 | 
			
		||||
			eq(WgzAttendance::getRecruitId, by.getId()).
 | 
			
		||||
			eq(WgzAttendance::getRecruitId, by.getId())
 | 
			
		||||
			.and(wrapper -> wrapper
 | 
			
		||||
				.eq(WgzAttendance::getLate, 1)
 | 
			
		||||
				.or()
 | 
			
		||||
				.eq(WgzAttendance::getEarlyLeave, 1)
 | 
			
		||||
				.or()
 | 
			
		||||
				.eq(WgzAttendance::getMissedIn, 1)
 | 
			
		||||
				.or()
 | 
			
		||||
				.eq(WgzAttendance::getMissedOut, 1)
 | 
			
		||||
			);
 | 
			
		||||
		List<WgzAttendance> wgzAttendances = baseMapper.selectList(apply);
 | 
			
		||||
		//4、将这些数据进行拆分
 | 
			
		||||
		ArrayList<WgzAppCardReplacementApplicationTwo> list = new ArrayList<>();
 | 
			
		||||
		for (WgzAttendance wgzAttendance : wgzAttendances) {
 | 
			
		||||
			String exceptionType = wgzAttendance.getExceptionType();
 | 
			
		||||
			if (exceptionType.contains("1")) { // 迟到
 | 
			
		||||
				addRecord(wgzAttendance, 1, wgzAttendance.getClockInTime(), list);
 | 
			
		||||
			}
 | 
			
		||||
			if (exceptionType.contains("2")) { // 早退
 | 
			
		||||
				addRecord(wgzAttendance, 2, wgzAttendance.getClockOutTime(), list);
 | 
			
		||||
			}
 | 
			
		||||
			if (exceptionType.contains("3")) { // 上班缺卡
 | 
			
		||||
				addRecord(wgzAttendance, 3, LocalDateTime.from(appById.getBeginWorkTime()), list);
 | 
			
		||||
			}
 | 
			
		||||
			if (exceptionType.contains("4")) { // 下班缺卡
 | 
			
		||||
				addRecord(wgzAttendance, 4, LocalDateTime.from(appById.getEndWorkTime()), list);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
//	@Override
 | 
			
		||||
//	public WgzAttendance findByUserIdWait(Long appUserId, Long recruitId, String date) {
 | 
			
		||||
//		LambdaQueryWrapper<WgzAttendance> qw = new LambdaQueryWrapper<>();
 | 
			
		||||
//		qw.eq(WgzAttendance::getRecruitId,recruitId);
 | 
			
		||||
//		qw.eq(WgzAttendance::getUserId,appUserId);
 | 
			
		||||
//		return null;
 | 
			
		||||
//	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 获取指定人、指定工地、指定日期的打卡记录
 | 
			
		||||
	 * @param appUserId 务工者用户id
 | 
			
		||||
	 * @param recruitId 工地id
 | 
			
		||||
	 * @param date	具体日期
 | 
			
		||||
	 * @return WgzAttendance
 | 
			
		||||
	 */
 | 
			
		||||
	public WgzAttendance publicFindByUserIdWait(Long appUserId, Long recruitId, String date) {
 | 
			
		||||
		LambdaQueryWrapper<WgzAttendance> qw = new LambdaQueryWrapper<>();
 | 
			
		||||
		qw.eq(WgzAttendance::getRecruitId,recruitId);
 | 
			
		||||
		qw.eq(WgzAttendance::getUserId,appUserId);
 | 
			
		||||
		qw.eq(WgzAttendance::getDate,date);
 | 
			
		||||
		return baseMapper.selectOne(qw);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 计算两个时间之间的工作小时数
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param startTime 开始时间
 | 
			
		||||
	 * @param endTime   结束时间
 | 
			
		||||
	 * @return 工作小时数
 | 
			
		||||
	 */
 | 
			
		||||
	public double calculateWorkingHours(LocalDateTime startTime, LocalDateTime endTime) {
 | 
			
		||||
		// 计算两个时间之间的持续时间
 | 
			
		||||
		Duration duration = Duration.between(startTime, endTime);
 | 
			
		||||
 | 
			
		||||
		// 将持续时间转换为分钟
 | 
			
		||||
		long minutes = duration.toMinutes();
 | 
			
		||||
 | 
			
		||||
		// 将分钟转换为小时
 | 
			
		||||
		double hours = (double) minutes / 60;
 | 
			
		||||
 | 
			
		||||
		// 使用 DecimalFormat 保留两位小数
 | 
			
		||||
		DecimalFormat df = new DecimalFormat("#.00");
 | 
			
		||||
		String formattedHours = df.format(hours);
 | 
			
		||||
 | 
			
		||||
		// 将格式化后的字符串转换回 double 类型
 | 
			
		||||
		return Double.parseDouble(formattedHours);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 组装上班、下班打卡记录
 | 
			
		||||
	 * @param wa 打卡记录
 | 
			
		||||
	 * @param num 1上班 2下班
 | 
			
		||||
	 * @return WgzAppPunchTheCalendarRecordThree
 | 
			
		||||
	 */
 | 
			
		||||
	public WgzAppPunchTheCalendarRecordThree sbOrXb( WgzAttendance wa,int num) {
 | 
			
		||||
		WgzAppPunchTheCalendarRecordThree sbb = new WgzAppPunchTheCalendarRecordThree().
 | 
			
		||||
			setClockingTime(wa.getClockInTime()).
 | 
			
		||||
			setPnchOsition(wa.getPnchOsition()).
 | 
			
		||||
			setClockingCondition(0); //正常
 | 
			
		||||
		//判断是否请假
 | 
			
		||||
		if (wa.getLeaveMarkId()!=null && wa.getLeaveMarkId()!=0) {
 | 
			
		||||
			sbb.setClockingCondition(7);
 | 
			
		||||
		}
 | 
			
		||||
		if (num == 1){
 | 
			
		||||
			//判断上班迟到
 | 
			
		||||
			if (wa.getLate() == 1) {
 | 
			
		||||
				sbb.setClockingCondition(1);
 | 
			
		||||
			}
 | 
			
		||||
			//判断是否上班补卡
 | 
			
		||||
			if (wa.getExceptionType().contains("5")) {
 | 
			
		||||
				sbb.setClockingCondition(5);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (num == 2){
 | 
			
		||||
			//判断下班早退
 | 
			
		||||
			if (wa.getEarlyLeave() == 1) {
 | 
			
		||||
				sbb.setClockingCondition(2);
 | 
			
		||||
			}
 | 
			
		||||
			//判断是否下班补卡
 | 
			
		||||
			if (wa.getExceptionType().contains("6")) {
 | 
			
		||||
				sbb.setClockingCondition(6);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return sbb;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 补卡
 | 
			
		||||
	 * @param wgzAttendance 打卡记录
 | 
			
		||||
	 * @param type 1上班 2下班
 | 
			
		||||
	 * @param fillingDataTime 补卡时间
 | 
			
		||||
	 * @param list 补卡记录
 | 
			
		||||
	 */
 | 
			
		||||
	private void addRecord(WgzAttendance wgzAttendance, int type, LocalDateTime fillingDataTime, List<WgzAppCardReplacementApplicationTwo> list) {
 | 
			
		||||
		LocalDate date = wgzAttendance.getDate();
 | 
			
		||||
		DayOfWeek dayOfWeek = date.getDayOfWeek();
 | 
			
		||||
		String week = dayOfWeek.toString();
 | 
			
		||||
		WgzAppCardReplacementApplicationTwo two = new WgzAppCardReplacementApplicationTwo()
 | 
			
		||||
			.setId(wgzAttendance.getId())
 | 
			
		||||
			.setType(type)
 | 
			
		||||
			.setFillingData(date)
 | 
			
		||||
			.setWeek(week)
 | 
			
		||||
			.setFillingDataTime(fillingDataTime);
 | 
			
		||||
		list.add(two);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -155,6 +155,7 @@ public class WgzLeaveServiceImpl extends ServicePlusImpl<WgzLeaveMapper, WgzLeav
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	@Transactional
 | 
			
		||||
	public Boolean userCancelLeave(WgzAppCancelLeaveReq req) {
 | 
			
		||||
		WgzLeave wgzLeave = new WgzLeave().
 | 
			
		||||
			setId(req.getId()).
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,172 @@
 | 
			
		||||
package com.ruoyi.wgz.service.impl;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.bean.BeanUtil;
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 | 
			
		||||
import com.ruoyi.bgt.domain.BgtProjectRecruit;
 | 
			
		||||
import com.ruoyi.bgt.domain.BgtProjectRecruitApply;
 | 
			
		||||
import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService;
 | 
			
		||||
import com.ruoyi.bgt.service.IBgtProjectRecruitService;
 | 
			
		||||
import com.ruoyi.common.utils.PageUtils;
 | 
			
		||||
import com.ruoyi.common.core.page.TableDataInfo;
 | 
			
		||||
import com.ruoyi.common.utils.SecurityUtils;
 | 
			
		||||
import com.ruoyi.wgz.bo.req.WgzAppReplacementCardRecordReq;
 | 
			
		||||
import com.ruoyi.wgz.bo.req.WgzAppCardReplacementApplicationReq;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzAppCardReplacementApplicationRes;
 | 
			
		||||
import com.ruoyi.wgz.bo.res.WgzReplacementCardRecordRes;
 | 
			
		||||
import com.ruoyi.wgz.domain.WgzAttendance;
 | 
			
		||||
import com.ruoyi.wgz.service.IWgzAttendanceService;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 | 
			
		||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 | 
			
		||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
			
		||||
import com.ruoyi.wgz.bo.WgzReissueacardQueryBo;
 | 
			
		||||
import com.ruoyi.wgz.domain.WgzReissueacard;
 | 
			
		||||
import com.ruoyi.wgz.mapper.WgzReissueacardMapper;
 | 
			
		||||
import com.ruoyi.wgz.service.IWgzReissueacardService;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
 | 
			
		||||
import java.time.format.DateTimeFormatter;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 补卡申请Service业务层处理
 | 
			
		||||
 *
 | 
			
		||||
 * @author ruoyi
 | 
			
		||||
 * @date 2025-02-20
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
public class WgzReissueacardServiceImpl extends ServicePlusImpl<WgzReissueacardMapper, WgzReissueacard> implements IWgzReissueacardService {
 | 
			
		||||
 | 
			
		||||
	@Autowired
 | 
			
		||||
	private IBgtProjectRecruitApplyService iBgtProjectRecruitApplyService;
 | 
			
		||||
 | 
			
		||||
	@Autowired
 | 
			
		||||
	private IBgtProjectRecruitService iBgtProjectRecruitService;
 | 
			
		||||
 | 
			
		||||
	@Autowired
 | 
			
		||||
	private IWgzAttendanceService iWgzAttendanceService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public WgzReissueacard queryById(Long id){
 | 
			
		||||
        return getById(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public TableDataInfo<WgzReissueacard> queryPageList(WgzReissueacardQueryBo bo) {
 | 
			
		||||
        Page<WgzReissueacard> result = page(PageUtils.buildPage(), buildQueryWrapper(bo));
 | 
			
		||||
        return PageUtils.buildDataInfo(result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<WgzReissueacard> queryList(WgzReissueacardQueryBo bo) {
 | 
			
		||||
        return list(buildQueryWrapper(bo));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private LambdaQueryWrapper<WgzReissueacard> buildQueryWrapper(WgzReissueacardQueryBo bo) {
 | 
			
		||||
        Map<String, Object> params = bo.getParams();
 | 
			
		||||
        LambdaQueryWrapper<WgzReissueacard> lqw = Wrappers.lambdaQuery();
 | 
			
		||||
        lqw.eq(bo.getRecruitId() != null, WgzReissueacard::getRecruitId, bo.getRecruitId());
 | 
			
		||||
        lqw.eq(bo.getUserId() != null, WgzReissueacard::getUserId, bo.getUserId());
 | 
			
		||||
        lqw.eq(bo.getAttendanceId() != null, WgzReissueacard::getAttendanceId, bo.getAttendanceId());
 | 
			
		||||
        lqw.eq(StrUtil.isNotBlank(bo.getType()), WgzReissueacard::getType, bo.getType());
 | 
			
		||||
        lqw.like(StrUtil.isNotBlank(bo.getRecruitName()), WgzReissueacard::getRecruitName, bo.getRecruitName());
 | 
			
		||||
        lqw.eq(StrUtil.isNotBlank(bo.getRawTime()), WgzReissueacard::getRawTime, bo.getRawTime());
 | 
			
		||||
        lqw.eq(bo.getNowTime() != null, WgzReissueacard::getNowTime, bo.getNowTime());
 | 
			
		||||
        lqw.eq(StrUtil.isNotBlank(bo.getReason()), WgzReissueacard::getReason, bo.getReason());
 | 
			
		||||
        lqw.eq(bo.getAuditorUserId() != null, WgzReissueacard::getAuditorUserId, bo.getAuditorUserId());
 | 
			
		||||
        lqw.eq(StrUtil.isNotBlank(bo.getAuditorType()), WgzReissueacard::getAuditorType, bo.getAuditorType());
 | 
			
		||||
        lqw.eq(StrUtil.isNotBlank(bo.getAuditorOpinion()), WgzReissueacard::getAuditorOpinion, bo.getAuditorOpinion());
 | 
			
		||||
        lqw.eq(bo.getAuditorTime() != null, WgzReissueacard::getAuditorTime, bo.getAuditorTime());
 | 
			
		||||
        return lqw;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean insert(WgzReissueacard bo) {
 | 
			
		||||
        WgzReissueacard add = BeanUtil.toBean(bo, WgzReissueacard.class);
 | 
			
		||||
        validEntityBeforeSave(add);
 | 
			
		||||
        return save(add);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean update(WgzReissueacard bo) {
 | 
			
		||||
        WgzReissueacard update = BeanUtil.toBean(bo, WgzReissueacard.class);
 | 
			
		||||
        validEntityBeforeSave(update);
 | 
			
		||||
        return updateById(update);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存前的数据校验
 | 
			
		||||
     *
 | 
			
		||||
     * @param entity 实体类数据
 | 
			
		||||
     */
 | 
			
		||||
    private void validEntityBeforeSave(WgzReissueacard entity){
 | 
			
		||||
        //TODO 做一些数据校验,如唯一约束
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
 | 
			
		||||
        if(isValid){
 | 
			
		||||
            //TODO 做一些业务上的校验,判断是否需要校验
 | 
			
		||||
        }
 | 
			
		||||
        return removeByIds(ids);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * APP相关
 | 
			
		||||
	 * =================================================================================================================
 | 
			
		||||
	 * =================================================================================================================
 | 
			
		||||
	 * =================================================================================================================
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	@Transactional
 | 
			
		||||
	public Boolean userCardReplacementApplication(WgzAppCardReplacementApplicationReq req) {
 | 
			
		||||
		//1、获取当前用户信息
 | 
			
		||||
		Long appUserId = SecurityUtils.getAppUserId();
 | 
			
		||||
		//2、获取当前用户所在的工地id
 | 
			
		||||
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
 | 
			
		||||
		//3、根据招工id获取到具体招工信息
 | 
			
		||||
		BgtProjectRecruit appById = iBgtProjectRecruitService.getAppById(by.getId());
 | 
			
		||||
		//4、获取到原打卡的信息
 | 
			
		||||
		WgzAttendance attendanceInfo = iWgzAttendanceService.findById(req.getAttendanceId());
 | 
			
		||||
		if (Objects.isNull(attendanceInfo)) {
 | 
			
		||||
			throw new RuntimeException("打卡信息不存在");
 | 
			
		||||
		}
 | 
			
		||||
		String rawTime = "";
 | 
			
		||||
		if (attendanceInfo.getClockInTime() == null) {
 | 
			
		||||
			rawTime = "缺卡";
 | 
			
		||||
		}else{
 | 
			
		||||
			rawTime = attendanceInfo.getClockInTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
		}
 | 
			
		||||
		//5、组装补卡申请数据
 | 
			
		||||
		WgzReissueacard wgzReissueacard = new WgzReissueacard().
 | 
			
		||||
			setRecruitId(by.getRecruitId()).
 | 
			
		||||
			setUserId(appUserId).
 | 
			
		||||
			setAttendanceId(req.getAttendanceId()).
 | 
			
		||||
			setType(req.getType()).
 | 
			
		||||
			setRecruitName(appById.getRecruitName()).
 | 
			
		||||
			setRawTime(rawTime).
 | 
			
		||||
			setNowTime(req.getNowTime()).
 | 
			
		||||
			setReason(req.getReason()).
 | 
			
		||||
			setAttendanceId(appById.getUserId());
 | 
			
		||||
		return baseMapper.insert(wgzReissueacard) > 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public TableDataInfo<WgzReplacementCardRecordRes> userReplacementCardRecord(WgzAppReplacementCardRecordReq req) {
 | 
			
		||||
		Page<WgzReplacementCardRecordRes> queryDTOPage = new Page<>();
 | 
			
		||||
		queryDTOPage.setCurrent(req.getPageNum());
 | 
			
		||||
		queryDTOPage.setSize(req.getPageSize());
 | 
			
		||||
		return PageUtils.buildDataInfo(baseMapper.userReplacementCardRecordListPage(queryDTOPage));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -116,6 +116,7 @@ public class WgzUserServiceImpl extends ServicePlusImpl<WgzUserMapper, WgzUser>
 | 
			
		||||
 | 
			
		||||
	//注册
 | 
			
		||||
	@Override
 | 
			
		||||
	@Transactional
 | 
			
		||||
	public Boolean userRegister(WgzAppRegisterReq bo) {
 | 
			
		||||
		WgzUser wgzUser = new WgzUser();
 | 
			
		||||
		//1、查询手机号是否存在
 | 
			
		||||
@ -135,6 +136,7 @@ public class WgzUserServiceImpl extends ServicePlusImpl<WgzUserMapper, WgzUser>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	@Transactional
 | 
			
		||||
	public Boolean userModifyingUserProfilePicture(WgzAppModifyingUserProfilePictureReq req) {
 | 
			
		||||
		WgzUser user = new WgzUser();
 | 
			
		||||
		BeanUtils.copyProperties(req, user);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user