From aa20705f2d1f1446a3a3a69b7f718d1971f1d454 Mon Sep 17 00:00:00 2001 From: Echo <4759156@qq.com> Date: Wed, 10 Apr 2024 10:21:52 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=88=A0=E9=99=A4idea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 -------- .idea/cloud-server.iml | 9 --------- .idea/misc.xml | 6 ------ .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 5 files changed, 37 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/cloud-server.iml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b81..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/cloud-server.iml b/.idea/cloud-server.iml deleted file mode 100644 index d6ebd480..00000000 --- a/.idea/cloud-server.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 1c2e834b..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 06a647e6..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From da0dcda2fe683c3267f765e63b92703236711e08 Mon Sep 17 00:00:00 2001 From: aikai Date: Wed, 10 Apr 2024 11:19:57 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E8=80=83=E5=8B=A4=E8=A1=A8=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=20/=20=E8=8E=B7=E5=8F=96=E8=80=83?= =?UTF-8?q?=E5=8B=A4=E6=89=93=E5=8D=A1=E9=A1=B5=E9=9D=A2=EF=BC=88=E9=83=A8?= =?UTF-8?q?=E5=88=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/enums/ErrorCodeConstants.java | 7 ++ .../fixed/AttendanceFixedController.java | 95 +++++++++++++++++++ .../fixed/vo/AttendanceFixedPageReqVO.java | 32 +++++++ .../admin/fixed/vo/AttendanceFixedRespVO.java | 36 +++++++ .../fixed/vo/AttendanceFixedSaveReqVO.java | 25 +++++ .../group/AttendanceGroupController.java | 95 +++++++++++++++++++ .../group/vo/AttendanceGroupPageReqVO.java | 49 ++++++++++ .../admin/group/vo/AttendanceGroupRespVO.java | 60 ++++++++++++ .../group/vo/AttendanceGroupSaveReqVO.java | 44 +++++++++ .../AttendanceGroupShiftController.java | 95 +++++++++++++++++++ .../vo/AttendanceGroupShiftPageReqVO.java | 31 ++++++ .../vo/AttendanceGroupShiftRespVO.java | 36 +++++++ .../vo/AttendanceGroupShiftSaveReqVO.java | 25 +++++ .../AttendanceGroupUserController.java | 95 +++++++++++++++++++ .../vo/AttendanceGroupUserPageReqVO.java | 28 ++++++ .../vo/AttendanceGroupUserRespVO.java | 32 +++++++ .../vo/AttendanceGroupUserSaveReqVO.java | 22 +++++ .../AttendancePunchRecordController.java | 95 +++++++++++++++++++ .../vo/AttendancePunchRecordPageReqVO.java | 57 +++++++++++ .../vo/AttendancePunchRecordRespVO.java | 68 +++++++++++++ .../vo/AttendancePunchRecordSaveReqVO.java | 51 ++++++++++ .../AttendanceSchedulingController.java | 95 +++++++++++++++++++ .../vo/AttendanceSchedulingPageReqVO.java | 34 +++++++ .../vo/AttendanceSchedulingRespVO.java | 40 ++++++++ .../vo/AttendanceSchedulingSaveReqVO.java | 28 ++++++ .../app/attendance/AttendanceController.java | 41 ++++++++ .../dto/AttendancePunchPageDTO.java | 20 ++++ .../attendance/vo/AttendancePunchPageVO.java | 9 ++ .../dataobject/fixed/AttendanceFixedDO.java | 43 +++++++++ .../dataobject/group/AttendanceGroupDO.java | 75 +++++++++++++++ .../groupshift/AttendanceGroupShiftDO.java | 43 +++++++++ .../groupuser/AttendanceGroupUserDO.java | 39 ++++++++ .../punchrecord/AttendancePunchRecordDO.java | 76 +++++++++++++++ .../scheduling/AttendanceSchedulingDO.java | 47 +++++++++ .../mysql/fixed/AttendanceFixedMapper.java | 29 ++++++ .../mysql/group/AttendanceGroupMapper.java | 42 ++++++++ .../AttendanceGroupShiftMapper.java | 29 ++++++ .../groupuser/AttendanceGroupUserMapper.java | 28 ++++++ .../AttendancePunchRecordMapper.java | 37 ++++++++ .../AttendanceSchedulingMapper.java | 30 ++++++ .../module/system/handler/PunchHandler.java | 27 ++++++ .../service/attendance/AttendanceService.java | 15 +++ .../attendance/AttendanceServiceImpl.java | 39 ++++++++ .../service/fixed/AttendanceFixedService.java | 55 +++++++++++ .../fixed/AttendanceFixedServiceImpl.java | 74 +++++++++++++++ .../service/group/AttendanceGroupService.java | 62 ++++++++++++ .../group/AttendanceGroupServiceImpl.java | 82 ++++++++++++++++ .../AttendanceGroupShiftService.java | 55 +++++++++++ .../AttendanceGroupShiftServiceImpl.java | 74 +++++++++++++++ .../groupuser/AttendanceGroupUserService.java | 55 +++++++++++ .../AttendanceGroupUserServiceImpl.java | 74 +++++++++++++++ .../system/service/punch/PunchService.java | 12 +++ .../AttendancePunchRecordService.java | 55 +++++++++++ .../AttendancePunchRecordServiceImpl.java | 74 +++++++++++++++ .../AttendanceSchedulingService.java | 55 +++++++++++ .../AttendanceSchedulingServiceImpl.java | 74 +++++++++++++++ .../mapper/fixed/AttendanceFixedMapper.xml | 12 +++ .../mapper/group/AttendanceGroupMapper.xml | 19 ++++ .../groupshift/AttendanceGroupShiftMapper.xml | 12 +++ .../groupuser/AttendanceGroupUserMapper.xml | 12 +++ .../AttendancePunchRecordMapper.xml | 12 +++ .../scheduling/AttendanceSchedulingMapper.xml | 12 +++ 62 files changed, 2824 insertions(+) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/AttendanceFixedController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedPageReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedRespVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedSaveReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupRespVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupSaveReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftPageReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftRespVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftSaveReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserPageReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserRespVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserSaveReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordPageReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordRespVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/AttendanceSchedulingController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingPageReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingRespVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingSaveReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/AttendanceController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchPageVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/fixed/AttendanceFixedDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/group/AttendanceGroupDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupshift/AttendanceGroupShiftDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupuser/AttendanceGroupUserDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/punchrecord/AttendancePunchRecordDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/scheduling/AttendanceSchedulingDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/fixed/AttendanceFixedMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/group/AttendanceGroupMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupshift/AttendanceGroupShiftMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupuser/AttendanceGroupUserMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/punchrecord/AttendancePunchRecordMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/scheduling/AttendanceSchedulingMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/handler/PunchHandler.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punch/PunchService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/fixed/AttendanceFixedMapper.xml create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupshift/AttendanceGroupShiftMapper.xml create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupuser/AttendanceGroupUserMapper.xml create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/punchrecord/AttendancePunchRecordMapper.xml create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index ef5c3a62..0e7d3fbd 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -171,4 +171,11 @@ public interface ErrorCodeConstants { // ========== 站内信发送 1-002-028-000 ========== ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_028_000, "模板参数({})缺失"); + // ========== 站内信发送 1-003-001-000 ========== + ErrorCode SCHEDULING_NOT_EXISTS = new ErrorCode(1_003_001_000, "排班制考勤设置不存在"); + ErrorCode PUNCH_RECORD_NOT_EXISTS = new ErrorCode(1_003_002_000, "用户打卡记录不存在"); + ErrorCode GROUP_USER_NOT_EXISTS = new ErrorCode(1_003_003_000, "考勤组人员不存在"); + ErrorCode GROUP_SHIFT_NOT_EXISTS = new ErrorCode(1_003_004_000, "考勤组班次不存在"); + ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1_003_005_000, "考勤组不存在"); + ErrorCode FIXED_NOT_EXISTS = new ErrorCode(1_003_006_000, "固定班制考勤设置"); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/AttendanceFixedController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/AttendanceFixedController.java new file mode 100644 index 00000000..0aa9db43 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/AttendanceFixedController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.fixed; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.system.controller.admin.fixed.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.fixed.AttendanceFixedDO; +import cn.iocoder.yudao.module.system.service.fixed.AttendanceFixedService; + +@Tag(name = "管理后台 - 固定班制考勤设置") +@RestController +@RequestMapping("/system/attendance/fixed") +@Validated +public class AttendanceFixedController { + + @Resource + private AttendanceFixedService fixedService; + + @PostMapping("/create") + @Operation(summary = "创建固定班制考勤设置") + @PreAuthorize("@ss.hasPermission('attendance:fixed:create')") + public CommonResult createFixed(@Valid @RequestBody AttendanceFixedSaveReqVO createReqVO) { + return success(fixedService.createFixed(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新固定班制考勤设置") + @PreAuthorize("@ss.hasPermission('attendance:fixed:update')") + public CommonResult updateFixed(@Valid @RequestBody AttendanceFixedSaveReqVO updateReqVO) { + fixedService.updateFixed(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除固定班制考勤设置") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('attendance:fixed:delete')") + public CommonResult deleteFixed(@RequestParam("id") Long id) { + fixedService.deleteFixed(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得固定班制考勤设置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('attendance:fixed:query')") + public CommonResult getFixed(@RequestParam("id") Long id) { + AttendanceFixedDO fixed = fixedService.getFixed(id); + return success(BeanUtils.toBean(fixed, AttendanceFixedRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得固定班制考勤设置分页") + @PreAuthorize("@ss.hasPermission('attendance:fixed:query')") + public CommonResult> getFixedPage(@Valid AttendanceFixedPageReqVO pageReqVO) { + PageResult pageResult = fixedService.getFixedPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AttendanceFixedRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出固定班制考勤设置 Excel") + @PreAuthorize("@ss.hasPermission('attendance:fixed:export')") + @OperateLog(type = EXPORT) + public void exportFixedExcel(@Valid AttendanceFixedPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = fixedService.getFixedPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "固定班制考勤设置.xls", "数据", AttendanceFixedRespVO.class, + BeanUtils.toBean(list, AttendanceFixedRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedPageReqVO.java new file mode 100644 index 00000000..a7ac1a1e --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedPageReqVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.system.controller.admin.fixed.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 固定班制考勤设置分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AttendanceFixedPageReqVO extends PageParam { + + @Schema(description = "考勤组id", example = "19908") + private Long attendanceGroupId; + + @Schema(description = "周时间 1-7") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Integer[] weekTime; + + @Schema(description = "班次id", example = "16385") + private Long attendanceGroupShiftId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedRespVO.java new file mode 100644 index 00000000..b2e76400 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedRespVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.system.controller.admin.fixed.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 固定班制考勤设置 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AttendanceFixedRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23824") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "考勤组id", example = "19908") + @ExcelProperty("考勤组id") + private Long attendanceGroupId; + + @Schema(description = "周时间 1-7") + @ExcelProperty("周时间 1-7") + private Integer weekTime; + + @Schema(description = "班次id", example = "16385") + @ExcelProperty("班次id") + private Long attendanceGroupShiftId; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedSaveReqVO.java new file mode 100644 index 00000000..48f00124 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/fixed/vo/AttendanceFixedSaveReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.system.controller.admin.fixed.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; + +@Schema(description = "管理后台 - 固定班制考勤设置新增/修改 Request VO") +@Data +public class AttendanceFixedSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23824") + private Long id; + + @Schema(description = "考勤组id", example = "19908") + private Long attendanceGroupId; + + @Schema(description = "周时间 1-7") + private Integer weekTime; + + @Schema(description = "班次id", example = "16385") + private Long attendanceGroupShiftId; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java new file mode 100644 index 00000000..1f92fd9b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.group; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.system.controller.admin.group.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.group.AttendanceGroupDO; +import cn.iocoder.yudao.module.system.service.group.AttendanceGroupService; + +@Tag(name = "管理后台 - 考勤组") +@RestController +@RequestMapping("/system/attendance/group") +@Validated +public class AttendanceGroupController { + + @Resource + private AttendanceGroupService groupService; + + @PostMapping("/create") + @Operation(summary = "创建考勤组") + @PreAuthorize("@ss.hasPermission('attendance:group:create')") + public CommonResult createGroup(@Valid @RequestBody AttendanceGroupSaveReqVO createReqVO) { + return success(groupService.createGroup(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新考勤组") + @PreAuthorize("@ss.hasPermission('attendance:group:update')") + public CommonResult updateGroup(@Valid @RequestBody AttendanceGroupSaveReqVO updateReqVO) { + groupService.updateGroup(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除考勤组") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('attendance:group:delete')") + public CommonResult deleteGroup(@RequestParam("id") Long id) { + groupService.deleteGroup(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得考勤组") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('attendance:group:query')") + public CommonResult getGroup(@RequestParam("id") Long id) { + AttendanceGroupDO group = groupService.getGroup(id); + return success(BeanUtils.toBean(group, AttendanceGroupRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得考勤组分页") + @PreAuthorize("@ss.hasPermission('attendance:group:query')") + public CommonResult> getGroupPage(@Valid AttendanceGroupPageReqVO pageReqVO) { + PageResult pageResult = groupService.getGroupPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AttendanceGroupRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出考勤组 Excel") + @PreAuthorize("@ss.hasPermission('attendance:group:export')") + @OperateLog(type = EXPORT) + public void exportGroupExcel(@Valid AttendanceGroupPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = groupService.getGroupPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "考勤组.xls", "数据", AttendanceGroupRespVO.class, + BeanUtils.toBean(list, AttendanceGroupRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java new file mode 100644 index 00000000..5e59f3be --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.system.controller.admin.group.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 考勤组分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AttendanceGroupPageReqVO extends PageParam { + + @Schema(description = "考勤组管理员id", example = "15633") + private Long userId; + + @Schema(description = "群组名称", example = "李四") + private String groupName; + + @Schema(description = "考勤类型 1固定班制 2排班制", example = "1") + private Integer type; + + @Schema(description = "打卡类型 1考勤机 2小程序范围打卡", example = "2") + private Integer punchType; + + @Schema(description = "经度") + private String longitude; + + @Schema(description = "纬度") + private String latitude; + + @Schema(description = "范围(米)") + private Integer scope; + + @Schema(description = "是否允许外勤打卡 0否 1是") + private Integer fieldworkFlag; + + @Schema(description = "节假日自动排休 0否 1是") + private Integer autoHolidaysFlag; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupRespVO.java new file mode 100644 index 00000000..936cc28c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupRespVO.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.system.controller.admin.group.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 考勤组 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AttendanceGroupRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22881") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "考勤组管理员id", example = "15633") + @ExcelProperty("考勤组管理员id") + private Long userId; + + @Schema(description = "群组名称", example = "李四") + @ExcelProperty("群组名称") + private String groupName; + + @Schema(description = "考勤类型 1固定班制 2排班制", example = "1") + @ExcelProperty("考勤类型 1固定班制 2排班制") + private Integer type; + + @Schema(description = "打卡类型 1考勤机 2小程序范围打卡", example = "2") + @ExcelProperty("打卡类型 1考勤机 2小程序范围打卡") + private Integer punchType; + + @Schema(description = "经度") + @ExcelProperty("经度") + private String longitude; + + @Schema(description = "纬度") + @ExcelProperty("纬度") + private String latitude; + + @Schema(description = "范围(米)") + @ExcelProperty("范围(米)") + private Integer scope; + + @Schema(description = "是否允许外勤打卡 0否 1是") + @ExcelProperty("是否允许外勤打卡 0否 1是") + private Integer fieldworkFlag; + + @Schema(description = "节假日自动排休 0否 1是") + @ExcelProperty("节假日自动排休 0否 1是") + private Integer autoHolidaysFlag; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupSaveReqVO.java new file mode 100644 index 00000000..ac217805 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupSaveReqVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.system.controller.admin.group.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; + +@Schema(description = "管理后台 - 考勤组新增/修改 Request VO") +@Data +public class AttendanceGroupSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22881") + private Long id; + + @Schema(description = "考勤组管理员id", example = "15633") + private Long userId; + + @Schema(description = "群组名称", example = "李四") + private String groupName; + + @Schema(description = "考勤类型 1固定班制 2排班制", example = "1") + private Integer type; + + @Schema(description = "打卡类型 1考勤机 2小程序范围打卡", example = "2") + private Integer punchType; + + @Schema(description = "经度") + private String longitude; + + @Schema(description = "纬度") + private String latitude; + + @Schema(description = "范围(米)") + private Integer scope; + + @Schema(description = "是否允许外勤打卡 0否 1是") + private Integer fieldworkFlag; + + @Schema(description = "节假日自动排休 0否 1是") + private Integer autoHolidaysFlag; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java new file mode 100644 index 00000000..15337204 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupshift; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.groupshift.AttendanceGroupShiftDO; +import cn.iocoder.yudao.module.system.service.groupshift.AttendanceGroupShiftService; + +@Tag(name = "管理后台 - 考勤组班次") +@RestController +@RequestMapping("/system/attendance/group-shift") +@Validated +public class AttendanceGroupShiftController { + + @Resource + private AttendanceGroupShiftService groupShiftService; + + @PostMapping("/create") + @Operation(summary = "创建考勤组班次") + @PreAuthorize("@ss.hasPermission('attendance:group-shift:create')") + public CommonResult createGroupShift(@Valid @RequestBody AttendanceGroupShiftSaveReqVO createReqVO) { + return success(groupShiftService.createGroupShift(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新考勤组班次") + @PreAuthorize("@ss.hasPermission('attendance:group-shift:update')") + public CommonResult updateGroupShift(@Valid @RequestBody AttendanceGroupShiftSaveReqVO updateReqVO) { + groupShiftService.updateGroupShift(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除考勤组班次") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('attendance:group-shift:delete')") + public CommonResult deleteGroupShift(@RequestParam("id") Long id) { + groupShiftService.deleteGroupShift(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得考勤组班次") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('attendance:group-shift:query')") + public CommonResult getGroupShift(@RequestParam("id") Long id) { + AttendanceGroupShiftDO groupShift = groupShiftService.getGroupShift(id); + return success(BeanUtils.toBean(groupShift, AttendanceGroupShiftRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得考勤组班次分页") + @PreAuthorize("@ss.hasPermission('attendance:group-shift:query')") + public CommonResult> getGroupShiftPage(@Valid AttendanceGroupShiftPageReqVO pageReqVO) { + PageResult pageResult = groupShiftService.getGroupShiftPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AttendanceGroupShiftRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出考勤组班次 Excel") + @PreAuthorize("@ss.hasPermission('attendance:group-shift:export')") + @OperateLog(type = EXPORT) + public void exportGroupShiftExcel(@Valid AttendanceGroupShiftPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = groupShiftService.getGroupShiftPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "考勤组班次.xls", "数据", AttendanceGroupShiftRespVO.class, + BeanUtils.toBean(list, AttendanceGroupShiftRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftPageReqVO.java new file mode 100644 index 00000000..d468a872 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftPageReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupshift.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 考勤组班次分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AttendanceGroupShiftPageReqVO extends PageParam { + + @Schema(description = "考勤组id", example = "24585") + private Long attendanceGroupId; + + @Schema(description = "班次名称", example = "张三") + private String name; + + @Schema(description = "班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + private String attendanceTimeJson; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftRespVO.java new file mode 100644 index 00000000..56e65e08 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftRespVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupshift.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 考勤组班次 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AttendanceGroupShiftRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5305") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "考勤组id", example = "24585") + @ExcelProperty("考勤组id") + private Long attendanceGroupId; + + @Schema(description = "班次名称", example = "张三") + @ExcelProperty("班次名称") + private String name; + + @Schema(description = "班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + @ExcelProperty("班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + private String attendanceTimeJson; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftSaveReqVO.java new file mode 100644 index 00000000..3f6b4473 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/vo/AttendanceGroupShiftSaveReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupshift.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; + +@Schema(description = "管理后台 - 考勤组班次新增/修改 Request VO") +@Data +public class AttendanceGroupShiftSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5305") + private Long id; + + @Schema(description = "考勤组id", example = "24585") + private Long attendanceGroupId; + + @Schema(description = "班次名称", example = "张三") + private String name; + + @Schema(description = "班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + private String attendanceTimeJson; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java new file mode 100644 index 00000000..03a10111 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupuser; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.groupuser.AttendanceGroupUserDO; +import cn.iocoder.yudao.module.system.service.groupuser.AttendanceGroupUserService; + +@Tag(name = "管理后台 - 考勤组人员") +@RestController +@RequestMapping("/system/attendance/group-user") +@Validated +public class AttendanceGroupUserController { + + @Resource + private AttendanceGroupUserService groupUserService; + + @PostMapping("/create") + @Operation(summary = "创建考勤组人员") + @PreAuthorize("@ss.hasPermission('attendance:group-user:create')") + public CommonResult createGroupUser(@Valid @RequestBody AttendanceGroupUserSaveReqVO createReqVO) { + return success(groupUserService.createGroupUser(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新考勤组人员") + @PreAuthorize("@ss.hasPermission('attendance:group-user:update')") + public CommonResult updateGroupUser(@Valid @RequestBody AttendanceGroupUserSaveReqVO updateReqVO) { + groupUserService.updateGroupUser(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除考勤组人员") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('attendance:group-user:delete')") + public CommonResult deleteGroupUser(@RequestParam("id") Long id) { + groupUserService.deleteGroupUser(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得考勤组人员") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('attendance:group-user:query')") + public CommonResult getGroupUser(@RequestParam("id") Long id) { + AttendanceGroupUserDO groupUser = groupUserService.getGroupUser(id); + return success(BeanUtils.toBean(groupUser, AttendanceGroupUserRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得考勤组人员分页") + @PreAuthorize("@ss.hasPermission('attendance:group-user:query')") + public CommonResult> getGroupUserPage(@Valid AttendanceGroupUserPageReqVO pageReqVO) { + PageResult pageResult = groupUserService.getGroupUserPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AttendanceGroupUserRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出考勤组人员 Excel") + @PreAuthorize("@ss.hasPermission('attendance:group-user:export')") + @OperateLog(type = EXPORT) + public void exportGroupUserExcel(@Valid AttendanceGroupUserPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = groupUserService.getGroupUserPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "考勤组人员.xls", "数据", AttendanceGroupUserRespVO.class, + BeanUtils.toBean(list, AttendanceGroupUserRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserPageReqVO.java new file mode 100644 index 00000000..ec64ead1 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserPageReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupuser.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 考勤组人员分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AttendanceGroupUserPageReqVO extends PageParam { + + @Schema(description = "考勤组id", example = "21406") + private Long attendanceGroupId; + + @Schema(description = "用户id", example = "22547") + private Long userId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserRespVO.java new file mode 100644 index 00000000..e53abc1b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserRespVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupuser.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 考勤组人员 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AttendanceGroupUserRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31257") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "考勤组id", example = "21406") + @ExcelProperty("考勤组id") + private Long attendanceGroupId; + + @Schema(description = "用户id", example = "22547") + @ExcelProperty("用户id") + private Long userId; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserSaveReqVO.java new file mode 100644 index 00000000..df0d5031 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserSaveReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupuser.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; + +@Schema(description = "管理后台 - 考勤组人员新增/修改 Request VO") +@Data +public class AttendanceGroupUserSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31257") + private Long id; + + @Schema(description = "考勤组id", example = "21406") + private Long attendanceGroupId; + + @Schema(description = "用户id", example = "22547") + private Long userId; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java new file mode 100644 index 00000000..c55fdd50 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.punchrecord; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.punchrecord.AttendancePunchRecordDO; +import cn.iocoder.yudao.module.system.service.punchrecord.AttendancePunchRecordService; + +@Tag(name = "管理后台 - 用户打卡记录") +@RestController +@RequestMapping("/system/attendance/punch-record") +@Validated +public class AttendancePunchRecordController { + + @Resource + private AttendancePunchRecordService punchRecordService; + + @PostMapping("/create") + @Operation(summary = "创建用户打卡记录") + @PreAuthorize("@ss.hasPermission('attendance:punch-record:create')") + public CommonResult createPunchRecord(@Valid @RequestBody AttendancePunchRecordSaveReqVO createReqVO) { + return success(punchRecordService.createPunchRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新用户打卡记录") + @PreAuthorize("@ss.hasPermission('attendance:punch-record:update')") + public CommonResult updatePunchRecord(@Valid @RequestBody AttendancePunchRecordSaveReqVO updateReqVO) { + punchRecordService.updatePunchRecord(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除用户打卡记录") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('attendance:punch-record:delete')") + public CommonResult deletePunchRecord(@RequestParam("id") Long id) { + punchRecordService.deletePunchRecord(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得用户打卡记录") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('attendance:punch-record:query')") + public CommonResult getPunchRecord(@RequestParam("id") Long id) { + AttendancePunchRecordDO punchRecord = punchRecordService.getPunchRecord(id); + return success(BeanUtils.toBean(punchRecord, AttendancePunchRecordRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得用户打卡记录分页") + @PreAuthorize("@ss.hasPermission('attendance:punch-record:query')") + public CommonResult> getPunchRecordPage(@Valid AttendancePunchRecordPageReqVO pageReqVO) { + PageResult pageResult = punchRecordService.getPunchRecordPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AttendancePunchRecordRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出用户打卡记录 Excel") + @PreAuthorize("@ss.hasPermission('attendance:punch-record:export')") + @OperateLog(type = EXPORT) + public void exportPunchRecordExcel(@Valid AttendancePunchRecordPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = punchRecordService.getPunchRecordPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "用户打卡记录.xls", "数据", AttendancePunchRecordRespVO.class, + BeanUtils.toBean(list, AttendancePunchRecordRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordPageReqVO.java new file mode 100644 index 00000000..bdd7c654 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordPageReqVO.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 用户打卡记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AttendancePunchRecordPageReqVO extends PageParam { + + @Schema(description = "考勤组管理员id", example = "11409") + private Long userId; + + @Schema(description = "考勤组id", example = "22293") + private Long attendanceGroupId; + + @Schema(description = "班次id", example = "10780") + private Long attendanceGroupShiftId; + + @Schema(description = "考勤类型 1固定班制 2排班制", example = "2") + private Integer type; + + @Schema(description = "打卡类型 1考勤机 2小程序范围打卡", example = "2") + private Integer punchType; + + @Schema(description = "班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + private String attendanceTimeJson; + + @Schema(description = "打卡状态 0正常 1迟到 2缺卡 3外勤 4补卡", example = "1") + private Integer status; + + @Schema(description = "日期yyyy-MM-dd格式") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private String[] dayTime; + + @Schema(description = "打卡时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] punchTime; + + @Schema(description = "打卡备注", example = "你说的对") + private String remark; + + @Schema(description = "图片") + private String image; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordRespVO.java new file mode 100644 index 00000000..15067d80 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordRespVO.java @@ -0,0 +1,68 @@ +package cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 用户打卡记录 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AttendancePunchRecordRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "65") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "考勤组管理员id", example = "11409") + @ExcelProperty("考勤组管理员id") + private Long userId; + + @Schema(description = "考勤组id", example = "22293") + @ExcelProperty("考勤组id") + private Long attendanceGroupId; + + @Schema(description = "班次id", example = "10780") + @ExcelProperty("班次id") + private Long attendanceGroupShiftId; + + @Schema(description = "考勤类型 1固定班制 2排班制", example = "2") + @ExcelProperty("考勤类型 1固定班制 2排班制") + private Integer type; + + @Schema(description = "打卡类型 1考勤机 2小程序范围打卡", example = "2") + @ExcelProperty("打卡类型 1考勤机 2小程序范围打卡") + private Integer punchType; + + @Schema(description = "班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + @ExcelProperty("班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + private String attendanceTimeJson; + + @Schema(description = "打卡状态 0正常 1迟到 2缺卡 3外勤 4补卡", example = "1") + @ExcelProperty("打卡状态 0正常 1迟到 2缺卡 3外勤 4补卡") + private Integer status; + + @Schema(description = "日期yyyy-MM-dd格式") + @ExcelProperty("日期yyyy-MM-dd格式") + private String dayTime; + + @Schema(description = "打卡时间") + @ExcelProperty("打卡时间") + private LocalDateTime punchTime; + + @Schema(description = "打卡备注", example = "你说的对") + @ExcelProperty("打卡备注") + private String remark; + + @Schema(description = "图片") + @ExcelProperty("图片") + private String image; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java new file mode 100644 index 00000000..397e7019 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 用户打卡记录新增/修改 Request VO") +@Data +public class AttendancePunchRecordSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "65") + private Long id; + + @Schema(description = "考勤组管理员id", example = "11409") + private Long userId; + + @Schema(description = "考勤组id", example = "22293") + private Long attendanceGroupId; + + @Schema(description = "班次id", example = "10780") + private Long attendanceGroupShiftId; + + @Schema(description = "考勤类型 1固定班制 2排班制", example = "2") + private Integer type; + + @Schema(description = "打卡类型 1考勤机 2小程序范围打卡", example = "2") + private Integer punchType; + + @Schema(description = "班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}]") + private String attendanceTimeJson; + + @Schema(description = "打卡状态 0正常 1迟到 2缺卡 3外勤 4补卡", example = "1") + private Integer status; + + @Schema(description = "日期yyyy-MM-dd格式") + private String dayTime; + + @Schema(description = "打卡时间") + private LocalDateTime punchTime; + + @Schema(description = "打卡备注", example = "你说的对") + private String remark; + + @Schema(description = "图片") + private String image; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/AttendanceSchedulingController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/AttendanceSchedulingController.java new file mode 100644 index 00000000..efa200b5 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/AttendanceSchedulingController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.scheduling; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.system.controller.admin.scheduling.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.scheduling.AttendanceSchedulingDO; +import cn.iocoder.yudao.module.system.service.scheduling.AttendanceSchedulingService; + +@Tag(name = "管理后台 - 排班制考勤设置") +@RestController +@RequestMapping("/system/attendance/scheduling") +@Validated +public class AttendanceSchedulingController { + + @Resource + private AttendanceSchedulingService schedulingService; + + @PostMapping("/create") + @Operation(summary = "创建排班制考勤设置") + @PreAuthorize("@ss.hasPermission('attendance:scheduling:create')") + public CommonResult createScheduling(@Valid @RequestBody AttendanceSchedulingSaveReqVO createReqVO) { + return success(schedulingService.createScheduling(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新排班制考勤设置") + @PreAuthorize("@ss.hasPermission('attendance:scheduling:update')") + public CommonResult updateScheduling(@Valid @RequestBody AttendanceSchedulingSaveReqVO updateReqVO) { + schedulingService.updateScheduling(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除排班制考勤设置") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('attendance:scheduling:delete')") + public CommonResult deleteScheduling(@RequestParam("id") Long id) { + schedulingService.deleteScheduling(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得排班制考勤设置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('attendance:scheduling:query')") + public CommonResult getScheduling(@RequestParam("id") Long id) { + AttendanceSchedulingDO scheduling = schedulingService.getScheduling(id); + return success(BeanUtils.toBean(scheduling, AttendanceSchedulingRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得排班制考勤设置分页") + @PreAuthorize("@ss.hasPermission('attendance:scheduling:query')") + public CommonResult> getSchedulingPage(@Valid AttendanceSchedulingPageReqVO pageReqVO) { + PageResult pageResult = schedulingService.getSchedulingPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AttendanceSchedulingRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出排班制考勤设置 Excel") + @PreAuthorize("@ss.hasPermission('attendance:scheduling:export')") + @OperateLog(type = EXPORT) + public void exportSchedulingExcel(@Valid AttendanceSchedulingPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = schedulingService.getSchedulingPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "排班制考勤设置.xls", "数据", AttendanceSchedulingRespVO.class, + BeanUtils.toBean(list, AttendanceSchedulingRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingPageReqVO.java new file mode 100644 index 00000000..a8227026 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingPageReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.system.controller.admin.scheduling.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 排班制考勤设置分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AttendanceSchedulingPageReqVO extends PageParam { + + @Schema(description = "第几天") + private Integer indexDay; + + @Schema(description = "考勤组id", example = "5025") + private Long attendanceGroupId; + + @Schema(description = "班次id", example = "9583") + private Long attendanceGroupShiftId; + + @Schema(description = "是否休息 0否 1是") + private Integer restFlag; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingRespVO.java new file mode 100644 index 00000000..56089990 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingRespVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.system.controller.admin.scheduling.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 排班制考勤设置 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AttendanceSchedulingRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23862") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "第几天") + @ExcelProperty("第几天") + private Integer indexDay; + + @Schema(description = "考勤组id", example = "5025") + @ExcelProperty("考勤组id") + private Long attendanceGroupId; + + @Schema(description = "班次id", example = "9583") + @ExcelProperty("班次id") + private Long attendanceGroupShiftId; + + @Schema(description = "是否休息 0否 1是") + @ExcelProperty("是否休息 0否 1是") + private Integer restFlag; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingSaveReqVO.java new file mode 100644 index 00000000..e6dbfd01 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/scheduling/vo/AttendanceSchedulingSaveReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.system.controller.admin.scheduling.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; + +@Schema(description = "管理后台 - 排班制考勤设置新增/修改 Request VO") +@Data +public class AttendanceSchedulingSaveReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23862") + private Long id; + + @Schema(description = "第几天") + private Integer indexDay; + + @Schema(description = "考勤组id", example = "5025") + private Long attendanceGroupId; + + @Schema(description = "班次id", example = "9583") + private Long attendanceGroupShiftId; + + @Schema(description = "是否休息 0否 1是") + private Integer restFlag; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/AttendanceController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/AttendanceController.java new file mode 100644 index 00000000..fe41559f --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/AttendanceController.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.system.controller.app.attendance; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; +import cn.iocoder.yudao.module.system.controller.app.attendance.dto.AttendancePunchPageDTO; +import cn.iocoder.yudao.module.system.controller.app.attendance.vo.AttendancePunchPageVO; +import cn.iocoder.yudao.module.system.controller.app.dict.vo.AppDictDataRespVO; +import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; +import cn.iocoder.yudao.module.system.handler.PunchHandler; +import cn.iocoder.yudao.module.system.service.attendance.AttendanceService; +import cn.iocoder.yudao.module.system.service.dict.DictDataService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "考勤 App - 考勤管理") +@RestController +@RequestMapping("/system/attendance") +@Validated +public class AttendanceController { + + @Resource + private AttendanceService attendanceService; + + @GetMapping("/getPunchPage") + @Operation(summary = "获取考勤页面") + public CommonResult getPunchPage(@ModelAttribute AttendancePunchPageDTO dto) { + Long userId = WebFrameworkUtils.getLoginUserId(); + AttendancePunchPageVO vo = attendanceService.getPunchPage(dto.setUserId(userId)); + return success(vo); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java new file mode 100644 index 00000000..b78bb757 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.system.controller.app.attendance.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class AttendancePunchPageDTO { + + @Schema(description = "经度") + private String longitude; + + @Schema(description = "纬度") + private String latitude; + + @Schema(description = "当前用户id", hidden = true) + private Long userId; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchPageVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchPageVO.java new file mode 100644 index 00000000..2eff07c0 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchPageVO.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.system.controller.app.attendance.vo; + +import lombok.Data; + +@Data +public class AttendancePunchPageVO { + + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/fixed/AttendanceFixedDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/fixed/AttendanceFixedDO.java new file mode 100644 index 00000000..da0900b2 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/fixed/AttendanceFixedDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.fixed; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 固定班制考勤设置 DO + * + * @author 艾楷 + */ +@TableName("kq_attendance_fixed") +@KeySequence("kq_attendance_fixed_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceFixedDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 考勤组id + */ + private Long attendanceGroupId; + /** + * 周时间 1-7 + */ + private Integer weekTime; + /** + * 班次id + */ + private Long attendanceGroupShiftId; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/group/AttendanceGroupDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/group/AttendanceGroupDO.java new file mode 100644 index 00000000..1c1ee3fa --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/group/AttendanceGroupDO.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.group; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 考勤组 DO + * + * @author 艾楷 + */ +@TableName("kq_attendance_group") +@KeySequence("kq_attendance_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceGroupDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 考勤组管理员id + */ + private Long userId; + /** + * 群组名称 + */ + private String groupName; + /** + * 考勤类型 1固定班制 2排班制 + */ + private Integer type; + /** + * 打卡类型 1考勤机 2小程序范围打卡 + */ + private Integer punchType; + /** + * 经度 + */ + private String longitude; + /** + * 纬度 + */ + private String latitude; + /** + * 范围(米) + */ + private Integer scope; + /** + * 是否允许外勤打卡 0否 1是 + */ + private Integer fieldworkFlag; + /** + * 节假日自动排休 0否 1是 + */ + private Integer autoHolidaysFlag; + + + public static String getCodeByType(Integer type) { + if (type == 1) { + return "fixed"; + } else { + return "scheduling"; + } + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupshift/AttendanceGroupShiftDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupshift/AttendanceGroupShiftDO.java new file mode 100644 index 00000000..abb2cd66 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupshift/AttendanceGroupShiftDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.groupshift; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 考勤组班次 DO + * + * @author 艾楷 + */ +@TableName("kq_attendance_group_shift") +@KeySequence("kq_attendance_group_shift_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceGroupShiftDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 考勤组id + */ + private Long attendanceGroupId; + /** + * 班次名称 + */ + private String name; + /** + * 班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}] + */ + private String attendanceTimeJson; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupuser/AttendanceGroupUserDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupuser/AttendanceGroupUserDO.java new file mode 100644 index 00000000..98eb30db --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/groupuser/AttendanceGroupUserDO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.groupuser; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 考勤组人员 DO + * + * @author 艾楷 + */ +@TableName("kq_attendance_group_user") +@KeySequence("kq_attendance_group_user_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceGroupUserDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 考勤组id + */ + private Long attendanceGroupId; + /** + * 用户id + */ + private Long userId; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/punchrecord/AttendancePunchRecordDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/punchrecord/AttendancePunchRecordDO.java new file mode 100644 index 00000000..e7fd91c1 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/punchrecord/AttendancePunchRecordDO.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.punchrecord; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 用户打卡记录 DO + * + * @author 艾楷 + */ +@TableName("kq_attendance_punch_record") +@KeySequence("kq_attendance_punch_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AttendancePunchRecordDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 考勤组管理员id + */ + private Long userId; + /** + * 考勤组id + */ + private Long attendanceGroupId; + /** + * 班次id + */ + private Long attendanceGroupShiftId; + /** + * 考勤类型 1固定班制 2排班制 + */ + private Integer type; + /** + * 打卡类型 1考勤机 2小程序范围打卡 + */ + private Integer punchType; + /** + * 班次考勤时间json[{start_tiem:HH:mm,start_check_flag:true,end_time:HH:mm,end_check_flah: true}] + */ + private String attendanceTimeJson; + /** + * 打卡状态 0正常 1迟到 2缺卡 3外勤 4补卡 + */ + private Integer status; + /** + * 日期yyyy-MM-dd格式 + */ + private String dayTime; + /** + * 打卡时间 + */ + private LocalDateTime punchTime; + /** + * 打卡备注 + */ + private String remark; + /** + * 图片 + */ + private String image; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/scheduling/AttendanceSchedulingDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/scheduling/AttendanceSchedulingDO.java new file mode 100644 index 00000000..4ea9ab31 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/scheduling/AttendanceSchedulingDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.scheduling; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 排班制考勤设置 DO + * + * @author 艾楷 + */ +@TableName("kq_attendance_scheduling") +@KeySequence("kq_attendance_scheduling_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceSchedulingDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 第几天 + */ + private Integer indexDay; + /** + * 考勤组id + */ + private Long attendanceGroupId; + /** + * 班次id + */ + private Long attendanceGroupShiftId; + /** + * 是否休息 0否 1是 + */ + private Integer restFlag; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/fixed/AttendanceFixedMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/fixed/AttendanceFixedMapper.java new file mode 100644 index 00000000..ac5425df --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/fixed/AttendanceFixedMapper.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.system.dal.mysql.fixed; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.system.dal.dataobject.fixed.AttendanceFixedDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.system.controller.admin.fixed.vo.*; + +/** + * 固定班制考勤设置 Mapper + * + * @author 艾楷 + */ +@Mapper +public interface AttendanceFixedMapper extends BaseMapperX { + + default PageResult selectPage(AttendanceFixedPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AttendanceFixedDO::getAttendanceGroupId, reqVO.getAttendanceGroupId()) + .betweenIfPresent(AttendanceFixedDO::getWeekTime, reqVO.getWeekTime()) + .eqIfPresent(AttendanceFixedDO::getAttendanceGroupShiftId, reqVO.getAttendanceGroupShiftId()) + .betweenIfPresent(AttendanceFixedDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(AttendanceFixedDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/group/AttendanceGroupMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/group/AttendanceGroupMapper.java new file mode 100644 index 00000000..7bb5f9f0 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/group/AttendanceGroupMapper.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.system.dal.mysql.group; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupPageReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.group.AttendanceGroupDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 考勤组 Mapper + * + * @author 艾楷 + */ +@Mapper +public interface AttendanceGroupMapper extends BaseMapperX { + + default PageResult selectPage(AttendanceGroupPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AttendanceGroupDO::getUserId, reqVO.getUserId()) + .likeIfPresent(AttendanceGroupDO::getGroupName, reqVO.getGroupName()) + .eqIfPresent(AttendanceGroupDO::getType, reqVO.getType()) + .eqIfPresent(AttendanceGroupDO::getPunchType, reqVO.getPunchType()) + .eqIfPresent(AttendanceGroupDO::getLongitude, reqVO.getLongitude()) + .eqIfPresent(AttendanceGroupDO::getLatitude, reqVO.getLatitude()) + .eqIfPresent(AttendanceGroupDO::getScope, reqVO.getScope()) + .eqIfPresent(AttendanceGroupDO::getAutoHolidaysFlag, reqVO.getAutoHolidaysFlag()) + .betweenIfPresent(AttendanceGroupDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(AttendanceGroupDO::getId)); + } + + /** + * 通过当前登录用户获取用户所在群组 + * + * @param userId + * @return + */ + List getByUserId(@Param("userId") Long userId); +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupshift/AttendanceGroupShiftMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupshift/AttendanceGroupShiftMapper.java new file mode 100644 index 00000000..8209d587 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupshift/AttendanceGroupShiftMapper.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.system.dal.mysql.groupshift; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.system.dal.dataobject.groupshift.AttendanceGroupShiftDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.*; + +/** + * 考勤组班次 Mapper + * + * @author 艾楷 + */ +@Mapper +public interface AttendanceGroupShiftMapper extends BaseMapperX { + + default PageResult selectPage(AttendanceGroupShiftPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AttendanceGroupShiftDO::getAttendanceGroupId, reqVO.getAttendanceGroupId()) + .likeIfPresent(AttendanceGroupShiftDO::getName, reqVO.getName()) + .eqIfPresent(AttendanceGroupShiftDO::getAttendanceTimeJson, reqVO.getAttendanceTimeJson()) + .betweenIfPresent(AttendanceGroupShiftDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(AttendanceGroupShiftDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupuser/AttendanceGroupUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupuser/AttendanceGroupUserMapper.java new file mode 100644 index 00000000..c212ccc5 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/groupuser/AttendanceGroupUserMapper.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.system.dal.mysql.groupuser; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.system.dal.dataobject.groupuser.AttendanceGroupUserDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.*; + +/** + * 考勤组人员 Mapper + * + * @author 艾楷 + */ +@Mapper +public interface AttendanceGroupUserMapper extends BaseMapperX { + + default PageResult selectPage(AttendanceGroupUserPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AttendanceGroupUserDO::getAttendanceGroupId, reqVO.getAttendanceGroupId()) + .eqIfPresent(AttendanceGroupUserDO::getUserId, reqVO.getUserId()) + .betweenIfPresent(AttendanceGroupUserDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(AttendanceGroupUserDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/punchrecord/AttendancePunchRecordMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/punchrecord/AttendancePunchRecordMapper.java new file mode 100644 index 00000000..e4a34032 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/punchrecord/AttendancePunchRecordMapper.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.system.dal.mysql.punchrecord; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.system.dal.dataobject.punchrecord.AttendancePunchRecordDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.*; + +/** + * 用户打卡记录 Mapper + * + * @author 艾楷 + */ +@Mapper +public interface AttendancePunchRecordMapper extends BaseMapperX { + + default PageResult selectPage(AttendancePunchRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AttendancePunchRecordDO::getUserId, reqVO.getUserId()) + .eqIfPresent(AttendancePunchRecordDO::getAttendanceGroupId, reqVO.getAttendanceGroupId()) + .eqIfPresent(AttendancePunchRecordDO::getAttendanceGroupShiftId, reqVO.getAttendanceGroupShiftId()) + .eqIfPresent(AttendancePunchRecordDO::getType, reqVO.getType()) + .eqIfPresent(AttendancePunchRecordDO::getPunchType, reqVO.getPunchType()) + .eqIfPresent(AttendancePunchRecordDO::getAttendanceTimeJson, reqVO.getAttendanceTimeJson()) + .eqIfPresent(AttendancePunchRecordDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(AttendancePunchRecordDO::getDayTime, reqVO.getDayTime()) + .betweenIfPresent(AttendancePunchRecordDO::getPunchTime, reqVO.getPunchTime()) + .eqIfPresent(AttendancePunchRecordDO::getRemark, reqVO.getRemark()) + .eqIfPresent(AttendancePunchRecordDO::getImage, reqVO.getImage()) + .betweenIfPresent(AttendancePunchRecordDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(AttendancePunchRecordDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/scheduling/AttendanceSchedulingMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/scheduling/AttendanceSchedulingMapper.java new file mode 100644 index 00000000..13b05f5c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/scheduling/AttendanceSchedulingMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.system.dal.mysql.scheduling; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.system.dal.dataobject.scheduling.AttendanceSchedulingDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.system.controller.admin.scheduling.vo.*; + +/** + * 排班制考勤设置 Mapper + * + * @author 艾楷 + */ +@Mapper +public interface AttendanceSchedulingMapper extends BaseMapperX { + + default PageResult selectPage(AttendanceSchedulingPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AttendanceSchedulingDO::getIndexDay, reqVO.getIndexDay()) + .eqIfPresent(AttendanceSchedulingDO::getAttendanceGroupId, reqVO.getAttendanceGroupId()) + .eqIfPresent(AttendanceSchedulingDO::getAttendanceGroupShiftId, reqVO.getAttendanceGroupShiftId()) + .eqIfPresent(AttendanceSchedulingDO::getRestFlag, reqVO.getRestFlag()) + .betweenIfPresent(AttendanceSchedulingDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(AttendanceSchedulingDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/handler/PunchHandler.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/handler/PunchHandler.java new file mode 100644 index 00000000..47b2aec0 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/handler/PunchHandler.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.system.handler; + +import cn.iocoder.yudao.module.system.service.punch.PunchService; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @Author : AiKai + * @Description : 利用Spring的发现机制,将实现了IChannelLoginService的类都put到channelLoginServiceMap里面。 + * 后面只需要根据channelType对应好 各个实现类的注解 如: @Component("sys") 就可以取出不同的业务实现类 + **/ +@Service +public class PunchHandler { + private final Map punchServiceMap = new ConcurrentHashMap<>(); + + public PunchHandler(Map strategyMap) { + this.punchServiceMap.clear(); + strategyMap.forEach((k, v) -> this.punchServiceMap.put(k, v)); + } + + public PunchService getResource(String channelType) { + return punchServiceMap.get(channelType); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceService.java new file mode 100644 index 00000000..f999363c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceService.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.system.service.attendance; + +import cn.iocoder.yudao.module.system.controller.app.attendance.dto.AttendancePunchPageDTO; +import cn.iocoder.yudao.module.system.controller.app.attendance.vo.AttendancePunchPageVO; + +/** + * 考勤 Service 接口 + * + * @author 艾楷 + */ +public interface AttendanceService { + + + AttendancePunchPageVO getPunchPage(AttendancePunchPageDTO attendancePunchPageDTO); +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java new file mode 100644 index 00000000..0e6f1c77 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.service.attendance; + +import cn.iocoder.yudao.module.system.controller.app.attendance.dto.AttendancePunchPageDTO; +import cn.iocoder.yudao.module.system.controller.app.attendance.vo.AttendancePunchPageVO; +import cn.iocoder.yudao.module.system.dal.dataobject.group.AttendanceGroupDO; +import cn.iocoder.yudao.module.system.handler.PunchHandler; +import cn.iocoder.yudao.module.system.service.group.AttendanceGroupService; +import cn.iocoder.yudao.module.system.service.punch.PunchService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 考勤 实现类 + */ +@Service +@Slf4j +public class AttendanceServiceImpl implements AttendanceService { + @Resource + private PunchHandler punchHandler; + @Resource + private AttendanceGroupService attendanceGroupService; + + @Override + public AttendancePunchPageVO getPunchPage(AttendancePunchPageDTO attendancePunchPageDTO) { + AttendancePunchPageVO vo = new AttendancePunchPageVO(); + //获取当前登录用户所在群组 + AttendanceGroupDO activationGroup = attendanceGroupService.getByUserId(attendancePunchPageDTO.getUserId()); + if (activationGroup == null) { + // TODO: 2024/4/10 不在考勤组 - 返回回去 + return vo; + } + //判断目前是否在班次内 + PunchService punchService = punchHandler.getResource(AttendanceGroupDO.getCodeByType(activationGroup.getType())); + // TODO: 2024/4/10 处理打卡 + return null; + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedService.java new file mode 100644 index 00000000..9e5e6d25 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.system.service.fixed; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.system.controller.admin.fixed.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.fixed.AttendanceFixedDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 固定班制考勤设置 Service 接口 + * + * @author 艾楷 + */ +public interface AttendanceFixedService { + + /** + * 创建固定班制考勤设置 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createFixed(@Valid AttendanceFixedSaveReqVO createReqVO); + + /** + * 更新固定班制考勤设置 + * + * @param updateReqVO 更新信息 + */ + void updateFixed(@Valid AttendanceFixedSaveReqVO updateReqVO); + + /** + * 删除固定班制考勤设置 + * + * @param id 编号 + */ + void deleteFixed(Long id); + + /** + * 获得固定班制考勤设置 + * + * @param id 编号 + * @return 固定班制考勤设置 + */ + AttendanceFixedDO getFixed(Long id); + + /** + * 获得固定班制考勤设置分页 + * + * @param pageReqVO 分页查询 + * @return 固定班制考勤设置分页 + */ + PageResult getFixedPage(AttendanceFixedPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedServiceImpl.java new file mode 100644 index 00000000..6c09d70e --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/fixed/AttendanceFixedServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.system.service.fixed; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.system.controller.admin.fixed.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.fixed.AttendanceFixedDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.system.dal.mysql.fixed.AttendanceFixedMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; + +/** + * 固定班制考勤设置 Service 实现类 + * + * @author 艾楷 + */ +@Service("fixed") +@Validated +public class AttendanceFixedServiceImpl implements AttendanceFixedService { + + @Resource + private AttendanceFixedMapper fixedMapper; + + @Override + public Long createFixed(AttendanceFixedSaveReqVO createReqVO) { + // 插入 + AttendanceFixedDO fixed = BeanUtils.toBean(createReqVO, AttendanceFixedDO.class); + fixedMapper.insert(fixed); + // 返回 + return fixed.getId(); + } + + @Override + public void updateFixed(AttendanceFixedSaveReqVO updateReqVO) { + // 校验存在 + validateFixedExists(updateReqVO.getId()); + // 更新 + AttendanceFixedDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceFixedDO.class); + fixedMapper.updateById(updateObj); + } + + @Override + public void deleteFixed(Long id) { + // 校验存在 + validateFixedExists(id); + // 删除 + fixedMapper.deleteById(id); + } + + private void validateFixedExists(Long id) { + if (fixedMapper.selectById(id) == null) { + throw exception(FIXED_NOT_EXISTS); + } + } + + @Override + public AttendanceFixedDO getFixed(Long id) { + return fixedMapper.selectById(id); + } + + @Override + public PageResult getFixedPage(AttendanceFixedPageReqVO pageReqVO) { + return fixedMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupService.java new file mode 100644 index 00000000..8f02d0e0 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupService.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.system.service.group; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.group.AttendanceGroupDO; + +import javax.validation.Valid; + +/** + * 考勤组 Service 接口 + * + * @author 艾楷 + */ +public interface AttendanceGroupService { + + /** + * 创建考勤组 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createGroup(@Valid AttendanceGroupSaveReqVO createReqVO); + + /** + * 更新考勤组 + * + * @param updateReqVO 更新信息 + */ + void updateGroup(@Valid AttendanceGroupSaveReqVO updateReqVO); + + /** + * 删除考勤组 + * + * @param id 编号 + */ + void deleteGroup(Long id); + + /** + * 获得考勤组 + * + * @param id 编号 + * @return 考勤组 + */ + AttendanceGroupDO getGroup(Long id); + + /** + * 获得考勤组分页 + * + * @param pageReqVO 分页查询 + * @return 考勤组分页 + */ + PageResult getGroupPage(AttendanceGroupPageReqVO pageReqVO); + + /** + * 获取用户所在群组 + * + * @param userId + * @return + */ + AttendanceGroupDO getByUserId(Long userId); +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupServiceImpl.java new file mode 100644 index 00000000..b7c5cd92 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/group/AttendanceGroupServiceImpl.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.system.service.group; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.group.AttendanceGroupDO; +import cn.iocoder.yudao.module.system.dal.mysql.group.AttendanceGroupMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.rmi.activation.ActivationGroup; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.GROUP_NOT_EXISTS; + +/** + * 考勤组 Service 实现类 + * + * @author 艾楷 + */ +@Service +@Validated +public class AttendanceGroupServiceImpl implements AttendanceGroupService { + + @Resource + private AttendanceGroupMapper groupMapper; + + @Override + public Long createGroup(AttendanceGroupSaveReqVO createReqVO) { + // 插入 + AttendanceGroupDO group = BeanUtils.toBean(createReqVO, AttendanceGroupDO.class); + groupMapper.insert(group); + // 返回 + return group.getId(); + } + + @Override + public void updateGroup(AttendanceGroupSaveReqVO updateReqVO) { + // 校验存在 + validateGroupExists(updateReqVO.getId()); + // 更新 + AttendanceGroupDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceGroupDO.class); + groupMapper.updateById(updateObj); + } + + @Override + public void deleteGroup(Long id) { + // 校验存在 + validateGroupExists(id); + // 删除 + groupMapper.deleteById(id); + } + + private void validateGroupExists(Long id) { + if (groupMapper.selectById(id) == null) { + throw exception(GROUP_NOT_EXISTS); + } + } + + @Override + public AttendanceGroupDO getGroup(Long id) { + return groupMapper.selectById(id); + } + + @Override + public PageResult getGroupPage(AttendanceGroupPageReqVO pageReqVO) { + return groupMapper.selectPage(pageReqVO); + } + + @Override + public AttendanceGroupDO getByUserId(Long userId) { + List dos = groupMapper.getByUserId(userId); + if (!dos.isEmpty()) { + return dos.get(0); + } + return null; + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftService.java new file mode 100644 index 00000000..0a91cac1 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.system.service.groupshift; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.groupshift.AttendanceGroupShiftDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 考勤组班次 Service 接口 + * + * @author 艾楷 + */ +public interface AttendanceGroupShiftService { + + /** + * 创建考勤组班次 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createGroupShift(@Valid AttendanceGroupShiftSaveReqVO createReqVO); + + /** + * 更新考勤组班次 + * + * @param updateReqVO 更新信息 + */ + void updateGroupShift(@Valid AttendanceGroupShiftSaveReqVO updateReqVO); + + /** + * 删除考勤组班次 + * + * @param id 编号 + */ + void deleteGroupShift(Long id); + + /** + * 获得考勤组班次 + * + * @param id 编号 + * @return 考勤组班次 + */ + AttendanceGroupShiftDO getGroupShift(Long id); + + /** + * 获得考勤组班次分页 + * + * @param pageReqVO 分页查询 + * @return 考勤组班次分页 + */ + PageResult getGroupShiftPage(AttendanceGroupShiftPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftServiceImpl.java new file mode 100644 index 00000000..24f73428 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupshift/AttendanceGroupShiftServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.system.service.groupshift; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.groupshift.AttendanceGroupShiftDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.system.dal.mysql.groupshift.AttendanceGroupShiftMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; + +/** + * 考勤组班次 Service 实现类 + * + * @author 艾楷 + */ +@Service +@Validated +public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftService { + + @Resource + private AttendanceGroupShiftMapper groupShiftMapper; + + @Override + public Long createGroupShift(AttendanceGroupShiftSaveReqVO createReqVO) { + // 插入 + AttendanceGroupShiftDO groupShift = BeanUtils.toBean(createReqVO, AttendanceGroupShiftDO.class); + groupShiftMapper.insert(groupShift); + // 返回 + return groupShift.getId(); + } + + @Override + public void updateGroupShift(AttendanceGroupShiftSaveReqVO updateReqVO) { + // 校验存在 + validateGroupShiftExists(updateReqVO.getId()); + // 更新 + AttendanceGroupShiftDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceGroupShiftDO.class); + groupShiftMapper.updateById(updateObj); + } + + @Override + public void deleteGroupShift(Long id) { + // 校验存在 + validateGroupShiftExists(id); + // 删除 + groupShiftMapper.deleteById(id); + } + + private void validateGroupShiftExists(Long id) { + if (groupShiftMapper.selectById(id) == null) { + throw exception(GROUP_SHIFT_NOT_EXISTS); + } + } + + @Override + public AttendanceGroupShiftDO getGroupShift(Long id) { + return groupShiftMapper.selectById(id); + } + + @Override + public PageResult getGroupShiftPage(AttendanceGroupShiftPageReqVO pageReqVO) { + return groupShiftMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserService.java new file mode 100644 index 00000000..56b80eee --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.system.service.groupuser; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.groupuser.AttendanceGroupUserDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 考勤组人员 Service 接口 + * + * @author 艾楷 + */ +public interface AttendanceGroupUserService { + + /** + * 创建考勤组人员 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createGroupUser(@Valid AttendanceGroupUserSaveReqVO createReqVO); + + /** + * 更新考勤组人员 + * + * @param updateReqVO 更新信息 + */ + void updateGroupUser(@Valid AttendanceGroupUserSaveReqVO updateReqVO); + + /** + * 删除考勤组人员 + * + * @param id 编号 + */ + void deleteGroupUser(Long id); + + /** + * 获得考勤组人员 + * + * @param id 编号 + * @return 考勤组人员 + */ + AttendanceGroupUserDO getGroupUser(Long id); + + /** + * 获得考勤组人员分页 + * + * @param pageReqVO 分页查询 + * @return 考勤组人员分页 + */ + PageResult getGroupUserPage(AttendanceGroupUserPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserServiceImpl.java new file mode 100644 index 00000000..f95daf34 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/groupuser/AttendanceGroupUserServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.system.service.groupuser; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.groupuser.AttendanceGroupUserDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.system.dal.mysql.groupuser.AttendanceGroupUserMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; + +/** + * 考勤组人员 Service 实现类 + * + * @author 艾楷 + */ +@Service +@Validated +public class AttendanceGroupUserServiceImpl implements AttendanceGroupUserService { + + @Resource + private AttendanceGroupUserMapper groupUserMapper; + + @Override + public Long createGroupUser(AttendanceGroupUserSaveReqVO createReqVO) { + // 插入 + AttendanceGroupUserDO groupUser = BeanUtils.toBean(createReqVO, AttendanceGroupUserDO.class); + groupUserMapper.insert(groupUser); + // 返回 + return groupUser.getId(); + } + + @Override + public void updateGroupUser(AttendanceGroupUserSaveReqVO updateReqVO) { + // 校验存在 + validateGroupUserExists(updateReqVO.getId()); + // 更新 + AttendanceGroupUserDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceGroupUserDO.class); + groupUserMapper.updateById(updateObj); + } + + @Override + public void deleteGroupUser(Long id) { + // 校验存在 + validateGroupUserExists(id); + // 删除 + groupUserMapper.deleteById(id); + } + + private void validateGroupUserExists(Long id) { + if (groupUserMapper.selectById(id) == null) { + throw exception(GROUP_USER_NOT_EXISTS); + } + } + + @Override + public AttendanceGroupUserDO getGroupUser(Long id) { + return groupUserMapper.selectById(id); + } + + @Override + public PageResult getGroupUserPage(AttendanceGroupUserPageReqVO pageReqVO) { + return groupUserMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punch/PunchService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punch/PunchService.java new file mode 100644 index 00000000..c3a7e906 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punch/PunchService.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.system.service.punch; + +/** + * 打卡 Service 接口 + * + * @author 艾楷 + */ +public interface PunchService { + + + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordService.java new file mode 100644 index 00000000..7d5b9caf --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.system.service.punchrecord; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.punchrecord.AttendancePunchRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 用户打卡记录 Service 接口 + * + * @author 艾楷 + */ +public interface AttendancePunchRecordService { + + /** + * 创建用户打卡记录 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createPunchRecord(@Valid AttendancePunchRecordSaveReqVO createReqVO); + + /** + * 更新用户打卡记录 + * + * @param updateReqVO 更新信息 + */ + void updatePunchRecord(@Valid AttendancePunchRecordSaveReqVO updateReqVO); + + /** + * 删除用户打卡记录 + * + * @param id 编号 + */ + void deletePunchRecord(Long id); + + /** + * 获得用户打卡记录 + * + * @param id 编号 + * @return 用户打卡记录 + */ + AttendancePunchRecordDO getPunchRecord(Long id); + + /** + * 获得用户打卡记录分页 + * + * @param pageReqVO 分页查询 + * @return 用户打卡记录分页 + */ + PageResult getPunchRecordPage(AttendancePunchRecordPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordServiceImpl.java new file mode 100644 index 00000000..6bc54ceb --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/punchrecord/AttendancePunchRecordServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.system.service.punchrecord; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.punchrecord.AttendancePunchRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.system.dal.mysql.punchrecord.AttendancePunchRecordMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; + +/** + * 用户打卡记录 Service 实现类 + * + * @author 艾楷 + */ +@Service +@Validated +public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordService { + + @Resource + private AttendancePunchRecordMapper punchRecordMapper; + + @Override + public Long createPunchRecord(AttendancePunchRecordSaveReqVO createReqVO) { + // 插入 + AttendancePunchRecordDO punchRecord = BeanUtils.toBean(createReqVO, AttendancePunchRecordDO.class); + punchRecordMapper.insert(punchRecord); + // 返回 + return punchRecord.getId(); + } + + @Override + public void updatePunchRecord(AttendancePunchRecordSaveReqVO updateReqVO) { + // 校验存在 + validatePunchRecordExists(updateReqVO.getId()); + // 更新 + AttendancePunchRecordDO updateObj = BeanUtils.toBean(updateReqVO, AttendancePunchRecordDO.class); + punchRecordMapper.updateById(updateObj); + } + + @Override + public void deletePunchRecord(Long id) { + // 校验存在 + validatePunchRecordExists(id); + // 删除 + punchRecordMapper.deleteById(id); + } + + private void validatePunchRecordExists(Long id) { + if (punchRecordMapper.selectById(id) == null) { + throw exception(PUNCH_RECORD_NOT_EXISTS); + } + } + + @Override + public AttendancePunchRecordDO getPunchRecord(Long id) { + return punchRecordMapper.selectById(id); + } + + @Override + public PageResult getPunchRecordPage(AttendancePunchRecordPageReqVO pageReqVO) { + return punchRecordMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingService.java new file mode 100644 index 00000000..2dc4ca64 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.system.service.scheduling; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.system.controller.admin.scheduling.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.scheduling.AttendanceSchedulingDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 排班制考勤设置 Service 接口 + * + * @author 艾楷 + */ +public interface AttendanceSchedulingService { + + /** + * 创建排班制考勤设置 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createScheduling(@Valid AttendanceSchedulingSaveReqVO createReqVO); + + /** + * 更新排班制考勤设置 + * + * @param updateReqVO 更新信息 + */ + void updateScheduling(@Valid AttendanceSchedulingSaveReqVO updateReqVO); + + /** + * 删除排班制考勤设置 + * + * @param id 编号 + */ + void deleteScheduling(Long id); + + /** + * 获得排班制考勤设置 + * + * @param id 编号 + * @return 排班制考勤设置 + */ + AttendanceSchedulingDO getScheduling(Long id); + + /** + * 获得排班制考勤设置分页 + * + * @param pageReqVO 分页查询 + * @return 排班制考勤设置分页 + */ + PageResult getSchedulingPage(AttendanceSchedulingPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingServiceImpl.java new file mode 100644 index 00000000..2319a432 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/scheduling/AttendanceSchedulingServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.system.service.scheduling; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.system.controller.admin.scheduling.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.scheduling.AttendanceSchedulingDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.system.dal.mysql.scheduling.AttendanceSchedulingMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; + +/** + * 排班制考勤设置 Service 实现类 + * + * @author 艾楷 + */ +@Service("scheduling") +@Validated +public class AttendanceSchedulingServiceImpl implements AttendanceSchedulingService { + + @Resource + private AttendanceSchedulingMapper schedulingMapper; + + @Override + public Long createScheduling(AttendanceSchedulingSaveReqVO createReqVO) { + // 插入 + AttendanceSchedulingDO scheduling = BeanUtils.toBean(createReqVO, AttendanceSchedulingDO.class); + schedulingMapper.insert(scheduling); + // 返回 + return scheduling.getId(); + } + + @Override + public void updateScheduling(AttendanceSchedulingSaveReqVO updateReqVO) { + // 校验存在 + validateSchedulingExists(updateReqVO.getId()); + // 更新 + AttendanceSchedulingDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceSchedulingDO.class); + schedulingMapper.updateById(updateObj); + } + + @Override + public void deleteScheduling(Long id) { + // 校验存在 + validateSchedulingExists(id); + // 删除 + schedulingMapper.deleteById(id); + } + + private void validateSchedulingExists(Long id) { + if (schedulingMapper.selectById(id) == null) { + throw exception(SCHEDULING_NOT_EXISTS); + } + } + + @Override + public AttendanceSchedulingDO getScheduling(Long id) { + return schedulingMapper.selectById(id); + } + + @Override + public PageResult getSchedulingPage(AttendanceSchedulingPageReqVO pageReqVO) { + return schedulingMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/fixed/AttendanceFixedMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/fixed/AttendanceFixedMapper.xml new file mode 100644 index 00000000..871e1845 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/fixed/AttendanceFixedMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml new file mode 100644 index 00000000..3ef95aaa --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupshift/AttendanceGroupShiftMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupshift/AttendanceGroupShiftMapper.xml new file mode 100644 index 00000000..de293bf0 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupshift/AttendanceGroupShiftMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupuser/AttendanceGroupUserMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupuser/AttendanceGroupUserMapper.xml new file mode 100644 index 00000000..817415c0 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/groupuser/AttendanceGroupUserMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/punchrecord/AttendancePunchRecordMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/punchrecord/AttendancePunchRecordMapper.xml new file mode 100644 index 00000000..b564016c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/punchrecord/AttendancePunchRecordMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml new file mode 100644 index 00000000..511d3a24 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file From c1dedf1e262105964e8ae8c833b18a5741b425ad Mon Sep 17 00:00:00 2001 From: aikai Date: Wed, 10 Apr 2024 19:42:33 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rule/dept/DeptDataPermissionRule.java | 42 +++++++++-------- .../task/BpmProcessInstanceController.java | 8 +++- .../task/BpmProcessInstanceExtMapper.java | 46 +++++++------------ .../config/DataPermissionConfiguration.java | 21 ++++----- .../task/BpmProcessInstanceServiceImpl.java | 2 +- 5 files changed, 55 insertions(+), 64 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java index bff515ed..d40d7f5e 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.framework.datapermission.core.rule.dept; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -22,27 +23,22 @@ import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.InExpression; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * 基于部门的 {@link DataPermissionRule} 数据权限规则实现 - * + *

* 注意,使用 DeptDataPermissionRule 时,需要保证表中有 dept_id 部门编号的字段,可自定义。 - * + *

* 实际业务场景下,会存在一个经典的问题?当用户修改部门时,冗余的 dept_id 是否需要修改? * 1. 一般情况下,dept_id 不进行修改,则会导致用户看不到之前的数据。【yudao-server 采用该方案】 * 2. 部分情况下,希望该用户还是能看到之前的数据,则有两种方式解决:【需要你改造该 DeptDataPermissionRule 的实现代码】 - * 1)编写洗数据的脚本,将 dept_id 修改成新部门的编号;【建议】 - * 最终过滤条件是 WHERE dept_id = ? - * 2)洗数据的话,可能涉及的数据量较大,也可以采用 user_id 进行过滤的方式,此时需要获取到 dept_id 对应的所有 user_id 用户编号; - * 最终过滤条件是 WHERE user_id IN (?, ?, ? ...) - * 3)想要保证原 dept_id 和 user_id 都可以看的到,此时使用 dept_id 和 user_id 一起过滤; - * 最终过滤条件是 WHERE dept_id = ? OR user_id IN (?, ?, ? ...) - * - + * 1)编写洗数据的脚本,将 dept_id 修改成新部门的编号;【建议】 + * 最终过滤条件是 WHERE dept_id = ? + * 2)洗数据的话,可能涉及的数据量较大,也可以采用 user_id 进行过滤的方式,此时需要获取到 dept_id 对应的所有 user_id 用户编号; + * 最终过滤条件是 WHERE user_id IN (?, ?, ? ...) + * 3)想要保证原 dept_id 和 user_id 都可以看的到,此时使用 dept_id 和 user_id 一起过滤; + * 最终过滤条件是 WHERE dept_id = ? OR user_id IN (?, ?, ? ...) */ @AllArgsConstructor @Slf4j @@ -60,10 +56,15 @@ public class DeptDataPermissionRule implements DataPermissionRule { private final PermissionApi permissionApi; + // TODO: 2024/4/10 注意 - 如果需要降级低权的话 要把需要的表名称加在这里 并且在方法上开启数据权限 并且添加 DataPermissionConfiguration 对象 + private static final List LOW_POWER_TABLES = Arrays.asList( + "bpm_process_instance_ext" + ); + /** * 基于部门的表字段配置 * 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。 - * + *

* key:表名 * value:字段名 */ @@ -71,7 +72,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { /** * 基于用户的表字段配置 * 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。 - * + *

* key:表名 * value:字段名 */ @@ -113,18 +114,19 @@ public class DeptDataPermissionRule implements DataPermissionRule { } // 情况一,如果是 ALL 可查看全部,则无需拼接条件 - if (deptDataPermission.getAll()) { + // 并且 (低权 和 支持地权) 都不成立 + if (deptDataPermission.getAll() && !((deptDataPermission.getSelf() || CollectionUtil.isNotEmpty(deptDataPermission.getDeptIds())) && LOW_POWER_TABLES.contains(tableName))) { return null; } // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限 if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) - && Boolean.FALSE.equals(deptDataPermission.getSelf())) { + && Boolean.FALSE.equals(deptDataPermission.getSelf())) { return new EqualsTo(null, null); // WHERE null = null,可以保证返回的数据为空 } // 情况三,拼接 Dept 和 User 的条件,最后组合 - Expression deptExpression = buildDeptExpression(tableName,tableAlias, deptDataPermission.getDeptIds()); + Expression deptExpression = buildDeptExpression(tableName, tableAlias, deptDataPermission.getDeptIds()); Expression userExpression = buildUserExpression(tableName, tableAlias, deptDataPermission.getSelf(), loginUser.getId()); if (deptExpression == null && userExpression == null) { // TODO 芋艿:获得不到条件的时候,暂时不抛出异常,而是不返回数据 @@ -180,7 +182,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { public void addDeptColumn(Class entityClass, String columnName) { String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName(); - addDeptColumn(tableName, columnName); + addDeptColumn(tableName, columnName); } public void addDeptColumn(String tableName, String columnName) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java index c10b3375..3ef62b01 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -25,7 +25,6 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti @RestController @RequestMapping("/bpm/process-instance") @Validated -@DataPermission(enable = false) public class BpmProcessInstanceController { @Resource @@ -34,6 +33,7 @@ public class BpmProcessInstanceController { @GetMapping("/my-page") @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用") @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") + @DataPermission(enable = false) public CommonResult> getMyProcessInstancePage( @Valid BpmProcessInstanceMyPageReqVO pageReqVO) { return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO)); @@ -42,6 +42,7 @@ public class BpmProcessInstanceController { @PostMapping("/create") @Operation(summary = "新建流程实例") @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") + @DataPermission(enable = false) public CommonResult createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) { return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); } @@ -50,6 +51,7 @@ public class BpmProcessInstanceController { @Operation(summary = "获得指定流程实例", description = "在【流程详细】界面中,进行调用") @Parameter(name = "id", description = "流程实例的编号", required = true) @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") + @DataPermission(enable = false) public CommonResult getProcessInstance(@RequestParam("id") String id) { return success(processInstanceService.getProcessInstanceVO(id)); } @@ -57,6 +59,7 @@ public class BpmProcessInstanceController { @DeleteMapping("/cancel") @Operation(summary = "取消流程实例", description = "撤回发起的流程") @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')") + @DataPermission(enable = false) public CommonResult cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) { processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO); return success(true); @@ -69,6 +72,7 @@ public class BpmProcessInstanceController { @GetMapping("/process_instance_group_name_statistics") @Operation(summary = "根据流程名称分组,统计各个流程的具体实例数据", description = "根据流程名称分组,统计各个流程的具体实例数据") //@PreAuthorize("@ss.hasPermission('bpm:task:update')") + @DataPermission(enable = false) public CommonResult> getProcessInstancesGroupByModelName(@Valid BpmProcessInstanceStatisticsReqVO reqVO) { List list = processInstanceService.getProcessInstancesGroupByModelName(reqVO); return success(list); @@ -80,6 +84,7 @@ public class BpmProcessInstanceController { */ @GetMapping("/process_instance_result_status_statistics") @Operation(summary = "流程实例的状态统计查询", description = "根据流程状态(处理中,通过,不通过,取消),统计各个状态的数据量") + @DataPermission(enable = false) public CommonResult> getProcessInstancesGroupByResultStatus(@Valid BpmProcessInstanceStatisticsReqVO reqVO) { List list = processInstanceService.getProcessInstancesGroupByResultStatus(reqVO); return success(list); @@ -95,6 +100,7 @@ public class BpmProcessInstanceController { @GetMapping("/getUserProcessTpo10") @Operation(summary = "获得用户审批耗时最长Top10", description = "在工作台-给数据权限是可以查看全部数据的用户查询使用") + @DataPermission(enable = false) public CommonResult> getUserProcessTpo10(@Valid BpmProcessInstanceStatisticsReqVO reqVO) { List list = processInstanceService.getUserProcessTpo10(reqVO); return success(list); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java index 4916ce68..8128614e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java @@ -8,10 +8,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceStatisticsReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceStatisticsRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; import java.util.List; @@ -21,7 +18,7 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX selectCCPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() // .eqIfPresent(BpmProcessInstanceExtDO::getStartUserId, userId) - .likeIfPresent(BpmProcessInstanceExtDO::getCcids, "["+userId+"]") + .likeIfPresent(BpmProcessInstanceExtDO::getCcids, "[" + userId + "]") .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId()) .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory()) .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus()) @@ -53,36 +50,25 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO reqVO) ; + List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO reqVO); - List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO reqVO) ; + List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO reqVO); + + default PageResult selectStatisticePage(BpmProcessInstanceMyPageReqVO reqVO) { + //如果为空,那么查询全部 + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName()) + .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId()) + .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory()) + .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus()) + .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult()) + .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(BpmProcessInstanceExtDO::getId)); - default PageResult selectStatisticePage(Long[] userIds, BpmProcessInstanceMyPageReqVO reqVO) { - if( userIds == null ) { - //如果为空,那么查询全部 - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName()) - .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId()) - .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory()) - .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus()) - .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult()) - .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(BpmProcessInstanceExtDO::getId)); - }else { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName()) - .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId()) - .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory()) - .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus()) - .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult()) - .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getCreateTime()) - .in(BpmProcessInstanceExtDO::getStartUserId,userIds) - .orderByDesc(BpmProcessInstanceExtDO::getId)); - } } - List getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO reqVO) ; + List getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO reqVO); - List selectUnfinishProcessCount(BpmProcessInstanceStatisticsReqVO reqVO) ; + List selectUnfinishProcessCount(BpmProcessInstanceStatisticsReqVO reqVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/datapermission/config/DataPermissionConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/datapermission/config/DataPermissionConfiguration.java index 0c0c3938..140c9c14 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/datapermission/config/DataPermissionConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/datapermission/config/DataPermissionConfiguration.java @@ -8,20 +8,17 @@ import org.springframework.context.annotation.Configuration; /** * 工作流 模块的数据权限 Configuration * - + */ -//@Configuration(proxyBeanMethods = false) +@Configuration(proxyBeanMethods = false) public class DataPermissionConfiguration { -// @Bean -// public DeptDataPermissionRuleCustomizer sysDeptDataPermissionRuleCustomizer() { -// return rule -> { -// // dept -// rule.addDeptColumn(AdminUserDO.class); -// rule.addDeptColumn(DeptDO.class, "id"); -// // user -// rule.addUserColumn(BpmProcessInstanceExtDO.class, "start_user_id"); -// }; -// } + @Bean + public DeptDataPermissionRuleCustomizer sysDeptDataPermissionRuleCustomizer() { + return rule -> { + // user + rule.addUserColumn(BpmProcessInstanceExtDO.class, "start_user_id"); + }; + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index ab87c40d..8a53a6aa 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -1 +1 @@ -package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmConstants; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.lang.reflect.Field; import java.text.DecimalFormat; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. * * HistoricProcessInstance & ProcessInstance 的关系: * 1. * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private TaskService engineTaskService; @Resource private BpmTaskAssignRuleMapper taskRuleMapper; @Resource private BpmUserGroupService userGroupService; @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource @Lazy // 解决循环依赖 private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getProcessInstances(Set ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); // 获得 User Map Map userMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap, userMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())).getCheckedData(); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()).getCheckedData(); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getHistoricProcessInstances(Set ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); Map processVariables = runtimeService.getVariables(instance.getProcessInstanceId()); String reason = (String)processVariables.get("approve_reason") ; // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance,reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) .setFormVariables(variables)); /** 创建流程后,添加抄送人 End add by yj 2024.1.4 */ processCCToUsers(definition,instance) ; /** 通过自己发起的流程 */ approveSelfTask(instance.getId()) ; return instance.getId(); } private void approveSelfTask(String processInstanceId ) { List tasks =engineTaskService.createTaskQuery().processInstanceId(processInstanceId).list() ; if( tasks != null && tasks.size() > 0) { Task task = tasks.get(0) ; String assigneeId = task.getAssignee(); //如果当前登陆用户是审批人,那么自动审批通过 if( assigneeId.equals( SecurityFrameworkUtils.getLoginUserId().toString() )) { BpmTaskApproveReqVO reqVO = new BpmTaskApproveReqVO() ; reqVO.setId(task.getId()) ; reqVO.setReason(BpmConstants.AUTO_APPRAVAL); taskService.approveTask(getLoginUserId(), reqVO); } } } /** * 获得抄送我的流程实例的分页 * * @param userId 用户编号 * @param pageReqVO 分页请求 * @return 流程实例的分页 */ public PageResult getMyCCProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectCCPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap,null); } public List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO pageReqVO){ pageReqVO = getUserids(pageReqVO) ; return processInstanceExtMapper.getProcessInstancesGroupByModelName(pageReqVO) ; } public List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO pageReqVO){ pageReqVO = getUserids(pageReqVO) ; return processInstanceExtMapper.getProcessInstancesGroupByResultStatus(pageReqVO) ; } public PageResult getStatisticsProcessInstancePage(@Valid BpmProcessInstanceMyPageReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO) ; // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectStatisticePage(pageReqVO.getUserIds(), pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); //获得 审批人 User Map Map assigneeUserMap = adminUserApi.getUserMap(longIds); //获得 发起人 User Map List bpieDOs = pageResult.getList() ; longIds = new ArrayList<>() ; for (BpmProcessInstanceExtDO bpieDO: bpieDOs) { longIds.add(bpieDO.getStartUserId()) ; } Map startUserMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertStatisticsPage(pageResult, taskMap, assigneeUserMap,startUserMap); } @Resource PermissionApi permissionApi; /** * 根据数据权限,查询关联操作的用户IDS * @param pageReqVO * @return * @param */ private T getUserids(T pageReqVO) { try { Class clazz = (Class) pageReqVO.getClass(); Field idField = clazz.getDeclaredField("userIds"); idField.setAccessible(true); // 设置可访问性 Long[] userIds = null; Long userId = WebFrameworkUtils.getLoginUserId(); DeptDataPermissionRespDTO deptDataPermission = permissionApi.getDeptDataPermission(userId).getCheckedData(); //查询全部 if (deptDataPermission.getAll()) { //idField.set(pageReqVO, null); // 设置属性值 return pageReqVO; } // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限 if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) && Boolean.FALSE.equals(deptDataPermission.getSelf())) { //设置成0,一个不存在的用户Id,就查询不到数据了。 userIds = new Long[]{0L}; idField.set(pageReqVO, userIds); return pageReqVO; } //情况三 至查询自己 if (deptDataPermission.getSelf()) { userIds = new Long[]{userId}; idField.set(pageReqVO, userIds); return pageReqVO; } Set deptIds = deptDataPermission.getDeptIds(); //查询部门关联的用户Id List users = adminUserApi.getUserListByDeptIds(deptIds).getCheckedData(); List tempList = new ArrayList<>(); for (AdminUserRespDTO user : users) { Long id = user.getId(); tempList.add(id); } tempList.add(userId); userIds = tempList.stream().toArray(Long[]::new); //将临时的List集合转换成数组集合 idField.set(pageReqVO, userIds); return pageReqVO; }catch (Exception exception){ exception.printStackTrace(); throw exception(BPM_SYSTEM_BUG); } } /** * /创建流程后,添加抄送人 Begin add by yj 2024.1.4 * 在设计流程的时候,需要添加一个任务块 名字必须叫Activity_cc 分配权限的时候,需要选择用户组。 * * @param definition * @param instance */ private void processCCToUsers(ProcessDefinition definition, ProcessInstance instance) { //获取bpm_task_assign_reule (Bpm 任务规则表)的流程中有没有配置抄送节点 固定抄送名称为:Activity_cc String processDefinitionId = definition.getId() ; List rules = taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, null); for(BpmTaskAssignRuleDO rule :rules ){ String key = rule.getTaskDefinitionKey() ; //任务名称 Integer type = rule.getType() ; if( !key.isEmpty() && key.equals(BpmConstants.CC_NAME) && type == 40 ) { StringBuffer str = new StringBuffer() ; Set options = rule.getOptions() ; List list = new ArrayList(options); for(Long groupId : list) { //需要根据这个groupId,查询这个组中的用户id BpmUserGroupDO userGroup = userGroupService.getUserGroup(groupId); Set userIds = userGroup.getMemberUserIds() ; List userIdList = new ArrayList(userIds); for(Long user_id : userIdList) { str.append("[").append(user_id).append("]") ; } } String ccids = str.toString() ; //根据processDefinitionId 将ccids保存到bpm_process_instance_ext中的ccids字段 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessDefinitionId(processDefinitionId) .setCcids(ccids) .setProcessInstanceId(instance.getProcessInstanceId()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); break ; } } } @Resource private BpmTaskExtMapper taskExtMapper; @Override public List getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO pageReqVO) { //按审核人分组查询,统计已完成流程数量及平均耗时间 List respVOS = processInstanceExtMapper.getUserProcessTpo10(pageReqVO); if( respVOS == null || respVOS.size() == 0) { return null ; } List idList = respVOS.stream() .map(BpmProcessFinishStatisticsRespVO::getUserId) .collect(Collectors.toList()); //根据userId,查询UserMap Map userMap = adminUserApi.getUserMap(idList) ; Long[] idsArray = new Long[userMap.size()]; // 使用 map 的 keySet() 方法获取键集合 Set keys = userMap.keySet(); // 遍历键集合,将每个键添加到数组中 int index = 0; for (Long key : keys) { idsArray[index++] = key; } pageReqVO.setUserIds(idsArray) ; //按审核人分组查询,未审批完成的流程数量 List bpmTaskExtDOs = processInstanceExtMapper.selectUnfinishProcessCount( pageReqVO ) ; //按审核人分组查询,未完成的记录数 Map unFinfishCountCountMap = new HashMap<>(); for (BpmProcessFinishStatisticsRespVO item : bpmTaskExtDOs) { unFinfishCountCountMap.put(item.getUserId(), item.getUnFinfishCount()); } respVOS.forEach(respVO -> respVO.setName( userMap.get(respVO.getUserId()).getNickname())); respVOS.forEach(respVO -> respVO.setUnFinfishCount( unFinfishCountCountMap.get(respVO.getUserId()))); //获取排行榜第一记录的耗时,作为基础数据 double num = Double.parseDouble(respVOS.get(0).getUserTime()); // 先将字符串转换为双精度浮点数 int baseNumber = (int)num; // 再通过类型转换操作符将其转换为整数 DecimalFormat df = new DecimalFormat("#.00"); respVOS.forEach(respVO -> { //格式化流程完成率 float finfishCount = (float) respVO.getFinfishCount() ; float unFinfishCount = respVO.getUnFinfishCount() == null ? 0: respVO.getUnFinfishCount(); float all = finfishCount + unFinfishCount ; float result = finfishCount / all; float rate = result * 100 ; respVO.setCompletionRate(df.format(rate)+"%") ; double dValue = Double.parseDouble(respVO.getUserTime()); // 将字符串转换为double类型 int roundedValue = (int) Math.round(dValue); // 使用Math.round()进行四舍五入,并转换为int类型 respVO.setUserTime(roundedValue+"") ; //格式化进度百度比, 参照最高的数据进行百分比显示 double percentage = ((int)Double.parseDouble(respVO.getUserTime()) / (double) baseNumber) * 100; respVO.setPercentage((int) Math.round(percentage)) ; //设置未完成 respVO.setUnFinfishCount( Integer.valueOf((int)unFinfishCount)) ; }); return respVOS ; } @Override public BpmProcessInstanceExtDO getProcessInstanceDO(String id) { return processInstanceExtMapper.selectByProcessInstanceId(id); } } \ No newline at end of file +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmConstants; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.lang.reflect.Field; import java.text.DecimalFormat; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. * * HistoricProcessInstance & ProcessInstance 的关系: * 1. * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private TaskService engineTaskService; @Resource private BpmTaskAssignRuleMapper taskRuleMapper; @Resource private BpmUserGroupService userGroupService; @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource @Lazy // 解决循环依赖 private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getProcessInstances(Set ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); // 获得 User Map Map userMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap, userMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())).getCheckedData(); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()).getCheckedData(); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getHistoricProcessInstances(Set ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); Map processVariables = runtimeService.getVariables(instance.getProcessInstanceId()); String reason = (String)processVariables.get("approve_reason") ; // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance,reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) .setFormVariables(variables)); /** 创建流程后,添加抄送人 End add by yj 2024.1.4 */ processCCToUsers(definition,instance) ; /** 通过自己发起的流程 */ approveSelfTask(instance.getId()) ; return instance.getId(); } private void approveSelfTask(String processInstanceId ) { List tasks =engineTaskService.createTaskQuery().processInstanceId(processInstanceId).list() ; if( tasks != null && tasks.size() > 0) { Task task = tasks.get(0) ; String assigneeId = task.getAssignee(); //如果当前登陆用户是审批人,那么自动审批通过 if( assigneeId.equals( SecurityFrameworkUtils.getLoginUserId().toString() )) { BpmTaskApproveReqVO reqVO = new BpmTaskApproveReqVO() ; reqVO.setId(task.getId()) ; reqVO.setReason(BpmConstants.AUTO_APPRAVAL); taskService.approveTask(getLoginUserId(), reqVO); } } } /** * 获得抄送我的流程实例的分页 * * @param userId 用户编号 * @param pageReqVO 分页请求 * @return 流程实例的分页 */ public PageResult getMyCCProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectCCPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap,null); } public List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO pageReqVO){ pageReqVO = getUserids(pageReqVO) ; return processInstanceExtMapper.getProcessInstancesGroupByModelName(pageReqVO) ; } public List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO pageReqVO){ pageReqVO = getUserids(pageReqVO) ; return processInstanceExtMapper.getProcessInstancesGroupByResultStatus(pageReqVO) ; } public PageResult getStatisticsProcessInstancePage(@Valid BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectStatisticePage(pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); //获得 审批人 User Map Map assigneeUserMap = adminUserApi.getUserMap(longIds); //获得 发起人 User Map List bpieDOs = pageResult.getList() ; longIds = new ArrayList<>() ; for (BpmProcessInstanceExtDO bpieDO: bpieDOs) { longIds.add(bpieDO.getStartUserId()) ; } Map startUserMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertStatisticsPage(pageResult, taskMap, assigneeUserMap,startUserMap); } @Resource PermissionApi permissionApi; /** * 根据数据权限,查询关联操作的用户IDS * @param pageReqVO * @return * @param */ private T getUserids(T pageReqVO) { try { Class clazz = (Class) pageReqVO.getClass(); Field idField = clazz.getDeclaredField("userIds"); idField.setAccessible(true); // 设置可访问性 Long[] userIds = null; Long userId = WebFrameworkUtils.getLoginUserId(); DeptDataPermissionRespDTO deptDataPermission = permissionApi.getDeptDataPermission(userId).getCheckedData(); //查询全部 if (deptDataPermission.getAll()) { //idField.set(pageReqVO, null); // 设置属性值 return pageReqVO; } // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限 if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) && Boolean.FALSE.equals(deptDataPermission.getSelf())) { //设置成0,一个不存在的用户Id,就查询不到数据了。 userIds = new Long[]{0L}; idField.set(pageReqVO, userIds); return pageReqVO; } //情况三 至查询自己 if (deptDataPermission.getSelf()) { userIds = new Long[]{userId}; idField.set(pageReqVO, userIds); return pageReqVO; } Set deptIds = deptDataPermission.getDeptIds(); //查询部门关联的用户Id List users = adminUserApi.getUserListByDeptIds(deptIds).getCheckedData(); List tempList = new ArrayList<>(); for (AdminUserRespDTO user : users) { Long id = user.getId(); tempList.add(id); } tempList.add(userId); userIds = tempList.stream().toArray(Long[]::new); //将临时的List集合转换成数组集合 idField.set(pageReqVO, userIds); return pageReqVO; }catch (Exception exception){ exception.printStackTrace(); throw exception(BPM_SYSTEM_BUG); } } /** * /创建流程后,添加抄送人 Begin add by yj 2024.1.4 * 在设计流程的时候,需要添加一个任务块 名字必须叫Activity_cc 分配权限的时候,需要选择用户组。 * * @param definition * @param instance */ private void processCCToUsers(ProcessDefinition definition, ProcessInstance instance) { //获取bpm_task_assign_reule (Bpm 任务规则表)的流程中有没有配置抄送节点 固定抄送名称为:Activity_cc String processDefinitionId = definition.getId() ; List rules = taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, null); for(BpmTaskAssignRuleDO rule :rules ){ String key = rule.getTaskDefinitionKey() ; //任务名称 Integer type = rule.getType() ; if( !key.isEmpty() && key.equals(BpmConstants.CC_NAME) && type == 40 ) { StringBuffer str = new StringBuffer() ; Set options = rule.getOptions() ; List list = new ArrayList(options); for(Long groupId : list) { //需要根据这个groupId,查询这个组中的用户id BpmUserGroupDO userGroup = userGroupService.getUserGroup(groupId); Set userIds = userGroup.getMemberUserIds() ; List userIdList = new ArrayList(userIds); for(Long user_id : userIdList) { str.append("[").append(user_id).append("]") ; } } String ccids = str.toString() ; //根据processDefinitionId 将ccids保存到bpm_process_instance_ext中的ccids字段 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessDefinitionId(processDefinitionId) .setCcids(ccids) .setProcessInstanceId(instance.getProcessInstanceId()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); break ; } } } @Resource private BpmTaskExtMapper taskExtMapper; @Override public List getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO pageReqVO) { //按审核人分组查询,统计已完成流程数量及平均耗时间 List respVOS = processInstanceExtMapper.getUserProcessTpo10(pageReqVO); if( respVOS == null || respVOS.size() == 0) { return null ; } List idList = respVOS.stream() .map(BpmProcessFinishStatisticsRespVO::getUserId) .collect(Collectors.toList()); //根据userId,查询UserMap Map userMap = adminUserApi.getUserMap(idList) ; Long[] idsArray = new Long[userMap.size()]; // 使用 map 的 keySet() 方法获取键集合 Set keys = userMap.keySet(); // 遍历键集合,将每个键添加到数组中 int index = 0; for (Long key : keys) { idsArray[index++] = key; } pageReqVO.setUserIds(idsArray) ; //按审核人分组查询,未审批完成的流程数量 List bpmTaskExtDOs = processInstanceExtMapper.selectUnfinishProcessCount( pageReqVO ) ; //按审核人分组查询,未完成的记录数 Map unFinfishCountCountMap = new HashMap<>(); for (BpmProcessFinishStatisticsRespVO item : bpmTaskExtDOs) { unFinfishCountCountMap.put(item.getUserId(), item.getUnFinfishCount()); } respVOS.forEach(respVO -> respVO.setName( userMap.get(respVO.getUserId()).getNickname())); respVOS.forEach(respVO -> respVO.setUnFinfishCount( unFinfishCountCountMap.get(respVO.getUserId()))); //获取排行榜第一记录的耗时,作为基础数据 double num = Double.parseDouble(respVOS.get(0).getUserTime()); // 先将字符串转换为双精度浮点数 int baseNumber = (int)num; // 再通过类型转换操作符将其转换为整数 DecimalFormat df = new DecimalFormat("#.00"); respVOS.forEach(respVO -> { //格式化流程完成率 float finfishCount = (float) respVO.getFinfishCount() ; float unFinfishCount = respVO.getUnFinfishCount() == null ? 0: respVO.getUnFinfishCount(); float all = finfishCount + unFinfishCount ; float result = finfishCount / all; float rate = result * 100 ; respVO.setCompletionRate(df.format(rate)+"%") ; double dValue = Double.parseDouble(respVO.getUserTime()); // 将字符串转换为double类型 int roundedValue = (int) Math.round(dValue); // 使用Math.round()进行四舍五入,并转换为int类型 respVO.setUserTime(roundedValue+"") ; //格式化进度百度比, 参照最高的数据进行百分比显示 double percentage = ((int)Double.parseDouble(respVO.getUserTime()) / (double) baseNumber) * 100; respVO.setPercentage((int) Math.round(percentage)) ; //设置未完成 respVO.setUnFinfishCount( Integer.valueOf((int)unFinfishCount)) ; }); return respVOS ; } @Override public BpmProcessInstanceExtDO getProcessInstanceDO(String id) { return processInstanceExtMapper.selectByProcessInstanceId(id); } } \ No newline at end of file From 98873d8b89790fa1a55ab03314d40b9cb2e8f8e5 Mon Sep 17 00:00:00 2001 From: aikai Date: Wed, 10 Apr 2024 21:13:16 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-gateway/src/main/resources/bootstrap.yaml | 2 +- .../yudao-module-bpm-biz/src/main/resources/bootstrap.yaml | 2 +- .../yudao-module-infra-biz/src/main/resources/bootstrap.yaml | 2 +- .../yudao-module-system-biz/src/main/resources/bootstrap.yaml | 2 +- .../src/main/resources/bootstrap.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/yudao-gateway/src/main/resources/bootstrap.yaml b/yudao-gateway/src/main/resources/bootstrap.yaml index 55165083..ba7a42c4 100644 --- a/yudao-gateway/src/main/resources/bootstrap.yaml +++ b/yudao-gateway/src/main/resources/bootstrap.yaml @@ -3,7 +3,7 @@ spring: name: gateway-server profiles: - active: local #local + active: dev #local # active: prod server: port: 48080 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/bootstrap.yaml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/bootstrap.yaml index 90fc58af..f2da21dc 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/bootstrap.yaml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/bootstrap.yaml @@ -3,7 +3,7 @@ spring: name: bpm-server profiles: - active: local #local + active: dev #local # active: prod server: diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/bootstrap.yaml b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/bootstrap.yaml index b28d9964..64e03794 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/bootstrap.yaml +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/bootstrap.yaml @@ -3,7 +3,7 @@ spring: name: infra-server profiles: - active: local #local + active: dev #local # active: prod server: diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/bootstrap.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/bootstrap.yaml index 7abdef88..9498addd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/bootstrap.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/bootstrap.yaml @@ -3,7 +3,7 @@ spring: name: system-server profiles: - active: local #local + active: dev #local # active: prod server: diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/bootstrap.yaml b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/bootstrap.yaml index 7591aed7..818d6381 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/bootstrap.yaml +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/bootstrap.yaml @@ -3,7 +3,7 @@ spring: name: smartfactory-server profiles: - active: local + active: dev server: port: 48090 From 72f6b89fd9480bc026aed6d6e809e3cd646e3dc5 Mon Sep 17 00:00:00 2001 From: aikai Date: Thu, 11 Apr 2024 13:04:55 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B0=8F=E7=A8=8B=E5=BA=8F=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yaml | 4 ++-- .../src/main/resources/application-local.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml index 72d23f84..96835b0f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml @@ -125,8 +125,8 @@ wx: miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 # appid: wx62056c0d5e8db250 # secret: 333ae72f41552af1e998fe1f54e1584a - appid: wx63c280fe3248a3e7 # wenhualian的接口测试号 - secret: 6f270509224a7ae1296bbf1c8cb97aed + appid: wxea777d1b1e12eb32 # wenhualian的接口测试号 + secret: 2db58956286099e58e959fa537e046b0 config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 key-prefix: wa # Redis Key 的前缀 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml index 6a749708..bc7aa1a6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml @@ -143,8 +143,8 @@ wx: miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 # appid: wx62056c0d5e8db250 # secret: 333ae72f41552af1e998fe1f54e1584a - appid: wx2919e237e6018bea # wenhualian的接口测试号 - secret: ad7ab17918f6defa85a9677778eb7780 + appid: wxea777d1b1e12eb32 # wenhualian的接口测试号 + secret: 2db58956286099e58e959fa537e046b0 config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 key-prefix: wa # Redis Key 的前缀 From ebe9f0c445a44421a361257978dd382bcf419fe4 Mon Sep 17 00:00:00 2001 From: aikai Date: Thu, 11 Apr 2024 16:02:56 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E9=87=87=E8=B4=AD=E6=94=AF=E4=BB=98=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E9=87=87=E8=B4=AD=E8=AF=A6=E6=83=85json?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/oa/vo/procurepay/BpmOAProcurePayItemRespVO.java | 5 +++++ .../admin/oa/vo/procurepay/BpmOAProcurePayRespVO.java | 7 +++++++ .../admin/oa/vo/procurepay/BpmOAProcurePaySaveReqVO.java | 3 +++ .../main/resources/mapper/oa/BpmOAProcurePayItemMapper.xml | 1 + 4 files changed, 16 insertions(+) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayItemRespVO.java index 5a4bb4ef..e5a252c0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayItemRespVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.procurepay; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -7,6 +8,7 @@ import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; @Schema(description = "管理后台 - 采购收款明细 Response VO") @Data @@ -45,6 +47,7 @@ public class BpmOAProcurePayItemRespVO { @Schema(description = "期望交付日期") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime expectedDeliveryDate; @Schema(description = "备注") @@ -56,4 +59,6 @@ public class BpmOAProcurePayItemRespVO { @Schema(description = "采购总金额大写") private String totalMoneyChinese; + @Schema(description = "采购详情json数据") + private String procureDetailJson; } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayRespVO.java index b3f51e9a..1b4fbc3b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePayRespVO.java @@ -1,13 +1,18 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.procurepay; import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + @Schema(description = "管理后台 - 采购支付 Response VO") @Data public class BpmOAProcurePayRespVO { @@ -22,6 +27,8 @@ public class BpmOAProcurePayRespVO { private String reason; @Schema(description = "支付日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime payTime; @Schema(description = "采购付款总金额", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePaySaveReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePaySaveReqVO.java index e3bae9f4..99bac792 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePaySaveReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/procurepay/BpmOAProcurePaySaveReqVO.java @@ -10,6 +10,8 @@ import java.math.BigDecimal; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + @Schema(description = "管理后台 - 采购支付新增/修改 Request VO") @Data public class BpmOAProcurePaySaveReqVO { @@ -25,6 +27,7 @@ public class BpmOAProcurePaySaveReqVO { private String reason; @Schema(description = "支付日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime payTime; @Schema(description = "采购付款总金额", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcurePayItemMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcurePayItemMapper.xml index cfa7974e..9a2e29de 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcurePayItemMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcurePayItemMapper.xml @@ -18,6 +18,7 @@ b.reason, b.procure_type, b.expected_delivery_date, + b.procure_detail_json as procureDetailJson, b.remarks, b.total_money, b.total_money_chinese