From 3dc735d1e639fbeccc0c18835d49ff5d7d4d2bb2 Mon Sep 17 00:00:00 2001 From: Yangk Date: Wed, 6 May 2026 17:53:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(oa):=20=E5=AE=8C=E5=96=84=E6=9C=88?= =?UTF-8?q?=E5=B7=A5=E6=97=B6=E6=B1=87=E6=80=BB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增工时汇总明细子表管理功能 - 添加工时汇总数据预览生成功能 - 优化数据库查询添加部门和负责人关联信息 - 实现工时数据聚合统计功能 - 完善数据校验和事务处理机制 --- .../ErpTimesheetSummaryController.java | 10 + .../erp/domain/ErpTimesheetStandardMonth.java | 4 +- .../oa/erp/domain/ErpTimesheetSummary.java | 12 +- .../erp/domain/ErpTimesheetSummaryDetail.java | 8 +- .../bo/ErpTimesheetStandardMonthBo.java | 3 +- .../erp/domain/bo/ErpTimesheetSummaryBo.java | 20 +- .../bo/ErpTimesheetSummaryDetailBo.java | 7 +- .../vo/ErpTimesheetStandardMonthVo.java | 3 +- .../vo/ErpTimesheetSummaryDetailVo.java | 7 +- .../erp/domain/vo/ErpTimesheetSummaryVo.java | 29 ++- .../erp/mapper/ErpTimesheetSummaryMapper.java | 13 ++ .../service/IErpTimesheetSummaryService.java | 9 + .../impl/ErpTimesheetSummaryServiceImpl.java | 200 ++++++++++++++---- .../oa/erp/ErpTimesheetSummaryMapper.xml | 46 +++- 14 files changed, 302 insertions(+), 69 deletions(-) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpTimesheetSummaryController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpTimesheetSummaryController.java index f70bbba3..aadac5f9 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpTimesheetSummaryController.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpTimesheetSummaryController.java @@ -113,4 +113,14 @@ public class ErpTimesheetSummaryController extends BaseController { return R.ok(list); } + /** + * 生成月汇总工时预览 + */ + @SaCheckPermission("oa/erp:timesheetSummary:add") + @Log(title = "生成月汇总工时预览", businessType = BusinessType.OTHER) + @PostMapping("/generate") + public R generate(@RequestBody ErpTimesheetSummaryBo bo) { + return R.ok(erpTimesheetSummaryService.generateSummary(bo.getMonthCode(), bo.getDeptId())); + } + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetStandardMonth.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetStandardMonth.java index 154f22e2..1f10109f 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetStandardMonth.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetStandardMonth.java @@ -4,6 +4,8 @@ import org.dromara.common.tenant.core.TenantEntity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; @@ -52,7 +54,7 @@ public class ErpTimesheetStandardMonth extends TenantEntity { /** * 月标准工时天数(如21.0、21.5) */ - private Long standardDays; + private BigDecimal standardDays; /** * 备注 diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummary.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummary.java index fa4493c6..2e6f6d5c 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummary.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummary.java @@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; +import java.math.BigDecimal; + import java.io.Serial; /** @@ -55,27 +57,27 @@ public class ErpTimesheetSummary extends TenantEntity { /** * 月标准工时天数(冗余,取自标准月表) */ - private Long standardDays; + private BigDecimal standardDays; /** * 项目工时合计(天) */ - private Long totalProjectHours; + private BigDecimal totalProjectHours; /** * 部门工时合计(天) */ - private Long totalDeptHours; + private BigDecimal totalDeptHours; /** * 总工时合计(天) */ - private Long totalHours; + private BigDecimal totalHours; /** * 汇总人数 */ - private Long staffCount; + private Integer staffCount; /** * 备注 diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummaryDetail.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummaryDetail.java index 3ca732e8..60e3b6d3 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummaryDetail.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpTimesheetSummaryDetail.java @@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; +import java.math.BigDecimal; + import java.io.Serial; /** @@ -35,7 +37,7 @@ public class ErpTimesheetSummaryDetail extends TenantEntity { /** * 排序号 */ - private Long sortOrder; + private Integer sortOrder; /** * 员工用户ID @@ -70,7 +72,7 @@ public class ErpTimesheetSummaryDetail extends TenantEntity { /** * 原项目工时(天) */ - private Long originalHours; + private BigDecimal originalHours; /** * 修改后项目ID @@ -90,7 +92,7 @@ public class ErpTimesheetSummaryDetail extends TenantEntity { /** * 修改后工时(天) */ - private Long adjustedHours; + private BigDecimal adjustedHours; /** * 生成行标识(1自动汇总生成 0手动新增) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetStandardMonthBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetStandardMonthBo.java index 6c83c390..e2ef1a0b 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetStandardMonthBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetStandardMonthBo.java @@ -8,6 +8,7 @@ import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; +import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; @@ -54,7 +55,7 @@ public class ErpTimesheetStandardMonthBo extends BaseEntity { /** * 月标准工时天数(如21.0、21.5) */ - private Long standardDays; + private BigDecimal standardDays; /** * 备注 diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryBo.java index 8025f5dd..1e8ada03 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryBo.java @@ -8,6 +8,8 @@ import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; +import java.math.BigDecimal; +import java.util.List; /** * 月汇总工时信息业务对象 erp_timesheet_summary @@ -29,7 +31,7 @@ public class ErpTimesheetSummaryBo extends BaseEntity { /** * 汇总编号 */ - @NotBlank(message = "汇总编号不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotBlank(message = "汇总编号不能为空", groups = { EditGroup.class }) private String summaryCode; /** @@ -47,7 +49,7 @@ public class ErpTimesheetSummaryBo extends BaseEntity { /** * 汇总人(部门负责人)用户ID */ - @NotNull(message = "汇总人(部门负责人)用户ID不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotNull(message = "汇总人(部门负责人)用户ID不能为空", groups = { EditGroup.class }) private Long userId; /** @@ -58,32 +60,36 @@ public class ErpTimesheetSummaryBo extends BaseEntity { /** * 月标准工时天数(冗余,取自标准月表) */ - private Long standardDays; + private BigDecimal standardDays; /** * 项目工时合计(天) */ - private Long totalProjectHours; + private BigDecimal totalProjectHours; /** * 部门工时合计(天) */ - private Long totalDeptHours; + private BigDecimal totalDeptHours; /** * 总工时合计(天) */ - private Long totalHours; + private BigDecimal totalHours; /** * 汇总人数 */ - private Long staffCount; + private Integer staffCount; /** * 备注 */ private String remark; + /** + * 汇总明细子表列表 + */ + private List summaryDetailList; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryDetailBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryDetailBo.java index 8937d9cd..83185caf 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryDetailBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTimesheetSummaryDetailBo.java @@ -8,6 +8,7 @@ import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; +import java.math.BigDecimal; /** * 月汇总工时明细业务对象 erp_timesheet_summary_detail @@ -35,7 +36,7 @@ public class ErpTimesheetSummaryDetailBo extends BaseEntity { /** * 排序号 */ - private Long sortOrder; + private Integer sortOrder; /** * 员工用户ID @@ -72,7 +73,7 @@ public class ErpTimesheetSummaryDetailBo extends BaseEntity { /** * 原项目工时(天) */ - private Long originalHours; + private BigDecimal originalHours; /** * 修改后项目ID @@ -92,7 +93,7 @@ public class ErpTimesheetSummaryDetailBo extends BaseEntity { /** * 修改后工时(天) */ - private Long adjustedHours; + private BigDecimal adjustedHours; /** * 生成行标识(1自动汇总生成 0手动新增) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetStandardMonthVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetStandardMonthVo.java index e7d9e61e..0bcb6338 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetStandardMonthVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetStandardMonthVo.java @@ -12,6 +12,7 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; +import java.math.BigDecimal; import java.util.Date; @@ -64,7 +65,7 @@ public class ErpTimesheetStandardMonthVo implements Serializable { * 月标准工时天数(如21.0、21.5) */ @ExcelProperty(value = "月标准工时天数(如21.0、21.5)") - private Long standardDays; + private BigDecimal standardDays; /** * 备注 diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryDetailVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryDetailVo.java index 6461842d..3f25de23 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryDetailVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryDetailVo.java @@ -10,6 +10,7 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; +import java.math.BigDecimal; import java.util.Date; @@ -44,7 +45,7 @@ public class ErpTimesheetSummaryDetailVo implements Serializable { * 排序号 */ @ExcelProperty(value = "排序号") - private Long sortOrder; + private Integer sortOrder; /** * 员工用户ID @@ -87,7 +88,7 @@ public class ErpTimesheetSummaryDetailVo implements Serializable { * 原项目工时(天) */ @ExcelProperty(value = "原项目工时(天)") - private Long originalHours; + private BigDecimal originalHours; /** * 修改后项目ID @@ -111,7 +112,7 @@ public class ErpTimesheetSummaryDetailVo implements Serializable { * 修改后工时(天) */ @ExcelProperty(value = "修改后工时(天)") - private Long adjustedHours; + private BigDecimal adjustedHours; /** * 生成行标识(1自动汇总生成 0手动新增) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryVo.java index f9683312..3ef2e37f 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTimesheetSummaryVo.java @@ -10,7 +10,9 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; +import java.math.BigDecimal; import java.util.Date; +import java.util.List; @@ -68,31 +70,31 @@ public class ErpTimesheetSummaryVo implements Serializable { * 月标准工时天数(冗余,取自标准月表) */ @ExcelProperty(value = "月标准工时天数(冗余,取自标准月表)") - private Long standardDays; + private BigDecimal standardDays; /** * 项目工时合计(天) */ @ExcelProperty(value = "项目工时合计(天)") - private Long totalProjectHours; + private BigDecimal totalProjectHours; /** * 部门工时合计(天) */ @ExcelProperty(value = "部门工时合计(天)") - private Long totalDeptHours; + private BigDecimal totalDeptHours; /** * 总工时合计(天) */ @ExcelProperty(value = "总工时合计(天)") - private Long totalHours; + private BigDecimal totalHours; /** * 汇总人数 */ @ExcelProperty(value = "汇总人数") - private Long staffCount; + private Integer staffCount; /** * 备注 @@ -100,5 +102,22 @@ public class ErpTimesheetSummaryVo implements Serializable { @ExcelProperty(value = "备注") private String remark; + /** + * 部门名称 + */ + @ExcelProperty(value = "部门名称") + private String deptName; + + /** + * 负责人姓名 + */ + @ExcelProperty(value = "负责人姓名") + private String leaderName; + + /** + * 汇总明细子表列表 + */ + private List summaryDetailList; + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpTimesheetSummaryMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpTimesheetSummaryMapper.java index b8a72245..0095df3f 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpTimesheetSummaryMapper.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpTimesheetSummaryMapper.java @@ -1,12 +1,15 @@ package org.dromara.oa.erp.mapper; import java.util.List; +import java.util.Date; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; import org.dromara.oa.erp.domain.ErpTimesheetSummary; import org.dromara.oa.erp.domain.vo.ErpTimesheetSummaryVo; +import org.dromara.oa.erp.domain.vo.ErpTimesheetSummaryDetailVo; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; /** @@ -34,4 +37,14 @@ public interface ErpTimesheetSummaryMapper extends BaseMapperPlus selectCustomErpTimesheetSummaryVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + /** + * 聚合查询项目工时 + */ + List selectProjectAggregation(@Param("deptId") Long deptId, @Param("startDate") Date startDate, @Param("endDate") Date endDate); + + /** + * 聚合查询部门工时 + */ + List selectDeptAggregation(@Param("deptId") Long deptId, @Param("startDate") Date startDate, @Param("endDate") Date endDate); + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpTimesheetSummaryService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpTimesheetSummaryService.java index 17e2ab68..66189614 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpTimesheetSummaryService.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpTimesheetSummaryService.java @@ -66,4 +66,13 @@ public interface IErpTimesheetSummaryService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 生成月汇总工时预览数据(不落库) + * + * @param monthCode 月份编码 + * @param deptId 部门ID + * @return 预览数据 + */ + ErpTimesheetSummaryVo generateSummary(String monthCode, Long deptId); } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTimesheetSummaryServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTimesheetSummaryServiceImpl.java index b4bc9008..9e44d225 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTimesheetSummaryServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTimesheetSummaryServiceImpl.java @@ -1,10 +1,13 @@ package org.dromara.oa.erp.service.impl; +import org.dromara.common.satoken.utils.LoginHelper; + import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; - import org.dromara.common.mybatis.core.page.TableDataInfo; - import org.dromara.common.mybatis.core.page.PageQuery; - import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -14,7 +17,17 @@ import org.dromara.oa.erp.domain.bo.ErpTimesheetSummaryBo; import org.dromara.oa.erp.domain.vo.ErpTimesheetSummaryVo; import org.dromara.oa.erp.domain.ErpTimesheetSummary; import org.dromara.oa.erp.mapper.ErpTimesheetSummaryMapper; +import org.dromara.oa.erp.mapper.ErpTimesheetSummaryDetailMapper; import org.dromara.oa.erp.service.IErpTimesheetSummaryService; +import org.dromara.oa.erp.domain.ErpTimesheetSummaryDetail; +import org.dromara.oa.erp.domain.bo.ErpTimesheetSummaryDetailBo; +import org.springframework.transaction.annotation.Transactional; +import org.dromara.oa.erp.mapper.ErpTimesheetStandardMonthMapper; +import org.dromara.oa.erp.domain.ErpTimesheetStandardMonth; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.oa.erp.domain.vo.ErpTimesheetSummaryDetailVo; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -31,6 +44,8 @@ import java.util.Collection; public class ErpTimesheetSummaryServiceImpl implements IErpTimesheetSummaryService { private final ErpTimesheetSummaryMapper baseMapper; + private final ErpTimesheetSummaryDetailMapper detailMapper; + private final ErpTimesheetStandardMonthMapper standardMonthMapper; /** * 查询月汇总工时信息 @@ -39,23 +54,28 @@ public class ErpTimesheetSummaryServiceImpl implements IErpTimesheetSummaryServi * @return 月汇总工时信息 */ @Override - public ErpTimesheetSummaryVo queryById(Long summaryId){ - return baseMapper.selectVoById(summaryId); + public ErpTimesheetSummaryVo queryById(Long summaryId) { + ErpTimesheetSummaryVo vo = baseMapper.selectVoById(summaryId); + if (vo != null) { + vo.setSummaryDetailList(detailMapper.selectVoList(Wrappers.lambdaQuery() + .eq(ErpTimesheetSummaryDetail::getSummaryId, summaryId))); + } + return vo; } - /** - * 分页查询月汇总工时信息列表 - * - * @param bo 查询条件 - * @param pageQuery 分页参数 - * @return 月汇总工时信息分页列表 - */ - @Override - public TableDataInfo queryPageList(ErpTimesheetSummaryBo bo, PageQuery pageQuery) { - MPJLambdaWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } + /** + * 分页查询月汇总工时信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 月汇总工时信息分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpTimesheetSummaryBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectCustomErpTimesheetSummaryVoList(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } /** * 查询符合条件的月汇总工时信息列表 @@ -66,25 +86,25 @@ public class ErpTimesheetSummaryServiceImpl implements IErpTimesheetSummaryServi @Override public List queryList(ErpTimesheetSummaryBo bo) { MPJLambdaWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + return baseMapper.selectCustomErpTimesheetSummaryVoList(lqw); } private MPJLambdaWrapper buildQueryWrapper(ErpTimesheetSummaryBo bo) { - Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpTimesheetSummary.class) - .selectAll(ErpTimesheetSummary.class) - .eq(ErpTimesheetSummary::getDelFlag, "0") - .eq(StringUtils.isNotBlank(bo.getSummaryCode()), ErpTimesheetSummary::getSummaryCode, bo.getSummaryCode()) - .eq(StringUtils.isNotBlank(bo.getMonthCode()), ErpTimesheetSummary::getMonthCode, bo.getMonthCode()) - .eq(bo.getDeptId() != null, ErpTimesheetSummary::getDeptId, bo.getDeptId()) - .eq(bo.getUserId() != null, ErpTimesheetSummary::getUserId, bo.getUserId()) - .eq(bo.getStandardMonthId() != null, ErpTimesheetSummary::getStandardMonthId, bo.getStandardMonthId()) - .eq(bo.getStandardDays() != null, ErpTimesheetSummary::getStandardDays, bo.getStandardDays()) - .eq(bo.getTotalProjectHours() != null, ErpTimesheetSummary::getTotalProjectHours, bo.getTotalProjectHours()) - .eq(bo.getTotalDeptHours() != null, ErpTimesheetSummary::getTotalDeptHours, bo.getTotalDeptHours()) - .eq(bo.getTotalHours() != null, ErpTimesheetSummary::getTotalHours, bo.getTotalHours()) - .eq(bo.getStaffCount() != null, ErpTimesheetSummary::getStaffCount, bo.getStaffCount()) -; + .selectAll(ErpTimesheetSummary.class) + .eq(ErpTimesheetSummary::getDelFlag, "0") + .eq(StringUtils.isNotBlank(bo.getSummaryCode()), ErpTimesheetSummary::getSummaryCode, + bo.getSummaryCode()) + .eq(StringUtils.isNotBlank(bo.getMonthCode()), ErpTimesheetSummary::getMonthCode, bo.getMonthCode()) + .eq(bo.getDeptId() != null, ErpTimesheetSummary::getDeptId, bo.getDeptId()) + .eq(bo.getUserId() != null, ErpTimesheetSummary::getUserId, bo.getUserId()) + .eq(bo.getStandardMonthId() != null, ErpTimesheetSummary::getStandardMonthId, bo.getStandardMonthId()) + .eq(bo.getStandardDays() != null, ErpTimesheetSummary::getStandardDays, bo.getStandardDays()) + .eq(bo.getTotalProjectHours() != null, ErpTimesheetSummary::getTotalProjectHours, + bo.getTotalProjectHours()) + .eq(bo.getTotalDeptHours() != null, ErpTimesheetSummary::getTotalDeptHours, bo.getTotalDeptHours()) + .eq(bo.getTotalHours() != null, ErpTimesheetSummary::getTotalHours, bo.getTotalHours()) + .eq(bo.getStaffCount() != null, ErpTimesheetSummary::getStaffCount, bo.getStaffCount()); return lqw; } @@ -95,12 +115,21 @@ public class ErpTimesheetSummaryServiceImpl implements IErpTimesheetSummaryServi * @return 是否新增成功 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean insertByBo(ErpTimesheetSummaryBo bo) { + if (StringUtils.isBlank(bo.getSummaryCode())) { + // 生成规则:TS-月份-4位随机数 + bo.setSummaryCode("TS" + bo.getMonthCode() + (int) ((Math.random() * 9 + 1) * 1000)); + } + if (bo.getUserId() == null) { + bo.setUserId(LoginHelper.getUserId()); + } ErpTimesheetSummary add = MapstructUtils.convert(bo, ErpTimesheetSummary.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setSummaryId(add.getSummaryId()); + saveDetails(add.getSummaryId(), bo.getSummaryDetailList()); } return flag; } @@ -112,17 +141,109 @@ public class ErpTimesheetSummaryServiceImpl implements IErpTimesheetSummaryServi * @return 是否修改成功 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean updateByBo(ErpTimesheetSummaryBo bo) { ErpTimesheetSummary update = MapstructUtils.convert(bo, ErpTimesheetSummary.class); validEntityBeforeSave(update); + // 先删除原有的明细 + detailMapper.delete(Wrappers.lambdaQuery() + .eq(ErpTimesheetSummaryDetail::getSummaryId, bo.getSummaryId())); + // 保存新明细 + saveDetails(bo.getSummaryId(), bo.getSummaryDetailList()); return baseMapper.updateById(update) > 0; } + /** + * 批量保存明细 + */ + private void saveDetails(Long summaryId, List detailBoList) { + if (CollUtil.isNotEmpty(detailBoList)) { + List details = MapstructUtils.convert(detailBoList, + ErpTimesheetSummaryDetail.class); + for (ErpTimesheetSummaryDetail detail : details) { + detail.setSummaryId(summaryId); + detail.setSummaryDetailId(null); + } + detailMapper.insertBatch(details); + } + } + + @Override + public ErpTimesheetSummaryVo generateSummary(String monthCode, Long deptId) { + // 1. 获取标准月份 + ErpTimesheetStandardMonth standardMonth = standardMonthMapper + .selectOne(Wrappers.lambdaQuery() + .eq(ErpTimesheetStandardMonth::getMonthCode, monthCode)); + if (standardMonth == null) { + throw new ServiceException("该月份的标准工时未配置"); + } + + // 2. 聚合项目工时和部门工时 + List projectDetails = baseMapper.selectProjectAggregation(deptId, + standardMonth.getStartDate(), standardMonth.getEndDate()); + List deptDetails = baseMapper.selectDeptAggregation(deptId, + standardMonth.getStartDate(), standardMonth.getEndDate()); + + // 3. 合并明细并设置默认值 + List allDetails = new ArrayList<>(); + int sortOrder = 1; + BigDecimal totalProjectHours = BigDecimal.ZERO; + BigDecimal totalDeptHours = BigDecimal.ZERO; + + for (ErpTimesheetSummaryDetailVo pd : projectDetails) { + pd.setSortOrder(sortOrder++); + pd.setAdjustedHours(pd.getOriginalHours()); + pd.setAdjustedProjectId(pd.getOriginalProjectId()); + pd.setAdjustedProjectCode(pd.getOriginalProjectCode()); + pd.setAdjustedProjectName(pd.getOriginalProjectName()); + pd.setIsGenerated("1"); + allDetails.add(pd); + totalProjectHours = totalProjectHours + .add(pd.getOriginalHours() != null ? pd.getOriginalHours() : BigDecimal.ZERO); + } + + for (ErpTimesheetSummaryDetailVo dd : deptDetails) { + dd.setSortOrder(sortOrder++); + dd.setAdjustedHours(dd.getOriginalHours()); + dd.setIsGenerated("1"); + allDetails.add(dd); + totalDeptHours = totalDeptHours + .add(dd.getOriginalHours() != null ? dd.getOriginalHours() : BigDecimal.ZERO); + } + + // 4. 组装主表数据 + ErpTimesheetSummaryVo summaryVo = new ErpTimesheetSummaryVo(); + summaryVo.setMonthCode(monthCode); + summaryVo.setDeptId(deptId); + summaryVo.setStandardMonthId(standardMonth.getStandardMonthId()); + summaryVo.setStandardDays(standardMonth.getStandardDays()); + + summaryVo.setTotalProjectHours(totalProjectHours); + summaryVo.setTotalDeptHours(totalDeptHours); + summaryVo.setTotalHours(totalProjectHours.add(totalDeptHours)); + + // 统计不重复的人数 + long staffCount = allDetails.stream().map(ErpTimesheetSummaryDetailVo::getStaffUserId).distinct().count(); + summaryVo.setStaffCount((int) staffCount); + + summaryVo.setSummaryDetailList(allDetails); + + return summaryVo; + } + /** * 保存前的数据校验 */ - private void validEntityBeforeSave(ErpTimesheetSummary entity){ - //TODO 做一些数据校验,如唯一约束 + private void validEntityBeforeSave(ErpTimesheetSummary entity) { + // 校验同一部门同一月份不能重复生成 + boolean exists = baseMapper.exists(Wrappers.lambdaQuery() + .eq(ErpTimesheetSummary::getDeptId, entity.getDeptId()) + .eq(ErpTimesheetSummary::getMonthCode, entity.getMonthCode()) + .ne(entity.getSummaryId() != null, ErpTimesheetSummary::getSummaryId, entity.getSummaryId()) + .eq(ErpTimesheetSummary::getDelFlag, "0")); + if (exists) { + throw new ServiceException("该部门 " + entity.getMonthCode() + " 月份的工时汇总已存在,请勿重复操作"); + } } /** @@ -133,10 +254,15 @@ public class ErpTimesheetSummaryServiceImpl implements IErpTimesheetSummaryServi * @return 是否删除成功 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ - //TODO 做一些业务上的校验,判断是否需要校验 + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 } + // 删除关联明细 + detailMapper.delete(Wrappers.lambdaQuery() + .in(ErpTimesheetSummaryDetail::getSummaryId, ids)); return baseMapper.deleteByIds(ids) > 0; } + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpTimesheetSummaryMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpTimesheetSummaryMapper.xml index c409a3af..d303db20 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpTimesheetSummaryMapper.xml +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpTimesheetSummaryMapper.xml @@ -6,9 +6,49 @@ - + select t.*, d.dept_name, u.nick_name as leader_name + from erp_timesheet_summary t + left join sys_dept d on t.dept_id = d.dept_id and d.del_flag = '0' + left join sys_user u on d.leader = u.user_id and u.del_flag = '0' + ${ew.getCustomSqlSegment} + + + + +