| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceMyStatusRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordImportExcelVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordImportReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordRespVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRecordDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAttendanceClockTypeEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.attendance.HrmAttendanceRecordService; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | |
| | | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; |
| | | import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.EMPLOYEE_NOT_EXISTS; |
| | | import static cn.iocoder.yudao.module.hrm.enums.LogRecordConstants.*; |
| | | |
| | |
| | | |
| | | @PostMapping("/clock-in") |
| | | @Operation(summary = "上班打卡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:clock')") |
| | | public CommonResult<HrmAttendanceRecordRespVO> clockIn(@RequestParam("location") String location) { |
| | | Long loginUserId = getLoginUserId(); |
| | | HrmEmployeeDO employee = employeeService.getEmployeeByUserId(loginUserId); |
| | | if (employee == null) { |
| | | throw exception(EMPLOYEE_NOT_EXISTS, "当前用户未关联员工信息,无法打卡"); |
| | | throw exception(EMPLOYEE_NOT_EXISTS, |
| | | "当前登录账号未关联员工档案,无法打卡。请联系管理员在【员工管理】中将该登录账号绑定到员工。"); |
| | | } |
| | | HrmAttendanceRecordDO record = attendanceRecordService.clockIn(employee.getId(), LocalDateTime.now(), location); |
| | | HrmAttendanceRecordRespVO respVO = BeanUtils.toBean(record, HrmAttendanceRecordRespVO.class); |
| | | respVO.setUserName(employee.getName()); |
| | | if (record.getDeptId() != null) { |
| | | DeptRespDTO dept = deptApi.getDept(record.getDeptId()); |
| | | if (dept != null) { |
| | | respVO.setDeptName(dept.getName()); |
| | | } |
| | | } |
| | | return success(respVO); |
| | | return success(buildClockRespVO(record, employee)); |
| | | } |
| | | |
| | | @PostMapping("/clock-out") |
| | | @Operation(summary = "下班打卡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:clock')") |
| | | public CommonResult<HrmAttendanceRecordRespVO> clockOut(@RequestParam("location") String location) { |
| | | Long loginUserId = getLoginUserId(); |
| | | HrmEmployeeDO employee = employeeService.getEmployeeByUserId(loginUserId); |
| | | if (employee == null) { |
| | | throw exception(EMPLOYEE_NOT_EXISTS, "当前用户未关联员工信息,无法打卡"); |
| | | throw exception(EMPLOYEE_NOT_EXISTS, |
| | | "当前登录账号未关联员工档案,无法打卡。请联系管理员在【员工管理】中将该登录账号绑定到员工。"); |
| | | } |
| | | HrmAttendanceRecordDO record = attendanceRecordService.clockOut(employee.getId(), LocalDateTime.now(), location); |
| | | return success(buildClockRespVO(record, employee)); |
| | | } |
| | | |
| | | @GetMapping("/my-status") |
| | | @Operation(summary = "获得当前登录人的考勤状态") |
| | | @Parameter(name = "date", description = "考勤日期,格式 yyyy-MM-dd,默认服务器当天", example = "2026-10-17") |
| | | public CommonResult<HrmAttendanceMyStatusRespVO> getMyStatus( |
| | | @RequestParam(value = "date", required = false) |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) LocalDate date) { |
| | | return success(attendanceRecordService.getMyStatus(getLoginUserId(), date)); |
| | | } |
| | | |
| | | /** |
| | | * 构建打卡返回 VO,字段与 my-status.record 保持一致 |
| | | */ |
| | | private HrmAttendanceRecordRespVO buildClockRespVO(HrmAttendanceRecordDO record, HrmEmployeeDO employee) { |
| | | HrmAttendanceRecordRespVO respVO = BeanUtils.toBean(record, HrmAttendanceRecordRespVO.class); |
| | | respVO.setClockInTypeName(HrmAttendanceClockTypeEnum.getNameByType(record.getClockInType())); |
| | | respVO.setClockOutTypeName(HrmAttendanceClockTypeEnum.getNameByType(record.getClockOutType())); |
| | | respVO.setUserName(employee.getName()); |
| | | if (record.getDeptId() != null) { |
| | | DeptRespDTO dept = deptApi.getDept(record.getDeptId()); |
| | |
| | | respVO.setDeptName(dept.getName()); |
| | | } |
| | | } |
| | | return success(respVO); |
| | | return respVO; |
| | | } |
| | | |
| | | private Long getLoginUserId() { |