diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtAttendanceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtAttendanceController.java index 57982da..009bab0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtAttendanceController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtAttendanceController.java @@ -2,6 +2,8 @@ package com.ruoyi.web.controller.bgt; import com.ruoyi.bgt.domain.dto.BgtAttendanceDTO; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDetailDTO; +import com.ruoyi.bgt.domain.vo.BgtAttendanceDetailVO; import com.ruoyi.bgt.domain.vo.BgtAttendanceVO; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.wgz.service.IWgzAttendanceService; @@ -23,10 +25,16 @@ public class AppBgtAttendanceController { private final IWgzAttendanceService attendanceService; @ApiOperation("App包工头总体考勤情况") - @GetMapping() + @GetMapping("attendance") public AjaxResult attendanceDetail(@Validated BgtAttendanceDTO dto) { return AjaxResult.success(attendanceService.attendanceDetail(dto)); } + @ApiOperation("App包工头考勤统计详情") + @GetMapping("attendanceDetail") + public AjaxResult attendanceDetail(@Validated BgtAttendanceDetailDTO dto) { + return AjaxResult.success(attendanceService.bgtAttendanceDetail(dto)); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtProjectRecruitApplyController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtProjectRecruitApplyController.java index 2277dc2..a8f77b5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtProjectRecruitApplyController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bgt/AppBgtProjectRecruitApplyController.java @@ -1,8 +1,10 @@ package com.ruoyi.web.controller.bgt; import com.ruoyi.bgt.domain.BgtProjectRecruitApply; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDayDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyConsentDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO; +import com.ruoyi.bgt.domain.dto.BgtScoreDTO; import com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO; import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService; import com.ruoyi.common.annotation.Log; @@ -20,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.validation.constraints.NotNull; import java.util.List; /** @@ -40,8 +43,8 @@ public class AppBgtProjectRecruitApplyController extends BaseController { @ApiOperation("App务工者列表") @GetMapping("/list") - public List list(@Validated BgtProjectRecruitApplyQueryDTO dto) { - return iBgtProjectRecruitApplyService.appQueryList(dto); + public AjaxResult> list(@Validated BgtProjectRecruitApplyQueryDTO dto) { + return AjaxResult.success(iBgtProjectRecruitApplyService.appQueryList(dto)); } @ApiOperation("App务工者个人详情") @@ -67,5 +70,28 @@ public class AppBgtProjectRecruitApplyController extends BaseController { } + @ApiOperation("指定日期打卡记录") + @GetMapping("/todayAttendanceList") + public AjaxResult> todayAttendanceList(@Validated BgtAttendanceDayDTO req) { + return AjaxResult.success(iBgtProjectRecruitApplyService.todayAttendanceList(req)); + } + + + @ApiOperation("App务工者退场") + @Log(title = "App务工者退场", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/quit/{id}") + public AjaxResult quit(@NotNull(message = "主键不能为空") + @PathVariable("id") Long id) { + return toAjax(iBgtProjectRecruitApplyService.quit(id) ? 1 : 0); + } + + @ApiOperation("App务工者打分") + @Log(title = "App务工者打分", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/score") + public AjaxResult score(@Validated @RequestBody BgtScoreDTO dto) { + return toAjax(iBgtProjectRecruitApplyService.score(dto) ? 1 : 0); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wgz/controller/WgzScoreRecordController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wgz/controller/WgzScoreRecordController.java new file mode 100644 index 0000000..a0c54c0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wgz/controller/WgzScoreRecordController.java @@ -0,0 +1,109 @@ +package com.ruoyi.web.controller.wgz.controller; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.wgz.bo.WgzScoreRecordQueryBo; +import com.ruoyi.wgz.domain.WgzScoreRecord; +import com.ruoyi.wgz.service.IWgzScoreRecordService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 务工者评分记录Controller + * + * @author ruoyi + * @date 2025-02-21 + */ +@Api(value = "务工者评分记录控制器", tags = {"务工者评分记录管理"}) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@RestController +@RequestMapping("/wgz/record") +public class WgzScoreRecordController extends BaseController { + + private final IWgzScoreRecordService iWgzScoreRecordService; + + /** + * 查询务工者评分记录列表 + */ + @ApiOperation("查询务工者评分记录列表") + @PreAuthorize("@ss.hasPermi('wgz:record:list')") + @GetMapping("/list") + public TableDataInfo list(@Validated WgzScoreRecordQueryBo bo) { + return iWgzScoreRecordService.queryPageList(bo); + } + + /** + * 导出务工者评分记录列表 + */ + @ApiOperation("导出务工者评分记录列表") + @PreAuthorize("@ss.hasPermi('wgz:record:export')") + @Log(title = "务工者评分记录", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public AjaxResult export(@Validated WgzScoreRecordQueryBo bo) { + List list = iWgzScoreRecordService.queryList(bo); + ExcelUtil util = new ExcelUtil(WgzScoreRecord.class); + return util.exportExcel(list, "务工者评分记录"); + } + + /** + * 获取务工者评分记录详细信息 + */ + @ApiOperation("获取务工者评分记录详细信息") + @PreAuthorize("@ss.hasPermi('wgz:record:query')") + @GetMapping("/{id}") + public AjaxResult getInfo(@NotNull(message = "主键不能为空") + @PathVariable("id") Long id) { + return AjaxResult.success(iWgzScoreRecordService.queryById(id)); + } + + /** + * 新增务工者评分记录 + */ + @ApiOperation("新增务工者评分记录") + @PreAuthorize("@ss.hasPermi('wgz:record:add')") + @Log(title = "务工者评分记录", businessType = BusinessType.INSERT) + @RepeatSubmit + @PostMapping() + public AjaxResult add(@Validated @RequestBody WgzScoreRecord bo) { + return toAjax(iWgzScoreRecordService.insert(bo) ? 1 : 0); + } + + /** + * 修改务工者评分记录 + */ + @ApiOperation("修改务工者评分记录") + @PreAuthorize("@ss.hasPermi('wgz:record:edit')") + @Log(title = "务工者评分记录", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping() + public AjaxResult edit(@Validated @RequestBody WgzScoreRecord bo) { + return toAjax(iWgzScoreRecordService.update(bo) ? 1 : 0); + } + + /** + * 删除务工者评分记录 + */ + @ApiOperation("删除务工者评分记录") + @PreAuthorize("@ss.hasPermi('wgz:record:remove')") + @Log(title = "务工者评分记录" , businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(iWgzScoreRecordService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/RecruitApplyStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/RecruitApplyStatus.java index 902ca20..3890ed1 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/RecruitApplyStatus.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/RecruitApplyStatus.java @@ -7,7 +7,14 @@ package com.ruoyi.common.enums; */ public enum RecruitApplyStatus { - TO_PASS("0", "未选择"), PASS("1", "已选择"), ; + SIGN_UP("0", "报名"), + BGT_PASS("1", "包工头同意"), + BGT_REFUSE("2", "包工头拒绝"), + WGZ_PASS("3", "务工者同意"), + WGZ_REFUSE("4", "务工者拒绝"), + WORKING("5", "进场"), + OUT_WORK("6", "离场"), + ; private final String code; private final String info; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 066f073..1651257 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -24,6 +24,10 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + public static String DAY = "1"; + + public static String MONTH = "2"; + private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/BgtProjectRecruit.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/BgtProjectRecruit.java index ffc0c4e..9010146 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/BgtProjectRecruit.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/BgtProjectRecruit.java @@ -10,6 +10,7 @@ import lombok.experimental.Accessors; import java.io.Serializable; import java.math.BigDecimal; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -94,9 +95,14 @@ public class BgtProjectRecruit implements Serializable { /** * 招工开始时间 */ - @Excel(name = "招工开始时间") @ApiModelProperty("招工开始时间") - private String recruitBeginTime; + private LocalDate recruitBeginTime; + + @ApiModelProperty("招工结束时间") + private LocalDate recruitEndTime; + + @ApiModelProperty("招工开工时间") + private LocalDate recruitWorkBeginTime; /** * 联系人 diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDTO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDTO.java index 4a970d9..c1ed028 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDTO.java @@ -1,10 +1,14 @@ package com.ruoyi.bgt.domain.dto; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; @Data @NoArgsConstructor @@ -15,8 +19,10 @@ public class BgtAttendanceDTO { @ApiModelProperty("任务ID") private Long taskId; + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") @ApiModelProperty("日期") - private String date; + private LocalDate date; @ApiModelProperty("日期类型(1日 2月)") private String dateType; diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDayDTO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDayDTO.java new file mode 100644 index 0000000..3ec9ee1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDayDTO.java @@ -0,0 +1,27 @@ +package com.ruoyi.bgt.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +@Data +@NoArgsConstructor +@Accessors(chain = true) +@ApiModel("App包工头总体考勤查询对象") +public class BgtAttendanceDayDTO { + + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty("日期") + private LocalDate date; + + @ApiModelProperty("考勤类型(1出勤 2缺勤 3迟到)") + private Integer attendanceType; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDetailDTO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDetailDTO.java new file mode 100644 index 0000000..5b20b63 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtAttendanceDetailDTO.java @@ -0,0 +1,30 @@ +package com.ruoyi.bgt.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +@Data +@NoArgsConstructor +@Accessors(chain = true) +@ApiModel("App包工头总体考勤查询对象") +public class BgtAttendanceDetailDTO { + + @ApiModelProperty("务工者ID") + private Long userId; + + @ApiModelProperty("任务Id") + private Long taskId; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty("日期") + private LocalDate date; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitApplyQueryDTO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitApplyQueryDTO.java index b419069..8d81942 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitApplyQueryDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitApplyQueryDTO.java @@ -18,8 +18,8 @@ public class BgtProjectRecruitApplyQueryDTO extends BaseEntity { @NotEmpty(message = "招工ID列表不能为空") private List recruitIds; - @ApiModelProperty("选择状态(0未选择 1已选择)") - private String status; + @ApiModelProperty("选择状态(0报名 1包工同意 2包工头拒绝(截止时间)3务工者同意 4务工者拒绝 5进场 6离场)") + private List status; @ApiModelProperty("务工者名字") private String username; diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitQueryDTO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitQueryDTO.java index f01fb0d..5eee471 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitQueryDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtProjectRecruitQueryDTO.java @@ -6,6 +6,8 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; + /** * 包工头招工分页查询对象 bgt_project_recruit * @@ -31,8 +33,8 @@ public class BgtProjectRecruitQueryDTO extends BaseEntity { @ApiModelProperty("招工名称") private String recruitName; - @ApiModelProperty("选择状态(0未选择 1已选择)") - private String status; + @ApiModelProperty("选择状态(0报名 1包工同意 2包工头拒绝(截止时间)3务工者同意 4务工者拒绝 5进场 6离场)") + private List status; // /** 项目ID */ // @ApiModelProperty("项目ID") diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtScoreDTO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtScoreDTO.java new file mode 100644 index 0000000..881c6f1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/dto/BgtScoreDTO.java @@ -0,0 +1,31 @@ +package com.ruoyi.bgt.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@NoArgsConstructor +@Accessors(chain = true) +@ApiModel("App包工头打分对象") +public class BgtScoreDTO { + /** 招工ID */ + @ApiModelProperty("招工ID") + private Long recruitId; + /** 被评人ID(务工者) */ + @ApiModelProperty("被评人ID(务工者)") + private Long userId; + /** 打分人ID(包工头) */ + @ApiModelProperty("打分人ID(包工头)") + private Long scoreBy; + /** 评分 */ + @ApiModelProperty("评分") + private BigDecimal score; + /** 评分内容 */ + @ApiModelProperty("评分内容") + private String content; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceCountVO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceCountVO.java index 39c2ce5..e910c7b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceCountVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceCountVO.java @@ -2,6 +2,7 @@ package com.ruoyi.bgt.domain.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; @@ -17,6 +18,7 @@ import java.time.LocalDate; */ @Data @NoArgsConstructor +@AllArgsConstructor @Accessors(chain = true) @ApiModel("包工头考勤打卡统计对象") public class BgtAttendanceCountVO implements Serializable { @@ -32,5 +34,8 @@ public class BgtAttendanceCountVO implements Serializable { @ApiModelProperty("日期") private LocalDate date; + @ApiModelProperty("缺勤人数") + private Integer absenceDutyNum; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceDetailVO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceDetailVO.java new file mode 100644 index 0000000..28d41b3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceDetailVO.java @@ -0,0 +1,63 @@ +package com.ruoyi.bgt.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.time.LocalDate; +import java.util.List; + +@Data +@NoArgsConstructor +@Accessors(chain = true) +@ApiModel("App包工头总体考勤视图对象") +public class BgtAttendanceDetailVO { + + @ApiModelProperty("务工者Id") + private Long userId; + + @ApiModelProperty("姓名") + private String username; + + @ApiModelProperty("头像") + private String avatarName; + + @ApiModelProperty("进场时间") + private LocalDate entryTime; + + @ApiModelProperty("选择状态(0未选择 1已选择)") + private String status; + + @ApiModelProperty("出勤天数") + private Double dayNum=0D; + + @ApiModelProperty("迟到次数") + private Integer lateNum = 0; + + @ApiModelProperty("迟到分钟") + private Integer lateMinute = 0; + + @ApiModelProperty("迟到记录") + private List lateRecords; + + @ApiModelProperty("早退次数") + private Integer earlyLeaveNum = 0; + + @ApiModelProperty("早退分钟") + private Integer earlyLeaveMinute = 0; + + @ApiModelProperty("早退记录") + private List earlyLeaveRecords; + + @ApiModelProperty("缺卡次数") + private Integer missNum = 0; + + @ApiModelProperty("缺卡记录") + private List missRecords; + + @ApiModelProperty("考勤记录") + private List records; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceVO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceVO.java index 4039086..e1cd850 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtAttendanceVO.java @@ -21,22 +21,25 @@ public class BgtAttendanceVO { private String taskName; @ApiModelProperty("到岗人数") - private Integer reportToDutyNum; + private Integer reportToDutyNum = 0; @ApiModelProperty("总人数") - private Integer totalNum; + private Integer totalNum = 0; @ApiModelProperty("缺勤人数") - private Integer absenceDutyNum; + private Integer absenceDutyNum = 0; @ApiModelProperty("请假人数") - private Integer leaveNum; + private Integer leaveNum = 0; @ApiModelProperty("迟到人数") - private Integer lateNum; + private Integer lateNum = 0; + + @ApiModelProperty("外勤人数") + private Integer outDutyNum = 0; @ApiModelProperty("考勤列表") - List countVOS; + List countVOs; //务工者列表 @ApiModelProperty("申请者列表") diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitApplyVO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitApplyVO.java index 8589658..872d42d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitApplyVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitApplyVO.java @@ -1,5 +1,6 @@ package com.ruoyi.bgt.domain.vo; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -7,6 +8,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; +import java.time.LocalDate; /** * 包工头招工申请对象 bgt_project_recruit_apply @@ -25,6 +27,10 @@ public class BgtProjectRecruitApplyVO implements Serializable { @ApiModelProperty("主键ID") private Long id; + @ApiModelProperty("进场时间") + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate entryTime; + @ApiModelProperty("务工者用户ID") private Long userId; @@ -40,4 +46,14 @@ public class BgtProjectRecruitApplyVO implements Serializable { @ApiModelProperty("头像") private String avatarName; + @ApiModelProperty("工种") + private String typeOfWork; + + @ApiModelProperty("招工主题") + private String recruitName; + + @ApiModelProperty("任务名") + private String taskName; + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitDetailVO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitDetailVO.java index 6d997e1..47a425a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitDetailVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/BgtProjectRecruitDetailVO.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -60,8 +61,15 @@ public class BgtProjectRecruitDetailVO implements Serializable { @ApiModelProperty("招工数量") private Integer recruitStaffNum; - @ApiModelProperty("招工开始时间") - private String recruitBeginTime; + + @ApiModelProperty("招工开始时间") + private LocalDate recruitBeginTime; + + @ApiModelProperty("招工结束时间") + private LocalDate recruitEndTime; + + @ApiModelProperty("招工开工时间") + private LocalDate recruitWorkBeginTime; @ApiModelProperty("联系人") private String recruitContactPerson; diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/WgzAttendanceRecordVO.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/WgzAttendanceRecordVO.java new file mode 100644 index 0000000..c3f3950 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/domain/vo/WgzAttendanceRecordVO.java @@ -0,0 +1,45 @@ +package com.ruoyi.bgt.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalTime; + +/** + * 考勤打卡对象 wgz_attendance + * + * @author ruoyi + * @date 2025-02-20 + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +@ApiModel("考勤打卡视图对象") +public class WgzAttendanceRecordVO implements Serializable { + + private static final long serialVersionUID=1L; + + + @ApiModelProperty("打卡日期") + private LocalDate date; + + @ApiModelProperty("星期") + private String week; + + @ApiModelProperty("天数") + private Double day; + + @ApiModelProperty("时间") + @JsonFormat(pattern = "HH:mm") + private LocalTime time; + + @ApiModelProperty("分钟") + private Integer minutes; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/mapper/BgtProjectRecruitApplyMapper.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/mapper/BgtProjectRecruitApplyMapper.java index b94fc14..1b5d987 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/mapper/BgtProjectRecruitApplyMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/mapper/BgtProjectRecruitApplyMapper.java @@ -2,10 +2,11 @@ package com.ruoyi.bgt.mapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.bgt.domain.BgtProjectRecruitApply; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDayDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO; import com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO; -import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache; +import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import com.ruoyi.wgz.bo.req.WgzAppUnderwayReq; import com.ruoyi.wgz.bo.res.WgzAppUnderwayRes; import org.apache.ibatis.annotations.CacheNamespace; @@ -25,6 +26,8 @@ public interface BgtProjectRecruitApplyMapper extends BaseMapperPlus appQueryList(@Param("dto") BgtProjectRecruitApplyQueryDTO dto); + List todayAttendanceList(@Param("dto") BgtAttendanceDayDTO dto); + // 获取指定项目下的所有成员(分页) Page underwayPage (@Param("page") Page page, @Param("userId") Long userId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/service/IBgtProjectRecruitApplyService.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/service/IBgtProjectRecruitApplyService.java index 886dad7..3329d7a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/service/IBgtProjectRecruitApplyService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/service/IBgtProjectRecruitApplyService.java @@ -2,11 +2,15 @@ package com.ruoyi.bgt.service; import com.ruoyi.bgt.bo.BgtProjectRecruitApplyQueryBo; import com.ruoyi.bgt.domain.BgtProjectRecruitApply; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDayDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyConsentDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO; +import com.ruoyi.bgt.domain.dto.BgtScoreDTO; import com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO; 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 com.ruoyi.wgz.bo.req.WgzAppUnderwayReq; import com.ruoyi.wgz.bo.res.WgzAppUnderwayRes; import org.springframework.validation.annotation.Validated; @@ -81,12 +85,26 @@ public interface IBgtProjectRecruitApplyService extends IServicePlus todayAttendanceList(BgtAttendanceDayDTO dto); + + /** + * 退场 + */ + Boolean quit(Long id); + + /** + * 评分 + */ + Boolean score(@Validated @RequestBody BgtScoreDTO dto); + /** * 务工者取消报名 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitApplyServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitApplyServiceImpl.java index 38c8c22..7a69a65 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitApplyServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitApplyServiceImpl.java @@ -8,8 +8,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.bgt.bo.BgtProjectRecruitApplyQueryBo; import com.ruoyi.bgt.domain.BgtProjectRecruitApply; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDayDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyConsentDTO; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO; +import com.ruoyi.bgt.domain.dto.BgtScoreDTO; import com.ruoyi.bgt.domain.vo.BgtProjectRecruitApplyVO; import com.ruoyi.bgt.mapper.BgtProjectRecruitApplyMapper; import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService; @@ -23,10 +25,17 @@ import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.wgz.bo.req.WgzAppRegisteredProjectReq; import com.ruoyi.wgz.bo.req.WgzAppUnderwayReq; import com.ruoyi.wgz.bo.res.WgzAppUnderwayRes; +import com.ruoyi.wgz.domain.WgzScoreRecord; +import com.ruoyi.wgz.domain.WgzUser; +import com.ruoyi.wgz.service.IWgzScoreRecordService; +import com.ruoyi.wgz.service.IWgzUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -43,6 +52,10 @@ public class BgtProjectRecruitApplyServiceImpl extends ServicePlusImpl list = baseMapper.selectList(Wrappers.lambdaQuery() .eq(BgtProjectRecruitApply::getUserId, recruitApply.getUserId()) - .eq(BgtProjectRecruitApply::getStatus,RecruitApplyStatus.PASS.getCode()) + .in(BgtProjectRecruitApply::getStatus, Arrays.asList(RecruitApplyStatus.WGZ_PASS.getCode(), RecruitApplyStatus.WORKING.getCode())) .isNotNull(BgtProjectRecruitApply::getLeaveTime)); if(CollectionUtil.isNotEmpty(list)){ throw new BaseException("该务工者已进入其他工地"); } recruitApply.setEntryTime(dto.getEntryTime()); - recruitApply.setStatus(RecruitApplyStatus.PASS.getCode()); + recruitApply.setStatus(RecruitApplyStatus.BGT_PASS.getCode()); dto.getEntryMaterials().addAll(dto.getInsurances()); annexService.insertBatch(dto.getEntryMaterials()); return updateById(recruitApply); @@ -173,6 +186,37 @@ public class BgtProjectRecruitApplyServiceImpl extends ServicePlusImpl0; } + public List todayAttendanceList(BgtAttendanceDayDTO dto){ + return baseMapper.todayAttendanceList(dto); + } + + @Override + public Boolean quit(Long id) { + return super.lambdaUpdate().eq(BgtProjectRecruitApply::getId, id) + .set(BgtProjectRecruitApply::getLeaveTime, LocalDate.now()) + .set(BgtProjectRecruitApply::getStatus, RecruitApplyStatus.OUT_WORK.getCode()) + .update(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean score(BgtScoreDTO dto) { + dto.setScoreBy(SecurityUtils.getAppUserId()); + Boolean insert = scoreRecordService.insert(BeanUtil.copyProperties(dto, WgzScoreRecord.class)); + + List wgzScoreRecords = scoreRecordService.getBaseMapper().selectList(Wrappers.lambdaQuery() + .eq(WgzScoreRecord::getUserId, dto.getUserId())); + double rawNewScore = wgzScoreRecords.stream() + .mapToDouble(WgzScoreRecord::getScore) + .sum(); + // 使用 DecimalFormat 格式化结果 + DecimalFormat df = new DecimalFormat("#.0"); + String formatted = df.format(rawNewScore); + Double newScore = Double.parseDouble(formatted); + //更新务工者 + wgzUserService.lambdaUpdate().set(WgzUser::getScore, newScore).eq(WgzUser::getUserId, dto.getUserId()).update(); + return insert; + } @Override @Transactional public Boolean userCancelRegistration(Long recruitId) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitServiceImpl.java index 8d35d87..15a209c 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/bgt/service/impl/BgtProjectRecruitServiceImpl.java @@ -139,7 +139,7 @@ public class BgtProjectRecruitServiceImpl extends ServicePlusImpl fillMissingDates(List countVOS, LocalDate startDate, LocalDate endDate) { + // 使用 HashSet 存储已有的日期,方便快速查找 + Set existingDates = new HashSet<>(); + for (BgtAttendanceCountVO vo : countVOS) { + existingDates.add(vo.getDate()); + } + + // 创建一个新的列表,用于存储补充后的结果 + List filledList = new ArrayList<>(countVOS); + + // 遍历日期范围,补充缺失的日期 + LocalDate currentDate = startDate; + while (!currentDate.isAfter(endDate)) { + if (!existingDates.contains(currentDate)) { + // 如果当前日期不在已有日期集合中,创建一个新的 BgtAttendanceCountVO 对象并添加到结果列表中 + filledList.add(new BgtAttendanceCountVO(0,0,currentDate,0)); + } + // 日期递增一天 + currentDate = currentDate.plusDays(1); + } + + // 对结果列表按日期排序 + filledList.sort(Comparator.comparing(BgtAttendanceCountVO::getDate)); + + return filledList; + } + + + public static List statisticsByMonth(List countVOS, LocalDate startDate, LocalDate endDate) { + // 用于存储每个月的统计结果 + Map monthMap = new TreeMap<>(); + + // 遍历所有的 BgtAttendanceCountVO 对象 + for (BgtAttendanceCountVO countVO : countVOS) { + LocalDate date = countVO.getDate(); + YearMonth yearMonth = YearMonth.from(date); + + // 如果该月份已经在 map 中,则累加该月份的到岗人数和总人数 + if (monthMap.containsKey(yearMonth)) { + BgtAttendanceCountVO existingVO = monthMap.get(yearMonth); + existingVO.setReportToDutyNum(existingVO.getReportToDutyNum() + countVO.getReportToDutyNum()); + existingVO.setTotalNum(existingVO.getTotalNum()>countVO.getTotalNum()?existingVO.getTotalNum():countVO.getTotalNum()); + existingVO.setAbsenceDutyNum(existingVO.getAbsenceDutyNum() + countVO.getTotalNum()-countVO.getReportToDutyNum()); + } else { + // 如果该月份不在 map 中,则创建一个新的 BgtAttendanceCountVO 对象 + BgtAttendanceCountVO newVO = new BgtAttendanceCountVO(countVO.getReportToDutyNum(), countVO.getTotalNum(), date.withDayOfMonth(1),0); + monthMap.put(yearMonth, newVO); + } + } + + // 找出日期范围的起始月份和结束月份 + if (monthMap.isEmpty()) { + return new ArrayList<>(); + } + YearMonth startMonth = YearMonth.from(startDate); + YearMonth endMonth = YearMonth.from(endDate); + + // 补足空白月份 + List result = new ArrayList<>(); + for (YearMonth currentMonth = startMonth; !currentMonth.isAfter(endMonth); currentMonth = currentMonth.plusMonths(1)) { + if (monthMap.containsKey(currentMonth)) { + result.add(monthMap.get(currentMonth)); + } else { + // 如果该月份没有统计数据,则创建一个新的 BgtAttendanceCountVO 对象,将到岗人数和总人数都设置为 0 + BgtAttendanceCountVO emptyVO = new BgtAttendanceCountVO(0, 0, currentMonth.atDay(1),0); + result.add(emptyVO); + } + } + + return result; + } + + + public static Integer getMinutes(LocalDateTime clockInTime,LocalTime beginWorkTime){ + LocalDateTime workDateTime = LocalDateTime.of(clockInTime.toLocalDate(), beginWorkTime); + + // 计算两个 LocalDateTime 对象之间的时间差 + Duration duration = Duration.between(workDateTime, clockInTime); + + // 将时间差转换为分钟数 + long minutes = duration.toMinutes(); + return (int) minutes; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/fbs/service/impl/FbsProjectTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/fbs/service/impl/FbsProjectTaskServiceImpl.java index bb692cf..c9685fa 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/fbs/service/impl/FbsProjectTaskServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/fbs/service/impl/FbsProjectTaskServiceImpl.java @@ -11,6 +11,7 @@ import com.ruoyi.bgt.bo.BgtProjectRecruitQueryBo; import com.ruoyi.bgt.domain.BgtProjectRecruit; import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO; import com.ruoyi.bgt.domain.dto.BgtWageApplicationQueryDTO; +import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO; import com.ruoyi.bgt.domain.vo.BgtWageApplicationListVO; import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService; import com.ruoyi.bgt.service.IBgtProjectRecruitService; @@ -21,6 +22,7 @@ import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.AuditStatus; import com.ruoyi.common.enums.ProjectTaskStatus; import com.ruoyi.common.enums.RecruitApplyStatus; +import com.ruoyi.common.util.DataUtil; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.fbs.bo.FbsProjectTaskQueryBo; import com.ruoyi.fbs.domain.FbsProjectTask; @@ -30,7 +32,6 @@ import com.ruoyi.fbs.domain.vo.AppTaskVO; import com.ruoyi.fbs.mapper.FbsProjectTaskMapper; import com.ruoyi.fbs.service.IFbsProjectTaskApplyService; import com.ruoyi.fbs.service.IFbsProjectTaskService; -import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO; import com.ruoyi.wgz.service.IWgzAttendanceService; import com.ruoyi.zbf.domain.ZbfProject; import com.ruoyi.zbf.service.IZbfProjectService; @@ -39,9 +40,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import java.time.LocalDate; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -163,7 +162,7 @@ public class FbsProjectTaskServiceImpl extends ServicePlusImpl countVOS = attendanceService.countByTaskId(id, startOfMonth, date); if(CollectionUtil.isNotEmpty(countVOS)){ BgtAttendanceCountVO vo = countVOS.get(0); - appTaskDetailVO.setCountVOS(countVOS); + appTaskDetailVO.setCountVOS(DataUtil.fillMissingDates(countVOS, startOfMonth, date)); appTaskDetailVO.setTotalNum(vo.getTotalNum()); appTaskDetailVO.setReportToDutyNum(vo.getReportToDutyNum()); appTaskDetailVO.setReportToDutyRate(vo.getReportToDutyNum()/vo.getTotalNum()*100); @@ -195,4 +194,6 @@ public class FbsProjectTaskServiceImpl extends ServicePlusImpl { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzAttendanceService.java b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzAttendanceService.java index 4ea5808..9f2a37f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzAttendanceService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzAttendanceService.java @@ -1,19 +1,17 @@ package com.ruoyi.wgz.service; import com.ruoyi.bgt.domain.dto.BgtAttendanceDTO; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDetailDTO; import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO; +import com.ruoyi.bgt.domain.vo.BgtAttendanceDetailVO; import com.ruoyi.bgt.domain.vo.BgtAttendanceVO; -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; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.wgz.bo.WgzAttendanceQueryBo; 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 org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; @@ -120,4 +118,9 @@ public interface IWgzAttendanceService extends IServicePlus { */ Integer attendanceDetail(Long userId,Long recruitId, Integer num); + /** + * 考勤统计详情 + */ + BgtAttendanceDetailVO bgtAttendanceDetail(BgtAttendanceDetailDTO dto); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzScoreRecordService.java b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzScoreRecordService.java new file mode 100644 index 0000000..3c6c5ba --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/IWgzScoreRecordService.java @@ -0,0 +1,55 @@ +package com.ruoyi.wgz.service; + +import com.ruoyi.wgz.domain.WgzScoreRecord; +import com.ruoyi.wgz.bo.WgzScoreRecordQueryBo; +import com.ruoyi.common.core.mybatisplus.core.IServicePlus; +import com.ruoyi.common.core.page.TableDataInfo; + +import java.util.Collection; +import java.util.List; + +/** + * 务工者评分记录Service接口 + * + * @author ruoyi + * @date 2025-02-21 + */ +public interface IWgzScoreRecordService extends IServicePlus { + /** + * 查询单个 + * @return + */ + WgzScoreRecord queryById(Long id); + + /** + * 查询列表 + */ + TableDataInfo queryPageList(WgzScoreRecordQueryBo bo); + + /** + * 查询列表 + */ + List queryList(WgzScoreRecordQueryBo bo); + + /** + * 根据新增业务对象插入务工者评分记录 + * @param bo 务工者评分记录新增业务对象 + * @return + */ + Boolean insert(WgzScoreRecord bo); + + /** + * 根据编辑业务对象修改务工者评分记录 + * @param bo 务工者评分记录编辑业务对象 + * @return + */ + Boolean update(WgzScoreRecord bo); + + /** + * 校验并删除数据 + * @param ids 主键集合 + * @param isValid 是否校验,true-删除前校验,false-不校验 + * @return + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzAttendanceServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzAttendanceServiceImpl.java index 9e3709a..9c501ff 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzAttendanceServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzAttendanceServiceImpl.java @@ -1,6 +1,7 @@ package com.ruoyi.wgz.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -8,13 +9,21 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.bgt.domain.BgtProjectRecruit; import com.ruoyi.bgt.domain.BgtProjectRecruitApply; import com.ruoyi.bgt.domain.dto.BgtAttendanceDTO; +import com.ruoyi.bgt.domain.dto.BgtAttendanceDetailDTO; +import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO; +import com.ruoyi.bgt.domain.vo.BgtAttendanceDetailVO; import com.ruoyi.bgt.domain.vo.BgtAttendanceVO; +import com.ruoyi.bgt.domain.vo.WgzAttendanceRecordVO; import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService; import com.ruoyi.bgt.service.IBgtProjectRecruitService; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.util.DataUtil; +import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.fbs.domain.FbsProjectTask; +import com.ruoyi.fbs.service.IFbsProjectTaskService; import com.ruoyi.wgz.bo.WgzAttendanceQueryBo; import com.ruoyi.wgz.bo.req.WgzAppSubmitTheClockReq; import com.ruoyi.wgz.bo.res.WgzAppCardReplacementApplicationRes; @@ -24,24 +33,22 @@ 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.WgzAttendance; -import com.ruoyi.wgz.domain.WgzLeave; -import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO; +import com.ruoyi.wgz.domain.WgzUser; import com.ruoyi.wgz.mapper.WgzAttendanceMapper; import com.ruoyi.wgz.service.IWgzAttendanceService; import com.ruoyi.wgz.service.IWgzLeaveService; -import org.aspectj.weaver.ast.Var; +import com.ruoyi.wgz.service.IWgzUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAdjusters; import java.util.*; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.stream.Collectors; /** * 考勤打卡Service业务层处理 @@ -65,6 +72,12 @@ public class WgzAttendanceServiceImpl extends ServicePlusImpl countByTaskId(Long taskId, LocalDate beginDate, LocalDate endDate) { return baseMapper.countByTaskId(taskId, beginDate, endDate); @@ -332,14 +346,62 @@ public class WgzAttendanceServiceImpl extends ServicePlusImpl countVOS = countByTaskId(dto.getTaskId(), startData, endData); + if(CollectionUtil.isNotEmpty(countVOS)){ + bgtAttendanceVO.setCountVOs(DataUtil.fillMissingDates(countVOS, startData, endData)); + BgtAttendanceCountVO countVO = countVOS.stream() + .filter(vo -> vo.getDate().isEqual(date)) + .findFirst().orElse(null); + bgtAttendanceVO.setReportToDutyNum(countVO.getReportToDutyNum()); + bgtAttendanceVO.setTotalNum(countVO.getTotalNum()); + bgtAttendanceVO.setAbsenceDutyNum(countVO.getTotalNum()-countVO.getReportToDutyNum()); + } + }else if(dto.getDateType().equals(DateUtils.MONTH)){ + // 获取本年开始日期 + startData = date.with(TemporalAdjusters.firstDayOfYear()); + endData = date.with(TemporalAdjusters.lastDayOfMonth()); + List countVOS = countByTaskId(dto.getTaskId(), startData, endData); + if(CollectionUtil.isNotEmpty(countVOS)){ + bgtAttendanceVO.setCountVOs(DataUtil.statisticsByMonth(countVOS,startData, endData)); + } + BgtAttendanceCountVO countVO = countVOS.stream() + .filter(vo -> YearMonth.from(vo.getDate()).equals(YearMonth.from(date))) + .findFirst().orElse(null); + bgtAttendanceVO.setReportToDutyNum(countVO.getReportToDutyNum()); + bgtAttendanceVO.setTotalNum(countVO.getTotalNum()); + bgtAttendanceVO.setAbsenceDutyNum(countVO.getAbsenceDutyNum()); + } + getLateAndLeave(bgtAttendanceVO, startData, endData); + return bgtAttendanceVO; } - // @Override + public void getLateAndLeave(BgtAttendanceVO vo,LocalDate startDate, LocalDate endDate){ + List bgtProjectRecruits = iBgtProjectRecruitService.getBaseMapper().selectList(Wrappers.lambdaQuery() + .eq(BgtProjectRecruit::getTaskId, vo.getTaskId())); + List recruitIds = bgtProjectRecruits.stream().map(BgtProjectRecruit::getId).collect(Collectors.toList()); + Integer late = baseMapper.selectCount(Wrappers.lambdaQuery().eq(WgzAttendance::getLate, 1) + .in(WgzAttendance::getRecruitId, recruitIds).between(WgzAttendance::getDate, startDate, endDate)); + Integer leave = baseMapper.selectCount(Wrappers.lambdaQuery().isNotNull(WgzAttendance::getLeaveMarkId) + .in(WgzAttendance::getRecruitId, recruitIds).between(WgzAttendance::getDate, startDate, endDate)); + vo.setLateNum(late); + vo.setLeaveNum(leave); + } + +// @Override // public WgzAttendance findByUserIdWait(Long appUserId, Long recruitId, String date) { // LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); // qw.eq(WgzAttendance::getRecruitId,recruitId); @@ -444,4 +506,105 @@ public class WgzAttendanceServiceImpl extends ServicePlusImpl bgtProjectRecruits = iBgtProjectRecruitService.getBaseMapper().selectList(Wrappers.lambdaQuery() + .eq(BgtProjectRecruit::getTaskId, dto.getTaskId())); + List recruitIds = bgtProjectRecruits.stream().map(BgtProjectRecruit::getId).collect(Collectors.toList()); + + BgtProjectRecruitApply recruitApply = iBgtProjectRecruitApplyService.getById(recruitIds.get(0)); + bgtAttendanceDetailVO.setEntryTime(recruitApply.getEntryTime()); + bgtAttendanceDetailVO.setStatus(recruitApply.getStatus()); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(WgzAttendance::getUserId,dto.getUserId()); + + wrapper.in(WgzAttendance::getRecruitId,recruitIds); + LocalDate date = dto.getDate(); + LocalDate startDate = date.with(TemporalAdjusters.firstDayOfMonth()); + LocalDate endData = date.with(TemporalAdjusters.lastDayOfMonth()); + wrapper.between(WgzAttendance::getDate,startDate,endData); + List wgzAttendances = baseMapper.selectList(wrapper); + // 创建SimpleDateFormat对象,格式化日期为中文星期 + SimpleDateFormat sdf = new SimpleDateFormat("EEEE", java.util.Locale.CHINESE); + + //获取招工打卡时间 + List list = iBgtProjectRecruitService.list(Wrappers.lambdaQuery().in(BgtProjectRecruit::getId)); + Map recruitMap = list.stream().collect(Collectors.toMap(BgtProjectRecruit::getId, recruit -> recruit)); + + + List lateRecords = new ArrayList<>(); + List earlyLeaveRecords= new ArrayList<>(); + List missRecords= new ArrayList<>(); + List records= new ArrayList<>(); + + + for (WgzAttendance wgzAttendance:wgzAttendances){ + WgzAttendanceRecordVO recordVO = new WgzAttendanceRecordVO(); + recordVO.setDate(wgzAttendance.getDate()); + recordVO.setWeek(sdf.format(date)); + if(wgzAttendance.getMissedIn()==0 && wgzAttendance.getMissedOut()==0){ + recordVO.setDay(1D); + records.add(recordVO); + }else if(wgzAttendance.getMissedIn()==1 && wgzAttendance.getMissedOut()==1){ + recordVO.setDay(0D); + }else { + recordVO.setDay(0.5D); + records.add(recordVO); + } + BgtProjectRecruit recruit = recruitMap.get(wgzAttendance.getRecruitId()); + LocalDateTime clockInTime = wgzAttendance.getClockInTime(); + LocalDateTime clockOutTime = wgzAttendance.getClockOutTime(); + LocalTime beginWorkTime = recruit.getBeginWorkTime(); + LocalTime endWorkTime = recruit.getEndWorkTime(); + if (wgzAttendance.getLate() == 1) { + WgzAttendanceRecordVO LateRecordVO = BeanUtil.copyProperties(recordVO, WgzAttendanceRecordVO.class); + LateRecordVO.setTime(clockInTime.toLocalTime()); + LateRecordVO.setMinutes(DataUtil.getMinutes(clockInTime,beginWorkTime)); + lateRecords.add(LateRecordVO); + } + if (wgzAttendance.getEarlyLeave() == 1) { + WgzAttendanceRecordVO earlyLeaveRecordVO = BeanUtil.copyProperties(recordVO, WgzAttendanceRecordVO.class); + earlyLeaveRecordVO.setTime(clockOutTime.toLocalTime()); + earlyLeaveRecordVO.setMinutes(DataUtil.getMinutes(clockOutTime,endWorkTime)); + earlyLeaveRecords.add(earlyLeaveRecordVO); + } + + if (wgzAttendance.getMissedIn() == 1) { + WgzAttendanceRecordVO missRecordVO = BeanUtil.copyProperties(recordVO, WgzAttendanceRecordVO.class); + missRecordVO.setTime(beginWorkTime); + missRecords.add(missRecordVO); + } + + if (wgzAttendance.getMissedOut() == 1) { + WgzAttendanceRecordVO missRecordVO = BeanUtil.copyProperties(recordVO, WgzAttendanceRecordVO.class); + missRecordVO.setTime(endWorkTime); + missRecords.add(missRecordVO); + } + } + bgtAttendanceDetailVO.setDayNum(records.stream().mapToDouble(WgzAttendanceRecordVO::getDay).sum()); + + bgtAttendanceDetailVO.setLateNum(lateRecords.size()); + bgtAttendanceDetailVO.setLateMinute(lateRecords.stream().mapToInt(WgzAttendanceRecordVO::getMinutes).sum()); + bgtAttendanceDetailVO.setLateRecords(lateRecords); + + bgtAttendanceDetailVO.setEarlyLeaveNum(earlyLeaveRecords.size()); + bgtAttendanceDetailVO.setEarlyLeaveMinute(earlyLeaveRecords.stream().mapToInt(WgzAttendanceRecordVO::getMinutes).sum()); + bgtAttendanceDetailVO.setEarlyLeaveRecords(earlyLeaveRecords); + + bgtAttendanceDetailVO.setMissNum(earlyLeaveRecords.size()); + bgtAttendanceDetailVO.setMissRecords(earlyLeaveRecords); + return bgtAttendanceDetailVO; + + + + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzScoreRecordServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzScoreRecordServiceImpl.java new file mode 100644 index 0000000..785330f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/wgz/service/impl/WgzScoreRecordServiceImpl.java @@ -0,0 +1,88 @@ +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.common.utils.PageUtils; +import com.ruoyi.common.core.page.PagePlus; +import com.ruoyi.common.core.page.TableDataInfo; +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.WgzScoreRecordQueryBo; +import com.ruoyi.wgz.domain.WgzScoreRecord; +import com.ruoyi.wgz.mapper.WgzScoreRecordMapper; +import com.ruoyi.wgz.service.IWgzScoreRecordService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 务工者评分记录Service业务层处理 + * + * @author ruoyi + * @date 2025-02-21 + */ +@Service +public class WgzScoreRecordServiceImpl extends ServicePlusImpl implements IWgzScoreRecordService { + + @Override + public WgzScoreRecord queryById(Long id){ + return getById(id); + } + + @Override + public TableDataInfo queryPageList(WgzScoreRecordQueryBo bo) { + Page result = page(PageUtils.buildPage(), buildQueryWrapper(bo)); + return PageUtils.buildDataInfo(result); + } + + @Override + public List queryList(WgzScoreRecordQueryBo bo) { + return list(buildQueryWrapper(bo)); + } + + private LambdaQueryWrapper buildQueryWrapper(WgzScoreRecordQueryBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getRecruitId() != null, WgzScoreRecord::getRecruitId, bo.getRecruitId()); + lqw.eq(bo.getUserId() != null, WgzScoreRecord::getUserId, bo.getUserId()); + lqw.eq(bo.getScoreBy() != null, WgzScoreRecord::getScoreBy, bo.getScoreBy()); + lqw.eq(bo.getScore() != null, WgzScoreRecord::getScore, bo.getScore()); + lqw.eq(StrUtil.isNotBlank(bo.getContent()), WgzScoreRecord::getContent, bo.getContent()); + return lqw; + } + + @Override + public Boolean insert(WgzScoreRecord bo) { + WgzScoreRecord add = BeanUtil.toBean(bo, WgzScoreRecord.class); + validEntityBeforeSave(add); + return save(add); + } + + @Override + public Boolean update(WgzScoreRecord bo) { + WgzScoreRecord update = BeanUtil.toBean(bo, WgzScoreRecord.class); + validEntityBeforeSave(update); + return updateById(update); + } + + /** + * 保存前的数据校验 + * + * @param entity 实体类数据 + */ + private void validEntityBeforeSave(WgzScoreRecord entity){ + //TODO 做一些数据校验,如唯一约束 + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return removeByIds(ids); + } +} diff --git a/ruoyi-system/src/main/resources/mapper/bgt/BgtProjectRecruitApplyMapper.xml b/ruoyi-system/src/main/resources/mapper/bgt/BgtProjectRecruitApplyMapper.xml index c4b4304..6affe34 100644 --- a/ruoyi-system/src/main/resources/mapper/bgt/BgtProjectRecruitApplyMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/bgt/BgtProjectRecruitApplyMapper.xml @@ -17,15 +17,64 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + diff --git a/ruoyi-system/src/main/resources/mapper/wgz/WgzScoreRecordMapper.xml b/ruoyi-system/src/main/resources/mapper/wgz/WgzScoreRecordMapper.xml new file mode 100644 index 0000000..7af628c --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/wgz/WgzScoreRecordMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + +