0513新功能优化

This commit is contained in:
lzm
2026-05-13 11:39:55 +08:00
parent c496f00fd2
commit bac721f5c4
9 changed files with 253 additions and 9 deletions

View File

@@ -1,9 +1,17 @@
package cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit; package cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit;
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult; import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitPlanningDetailRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitRespVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitSaveReqVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitSaveReqVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO;
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService; import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService;
import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService;
import cn.iocoder.lyzsys.module.tjt.service.planningquarter.ProjectPlanningQuarterService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@@ -13,6 +21,11 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success; import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
@@ -22,8 +35,15 @@ import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
@Validated @Validated
public class ProjectOutputSplitController { public class ProjectOutputSplitController {
private static final int RATIO_SCALE = 4;
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
@Resource @Resource
private ProjectOutputSplitService projectOutputSplitService; private ProjectOutputSplitService projectOutputSplitService;
@Resource
private ProjectPlanningService projectPlanningService;
@Resource
private ProjectPlanningQuarterService projectPlanningQuarterService;
@GetMapping("/get-by-planning") @GetMapping("/get-by-planning")
@Operation(summary = "根据合约规划获得页面4拆分比例") @Operation(summary = "根据合约规划获得页面4拆分比例")
@@ -33,6 +53,29 @@ public class ProjectOutputSplitController {
return success(projectOutputSplitService.getProjectOutputSplit(planningId)); return success(projectOutputSplitService.getProjectOutputSplit(planningId));
} }
@GetMapping("/planning-detail")
@Operation(summary = "获得页面4合约规划分配聚合详情")
@Parameter(name = "planningId", description = "合约规划 ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('tjt:planning:query') && @ss.hasPermission('tjt:output-split:query') && @ss.hasPermission('tjt:planning-quarter:query')")
public CommonResult<ProjectOutputSplitPlanningDetailRespVO> getProjectOutputSplitPlanningDetail(
@RequestParam("planningId") Long planningId) {
ProjectPlanningDO planning = projectPlanningService.getProjectPlanning(planningId);
if (planning == null) {
return success(null);
}
ProjectOutputSplitPlanningDetailRespVO respVO = new ProjectOutputSplitPlanningDetailRespVO();
Map<Long, BigDecimal> allocatedAmountMap =
projectPlanningService.getAllocatedAmountMap(Collections.singleton(planningId));
respVO.setPlanning(BeanUtils.toBean(planning, ProjectPlanningRespVO.class,
planningRespVO -> fillDistributionSummary(planningRespVO, allocatedAmountMap)));
respVO.setOutputSplit(projectOutputSplitService.getProjectOutputSplit(planningId));
List<ProjectPlanningQuarterDO> quarterList =
projectPlanningQuarterService.getProjectPlanningQuarterListByPlanningId(planningId);
respVO.setQuarters(BeanUtils.toBean(quarterList, ProjectPlanningQuarterRespVO.class));
return success(respVO);
}
@PutMapping("/save") @PutMapping("/save")
@Operation(summary = "保存页面4拆分比例") @Operation(summary = "保存页面4拆分比例")
@PreAuthorize("@ss.hasPermission('tjt:output-split:update')") @PreAuthorize("@ss.hasPermission('tjt:output-split:update')")
@@ -40,4 +83,15 @@ public class ProjectOutputSplitController {
return success(projectOutputSplitService.saveProjectOutputSplit(reqVO)); return success(projectOutputSplitService.saveProjectOutputSplit(reqVO));
} }
private void fillDistributionSummary(ProjectPlanningRespVO respVO, Map<Long, BigDecimal> allocatedAmountMap) {
BigDecimal allocatedRatio = allocatedAmountMap.getOrDefault(respVO.getId(), ZERO_RATIO);
BigDecimal totalDistributionAmount = respVO.getTotalDistributionAmount() == null
? ZERO_RATIO : respVO.getTotalDistributionAmount().setScale(RATIO_SCALE, RoundingMode.HALF_UP);
BigDecimal allocatedAmount = totalDistributionAmount.multiply(allocatedRatio)
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
respVO.setAllocatedAmount(allocatedAmount);
respVO.setPendingAmount(totalDistributionAmount.subtract(allocatedAmount)
.setScale(RATIO_SCALE, RoundingMode.HALF_UP));
}
} }

