From 4ed5025a3a34b95897bdd19a63a3adc7889fe669 Mon Sep 17 00:00:00 2001 From: gaoxiong Date: Mon, 21 Jul 2025 22:46:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=83=E5=8B=A4=E6=89=93=E5=8D=A1=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dite/znpt/converts/Converts.java | 4 + .../domain/entity/AttendanceRecordEntity.java | 54 +++++++++++ .../znpt/domain/vo/AttendanceRecordReq.java | 34 +++++++ .../znpt/domain/vo/AttendanceRecordResp.java | 54 +++++++++++ .../znpt/mapper/AttendanceRecordMapper.java | 12 +++ .../znpt/service/AttendanceRecordService.java | 23 +++++ .../impl/AttendanceRecordServiceImpl.java | 93 +++++++++++++++++++ .../AttendanceRecordController.java | 49 ++++++++++ web/src/main/resources/application.yml | 2 +- 9 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/com/dite/znpt/domain/entity/AttendanceRecordEntity.java create mode 100644 core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordReq.java create mode 100644 core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordResp.java create mode 100644 core/src/main/java/com/dite/znpt/mapper/AttendanceRecordMapper.java create mode 100644 core/src/main/java/com/dite/znpt/service/AttendanceRecordService.java create mode 100644 core/src/main/java/com/dite/znpt/service/impl/AttendanceRecordServiceImpl.java create mode 100644 web/src/main/java/com/dite/znpt/web/controller/AttendanceRecordController.java diff --git a/core/src/main/java/com/dite/znpt/converts/Converts.java b/core/src/main/java/com/dite/znpt/converts/Converts.java index 7154245..9c20029 100644 --- a/core/src/main/java/com/dite/znpt/converts/Converts.java +++ b/core/src/main/java/com/dite/znpt/converts/Converts.java @@ -116,5 +116,9 @@ public interface Converts { InspectionReportReportInfo toInspectionReportReportInfo(InspectionReportEntity entity); List toInspectionReportSchemeInfo(List list); + + AttendanceRecordEntity toAttendanceRecordEntity(AttendanceRecordReq req); + + List toAttendanceRecordResp(List list); } diff --git a/core/src/main/java/com/dite/znpt/domain/entity/AttendanceRecordEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/AttendanceRecordEntity.java new file mode 100644 index 0000000..d6413ee --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/entity/AttendanceRecordEntity.java @@ -0,0 +1,54 @@ +package com.dite.znpt.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dite.znpt.domain.AuditableEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 20:51 + * @Description: + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("attendance_record") +@ApiModel(value="AttendanceRecordEntity对象", description="打卡记录表") +public class AttendanceRecordEntity extends AuditableEntity implements Serializable { + @Serial + private static final long serialVersionUID = 6186237408298557453L; + + @ApiModelProperty("考勤记录id") + @TableId(value = "record_id", type = IdType.ASSIGN_UUID) + private String recordId; + + @ApiModelProperty("考勤人员") + private String userId; + + @ApiModelProperty("记录类型,0-上班,1-下班,2-无效") + private String recordType; + + @ApiModelProperty("考勤日期") + private LocalDate attendanceDate; + + @ApiModelProperty("打卡时间") + private LocalDateTime recordTime; + + @ApiModelProperty("照片") + private String recordImage; + + @ApiModelProperty("打卡地点,经纬度") + private String recordPosition; + + @ApiModelProperty("打卡地点,中文描述") + private String recordPositionLabel; +} diff --git a/core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordReq.java b/core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordReq.java new file mode 100644 index 0000000..e9692f0 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordReq.java @@ -0,0 +1,34 @@ +package com.dite.znpt.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serial; +import java.io.Serializable; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 21:10 + * @Description: + */ +@Data +@ApiModel("考勤记录请求对象") +public class AttendanceRecordReq implements Serializable { + @Serial + private static final long serialVersionUID = 3567864990724491657L; + + @NotBlank(message = "打卡照片不能为空") + @ApiModelProperty("打卡照片") + private String recordImage; + + @NotBlank(message = "打卡地点不能为空") + @ApiModelProperty("打卡地点,经纬度") + private String recordPosition; + + @ApiModelProperty("打卡地点,中文描述") + private String recordPositionLabel; + + +} diff --git a/core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordResp.java b/core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordResp.java new file mode 100644 index 0000000..22d250a --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/vo/AttendanceRecordResp.java @@ -0,0 +1,54 @@ +package com.dite.znpt.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 21:11 + * @Description: + */ +@Data +@ApiModel("考勤记录响应对象") +public class AttendanceRecordResp implements Serializable { + @Serial + private static final long serialVersionUID = -4158464225924809958L; + + + @ApiModelProperty("考勤记录id") + private String recordId; + + @ApiModelProperty("考勤人员id") + private String userId; + + @ApiModelProperty("考勤人员") + private String name; + + @ApiModelProperty("记录类型, 0-上班,1-下班,2-无效") + private String recordType; + + @JsonFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty("考勤日期") + private LocalDate attendanceDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("打卡时间") + private LocalDateTime recordTime; + + @ApiModelProperty("打卡照片") + private String recordImage; + + @ApiModelProperty("打卡地点,经纬度") + private String recordPosition; + + @ApiModelProperty("打卡地点,中文描述") + private String recordPositionLabel; +} diff --git a/core/src/main/java/com/dite/znpt/mapper/AttendanceRecordMapper.java b/core/src/main/java/com/dite/znpt/mapper/AttendanceRecordMapper.java new file mode 100644 index 0000000..30a0de8 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/mapper/AttendanceRecordMapper.java @@ -0,0 +1,12 @@ +package com.dite.znpt.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dite.znpt.domain.entity.AttendanceRecordEntity; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 21:19 + * @Description: + */ +public interface AttendanceRecordMapper extends BaseMapper { +} diff --git a/core/src/main/java/com/dite/znpt/service/AttendanceRecordService.java b/core/src/main/java/com/dite/znpt/service/AttendanceRecordService.java new file mode 100644 index 0000000..99bb6eb --- /dev/null +++ b/core/src/main/java/com/dite/znpt/service/AttendanceRecordService.java @@ -0,0 +1,23 @@ +package com.dite.znpt.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.dite.znpt.domain.entity.AttendanceRecordEntity; +import com.dite.znpt.domain.vo.AttendanceRecordReq; +import com.dite.znpt.domain.vo.AttendanceRecordResp; +import io.swagger.models.auth.In; + +import java.util.List; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 21:20 + * @Description: + */ +public interface AttendanceRecordService extends IService { + + void save(AttendanceRecordReq req); + + List listToday(String userId); + + List listMonth(String userId, Integer year, Integer month); +} diff --git a/core/src/main/java/com/dite/znpt/service/impl/AttendanceRecordServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/AttendanceRecordServiceImpl.java new file mode 100644 index 0000000..9d9cc8f --- /dev/null +++ b/core/src/main/java/com/dite/znpt/service/impl/AttendanceRecordServiceImpl.java @@ -0,0 +1,93 @@ +package com.dite.znpt.service.impl; + +import cn.dev33.satoken.stp.StpUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dite.znpt.constant.Constants; +import com.dite.znpt.constant.Message; +import com.dite.znpt.converts.Converts; +import com.dite.znpt.domain.entity.AttendanceRecordEntity; +import com.dite.znpt.domain.entity.UserEntity; +import com.dite.znpt.domain.vo.AttendanceRecordReq; +import com.dite.znpt.domain.vo.AttendanceRecordResp; +import com.dite.znpt.exception.ServiceException; +import com.dite.znpt.mapper.AttendanceRecordMapper; +import com.dite.znpt.service.AttendanceRecordService; +import com.dite.znpt.service.UserService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 21:20 + * @Description: + */ +@Service +public class AttendanceRecordServiceImpl extends ServiceImpl implements AttendanceRecordService { + + @Resource + private UserService userService; + @Transactional(rollbackFor = Exception.class) + @Override + public void save(AttendanceRecordReq req) { + AttendanceRecordEntity entity = Converts.INSTANCE.toAttendanceRecordEntity(req); + entity.setUserId(StpUtil.getLoginId().toString()); + List list = this.list(Wrappers.lambdaQuery() + .eq(AttendanceRecordEntity::getUserId, entity.getUserId()) + .eq(AttendanceRecordEntity::getAttendanceDate, LocalDate.now()) + .orderByAsc(AttendanceRecordEntity::getCreateTime) + ); + if(list.isEmpty()){ + entity.setRecordType("0"); + }else { + entity.setRecordType("1"); + List invalidRecordList = list.stream().filter(record -> "1".equals(record.getRecordType())).collect(Collectors.toList()); + invalidRecordList.forEach(record -> { + record.setRecordType("2"); + }); + this.updateBatchById(invalidRecordList); + } + this.save(entity); + } + + @Override + public List listToday(String userId) { + List list = Converts.INSTANCE.toAttendanceRecordResp( + this.list(Wrappers.lambdaQuery() + .eq(AttendanceRecordEntity::getUserId, userId) + .eq(AttendanceRecordEntity::getAttendanceDate, LocalDate.now()) + .orderByAsc(AttendanceRecordEntity::getCreateTime) + ) + ); + UserEntity user = userService.getById(userId); + list.forEach(resp -> { + resp.setName(user.getName()); + }); + return list; + } + + @Override + public List listMonth(String userId, Integer year, Integer month) { + LocalDate beginDate = LocalDate.of(year, month, 1); + LocalDate endDate = beginDate.plusMonths(1L); + List list = Converts.INSTANCE.toAttendanceRecordResp( + this.list(Wrappers.lambdaQuery() + .eq(AttendanceRecordEntity::getUserId, userId) + .ge(AttendanceRecordEntity::getAttendanceDate, beginDate) + .lt(AttendanceRecordEntity::getAttendanceDate, endDate) + .orderByAsc(AttendanceRecordEntity::getCreateTime) + ) + ); + UserEntity user = userService.getById(userId); + list.forEach(resp -> { + resp.setName(user.getName()); + }); + return list; + } +} diff --git a/web/src/main/java/com/dite/znpt/web/controller/AttendanceRecordController.java b/web/src/main/java/com/dite/znpt/web/controller/AttendanceRecordController.java new file mode 100644 index 0000000..844c3bb --- /dev/null +++ b/web/src/main/java/com/dite/znpt/web/controller/AttendanceRecordController.java @@ -0,0 +1,49 @@ +package com.dite.znpt.web.controller; + +import cn.dev33.satoken.stp.StpUtil; +import com.dite.znpt.domain.Result; +import com.dite.znpt.domain.vo.AttendanceRecordReq; +import com.dite.znpt.domain.vo.AttendanceRecordResp; +import com.dite.znpt.service.AttendanceRecordService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @Author: gaoxiong + * @Date: 2025/7/21 21:21 + * @Description: + */ +@Api(tags = "考勤记录") +@RestController +@RequestMapping("/attendance-record") +public class AttendanceRecordController { + @Resource + private AttendanceRecordService attendanceRecordService; + + + @ApiOperation(value = "新增考勤记录", httpMethod = "POST") + @PostMapping + public Result add(@Validated @RequestBody AttendanceRecordReq req){ + attendanceRecordService.save(req); + return Result.ok(); + } + + @ApiOperation(value = "查询当天考勤记录", httpMethod = "GET") + @GetMapping("/list-today") + public Result> listToday(){ + String userId = StpUtil.getLoginId().toString(); + return Result.ok(attendanceRecordService.listToday(userId)); + } + + @ApiOperation(value = "按月份查询指定人员考勤记录", httpMethod = "GET") + @GetMapping("/list-month/{year}/{month}") + public Result> listMonth(@PathVariable Integer year, @PathVariable Integer month){ + String userId = StpUtil.getLoginId().toString(); + return Result.ok(attendanceRecordService.listMonth(userId, year, month)); + } +} diff --git a/web/src/main/resources/application.yml b/web/src/main/resources/application.yml index e3bfcc2..694c057 100644 --- a/web/src/main/resources/application.yml +++ b/web/src/main/resources/application.yml @@ -25,6 +25,6 @@ spring: # flowable相关表 flowable: # true 会对数据库中所有表进行更新操作。如果表不存在,则自动创建(建议开发时使用) - database-schema-update: true + database-schema-update: false # 关闭定时任务JOB async-executor-activate: false \ No newline at end of file