Переглянути джерело

Merge branch 'ls2_performance_appraisal_0801' of http://git.ningdatech.com/liushuai/project-management into dev

tags/24080901
CMM 1 рік тому
джерело
коміт
299ee56023
9 змінених файлів з 551 додано та 22 видалено
  1. +10
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java
  2. +12
    -7
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java
  3. +37
    -14
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java
  4. +209
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java
  5. +69
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/ReAppraisalScoreExportDTO.java
  6. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/SelfAppraisalScoreExportDTO.java
  7. +2
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/req/PerformanceAppraisalExportReq.java
  8. +102
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/util/ExcelFillCellMergeStrategy.java
  9. +109
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/util/MultiColumnMergeStrategy.java

+ 10
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java Переглянути файл

@@ -1,9 +1,12 @@
package com.ningdatech.pmapi.performance.controller;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.ningdatech.log.annotation.WebLog;
import com.ningdatech.pmapi.common.util.ExcelDownUtil;
import com.ningdatech.pmapi.performance.manage.ReAppraisalManage;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalExportReq;
import org.springframework.web.bind.annotation.*;

import com.ningdatech.basic.model.PageVo;
@@ -50,4 +53,11 @@ public class ReAppraisalController {
return reAppraisalManage.submitReAppraisal(param);
}

@GetMapping("/score/export")
@ApiOperation("复评打分导出")
@WebLog(value = "复评打分导出",modular = "绩效评价-人工复评")
public void exportScore(@Valid @ModelAttribute PerformanceAppraisalExportReq param, HttpServletResponse response){
ExcelDownUtil.downXls(response, param, reAppraisalManage::exportScore);
}

}

+ 12
- 7
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java Переглянути файл

@@ -16,9 +16,8 @@ import com.ningdatech.pmapi.common.util.ExcelDownUtil;
import com.ningdatech.pmapi.common.util.ExcelExportStyle;
import com.ningdatech.pmapi.performance.constant.BizConst;
import com.ningdatech.pmapi.performance.enumration.AppraisalTypeEnum;
import com.ningdatech.pmapi.performance.enumration.PerformanceTemplateTypeEnum;
import com.ningdatech.pmapi.performance.helper.TemplateDetailBuildHelper;
import com.ningdatech.pmapi.performance.model.dto.AppraisalScoreExportDTO;
import com.ningdatech.pmapi.performance.model.dto.SelfAppraisalScoreExportDTO;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalInfoDTO;
import com.ningdatech.pmapi.performance.model.entity.*;
@@ -26,12 +25,13 @@ import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalExportReq;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.*;
import com.ningdatech.pmapi.performance.service.*;
import com.ningdatech.pmapi.performance.util.ExcelFillCellMergeStrategy;
import com.ningdatech.pmapi.performance.util.MultiColumnMergeStrategy;
import com.ningdatech.pmapi.portrait.model.entity.ProjectTag;
import com.ningdatech.pmapi.portrait.service.IProjectTagService;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.service.IRoleService;
@@ -432,8 +432,8 @@ public class OrgSelfAppraisalManage {
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, projectTemplate.getId()));
Map<Long, PerformanceIndicatorProjectTemplateDetail> templateDetailMap = templateDetails.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, t -> t));