View File

@@ -0,0 +1,24 @@
package cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Collections;
import java.util.List;
@Schema(description = "管理后台 - 页面4合约规划分配聚合详情 Response VO")
@Data
public class ProjectOutputSplitPlanningDetailRespVO {
@Schema(description = "合约规划详情")
private ProjectPlanningRespVO planning;
@Schema(description = "页面4拆分比例")
private ProjectOutputSplitRespVO outputSplit;
@Schema(description = "季度分配列表")
private List<ProjectPlanningQuarterRespVO> quarters = Collections.emptyList();
}

View File

@@ -4,11 +4,16 @@ import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
import cn.iocoder.lyzsys.framework.common.pojo.PageResult; import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
import cn.iocoder.lyzsys.framework.common.util.collection.CollectionUtils; import cn.iocoder.lyzsys.framework.common.util.collection.CollectionUtils;
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils; import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningOutputEditDetailRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningPageReqVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningPageReqVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningSaveReqVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningSaveReqVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningguidedetail.vo.ProjectPlanningGuideDetailRespVO;
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO; import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningguidedetail.ProjectPlanningGuideDetailDO;
import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants;
import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService; import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService;
import cn.iocoder.lyzsys.module.tjt.service.planningguidedetail.ProjectPlanningGuideDetailService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@@ -37,6 +42,8 @@ public class ProjectPlanningController {
@Resource @Resource
private ProjectPlanningService projectPlanningService; private ProjectPlanningService projectPlanningService;
@Resource
private ProjectPlanningGuideDetailService projectPlanningGuideDetailService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建合约规划") @Operation(summary = "创建合约规划")
@@ -97,6 +104,30 @@ public class ProjectPlanningController {
respVO -> fillDistributionSummary(respVO, allocatedAmountMap))); respVO -> fillDistributionSummary(respVO, allocatedAmountMap)));
} }
@GetMapping("/output-edit-detail")
@Operation(summary = "获得合约规划测算参数编辑详情")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('tjt:planning:query')")
public CommonResult<ProjectPlanningOutputEditDetailRespVO> getProjectPlanningOutputEditDetail(@RequestParam("id") Long id) {
ProjectPlanningDO planning = projectPlanningService.getProjectPlanning(id);
if (planning == null) {
return success(null);
}
Map<Long, BigDecimal> allocatedAmountMap = projectPlanningService.getAllocatedAmountMap(
Collections.singleton(planning.getId()));
ProjectPlanningOutputEditDetailRespVO respVO = new ProjectPlanningOutputEditDetailRespVO();
respVO.setPlanning(BeanUtils.toBean(planning, ProjectPlanningRespVO.class,
planningRespVO -> fillDistributionSummary(planningRespVO, allocatedAmountMap)));
if (ProjectPlanningBizTypeConstants.isMajorGuidanceScene(
planning.getOwnershipType(), planning.getCalculationMethod())) {
List<ProjectPlanningGuideDetailDO> guideDetails =
projectPlanningGuideDetailService.getProjectPlanningGuideDetailListByPlanningId(id);
respVO.setGuideDetails(BeanUtils.toBean(guideDetails, ProjectPlanningGuideDetailRespVO.class));
}
return success(respVO);
}
@GetMapping("/list-by-project") @GetMapping("/list-by-project")
@Operation(summary = "根据项目获得合约规划列表") @Operation(summary = "根据项目获得合约规划列表")
@Parameter(name = "projectId", description = "项目 ID", required = true, example = "1") @Parameter(name = "projectId", description = "项目 ID", required = true, example = "1")

View File

@@ -0,0 +1,20 @@
package cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningguidedetail.vo.ProjectPlanningGuideDetailRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Collections;
import java.util.List;
@Schema(description = "管理后台 - 合约规划测算参数编辑聚合详情 Response VO")
@Data
public class ProjectPlanningOutputEditDetailRespVO {
@Schema(description = "合约规划详情")
private ProjectPlanningRespVO planning;
@Schema(description = "指导价法明细列表,仅专业所 + 指导价法场景返回")
private List<ProjectPlanningGuideDetailRespVO> guideDetails = Collections.emptyList();
}

