项目总览修改成:当前专业所员工在“专业角色人员分配明细”中参与过的合约规划+当前专业所员工担任项目经理/工程负责人的项目下的合约规划

This commit is contained in:
lzm
2026-05-18 15:14:41 +08:00
parent 6b2b91249a
commit 62b83546a1
2 changed files with 96 additions and 13 deletions

View File

@@ -600,8 +600,8 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
List<ProjectPlanningDO> planningList = getProjectOverviewPlanningList(reportYear, employeeIds);
Map<Long, ProjectDO> projectMap = getProjectMap(planningList);
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(planningList);
Map<Long, ProjectOutputSplitDO> outputSplitMap = getOutputSplitMap(planningList);
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap = getRoleSplitMap(planningList);
Map<Long, ProjectOutputSplitDO> outputSplitMap = getExistingOutputSplitMap(planningList);
Map<Long, ProjectOverviewAccumulator> accumulatorMap = new LinkedHashMap<>();
for (ProjectPlanningDO planning : planningList) {
@@ -945,19 +945,33 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
if (reportYear == null || employeeIds == null || employeeIds.isEmpty()) {
return Collections.emptyList();
}
Set<Long> yearPlanningIds = getYearAmountPlanningIds(reportYear);
if (yearPlanningIds.isEmpty()) {
return Collections.emptyList();
}
List<SpecialtyRoleSplitPersonDO> personList = specialtyRoleSplitPersonMapper
.selectListByPlanningIdsAndEmployeeIds(yearPlanningIds, employeeIds);
if (personList.isEmpty()) {
return Collections.emptyList();
}
Set<Long> matchedPlanningIds = personList.stream()
Set<Long> candidatePlanningIds = specialtyRoleSplitPersonMapper.selectListByEmployeeIds(employeeIds).stream()
.map(SpecialtyRoleSplitPersonDO::getPlanningId)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Long> projectLeadProjectIds = projectRolePersonMapper.selectListByEmployeeIds(employeeIds).stream()
.filter(item -> Objects.equals(item.getRoleCode(), OutputSplitBizConstants.ROLE_PROJECT_MANAGER)
|| Objects.equals(item.getRoleCode(), OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL))
.map(ProjectRolePersonDO::getProjectId)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(LinkedHashSet::new));
if (!projectLeadProjectIds.isEmpty()) {
projectPlanningMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningDO>()
.in(ProjectPlanningDO::getProjectId, projectLeadProjectIds)
.in(ProjectPlanningDO::getOwnershipType, Arrays.asList(
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_MAJOR,
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_COMPREHENSIVE,
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_SPECIAL_SUBCONTRACT,
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_SOURCE_COOP_SUBCONTRACT
)))
.stream()
.map(ProjectPlanningDO::getId)
.filter(Objects::nonNull)
.forEach(candidatePlanningIds::add);
}
Set<Long> matchedPlanningIds = getYearAmountPlanningIds(reportYear, candidatePlanningIds);
if (matchedPlanningIds.isEmpty()) {
return Collections.emptyList();
}
@@ -1023,6 +1037,42 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
.collect(Collectors.toCollection(LinkedHashSet::new));
}
private Set<Long> getYearAmountPlanningIds(Integer reportYear, Collection<Long> planningIds) {
if (reportYear == null || planningIds == null || planningIds.isEmpty()) {
return Collections.emptySet();
}
Set<Long> result = new LinkedHashSet<>();
for (List<Long> partition : partitionIds(planningIds, 1000)) {
projectPlanningQuarterMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
.in(ProjectPlanningQuarterDO::getPlanningId, partition)
.eq(ProjectPlanningQuarterDO::getDistributionYear, reportYear)
.gt(ProjectPlanningQuarterDO::getDistributionAmount, BigDecimal.ZERO))
.stream()
.map(ProjectPlanningQuarterDO::getPlanningId)
.filter(Objects::nonNull)
.forEach(result::add);
}
return result;
}
private List<List<Long>> partitionIds(Collection<Long> ids, int partitionSize) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
List<Long> normalizedIds = ids.stream()
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (normalizedIds.isEmpty()) {
return Collections.emptyList();
}
List<List<Long>> result = new ArrayList<>();
for (int start = 0; start < normalizedIds.size(); start += partitionSize) {
result.add(normalizedIds.subList(start, Math.min(start + partitionSize, normalizedIds.size())));
}
return result;
}
private List<ProjectQuarterOutputExcelBuilder.QuarterRow> buildProjectQuarterOutputRows(
List<ProjectPlanningDO> planningList, Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
Map<Long, ProjectOutputSplitDO> outputSplitMap, Integer reportYear) {

View File

@@ -157,14 +157,17 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
List<SpecialtyRoleSplitRespVO> result = new ArrayList<>();
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
boolean useDefaultProjectLeadRoleRatio = shouldUseDefaultProjectLeadRoleRatio(dbMap, projectRolePersonMap);
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
BigDecimal specialtyAmount = getSpecialtyAmount(outputSplit, assessmentOutputValue, specialtyItem.getCode());
Map<String, BigDecimal> defaultRoleRatioMap = buildDefaultRoleRatioMap(
specialtyItem.getCode(), projectRolePersonMap);
for (OutputSplitBizConstants.RoleItem roleItem : OutputSplitBizConstants.getRoleItems(specialtyItem.getCode())) {
SpecialtyRoleSplitDO dbItem = dbMap.get(specialtyItem.getCode() + ":" + roleItem.getCode());
BigDecimal roleRatio = getStoredRoleRatio(
dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
BigDecimal roleRatio = useDefaultProjectLeadRoleRatio
&& OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyItem.getCode())
? ratio(defaultRoleRatioMap.get(roleItem.getCode()))
: getStoredRoleRatio(dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
List<SpecialtyRolePersonRespVO> persons = buildRespPersons(
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, projectRolePersonMap, personMap);
@@ -193,6 +196,33 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
return result;
}
private boolean shouldUseDefaultProjectLeadRoleRatio(Map<String, SpecialtyRoleSplitDO> dbMap,
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap) {
if (projectRolePersonMap == null || projectRolePersonMap.isEmpty()) {
return false;
}
boolean hasProjectLeadPerson = (projectRolePersonMap.get(OutputSplitBizConstants.ROLE_PROJECT_MANAGER) != null
&& !projectRolePersonMap.get(OutputSplitBizConstants.ROLE_PROJECT_MANAGER).isEmpty())
|| (projectRolePersonMap.get(OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL) != null
&& !projectRolePersonMap.get(OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL).isEmpty());
if (!hasProjectLeadPerson || dbMap == null || dbMap.isEmpty()) {
return false;
}
BigDecimal storedTotal = ZERO_RATIO;
boolean hasStoredProjectLead = false;
for (String roleCode : Arrays.asList(
OutputSplitBizConstants.ROLE_PROJECT_MANAGER,
OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL)) {
SpecialtyRoleSplitDO dbItem = dbMap.get(OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD + ":" + roleCode);
if (dbItem == null) {
continue;
}
hasStoredProjectLead = true;
storedTotal = storedTotal.add(ratio(dbItem.getRoleRatio())).setScale(RATIO_SCALE, RoundingMode.HALF_UP);
}
return hasStoredProjectLead && storedTotal.compareTo(ZERO_RATIO) == 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO) {
@@ -217,6 +247,9 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
BigDecimal assessmentOutputValue,
boolean strictValidate) {
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
if (!groupedMap.containsKey(specialtyItem.getCode())) {
continue;
}
Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap = groupedMap.getOrDefault(
specialtyItem.getCode(), new LinkedHashMap<>());
BigDecimal roleTotal = ZERO_RATIO;