List<AppraisalScoreExportDTO> exportDataList = Lists.newArrayList();
List<AppraisalScoreExportDTO> exportAdditionalDataList = Lists.newArrayList();
List<SelfAppraisalScoreExportDTO> exportDataList = Lists.newArrayList();
List<SelfAppraisalScoreExportDTO> exportAdditionalDataList = Lists.newArrayList();
// 构建指标和打分详情
List<PerformanceAppraisalScoreInfo> scoreInfoList = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalId, appraisalId)
@@ -445,7 +445,7 @@ public class OrgSelfAppraisalManage {
// 筛选出所有打分的三级指标模板详情ID
for (PerformanceAppraisalScoreInfo scoreInfo : scoreInfoList) {
AppraisalScoreExportDTO thirdDto = new AppraisalScoreExportDTO();
SelfAppraisalScoreExportDTO thirdDto = new SelfAppraisalScoreExportDTO();
Long detailId = scoreInfo.getTemplateDetailId();
PerformanceIndicatorProjectTemplateDetail thirdTemplateDetail = templateDetailMap.get(detailId);
thirdDto.setThirdIndexName(thirdTemplateDetail.getName());
@@ -489,10 +489,15 @@ public class OrgSelfAppraisalManage {

String fileName = "绩效评价_单位自评_评分明细表";
ExcelDownUtil.setFileName(fileName, response);
int[] mergeColumnIndex = {0};
// 需要从第几行开始合并
int mergeRowIndex = 1;
//数据导出处理函数
try {
EasyExcel.write(response.getOutputStream(), AppraisalScoreExportDTO.class)
EasyExcel.write(response.getOutputStream(), SelfAppraisalScoreExportDTO.class)
.autoCloseStream(false)
.registerWriteHandler(new MultiColumnMergeStrategy(exportDataList.size(),0,1))
.registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex))
.registerWriteHandler(ExcelExportStyle.formalStyle())
.sheet(fileName)
.doWrite(exportDataList);


+ 37
- 14
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java Переглянути файл

@@ -498,27 +498,50 @@ public class PerformanceAppraisalPlanManage {
PerformanceAppraisal pa = performanceAppraisalService.getById(id);
VUtils.isTrue(Objects.isNull(pa)).throwMessage("绩效评价不存在 删除失败!");

// 获取评价计划内的待评价项目信息,并按自评开始时间排序
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, id)
.orderBy(Boolean.TRUE,Boolean.TRUE,PerformanceAppraisalProject::getSelfAppraisalStart));
// 获取计划内项目的自评开始时间
Optional<LocalDateTime> min = paps.stream().map(PerformanceAppraisalProject::getSelfAppraisalStart).min(LocalDateTime::compareTo);
if (min.isPresent()){
// 比较当前时间与自评开始时间最小值
if (LocalDateTime.now().isAfter(min.get())){
throw new BizException("评价计划内已有项目到达自评时间,无法删除!");
}
}

if(performanceAppraisalService.removeById(id)){
// 删除评价计划关联的项目
//绩效关联的项目
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, id));
performanceAppraisalProjectService.removeBatchByIds(paps);
List<String> projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList());
// 删除项目的打分信息
performanceAppraisalScoreInfoService.remove(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalId,id)
.in(PerformanceAppraisalScoreInfo::getAppraisalProjectCode,projectCodes));
if (CollUtil.isNotEmpty(paps)) {
performanceAppraisalProjectService.removeBatchByIds(paps);
List<String> projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList());
// 删除项目的打分信息
List<PerformanceAppraisalScoreInfo> scoreInfos = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalId, id)
.in(PerformanceAppraisalScoreInfo::getAppraisalProjectCode, projectCodes));
if (CollUtil.isNotEmpty(scoreInfos)) {
performanceAppraisalScoreInfoService.removeBatchByIds(scoreInfos);
}
}
// 删除评价计划关联的应用
//绩效关联的应用
List<PerformanceAppraisalApplication> paas = performanceAppraisalApplicationService.list(Wrappers.lambdaQuery(PerformanceAppraisalApplication.class)
.eq(PerformanceAppraisalApplication::getAppraisalId, id));
performanceAppraisalApplicationService.removeBatchByIds(paas);
List<Long> applicationIds = paas.stream().map(PerformanceAppraisalApplication::getApplicationId).collect(Collectors.toList());
// 删除应用的打分信息
performanceAppraisalAppScoreInfoService.remove(Wrappers.lambdaQuery(PerformanceAppraisalAppScoreInfo.class)
.eq(PerformanceAppraisalAppScoreInfo::getAppraisalId,id)
.in(PerformanceAppraisalAppScoreInfo::getApplicationId,applicationIds));
if (CollUtil.isNotEmpty(paas)) {
performanceAppraisalApplicationService.removeBatchByIds(paas);
List<Long> applicationIds = paas.stream().map(PerformanceAppraisalApplication::getApplicationId).collect(Collectors.toList());
// 删除应用的打分信息
List<PerformanceAppraisalAppScoreInfo> scoreInfos = performanceAppraisalAppScoreInfoService
.list(Wrappers.lambdaQuery(PerformanceAppraisalAppScoreInfo.class)
.eq(PerformanceAppraisalAppScoreInfo::getAppraisalId, id)
.in(PerformanceAppraisalAppScoreInfo::getApplicationId, applicationIds));
if (CollUtil.isNotEmpty(scoreInfos)) {
performanceAppraisalAppScoreInfoService.removeBatchByIds(scoreInfos);
}
}
// 删除评级计划关联的分组信息
groupService.remove(Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class)
.eq(PerformanceAppraisalProjectGroup::getAppraisalId,id));


