Quellcode durchsuchen

补充奖金分摊逻辑

zhouyy vor 5 Monaten
Ursprung
Commit
b1dce7db3d
28 geänderte Dateien mit 1144 neuen und 33 gelöschten Zeilen
  1. 31 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractBonusDetailController.java
  2. 46 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractBonusSummaryController.java
  3. 11 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractBonusDetail.java
  4. 85 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractBonusSummary.java
  5. 14 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/bo/BonusDataBO.java
  6. 0 10
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/bo/TransBonusData.java
  7. 26 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/excel/ProjectContractBonusExlceHead.java
  8. 73 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractBonusSummaryVO.java
  9. 15 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractProjectBonusVO.java
  10. 5 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ImportBonusTemplateVO.java
  11. 12 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusTimeDetailVO.java
  12. 15 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusTimeVO.java
  13. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusTotalTimeVO.java
  14. 13 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusVO.java
  15. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserProjectBonusTimeDetailVO.java
  16. 15 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserProjectBonusTimeVO.java
  17. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractBonusDetailMapper.java
  18. 14 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractBonusSummaryMapper.java
  19. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  20. 8 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractBonusDetailService.java
  21. 13 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractBonusSummaryService.java
  22. 309 16
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractBonusDetailServiceImpl.java
  23. 71 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractBonusSummaryServiceImpl.java
  24. 83 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/converter/ExcelMergeStrategy.java
  25. 79 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/converter/WidthStyleStrategy.java
  26. 43 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractBonusDetailMapper.xml
  27. 32 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractBonusSummaryMapper.xml
  28. 88 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

+ 31 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractBonusDetailController.java

@@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
 @RestController
 @RequestMapping("/contractBonusDetail")
