0512新功能优化
This commit is contained in:
@@ -74,8 +74,9 @@ public class EmployeeController {
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "officeId", required = false) Long officeId,
|
||||
@RequestParam(value = "status", required = false) String status,
|
||||
@RequestParam(value = "enabledFlag", required = false) Boolean enabledFlag) {
|
||||
return success(employeeService.getEmployeeSimpleList(keyword, officeId, status, enabledFlag));
|
||||
@RequestParam(value = "enabledFlag", required = false) Boolean enabledFlag,
|
||||
@RequestParam(value = "officeLeaderFlag", required = false) Boolean officeLeaderFlag) {
|
||||
return success(employeeService.getEmployeeSimpleList(keyword, officeId, status, enabledFlag, officeLeaderFlag));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,4 +22,7 @@ public class EmployeePageReqVO extends PageParam {
|
||||
@Schema(description = "是否启用", example = "true")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
@Schema(description = "是否所长", example = "false")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ public class EmployeeRespVO {
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否所长")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sortNo;
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@ public class EmployeeSaveReqVO {
|
||||
@Size(max = 255, message = "备注长度不能超过 255 个字符")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否所长", example = "false")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
@Schema(description = "排序号", example = "1")
|
||||
private Integer sortNo;
|
||||
|
||||
|
||||
@@ -28,4 +28,7 @@ public class EmployeeSimpleRespVO {
|
||||
@Schema(description = "职称")
|
||||
private String jobTitle;
|
||||
|
||||
@Schema(description = "是否所长")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employeeyearcostbudget.EmployeeYearCostBudgetService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -34,6 +32,14 @@ public class EmployeeYearCostBudgetController {
|
||||
return success(employeeYearCostBudgetService.createEmployeeYearCostBudget(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/generate")
|
||||
@Operation(summary = "按年度生成员工年度成本预算")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-cost-budget:create')")
|
||||
public CommonResult<EmployeeYearCostBudgetGenerateRespVO> generateEmployeeYearCostBudget(
|
||||
@Valid @RequestBody EmployeeYearCostBudgetGenerateReqVO generateReqVO) {
|
||||
return success(employeeYearCostBudgetService.generateEmployeeYearCostBudget(generateReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改员工年度成本预算")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-cost-budget:update')")
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 员工年度成本预算按年度生成 Request VO")
|
||||
@Data
|
||||
public class EmployeeYearCostBudgetGenerateReqVO {
|
||||
|
||||
@Schema(description = "预算年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "预算年度不能为空")
|
||||
private Integer budgetYear;
|
||||
|
||||
@Schema(description = "默认预计发生成本", example = "0")
|
||||
@DecimalMin(value = "0", message = "默认预计发生成本不能小于 0")
|
||||
private BigDecimal expectedCostAmount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 员工年度成本预算按年度生成 Response VO")
|
||||
@Data
|
||||
public class EmployeeYearCostBudgetGenerateRespVO {
|
||||
|
||||
@Schema(description = "预算年度")
|
||||
private Integer budgetYear;
|
||||
|
||||
@Schema(description = "已启用员工数量")
|
||||
private Integer totalEnabledEmployeeCount;
|
||||
|
||||
@Schema(description = "本次新增预算记录数量")
|
||||
private Integer createdCount;
|
||||
|
||||
@Schema(description = "已存在并跳过的预算记录数量")
|
||||
private Integer skippedCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employeeyearleaderoutput.EmployeeYearLeaderOutputService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 年度所长考核产值")
|
||||
@RestController
|
||||
@RequestMapping("/tjt/employee-year-leader-output")
|
||||
@Validated
|
||||
public class EmployeeYearLeaderOutputController {
|
||||
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputService employeeYearLeaderOutputService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建年度所长考核产值")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:create')")
|
||||
public CommonResult<Long> createEmployeeYearLeaderOutput(
|
||||
@Valid @RequestBody EmployeeYearLeaderOutputSaveReqVO createReqVO) {
|
||||
return success(employeeYearLeaderOutputService.createEmployeeYearLeaderOutput(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/generate")
|
||||
@Operation(summary = "按年度生成年度所长考核产值")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:create')")
|
||||
public CommonResult<EmployeeYearLeaderOutputGenerateRespVO> generateEmployeeYearLeaderOutput(
|
||||
@Valid @RequestBody EmployeeYearLeaderOutputGenerateReqVO generateReqVO) {
|
||||
return success(employeeYearLeaderOutputService.generateEmployeeYearLeaderOutput(generateReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改年度所长考核产值")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:update')")
|
||||
public CommonResult<Boolean> updateEmployeeYearLeaderOutput(
|
||||
@Valid @RequestBody EmployeeYearLeaderOutputSaveReqVO updateReqVO) {
|
||||
employeeYearLeaderOutputService.updateEmployeeYearLeaderOutput(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除年度所长考核产值")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:delete')")
|
||||
public CommonResult<Boolean> deleteEmployeeYearLeaderOutput(@RequestParam("id") Long id) {
|
||||
employeeYearLeaderOutputService.deleteEmployeeYearLeaderOutput(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得年度所长考核产值详情")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:query')")
|
||||
public CommonResult<EmployeeYearLeaderOutputRespVO> getEmployeeYearLeaderOutput(@RequestParam("id") Long id) {
|
||||
return success(employeeYearLeaderOutputService.getEmployeeYearLeaderOutput(id));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得年度所长考核产值分页")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:query')")
|
||||
public CommonResult<PageResult<EmployeeYearLeaderOutputRespVO>> getEmployeeYearLeaderOutputPage(
|
||||
@Valid EmployeeYearLeaderOutputPageReqVO pageReqVO) {
|
||||
return success(employeeYearLeaderOutputService.getEmployeeYearLeaderOutputPage(pageReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值按年度生成 Request VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputGenerateReqVO {
|
||||
|
||||
@Schema(description = "产值年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "产值年度不能为空")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "默认所长考核产值", example = "0")
|
||||
@DecimalMin(value = "0", message = "默认所长考核产值不能小于 0")
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值按年度生成 Response VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputGenerateRespVO {
|
||||
|
||||
@Schema(description = "产值年度")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "已启用所长数量")
|
||||
private Integer totalEnabledLeaderCount;
|
||||
|
||||
@Schema(description = "本次新增记录数量")
|
||||
private Integer createdCount;
|
||||
|
||||
@Schema(description = "已存在并跳过的记录数量")
|
||||
private Integer skippedCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EmployeeYearLeaderOutputPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "员工 ID", example = "1")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名", example = "张")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "产值年度", example = "2026")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "是否启用", example = "true")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值 Response VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputRespVO {
|
||||
|
||||
@Schema(description = "记录 ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "员工 ID")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "产值年度")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "所长考核产值")
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sortNo;
|
||||
|
||||
@Schema(description = "是否启用")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值新增/修改 Request VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputSaveReqVO {
|
||||
|
||||
@Schema(description = "记录 ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "员工 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "员工 ID 不能为空")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名,后端根据 employeeId 回填", example = "张三")
|
||||
@Size(max = 64, message = "员工姓名长度不能超过 64 个字符")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "产值年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "产值年度不能为空")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "所长考核产值", requiredMode = Schema.RequiredMode.REQUIRED, example = "100000")
|
||||
@NotNull(message = "所长考核产值不能为空")
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
@Schema(description = "备注")
|
||||
@Size(max = 255, message = "备注长度不能超过 255 个字符")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "排序号", example = "1")
|
||||
private Integer sortNo;
|
||||
|
||||
@Schema(description = "是否启用", example = "true")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
}
|
||||
@@ -28,6 +28,9 @@ public class ProjectProfitRespVO {
|
||||
@Schema(description = "最终结算金额")
|
||||
private BigDecimal finalSettlementAmount;
|
||||
|
||||
@Schema(description = "有效结算金额,最终结算金额大于 0 时取最终结算金额,否则取合同产值")
|
||||
private BigDecimal effectiveSettlementAmount;
|
||||
|
||||
@Schema(description = "综合所协作金额")
|
||||
private BigDecimal comprehensivePlanningAmount;
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.EmployeeOutputSummaryExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectBudgetExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectLeadQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectOverviewExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.SpecialtyPersonOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.report.ProjectOutputReportService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -22,6 +18,7 @@ import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 产值报表导出")
|
||||
@RestController
|
||||
@@ -69,6 +66,22 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportSpecialtyPersonOutputExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/specialty-person-output/preview")
|
||||
@Operation(summary = "预览专业内人员年度季度计取表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-specialty-person:query', 'tjt:report-specialty-person:export')")
|
||||
public CommonResult<SpecialtyPersonOutputPreviewRespVO> getSpecialtyPersonOutputPreview(
|
||||
@Valid SpecialtyPersonOutputPreviewReqVO reqVO) {
|
||||
return success(projectOutputReportService.getSpecialtyPersonOutputPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/project-overview/preview")
|
||||
@Operation(summary = "预览项目总览表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-summary:query', 'tjt:report-summary:export')")
|
||||
public CommonResult<ProjectOverviewPreviewRespVO> getProjectOverviewPreview(
|
||||
@Valid ProjectOverviewExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getProjectOverviewPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/project-overview/export-excel")
|
||||
@Operation(summary = "导出项目总览表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-summary:export')")
|
||||
@@ -78,6 +91,14 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportProjectOverviewExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/employee-output-summary/preview")
|
||||
@Operation(summary = "预览员工个人考核产值汇总表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-summary:query', 'tjt:report-summary:export')")
|
||||
public CommonResult<EmployeeOutputSummaryPreviewRespVO> getEmployeeOutputSummaryPreview(
|
||||
@Valid EmployeeOutputSummaryExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getEmployeeOutputSummaryPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/employee-output-summary/export-excel")
|
||||
@Operation(summary = "导出员工个人考核产值汇总表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-summary:export')")
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 员工个人考核产值汇总表预览 Response VO")
|
||||
@Data
|
||||
public class EmployeeOutputSummaryPreviewRespVO {
|
||||
|
||||
@Schema(description = "年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "预计 K 值,小数值,例如 0.4 表示 40%")
|
||||
private BigDecimal kValue;
|
||||
|
||||
@Schema(description = "员工明细行,金额单位:万元")
|
||||
private List<EmployeeOutputSummaryExcelRespVO> rows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "合计行,金额单位:万元")
|
||||
private EmployeeOutputSummaryExcelRespVO totalRow;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 项目总览表预览 Response VO")
|
||||
@Data
|
||||
public class ProjectOverviewPreviewRespVO {
|
||||
|
||||
@Schema(description = "年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "专业所名称", example = "给排水所")
|
||||
private String officeName;
|
||||
|
||||
@Schema(description = "员工动态列")
|
||||
private List<EmployeeColumn> employeeColumns = Collections.emptyList();
|
||||
|
||||
@Schema(description = "项目行")
|
||||
private List<ProjectRow> rows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "合计行")
|
||||
private ProjectRow totalRow;
|
||||
|
||||
@Schema(description = "员工动态列")
|
||||
@Data
|
||||
public static class EmployeeColumn {
|
||||
|
||||
@Schema(description = "员工 ID", example = "1")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名", example = "张三")
|
||||
private String employeeName;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "项目总览行")
|
||||
@Data
|
||||
public static class ProjectRow {
|
||||
|
||||
@Schema(description = "序号", example = "1")
|
||||
private Integer serialNo;
|
||||
|
||||
@Schema(description = "是否合计行", example = "false")
|
||||
private Boolean totalRow = false;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "工程进度情况及其它说明")
|
||||
private String progressText;
|
||||
|
||||
@Schema(description = "工作阶段")
|
||||
private String workStage;
|
||||
|
||||
@Schema(description = "本专业 + 项目总核算总产值,单位:万元")
|
||||
private BigDecimal totalOutputAmountWan;
|
||||
|
||||
@Schema(description = "往期已发放比例,小数值,例如 0.2 表示 20%")
|
||||
private BigDecimal historicalIssuedRatio;
|
||||
|
||||
@Schema(description = "本期结算占比,小数值,例如 0.2 表示 20%")
|
||||
private BigDecimal currentSettlementRatio;
|
||||
|
||||
@Schema(description = "本期结算考核产值,单位:万元")
|
||||
private BigDecimal currentSettlementAmountWan;
|
||||
|
||||
@Schema(description = "未结算比例,小数值,例如 0.2 表示 20%")
|
||||
private BigDecimal pendingRatio;
|
||||
|
||||
@Schema(description = "员工季度金额,key 为员工 ID,金额单位:万元")
|
||||
private Map<Long, EmployeeAmountValue> employeeAmountMap = new LinkedHashMap<>();
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "员工季度金额")
|
||||
@Data
|
||||
public static class EmployeeAmountValue {
|
||||
|
||||
@Schema(description = "一季度,单位:万元")
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
|
||||
@Schema(description = "二季度,单位:万元")
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "三季度,单位:万元")
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "四季度,单位:万元")
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
|
||||
@Schema(description = "本年度小计,单位:万元")
|
||||
private BigDecimal annualTotalAmountWan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 专业内人员年度季度计取预览 Request VO")
|
||||
@Data
|
||||
public class SpecialtyPersonOutputPreviewReqVO {
|
||||
|
||||
@Schema(description = "合约规划 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "合约规划 ID 不能为空")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "预览年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 专业内人员年度季度计取预览 Response VO")
|
||||
@Data
|
||||
public class SpecialtyPersonOutputPreviewRespVO {
|
||||
|
||||
@Schema(description = "锚点合约规划 ID")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "预览年度")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "专业分组")
|
||||
private List<GroupRow> groups;
|
||||
|
||||
@Schema(description = "专业分组")
|
||||
@Data
|
||||
public static class GroupRow {
|
||||
|
||||
@Schema(description = "专业编码")
|
||||
private String specialtyCode;
|
||||
|
||||
@Schema(description = "专业名称")
|
||||
private String specialtyName;
|
||||
|
||||
@Schema(description = "是否允许导出专业内人员计取表")
|
||||
private Boolean exportable;
|
||||
|
||||
@Schema(description = "专业金额(元)")
|
||||
private BigDecimal specialtyAmount;
|
||||
|
||||
@Schema(description = "角色比例合计")
|
||||
private BigDecimal roleTotal;
|
||||
|
||||
@Schema(description = "已配置人数")
|
||||
private Integer personCount;
|
||||
|
||||
@Schema(description = "是否超额")
|
||||
private Boolean overRatio;
|
||||
|
||||
@Schema(description = "专业一季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterOneAmountWan;
|
||||
|
||||
@Schema(description = "专业二季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "专业三季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "专业四季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterFourAmountWan;
|
||||
|
||||
@Schema(description = "专业本年度小计金额(万元)")
|
||||
private BigDecimal specialtyYearTotalAmountWan;
|
||||
|
||||
@Schema(description = "角色人员年度季度计取明细")
|
||||
private List<RoleRow> rows;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "角色人员年度季度计取明细")
|
||||
@Data
|
||||
public static class RoleRow {
|
||||
|
||||
@Schema(description = "专业编码")
|
||||
private String specialtyCode;
|
||||
|
||||
@Schema(description = "专业名称")
|
||||
private String specialtyName;
|
||||
|
||||
@Schema(description = "角色编码")
|
||||
private String roleCode;
|
||||
|
||||
@Schema(description = "角色名称")
|
||||
private String roleName;
|
||||
|
||||
@Schema(description = "角色比例")
|
||||
private BigDecimal roleRatio;
|
||||
|
||||
@Schema(description = "角色金额(元)")
|
||||
private BigDecimal roleAmount;
|
||||
|
||||
@Schema(description = "人员比例合计")
|
||||
private BigDecimal personTotalRatio;
|
||||
|
||||
@Schema(description = "人员明细")
|
||||
private List<PersonRow> persons;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "人员年度季度计取明细")
|
||||
@Data
|
||||
public static class PersonRow {
|
||||
|
||||
@Schema(description = "人员唯一键")
|
||||
private String personKey;
|
||||
|
||||
@Schema(description = "员工 ID")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "人员工作量比例")
|
||||
private BigDecimal personRatio;
|
||||
|
||||
@Schema(description = "人员金额(元)")
|
||||
private BigDecimal personAmount;
|
||||
|
||||
@Schema(description = "参与角色")
|
||||
private String roleNames;
|
||||
|
||||
@Schema(description = "占专业比例合计")
|
||||
private BigDecimal adjustedPersonRatio;
|
||||
|
||||
@Schema(description = "一季度比例")
|
||||
private BigDecimal quarterOneRatio;
|
||||
|
||||
@Schema(description = "一季度金额(万元)")
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
|
||||
@Schema(description = "二季度比例")
|
||||
private BigDecimal quarterTwoRatio;
|
||||
|
||||
@Schema(description = "二季度金额(万元)")
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "三季度比例")
|
||||
private BigDecimal quarterThreeRatio;
|
||||
|
||||
@Schema(description = "三季度金额(万元)")
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "四季度比例")
|
||||
private BigDecimal quarterFourRatio;
|
||||
|
||||
@Schema(description = "四季度金额(万元)")
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
|
||||
@Schema(description = "本年度小计比例")
|
||||
private BigDecimal yearTotalRatio;
|
||||
|
||||
@Schema(description = "本年度小计金额(万元)")
|
||||
private BigDecimal yearTotalAmountWan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,8 @@ public class EmployeeDO extends TenantBaseDO {
|
||||
|
||||
private String remark;
|
||||
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
private Boolean enabledFlag;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@TableName("tjt_employee_year_leader_output")
|
||||
@KeySequence("tjt_employee_year_leader_output_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EmployeeYearLeaderOutputDO extends TenantBaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
private String employeeName;
|
||||
|
||||
private Integer outputYear;
|
||||
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
private String remark;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
private Boolean enabledFlag;
|
||||
|
||||
}
|
||||
@@ -35,8 +35,6 @@ public class SpecialtyRoleSplitDO extends TenantBaseDO {
|
||||
|
||||
private BigDecimal roleRatio;
|
||||
|
||||
private String personsJson;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 页面 5 角色人员分配明细 DO
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
@TableName("tjt_specialty_role_split_person")
|
||||
@KeySequence("tjt_specialty_role_split_person_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SpecialtyRoleSplitPersonDO extends TenantBaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long roleSplitId;
|
||||
|
||||
private Long outputSplitId;
|
||||
|
||||
private Long projectId;
|
||||
|
||||
private Long planningId;
|
||||
|
||||
private String specialtyCode;
|
||||
|
||||
private String specialtyName;
|
||||
|
||||
private String roleCode;
|
||||
|
||||
private String roleName;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
private String employeeName;
|
||||
|
||||
private BigDecimal personRatio;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
}
|
||||
@@ -18,16 +18,34 @@ public interface EmployeeMapper extends BaseMapperX<EmployeeDO> {
|
||||
.eqIfPresent(EmployeeDO::getOfficeId, reqVO.getOfficeId())
|
||||
.eqIfPresent(EmployeeDO::getEmployeeStatus, reqVO.getEmployeeStatus())
|
||||
.eqIfPresent(EmployeeDO::getEnabledFlag, reqVO.getEnabledFlag())
|
||||
.eqIfPresent(EmployeeDO::getOfficeLeaderFlag, reqVO.getOfficeLeaderFlag())
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
default List<EmployeeDO> selectSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag) {
|
||||
default List<EmployeeDO> selectSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag,
|
||||
Boolean officeLeaderFlag) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
.likeIfPresent(EmployeeDO::getEmployeeName, keyword)
|
||||
.eqIfPresent(EmployeeDO::getOfficeId, officeId)
|
||||
.eqIfPresent(EmployeeDO::getEmployeeStatus, status)
|
||||
.eqIfPresent(EmployeeDO::getEnabledFlag, enabledFlag)
|
||||
.eqIfPresent(EmployeeDO::getOfficeLeaderFlag, officeLeaderFlag)
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
default List<EmployeeDO> selectEnabledList() {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
.eq(EmployeeDO::getEnabledFlag, Boolean.TRUE)
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
default List<EmployeeDO> selectEnabledLeaderList() {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
.eq(EmployeeDO::getEnabledFlag, Boolean.TRUE)
|
||||
.eq(EmployeeDO::getOfficeLeaderFlag, Boolean.TRUE)
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.E
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearcostbudget.EmployeeYearCostBudgetDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface EmployeeYearCostBudgetMapper extends BaseMapperX<EmployeeYearCostBudgetDO> {
|
||||
|
||||
@@ -27,6 +29,11 @@ public interface EmployeeYearCostBudgetMapper extends BaseMapperX<EmployeeYearCo
|
||||
.eq(EmployeeYearCostBudgetDO::getBudgetYear, budgetYear));
|
||||
}
|
||||
|
||||
default List<EmployeeYearCostBudgetDO> selectListByBudgetYear(Integer budgetYear) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeYearCostBudgetDO>()
|
||||
.eq(EmployeeYearCostBudgetDO::getBudgetYear, budgetYear));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<EmployeeYearCostBudgetDO>()
|
||||
.eq(EmployeeYearCostBudgetDO::getEmployeeId, employeeId));
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.EmployeeYearLeaderOutputPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput.EmployeeYearLeaderOutputDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface EmployeeYearLeaderOutputMapper extends BaseMapperX<EmployeeYearLeaderOutputDO> {
|
||||
|
||||
default PageResult<EmployeeYearLeaderOutputDO> selectPage(EmployeeYearLeaderOutputPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eqIfPresent(EmployeeYearLeaderOutputDO::getEmployeeId, reqVO.getEmployeeId())
|
||||
.likeIfPresent(EmployeeYearLeaderOutputDO::getEmployeeName, reqVO.getEmployeeName())
|
||||
.eqIfPresent(EmployeeYearLeaderOutputDO::getOutputYear, reqVO.getOutputYear())
|
||||
.eqIfPresent(EmployeeYearLeaderOutputDO::getEnabledFlag, reqVO.getEnabledFlag())
|
||||
.orderByDesc(EmployeeYearLeaderOutputDO::getOutputYear)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getSortNo)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getId));
|
||||
}
|
||||
|
||||
default EmployeeYearLeaderOutputDO selectByEmployeeIdAndOutputYear(Long employeeId, Integer outputYear) {
|
||||
return selectOne(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getEmployeeId, employeeId)
|
||||
.eq(EmployeeYearLeaderOutputDO::getOutputYear, outputYear));
|
||||
}
|
||||
|
||||
default List<EmployeeYearLeaderOutputDO> selectListByOutputYear(Integer outputYear) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getOutputYear, outputYear));
|
||||
}
|
||||
|
||||
default List<EmployeeYearLeaderOutputDO> selectEnabledListByOutputYear(Integer outputYear,
|
||||
Collection<Long> employeeIds) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getOutputYear, outputYear)
|
||||
.eq(EmployeeYearLeaderOutputDO::getEnabledFlag, Boolean.TRUE)
|
||||
.inIfPresent(EmployeeYearLeaderOutputDO::getEmployeeId, employeeIds)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getSortNo)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getEmployeeId, employeeId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,19 @@ public interface ProjectRolePersonMapper extends BaseMapperX<ProjectRolePersonDO
|
||||
.orderByAsc(ProjectRolePersonDO::getId));
|
||||
}
|
||||
|
||||
default List<ProjectRolePersonDO> selectListByEmployeeIds(Collection<Long> employeeIds) {
|
||||
if (employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<ProjectRolePersonDO>()
|
||||
.in(ProjectRolePersonDO::getEmployeeId, employeeIds)
|
||||
.eq(ProjectRolePersonDO::getEnabledFlag, Boolean.TRUE)
|
||||
.orderByAsc(ProjectRolePersonDO::getProjectId)
|
||||
.orderByAsc(ProjectRolePersonDO::getRoleCode)
|
||||
.orderByAsc(ProjectRolePersonDO::getSortNo)
|
||||
.orderByAsc(ProjectRolePersonDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<ProjectRolePersonDO>()
|
||||
.eq(ProjectRolePersonDO::getEmployeeId, employeeId));
|
||||
|
||||
@@ -5,6 +5,8 @@ import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplit.SpecialtyRoleSplitDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -22,9 +24,15 @@ public interface SpecialtyRoleSplitMapper extends BaseMapperX<SpecialtyRoleSplit
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitDO> selectListByPersonsJsonKeyword(String keyword) {
|
||||
default List<SpecialtyRoleSplitDO> selectListByOutputSplitIds(Collection<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitDO>()
|
||||
.like(SpecialtyRoleSplitDO::getPersonsJson, keyword));
|
||||
.in(SpecialtyRoleSplitDO::getOutputSplitId, outputSplitIds)
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getOutputSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplitperson;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson.SpecialtyRoleSplitPersonDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 页面 5 角色人员分配明细 Mapper
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
@Mapper
|
||||
public interface SpecialtyRoleSplitPersonMapper extends BaseMapperX<SpecialtyRoleSplitPersonDO> {
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByRoleSplitId(Long roleSplitId) {
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.eq(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByRoleSplitIds(Collection<Long> roleSplitIds) {
|
||||
if (roleSplitIds == null || roleSplitIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByOutputSplitIds(Collection<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getOutputSplitId, outputSplitIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getOutputSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByEmployeeIds(Collection<Long> employeeIds) {
|
||||
if (employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getEmployeeId, employeeIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByPlanningIdsAndEmployeeIds(Collection<Long> planningIds,
|
||||
Collection<Long> employeeIds) {
|
||||
if (planningIds == null || planningIds.isEmpty() || employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getPlanningId, planningIds)
|
||||
.in(SpecialtyRoleSplitPersonDO::getEmployeeId, employeeIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default void deleteByRoleSplitId(Long roleSplitId) {
|
||||
delete(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitId);
|
||||
}
|
||||
|
||||
default void deleteByRoleSplitIds(Collection<Long> roleSplitIds) {
|
||||
if (roleSplitIds == null || roleSplitIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
delete(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitIds));
|
||||
}
|
||||
|
||||
default void deleteByOutputSplitId(Long outputSplitId) {
|
||||
delete(SpecialtyRoleSplitPersonDO::getOutputSplitId, outputSplitId);
|
||||
}
|
||||
|
||||
default void deleteByOutputSplitIds(Collection<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
delete(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getOutputSplitId, outputSplitIds));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.eq(SpecialtyRoleSplitPersonDO::getEmployeeId, employeeId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,9 +55,14 @@ public interface ErrorCodeConstants {
|
||||
// ========== 员工管理 1-020-008-000 ==========
|
||||
ErrorCode EMPLOYEE_NOT_EXISTS = new ErrorCode(1_020_008_000, "员工记录不存在");
|
||||
ErrorCode EMPLOYEE_IN_USE = new ErrorCode(1_020_008_001, "当前员工已被业务数据引用,不能删除");
|
||||
ErrorCode EMPLOYEE_NOT_OFFICE_LEADER = new ErrorCode(1_020_008_002, "当前员工未启用或未标记为所长,不能维护年度所长考核产值");
|
||||
|
||||
// ========== 员工年度成本预算 1-020-009-000 ==========
|
||||
ErrorCode EMPLOYEE_YEAR_COST_BUDGET_NOT_EXISTS = new ErrorCode(1_020_009_000, "员工年度成本预算记录不存在");
|
||||
ErrorCode EMPLOYEE_YEAR_COST_BUDGET_DUPLICATE = new ErrorCode(1_020_009_001, "当前员工该年度预计发生成本已存在");
|
||||
|
||||
// ========== 年度所长考核产值 1-020-010-000 ==========
|
||||
ErrorCode EMPLOYEE_YEAR_LEADER_OUTPUT_NOT_EXISTS = new ErrorCode(1_020_010_000, "年度所长考核产值记录不存在");
|
||||
ErrorCode EMPLOYEE_YEAR_LEADER_OUTPUT_DUPLICATE = new ErrorCode(1_020_010_001, "当前所长该年度考核产值已存在");
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public interface EmployeeService {
|
||||
|
||||
PageResult<EmployeeRespVO> getEmployeePage(EmployeePageReqVO pageReqVO);
|
||||
|
||||
List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag);
|
||||
List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status,
|
||||
Boolean enabledFlag, Boolean officeLeaderFlag);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,21 +2,19 @@ package cn.iocoder.lyzsys.module.tjt.service.employee;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeePageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeeRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeeSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeeSimpleRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.office.OfficeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplit.SpecialtyRoleSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearcostbudget.EmployeeYearCostBudgetMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput.EmployeeYearLeaderOutputMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.office.OfficeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplit.SpecialtyRoleSplitMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplitperson.SpecialtyRoleSplitPersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.office.OfficeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -43,9 +41,11 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
@Resource
|
||||
private EmployeeYearCostBudgetMapper employeeYearCostBudgetMapper;
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputMapper employeeYearLeaderOutputMapper;
|
||||
@Resource
|
||||
private ProjectRolePersonMapper projectRolePersonMapper;
|
||||
@Resource
|
||||
private SpecialtyRoleSplitMapper specialtyRoleSplitMapper;
|
||||
private SpecialtyRoleSplitPersonMapper specialtyRoleSplitPersonMapper;
|
||||
@Resource
|
||||
private OfficeService officeService;
|
||||
|
||||
@@ -56,6 +56,9 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
if (employee.getEnabledFlag() == null) {
|
||||
employee.setEnabledFlag(Boolean.TRUE);
|
||||
}
|
||||
if (employee.getOfficeLeaderFlag() == null) {
|
||||
employee.setOfficeLeaderFlag(Boolean.FALSE);
|
||||
}
|
||||
employeeMapper.insert(employee);
|
||||
return employee.getId();
|
||||
}
|
||||
@@ -64,13 +67,18 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
public void updateEmployee(EmployeeSaveReqVO updateReqVO) {
|
||||
validateEmployeeExists(updateReqVO.getId());
|
||||
officeService.validateOfficeExists(updateReqVO.getOfficeId());
|
||||
employeeMapper.updateById(BeanUtils.toBean(updateReqVO, EmployeeDO.class));
|
||||
EmployeeDO employee = BeanUtils.toBean(updateReqVO, EmployeeDO.class);
|
||||
if (employee.getOfficeLeaderFlag() == null) {
|
||||
employee.setOfficeLeaderFlag(Boolean.FALSE);
|
||||
}
|
||||
employeeMapper.updateById(employee);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEmployee(Long id) {
|
||||
validateEmployeeExists(id);
|
||||
if (employeeYearCostBudgetMapper.selectCountByEmployeeId(id) > 0
|
||||
|| employeeYearLeaderOutputMapper.selectCountByEmployeeId(id) > 0
|
||||
|| projectRolePersonMapper.selectCountByEmployeeId(id) > 0
|
||||
|| existsInSpecialtyRoleSplit(id)) {
|
||||
throw exception(EMPLOYEE_IN_USE);
|
||||
@@ -104,8 +112,10 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag) {
|
||||
List<EmployeeDO> list = employeeMapper.selectSimpleList(keyword, officeId, status, enabledFlag == null ? Boolean.TRUE : enabledFlag);
|
||||
public List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status,
|
||||
Boolean enabledFlag, Boolean officeLeaderFlag) {
|
||||
List<EmployeeDO> list = employeeMapper.selectSimpleList(keyword, officeId, status,
|
||||
enabledFlag == null ? Boolean.TRUE : enabledFlag, officeLeaderFlag);
|
||||
Map<Long, OfficeDO> officeMap = getOfficeMap(CollectionUtils.convertSet(list, EmployeeDO::getOfficeId));
|
||||
return BeanUtils.toBean(list, EmployeeSimpleRespVO.class, respVO ->
|
||||
respVO.setOfficeName(officeMap.containsKey(respVO.getOfficeId())
|
||||
@@ -113,20 +123,7 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
}
|
||||
|
||||
private boolean existsInSpecialtyRoleSplit(Long employeeId) {
|
||||
List<SpecialtyRoleSplitDO> candidateList = specialtyRoleSplitMapper.selectListByPersonsJsonKeyword("\"employeeId\":" + employeeId);
|
||||
for (SpecialtyRoleSplitDO item : candidateList) {
|
||||
List<SpecialtyRolePersonSaveReqVO> persons = JsonUtils.parseArray(item.getPersonsJson(), SpecialtyRolePersonSaveReqVO.class);
|
||||
if (persons == null) {
|
||||
continue;
|
||||
}
|
||||
boolean matched = persons.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.anyMatch(person -> Objects.equals(person.getEmployeeId(), employeeId));
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return specialtyRoleSplitPersonMapper.selectCountByEmployeeId(employeeId) > 0;
|
||||
}
|
||||
|
||||
private Map<Long, OfficeDO> getOfficeMap(Set<Long> officeIds) {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.employeeyearcostbudget;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@@ -11,6 +9,8 @@ public interface EmployeeYearCostBudgetService {
|
||||
|
||||
Long createEmployeeYearCostBudget(@Valid EmployeeYearCostBudgetSaveReqVO createReqVO);
|
||||
|
||||
EmployeeYearCostBudgetGenerateRespVO generateEmployeeYearCostBudget(@Valid EmployeeYearCostBudgetGenerateReqVO reqVO);
|
||||
|
||||
void updateEmployeeYearCostBudget(@Valid EmployeeYearCostBudgetSaveReqVO updateReqVO);
|
||||
|
||||
void deleteEmployeeYearCostBudget(Long id);
|
||||
|
||||
@@ -2,18 +2,22 @@ package cn.iocoder.lyzsys.module.tjt.service.employeeyearcostbudget;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearcostbudget.EmployeeYearCostBudgetDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearcostbudget.EmployeeYearCostBudgetMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.EMPLOYEE_YEAR_COST_BUDGET_DUPLICATE;
|
||||
@@ -26,6 +30,8 @@ public class EmployeeYearCostBudgetServiceImpl implements EmployeeYearCostBudget
|
||||
@Resource
|
||||
private EmployeeYearCostBudgetMapper employeeYearCostBudgetMapper;
|
||||
@Resource
|
||||
private EmployeeMapper employeeMapper;
|
||||
@Resource
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Override
|
||||
@@ -41,6 +47,32 @@ public class EmployeeYearCostBudgetServiceImpl implements EmployeeYearCostBudget
|
||||
return budget.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeYearCostBudgetGenerateRespVO generateEmployeeYearCostBudget(EmployeeYearCostBudgetGenerateReqVO reqVO) {
|
||||
BigDecimal expectedCostAmount = amount(reqVO.getExpectedCostAmount());
|
||||
List<EmployeeDO> enabledEmployees = employeeMapper.selectEnabledList();
|
||||
Set<Long> existingEmployeeIds = employeeYearCostBudgetMapper.selectListByBudgetYear(reqVO.getBudgetYear())
|
||||
.stream()
|
||||
.map(EmployeeYearCostBudgetDO::getEmployeeId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<EmployeeYearCostBudgetDO> createList = enabledEmployees.stream()
|
||||
.filter(employee -> !existingEmployeeIds.contains(employee.getId()))
|
||||
.map(employee -> buildInitialBudget(employee, reqVO.getBudgetYear(), expectedCostAmount))
|
||||
.collect(Collectors.toList());
|
||||
if (!createList.isEmpty()) {
|
||||
employeeYearCostBudgetMapper.insertBatch(createList);
|
||||
}
|
||||
|
||||
EmployeeYearCostBudgetGenerateRespVO respVO = new EmployeeYearCostBudgetGenerateRespVO();
|
||||
respVO.setBudgetYear(reqVO.getBudgetYear());
|
||||
respVO.setTotalEnabledEmployeeCount(enabledEmployees.size());
|
||||
respVO.setCreatedCount(createList.size());
|
||||
respVO.setSkippedCount(enabledEmployees.size() - createList.size());
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmployeeYearCostBudget(EmployeeYearCostBudgetSaveReqVO updateReqVO) {
|
||||
validateExists(updateReqVO.getId());
|
||||
@@ -82,4 +114,21 @@ public class EmployeeYearCostBudgetServiceImpl implements EmployeeYearCostBudget
|
||||
}
|
||||
}
|
||||
|
||||
private EmployeeYearCostBudgetDO buildInitialBudget(EmployeeDO employee, Integer budgetYear, BigDecimal expectedCostAmount) {
|
||||
EmployeeYearCostBudgetDO budget = new EmployeeYearCostBudgetDO();
|
||||
budget.setEmployeeId(employee.getId());
|
||||
budget.setEmployeeName(employee.getEmployeeName());
|
||||
budget.setBudgetYear(budgetYear);
|
||||
budget.setExpectedCostAmount(expectedCostAmount);
|
||||
budget.setSortNo(employee.getSortNo() == null ? 0 : employee.getSortNo());
|
||||
budget.setEnabledFlag(Boolean.TRUE);
|
||||
budget.setRemark("");
|
||||
return budget;
|
||||
}
|
||||
|
||||
private BigDecimal amount(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
|
||||
: value.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface EmployeeYearLeaderOutputService {
|
||||
|
||||
Long createEmployeeYearLeaderOutput(@Valid EmployeeYearLeaderOutputSaveReqVO createReqVO);
|
||||
|
||||
EmployeeYearLeaderOutputGenerateRespVO generateEmployeeYearLeaderOutput(
|
||||
@Valid EmployeeYearLeaderOutputGenerateReqVO reqVO);
|
||||
|
||||
void updateEmployeeYearLeaderOutput(@Valid EmployeeYearLeaderOutputSaveReqVO updateReqVO);
|
||||
|
||||
void deleteEmployeeYearLeaderOutput(Long id);
|
||||
|
||||
EmployeeYearLeaderOutputRespVO getEmployeeYearLeaderOutput(Long id);
|
||||
|
||||
PageResult<EmployeeYearLeaderOutputRespVO> getEmployeeYearLeaderOutputPage(
|
||||
EmployeeYearLeaderOutputPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput.EmployeeYearLeaderOutputDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput.EmployeeYearLeaderOutputMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
public class EmployeeYearLeaderOutputServiceImpl implements EmployeeYearLeaderOutputService {
|
||||
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputMapper employeeYearLeaderOutputMapper;
|
||||
@Resource
|
||||
private EmployeeMapper employeeMapper;
|
||||
@Resource
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Override
|
||||
public Long createEmployeeYearLeaderOutput(EmployeeYearLeaderOutputSaveReqVO createReqVO) {
|
||||
EmployeeDO employee = validateEmployeeIsOfficeLeader(createReqVO.getEmployeeId());
|
||||
validateDuplicate(null, createReqVO.getEmployeeId(), createReqVO.getOutputYear());
|
||||
EmployeeYearLeaderOutputDO output = BeanUtils.toBean(createReqVO, EmployeeYearLeaderOutputDO.class);
|
||||
output.setEmployeeName(employee.getEmployeeName());
|
||||
output.setLeaderOutputAmount(amount(output.getLeaderOutputAmount()));
|
||||
if (output.getEnabledFlag() == null) {
|
||||
output.setEnabledFlag(Boolean.TRUE);
|
||||
}
|
||||
employeeYearLeaderOutputMapper.insert(output);
|
||||
return output.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeYearLeaderOutputGenerateRespVO generateEmployeeYearLeaderOutput(
|
||||
EmployeeYearLeaderOutputGenerateReqVO reqVO) {
|
||||
BigDecimal leaderOutputAmount = amount(reqVO.getLeaderOutputAmount());
|
||||
List<EmployeeDO> enabledLeaders = employeeMapper.selectEnabledLeaderList();
|
||||
Set<Long> existingEmployeeIds = employeeYearLeaderOutputMapper.selectListByOutputYear(reqVO.getOutputYear())
|
||||
.stream()
|
||||
.map(EmployeeYearLeaderOutputDO::getEmployeeId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<EmployeeYearLeaderOutputDO> createList = enabledLeaders.stream()
|
||||
.filter(employee -> !existingEmployeeIds.contains(employee.getId()))
|
||||
.map(employee -> buildInitialOutput(employee, reqVO.getOutputYear(), leaderOutputAmount))
|
||||
.collect(Collectors.toList());
|
||||
if (!createList.isEmpty()) {
|
||||
employeeYearLeaderOutputMapper.insertBatch(createList);
|
||||
}
|
||||
|
||||
EmployeeYearLeaderOutputGenerateRespVO respVO = new EmployeeYearLeaderOutputGenerateRespVO();
|
||||
respVO.setOutputYear(reqVO.getOutputYear());
|
||||
respVO.setTotalEnabledLeaderCount(enabledLeaders.size());
|
||||
respVO.setCreatedCount(createList.size());
|
||||
respVO.setSkippedCount(enabledLeaders.size() - createList.size());
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmployeeYearLeaderOutput(EmployeeYearLeaderOutputSaveReqVO updateReqVO) {
|
||||
validateExists(updateReqVO.getId());
|
||||
EmployeeDO employee = validateEmployeeIsOfficeLeader(updateReqVO.getEmployeeId());
|
||||
validateDuplicate(updateReqVO.getId(), updateReqVO.getEmployeeId(), updateReqVO.getOutputYear());
|
||||
EmployeeYearLeaderOutputDO updateObj = BeanUtils.toBean(updateReqVO, EmployeeYearLeaderOutputDO.class);
|
||||
updateObj.setEmployeeName(employee.getEmployeeName());
|
||||
updateObj.setLeaderOutputAmount(amount(updateObj.getLeaderOutputAmount()));
|
||||
employeeYearLeaderOutputMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEmployeeYearLeaderOutput(Long id) {
|
||||
validateExists(id);
|
||||
employeeYearLeaderOutputMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeYearLeaderOutputRespVO getEmployeeYearLeaderOutput(Long id) {
|
||||
return BeanUtils.toBean(validateExists(id), EmployeeYearLeaderOutputRespVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<EmployeeYearLeaderOutputRespVO> getEmployeeYearLeaderOutputPage(
|
||||
EmployeeYearLeaderOutputPageReqVO pageReqVO) {
|
||||
return BeanUtils.toBean(employeeYearLeaderOutputMapper.selectPage(pageReqVO),
|
||||
EmployeeYearLeaderOutputRespVO.class);
|
||||
}
|
||||
|
||||
private EmployeeYearLeaderOutputDO validateExists(Long id) {
|
||||
EmployeeYearLeaderOutputDO output = employeeYearLeaderOutputMapper.selectById(id);
|
||||
if (output == null) {
|
||||
throw exception(EMPLOYEE_YEAR_LEADER_OUTPUT_NOT_EXISTS);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private EmployeeDO validateEmployeeIsOfficeLeader(Long employeeId) {
|
||||
EmployeeDO employee = employeeService.validateEmployeeExists(employeeId);
|
||||
if (!Boolean.TRUE.equals(employee.getEnabledFlag()) || !Boolean.TRUE.equals(employee.getOfficeLeaderFlag())) {
|
||||
throw exception(EMPLOYEE_NOT_OFFICE_LEADER);
|
||||
}
|
||||
return employee;
|
||||
}
|
||||
|
||||
private void validateDuplicate(Long id, Long employeeId, Integer outputYear) {
|
||||
EmployeeYearLeaderOutputDO duplicate =
|
||||
employeeYearLeaderOutputMapper.selectByEmployeeIdAndOutputYear(employeeId, outputYear);
|
||||
if (duplicate != null && !Objects.equals(duplicate.getId(), id)) {
|
||||
throw exception(EMPLOYEE_YEAR_LEADER_OUTPUT_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
private EmployeeYearLeaderOutputDO buildInitialOutput(EmployeeDO employee, Integer outputYear,
|
||||
BigDecimal leaderOutputAmount) {
|
||||
EmployeeYearLeaderOutputDO output = new EmployeeYearLeaderOutputDO();
|
||||
output.setEmployeeId(employee.getId());
|
||||
output.setEmployeeName(employee.getEmployeeName());
|
||||
output.setOutputYear(outputYear);
|
||||
output.setLeaderOutputAmount(leaderOutputAmount);
|
||||
output.setSortNo(employee.getSortNo() == null ? 0 : employee.getSortNo());
|
||||
output.setEnabledFlag(Boolean.TRUE);
|
||||
output.setRemark("");
|
||||
return output;
|
||||
}
|
||||
|
||||
private BigDecimal amount(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
|
||||
: value.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,22 +104,24 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
BigDecimal majorExpectedPerformance = calculateMajorExpectedPerformance(majorPlanningList);
|
||||
BigDecimal contractAmount = amount(project.getContractAmount());
|
||||
BigDecimal finalSettlementAmount = amount(project.getFinalSettlementAmount());
|
||||
BigDecimal effectiveSettlementAmount = finalSettlementAmount.compareTo(BigDecimal.ZERO) > 0
|
||||
? finalSettlementAmount : contractAmount;
|
||||
BigDecimal innovationOutputRate = project.getInnovationOutputRate() == null
|
||||
? DEFAULT_INNOVATION_OUTPUT_RATE : ratio(project.getInnovationOutputRate());
|
||||
BigDecimal innovationOutputValue = contractAmount.compareTo(BigDecimal.ZERO) <= 0
|
||||
? ZERO_AMOUNT
|
||||
: contractAmount.multiply(innovationOutputRate).setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal otherCost = amount(project.getOtherCost());
|
||||
BigDecimal profitLossValue = finalSettlementAmount
|
||||
BigDecimal profitLossValue = effectiveSettlementAmount
|
||||
.subtract(comprehensivePlanningAmount)
|
||||
.subtract(subcontractPlanningAmount)
|
||||
.subtract(majorExpectedPerformance)
|
||||
.subtract(innovationOutputValue)
|
||||
.subtract(otherCost)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal profitLossRate = finalSettlementAmount.compareTo(BigDecimal.ZERO) == 0
|
||||
BigDecimal profitLossRate = effectiveSettlementAmount.compareTo(BigDecimal.ZERO) == 0
|
||||
? ZERO_RATIO
|
||||
: profitLossValue.divide(finalSettlementAmount, 4, RoundingMode.HALF_UP);
|
||||
: profitLossValue.divide(effectiveSettlementAmount, 4, RoundingMode.HALF_UP);
|
||||
|
||||
ProjectProfitRespVO respVO = new ProjectProfitRespVO();
|
||||
respVO.setProjectId(project.getId());
|
||||
@@ -128,6 +130,7 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
respVO.setContractSignedFlag(project.getContractSignedFlag());
|
||||
respVO.setContractAmount(contractAmount);
|
||||
respVO.setFinalSettlementAmount(finalSettlementAmount);
|
||||
respVO.setEffectiveSettlementAmount(effectiveSettlementAmount);
|
||||
respVO.setComprehensivePlanningAmount(comprehensivePlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setSubcontractPlanningAmount(subcontractPlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setMajorOutputValue(majorOutputValue.setScale(2, RoundingMode.HALF_UP));
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.report;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.EmployeeOutputSummaryExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectBudgetExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectLeadQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectOverviewExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.SpecialtyPersonOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@@ -25,9 +20,15 @@ public interface ProjectOutputReportService {
|
||||
void exportSpecialtyPersonOutputExcel(HttpServletResponse response, SpecialtyPersonOutputExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
SpecialtyPersonOutputPreviewRespVO getSpecialtyPersonOutputPreview(SpecialtyPersonOutputPreviewReqVO reqVO);
|
||||
|
||||
ProjectOverviewPreviewRespVO getProjectOverviewPreview(ProjectOverviewExportReqVO reqVO);
|
||||
|
||||
void exportProjectOverviewExcel(HttpServletResponse response, ProjectOverviewExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
EmployeeOutputSummaryPreviewRespVO getEmployeeOutputSummaryPreview(EmployeeOutputSummaryExportReqVO reqVO);
|
||||
|
||||
void exportEmployeeOutputSummaryExcel(HttpServletResponse response, EmployeeOutputSummaryExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.Speci
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearcostbudget.EmployeeYearCostBudgetDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput.EmployeeYearLeaderOutputDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.office.OfficeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.outputsplit.ProjectOutputSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
@@ -13,14 +14,17 @@ import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningguidedetail.ProjectPl
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.project.ProjectDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.projectroleperson.ProjectRolePersonDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson.SpecialtyRoleSplitPersonDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.yearkvalue.YearKValueDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearcostbudget.EmployeeYearCostBudgetMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput.EmployeeYearLeaderOutputMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.office.OfficeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planningquarter.ProjectPlanningQuarterMapper;
|
||||
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.specialtyrolesplitperson.SpecialtyRoleSplitPersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.yearkvalue.YearKValueMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants;
|
||||
@@ -69,12 +73,16 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
@Resource
|
||||
private ProjectRolePersonMapper projectRolePersonMapper;
|
||||
@Resource
|
||||
private SpecialtyRoleSplitPersonMapper specialtyRoleSplitPersonMapper;
|
||||
@Resource
|
||||
private EmployeeMapper employeeMapper;
|
||||
@Resource
|
||||
private OfficeMapper officeMapper;
|
||||
@Resource
|
||||
private EmployeeYearCostBudgetMapper employeeYearCostBudgetMapper;
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputMapper employeeYearLeaderOutputMapper;
|
||||
@Resource
|
||||
private YearKValueMapper yearKValueMapper;
|
||||
@Resource
|
||||
private ProjectOutputSplitService projectOutputSplitService;
|
||||
@@ -247,6 +255,260 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
@Override
|
||||
public void exportSpecialtyPersonOutputExcel(HttpServletResponse response,
|
||||
SpecialtyPersonOutputExportReqVO reqVO) throws IOException {
|
||||
SpecialtyPersonOutputBuildResult result = buildSpecialtyPersonOutputData(reqVO);
|
||||
SpecialtyPersonOutputExcelBuilder.ExportData data = result.getData();
|
||||
|
||||
specialtyPersonOutputExcelBuilder.writeWorkbook(response,
|
||||
buildFileName(result.getProject().getProjectName(), result.getReportYear(),
|
||||
data.getSpecialtyName() + "专业内人员年度季度计取表"),
|
||||
specialtyPersonOutputExcelBuilder.build(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpecialtyPersonOutputPreviewRespVO getSpecialtyPersonOutputPreview(SpecialtyPersonOutputPreviewReqVO reqVO) {
|
||||
ProjectPlanningDO anchorPlanning = validatePlanningExists(reqVO.getPlanningId());
|
||||
ProjectDO project = validateProjectExists(anchorPlanning.getProjectId());
|
||||
Integer reportYear = resolveExportYear(reqVO.getYear());
|
||||
List<ProjectPlanningDO> planningList = sortPlanningList(projectPlanningMapper.selectListByProjectId(project.getId()));
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(planningList);
|
||||
List<ProjectPlanningDO> relevantPlanningList = planningList.stream()
|
||||
.filter(item -> hasYearAmount(quarterMap.get(item.getId()), reportYear))
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap = getOutputSplitMap(relevantPlanningList);
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap = getRoleSplitMap(relevantPlanningList);
|
||||
List<SpecialtyRoleSplitRespVO> anchorRoleList =
|
||||
specialtyRoleSplitService.getSpecialtyRoleSplitListByPlanningId(anchorPlanning.getId());
|
||||
|
||||
SpecialtyPersonOutputPreviewRespVO respVO = new SpecialtyPersonOutputPreviewRespVO();
|
||||
respVO.setPlanningId(anchorPlanning.getId());
|
||||
respVO.setYear(reportYear);
|
||||
respVO.setProjectName(project.getProjectName());
|
||||
respVO.setGroups(buildSpecialtyPersonPreviewGroups(anchorRoleList, relevantPlanningList, quarterMap,
|
||||
outputSplitMap, roleSplitMap, reportYear));
|
||||
return respVO;
|
||||
}
|
||||
|
||||
private List<SpecialtyPersonOutputPreviewRespVO.GroupRow> buildSpecialtyPersonPreviewGroups(
|
||||
List<SpecialtyRoleSplitRespVO> anchorRoleList,
|
||||
List<ProjectPlanningDO> relevantPlanningList,
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap,
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap,
|
||||
Integer reportYear) {
|
||||
if (anchorRoleList == null || anchorRoleList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<String, List<SpecialtyRoleSplitRespVO>> groupMap = anchorRoleList.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.groupingBy(SpecialtyRoleSplitRespVO::getSpecialtyCode,
|
||||
LinkedHashMap::new, Collectors.toList()));
|
||||
List<SpecialtyPersonOutputPreviewRespVO.GroupRow> groups = new ArrayList<>();
|
||||
for (Map.Entry<String, List<SpecialtyRoleSplitRespVO>> entry : groupMap.entrySet()) {
|
||||
String specialtyCode = entry.getKey();
|
||||
if (!isSpecialtyPersonExportable(specialtyCode)) {
|
||||
continue;
|
||||
}
|
||||
List<SpecialtyRoleSplitRespVO> roleRows = entry.getValue().stream()
|
||||
.sorted(Comparator.comparing(SpecialtyRoleSplitRespVO::getSortNo,
|
||||
Comparator.nullsLast(Integer::compareTo)))
|
||||
.collect(Collectors.toList());
|
||||
SpecialtyQuarterPreviewAggregate aggregate = buildSpecialtyQuarterPreviewAggregate(relevantPlanningList,
|
||||
quarterMap, outputSplitMap, roleSplitMap, specialtyCode, reportYear);
|
||||
|
||||
SpecialtyPersonOutputPreviewRespVO.GroupRow group = new SpecialtyPersonOutputPreviewRespVO.GroupRow();
|
||||
group.setSpecialtyCode(specialtyCode);
|
||||
group.setSpecialtyName(resolveSpecialtyName(roleRows, specialtyCode));
|
||||
group.setExportable(Boolean.TRUE);
|
||||
group.setSpecialtyAmount(amount(roleRows.isEmpty() ? null : roleRows.get(0).getSpecialtyAmount()));
|
||||
group.setRoleTotal(sumRoleRatio(roleRows));
|
||||
group.setPersonCount(countPreviewPersons(roleRows));
|
||||
group.setOverRatio(group.getRoleTotal().compareTo(FULL_RATIO) > 0);
|
||||
group.setSpecialtyQuarterOneAmountWan(aggregate.getSpecialtyQuarterOneAmountWan());
|
||||
group.setSpecialtyQuarterTwoAmountWan(aggregate.getSpecialtyQuarterTwoAmountWan());
|
||||
group.setSpecialtyQuarterThreeAmountWan(aggregate.getSpecialtyQuarterThreeAmountWan());
|
||||
group.setSpecialtyQuarterFourAmountWan(aggregate.getSpecialtyQuarterFourAmountWan());
|
||||
group.setSpecialtyYearTotalAmountWan(aggregate.getSpecialtyYearTotalAmountWan());
|
||||
group.setRows(buildSpecialtyPreviewRoleRows(roleRows, aggregate));
|
||||
groups.add(group);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
private SpecialtyQuarterPreviewAggregate buildSpecialtyQuarterPreviewAggregate(
|
||||
List<ProjectPlanningDO> relevantPlanningList,
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap,
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap,
|
||||
String specialtyCode,
|
||||
Integer reportYear) {
|
||||
SpecialtyQuarterPreviewAggregate aggregate = new SpecialtyQuarterPreviewAggregate();
|
||||
if (relevantPlanningList == null || relevantPlanningList.isEmpty()) {
|
||||
return aggregate;
|
||||
}
|
||||
for (ProjectPlanningDO planning : relevantPlanningList) {
|
||||
QuarterSummary quarterSummary = buildQuarterSummary(planning, quarterMap.get(planning.getId()), reportYear);
|
||||
ProjectOutputSplitDO outputSplit = outputSplitMap.get(planning.getId());
|
||||
BigDecimal specialtyRatio = getSpecialtyRatio(outputSplit, specialtyCode);
|
||||
BigDecimal officeRatio = outputSplit == null ? ZERO_RATIO : ratio(outputSplit.getOfficeRatio());
|
||||
BigDecimal specialtyBaseRatio = multiplyRatio(officeRatio, specialtyRatio);
|
||||
|
||||
aggregate.setSpecialtyQuarterOneAmountWan(addAmountValue(aggregate.getSpecialtyQuarterOneAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterOneAmount(), specialtyBaseRatio))));
|
||||
aggregate.setSpecialtyQuarterTwoAmountWan(addAmountValue(aggregate.getSpecialtyQuarterTwoAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterTwoAmount(), specialtyBaseRatio))));
|
||||
aggregate.setSpecialtyQuarterThreeAmountWan(addAmountValue(aggregate.getSpecialtyQuarterThreeAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterThreeAmount(), specialtyBaseRatio))));
|
||||
aggregate.setSpecialtyQuarterFourAmountWan(addAmountValue(aggregate.getSpecialtyQuarterFourAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterFourAmount(), specialtyBaseRatio))));
|
||||
aggregate.setSpecialtyYearTotalAmountWan(addAmountValue(aggregate.getSpecialtyYearTotalAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getYearTotalAmount(), specialtyBaseRatio))));
|
||||
|
||||
List<SpecialtyRoleSplitRespVO> specialtyRoleRows = (roleSplitMap == null ? Collections.<SpecialtyRoleSplitRespVO>emptyList()
|
||||
: roleSplitMap.getOrDefault(planning.getId(), Collections.emptyList()))
|
||||
.stream()
|
||||
.filter(item -> Objects.equals(item.getSpecialtyCode(), specialtyCode))
|
||||
.collect(Collectors.toList());
|
||||
for (SpecialtyRoleSplitRespVO roleRow : specialtyRoleRows) {
|
||||
if (roleRow.getPersons() == null || roleRow.getPersons().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
BigDecimal roleRatio = ratio(roleRow.getRoleRatio());
|
||||
for (SpecialtyRolePersonRespVO person : roleRow.getPersons()) {
|
||||
if (!isValidSpecialtyRolePerson(person)) {
|
||||
continue;
|
||||
}
|
||||
BigDecimal personRatio = ratio(person.getPersonRatio());
|
||||
BigDecimal amountRatio = multiplyRatio(specialtyBaseRatio, roleRatio, personRatio);
|
||||
String rolePersonKey = buildSpecialtyRolePersonModuleKey(roleRow.getRoleCode(),
|
||||
person.getEmployeeId(), person.getEmployeeName());
|
||||
SpecialtyPersonOutputExcelBuilder.PersonAmountValue value = aggregate.getRolePersonAmountMap()
|
||||
.computeIfAbsent(rolePersonKey, key -> new SpecialtyPersonOutputExcelBuilder.PersonAmountValue());
|
||||
accumulateSpecialtyPersonAmount(value, quarterSummary, amountRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
return aggregate;
|
||||
}
|
||||
|
||||
private List<SpecialtyPersonOutputPreviewRespVO.RoleRow> buildSpecialtyPreviewRoleRows(
|
||||
List<SpecialtyRoleSplitRespVO> roleRows,
|
||||
SpecialtyQuarterPreviewAggregate aggregate) {
|
||||
List<SpecialtyPersonOutputPreviewRespVO.RoleRow> result = new ArrayList<>();
|
||||
for (SpecialtyRoleSplitRespVO roleRow : roleRows) {
|
||||
SpecialtyPersonOutputPreviewRespVO.RoleRow row = new SpecialtyPersonOutputPreviewRespVO.RoleRow();
|
||||
row.setSpecialtyCode(roleRow.getSpecialtyCode());
|
||||
row.setSpecialtyName(roleRow.getSpecialtyName());
|
||||
row.setRoleCode(roleRow.getRoleCode());
|
||||
row.setRoleName(roleRow.getRoleName());
|
||||
row.setRoleRatio(ratio(roleRow.getRoleRatio()));
|
||||
row.setRoleAmount(amount(roleRow.getRoleAmount()));
|
||||
row.setPersonTotalRatio(sumPersonRatio(roleRow.getPersons()));
|
||||
row.setPersons(buildSpecialtyPreviewPersons(roleRow, aggregate));
|
||||
result.add(row);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SpecialtyPersonOutputPreviewRespVO.PersonRow> buildSpecialtyPreviewPersons(
|
||||
SpecialtyRoleSplitRespVO roleRow,
|
||||
SpecialtyQuarterPreviewAggregate aggregate) {
|
||||
if (roleRow.getPersons() == null || roleRow.getPersons().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<SpecialtyPersonOutputPreviewRespVO.PersonRow> result = new ArrayList<>();
|
||||
BigDecimal roleRatio = ratio(roleRow.getRoleRatio());
|
||||
for (SpecialtyRolePersonRespVO person : roleRow.getPersons()) {
|
||||
if (!isValidSpecialtyRolePerson(person)) {
|
||||
continue;
|
||||
}
|
||||
BigDecimal personRatio = ratio(person.getPersonRatio());
|
||||
String personKey = buildSpecialtyPersonModuleKey(person.getEmployeeId(), person.getEmployeeName());
|
||||
String rolePersonKey = buildSpecialtyRolePersonModuleKey(roleRow.getRoleCode(),
|
||||
person.getEmployeeId(), person.getEmployeeName());
|
||||
SpecialtyPersonOutputExcelBuilder.PersonAmountValue value =
|
||||
aggregate.getRolePersonAmountMap().get(rolePersonKey);
|
||||
SpecialtyPersonOutputPreviewRespVO.PersonRow row = new SpecialtyPersonOutputPreviewRespVO.PersonRow();
|
||||
row.setPersonKey(personKey);
|
||||
row.setEmployeeId(person.getEmployeeId());
|
||||
row.setEmployeeName(defaultString(person.getEmployeeName()));
|
||||
row.setPersonRatio(personRatio);
|
||||
row.setPersonAmount(amount(person.getPersonAmount()));
|
||||
row.setRoleNames(defaultString(roleRow.getRoleName()));
|
||||
row.setAdjustedPersonRatio(multiplyRatio(roleRatio, personRatio));
|
||||
row.setQuarterOneRatio(value == null ? ZERO_RATIO : ratio(value.getQuarterOneRatio()));
|
||||
row.setQuarterOneAmountWan(value == null ? ZERO_AMOUNT : amount(value.getQuarterOneAmountWan()));
|
||||
row.setQuarterTwoRatio(value == null ? ZERO_RATIO : ratio(value.getQuarterTwoRatio()));
|
||||
row.setQuarterTwoAmountWan(value == null ? ZERO_AMOUNT : amount(value.getQuarterTwoAmountWan()));
|
||||
row.setQuarterThreeRatio(value == null ? ZERO_RATIO : ratio(value.getQuarterThreeRatio()));
|
||||
row.setQuarterThreeAmountWan(value == null ? ZERO_AMOUNT : amount(value.getQuarterThreeAmountWan()));
|
||||
row.setQuarterFourRatio(value == null ? ZERO_RATIO : ratio(value.getQuarterFourRatio()));
|
||||
row.setQuarterFourAmountWan(value == null ? ZERO_AMOUNT : amount(value.getQuarterFourAmountWan()));
|
||||
row.setYearTotalRatio(value == null ? ZERO_RATIO : ratio(value.getYearTotalRatio()));
|
||||
row.setYearTotalAmountWan(value == null ? ZERO_AMOUNT : amount(value.getYearTotalAmountWan()));
|
||||
result.add(row);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isSpecialtyPersonExportable(String specialtyCode) {
|
||||
return OutputSplitBizConstants.isValidSpecialtyCode(specialtyCode)
|
||||
&& !OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyCode);
|
||||
}
|
||||
|
||||
private String resolveSpecialtyName(List<SpecialtyRoleSplitRespVO> rows, String specialtyCode) {
|
||||
if (rows != null) {
|
||||
for (SpecialtyRoleSplitRespVO row : rows) {
|
||||
if (row != null && !defaultString(row.getSpecialtyName()).isEmpty()) {
|
||||
return defaultString(row.getSpecialtyName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return OutputSplitBizConstants.getSpecialtyName(specialtyCode);
|
||||
}
|
||||
|
||||
private BigDecimal sumRoleRatio(List<SpecialtyRoleSplitRespVO> roleRows) {
|
||||
BigDecimal total = ZERO_RATIO;
|
||||
if (roleRows == null) {
|
||||
return total;
|
||||
}
|
||||
for (SpecialtyRoleSplitRespVO row : roleRows) {
|
||||
total = addRatio(total, row.getRoleRatio());
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private BigDecimal sumPersonRatio(List<SpecialtyRolePersonRespVO> persons) {
|
||||
BigDecimal total = ZERO_RATIO;
|
||||
if (persons == null) {
|
||||
return total;
|
||||
}
|
||||
for (SpecialtyRolePersonRespVO person : persons) {
|
||||
if (isValidSpecialtyRolePerson(person)) {
|
||||
total = addRatio(total, person.getPersonRatio());
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private int countPreviewPersons(List<SpecialtyRoleSplitRespVO> roleRows) {
|
||||
if (roleRows == null) {
|
||||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
for (SpecialtyRoleSplitRespVO row : roleRows) {
|
||||
if (row.getPersons() == null) {
|
||||
continue;
|
||||
}
|
||||
for (SpecialtyRolePersonRespVO person : row.getPersons()) {
|
||||
if (isValidSpecialtyRolePerson(person)) {
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private SpecialtyPersonOutputBuildResult buildSpecialtyPersonOutputData(SpecialtyPersonOutputExportReqVO reqVO) {
|
||||
validateSpecialtyCode(reqVO.getSpecialtyCode());
|
||||
ProjectPlanningDO anchorPlanning = validatePlanningExists(reqVO.getPlanningId());
|
||||
ProjectDO project = validateProjectExists(anchorPlanning.getProjectId());
|
||||
@@ -288,7 +550,6 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
data.setEngineeringPrincipalRatio(engineeringPrincipalRow == null
|
||||
? ZERO_RATIO : ratio(engineeringPrincipalRow.getRoleRatio()));
|
||||
data.setYear(reportYear);
|
||||
|
||||
data.setCenterSignerLabel("设计中心相关负责人(签名):");
|
||||
data.setProjectSignerLabel("项目经理 / 工程负责人(签名):");
|
||||
data.setRolePersonModules(buildSpecialtyRolePersonModules(relevantPlanningList, roleSplitMap, reqVO.getSpecialtyCode()));
|
||||
@@ -296,14 +557,29 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
data.setRows(buildSpecialtyPlanningRows(relevantPlanningList, quarterMap, outputSplitMap,
|
||||
roleSplitMap, project.getProjectName(), reqVO.getSpecialtyCode(), reportYear));
|
||||
|
||||
specialtyPersonOutputExcelBuilder.writeWorkbook(response,
|
||||
buildFileName(project.getProjectName(), reportYear, data.getSpecialtyName() + "专业内人员年度季度计取表"),
|
||||
specialtyPersonOutputExcelBuilder.build(data));
|
||||
SpecialtyPersonOutputBuildResult result = new SpecialtyPersonOutputBuildResult();
|
||||
result.setAnchorPlanning(anchorPlanning);
|
||||
result.setProject(project);
|
||||
result.setReportYear(reportYear);
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectOverviewPreviewRespVO getProjectOverviewPreview(ProjectOverviewExportReqVO reqVO) {
|
||||
return buildProjectOverviewPreviewResp(buildProjectOverviewExportData(reqVO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportProjectOverviewExcel(HttpServletResponse response, ProjectOverviewExportReqVO reqVO)
|
||||
throws IOException {
|
||||
ProjectOverviewOutputExcelBuilder.ExportData data = buildProjectOverviewExportData(reqVO);
|
||||
projectOverviewOutputExcelBuilder.writeWorkbook(response,
|
||||
buildFileName(data.getOfficeName(), data.getYear(), "项目总览表"),
|
||||
projectOverviewOutputExcelBuilder.build(data));
|
||||
}
|
||||
|
||||
private ProjectOverviewOutputExcelBuilder.ExportData buildProjectOverviewExportData(ProjectOverviewExportReqVO reqVO) {
|
||||
Integer reportYear = resolveExportYear(reqVO.getYear());
|
||||
OfficeDO office = validateOfficeExists(reqVO.getOfficeId());
|
||||
List<EmployeeDO> employeeList = employeeMapper.selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
@@ -318,16 +594,14 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
Set<Long> employeeIds = employeeList.stream()
|
||||
.map(EmployeeDO::getId)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
List<ProjectPlanningDO> majorPlanningList = projectPlanningMapper.selectList(
|
||||
new LambdaQueryWrapperX<ProjectPlanningDO>()
|
||||
.eq(ProjectPlanningDO::getOwnershipType, ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_MAJOR));
|
||||
Map<Long, ProjectDO> projectMap = getProjectMap(majorPlanningList);
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(majorPlanningList);
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap = getOutputSplitMap(majorPlanningList);
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap = getRoleSplitMap(majorPlanningList);
|
||||
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, ProjectOverviewAccumulator> accumulatorMap = new LinkedHashMap<>();
|
||||
for (ProjectPlanningDO planning : majorPlanningList) {
|
||||
for (ProjectPlanningDO planning : planningList) {
|
||||
QuarterSummary quarterSummary = buildQuarterSummary(planning, quarterMap.get(planning.getId()), reportYear);
|
||||
if (quarterSummary.getYearTotalAmount().compareTo(ZERO_AMOUNT) <= 0) {
|
||||
continue;
|
||||
@@ -360,14 +634,25 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
data.setRows(rows);
|
||||
data.setTotalRow(buildProjectOverviewTotalRow(new ArrayList<>(accumulatorMap.values()), employeeList));
|
||||
|
||||
projectOverviewOutputExcelBuilder.writeWorkbook(response,
|
||||
buildFileName(office.getOfficeName(), reportYear, "项目总览表"),
|
||||
projectOverviewOutputExcelBuilder.build(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeOutputSummaryPreviewRespVO getEmployeeOutputSummaryPreview(EmployeeOutputSummaryExportReqVO reqVO) {
|
||||
return buildEmployeeOutputSummaryPreviewResp(buildEmployeeOutputSummaryExportData(reqVO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportEmployeeOutputSummaryExcel(HttpServletResponse response,
|
||||
EmployeeOutputSummaryExportReqVO reqVO) throws IOException {
|
||||
EmployeeOutputSummaryExcelBuilder.ExportData data = buildEmployeeOutputSummaryExportData(reqVO);
|
||||
employeeOutputSummaryExcelBuilder.writeWorkbook(response,
|
||||
buildFileName("员工个人考核产值", reqVO.getYear(), "汇总表"),
|
||||
employeeOutputSummaryExcelBuilder.build(data));
|
||||
}
|
||||
|
||||
private EmployeeOutputSummaryExcelBuilder.ExportData buildEmployeeOutputSummaryExportData(
|
||||
EmployeeOutputSummaryExportReqVO reqVO) {
|
||||
YearKValueDO yearKValue = yearKValueMapper.selectEnabledByKYear(reqVO.getYear());
|
||||
BigDecimal kValue = yearKValue == null ? DEFAULT_K_VALUE : ratio(yearKValue.getKValue());
|
||||
List<EmployeeDO> employeeList = employeeMapper.selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
@@ -382,23 +667,13 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
data.setYear(reqVO.getYear());
|
||||
data.setKValue(kValue);
|
||||
data.setRows(Collections.emptyList());
|
||||
employeeOutputSummaryExcelBuilder.writeWorkbook(response,
|
||||
buildFileName("员工个人考核产值", reqVO.getYear(), "汇总表"),
|
||||
employeeOutputSummaryExcelBuilder.build(data));
|
||||
return;
|
||||
return data;
|
||||
}
|
||||
|
||||
Set<Long> employeeIds = employeeList.stream().map(EmployeeDO::getId).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
|
||||
List<ProjectPlanningDO> majorPlanningList = projectPlanningMapper.selectList(
|
||||
new LambdaQueryWrapperX<ProjectPlanningDO>()
|
||||
.eq(ProjectPlanningDO::getOwnershipType, ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_MAJOR));
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(majorPlanningList);
|
||||
|
||||
List<ProjectPlanningDO> relevantPlanningList = majorPlanningList.stream()
|
||||
.filter(item -> hasYearAmount(quarterMap.get(item.getId()), reqVO.getYear()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<ProjectPlanningDO> relevantPlanningList = getEmployeeOutputSummaryPlanningList(reqVO.getYear(), employeeIds);
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(relevantPlanningList);
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap = getOutputSplitMap(relevantPlanningList);
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap = getRoleSplitMap(relevantPlanningList);
|
||||
Map<Long, EmployeeAccumulator> accumulatorMap = new LinkedHashMap<>();
|
||||
@@ -437,6 +712,10 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
.inIfPresent(EmployeeYearCostBudgetDO::getEmployeeId, employeeIds))
|
||||
.stream()
|
||||
.collect(Collectors.toMap(EmployeeYearCostBudgetDO::getEmployeeId, item -> item, (a, b) -> a));
|
||||
Map<Long, EmployeeYearLeaderOutputDO> leaderOutputMap = employeeYearLeaderOutputMapper
|
||||
.selectEnabledListByOutputYear(reqVO.getYear(), employeeIds)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(EmployeeYearLeaderOutputDO::getEmployeeId, item -> item, (a, b) -> a));
|
||||
|
||||
List<EmployeeOutputSummaryExcelRespVO> rows = new ArrayList<>();
|
||||
for (EmployeeDO employee : employeeList) {
|
||||
@@ -445,8 +724,9 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
accumulator = new EmployeeAccumulator();
|
||||
}
|
||||
EmployeeYearCostBudgetDO costBudget = costBudgetMap.get(employee.getId());
|
||||
EmployeeYearLeaderOutputDO leaderOutput = leaderOutputMap.get(employee.getId());
|
||||
BigDecimal expectedCostAmount = costBudget == null ? ZERO_AMOUNT : amount(costBudget.getExpectedCostAmount());
|
||||
BigDecimal officeLeaderOrBimAmount = ZERO_AMOUNT;
|
||||
BigDecimal officeLeaderOrBimAmount = leaderOutput == null ? ZERO_AMOUNT : amount(leaderOutput.getLeaderOutputAmount());
|
||||
BigDecimal annualTotalAmount = accumulator.getAnnualTotalAmount();
|
||||
BigDecimal totalAssessmentOutputAmount = annualTotalAmount.add(officeLeaderOrBimAmount)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
@@ -483,9 +763,129 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
data.setYear(reqVO.getYear());
|
||||
data.setKValue(kValue);
|
||||
data.setRows(rows);
|
||||
employeeOutputSummaryExcelBuilder.writeWorkbook(response,
|
||||
buildFileName("员工个人考核产值", reqVO.getYear(), "汇总表"),
|
||||
employeeOutputSummaryExcelBuilder.build(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
private ProjectOverviewPreviewRespVO buildProjectOverviewPreviewResp(
|
||||
ProjectOverviewOutputExcelBuilder.ExportData data) {
|
||||
ProjectOverviewPreviewRespVO respVO = new ProjectOverviewPreviewRespVO();
|
||||
respVO.setYear(data.getYear());
|
||||
respVO.setOfficeName(data.getOfficeName());
|
||||
respVO.setEmployeeColumns(data.getEmployeeColumns() == null
|
||||
? Collections.emptyList()
|
||||
: data.getEmployeeColumns().stream()
|
||||
.map(this::toProjectOverviewPreviewEmployeeColumn)
|
||||
.collect(Collectors.toList()));
|
||||
respVO.setRows(data.getRows() == null
|
||||
? Collections.emptyList()
|
||||
: data.getRows().stream()
|
||||
.map(row -> toProjectOverviewPreviewRow(row, false))
|
||||
.collect(Collectors.toList()));
|
||||
respVO.setTotalRow(toProjectOverviewPreviewRow(data.getTotalRow(), true));
|
||||
return respVO;
|
||||
}
|
||||
|
||||
private ProjectOverviewPreviewRespVO.EmployeeColumn toProjectOverviewPreviewEmployeeColumn(
|
||||
ProjectOverviewOutputExcelBuilder.EmployeeColumn column) {
|
||||
ProjectOverviewPreviewRespVO.EmployeeColumn previewColumn =
|
||||
new ProjectOverviewPreviewRespVO.EmployeeColumn();
|
||||
if (column == null) {
|
||||
return previewColumn;
|
||||
}
|
||||
previewColumn.setEmployeeId(column.getEmployeeId());
|
||||
previewColumn.setEmployeeName(column.getEmployeeName());
|
||||
return previewColumn;
|
||||
}
|
||||
|
||||
private ProjectOverviewPreviewRespVO.ProjectRow toProjectOverviewPreviewRow(
|
||||
ProjectOverviewOutputExcelBuilder.ProjectRow row, boolean totalRow) {
|
||||
ProjectOverviewPreviewRespVO.ProjectRow previewRow = new ProjectOverviewPreviewRespVO.ProjectRow();
|
||||
previewRow.setTotalRow(totalRow);
|
||||
if (row == null) {
|
||||
return previewRow;
|
||||
}
|
||||
previewRow.setSerialNo(row.getSerialNo());
|
||||
previewRow.setProjectName(totalRow ? "合计" : row.getProjectName());
|
||||
previewRow.setProgressText(row.getProgressText());
|
||||
previewRow.setWorkStage(row.getWorkStage());
|
||||
previewRow.setTotalOutputAmountWan(amountToWan(row.getTotalOutputAmount()));
|
||||
previewRow.setHistoricalIssuedRatio(row.getHistoricalIssuedRatio());
|
||||
previewRow.setCurrentSettlementRatio(row.getCurrentSettlementRatio());
|
||||
previewRow.setCurrentSettlementAmountWan(amountToWan(row.getCurrentSettlementAmount()));
|
||||
previewRow.setPendingRatio(row.getPendingRatio());
|
||||
Map<Long, ProjectOverviewPreviewRespVO.EmployeeAmountValue> employeeAmountMap = new LinkedHashMap<>();
|
||||
if (row.getEmployeeAmountMap() != null) {
|
||||
row.getEmployeeAmountMap().forEach((employeeId, value) ->
|
||||
employeeAmountMap.put(employeeId, toProjectOverviewPreviewEmployeeAmount(value)));
|
||||
}
|
||||
previewRow.setEmployeeAmountMap(employeeAmountMap);
|
||||
return previewRow;
|
||||
}
|
||||
|
||||
private ProjectOverviewPreviewRespVO.EmployeeAmountValue toProjectOverviewPreviewEmployeeAmount(
|
||||
ProjectOverviewOutputExcelBuilder.EmployeeAmountValue value) {
|
||||
ProjectOverviewPreviewRespVO.EmployeeAmountValue previewValue =
|
||||
new ProjectOverviewPreviewRespVO.EmployeeAmountValue();
|
||||
if (value == null) {
|
||||
return previewValue;
|
||||
}
|
||||
previewValue.setQuarterOneAmountWan(amountToWan(value.getQuarterOneAmount()));
|
||||
previewValue.setQuarterTwoAmountWan(amountToWan(value.getQuarterTwoAmount()));
|
||||
previewValue.setQuarterThreeAmountWan(amountToWan(value.getQuarterThreeAmount()));
|
||||
previewValue.setQuarterFourAmountWan(amountToWan(value.getQuarterFourAmount()));
|
||||
previewValue.setAnnualTotalAmountWan(amountToWan(value.getAnnualTotalAmount()));
|
||||
return previewValue;
|
||||
}
|
||||
|
||||
private EmployeeOutputSummaryPreviewRespVO buildEmployeeOutputSummaryPreviewResp(
|
||||
EmployeeOutputSummaryExcelBuilder.ExportData data) {
|
||||
EmployeeOutputSummaryPreviewRespVO respVO = new EmployeeOutputSummaryPreviewRespVO();
|
||||
respVO.setYear(data.getYear());
|
||||
respVO.setKValue(data.getKValue());
|
||||
List<EmployeeOutputSummaryExcelRespVO> rows = data.getRows() == null
|
||||
? Collections.emptyList() : data.getRows();
|
||||
respVO.setRows(rows);
|
||||
respVO.setTotalRow(buildEmployeeOutputSummaryTotalRow(rows));
|
||||
return respVO;
|
||||
}
|
||||
|
||||
private EmployeeOutputSummaryExcelRespVO buildEmployeeOutputSummaryTotalRow(
|
||||
List<EmployeeOutputSummaryExcelRespVO> rows) {
|
||||
EmployeeOutputSummaryExcelRespVO totalRow = new EmployeeOutputSummaryExcelRespVO();
|
||||
totalRow.setEmployeeName("合计");
|
||||
totalRow.setQuarterOneAmount(ZERO_AMOUNT);
|
||||
totalRow.setQuarterTwoAmount(ZERO_AMOUNT);
|
||||
totalRow.setQuarterThreeAmount(ZERO_AMOUNT);
|
||||
totalRow.setQuarterFourAmount(ZERO_AMOUNT);
|
||||
totalRow.setAnnualTotalAmount(ZERO_AMOUNT);
|
||||
totalRow.setOfficeLeaderOrBimAmount(ZERO_AMOUNT);
|
||||
totalRow.setTotalAssessmentOutputAmount(ZERO_AMOUNT);
|
||||
totalRow.setExpectedCostAmount(ZERO_AMOUNT);
|
||||
totalRow.setBasicAssessmentOutputAmount(ZERO_AMOUNT);
|
||||
totalRow.setRemainingOutputAmount(ZERO_AMOUNT);
|
||||
totalRow.setEstimatedYearEndPerformanceAmount(ZERO_AMOUNT);
|
||||
if (rows == null) {
|
||||
return totalRow;
|
||||
}
|
||||
for (EmployeeOutputSummaryExcelRespVO row : rows) {
|
||||
totalRow.setQuarterOneAmount(addAmountValue(totalRow.getQuarterOneAmount(), row.getQuarterOneAmount()));
|
||||
totalRow.setQuarterTwoAmount(addAmountValue(totalRow.getQuarterTwoAmount(), row.getQuarterTwoAmount()));
|
||||
totalRow.setQuarterThreeAmount(addAmountValue(totalRow.getQuarterThreeAmount(), row.getQuarterThreeAmount()));
|
||||
totalRow.setQuarterFourAmount(addAmountValue(totalRow.getQuarterFourAmount(), row.getQuarterFourAmount()));
|
||||
totalRow.setAnnualTotalAmount(addAmountValue(totalRow.getAnnualTotalAmount(), row.getAnnualTotalAmount()));
|
||||
totalRow.setOfficeLeaderOrBimAmount(addAmountValue(
|
||||
totalRow.getOfficeLeaderOrBimAmount(), row.getOfficeLeaderOrBimAmount()));
|
||||
totalRow.setTotalAssessmentOutputAmount(addAmountValue(
|
||||
totalRow.getTotalAssessmentOutputAmount(), row.getTotalAssessmentOutputAmount()));
|
||||
totalRow.setExpectedCostAmount(addAmountValue(totalRow.getExpectedCostAmount(), row.getExpectedCostAmount()));
|
||||
totalRow.setBasicAssessmentOutputAmount(addAmountValue(
|
||||
totalRow.getBasicAssessmentOutputAmount(), row.getBasicAssessmentOutputAmount()));
|
||||
totalRow.setRemainingOutputAmount(addAmountValue(
|
||||
totalRow.getRemainingOutputAmount(), row.getRemainingOutputAmount()));
|
||||
totalRow.setEstimatedYearEndPerformanceAmount(addAmountValue(
|
||||
totalRow.getEstimatedYearEndPerformanceAmount(), row.getEstimatedYearEndPerformanceAmount()));
|
||||
}
|
||||
return totalRow;
|
||||
}
|
||||
|
||||
private ProjectPlanningDO validatePlanningExists(Long planningId) {
|
||||
@@ -528,6 +928,96 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ProjectPlanningDO> getAssignablePlanningList() {
|
||||
return projectPlanningMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningDO>()
|
||||
.in(ProjectPlanningDO::getOwnershipType, Arrays.asList(
|
||||
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_MAJOR,
|
||||
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_COMPREHENSIVE,
|
||||
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_SUBCONTRACT
|
||||
)));
|
||||
}
|
||||
|
||||
private List<ProjectPlanningDO> getProjectOverviewPlanningList(Integer reportYear, Set<Long> employeeIds) {
|
||||
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()
|
||||
.map(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (matchedPlanningIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return sortPlanningList(projectPlanningMapper.selectBatchIds(matchedPlanningIds).stream()
|
||||
.filter(item -> item != null && ProjectPlanningBizTypeConstants.isValidOwnershipType(item.getOwnershipType()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private List<ProjectPlanningDO> getEmployeeOutputSummaryPlanningList(Integer reportYear, Set<Long> employeeIds) {
|
||||
if (reportYear == null || employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Set<Long> yearPlanningIds = getYearAmountPlanningIds(reportYear);
|
||||
if (yearPlanningIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Set<Long> matchedPlanningIds = specialtyRoleSplitPersonMapper
|
||||
.selectListByPlanningIdsAndEmployeeIds(yearPlanningIds, employeeIds)
|
||||
.stream()
|
||||
.map(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
|
||||
Set<Long> projectIds = projectRolePersonMapper.selectListByEmployeeIds(employeeIds)
|
||||
.stream()
|
||||
.map(ProjectRolePersonDO::getProjectId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (!projectIds.isEmpty()) {
|
||||
projectPlanningMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningDO>()
|
||||
.in(ProjectPlanningDO::getId, yearPlanningIds)
|
||||
.in(ProjectPlanningDO::getProjectId, projectIds)
|
||||
.in(ProjectPlanningDO::getOwnershipType, Arrays.asList(
|
||||
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_MAJOR,
|
||||
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_COMPREHENSIVE,
|
||||
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_SUBCONTRACT
|
||||
)))
|
||||
.stream()
|
||||
.map(ProjectPlanningDO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(matchedPlanningIds::add);
|
||||
}
|
||||
if (matchedPlanningIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return sortPlanningList(projectPlanningMapper.selectBatchIds(matchedPlanningIds).stream()
|
||||
.filter(item -> item != null && ProjectPlanningBizTypeConstants.isValidOwnershipType(item.getOwnershipType()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private Set<Long> getYearAmountPlanningIds(Integer reportYear) {
|
||||
if (reportYear == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return projectPlanningQuarterMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getDistributionYear, reportYear)
|
||||
.gt(ProjectPlanningQuarterDO::getDistributionAmount, BigDecimal.ZERO))
|
||||
.stream()
|
||||
.map(ProjectPlanningQuarterDO::getPlanningId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
|
||||
private List<ProjectQuarterOutputExcelBuilder.QuarterRow> buildProjectQuarterOutputRows(
|
||||
List<ProjectPlanningDO> planningList, Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap, Integer reportYear) {
|
||||
@@ -1021,9 +1511,8 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
outputSplit.setYear(resolveReportYear(planning));
|
||||
}
|
||||
outputSplit.setProjectLeadRatio(ZERO_RATIO);
|
||||
boolean majorPlanning = planning != null && ProjectPlanningBizTypeConstants.isMajor(planning.getOwnershipType());
|
||||
outputSplit.setOfficeRatio(majorPlanning ? FULL_RATIO : ZERO_RATIO);
|
||||
outputSplit.setArchRatio(majorPlanning ? FULL_RATIO : ZERO_RATIO);
|
||||
outputSplit.setOfficeRatio(FULL_RATIO);
|
||||
outputSplit.setArchRatio(FULL_RATIO);
|
||||
outputSplit.setDecorRatio(ZERO_RATIO);
|
||||
outputSplit.setStructRatio(ZERO_RATIO);
|
||||
outputSplit.setWaterRatio(ZERO_RATIO);
|
||||
@@ -1101,11 +1590,11 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
if (planningList == null || planningList.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> map = new LinkedHashMap<>();
|
||||
for (ProjectPlanningDO planning : planningList) {
|
||||
map.put(planning.getId(), specialtyRoleSplitService.getSpecialtyRoleSplitListByPlanningId(planning.getId()));
|
||||
}
|
||||
return map;
|
||||
List<Long> planningIds = planningList.stream()
|
||||
.map(ProjectPlanningDO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
return specialtyRoleSplitService.getSpecialtyRoleSplitListMapByPlanningIds(planningIds);
|
||||
}
|
||||
|
||||
private Map<Long, ProjectDO> getProjectMap(Collection<ProjectPlanningDO> planningList) {
|
||||
@@ -1492,14 +1981,24 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
private void accumulateSpecialtyPersonAmount(SpecialtyPersonOutputExcelBuilder.PersonAmountValue value,
|
||||
QuarterSummary quarterSummary,
|
||||
BigDecimal amountRatio) {
|
||||
value.setQuarterOneRatio(addRatio(value.getQuarterOneRatio(),
|
||||
multiplyRatio(quarterSummary.getQuarterOneRatio(), amountRatio)));
|
||||
value.setQuarterOneAmountWan(addAmountValue(value.getQuarterOneAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterOneAmount(), amountRatio))));
|
||||
value.setQuarterTwoRatio(addRatio(value.getQuarterTwoRatio(),
|
||||
multiplyRatio(quarterSummary.getQuarterTwoRatio(), amountRatio)));
|
||||
value.setQuarterTwoAmountWan(addAmountValue(value.getQuarterTwoAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterTwoAmount(), amountRatio))));
|
||||
value.setQuarterThreeRatio(addRatio(value.getQuarterThreeRatio(),
|
||||
multiplyRatio(quarterSummary.getQuarterThreeRatio(), amountRatio)));
|
||||
value.setQuarterThreeAmountWan(addAmountValue(value.getQuarterThreeAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterThreeAmount(), amountRatio))));
|
||||
value.setQuarterFourRatio(addRatio(value.getQuarterFourRatio(),
|
||||
multiplyRatio(quarterSummary.getQuarterFourRatio(), amountRatio)));
|
||||
value.setQuarterFourAmountWan(addAmountValue(value.getQuarterFourAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getQuarterFourAmount(), amountRatio))));
|
||||
value.setYearTotalRatio(addRatio(value.getYearTotalRatio(),
|
||||
multiplyRatio(quarterSummary.getCurrentYearRatio(), amountRatio)));
|
||||
value.setYearTotalAmountWan(addAmountValue(value.getYearTotalAmountWan(),
|
||||
amountToWan(multiplyAmount(quarterSummary.getYearTotalAmount(), amountRatio))));
|
||||
}
|
||||
@@ -1886,6 +2385,24 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class SpecialtyPersonOutputBuildResult {
|
||||
private ProjectPlanningDO anchorPlanning;
|
||||
private ProjectDO project;
|
||||
private Integer reportYear;
|
||||
private SpecialtyPersonOutputExcelBuilder.ExportData data;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class SpecialtyQuarterPreviewAggregate {
|
||||
private BigDecimal specialtyQuarterOneAmountWan = ZERO_AMOUNT;
|
||||
private BigDecimal specialtyQuarterTwoAmountWan = ZERO_AMOUNT;
|
||||
private BigDecimal specialtyQuarterThreeAmountWan = ZERO_AMOUNT;
|
||||
private BigDecimal specialtyQuarterFourAmountWan = ZERO_AMOUNT;
|
||||
private BigDecimal specialtyYearTotalAmountWan = ZERO_AMOUNT;
|
||||
private Map<String, SpecialtyPersonOutputExcelBuilder.PersonAmountValue> rolePersonAmountMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class PlanningOfficeContribution {
|
||||
private BigDecimal totalOutputAmount = ZERO_AMOUNT;
|
||||
|
||||
@@ -637,10 +637,15 @@ public class SpecialtyPersonOutputExcelBuilder extends AbstractProjectOutputExce
|
||||
|
||||
@Data
|
||||
public static class PersonAmountValue {
|
||||
private BigDecimal quarterOneRatio;
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
private BigDecimal quarterTwoRatio;
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
private BigDecimal quarterThreeRatio;
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
private BigDecimal quarterFourRatio;
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
private BigDecimal yearTotalRatio;
|
||||
private BigDecimal yearTotalAmountWan;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ package cn.iocoder.lyzsys.module.tjt.service.specialtyrolesplit;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitBatchSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitRespVO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 页面5角色比例 Service 接口
|
||||
@@ -14,6 +16,8 @@ public interface SpecialtyRoleSplitService {
|
||||
|
||||
List<SpecialtyRoleSplitRespVO> getSpecialtyRoleSplitListByPlanningId(Long planningId);
|
||||
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> getSpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds);
|
||||
|
||||
void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO);
|
||||
|
||||
void deleteByOutputSplitId(Long outputSplitId);
|
||||
|
||||
@@ -1,48 +1,34 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.specialtyrolesplit;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitBatchSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitSaveItemReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.outputsplit.ProjectOutputSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.project.ProjectDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.projectroleperson.ProjectRolePersonDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplit.SpecialtyRoleSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson.SpecialtyRoleSplitPersonDO;
|
||||
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.projectroleperson.ProjectRolePersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplit.SpecialtyRoleSplitMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplitperson.SpecialtyRoleSplitPersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_OUTPUT_SPLIT_PLANNING_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_DESIGN_PERSON_REQUIRED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_PERSON_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_PERSON_RATIO_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_ROLE_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_ROLE_RATIO_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_SPECIALTY_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
@@ -58,6 +44,8 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
@Resource
|
||||
private SpecialtyRoleSplitMapper specialtyRoleSplitMapper;
|
||||
@Resource
|
||||
private SpecialtyRoleSplitPersonMapper specialtyRoleSplitPersonMapper;
|
||||
@Resource
|
||||
private ProjectOutputSplitService projectOutputSplitService;
|
||||
@Resource
|
||||
private ProjectPlanningMapper projectPlanningMapper;
|
||||
@@ -71,15 +59,102 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
@Override
|
||||
public List<SpecialtyRoleSplitRespVO> getSpecialtyRoleSplitListByPlanningId(Long planningId) {
|
||||
ProjectPlanningDO planning = validatePlanningExists(planningId);
|
||||
ProjectDO project = validateProjectExists(planning.getProjectId());
|
||||
ProjectOutputSplitDO outputSplit = projectOutputSplitService.getOrCreateProjectOutputSplit(planningId);
|
||||
List<SpecialtyRoleSplitDO> dbList = specialtyRoleSplitMapper.selectListByOutputSplitId(outputSplit.getId());
|
||||
Map<String, SpecialtyRoleSplitDO> dbMap = dbList.stream().collect(Collectors.toMap(
|
||||
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap = projectRolePersonMapper
|
||||
.selectListByProjectId(project.getId()).stream()
|
||||
.collect(Collectors.groupingBy(ProjectRolePersonDO::getRoleCode, LinkedHashMap::new, Collectors.toList()));
|
||||
validateProjectExists(planning.getProjectId());
|
||||
return getSpecialtyRoleSplitListMapByPlanningIds(Collections.singletonList(planningId))
|
||||
.getOrDefault(planningId, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, List<SpecialtyRoleSplitRespVO>> getSpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds) {
|
||||
if (planningIds == null || planningIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<Long> normalizedPlanningIds = planningIds.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (normalizedPlanningIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<Long, ProjectPlanningDO> planningMap = projectPlanningMapper.selectBatchIds(normalizedPlanningIds).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(ProjectPlanningDO::getId, item -> item, (a, b) -> a, LinkedHashMap::new));
|
||||
if (planningMap.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Set<Long> projectIds = planningMap.values().stream()
|
||||
.map(ProjectPlanningDO::getProjectId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
Map<Long, ProjectDO> projectMap = projectIds.isEmpty()
|
||||
? Collections.emptyMap()
|
||||
: projectMapper.selectBatchIds(projectIds).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(ProjectDO::getId, item -> item, (a, b) -> a, LinkedHashMap::new));
|
||||
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap = new LinkedHashMap<>(
|
||||
projectOutputSplitService.getProjectOutputSplitMap(planningMap.keySet()));
|
||||
for (ProjectPlanningDO planning : planningMap.values()) {
|
||||
if (!outputSplitMap.containsKey(planning.getId())) {
|
||||
outputSplitMap.put(planning.getId(),
|
||||
projectOutputSplitService.getOrCreateProjectOutputSplit(planning.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
List<Long> outputSplitIds = outputSplitMap.values().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(ProjectOutputSplitDO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, List<SpecialtyRoleSplitDO>> roleSplitMap = specialtyRoleSplitMapper
|
||||
.selectListByOutputSplitIds(outputSplitIds).stream()
|
||||
.collect(Collectors.groupingBy(SpecialtyRoleSplitDO::getOutputSplitId,
|
||||
LinkedHashMap::new, Collectors.toList()));
|
||||
List<Long> roleSplitIds = roleSplitMap.values().stream()
|
||||
.flatMap(Collection::stream)
|
||||
.map(SpecialtyRoleSplitDO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap = specialtyRoleSplitPersonMapper
|
||||
.selectListByRoleSplitIds(roleSplitIds)
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(SpecialtyRoleSplitPersonDO::getRoleSplitId,
|
||||
LinkedHashMap::new, Collectors.toList()));
|
||||
|
||||
Map<Long, Map<String, List<ProjectRolePersonDO>>> projectRolePersonMap = projectRolePersonMapper
|
||||
.selectListByProjectIds(projectIds).stream()
|
||||
.collect(Collectors.groupingBy(ProjectRolePersonDO::getProjectId, LinkedHashMap::new,
|
||||
Collectors.groupingBy(ProjectRolePersonDO::getRoleCode, LinkedHashMap::new, Collectors.toList())));
|
||||
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> result = new LinkedHashMap<>();
|
||||
for (Long planningId : normalizedPlanningIds) {
|
||||
ProjectPlanningDO planning = planningMap.get(planningId);
|
||||
if (planning == null) {
|
||||
continue;
|
||||
}
|
||||
ProjectOutputSplitDO outputSplit = outputSplitMap.get(planningId);
|
||||
if (outputSplit == null) {
|
||||
continue;
|
||||
}
|
||||
ProjectDO project = projectMap.get(planning.getProjectId());
|
||||
List<SpecialtyRoleSplitDO> roleList = roleSplitMap.getOrDefault(outputSplit.getId(), Collections.emptyList());
|
||||
Map<String, List<ProjectRolePersonDO>> projectPersons = projectRolePersonMap
|
||||
.getOrDefault(planning.getProjectId(), Collections.emptyMap());
|
||||
result.put(planningId, buildRoleSplitRespList(planning, project, outputSplit, roleList, projectPersons, personMap));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SpecialtyRoleSplitRespVO> buildRoleSplitRespList(ProjectPlanningDO planning,
|
||||
ProjectDO project,
|
||||
ProjectOutputSplitDO outputSplit,
|
||||
List<SpecialtyRoleSplitDO> dbList,
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap,
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap) {
|
||||
List<SpecialtyRoleSplitDO> safeDbList = dbList == null ? Collections.emptyList() : dbList;
|
||||
Map<String, SpecialtyRoleSplitDO> dbMap = safeDbList.stream().collect(Collectors.toMap(
|
||||
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
||||
List<SpecialtyRoleSplitRespVO> result = new ArrayList<>();
|
||||
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
|
||||
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
||||
@@ -92,7 +167,7 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
|
||||
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
|
||||
List<SpecialtyRolePersonRespVO> persons = buildRespPersons(
|
||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, roleRatio, projectRolePersonMap);
|
||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, projectRolePersonMap, personMap);
|
||||
SpecialtyRoleSplitRespVO respVO = dbItem == null
|
||||
? new SpecialtyRoleSplitRespVO()
|
||||
: BeanUtils.toBean(dbItem, SpecialtyRoleSplitRespVO.class);
|
||||
@@ -102,7 +177,7 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
+ OutputSplitBizConstants.getRoleSortNo(roleItem.getCode()));
|
||||
}
|
||||
respVO.setPlanningId(planning.getId());
|
||||
respVO.setProjectName(project.getProjectName());
|
||||
respVO.setProjectName(project == null ? "" : project.getProjectName());
|
||||
respVO.setPlanningContent(planning.getPlanningContent());
|
||||
respVO.setSpecialtyCode(specialtyItem.getCode());
|
||||
respVO.setSpecialtyName(specialtyItem.getName());
|
||||
@@ -119,6 +194,7 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO) {
|
||||
ProjectPlanningDO planning = validatePlanningExists(reqVO.getPlanningId());
|
||||
ProjectOutputSplitDO outputSplit = projectOutputSplitService.getOrCreateProjectOutputSplit(reqVO.getPlanningId());
|
||||
@@ -140,25 +216,28 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
getSavePersons(roleMap, roleItem.getCode()));
|
||||
validateRolePersons(roleItem.getCode(), roleAmount, persons);
|
||||
roleTotal = roleTotal.add(roleRatio).setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
upsertRole(dbMap, outputSplit.getId(), specialtyItem.getCode(), specialtyItem.getName(),
|
||||
roleItem.getCode(), roleRatio,
|
||||
OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyItem.getCode())
|
||||
? null : toPersonJson(persons));
|
||||
SpecialtyRoleSplitDO role = upsertRole(dbMap, outputSplit.getId(), specialtyItem.getCode(),
|
||||
specialtyItem.getName(), roleItem.getCode(), roleRatio);
|
||||
refreshRolePersons(role, outputSplit, persons);
|
||||
}
|
||||
validateRoleTotal(roleTotal);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByOutputSplitId(Long outputSplitId) {
|
||||
specialtyRoleSplitPersonMapper.deleteByOutputSplitId(outputSplitId);
|
||||
specialtyRoleSplitMapper.delete(SpecialtyRoleSplitDO::getOutputSplitId, outputSplitId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByOutputSplitIds(List<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
specialtyRoleSplitPersonMapper.deleteByOutputSplitIds(outputSplitIds);
|
||||
specialtyRoleSplitMapper.delete(new cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX<SpecialtyRoleSplitDO>()
|
||||
.in(SpecialtyRoleSplitDO::getOutputSplitId, outputSplitIds));
|
||||
}
|
||||
@@ -181,8 +260,9 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return result;
|
||||
}
|
||||
|
||||
private void upsertRole(Map<String, SpecialtyRoleSplitDO> dbMap, Long outputSplitId, String specialtyCode,
|
||||
String specialtyName, String roleCode, BigDecimal roleRatio, String personsJson) {
|
||||
private SpecialtyRoleSplitDO upsertRole(Map<String, SpecialtyRoleSplitDO> dbMap, Long outputSplitId,
|
||||
String specialtyCode, String specialtyName, String roleCode,
|
||||
BigDecimal roleRatio) {
|
||||
String key = specialtyCode + ":" + roleCode;
|
||||
SpecialtyRoleSplitDO dbItem = dbMap.get(key);
|
||||
Integer sortNo = dbItem != null && dbItem.getSortNo() != null
|
||||
@@ -197,10 +277,10 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
createObj.setRoleCode(roleCode);
|
||||
createObj.setRoleName(OutputSplitBizConstants.getRoleName(roleCode));
|
||||
createObj.setRoleRatio(ratio(roleRatio));
|
||||
createObj.setPersonsJson(personsJson);
|
||||
createObj.setSortNo(sortNo);
|
||||
specialtyRoleSplitMapper.insert(createObj);
|
||||
return;
|
||||
dbMap.put(key, createObj);
|
||||
return createObj;
|
||||
}
|
||||
SpecialtyRoleSplitDO updateObj = new SpecialtyRoleSplitDO();
|
||||
updateObj.setId(dbItem.getId());
|
||||
@@ -210,9 +290,46 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
updateObj.setRoleCode(roleCode);
|
||||
updateObj.setRoleName(OutputSplitBizConstants.getRoleName(roleCode));
|
||||
updateObj.setRoleRatio(ratio(roleRatio));
|
||||
updateObj.setPersonsJson(personsJson);
|
||||
updateObj.setSortNo(sortNo);
|
||||
specialtyRoleSplitMapper.updateById(updateObj);
|
||||
dbMap.put(key, updateObj);
|
||||
return updateObj;
|
||||
}
|
||||
|
||||
private void refreshRolePersons(SpecialtyRoleSplitDO role, ProjectOutputSplitDO outputSplit,
|
||||
List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
if (role == null || role.getId() == null) {
|
||||
return;
|
||||
}
|
||||
specialtyRoleSplitPersonMapper.deleteByRoleSplitId(role.getId());
|
||||
if (OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(role.getSpecialtyCode())
|
||||
|| persons == null || persons.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<SpecialtyRoleSplitPersonDO> createList = new ArrayList<>();
|
||||
for (int i = 0; i < persons.size(); i++) {
|
||||
SpecialtyRolePersonSaveReqVO person = persons.get(i);
|
||||
if (person == null || person.getEmployeeId() == null) {
|
||||
continue;
|
||||
}
|
||||
SpecialtyRoleSplitPersonDO createObj = new SpecialtyRoleSplitPersonDO();
|
||||
createObj.setRoleSplitId(role.getId());
|
||||
createObj.setOutputSplitId(outputSplit.getId());
|
||||
createObj.setProjectId(outputSplit.getProjectId());
|
||||
createObj.setPlanningId(outputSplit.getPlanningId());
|
||||
createObj.setSpecialtyCode(role.getSpecialtyCode());
|
||||
createObj.setSpecialtyName(role.getSpecialtyName());
|
||||
createObj.setRoleCode(role.getRoleCode());
|
||||
createObj.setRoleName(role.getRoleName());
|
||||
createObj.setEmployeeId(person.getEmployeeId());
|
||||
createObj.setEmployeeName(person.getEmployeeName());
|
||||
createObj.setPersonRatio(ratio(person.getPersonRatio()));
|
||||
createObj.setSortNo(i + 1);
|
||||
createList.add(createObj);
|
||||
}
|
||||
if (!createList.isEmpty()) {
|
||||
specialtyRoleSplitPersonMapper.insertBatch(createList);
|
||||
}
|
||||
}
|
||||
|
||||
private List<SpecialtyRolePersonSaveReqVO> getSavePersons(Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap,
|
||||
@@ -298,13 +415,13 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
|
||||
private List<SpecialtyRolePersonRespVO> buildRespPersons(SpecialtyRoleSplitDO dbItem, String specialtyCode,
|
||||
String roleCode, BigDecimal roleAmount,
|
||||
BigDecimal roleRatio,
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap) {
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap,
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap) {
|
||||
List<SpecialtyRolePersonSaveReqVO> sourcePersons;
|
||||
if (OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyCode)) {
|
||||
sourcePersons = buildDefaultProjectLeadPersons(projectRolePersonMap.get(roleCode));
|
||||
} else {
|
||||
sourcePersons = parseStoredPersons(dbItem);
|
||||
sourcePersons = buildStoredPersons(dbItem, personMap);
|
||||
}
|
||||
List<SpecialtyRolePersonRespVO> result = new ArrayList<>();
|
||||
for (SpecialtyRolePersonSaveReqVO person : sourcePersons) {
|
||||
@@ -318,12 +435,13 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SpecialtyRolePersonSaveReqVO> parseStoredPersons(SpecialtyRoleSplitDO dbItem) {
|
||||
if (dbItem == null || dbItem.getPersonsJson() == null || dbItem.getPersonsJson().trim().isEmpty()) {
|
||||
private List<SpecialtyRolePersonSaveReqVO> buildStoredPersons(SpecialtyRoleSplitDO dbItem,
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap) {
|
||||
if (dbItem == null || dbItem.getId() == null || personMap == null || personMap.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<SpecialtyRolePersonSaveReqVO> persons = JsonUtils.parseArray(dbItem.getPersonsJson(), SpecialtyRolePersonSaveReqVO.class);
|
||||
if (persons == null) {
|
||||
List<SpecialtyRoleSplitPersonDO> persons = personMap.get(dbItem.getId());
|
||||
if (persons == null || persons.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return persons.stream()
|
||||
@@ -401,10 +519,6 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return projectOutputSplitService.getSpecialtyAmount(outputSplit, assessmentOutputValue, specialtyCode);
|
||||
}
|
||||
|
||||
private String toPersonJson(List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
return persons == null || persons.isEmpty() ? null : JsonUtils.toJsonString(persons);
|
||||
}
|
||||
|
||||
private BigDecimal sumPersonRatios(List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
BigDecimal sum = ZERO_RATIO;
|
||||
if (persons == null || persons.isEmpty()) {
|
||||
|
||||
@@ -51,18 +51,18 @@ spring:
|
||||
# url: jdbc:sqlserver://47.106.184.244:14333;DatabaseName=tjt_czjs;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8
|
||||
# username: sa # SQL Server 连接的示例
|
||||
# password: sql123456 # SQL Server 连接的示例
|
||||
url: jdbc:sqlserver://localhost:1433;DatabaseName=tjt_czjs;SelectMethod=cursor;encrypt=false;trustServerCertificate=true;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8
|
||||
url: jdbc:sqlserver://47.106.184.244:14333;DatabaseName=tjt_czjs;SelectMethod=cursor;encrypt=false;trustServerCertificate=true;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8
|
||||
username: tjt_user # SQL Server 连接的示例
|
||||
password: tjt@Admin2026 # SQL Server 连接的示例
|
||||
|
||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||
redis:
|
||||
host: 127.0.0.1 # 地址
|
||||
# host: 8.163.1.126
|
||||
# host: 127.0.0.1 # 地址
|
||||
host: 8.163.1.126
|
||||
port: 6379 # 端口
|
||||
database: 8 # 数据库索引
|
||||
password: lyzsys@2026
|
||||
# password: lyzbim2016
|
||||
# password: lyzsys@2026
|
||||
password: lyzbim2016
|
||||
|
||||
--- #################### 定时任务相关配置 ####################
|
||||
|
||||
|
||||
251
lyzsys-server/src/main/resources/application-prod.yaml
Normal file
251
lyzsys-server/src/main/resources/application-prod.yaml
Normal file
@@ -0,0 +1,251 @@
|
||||
server:
|
||||
port: 48080
|
||||
|
||||
--- #################### 数据库相关配置 ####################
|
||||
spring:
|
||||
autoconfigure:
|
||||
# noinspection SpringBootApplicationYaml
|
||||
exclude:
|
||||
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
|
||||
- org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置
|
||||
- org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建
|
||||
- org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
druid: # Druid 【监控】相关的全局配置
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
allow: # 设置白名单,不填则允许所有访问
|
||||
url-pattern: /druid/*
|
||||
login-username: # 控制台管理用户名和密码
|
||||
login-password:
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
log-slow-sql: true # 慢 SQL 记录
|
||||
slow-sql-millis: 100
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
dynamic: # 多数据源配置
|
||||
druid: # Druid 【连接池】相关的全局配置
|
||||
initial-size: 1 # 初始连接数
|
||||
min-idle: 1 # 最小连接池数量
|
||||
max-active: 5 # 最大连接池数量
|
||||
max-wait: 60000 # 配置获取连接等待超时的时间,单位:毫秒(1 分钟)
|
||||
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒(1 分钟)
|
||||
min-evictable-idle-time-millis: 600000 # 配置一个连接在池中最小生存的时间,单位:毫秒(10 分钟)
|
||||
max-evictable-idle-time-millis: 1800000 # 配置一个连接在池中最大生存的时间,单位:毫秒(30 分钟)
|
||||
validation-query: SELECT 1 # 配置检测连接是否有效
|
||||
test-while-idle: true
|
||||
test-on-borrow: false
|
||||
test-on-return: false
|
||||
pool-prepared-statements: true # 是否开启 PreparedStatement 缓存
|
||||
max-pool-prepared-statement-per-connection-size: 20 # 每个连接缓存的 PreparedStatement 数量
|
||||
primary: master
|
||||
datasource:
|
||||
master:
|
||||
url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=tjt_czjs;SelectMethod=cursor;encrypt=false;trustServerCertificate=true;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8
|
||||
username: tjt_user # SQL Server 连接的示例
|
||||
password: tjt@Admin2026 # SQL Server 连接的示例
|
||||
|
||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||
redis:
|
||||
host: 127.0.0.1 # 地址
|
||||
port: 6379 # 端口
|
||||
database: 8 # 数据库索引
|
||||
password: lyzsys@2026
|
||||
|
||||
--- #################### 定时任务相关配置 ####################
|
||||
|
||||
# Quartz 配置项,对应 QuartzProperties 配置类
|
||||
spring:
|
||||
quartz:
|
||||
auto-startup: true # 本地开发环境,尽量不要开启 Job
|
||||
scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
|
||||
job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
|
||||
wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
|
||||
properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档
|
||||
org:
|
||||
quartz:
|
||||
# Scheduler 相关配置
|
||||
scheduler:
|
||||
instanceName: schedulerName
|
||||
instanceId: AUTO # 自动生成 instance ID
|
||||
# JobStore 相关配置
|
||||
jobStore:
|
||||
# JobStore 实现类。可见博客:https://blog.csdn.net/weixin_42458219/article/details/122247162
|
||||
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
|
||||
isClustered: true # 是集群模式
|
||||
clusterCheckinInterval: 15000 # 集群检查频率,单位:毫秒。默认为 15000,即 15 秒
|
||||
misfireThreshold: 60000 # misfire 阀值,单位:毫秒。
|
||||
# 线程池相关配置
|
||||
threadPool:
|
||||
threadCount: 25 # 线程池大小。默认为 10 。
|
||||
threadPriority: 5 # 线程优先级
|
||||
class: org.quartz.simpl.SimpleThreadPool # 线程池类型
|
||||
jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置
|
||||
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
|
||||
|
||||
--- #################### 消息队列相关 ####################
|
||||
|
||||
# rocketmq 配置项,对应 RocketMQProperties 配置类
|
||||
rocketmq:
|
||||
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
|
||||
|
||||
spring:
|
||||
# RabbitMQ 配置项,对应 RabbitProperties 配置类
|
||||
rabbitmq:
|
||||
host: 127.0.0.1 # RabbitMQ 服务的地址
|
||||
port: 5672 # RabbitMQ 服务的端口
|
||||
username: rabbit # RabbitMQ 服务的账号
|
||||
password: rabbit # RabbitMQ 服务的密码
|
||||
# Kafka 配置项,对应 KafkaProperties 配置类
|
||||
kafka:
|
||||
bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
|
||||
|
||||
--- #################### 服务保障相关配置 ####################
|
||||
|
||||
# Lock4j 配置项
|
||||
lock4j:
|
||||
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
||||
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
|
||||
|
||||
--- #################### 监控相关配置 ####################
|
||||
|
||||
# Actuator 监控端点的配置项
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||
exposure:
|
||||
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||
|
||||
# Spring Boot Admin 配置项
|
||||
spring:
|
||||
boot:
|
||||
admin:
|
||||
# Spring Boot Admin Client 客户端的相关配置
|
||||
client:
|
||||
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
||||
instance:
|
||||
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
|
||||
username: admin
|
||||
password: admin
|
||||
# Spring Boot Admin Server 服务端的相关配置
|
||||
context-path: /admin # 配置 Spring
|
||||
|
||||
# 日志文件配置
|
||||
logging:
|
||||
file:
|
||||
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
|
||||
level:
|
||||
# 配置自己写的 MyBatis Mapper 打印日志
|
||||
cn.iocoder.lyzsys.module.bpm.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.infra.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # 配置 ApiErrorLogMapper 的日志级别为 info,避免和 GlobalExceptionHandler 重复打印
|
||||
cn.iocoder.lyzsys.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info
|
||||
cn.iocoder.lyzsys.module.infra.dal.mysql.file.FileConfigMapper: INFO # 配置 FileConfigMapper 的日志级别为 info
|
||||
cn.iocoder.lyzsys.module.pay.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 PayNotifyTaskMapper 的日志级别为 info
|
||||
cn.iocoder.lyzsys.module.system.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
|
||||
cn.iocoder.lyzsys.module.tool.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.member.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.trade.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.promotion.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.statistics.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.crm.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.erp.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.iot.dal.mysql: debug
|
||||
cn.iocoder.lyzsys.module.iot.dal.tdengine: DEBUG
|
||||
cn.iocoder.lyzsys.module.iot.service.rule: debug
|
||||
cn.iocoder.lyzsys.module.ai.dal.mysql: debug
|
||||
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
|
||||
|
||||
debug: false
|
||||
|
||||
--- #################### 微信公众号、小程序相关配置 ####################
|
||||
wx:
|
||||
mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
|
||||
# app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
|
||||
# secret: 5abee519483bc9f8cb37ce280e814bd0
|
||||
# app-id: wx5b23ba7a5589ecbb # 测试号(自己的)
|
||||
# secret: 2a7b3b20c537e52e74afd395eb85f61f
|
||||
app-id: wxf56b1542b9e85f8a # 测试号(Kongdy 提供的)
|
||||
secret: 496379dcef1ba869e9234de8d598cfd3
|
||||
# 存储配置,解决 AccessToken 的跨节点的共享
|
||||
config-storage:
|
||||
type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
|
||||
key-prefix: wx # Redis Key 的前缀
|
||||
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
|
||||
miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
|
||||
# appid: wx62056c0d5e8db250 # 测试号(牛希尧提供的)
|
||||
# secret: 333ae72f41552af1e998fe1f54e1584a
|
||||
# appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
|
||||
# secret: 6f270509224a7ae1296bbf1c8cb97aed
|
||||
appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
|
||||
secret: 4a1a04e07f6a4a0751b39c3064a92c8b
|
||||
# appid: wx66186af0759f47c9 # 测试号(puhui 提供的)
|
||||
# secret: 3218bcbd112cbc614c7264ceb20144ac
|
||||
config-storage:
|
||||
type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
|
||||
key-prefix: wa # Redis Key 的前缀
|
||||
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
|
||||
|
||||
--- #################### 芋道相关配置 ####################
|
||||
|
||||
# 芋道配置项,设置当前项目所有自定义的配置
|
||||
lyzsys:
|
||||
captcha:
|
||||
enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
|
||||
security:
|
||||
mock-enable: true
|
||||
pay:
|
||||
order-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
|
||||
refund-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
|
||||
transfer-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址
|
||||
access-log: # 访问日志的配置项
|
||||
enable: false
|
||||
demo: false # 关闭演示模式
|
||||
wxa-code:
|
||||
env-version: develop # 小程序版本: 正式版为 "release";体验版为 "trial";开发版为 "develop"
|
||||
wxa-subscribe-message:
|
||||
miniprogram-state: developer # 跳转小程序类型:开发版为 “developer”;体验版为 “trial”为;正式版为 “formal”
|
||||
tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
|
||||
|
||||
justauth:
|
||||
enabled: true
|
||||
type:
|
||||
DINGTALK: # 钉钉
|
||||
client-id: dingvrnreaje3yqvzhxg
|
||||
client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
|
||||
ignore-check-redirect-uri: true
|
||||
WECHAT_ENTERPRISE: # 企业微信
|
||||
client-id: wwd411c69a39ad2e54
|
||||
client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
|
||||
agent-id: 1000004
|
||||
ignore-check-redirect-uri: true
|
||||
# noinspection SpringBootApplicationYaml
|
||||
WECHAT_MINI_PROGRAM: # 微信小程序
|
||||
client-id: ${wx.miniapp.appid}
|
||||
client-secret: ${wx.miniapp.secret}
|
||||
ignore-check-redirect-uri: true
|
||||
ignore-check-state: true # 微信小程序,不会使用到 state,所以不进行校验
|
||||
WECHAT_MP: # 微信公众号
|
||||
client-id: ${wx.mp.app-id}
|
||||
client-secret: ${wx.mp.secret}
|
||||
ignore-check-redirect-uri: true
|
||||
ALIPAY: # 支付宝小程序
|
||||
client-id: xx
|
||||
client-secret: xx
|
||||
alipay-public-key: xx
|
||||
ignore-check-redirect-uri: true
|
||||
ignore-check-state: true
|
||||
cache:
|
||||
type: REDIS
|
||||
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
|
||||
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
|
||||
Reference in New Issue
Block a user