+ 209
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java Переглянути файл

@@ -1,12 +1,25 @@
package com.ningdatech.pmapi.performance.manage;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.excel.EasyExcel;
import com.google.common.collect.Lists;
import com.ningdatech.pmapi.common.enumeration.CommonEnum;
import com.ningdatech.pmapi.common.util.ExcelDownUtil;
import com.ningdatech.pmapi.common.util.ExcelExportStyle;
import com.ningdatech.pmapi.performance.model.dto.ReAppraisalScoreExportDTO;
import com.ningdatech.pmapi.performance.model.dto.SelfAppraisalScoreExportDTO;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalExportReq;
import com.ningdatech.pmapi.performance.util.ExcelFillCellMergeStrategy;
import com.ningdatech.pmapi.performance.util.MultiColumnMergeStrategy;
import com.ningdatech.pmapi.portrait.model.entity.ProjectTag;
import com.ningdatech.pmapi.portrait.service.IProjectTagService;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@@ -39,6 +52,8 @@ import cn.hutool.core.collection.CollUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;

/**
* ReAppraisalManage
* @return
@@ -57,6 +72,8 @@ public class ReAppraisalManage {
private final IPerformanceIndicatorProjectTemplateDetailService indicatorProjectTemplateDetailService;
private final IPerformanceAppraisalScoreInfoService performanceAppraisalScoreInfoService;
private final IPerformanceAppraisalProjectGroupService groupService;
private final IProjectTagService projectTagService;
private final IPerformanceIndicatorProjectTemplateService indicatorProjectTemplateService;
/**
* 复评-评价计划列表
* @param req
@@ -314,4 +331,196 @@ public class ReAppraisalManage {
}
}
}

public void exportScore(HttpServletResponse response, PerformanceAppraisalExportReq param) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();
String regionCode = user.getRegionCode();
String projectCode = param.getProjectCode();
Long appraisalId = param.getAppraisalId();

// 根据项目编码获取最新版本的项目信息
Project project = projectService.getProjectByCode(projectCode);
VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在!");
// 根据项目类型、预算年度、批复金额、项目标签匹配本区域指标模版
Integer projectType = project.getProjectType();
Integer projectYear = project.getProjectYear();
BigDecimal approvalAmount = project.getApprovalAmount();
VUtils.isTrue(Objects.isNull(approvalAmount)).throwMessage("未获取到该项目的立项批复金额");
// 根据项目code获取项目标签ID列表
List<Long> tagIdList = projectTagService.list(Wrappers.lambdaQuery(ProjectTag.class)
.eq(ProjectTag::getProjectCode, projectCode)).stream()
.map(ProjectTag::getTagId).collect(Collectors.toList());
VUtils.isTrue(CollUtil.isEmpty(tagIdList)).throwMessage("当前项目未设置标签,匹配不到指标模板,请至项目库或评价计划编辑页面设置标签!");

List<String> strIdList = tagIdList.stream().map(String::valueOf).collect(Collectors.toList());
String projectTagIds = String.join(StrPool.COMMA, strIdList);

Integer amountRange = null;
if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.FIVE_MILLION)) < 0){
amountRange = BizConst.AMOUNT_RANGE_ONE;
} else if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.FIVE_MILLION)) >= 0 &&
approvalAmount.compareTo(BigDecimal.valueOf(BizConst.TWENTY_MILLION)) < 0) {
amountRange = BizConst.AMOUNT_RANGE_TWO;
}else if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.TWENTY_MILLION)) >= 0){
amountRange = BizConst.AMOUNT_RANGE_THREE;
}
LambdaQueryWrapper<PerformanceIndicatorProjectTemplate> wrapper = Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplate.class)
.eq(PerformanceIndicatorProjectTemplate::getRegionCode, regionCode)
.eq(PerformanceIndicatorProjectTemplate::getProjectType, projectType)
.eq(PerformanceIndicatorProjectTemplate::getProjectYear, projectYear)
.eq(PerformanceIndicatorProjectTemplate::getAmountRange, amountRange)
.eq(PerformanceIndicatorProjectTemplate::getProjectTagIds,projectTagIds)
.eq(PerformanceIndicatorProjectTemplate::getStatus, CommonEnum.YES.getCode())
.orderByDesc(PerformanceIndicatorProjectTemplate::getUpdateOn);
List<PerformanceIndicatorProjectTemplate> templates = indicatorProjectTemplateService.list(wrapper);
VUtils.isTrue(CollUtil.isEmpty(templates)).throwMessage("该项目匹配不到指标模板,请返回上一页或者刷新重试。");
if (templates.size() > 1){
throw new BizException("当前项目匹配到多个模板,请返回模板库检查模板配置!");
}
PerformanceIndicatorProjectTemplate projectTemplate = templates.get(0);
// 装配项目指标详情及分数信息
// 获取模版绩效指标详情
List<PerformanceIndicatorProjectTemplateDetail> templateDetails = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, projectTemplate.getId()));
Map<Long, PerformanceIndicatorProjectTemplateDetail> templateDetailMap = templateDetails.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, t -> t));

List<SelfAppraisalScoreExportDTO> exportDataList = Lists.newArrayList();
List<SelfAppraisalScoreExportDTO> exportAdditionalDataList = Lists.newArrayList();
// 构建指标和打分详情
List<PerformanceAppraisalScoreInfo> scoreInfoList = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalId, appraisalId)
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.RE_APPRAISAL.getCode())
.eq(PerformanceAppraisalScoreInfo::getAppraisalProjectCode, projectCode)
.orderBy(Boolean.TRUE, Boolean.TRUE, PerformanceAppraisalScoreInfo::getTemplateDetailId));
Map<Long, PerformanceAppraisalScoreInfo> scoreInfoMap = scoreInfoList.stream()
.collect(Collectors.toMap(PerformanceAppraisalScoreInfo::getTemplateDetailId, p -> p));
// 按照复评打分人员分组
Map<String, List<PerformanceAppraisalScoreInfo>> scoreInfoUserMap = scoreInfoList.stream()
.collect(Collectors.groupingBy(PerformanceAppraisalScoreInfo::getAppraisalEmployeeName));
Set<String> reUserList = scoreInfoUserMap.keySet();

// 筛选出所有打分的三级指标模板详情ID
for (PerformanceAppraisalScoreInfo scoreInfo : scoreInfoList) {
SelfAppraisalScoreExportDTO thirdDto = new SelfAppraisalScoreExportDTO();
Long detailId = scoreInfo.getTemplateDetailId();
PerformanceIndicatorProjectTemplateDetail thirdTemplateDetail = templateDetailMap.get(detailId);
thirdDto.setThirdIndexName(thirdTemplateDetail.getName());
thirdDto.setIndexDetail(thirdTemplateDetail.getIndexDetail());
thirdDto.setGradeDetail(thirdTemplateDetail.getGradeDetail());
thirdDto.setSupportMaterial(thirdTemplateDetail.getSupportMaterial());
thirdDto.setIndexScore(thirdTemplateDetail.getIndexScore());
if (Boolean.TRUE.equals(thirdTemplateDetail.getIsAdditional())) {
thirdDto.setIsAdditional(CommonEnum.YES.getDesc());
} else if (Boolean.FALSE.equals(thirdTemplateDetail.getIsAdditional())) {
thirdDto.setIsAdditional(CommonEnum.NO.getDesc());
}
PerformanceAppraisalScoreInfo appraisalScoreInfo = scoreInfoMap.get(thirdTemplateDetail.getId());
if (Objects.nonNull(appraisalScoreInfo)) {
thirdDto.setAppraisalBasis(appraisalScoreInfo.getAppraisalBasis());
thirdDto.setAppraisalScore(appraisalScoreInfo.getAppraisalScore());
}
// 二级指标名称
Long secondId = thirdTemplateDetail.getParentId();
if (Objects.nonNull(secondId)) {
PerformanceIndicatorProjectTemplateDetail secondTemplateDetail = templateDetailMap.get(secondId);
if (Objects.nonNull(secondTemplateDetail)) {
thirdDto.setSecondIndexName(secondTemplateDetail.getName());
// 一级指标名称
Long firstId = secondTemplateDetail.getParentId();
if (Objects.nonNull(firstId)){
PerformanceIndicatorProjectTemplateDetail firstTemplateDetail = templateDetailMap.get(firstId);
if (Objects.nonNull(firstTemplateDetail)) {
thirdDto.setFirstIndexName(firstTemplateDetail.getName());
}
}
}
}
if (Boolean.FALSE.equals(thirdTemplateDetail.getIsAdditional())) {
exportDataList.add(thirdDto);
}else {
exportAdditionalDataList.add(thirdDto);
}
}
exportDataList.addAll(exportAdditionalDataList);
List<List<SelfAppraisalScoreExportDTO>> dataList = Lists.newArrayList();
dataList.add(exportDataList);
String fileName = "绩效评价_人工复评_评分明细表";
ExcelDownUtil.setFileName(fileName, response);
int[] mergeColumnIndex = {0};
// 需要从第几行开始合并
int mergeRowIndex = 2;

//数据导出处理函数
try {
EasyExcel.write(response.getOutputStream(), SelfAppraisalScoreExportDTO.class)
.autoCloseStream(false)
.head(head(reUserList))
.registerWriteHandler(new MultiColumnMergeStrategy(exportDataList.size(),0,1))
.registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex))
.registerWriteHandler(ExcelExportStyle.formalStyle())
.sheet(fileName)
//.doWrite(dataList);
.doWrite(getData());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private List<List<String>> head(Set<String> reUserList) {
List<List<String>> list = Lists.newArrayList();
List<String> head0 = Lists.newArrayList();
head0.add("一级指标");
List<String> head1 = Lists.newArrayList();
head1.add("二级指标");
List<String> head2 = Lists.newArrayList();
head2.add("三级指标");
List<String> head3 = Lists.newArrayList();
head2.add("指标分值");
List<String> head4 = Lists.newArrayList();
head2.add("指标细则");
List<String> head5 = Lists.newArrayList();
head2.add("评分细则");
List<String> head6 = Lists.newArrayList();
head2.add("佐证材料");
List<String> head7 = Lists.newArrayList();
head2.add("自评依据");
List<String> head8 = Lists.newArrayList();
head2.add("自评得分");


list.add(head0);
list.add(head1);
list.add(head2);
list.add(head3);
list.add(head4);
list.add(head5);
list.add(head6);
list.add(head7);
list.add(head8);

List<String> reUserHead = Lists.newArrayList();
reUserHead.add("复评依据");
reUserHead.add("复评得分");

for (String reUser : reUserList) {
for (String h : reUserHead) {
List<String> reUsers = Lists.newArrayList();
reUsers.add(reUser + "(复评)");
reUsers.add(h);
list.add(reUsers);
}
}
return list;
}

public List<List<ReAppraisalScoreExportDTO>> getData() {
List<List<ReAppraisalScoreExportDTO>> total = new ArrayList<>();
List<ReAppraisalScoreExportDTO> list = new ArrayList<>();
for (int i = 0; i < 15; i++) {
ReAppraisalScoreExportDTO dto = new ReAppraisalScoreExportDTO();
dto.setFirstIndexName("一级指标" + i);
list.add(dto);
}
total.add(list);
return total;
}
}

+ 69
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/ReAppraisalScoreExportDTO.java Переглянути файл

@@ -0,0 +1,69 @@
package com.ningdatech.pmapi.performance.model.dto;

import java.io.Serializable;
import java.math.BigDecimal;

import com.alibaba.excel.annotation.ExcelProperty;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* 绩效打分详情导出实体
*
* @author CMM
* @since 2023/08/16 10:31
*/
@Data
public class ReAppraisalScoreExportDTO implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty("一级指标名称")
@ExcelProperty(value = "一级指标",index = 0)
private String firstIndexName;