View File

@@ -2,9 +2,13 @@ package cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter;
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult; import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils; import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterPlanningDetailRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterSaveReqVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterSaveReqVO;
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO; import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService;
import cn.iocoder.lyzsys.module.tjt.service.planningquarter.ProjectPlanningQuarterService; import cn.iocoder.lyzsys.module.tjt.service.planningquarter.ProjectPlanningQuarterService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@@ -15,7 +19,11 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success; import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
@@ -25,8 +33,13 @@ import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
@Validated @Validated
public class ProjectPlanningQuarterController { public class ProjectPlanningQuarterController {
private static final int RATIO_SCALE = 4;
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
@Resource @Resource
private ProjectPlanningQuarterService projectPlanningQuarterService; private ProjectPlanningQuarterService projectPlanningQuarterService;
@Resource
private ProjectPlanningService projectPlanningService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建季度分配") @Operation(summary = "创建季度分配")
@@ -80,4 +93,37 @@ public class ProjectPlanningQuarterController {
return success(BeanUtils.toBean(list, ProjectPlanningQuarterRespVO.class)); return success(BeanUtils.toBean(list, ProjectPlanningQuarterRespVO.class));
} }
@GetMapping("/planning-detail")
@Operation(summary = "获得合约规划详情及季度分配列表")
@Parameter(name = "planningId", description = "合约规划 ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('tjt:planning:query') && @ss.hasPermission('tjt:planning-quarter:query')")
public CommonResult<ProjectPlanningQuarterPlanningDetailRespVO> getProjectPlanningQuarterPlanningDetail(
@RequestParam("planningId") Long planningId) {
ProjectPlanningDO planning = projectPlanningService.getProjectPlanning(planningId);
if (planning == null) {
return success(null);
}
List<ProjectPlanningQuarterDO> quarterList =
projectPlanningQuarterService.getProjectPlanningQuarterListByPlanningId(planningId);
ProjectPlanningQuarterPlanningDetailRespVO respVO = new ProjectPlanningQuarterPlanningDetailRespVO();
Map<Long, BigDecimal> allocatedAmountMap =
projectPlanningService.getAllocatedAmountMap(Collections.singleton(planningId));
respVO.setPlanning(BeanUtils.toBean(planning, ProjectPlanningRespVO.class,
planningRespVO -> fillDistributionSummary(planningRespVO, allocatedAmountMap)));
respVO.setQuarters(BeanUtils.toBean(quarterList, ProjectPlanningQuarterRespVO.class));
return success(respVO);
}
private void fillDistributionSummary(ProjectPlanningRespVO respVO, Map<Long, BigDecimal> allocatedAmountMap) {
BigDecimal allocatedRatio = allocatedAmountMap.getOrDefault(respVO.getId(), ZERO_RATIO);
BigDecimal totalDistributionAmount = respVO.getTotalDistributionAmount() == null
? ZERO_RATIO : respVO.getTotalDistributionAmount().setScale(RATIO_SCALE, RoundingMode.HALF_UP);
BigDecimal allocatedAmount = totalDistributionAmount.multiply(allocatedRatio)
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
respVO.setAllocatedAmount(allocatedAmount);
respVO.setPendingAmount(totalDistributionAmount.subtract(allocatedAmount)
.setScale(RATIO_SCALE, RoundingMode.HALF_UP));
}
} }

View File

@@ -0,0 +1,20 @@
package cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo;
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Collections;
import java.util.List;
@Schema(description = "管理后台 - 合约规划季度分配聚合详情 Response VO")
@Data
public class ProjectPlanningQuarterPlanningDetailRespVO {
@Schema(description = "合约规划详情")
private ProjectPlanningRespVO planning;
@Schema(description = "季度分配列表")
private List<ProjectPlanningQuarterRespVO> quarters = Collections.emptyList();
}

View File

