diff --git a/lyzsys-framework/lyzsys-spring-boot-starter-web/src/main/java/cn/iocoder/lyzsys/framework/web/config/LyzsysWebAutoConfiguration.java b/lyzsys-framework/lyzsys-spring-boot-starter-web/src/main/java/cn/iocoder/lyzsys/framework/web/config/LyzsysWebAutoConfiguration.java index 951b011..d560198 100644 --- a/lyzsys-framework/lyzsys-spring-boot-starter-web/src/main/java/cn/iocoder/lyzsys/framework/web/config/LyzsysWebAutoConfiguration.java +++ b/lyzsys-framework/lyzsys-spring-boot-starter-web/src/main/java/cn/iocoder/lyzsys/framework/web/config/LyzsysWebAutoConfiguration.java @@ -112,6 +112,7 @@ public class LyzsysWebAutoConfiguration { config.addAllowedOriginPattern("*"); // 设置访问源地址 config.addAllowedHeader("*"); // 设置访问源请求头 config.addAllowedMethod("*"); // 设置访问源请求方法 + config.addExposedHeader("Content-Disposition"); // 允许前端读取下载文件名 // 创建 UrlBasedCorsConfigurationSource 对象 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); // 对接口配置跨域设置 diff --git a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectBudgetExportReqVO.java b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectBudgetExportReqVO.java index 2de2236..c21331e 100644 --- a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectBudgetExportReqVO.java +++ b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectBudgetExportReqVO.java @@ -13,4 +13,7 @@ public class ProjectBudgetExportReqVO { @NotNull(message = "项目 ID 不能为空") private Long projectId; + @Schema(description = "导出年度", example = "2026") + private Integer year; + } diff --git a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectLeadQuarterOutputExportReqVO.java b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectLeadQuarterOutputExportReqVO.java index a81a437..2f7ffd7 100644 --- a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectLeadQuarterOutputExportReqVO.java +++ b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectLeadQuarterOutputExportReqVO.java @@ -13,4 +13,7 @@ public class ProjectLeadQuarterOutputExportReqVO { @NotNull(message = "合约规划 ID 不能为空") private Long planningId; + @Schema(description = "导出年度", example = "2026") + private Integer year; + } diff --git a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectQuarterOutputExportReqVO.java b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectQuarterOutputExportReqVO.java index a7e167c..1fe9c23 100644 --- a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectQuarterOutputExportReqVO.java +++ b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/ProjectQuarterOutputExportReqVO.java @@ -13,4 +13,7 @@ public class ProjectQuarterOutputExportReqVO { @NotNull(message = "合约规划 ID 不能为空") private Long planningId; + @Schema(description = "导出年度", example = "2026") + private Integer year; + } diff --git a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/SpecialtyPersonOutputExportReqVO.java b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/SpecialtyPersonOutputExportReqVO.java index 1250175..badade4 100644 --- a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/SpecialtyPersonOutputExportReqVO.java +++ b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/controller/admin/report/vo/SpecialtyPersonOutputExportReqVO.java @@ -18,4 +18,7 @@ public class SpecialtyPersonOutputExportReqVO { @NotBlank(message = "专业编码不能为空") private String specialtyCode; + @Schema(description = "导出年度", example = "2026") + private Integer year; + } diff --git a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/service/report/ProjectOutputReportServiceImpl.java b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/service/report/ProjectOutputReportServiceImpl.java index 8968c44..8e3b2ef 100644 --- a/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/service/report/ProjectOutputReportServiceImpl.java +++ b/lyzsys-module-tjt/src/main/java/cn/iocoder/lyzsys/module/tjt/service/report/ProjectOutputReportServiceImpl.java @@ -1,15 +1,7 @@ package cn.iocoder.lyzsys.module.tjt.service.report; -import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils; -import cn.iocoder.lyzsys.framework.excel.core.util.ExcelUtils; import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.EmployeeOutputSummaryExcelRespVO; -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 cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonRespVO; import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitRespVO; import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO; @@ -17,8 +9,8 @@ import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearcostbudget.Employ 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; -import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO; import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningguidedetail.ProjectPlanningGuideDetailDO; +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.yearkvalue.YearKValueDO; @@ -34,12 +26,7 @@ import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants; import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants; import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService; import cn.iocoder.lyzsys.module.tjt.service.planningguidedetail.ProjectPlanningGuideDetailService; -import cn.iocoder.lyzsys.module.tjt.service.report.builder.EmployeeOutputSummaryExcelBuilder; -import cn.iocoder.lyzsys.module.tjt.service.report.builder.ProjectBudgetExcelBuilder; -import cn.iocoder.lyzsys.module.tjt.service.report.builder.ProjectLeadQuarterOutputExcelBuilder; -import cn.iocoder.lyzsys.module.tjt.service.report.builder.ProjectOverviewOutputExcelBuilder; -import cn.iocoder.lyzsys.module.tjt.service.report.builder.ProjectQuarterOutputExcelBuilder; -import cn.iocoder.lyzsys.module.tjt.service.report.builder.SpecialtyPersonOutputExcelBuilder; +import cn.iocoder.lyzsys.module.tjt.service.report.builder.*; import cn.iocoder.lyzsys.module.tjt.service.specialtyrolesplit.SpecialtyRoleSplitService; import lombok.Data; import org.springframework.stereotype.Service; @@ -51,24 +38,12 @@ import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; -import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.OFFICE_NOT_EXISTS; -import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS; -import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_NOT_EXISTS; -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 @@ -124,6 +99,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic public void exportProjectBudgetExcel(HttpServletResponse response, ProjectBudgetExportReqVO reqVO) throws IOException { ProjectDO project = validateProjectExists(reqVO.getProjectId()); + Integer reportYear = resolveExportYear(reqVO.getYear()); List planningList = sortPlanningList(projectPlanningMapper.selectListByProjectId(project.getId())); List rolePersons = projectRolePersonMapper.selectListByProjectId(project.getId()); Map> quarterMap = getQuarterMap(planningList); @@ -157,11 +133,11 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic data.setTotalAssessmentArea(totalAssessmentArea); data.setTotalAssessmentOutputValue(totalAssessmentOutputValue); data.setTotalAssessmentOutputValueWan(amountToWan(totalAssessmentOutputValue)); - data.setQuarterBudgetRows(buildQuarterBudgetRows(planningList, quarterMap, LocalDate.now().getYear())); + data.setQuarterBudgetRows(buildQuarterBudgetRows(planningList, quarterMap, reportYear)); data.setYearRangeText(buildProjectBudgetYearRangeText(planningList, quarterMap)); projectBudgetExcelBuilder.writeWorkbook(response, - buildFileName(project.getProjectName(), "项目考核产值预算表"), + buildFileName(project.getProjectName(), reportYear, "项目考核产值预算表"), projectBudgetExcelBuilder.build(data)); } @@ -170,7 +146,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic throws IOException { ProjectPlanningDO anchorPlanning = validatePlanningExists(reqVO.getPlanningId()); ProjectDO project = validateProjectExists(anchorPlanning.getProjectId()); - Integer reportYear = LocalDate.now().getYear(); + Integer reportYear = resolveExportYear(reqVO.getYear()); List planningList = sortPlanningList(projectPlanningMapper.selectListByProjectId(project.getId())); Map> quarterMap = getQuarterMap(planningList); Map outputSplitMap = getExistingOutputSplitMap(planningList); @@ -184,7 +160,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic data.setRows(buildProjectQuarterOutputRows(planningList, quarterMap, outputSplitMap, reportYear)); projectQuarterOutputExcelBuilder.writeWorkbook(response, - buildFileName(project.getProjectName(), "专业间项目考核产值年度季度计取表"), + buildFileName(project.getProjectName(), reportYear, "专业间项目考核产值年度季度计取表"), projectQuarterOutputExcelBuilder.build(data)); } @@ -194,7 +170,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic throws IOException { ProjectPlanningDO anchorPlanning = validatePlanningExists(reqVO.getPlanningId()); ProjectDO project = validateProjectExists(anchorPlanning.getProjectId()); - Integer reportYear = LocalDate.now().getYear(); + Integer reportYear = resolveExportYear(reqVO.getYear()); List planningList = projectPlanningMapper.selectListByProjectId(project.getId()).stream() .sorted(Comparator .comparingInt((ProjectPlanningDO item) -> projectLeadOutputTypeOrder(item.getOwnershipType())) @@ -264,7 +240,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic data.setRows(rows); projectLeadQuarterOutputExcelBuilder.writeWorkbook(response, - buildFileName(project.getProjectName(), "项目经理工程负责人工作量及考核产值表"), + buildFileName(project.getProjectName(), reportYear, "项目经理工程负责人工作量及考核产值表"), projectLeadQuarterOutputExcelBuilder.build(data)); } @@ -274,7 +250,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic validateSpecialtyCode(reqVO.getSpecialtyCode()); ProjectPlanningDO anchorPlanning = validatePlanningExists(reqVO.getPlanningId()); ProjectDO project = validateProjectExists(anchorPlanning.getProjectId()); - Integer reportYear = LocalDate.now().getYear(); + Integer reportYear = resolveExportYear(reqVO.getYear()); List planningList = sortPlanningList(projectPlanningMapper.selectListByProjectId(project.getId())); Map> quarterMap = getQuarterMap(planningList); List relevantPlanningList = planningList.stream() @@ -321,15 +297,14 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic roleSplitMap, project.getProjectName(), reqVO.getSpecialtyCode(), reportYear)); specialtyPersonOutputExcelBuilder.writeWorkbook(response, - buildFileName(project.getProjectName(), - data.getSpecialtyName() + "专业内人员年度季度计取表"), + buildFileName(project.getProjectName(), reportYear, data.getSpecialtyName() + "专业内人员年度季度计取表"), specialtyPersonOutputExcelBuilder.build(data)); } @Override public void exportProjectOverviewExcel(HttpServletResponse response, ProjectOverviewExportReqVO reqVO) throws IOException { - Integer reportYear = reqVO.getYear() == null ? LocalDate.now().getYear() : reqVO.getYear(); + Integer reportYear = resolveExportYear(reqVO.getYear()); OfficeDO office = validateOfficeExists(reqVO.getOfficeId()); List employeeList = employeeMapper.selectList(new LambdaQueryWrapperX() .eq(EmployeeDO::getOfficeId, reqVO.getOfficeId()) @@ -386,7 +361,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic data.setTotalRow(buildProjectOverviewTotalRow(new ArrayList<>(accumulatorMap.values()), employeeList)); projectOverviewOutputExcelBuilder.writeWorkbook(response, - buildFileName(office.getOfficeName(), "项目总览表"), + buildFileName(office.getOfficeName(), reportYear, "项目总览表"), projectOverviewOutputExcelBuilder.build(data)); } @@ -408,7 +383,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic data.setKValue(kValue); data.setRows(Collections.emptyList()); employeeOutputSummaryExcelBuilder.writeWorkbook(response, - buildFileName(String.valueOf(reqVO.getYear()), "员工个人考核产值汇总"), + buildFileName("员工个人考核产值", reqVO.getYear(), "汇总表"), employeeOutputSummaryExcelBuilder.build(data)); return; } @@ -509,7 +484,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic data.setKValue(kValue); data.setRows(rows); employeeOutputSummaryExcelBuilder.writeWorkbook(response, - buildFileName(String.valueOf(reqVO.getYear()), "员工个人考核产值汇总"), + buildFileName("员工个人考核产值", reqVO.getYear(), "汇总表"), employeeOutputSummaryExcelBuilder.build(data)); } @@ -1072,6 +1047,10 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic return planning.getPlanningStartYear() == null ? LocalDate.now().getYear() : planning.getPlanningStartYear(); } + private Integer resolveExportYear(Integer year) { + return year == null ? LocalDate.now().getYear() : year; + } + private List resolveBudgetYears(ProjectPlanningDO planning, List quarterList) { Set yearSet = new LinkedHashSet<>(); if (planning != null && planning.getPlanningStartYear() != null) { @@ -1889,6 +1868,13 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic return sanitizeFileName(prefix) + "_" + sanitizeFileName(suffix) + ".xlsx"; } + private String buildFileName(String prefix, Integer reportYear, String suffix) { + if (reportYear == null) { + return buildFileName(prefix, suffix); + } + return sanitizeFileName(prefix) + "_" + reportYear + "_" + sanitizeFileName(suffix) + ".xlsx"; + } + private String sanitizeFileName(String value) { if (value == null || value.trim().isEmpty()) { return "报表"; diff --git a/lyzsys-server/src/main/resources/application-local.yaml b/lyzsys-server/src/main/resources/application-local.yaml index 099659b..03f35d1 100644 --- a/lyzsys-server/src/main/resources/application-local.yaml +++ b/lyzsys-server/src/main/resources/application-local.yaml @@ -48,42 +48,21 @@ spring: primary: master datasource: master: -# url: jdbc:mysql://123.60.156.158:3306/lyz_bus?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 - # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例 - # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 - # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 - url: jdbc:sqlserver://47.106.184.244:14333;DatabaseName=tjt_czjs;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例 - # # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例 - # url: jdbc:kingbase8://127.0.0.1:54321/test # 人大金仓 KingbaseES 连接的示例 - # url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss 连接的示例 - username: sa # SQL Server 连接的示例 - password: sql123456 # SQL Server 连接的示例 - # username: sa # SQL Server 连接的示例 - # password: Lyzsys@2024 # SQL Server 连接的示例 - # username: SYSDBA # DM 连接的示例 - # password: SYSDBA001 # DM 连接的示例 - # username: root # OpenGauss 连接的示例 - # password: Lyzsys@2024 # OpenGauss 连接的示例 -# slave: # 模拟从库,可根据自己需要修改 -# lazy: true # 开启懒加载,保证启动速度 -# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true -# username: root -# password: 123456 -# tdengine: # IoT 数据库(需要 IoT 物联网再开启噢!) -# lazy: true # 开启懒加载,保证启动速度 -# url: jdbc:TAOS-WS://127.0.0.1:6041/ruoyi_vue_pro?varcharAsString=true -# driver-class-name: com.taosdata.jdbc.ws.WebSocketDriver -# username: root -# password: taosdata -# druid: -# validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL +# 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 + username: tjt_user # SQL Server 连接的示例 + password: tjt@Admin2026 # SQL Server 连接的示例 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 redis: - host: 8.163.1.126 # 地址 + host: 127.0.0.1 # 地址 +# host: 8.163.1.126 port: 6379 # 端口 database: 8 # 数据库索引 - password: lyzbim2016 + password: lyzsys@2026 +# password: lyzbim2016 --- #################### 定时任务相关配置 ####################