@ApiModelProperty("二级指标名称")
@ExcelProperty(value = "二级指标",index = 1)
private String secondIndexName;

@ApiModelProperty("三级指标名称")
@ExcelProperty(value = "三级指标",index = 2)
private String thirdIndexName;

@ApiModelProperty("指标分值 3级指标才有")
@ExcelProperty(value = "指标分值",index = 3)
private BigDecimal indexScore;

@ApiModelProperty("指标细则 3级指标才有")
@ExcelProperty(value = "指标细则",index = 4)
private String indexDetail;

@ApiModelProperty("评分细则")
@ExcelProperty(value = "评分细则",index = 5)
private String gradeDetail;

@ApiModelProperty("佐证材料描述")
@ExcelProperty(value = "佐证材料",index = 6)
private String supportMaterial;

@ApiModelProperty("自评依据")
@ExcelProperty(value = "自评依据",index = 7)
private String selfAppraisalBasis;

@ApiModelProperty("自评得分")
@ExcelProperty(value = "自评得分",index = 8)
private BigDecimal selfAppraisalScore;

@ApiModelProperty("复评依据")
@ExcelProperty(value = "复评依据",index = 9)
private String reAppraisalBasis;

@ApiModelProperty("复评得分")
@ExcelProperty(value = "复评得分",index = 10)
private BigDecimal reAppraisalScore;