@@ -21,4 +21,7 @@ public class SpecialtyRoleSplitBatchSaveReqVO {
@Valid @Valid
private List<SpecialtyRoleSplitSaveItemReqVO> items; private List<SpecialtyRoleSplitSaveItemReqVO> items;
@Schema(description = "是否临时保存。true 时仅做基础格式处理,跳过角色合计、设计人员必填等强校验", example = "false")
private Boolean temporarySave;
} }

View File

@@ -12,6 +12,7 @@ import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
import cn.iocoder.lyzsys.module.tjt.dal.mysql.project.ProjectMapper; import cn.iocoder.lyzsys.module.tjt.dal.mysql.project.ProjectMapper;
import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper; import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper;
import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants; import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -76,7 +77,22 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
outputSplit.setProjectId(planning.getProjectId()); outputSplit.setProjectId(planning.getProjectId());
outputSplit.setYear(getPlanningYear(planning)); outputSplit.setYear(getPlanningYear(planning));
normalizeRatios(outputSplit); normalizeRatios(outputSplit);
projectOutputSplitMapper.insert(outputSplit); try {
projectOutputSplitMapper.insert(outputSplit);
} catch (DuplicateKeyException ex) {
// 并发下可能已由自动创建流程插入,重新查询后继续更新用户提交的比例。
outputSplit = projectOutputSplitMapper.selectByPlanningId(reqVO.getPlanningId());
if (outputSplit == null) {
throw ex;
}
ProjectOutputSplitDO updateObj = BeanUtils.toBean(reqVO, ProjectOutputSplitDO.class);
updateObj.setId(outputSplit.getId());
updateObj.setProjectId(planning.getProjectId());
updateObj.setYear(getPlanningYear(planning));
normalizeRatios(updateObj);
projectOutputSplitMapper.updateById(updateObj);
outputSplit = updateObj;
}
} else { } else {
ProjectOutputSplitDO updateObj = BeanUtils.toBean(reqVO, ProjectOutputSplitDO.class); ProjectOutputSplitDO updateObj = BeanUtils.toBean(reqVO, ProjectOutputSplitDO.class);
updateObj.setId(outputSplit.getId()); updateObj.setId(outputSplit.getId());
@@ -97,8 +113,17 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
return outputSplit; return outputSplit;
} }
ProjectOutputSplitDO createObj = buildDefaultOutputSplit(planning); ProjectOutputSplitDO createObj = buildDefaultOutputSplit(planning);
projectOutputSplitMapper.insert(createObj); try {
return createObj; projectOutputSplitMapper.insert(createObj);
return createObj;
} catch (DuplicateKeyException ex) {
// 唯一索引兜底并发创建,同一合约规划已存在时直接复用已有记录。
ProjectOutputSplitDO existing = projectOutputSplitMapper.selectByPlanningId(planningId);
if (existing != null) {
return existing;
}
throw ex;
}
} }
@Override @Override

View File