@@ -17,12 +19,15 @@ public class ContractBonusDetailController {
     @Resource
     private ContractBonusDetailService contractBonusDetailService;
 
+
+    /**导入模板数据*/
     @PostMapping("/transTemplateData")
-    public HttpRespMsg transTemplateData(Integer startDate, Integer endDate,
-           String bonusType, @RequestParam(value = "file") MultipartFile file) {
+    public HttpRespMsg transTemplateData(String startYM, String endYM
+            , String bonusType, @RequestParam(value = "file") MultipartFile file
+            , HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
-            contractBonusDetailService.transTemplateData(startDate,endDate,bonusType,file);
+            httpRespMsg = contractBonusDetailService.transTemplateData(startYM,endYM,bonusType,file,request);
         } catch (Exception e) {
             e.printStackTrace();
             httpRespMsg.setError(MessageUtils.message("other.error"));
@@ -30,6 +35,29 @@ public class ContractBonusDetailController {
         return httpRespMsg;
     }
 
+    /**获取合同主体奖金*/
+    @PostMapping("/getContractBonus")
+    public HttpRespMsg getContractBonus(@RequestParam(value = "year")Integer year
+            , HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusDetailService.getContractBonus(year,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return httpRespMsg;
+    }
+
+    @PostMapping("/exportContractBonus")
+    public void exportContractBonus(@RequestParam(value = "year")Integer year
+            , HttpServletRequest request, HttpServletResponse response) {
+        try {
+           contractBonusDetailService.exportContractBonus(year,request,response);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
 
 
 }

+ 46 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractBonusSummaryController.java

@@ -0,0 +1,46 @@
+package com.management.platform.controller;
+
+import com.management.platform.service.ContractBonusSummaryService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/contractBonusSummary")
+public class ContractBonusSummaryController {
+    @Resource
+    private ContractBonusSummaryService contractBonusSummaryService;
+
+    /**获取奖金概要数据*/
+    @PostMapping("/getBonusSummary")
+    public HttpRespMsg getBonusSummary(@RequestParam(value = "ym")String ym, HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusSummaryService.getBonusSummary(ym,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("other.error"));
+        }
+        return httpRespMsg;
+    }
+
+    /**删除奖金概要数据【级联】*/
+    @PostMapping("/deleteBonusSummary")
+    public HttpRespMsg deleteBonusSummary(String ids, HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusSummaryService.deleteBonusSummary(ids,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("other.error"));
+        }
+        return httpRespMsg;
+    }
+
+}

+ 11 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractBonusDetail.java

@@ -3,9 +3,11 @@ package com.management.platform.entity;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
 import java.util.Date;
@@ -26,7 +28,7 @@ public class ContractBonusDetail extends Model<ContractBonusDetail> {
      * 公司表外键
      */
     @TableField("company_id")
-    private String company_id;
+    private Integer companyId;
 
     /**
      * 员工id
@@ -46,6 +48,10 @@ public class ContractBonusDetail extends Model<ContractBonusDetail> {
     @TableField("project_id")
     private int projectId;
 
+    /**项目该月工时*/
+    @TableField("project_working_time")
+    private BigDecimal projectWorkingTime;
+
     /**
      * 奖金类型[中文]
      */
@@ -65,10 +71,10 @@ public class ContractBonusDetail extends Model<ContractBonusDetail> {
     private BigDecimal totalBonusValue;
 
     /**
-     * 年月 20240111
+     * 年月 2024-01
      */
     @TableField("ym")
-    private int ym;
+    private String ym;
 
     /**
      * 年 2024
@@ -92,5 +98,7 @@ public class ContractBonusDetail extends Model<ContractBonusDetail> {
      * 创建时间
      */
     @TableField("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 }

+ 85 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractBonusSummary.java

@@ -0,0 +1,85 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ContractBonusSummary extends Model<ContractBonusSummary> {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键id
+     */
+    @TableId("id")
+    private Long id;
+
+    /**
+     * 公司表外键
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 员工id
+     */
+    @TableField("user_id")
+    private String userId;
+
+    /**
+     * 所属合同主体[user表plate1]
+     */
+    @TableField("contract")
+    private String contract;
+
+    /**
+     * 奖金类型[中文]
+     */
+    @TableField("bonus_type")
+    private String bonusType;
+
+    /**
+     * 总奖金金额
+     */
+    @TableField("total_bonus_value")
+    private BigDecimal totalBonusValue;
+
+    /**生效年份*/
+    @TableField("year")
+    private Integer year;
+    /**
+     * 开始年月 2024-01
+     */
+    @TableField("start_ym")
+    private String startYM;
+
+    /**
+     * 结束年月 2024-01
+     */
+    @TableField("end_ym")
+    private String endYM;
+
+    /**
+     * 创建人id
+     */
+    @TableField("create_by")
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+}

+ 14 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/bo/BonusDataBO.java

@@ -0,0 +1,14 @@
+package com.management.platform.entity.bo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class BonusDataBO {
+    private int companyId;
+    private String startDate;
+    private String endDate;
+    private String bonusType;
+    private List<String> userIds;
+}

+ 0 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/bo/TransBonusData.java

@@ -1,10 +0,0 @@
-package com.management.platform.entity.bo;
-
-import lombok.Data;
-
-@Data
-public class TransBonusData {
-    private int startDate;
-    private int endDate;
-    private String bonusType;
-}

+ 26 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/excel/ProjectContractBonusExlceHead.java

@@ -0,0 +1,26 @@
+package com.management.platform.entity.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+@Data
+public class ProjectContractBonusExlceHead {
+    @ExcelProperty(value = "合同主体",index = 0)
+    private String contract;
+    @ExcelProperty(value = "项目名称",index = 1)
+    private String projectName;
+    @ExcelProperty(value = "第一季度奖",index = 2)
+    private String firstSeasonBonus;
+    @ExcelProperty(value = "第二季度奖",index = 3)
+    private String secondSeasonBonus;
+    @ExcelProperty(value = "第三季度奖",index = 4)
+    private String thirdSeasonBonus;
+    @ExcelProperty(value = "第四季度奖",index = 5)
+    private String forthSeasonBonus;
+    @ExcelProperty(value = "上半年奖",index = 6)
+    private String soonerHalfYearBonus;
+    @ExcelProperty(value = "下半年奖",index = 7)
+    private String latterHalfYearBonus;
+    @ExcelProperty(value = "全年奖",index = 8)
+    private String yearBonus;
+}

+ 73 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractBonusSummaryVO.java

@@ -0,0 +1,73 @@
+package com.management.platform.entity.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class ContractBonusSummaryVO {
+    private Long id;
+
+    /**
+     * 公司表外键
+     */
+    private Integer companyId;
+
+    /**
+     * 员工id
+     */
+    private String userId;
+    /**
+     * 员工姓名
+     */
+    private String userName;
+
+    /**
+     * 员工工号
+     */
+    private String jobNumber;
+
+    /**
+     * 所属合同主体[user表plate1]
+     */
+    private String contract;
+
+    /**
+     * 奖金类型[中文]
+     */
+    private String bonusType;
+
+    /**
+     * 总奖金金额
+     */
+    private BigDecimal totalBonusValue;
+
+    /**生效年份*/
+    private Integer year;
+    /**
+     * 开始年月 2024-01
+     */
+    private String startYM;
+
+    /**
+     * 结束年月 2024-01
+     */
+    private String endYM;
+
+    /**
+     * 创建人id
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+}

+ 15 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractProjectBonusVO.java

@@ -0,0 +1,15 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ContractProjectBonusVO {
+    private String contract;
+    private int projectId;
+    private String projectName;
+    private String bonusType;
+    private BigDecimal bonus;
+//    private List<ProjectBonusVO> projectBonusList;
+}

+ 5 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ImportBonusTemplateVO.java

@@ -16,4 +16,9 @@ public class ImportBonusTemplateVO {
     /**奖金金额*/
     @ExcelProperty(value = "奖金金额")
     private BigDecimal bonusValue;
+
+    /**之后填充*/
+    private String userId;
+    /**之后填充*/
+    private String contract;
 }

+ 12 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusTimeDetailVO.java

@@ -0,0 +1,12 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ProjectBonusTimeDetailVO {
+    private int projectId;
+    private BigDecimal costTime;
+    private String createDate;
+}

+ 15 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusTimeVO.java

@@ -0,0 +1,15 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ProjectBonusTimeVO {
+    private int projectId;
+    /**项目当月总工时*/
+    private BigDecimal projectYMCost;
+    /**项目当月奖金*/
+    private BigDecimal projectYMBonus;
+    private String ym;;
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusTotalTimeVO.java

@@ -0,0 +1,16 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class ProjectBonusTotalTimeVO {
+    private int projectId;
+    /**项目时间段内总工时*/
+    private BigDecimal projectTotalCost;
+    /**项目时间段内总奖金*/
+    private BigDecimal projectTotalBonus;
+    private List<ProjectBonusTimeVO> projectTimeList;
+}

+ 13 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ProjectBonusVO.java

@@ -0,0 +1,13 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ProjectBonusVO {
+    private int projectId;
+    private String projectName;
+    private String bonusType;
+    private BigDecimal bonus;
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserProjectBonusTimeDetailVO.java

@@ -0,0 +1,16 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class UserProjectBonusTimeDetailVO {
+    private String userId;
+    private String ym;
+    private int projectId;
+    /**项目当月总工时*/
+    private BigDecimal projectYMCost;
+    private List<ProjectBonusTimeDetailVO> projectTimeList;
+}

+ 15 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserProjectBonusTimeVO.java

@@ -0,0 +1,15 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class UserProjectBonusTimeVO {
+    private String userId;
+//    private int projectId;
+//    /**项目时间段内总工时*/
+//    private BigDecimal projectTotalCost;
+//    private List<ProjectBonusTimeVO> projectTimeList;
+    private List<ProjectBonusTotalTimeVO> projectTimeList;
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractBonusDetailMapper.java

@@ -2,6 +2,13 @@ package com.management.platform.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.management.platform.entity.ContractBonusDetail;
+import com.management.platform.entity.excel.ProjectContractBonusExlceHead;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 public interface ContractBonusDetailMapper extends BaseMapper<ContractBonusDetail> {
+    void batchInsert(@Param("toAddList") List<ContractBonusDetail> toAddBonusDetailList);
+
+    List<ProjectContractBonusExlceHead> getExportContractProjectBonus(Integer year, Integer companyId);
 }

+ 14 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractBonusSummaryMapper.java

@@ -0,0 +1,14 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.ContractBonusSummary;
+import com.management.platform.entity.vo.ContractBonusSummaryVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ContractBonusSummaryMapper extends BaseMapper<ContractBonusSummary> {
+    void batchInsertByImportData(@Param("toAddList") List<ContractBonusSummary> toAddSummaryList);
+
+    List<ContractBonusSummaryVO> getBonusSummary(@Param("ym") String ym, @Param("companyId") Integer companyId);
+}

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -2,6 +2,8 @@ package com.management.platform.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.management.platform.entity.Report;
+import com.management.platform.entity.bo.BonusDataBO;
+import com.management.platform.entity.vo.UserProjectBonusTimeVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
@@ -247,4 +249,6 @@ public interface ReportMapper extends BaseMapper<Report> {
     Integer getReportListWithTransferCount(Integer companyId, String startDate, String endDate,@Param("list") List<String> userIdList, Integer projectId);
 
     void batchUpdateReportStageToNull(List<Integer> list);
+
+    List<UserProjectBonusTimeVO> getUserProjectsByBonusBO(BonusDataBO bonusDataBO);
 }

+ 8 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractBonusDetailService.java

@@ -5,6 +5,13 @@ import com.management.platform.entity.ContractBonusDetail;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 public interface ContractBonusDetailService extends IService<ContractBonusDetail> {
-    HttpRespMsg transTemplateData(Integer startDate, Integer endDate, String bonusType, MultipartFile file);
+    HttpRespMsg transTemplateData(String startYM, String endYM, String bonusType, MultipartFile file, HttpServletRequest request);
+
+    HttpRespMsg getContractBonus(Integer year, HttpServletRequest request);
+
+    void exportContractBonus(Integer year, HttpServletRequest request, HttpServletResponse response);
 }

+ 13 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractBonusSummaryService.java

@@ -0,0 +1,13 @@
+package com.management.platform.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.ContractBonusSummary;
+import com.management.platform.util.HttpRespMsg;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface ContractBonusSummaryService extends IService<ContractBonusSummary> {
+    HttpRespMsg getBonusSummary(String ym, HttpServletRequest request);
+
+    HttpRespMsg deleteBonusSummary(String ids, HttpServletRequest request);
+}

+ 309 - 16
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractBonusDetailServiceImpl.java

@@ -1,22 +1,50 @@
 package com.management.platform.service.impl;
 
+import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.entity.ContractBonusDetail;
+import com.management.platform.entity.ContractBonusSummary;
+import com.management.platform.entity.User;
+import com.management.platform.entity.bo.BonusDataBO;
+import com.management.platform.entity.excel.ProjectContractBonusExlceHead;
 import com.management.platform.entity.vo.ImportBonusTemplateVO;
+import com.management.platform.entity.vo.ProjectBonusTimeVO;
+import com.management.platform.entity.vo.ProjectBonusTotalTimeVO;
+import com.management.platform.entity.vo.UserProjectBonusTimeVO;
 import com.management.platform.mapper.ContractBonusDetailMapper;
+import com.management.platform.mapper.ContractBonusSummaryMapper;
 import com.management.platform.mapper.ReportMapper;
+import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.ContractBonusDetailService;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
+import com.management.platform.util.converter.ExcelMergeStrategy;
 import com.management.platform.util.converter.ExcelTemplateTransUtil;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Service
 public class ContractBonusDetailServiceImpl extends ServiceImpl<ContractBonusDetailMapper, ContractBonusDetail> implements ContractBonusDetailService {
@@ -27,31 +55,296 @@ public class ContractBonusDetailServiceImpl extends ServiceImpl<ContractBonusDet
     @Resource
     private ReportMapper reportMapper;
 
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private ContractBonusSummaryMapper contractBonusSummaryMapper;
+
+    public static Map<Integer,String> bonusTypeMap = new HashMap<>();
+    static {
+        bonusTypeMap.put(1,"第一季度奖");
+        bonusTypeMap.put(2,"第二季度奖");
+        bonusTypeMap.put(3,"第三季度奖");
+        bonusTypeMap.put(4,"第四季度奖");
+        bonusTypeMap.put(5,"上半年奖");
+        bonusTypeMap.put(6,"下半年奖");
+        bonusTypeMap.put(7,"全年奖");
+    }
+
     @Override
-    public HttpRespMsg transTemplateData(Integer startDate, Integer endDate, String bonusType, MultipartFile file) {
+    @Transactional
+    public HttpRespMsg transTemplateData(String startYM, String endYM, String bonusType
+            , MultipartFile file, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        //解析文件
-        InputStream inputStream = null;
-        try {
-            inputStream = file.getInputStream();
-            List<ImportBonusTemplateVO> importDataList = ExcelTemplateTransUtil
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        if(null ==user){
+            httpRespMsg.setError("登录凭证有误,请联系管理员");
+            return httpRespMsg;
+        }
+
+        List<ImportBonusTemplateVO> importDataList = new ArrayList<>();
+        if(null == file || file.getSize()<=0){
+            httpRespMsg.setError("文件不能为空或大小为0");
+            return httpRespMsg;
+        }
+        try (InputStream inputStream = file.getInputStream()){
+            importDataList = ExcelTemplateTransUtil
                     .readExcelConverterObjectList(inputStream, ExcelTypeEnum.XLSX, ImportBonusTemplateVO.class);
 //        System.out.println("=========in==========");
 //        importDataList.forEach(System.out::println);
-
-            inputStream.close();
-        } catch (IOException e) {
+        }catch (Exception e){
             e.printStackTrace();
-            httpRespMsg.setError(MessageUtils.message(""));
-        }finally {
-            if(null != inputStream){
-                try {
-                    inputStream.close();
-                } catch (IOException ex) {
-                    ex.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("解析文件有误,请联系管理员"));
+            return httpRespMsg;
+        }
+
+        if(CollectionUtils.isNotEmpty(importDataList)){
+            //判断奖金金额是否有负数
+            for (ImportBonusTemplateVO templateVO : importDataList) {
+                if(templateVO.getBonusValue().compareTo(new BigDecimal(0)) <= 0){
+                    httpRespMsg.setError("奖金金额需为正数,请重新填写");
+                    return httpRespMsg;
+                }
+            }
+
+            //判断是否有重复工号
+            List<String> distinctCheck = importDataList.stream().map(ImportBonusTemplateVO::getJobNumber).distinct().collect(Collectors.toList());
+            if(distinctCheck.size() != importDataList.size()){
+                httpRespMsg.setError("文件内存在重复员工工号,请重新填写");
+                return httpRespMsg;
+            }
+//            distinctCheck.clear();
+            //判断文件内员工是否都在该公司下
+//            List<String> checkJobNumerList = importDataList.stream().map(ImportBonusTemplateVO::getJobNumber).collect(Collectors.toList());
+            List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
+//                    .select(User::getId, User::getCompanyId, User::getName, User::getJobNumber, User::getPlate3)
+                    .select(User::getId, User::getCompanyId, User::getName, User::getJobNumber, User::getPlate1)
+                    .eq(User::getCompanyId, user.getCompanyId())
+                    .eq(User::getIsActive, 1)
+                    .in(User::getJobNumber, distinctCheck)
+            );
+            if(CollectionUtils.isEmpty(users)){
+                httpRespMsg.setError("文件内员工在该公司不存在,请重新填写");
+                return httpRespMsg;
+            }
+            if(users.size() != distinctCheck.size()){
+                //记录不在该公司或未启用的员工
+                List<String> userJobNums = users.stream().map(User::getJobNumber).collect(Collectors.toList());
+                List<String> checkRes = distinctCheck.stream().filter(item -> !userJobNums.contains(item)).collect(Collectors.toList());
+                httpRespMsg.setError("工号:"+checkRes+" 的员工不在该公司或未激活,请重新填写模板文件");
+                return httpRespMsg;
+            }
+            distinctCheck.clear();
+            //判断是否都有plate1
+            List<User> checkPlate1 = users.stream().filter(t -> StringUtils.isBlank(t.getPlate1())).collect(Collectors.toList());
+            if(CollectionUtils.isNotEmpty(checkPlate1)){
+                httpRespMsg.setError("工号:"+checkPlate1.stream().map(User::getJobNumber).collect(Collectors.toList())+" 的员工没有合同主体");
+                return httpRespMsg;
+            }
+            checkPlate1.clear();
+            //判断姓名
+            Map<String, User> jobNumUserMap = users.stream().collect(Collectors.toMap(User::getJobNumber, t -> t));
+            List<String> errNameJobNumList = new ArrayList<>();
+            for (ImportBonusTemplateVO importData : importDataList) {
+                User tmpUser = jobNumUserMap.get(importData.getJobNumber());
+                //填充数据
+                importData.setUserId(tmpUser.getId());
+//                importData.setContract(tmpUser.getPlate3());
+                importData.setContract(tmpUser.getPlate1());
+                if(!importData.getUserName().equals(tmpUser.getName())){
+                    errNameJobNumList.add(importData.getJobNumber());
+                }
+            }
+            if(CollectionUtils.isNotEmpty(errNameJobNumList)){
+                httpRespMsg.setError("工号:"+errNameJobNumList+" 和组织记录姓名不匹配,请重新填写");
+                return httpRespMsg;
+            }
+            jobNumUserMap.clear();
+            errNameJobNumList.clear();
+
+            Integer useYear = Integer.valueOf(startYM.substring(0, 4));
+
+            //获取项目
+            List<String> userIds = users.stream().map(User::getId).collect(Collectors.toList());
+            BonusDataBO bonusDataBO = new BonusDataBO();
+            bonusDataBO.setStartDate(startYM+"-01");
+            bonusDataBO.setEndDate(endYM+"-31");
+            bonusDataBO.setBonusType(bonusType);
+            bonusDataBO.setUserIds(userIds);
+            bonusDataBO.setCompanyId(user.getCompanyId());
+            List<UserProjectBonusTimeVO> userProjectTimeList = reportMapper.getUserProjectsByBonusBO(bonusDataBO);
+            //员工在该时间段内是否都存在工时
+            List<String> checkUserTimeIdList = userProjectTimeList.stream().map(UserProjectBonusTimeVO::getUserId).collect(Collectors.toList());
+            if(importDataList.size() != userProjectTimeList.size()){
+                List<String> emptyTimeList = importDataList.stream()
+                        .filter(item -> !checkUserTimeIdList.contains(item.getUserId()))
+                        .map(ImportBonusTemplateVO::getJobNumber)
+                        .collect(Collectors.toList());
+                httpRespMsg.setError("工号:"+emptyTimeList+"的员工在该时间段内没有项目工时,请重新填写");
+                return httpRespMsg;
+            }
+
+            //层级1 userId  层级2 List< projectId 总时长 >  层级3 List<projectId 每月时长>
+            if(CollectionUtils.isNotEmpty(userProjectTimeList)){
+                Map<String, ImportBonusTemplateVO> userIdImportMap = importDataList.stream()
+                        .collect(Collectors.toMap(ImportBonusTemplateVO::getUserId, t -> t));
+
+                List<ContractBonusDetail> toDeleteBonusDetailList = new ArrayList<>();
+                List<ContractBonusDetail> toAddBonusDetailList = new ArrayList<>();
+                for (UserProjectBonusTimeVO userBonusVO : userProjectTimeList) {
+                    /**
+                     * 计算项目奖金总金额如何分摊
+                     * 获取该员工奖金总额
+                     * 获取该员工 该时间段内的项目工时总额
+                     * 获取该员工 该时间段内每个项目的工时
+                     * (最后一个项目的金额需要做减法)
+                     * */
+                    BigDecimal remainValue = new BigDecimal(0);
+                    ImportBonusTemplateVO importData = userIdImportMap.get(userBonusVO.getUserId());
+                    BigDecimal bonusValue = importData.getBonusValue();//该员工该类型的总奖金
+                    BigDecimal userTotalTimeVO = new BigDecimal(0);//该员工该时间段的总工时
+                    for (ProjectBonusTotalTimeVO bonusTotalTimeVO : userBonusVO.getProjectTimeList()) {
+                        userTotalTimeVO = userTotalTimeVO.add(bonusTotalTimeVO.getProjectTotalCost());
+                    }
+                    if(userTotalTimeVO.compareTo(new BigDecimal(0)) <= 0){
+                        httpRespMsg.setError("员工:"+userBonusVO.getUserId()+"该时间段内无工时");
+                        return httpRespMsg;
+                    }
+                    int index = 0;
+                    for (ProjectBonusTotalTimeVO timeVO : userBonusVO.getProjectTimeList()) {
+                        index++;
+                        if(index == userBonusVO.getProjectTimeList().size()){
+                            timeVO.setProjectTotalBonus(bonusValue.subtract(remainValue));
+                        }else{
+                            BigDecimal projectTotalValue = bonusValue.multiply(timeVO.getProjectTotalCost()
+                                            .divide(userTotalTimeVO, 10,BigDecimal.ROUND_HALF_UP))
+                                    .setScale(4, BigDecimal.ROUND_HALF_UP);
+                            remainValue = remainValue.add(projectTotalValue);
+                            timeVO.setProjectTotalBonus(projectTotalValue);
+                        }
+                    }
+
+                    //计算每个项目的当月分摊奖金 最后一个项目的分配奖金需要做减法
+                    for (ProjectBonusTotalTimeVO timeVO : userBonusVO.getProjectTimeList()) {
+                        int ymIndex = 0;
+                        BigDecimal remainYMValue = new BigDecimal(0);
+                        for (ProjectBonusTimeVO projectBonusYMVO : timeVO.getProjectTimeList()) {
+                            ymIndex++;
+                            ContractBonusDetail tmpContract = new ContractBonusDetail();
+                            tmpContract.setUserId(userBonusVO.getUserId());
+                            tmpContract.setContract(userIdImportMap.get(userBonusVO.getUserId()).getContract());
+                            tmpContract.setCompanyId(user.getCompanyId());
+                            tmpContract.setProjectId(projectBonusYMVO.getProjectId());
+                            tmpContract.setProjectWorkingTime(projectBonusYMVO.getProjectYMCost());
+                            tmpContract.setBonusType(bonusType);
+                            tmpContract.setTotalBonusValue(timeVO.getProjectTotalBonus());//项目奖金总金额
+                            tmpContract.setYm(projectBonusYMVO.getYm());
+                            tmpContract.setYear(useYear);
+                            tmpContract.setCreateBy(user.getId());
+                            if(ymIndex == timeVO.getProjectTimeList().size()){
+                                tmpContract.setBonusValue(timeVO.getProjectTotalBonus().subtract(remainYMValue));
+                            }else{
+                                BigDecimal projectYMBonus = timeVO.getProjectTotalBonus()
+                                        .multiply(projectBonusYMVO.getProjectYMCost().divide(timeVO.getProjectTotalCost(), 10,BigDecimal.ROUND_HALF_UP))
+                                        .setScale(4, BigDecimal.ROUND_HALF_UP);
+                                remainYMValue = remainYMValue.add(projectYMBonus);
+                                tmpContract.setBonusValue(projectYMBonus);
+                            }
+                            toAddBonusDetailList.add(tmpContract);
+                        }
+                    }
                 }
+
+                //该员工在该年内只能存在一条同奖金类型的数据
+                contractBonusSummaryMapper.delete(new LambdaQueryWrapper<ContractBonusSummary>()
+                        .eq(ContractBonusSummary::getCompanyId, user.getCompanyId())
+                        .eq(ContractBonusSummary::getYear, useYear)
+                        .eq(ContractBonusSummary::getBonusType,bonusType)
+                        .in(ContractBonusSummary::getUserId, checkUserTimeIdList)
+                );
+                contractBonusDetailMapper.delete(new LambdaQueryWrapper<ContractBonusDetail>()
+                        .eq(ContractBonusDetail::getCompanyId, user.getCompanyId())
+                        .eq(ContractBonusDetail::getBonusType,bonusType)
+                        .eq(ContractBonusDetail::getYear,useYear)
+                        .in(ContractBonusDetail::getUserId,checkUserTimeIdList)
+                );
+
+                //插入数据
+                List<ContractBonusSummary> toAddSummaryList = new ArrayList<>();
+                importDataList.forEach(t->{
+                    ContractBonusSummary contractBonusSummary = new ContractBonusSummary();
+                    contractBonusSummary.setCompanyId(user.getCompanyId());
+                    contractBonusSummary.setUserId(t.getUserId());
+                    contractBonusSummary.setContract(t.getContract());
+                    contractBonusSummary.setStartYM(startYM);
+                    contractBonusSummary.setEndYM(endYM);
+                    contractBonusSummary.setBonusType(bonusType);
+                    contractBonusSummary.setTotalBonusValue(t.getBonusValue());
+                    contractBonusSummary.setCreateBy(user.getId());
+                    contractBonusSummary.setYear(useYear);
+                    toAddSummaryList.add(contractBonusSummary);
+                });
+                contractBonusSummaryMapper.batchInsertByImportData(toAddSummaryList);
+                if(CollectionUtils.isNotEmpty(toAddBonusDetailList)){
+                    contractBonusDetailMapper.batchInsert(toAddBonusDetailList);
+                }
+
             }
+
+        }
+
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg getContractBonus(Integer year, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        if(null ==user){
+            httpRespMsg.setError("登录凭证有误,请联系管理员");
         }
+        List<ProjectContractBonusExlceHead> contractProjectBonusList=contractBonusDetailMapper.getExportContractProjectBonus(year,user.getCompanyId());
+        httpRespMsg.setData(contractProjectBonusList);
         return httpRespMsg;
     }
+
+    @Override
+    public void exportContractBonus(Integer year, HttpServletRequest request, HttpServletResponse response) {
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        if(null ==user){
+            response.setContentType("application/json;charset=UTF-8");
+            try (PrintWriter writer = response.getWriter()){
+                writer.write(JSONObject.toJSONString("登录凭证有误,请联系管理员"));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        List<ProjectContractBonusExlceHead> dataList=contractBonusDetailMapper.getExportContractProjectBonus(year,user.getCompanyId());
+
+        String fileName = null;
+        try {
+            fileName = URLEncoder.encode("奖金项目分摊.xlsx", StandardCharsets.UTF_8.toString());
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        response.setContentType("application/vnd.ms-excel;chartset=utf-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + null==fileName?"file":fileName);
+
+        try (ServletOutputStream outputStream = response.getOutputStream()){
+            EasyExcel.write(outputStream, ProjectContractBonusExlceHead.class)
+                    .excelType(ExcelTypeEnum.XLSX)
+                    .autoCloseStream(true)
+                    .registerWriteHandler(new ExcelMergeStrategy(
+                            dataList.stream().map(ProjectContractBonusExlceHead::getContract)
+                                    .collect(Collectors.toList()), 0
+                    ))
+//                    .registerWriteHandler(new WidthStyleStrategy())
+                    .sheet("sheet01")
+                    .doWrite(dataList);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
 }

+ 71 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractBonusSummaryServiceImpl.java

@@ -0,0 +1,71 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.entity.ContractBonusDetail;
+import com.management.platform.entity.ContractBonusSummary;
+import com.management.platform.entity.User;
+import com.management.platform.entity.vo.ContractBonusSummaryVO;
+import com.management.platform.mapper.ContractBonusDetailMapper;
+import com.management.platform.mapper.ContractBonusSummaryMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ContractBonusSummaryService;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+@Service
+public class ContractBonusSummaryServiceImpl extends ServiceImpl<ContractBonusSummaryMapper, ContractBonusSummary> implements ContractBonusSummaryService{
+
+    @Resource
+    private ContractBonusSummaryMapper contractBonusSummaryMapper;
+    @Resource
+    private ContractBonusDetailMapper contractBonusDetailMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Override
+    public HttpRespMsg getBonusSummary(String ym, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        if(null ==user){
+            httpRespMsg.setError("登录凭证有误,请联系管理员");
+            return httpRespMsg;
+        }
+        List<ContractBonusSummaryVO> resList =  contractBonusSummaryMapper.getBonusSummary(ym,user.getCompanyId());
+        httpRespMsg.setData(resList);
+        return httpRespMsg;
+    }
+
+    @Override
+    @Transactional
+    public HttpRespMsg deleteBonusSummary(String ids, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        if(StringUtils.isBlank(ids)){
+            httpRespMsg.setError("id不能为空");
+            return httpRespMsg;
+        }
+        String[] idsArr = ids.split(",");
+        for (String id : idsArr) {
+            ContractBonusSummary toDelSummary = contractBonusSummaryMapper.selectById(id);
+            if(null != toDelSummary){
+                contractBonusSummaryMapper.deleteById(id);
+                contractBonusDetailMapper.delete(new LambdaQueryWrapper<ContractBonusDetail>()
+                        .eq(ContractBonusDetail::getCompanyId, toDelSummary.getCompanyId())
+                        .eq(ContractBonusDetail::getBonusType,toDelSummary.getBonusType())
+                        .eq(ContractBonusDetail::getYear,toDelSummary.getYear())
+                        .in(ContractBonusDetail::getUserId,toDelSummary.getUserId())
+                );
+            }
+        }
+
+
+        return httpRespMsg;
+    }
+}

+ 83 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/converter/ExcelMergeStrategy.java

@@ -0,0 +1,83 @@
+package com.management.platform.util.converter;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExcelMergeStrategy extends AbstractMergeStrategy {
+
+    /**
+     * 分组,每几行合并一次
+     */
+    private List<Integer> exportFieldGroupCountList;
+
+    /**
+     * 目标合并列index
+     */
+    private Integer targetColumnIndex;
+
+    // 需要开始合并单元格的首行index
+    private Integer rowIndex;
+
+    // exportDataList为待合并目标列的值
+    public ExcelMergeStrategy(List<String> exportDataList, Integer targetColumnIndex) {
+        this.exportFieldGroupCountList = getGroupCountList(exportDataList);
+        this.targetColumnIndex = targetColumnIndex;
+    }
+
+    private void mergeGroupColumn(Sheet sheet) {
+        int rowCount = rowIndex;
+        for (Integer count : exportFieldGroupCountList) {
+            if(count == 1) {
+                rowCount += count;
+                continue ;
+            }
+            // 合并单元格
+            CellRangeAddress cellRangeAddress = new CellRangeAddress(rowCount, rowCount + count - 1, targetColumnIndex, targetColumnIndex);
+            sheet.addMergedRegionUnsafe(cellRangeAddress);
+            rowCount += count;
+        }
+    }
+
+    // 该方法将目标列根据值是否相同连续可合并,存储可合并的行数
+    private List<Integer> getGroupCountList(List<String> exportDataList){
+        if (CollectionUtils.isEmpty(exportDataList)) {
+            return new ArrayList<>();
+        }
+
+        List<Integer> groupCountList = new ArrayList<>();
+        int count = 1;
+
+        for (int i = 1; i < exportDataList.size(); i++) {
+            if (exportDataList.get(i).equals(exportDataList.get(i - 1))) {
+                count++;
+            } else {
+                groupCountList.add(count);
+                count = 1;
+            }
+        }
+        // 处理完最后一条后
+        groupCountList.add(count);
+        return groupCountList;
+    }
+
+
+    @Override
+    protected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {
+        if (null == rowIndex) {
+            rowIndex = cell.getRowIndex();
+        }
+        // 仅从首行以及目标列的单元格开始合并,忽略其他
+        if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == targetColumnIndex) {
+            mergeGroupColumn(sheet);
+        }
+    }
+
+
+}

+ 79 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/converter/WidthStyleStrategy.java

@@ -0,0 +1,79 @@
+package com.management.platform.util.converter;
+
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
+import org.apache.poi.ss.usermodel.Cell;
+import org.springframework.util.CollectionUtils;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 表头宽度根据数据内容自适应
+ */
+public class WidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
+
+    private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
+
+    /**
+     * 数据长度
+     *
+     * @param cellDataList
+     * @param cell
+     * @param isHead
+     * @return
+     */
+    private Integer dataLength(List<CellData> cellDataList, Cell cell, Boolean isHead) {
+        //头直接返回原始长度
+        if (isHead) {
+            return cell.getStringCellValue().getBytes().length;
+        } else {
+            //不是头的话  看是什么类型  用数字加就可以了
+            CellData cellData = cellDataList.get(0);
+            CellDataTypeEnum type = cellData.getType();
+            if (type == null) {
+                return -1;
+            } else {
+                switch (type) {
+                    case STRING:
+                        return cellData.getStringValue().getBytes().length + 1;
+                    case BOOLEAN:
+                        return cellData.getBooleanValue().toString().getBytes().length;
+                    case NUMBER:
+                        return cellData.getNumberValue().toString().getBytes().length * 2;
+                    default:
+                        return -1;
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
+        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
+        if (needSetWidth) {
+            Map<Integer, Integer> maxColumnWidthMap = CACHE.get(writeSheetHolder.getSheetNo());
+            if (maxColumnWidthMap == null) {
+                maxColumnWidthMap = new HashMap<>();
+                CACHE.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);
+            }
+
+            Integer columnWidth = this.dataLength(cellDataList, cell, isHead)/2;
+            if (columnWidth >= 0) {
+                if (columnWidth > 255) {
+                    columnWidth = 255;
+                }
+                Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
+                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
+                    maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
+                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
+                }
+            }
+        }
+    }
+}
+
+

+ 43 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractBonusDetailMapper.xml

@@ -3,4 +3,47 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.management.platform.mapper.ContractBonusDetailMapper">
 
+    <insert id="batchInsert">
+        insert into contract_bonus_detail(company_id, user_id, contract, project_id,project_working_time, bonus_type, bonus_value
+        , total_bonus_value, ym, year, month, create_by, create_time)
+        VALUES
+            <foreach collection="toAddList" item="detail" separator=",">
+                (#{detail.companyId},#{detail.userId},#{detail.contract},#{detail.projectId},#{detail.projectWorkingTime},#{detail.bonusType}
+                ,#{detail.bonusValue},#{detail.totalBonusValue},#{detail.ym},#{detail.year},null,#{detail.createBy},now())
+            </foreach>
+
+    </insert>
+
+
+<!--    <resultMap id="contractProjectBonus" type="com.management.platform.entity.vo.ContractProjectBonusVO">-->
+<!--        <result property="contract" column="contract"></result>-->
+<!--        <collection property="projectBonusList" ofType="com.management.platform.entity.vo.ProjectBonusVO">-->
+<!--            <result property="projectId" column="projectId"></result>-->
+<!--            <result property="projectName" column="projectName"></result>-->
+<!--            <result property="bonus" column="bonus"></result>-->
+<!--            <result property="bonusType" column="bonusType"></result>-->
+<!--        </collection>-->
+<!--    </resultMap>-->
+
+    <select id="getExportContractProjectBonus" resultType="com.management.platform.entity.excel.ProjectContractBonusExlceHead">
+        select tmp1.*,p.project_name as projectName
+        from
+            (
+                select contract,project_id projectId,bonus_type bonusType,
+                       max( case bonus_type when '第一季度奖' then bonus  else 0 end)  as firstSeasonBonus,
+                        max(case bonus_type when '第二季度奖' then bonus  else 0 end )as secondSeasonBonus,
+                        max(case bonus_type when '第三季度奖' then bonus  else 0 end) as thirdSeasonBonus,
+                        max(case bonus_type when '第四季度奖' then bonus  else 0 end) as forthSeasonBonus,
+                        max(case bonus_type when '上半年奖' then bonus  else 0 end) as soonerHalfYearBonus,
+                        max(case bonus_type when '下半年奖' then bonus  else 0 end) as latterHalfYearBonus,
+                        max(case bonus_type when '全年奖' then bonus  else 0 end) as yearBonus
+                from (
+                         select contract,bonus_type,project_id,sum(bonus_value) as bonus
+                         from contract_bonus_detail
+                         where year = #{year} and company_id = #{companyId}
+                         group by contract,bonus_type,project_id
+                     )tmp2 group by contract, project_id
+            )tmp1
+                left join project p on tmp1.projectId = p.id
+    </select>
 </mapper>

+ 32 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractBonusSummaryMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.management.platform.mapper.ContractBonusSummaryMapper">
+
+    <insert id="batchInsertByImportData">
+        insert into contract_bonus_summary(company_id,  user_id,contract, bonus_type, total_bonus_value
+        , start_ym, end_ym, create_by, create_time,year) VALUES
+        <foreach collection="toAddList" item="toAddItem" separator=",">
+            (#{toAddItem.companyId},#{toAddItem.userId},#{toAddItem.contract},#{toAddItem.bonusType},#{toAddItem.totalBonusValue},
+            #{toAddItem.startYM},#{toAddItem.endYM},#{toAddItem.createBy},now(),#{toAddItem.year})
+        </foreach>
+    </insert>
+
+    <select id="getBonusSummary" resultType="com.management.platform.entity.vo.ContractBonusSummaryVO">
+        select cbs.id, cbs.company_id, cbs.contract, cbs.user_id, cbs.bonus_type, cbs.total_bonus_value
+             , cbs.year, cbs.start_ym, cbs.end_ym, cbs.create_by, cbs.create_time
+             , u.job_number,u.name as userName
+        from contract_bonus_summary cbs
+                 left join user u on cbs.user_id = u.id
+        where
+            cbs.year = substr(#{ym},1,4)  and cbs.company_id = #{companyId}
+        and substr(cbs.start_ym,6,7) &lt;= substr(#{ym},6,7)
+        and substr(cbs.end_ym,6,7) &gt;= substr(#{ym},6,7)
+    </select>
+
+    <sql id="baseColumns">
+        id, company_id, contract, user_id, bonus_type, total_bonus_value, year, start_ym, end_ym, create_by, create_time
+    </sql>
+
+
+</mapper>

+ 88 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -1482,6 +1482,94 @@
         ) as total
     </select>
 
+    <resultMap id="userProjectTime" type="com.management.platform.entity.vo.UserProjectBonusTimeVO">
+        <result property="userId" column="userId"></result>
+        <collection property="projectTimeList" ofType="com.management.platform.entity.vo.ProjectBonusTotalTimeVO">
+            <result column="projectId" property="projectId"></result>
+            <result column="projectId" property="projectId"></result>
+            <result column="projectTotalCost" property="projectTotalCost"></result>
+            <collection property="projectTimeList" ofType="com.management.platform.entity.vo.ProjectBonusTimeVO">
+                <result column="projectId" property="projectId"></result>
+                <result property="ym" column="ym"></result>
+                <result property="projectYMCost" column="projectYMCost"></result>
+            </collection>
+        </collection>
+    </resultMap>
+
+    <select id="getUserProjectsByBonusBO" resultMap="userProjectTime">
+        select tmp1.creator_id as userId, tmp1.project_id as projectId,tmp1.projectTotalCost,tmp2.ym,tmp2.projectYMCost
+        from
+        (
+        select creator_id,project_id,sum(ifnull(working_time,0)) projectTotalCost
+        from report
+        where
+        company_id = 10
+        and create_date between str_to_date(#{startDate},'%Y-%m-%d') and str_to_date(#{endDate},'%Y-%m-%d')
+        and creator_id in
+        <foreach collection="userIds" item="userId" separator="," open="(" close=")">
+            #{userId}
+        </foreach>
+        group by creator_id,project_id
+        ) tmp1
+        left join
+        (
+        select creator_id,substr(create_date,1,7) as ym,project_id,sum(ifnull(working_time,0)) projectYMCost
+        from report
+        where
+        company_id = 10
+        and create_date between str_to_date(#{startDate},'%Y-%m-%d') and str_to_date(#{endDate},'%Y-%m-%d')
+        and creator_id in
+        <foreach collection="userIds" item="userId" separator="," open="(" close=")">
+            #{userId}
+        </foreach>
+        group by creator_id,substr(create_date,1,7),project_id
+        ) tmp2 on tmp1.creator_id = tmp2.creator_id and tmp1.project_id = tmp2.project_id
+
+    </select>
+
+
+    <resultMap id="userProjectTimeDetail" type="com.management.platform.entity.vo.UserProjectBonusTimeDetailVO">
+        <result property="userId" column="userId"></result>
+        <result column="projectId" property="projectId"></result>
+        <result column="projectYMCost" property="projectYMCost"></result>
+        <collection property="projectTimeList" ofType="com.management.platform.entity.vo.ProjectBonusTimeDetailVO">
+            <result column="projectId" property="projectId"></result>
+            <result property="costTime" column="costTime"></result>
+            <result property="createDate" column="createDate"></result>
+        </collection>
+    </resultMap>
+
+    <select id="getUserProjectsByBonusBODetail" resultMap="userProjectTimeDetail">
+        select tmp1.creator_id as userId, tmp1.project_id as projectId,tmp1.ym,tmp1.projectYMCost
+             ,tmp2.create_date as createDate,tmp2.working_time as costTime
+        from
+        (
+        select creator_id,substr(create_date,1,7) as ym,project_id,sum(ifnull(working_time,0)) projectYMCost
+        from report
+        where
+        company_id = 10
+        and create_date between str_to_date(#{startDate},'%Y-%m-%d') and str_to_date(#{endDate},'%Y-%m-%d')
+        and creator_id in
+        <foreach collection="userIds" item="userId" separator="," open="(" close=")">
+            #{userId}
+        </foreach>
+        group by creator_id,substr(create_date,1,7),project_id
+        ) tmp1
+        left join
+        (
+        select creator_id,project_id,create_date,working_time
+        from report
+        where
+        company_id = 10
+        and create_date between str_to_date(#{startDate},'%Y-%m-%d') and str_to_date(#{endDate},'%Y-%m-%d')
+        and creator_id in
+        <foreach collection="userIds" item="userId" separator="," open="(" close=")">
+            #{userId}
+        </foreach>
+        ) tmp2 on tmp1.creator_id = tmp2.creator_id and tmp1.project_id = tmp2.project_id
+
+    </select>
+
     <update id="batchUpdateReportStageToNull">
         update report set stage=null where id in
         <foreach collection="list" open="(" close=")" separator="," item="item">