@ApiModelProperty("是否为附加指标")
@ExcelProperty(value = "是否附加指标",index = 11)
private String isAdditional;
}

pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AppraisalScoreExportDTO.java → pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/SelfAppraisalScoreExportDTO.java Переглянути файл

@@ -14,7 +14,7 @@ import lombok.Data;
* @since 2023/08/16 10:31
*/
@Data
public class AppraisalScoreExportDTO implements Serializable {
public class SelfAppraisalScoreExportDTO implements Serializable {

private static final long serialVersionUID = 1L;


+ 2
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/model/req/PerformanceAppraisalExportReq.java Переглянути файл

@@ -17,4 +17,6 @@ public class PerformanceAppraisalExportReq {

@ApiModelProperty("评价计划Id")
private Long appraisalId;


}

+ 102
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/util/ExcelFillCellMergeStrategy.java Переглянути файл

@@ -0,0 +1,102 @@
package com.ningdatech.pmapi.performance.util;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

/**
* 单元格合并策略
*
* @author CMM
* @since 2023/08/17 10:57
*/

public class ExcelFillCellMergeStrategy implements CellWriteHandler {

private int[] mergeColumnIndex;
private int mergeRowIndex;

public ExcelFillCellMergeStrategy() {
}

public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}


@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();

if (curRowIndex > mergeRowIndex) {
for (int columnIndex : mergeColumnIndex) {
if (curColIndex == columnIndex) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}



/**
* 当前单元格向上合并
*
* @param cell 当前单元格
* @param curRowIndex 当前行
* @param curColIndex 当前列
*/
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
//获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并
Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
Object preData = preCell.getCellType() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();

// 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
if (curData.equals(preData)) {
Sheet sheet = writeSheetHolder.getSheet();
List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergeRegions.get(i);
// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
sheet.removeMergedRegion(i);
cellRangeAddr.setLastRow(curRowIndex);
sheet.addMergedRegion(cellRangeAddr);
isMerged = true;
}
}
// 若上一个单元格未被合并,则新增合并单元
if (!isMerged) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}

@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {

}

@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {

}
}


