feat(performance): 实现绩效表格预填充功能并优化配置管理
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package com.njcn.rdms.module.project.constant;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 绩效 Excel 单元格常量。
|
||||
*/
|
||||
public final class PerformanceExcelCellConstants {
|
||||
|
||||
private PerformanceExcelCellConstants() {
|
||||
}
|
||||
|
||||
public static final String ACTUAL_SCORE_TOTAL_CELL = "J10";
|
||||
public static final String BASE_SCORE_TOTAL_CELL = "K10";
|
||||
public static final String EXTRA_SCORE_TOTAL_CELL = "L10";
|
||||
|
||||
public static final List<String> RESULT_DESCRIPTION_CELLS = List.of("I6", "I7", "I8", "I9");
|
||||
public static final List<String> ACTUAL_SCORE_CELLS = List.of("J6", "J7", "J8", "J9", "J10");
|
||||
public static final List<String> BASE_SCORE_CELLS = List.of("K6", "K7", "K8", "K9", "K10");
|
||||
public static final List<String> EXTRA_SCORE_CELLS = List.of("L6", "L7", "L8", "L9", "L10");
|
||||
|
||||
public static final List<String> PREFILL_CELL_ADDRESSES = List.of(
|
||||
"I6", "I7", "I8", "I9",
|
||||
"J6", "J7", "J8", "J9", "J10",
|
||||
"K6", "K7", "K8", "K9", "K10",
|
||||
"L6", "L7", "L8", "L9", "L10"
|
||||
);
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceS
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetCreateReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetExcelUpdateReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPageReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPrefillRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetResponseRecordRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusActionReqVO;
|
||||
@@ -162,6 +163,14 @@ public class PerformanceSheetController {
|
||||
return success(performanceSheetService.getResponseRecords(id));
|
||||
}
|
||||
|
||||
@GetMapping("/prefill")
|
||||
@Operation(summary = "获取绩效表上一份预填充数据")
|
||||
@PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_CREATE + "')")
|
||||
public CommonResult<PerformanceSheetPrefillRespVO> prefill(@RequestParam("employeeId") Long employeeId,
|
||||
@RequestParam("periodMonth") String periodMonth) {
|
||||
return success(performanceSheetService.getPrefillData(employeeId, periodMonth));
|
||||
}
|
||||
|
||||
@GetMapping("/monthly-result")
|
||||
@Operation(summary = "获取月报审批绩效结果")
|
||||
@PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.njcn.rdms.module.project.controller.admin.performance.vo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 绩效分数单元格映射 Response VO")
|
||||
@Data
|
||||
public class PerformanceScoreCellMappingRespVO {
|
||||
@@ -15,4 +17,16 @@ public class PerformanceScoreCellMappingRespVO {
|
||||
|
||||
@Schema(description = "附加得分总计单元格", example = "L10")
|
||||
private String extraScoreTotalCell;
|
||||
|
||||
@Schema(description = "结果描述预填充单元格", example = "[\"I6\",\"I7\",\"I8\",\"I9\"]")
|
||||
private List<String> resultDescriptionCells;
|
||||
|
||||
@Schema(description = "实际得分预填充单元格", example = "[\"J6\",\"J7\",\"J8\",\"J9\",\"J10\"]")
|
||||
private List<String> actualScoreCells;
|
||||
|
||||
@Schema(description = "基础得分预填充单元格", example = "[\"K6\",\"K7\",\"K8\",\"K9\",\"K10\"]")
|
||||
private List<String> baseScoreCells;
|
||||
|
||||
@Schema(description = "附加得分预填充单元格", example = "[\"L6\",\"L7\",\"L8\",\"L9\",\"L10\"]")
|
||||
private List<String> extraScoreCells;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.rdms.module.project.controller.admin.performance.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 绩效表上一份预填充 Response VO")
|
||||
@Data
|
||||
public class PerformanceSheetPrefillRespVO {
|
||||
|
||||
@Schema(description = "来源绩效表 ID", example = "2042074259501088770")
|
||||
private Long sourceSheetId;
|
||||
|
||||
@Schema(description = "来源绩效月份", example = "2026-06")
|
||||
private String sourcePeriodMonth;
|
||||
|
||||
@Schema(description = "按单元格地址返回的预填充值,例如 {\"I6\":\"结果描述\",\"J10\":\"13.00\"}")
|
||||
private Map<String, String> cellValues = new LinkedHashMap<>();
|
||||
}
|
||||
@@ -20,6 +20,16 @@ public interface PerformanceSheetMapper extends BaseMapperX<PerformanceSheetDO>
|
||||
.eq(PerformanceSheetDO::getPeriodMonth, periodMonth));
|
||||
}
|
||||
|
||||
default PerformanceSheetDO selectLatestHistoryWithFile(Long employeeId, String beforePeriodMonth) {
|
||||
return selectOne(new LambdaQueryWrapperX<PerformanceSheetDO>()
|
||||
.eq(PerformanceSheetDO::getEmployeeId, employeeId)
|
||||
.lt(PerformanceSheetDO::getPeriodMonth, beforePeriodMonth)
|
||||
.isNotNull(PerformanceSheetDO::getFileId)
|
||||
.orderByDesc(PerformanceSheetDO::getPeriodMonth)
|
||||
.orderByDesc(PerformanceSheetDO::getId)
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
|
||||
default PageResult<PerformanceSheetDO> selectEmployeePage(Long employeeId, PerformanceSheetPageReqVO reqVO) {
|
||||
LambdaQueryWrapperX<PerformanceSheetDO> wrapper = buildPageQuery(reqVO)
|
||||
.eq(PerformanceSheetDO::getEmployeeId, employeeId)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.njcn.rdms.module.project.service.performance;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 绩效配置。
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "rdms.performance")
|
||||
@Data
|
||||
public class PerformanceProperties {
|
||||
|
||||
private ScoreCellMapping scoreCellMapping = new ScoreCellMapping();
|
||||
|
||||
@Data
|
||||
public static class ScoreCellMapping {
|
||||
|
||||
private String actualScoreTotal = "J10";
|
||||
|
||||
private String baseScoreTotal = "K10";
|
||||
|
||||
private String extraScoreTotal = "L10";
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceM
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetCreateReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetExcelUpdateReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPageReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPrefillRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetResponseRecordRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusActionReqVO;
|
||||
@@ -45,6 +46,8 @@ public interface PerformanceSheetService {
|
||||
|
||||
List<PerformanceSheetResponseRecordRespVO> getResponseRecords(Long id);
|
||||
|
||||
PerformanceSheetPrefillRespVO getPrefillData(Long employeeId, String periodMonth);
|
||||
|
||||
PerformanceMonthlyResultRespVO getMonthlyResult(Long employeeId, String periodMonth);
|
||||
|
||||
List<PerformanceSheetStatusDictRespVO> getStatusDict();
|
||||
|
||||
@@ -4,11 +4,13 @@ import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.njcn.rdms.module.project.constant.PerformanceExcelCellConstants;
|
||||
import com.njcn.rdms.module.project.constant.PerformanceConstants;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceMonthlyResultRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetCreateReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetExcelUpdateReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPageReqVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPrefillRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetResponseRecordRespVO;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusActionReqVO;
|
||||
@@ -47,9 +49,11 @@ import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.poi.ss.usermodel.Comment;
|
||||
import org.apache.poi.ss.usermodel.CreationHelper;
|
||||
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||
import org.apache.poi.ss.usermodel.DataFormat;
|
||||
import org.apache.poi.ss.usermodel.Drawing;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||
import org.apache.poi.ss.usermodel.PageMargin;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
@@ -57,6 +61,7 @@ import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||
import org.apache.poi.ss.util.CellAddress;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.ss.util.PaneInformation;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
|
||||
import org.apache.poi.xssf.usermodel.XSSFColor;
|
||||
@@ -67,6 +72,7 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -95,6 +101,7 @@ import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PerformanceSheetServiceImpl implements PerformanceSheetService {
|
||||
|
||||
private static final String EXCEL_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
@@ -292,6 +299,34 @@ public class PerformanceSheetServiceImpl implements PerformanceSheetService {
|
||||
PerformanceSheetResponseRecordRespVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PerformanceSheetPrefillRespVO getPrefillData(Long employeeId, String periodMonth) {
|
||||
String normalizedMonth = normalizePeriodMonth(periodMonth);
|
||||
AdminUserRespDTO employee = validateActiveUser(employeeId);
|
||||
AdminUserRespDTO manager = loadDirectManager(employee.getId());
|
||||
validateManagerOnly(manager.getId());
|
||||
|
||||
PerformanceSheetPrefillRespVO respVO = new PerformanceSheetPrefillRespVO();
|
||||
PerformanceSheetDO previousSheet = performanceSheetMapper.selectLatestHistoryWithFile(employeeId, normalizedMonth);
|
||||
if (previousSheet == null) {
|
||||
return respVO;
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, String> cellValues = readPrefillCellValues(previousSheet);
|
||||
if (cellValues.isEmpty()) {
|
||||
return respVO;
|
||||
}
|
||||
respVO.setSourceSheetId(previousSheet.getId());
|
||||
respVO.setSourcePeriodMonth(previousSheet.getPeriodMonth());
|
||||
respVO.setCellValues(cellValues);
|
||||
} catch (Exception ex) {
|
||||
log.warn("读取上一份绩效表预填充数据失败,sourceSheetId={}, employeeId={}, periodMonth={}",
|
||||
previousSheet.getId(), employeeId, normalizedMonth, ex);
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PerformanceMonthlyResultRespVO getMonthlyResult(Long employeeId, String periodMonth) {
|
||||
String normalizedMonth = normalizePeriodMonth(periodMonth);
|
||||
@@ -913,6 +948,44 @@ public class PerformanceSheetServiceImpl implements PerformanceSheetService {
|
||||
return filename.substring(0, dotIndex) + "_" + count + filename.substring(dotIndex);
|
||||
}
|
||||
|
||||
private Map<String, String> readPrefillCellValues(PerformanceSheetDO sheet) throws Exception {
|
||||
byte[] content = readFileContent(sheet);
|
||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
|
||||
Workbook workbook = WorkbookFactory.create(inputStream)) {
|
||||
if (workbook.getNumberOfSheets() <= 0) {
|
||||
return Map.of();
|
||||
}
|
||||
Sheet sourceSheet = workbook.getSheetAt(0);
|
||||
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
|
||||
DataFormatter formatter = new DataFormatter();
|
||||
Map<String, String> cellValues = new LinkedHashMap<>();
|
||||
for (String cellAddress : PerformanceExcelCellConstants.PREFILL_CELL_ADDRESSES) {
|
||||
String value = readCellDisplayValue(sourceSheet, evaluator, formatter, cellAddress);
|
||||
if (value != null) {
|
||||
cellValues.put(cellAddress, value);
|
||||
}
|
||||
}
|
||||
return cellValues;
|
||||
}
|
||||
}
|
||||
|
||||
private String readCellDisplayValue(Sheet sheet,
|
||||
FormulaEvaluator evaluator,
|
||||
DataFormatter formatter,
|
||||
String cellAddress) {
|
||||
CellReference reference = new CellReference(cellAddress);
|
||||
Row row = sheet.getRow(reference.getRow());
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
Cell cell = row.getCell(reference.getCol());
|
||||
if (cell == null) {
|
||||
return null;
|
||||
}
|
||||
String value = formatter.formatCellValue(cell, evaluator);
|
||||
return StringUtils.hasText(value) ? value.trim() : null;
|
||||
}
|
||||
|
||||
private PerformanceSheetDO merge(PerformanceSheetDO source, PerformanceSheetDO update) {
|
||||
PerformanceSheetDO merged = BeanUtils.toBean(source, PerformanceSheetDO.class);
|
||||
if (update.getStatusCode() != null) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.njcn.rdms.module.project.service.performance;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.project.constant.PerformanceExcelCellConstants;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceScoreCellMappingRespVO;
|
||||
@@ -25,8 +26,6 @@ public class PerformanceTemplateServiceImpl implements PerformanceTemplateServic
|
||||
|
||||
@Resource
|
||||
private PerformanceTemplateMapper performanceTemplateMapper;
|
||||
@Resource
|
||||
private PerformanceProperties performanceProperties;
|
||||
|
||||
@Override
|
||||
public PerformanceTemplateRespVO getCurrentTemplate() {
|
||||
@@ -98,11 +97,14 @@ public class PerformanceTemplateServiceImpl implements PerformanceTemplateServic
|
||||
}
|
||||
|
||||
private PerformanceScoreCellMappingRespVO scoreCellMapping() {
|
||||
PerformanceProperties.ScoreCellMapping mapping = performanceProperties.getScoreCellMapping();
|
||||
PerformanceScoreCellMappingRespVO respVO = new PerformanceScoreCellMappingRespVO();
|
||||
respVO.setActualScoreTotalCell(mapping.getActualScoreTotal());
|
||||
respVO.setBaseScoreTotalCell(mapping.getBaseScoreTotal());
|
||||
respVO.setExtraScoreTotalCell(mapping.getExtraScoreTotal());
|
||||
respVO.setActualScoreTotalCell(PerformanceExcelCellConstants.ACTUAL_SCORE_TOTAL_CELL);
|
||||
respVO.setBaseScoreTotalCell(PerformanceExcelCellConstants.BASE_SCORE_TOTAL_CELL);
|
||||
respVO.setExtraScoreTotalCell(PerformanceExcelCellConstants.EXTRA_SCORE_TOTAL_CELL);
|
||||
respVO.setResultDescriptionCells(PerformanceExcelCellConstants.RESULT_DESCRIPTION_CELLS);
|
||||
respVO.setActualScoreCells(PerformanceExcelCellConstants.ACTUAL_SCORE_CELLS);
|
||||
respVO.setBaseScoreCells(PerformanceExcelCellConstants.BASE_SCORE_CELLS);
|
||||
respVO.setExtraScoreCells(PerformanceExcelCellConstants.EXTRA_SCORE_CELLS);
|
||||
return respVO;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,10 +132,5 @@ rdms:
|
||||
cron: "0 0 12 1-31 * ?"
|
||||
scope:
|
||||
dept-ids: [100]
|
||||
performance:
|
||||
score-cell-mapping:
|
||||
actual-score-total: J10
|
||||
base-score-total: K10
|
||||
extra-score-total: L10
|
||||
|
||||
debug: false
|
||||
|
||||
Reference in New Issue
Block a user