@@ -203,7 +203,19 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b)); item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
Map<String, Map<String, SpecialtyRoleSplitSaveItemReqVO>> groupedMap = buildGroupedInput(reqVO.getItems()); Map<String, Map<String, SpecialtyRoleSplitSaveItemReqVO>> groupedMap = buildGroupedInput(reqVO.getItems());
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue(); BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
boolean temporarySave = Boolean.TRUE.equals(reqVO.getTemporarySave());
saveSpecialtyRoleSplits(outputSplit, dbMap, groupedMap, assessmentOutputValue, !temporarySave);
}
/**
* 专业人员分配共用保存流程:正式保存执行强校验,临时保存仅做基础格式处理后落库。
*/
private void saveSpecialtyRoleSplits(ProjectOutputSplitDO outputSplit,
Map<String, SpecialtyRoleSplitDO> dbMap,
Map<String, Map<String, SpecialtyRoleSplitSaveItemReqVO>> groupedMap,
BigDecimal assessmentOutputValue,
boolean strictValidate) {
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) { for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap = groupedMap.getOrDefault( Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap = groupedMap.getOrDefault(
specialtyItem.getCode(), new LinkedHashMap<>()); specialtyItem.getCode(), new LinkedHashMap<>());
@@ -213,14 +225,18 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
BigDecimal roleRatio = getSaveRoleRatio(roleMap, specialtyItem.getCode(), roleItem.getCode()); BigDecimal roleRatio = getSaveRoleRatio(roleMap, specialtyItem.getCode(), roleItem.getCode());
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio); BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
List<SpecialtyRolePersonSaveReqVO> persons = normalizePersons( List<SpecialtyRolePersonSaveReqVO> persons = normalizePersons(
getSavePersons(roleMap, roleItem.getCode())); getSavePersons(roleMap, roleItem.getCode()), strictValidate);
validateRolePersons(roleItem.getCode(), roleAmount, persons); if (strictValidate) {
validateRolePersons(roleItem.getCode(), roleAmount, persons);
}
roleTotal = roleTotal.add(roleRatio).setScale(RATIO_SCALE, RoundingMode.HALF_UP); roleTotal = roleTotal.add(roleRatio).setScale(RATIO_SCALE, RoundingMode.HALF_UP);
SpecialtyRoleSplitDO role = upsertRole(dbMap, outputSplit.getId(), specialtyItem.getCode(), SpecialtyRoleSplitDO role = upsertRole(dbMap, outputSplit.getId(), specialtyItem.getCode(),
specialtyItem.getName(), roleItem.getCode(), roleRatio); specialtyItem.getName(), roleItem.getCode(), roleRatio);
refreshRolePersons(role, outputSplit, persons); refreshRolePersons(role, outputSplit, persons);
} }
validateRoleTotal(roleTotal); if (strictValidate) {
validateRoleTotal(roleTotal);
}
} }
} }
@@ -351,7 +367,8 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
return roleRatio; return roleRatio;
} }
private List<SpecialtyRolePersonSaveReqVO> normalizePersons(List<SpecialtyRolePersonSaveReqVO> persons) { private List<SpecialtyRolePersonSaveReqVO> normalizePersons(List<SpecialtyRolePersonSaveReqVO> persons,
boolean strictValidate) {
List<SpecialtyRolePersonSaveReqVO> result = new ArrayList<>(); List<SpecialtyRolePersonSaveReqVO> result = new ArrayList<>();
if (persons == null || persons.isEmpty()) { if (persons == null || persons.isEmpty()) {
return result; return result;
@@ -367,14 +384,18 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
if (!hasEmployee && !hasRatio) { if (!hasEmployee && !hasRatio) {
continue; continue;
} }
if (!hasEmployee || !hasRatio) { if (!strictValidate && !hasEmployee) {
// 临时保存允许半成品输入,没有选员工的行不落库。
continue;
}
if (strictValidate && (!hasEmployee || !hasRatio)) {
throw exception(SPECIALTY_ROLE_SPLIT_PERSON_INVALID); throw exception(SPECIALTY_ROLE_SPLIT_PERSON_INVALID);
} }
EmployeeDO employee = employeeService.validateEmployeeExists(employeeId); EmployeeDO employee = employeeService.validateEmployeeExists(employeeId);
SpecialtyRolePersonSaveReqVO normalized = new SpecialtyRolePersonSaveReqVO(); SpecialtyRolePersonSaveReqVO normalized = new SpecialtyRolePersonSaveReqVO();
normalized.setEmployeeId(employeeId); normalized.setEmployeeId(employeeId);
normalized.setEmployeeName(employee.getEmployeeName()); normalized.setEmployeeName(employee.getEmployeeName());
BigDecimal normalizedRatio = ratio(personRatio); BigDecimal normalizedRatio = ratio(strictValidate ? personRatio : (personRatio == null ? ZERO_RATIO : personRatio));
if (normalizedRatio.compareTo(ZERO_RATIO) < 0 || normalizedRatio.compareTo(ONE_RATIO) > 0) { if (normalizedRatio.compareTo(ZERO_RATIO) < 0 || normalizedRatio.compareTo(ONE_RATIO) > 0) {
throw exception(SPECIALTY_ROLE_SPLIT_PERSON_RATIO_INVALID); throw exception(SPECIALTY_ROLE_SPLIT_PERSON_RATIO_INVALID);
} }