+ 109
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/util/MultiColumnMergeStrategy.java Переглянути файл

@@ -0,0 +1,109 @@
package com.ningdatech.pmapi.performance.util;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.ArrayList;
import java.util.List;

/**
* 指定列单元格合并策略
*
* @author CMM
* @since 2023/08/17 11:26
*/

public class MultiColumnMergeStrategy extends AbstractMergeStrategy {

// 合并的列编号,从0开始,指定的index或自己按字段顺序数
private Integer startCellIndex = 0;
private Integer endCellIndex = 0;

// 数据集大小,用于区别结束行位置
private Integer maxRow = 0;

// 禁止无参声明
private MultiColumnMergeStrategy() {
}

/**
* 每行每列都会进入,循环注意条件限制
*/
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
int currentCellIndex = cell.getColumnIndex();
int currentRowIndex = cell.getRowIndex();

// 判断该列是否需要合并
if (currentCellIndex < startCellIndex || currentCellIndex > endCellIndex) {
return;
}

Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
String currentCellValue = curData.toString();

List<String> rowList;
if (dataList.size() > currentRowIndex - 1) {
rowList = dataList.get(currentRowIndex - 1);
} else {
rowList = new ArrayList<>();
dataList.add(rowList);
}
rowList.add(currentCellValue);

// 结束的位置触发下最后一次没完成的合并
if (relativeRowIndex == (maxRow - 1) && currentCellIndex == endCellIndex) {
System.out.println(JSONObject.toJSONString(dataList));
List<String> tempList = null;
Integer tempIndex = null;
for (int i = 0; i < dataList.size(); i++) {
if (tempList == null) {
tempList = dataList.get(i);
tempIndex = i;
continue;
}
List<String> currList = dataList.get(i);
if (tempList.equals(currList)) {
if (i >= dataList.size() - 1) {
// 结束的位置触发下最后一次没完成的合并
for (int j = 0; j < tempList.size(); j++) {
sheet.addMergedRegionUnsafe(new CellRangeAddress(tempIndex + 1, i + 1, startCellIndex + j, startCellIndex + j));
}
}
continue;
}

// 当前行数据和上一行数据不同且上面有多行相同数据时触发合并
if (i - tempIndex > 1) {
for (int j = 0; j < tempList.size(); j++) {
sheet.addMergedRegionUnsafe(new CellRangeAddress(tempIndex + 1, i, startCellIndex + j, startCellIndex + j));
}
}


tempIndex = i;
tempList = currList;


}

}
}


public MultiColumnMergeStrategy(Integer maxRow, Integer startCellIndex, Integer endCellIndex) {
this.startCellIndex = startCellIndex;
this.endCellIndex = endCellIndex;
this.maxRow = maxRow;
}

// 记录上一次合并的信息
private final List<List<String>> dataList = new ArrayList<>();
}



Завантаження…
Відмінити
Зберегти