diff --git a/cf-framework/cf-spring-boot-starter-security/src/main/java/com/cf/imes/framework/security/core/util/SecurityFrameworkUtils.java b/cf-framework/cf-spring-boot-starter-security/src/main/java/com/cf/imes/framework/security/core/util/SecurityFrameworkUtils.java index 4f26f0557..32a9caa1e 100644 --- a/cf-framework/cf-spring-boot-starter-security/src/main/java/com/cf/imes/framework/security/core/util/SecurityFrameworkUtils.java +++ b/cf-framework/cf-spring-boot-starter-security/src/main/java/com/cf/imes/framework/security/core/util/SecurityFrameworkUtils.java @@ -1,5 +1,6 @@ package com.cf.imes.framework.security.core.util; +import cn.hutool.core.util.ObjectUtil; import com.cf.imes.framework.common.exception.ServiceException; import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants; import com.cf.imes.framework.security.core.LoginUser; @@ -132,4 +133,14 @@ public class SecurityFrameworkUtils { return loginUser.getOrganId(); } + + /** + * 当前用户是否超级管理员 + * + * @return + */ + public static boolean isSuperAdmin() { + LoginUser loginUser = getLoginUser(); + return ObjectUtil.isNotNull(loginUser) && loginUser.getIsSupAdmin(); + } } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/plan/PlanMapper.xml b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/plan/PlanMapper.xml index 6f9bff1be..18d4a1146 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/plan/PlanMapper.xml +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/plan/PlanMapper.xml @@ -161,9 +161,8 @@ ,CONCAT(YEAR(p.create_time), '-', MONTH(p.create_time), '-', DAY(p.create_time)) as date from order_plan p - join order_plan_item opi on p.id = opi.plan_id - join order_item oi on oi.id = opi.item_id - join order_plate op on oi.plate_id = op.id + join order_goods g on g.plan_id = p.id + join order_plate op on op.goods_id = g.id where p.create_time between #{req.createTime[0]} and #{req.createTime[1]} and p.deleted = 0 group by date; diff --git a/cf-module-report/cf-module-report-api/src/main/java/com/cf/imes/module/report/enums/ErrorCodeConstants.java b/cf-module-report/cf-module-report-api/src/main/java/com/cf/imes/module/report/enums/ErrorCodeConstants.java index 005c1f6ac..d7c744ad7 100644 --- a/cf-module-report/cf-module-report-api/src/main/java/com/cf/imes/module/report/enums/ErrorCodeConstants.java +++ b/cf-module-report/cf-module-report-api/src/main/java/com/cf/imes/module/report/enums/ErrorCodeConstants.java @@ -13,6 +13,8 @@ public final class ErrorCodeConstants { // ========== UREPORT template模块 1-003-001-000 ========== public static final ErrorCode TEMPLATE_NOT_EXISTS = new ErrorCode(1_003_001_001, "报表模板信息不存在"); public static final ErrorCode TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR = new ErrorCode(1_003_001_002, "内置模板操作权限不足"); + public static final ErrorCode TEMPLATE_NAME_UNIQE_ERROR = new ErrorCode(1_003_001_003, "模板名【{}】已存在,请编辑模板名后重试"); + // ========== UREPORT datasource模块 1-003-002-000 ========== public static final ErrorCode DATASOURCE_NOT_EXISTS = new ErrorCode(1_003_002_001, "报表数据源不存在"); diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/dataset/ReportDatasetServiceImpl.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/dataset/ReportDatasetServiceImpl.java index f4e37b2b0..e41d1bd8e 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/dataset/ReportDatasetServiceImpl.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/dataset/ReportDatasetServiceImpl.java @@ -1,12 +1,20 @@ package com.cf.imes.module.report.service.dataset; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import com.cf.imes.framework.common.util.object.BeanUtils; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.cf.imes.framework.security.core.LoginUser; +import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetReqVO; import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetSaveReqVO; import com.cf.imes.module.report.dal.dataobject.dataset.ReportDatasetDO; +import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO; +import com.cf.imes.module.report.dal.dataobject.template.ReportTemplateDO; import com.cf.imes.module.report.dal.mysql.dataset.ReportDatasetMapper; +import com.cf.imes.module.report.dal.mysql.datasource.ReportDatasourceMapper; +import com.cf.imes.module.report.dal.mysql.template.ReportTemplateMapper; +import com.cf.imes.module.report.enums.template.ReportTemplateTypeEnum; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -15,6 +23,9 @@ import java.util.List; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_NOT_EXISTS; +import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_NOT_EXISTS; +import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR; +import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_NOT_EXISTS; /** * 报表数据集 Service 实现类 @@ -25,6 +36,12 @@ import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_NOT_EXI @Service @Validated public class ReportDatasetServiceImpl implements ReportDatasetService { + @Resource + private ReportTemplateMapper reportTemplateMapper; + + @Resource + private ReportDatasourceMapper reportDatasourceMapper; + @Resource private ReportDatasetMapper datasetMapper; @@ -65,14 +82,41 @@ public class ReportDatasetServiceImpl implements ReportDatasetService { @Override public void deleteDataset(Long id) { // 校验存在 - validateDatasetExists(id); + ReportDatasetDO reportDatasetDO = validateDatasetExists(id); + // 校验内置模板操作权限 + validateSystemTemplate(reportDatasetDO.getDatasourceId()); // 删除 datasetMapper.deleteById(id); } - private void validateDatasetExists(Long id) { - if (datasetMapper.selectById(id) == null) { + private ReportDatasetDO validateDatasetExists(Long id) { + ReportDatasetDO reportDatasetDO = datasetMapper.selectById(id); + if (ObjectUtil.isNull(reportDatasetDO)) { throw exception(DATASET_NOT_EXISTS); + } else { + return reportDatasetDO; + } + } + + /** + * 校验只有超管可以操作内置模板 + * + * @param datasourceId 数据源id + */ + private void validateSystemTemplate(Long datasourceId) { + ReportDatasourceDO reportDatasourceDO = reportDatasourceMapper.selectById(datasourceId); + if (ObjectUtil.isNull(reportDatasourceDO)) { + throw exception(DATASOURCE_NOT_EXISTS); + } + ReportTemplateDO templateDO = reportTemplateMapper.selectById(reportDatasourceDO.getTemplateId()); + if (ObjectUtil.isNull(templateDO)) { + throw exception(TEMPLATE_NOT_EXISTS); + } + LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); + boolean isSuperAdmin = loginUser != null && loginUser.getIsSupAdmin(); + // 非超管不能操作内置模板 + if (ReportTemplateTypeEnum.SYSTEM.equals(templateDO.getType()) && !isSuperAdmin) { + throw exception(TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR); } } diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java index 855f361f2..520208be1 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java @@ -26,8 +26,10 @@ import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasource import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO; import com.cf.imes.module.report.dal.dataobject.dataset.ReportDatasetDO; import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO; +import com.cf.imes.module.report.dal.dataobject.template.ReportTemplateDO; import com.cf.imes.module.report.dal.mysql.dataset.ReportDatasetMapper; import com.cf.imes.module.report.dal.mysql.datasource.ReportDatasourceMapper; +import com.cf.imes.module.report.dal.mysql.template.ReportTemplateMapper; import com.cf.imes.module.report.enums.template.ReportTemplateTypeEnum; import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource; import com.cf.imes.module.report.service.dataset.ReportDatasetService; @@ -63,6 +65,8 @@ import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_BUIL import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_NOT_EXISTS; import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_SPRINGBEAN_GET_FAIL; import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_SPRINGBEAN_METHODS_GET_FAIL; +import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR; +import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_NOT_EXISTS; /** * 报表数据源 Service 实现类 @@ -74,6 +78,9 @@ import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_SPRI @Validated @Slf4j public class ReportDatasourceServiceImpl implements ReportDatasourceService { + @Resource + private ReportTemplateMapper reportTemplateMapper; + @Resource private ReportDatasourceMapper datasourceMapper; @@ -111,7 +118,9 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService { @Override public void deleteDatasource(Long id) { // 校验存在 - validateDatasourceExists(id); + ReportDatasourceDO reportDatasourceDO = validateDatasourceExists(id); + // 校验内置模板操作权限 + validateSystemTemplate(reportDatasourceDO.getTemplateId()); // 删除 datasourceMapper.deleteById(id); // 删除关联数据集 @@ -334,11 +343,32 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService { /** * 校验数据源是否存在 * - * @param id + * @param id 数据源id */ - private void validateDatasourceExists(Long id) { - if (datasourceMapper.selectById(id) == null) { + private ReportDatasourceDO validateDatasourceExists(Long id) { + ReportDatasourceDO reportDatasourceDO = datasourceMapper.selectById(id); + if (reportDatasourceDO == null) { throw exception(DATASOURCE_NOT_EXISTS); + } else { + return reportDatasourceDO; + } + } + + /** + * 校验只有超管可以操作内置模板 + * + * @param templateId 模板id + */ + private void validateSystemTemplate(Long templateId) { + ReportTemplateDO templateDO = reportTemplateMapper.selectById(templateId); + if (ObjectUtil.isNull(templateDO)) { + throw exception(TEMPLATE_NOT_EXISTS); + } + LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); + boolean isSuperAdmin = loginUser != null && loginUser.getIsSupAdmin(); + // 非超管不能操作内置模板 + if (ReportTemplateTypeEnum.SYSTEM.equals(templateDO.getType()) && !isSuperAdmin) { + throw exception(TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR); } } } diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/template/ReportTemplateServiceImpl.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/template/ReportTemplateServiceImpl.java index c87b078e3..c573f0ff5 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/template/ReportTemplateServiceImpl.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/template/ReportTemplateServiceImpl.java @@ -70,6 +70,7 @@ import java.util.Objects; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR; +import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_NAME_UNIQE_ERROR; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_NOT_EXISTS; /** @@ -96,9 +97,14 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { @Resource private ReportDatasetMapper datasetMapper; + private static final String UTF8_CHARSET = CharsetUtil.UTF_8; + @Override @Transactional(rollbackFor = Exception.class) public Long createReportTemplate(ReportTemplateSaveReqVO createReqVO) { + boolean isSuperAdmin = SecurityFrameworkUtils.isSuperAdmin(); + // 校验模板名唯一性 + validateTemplateNameUnique(createReqVO, isSuperAdmin); // url解码xml String content = createReqVO.getContent(); if (StringUtils.isNotEmpty(content)) { @@ -107,8 +113,6 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { // 新增模板 ReportTemplateDO template = BeanUtils.toBean(createReqVO, ReportTemplateDO.class); // 超管创建的作为内置模板 - LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); - boolean isSuperAdmin = loginUser != null && loginUser.getIsSupAdmin(); if (isSuperAdmin) { template.setType(ReportTemplateTypeEnum.SYSTEM); } else { @@ -125,15 +129,24 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { @Override @Transactional(rollbackFor = Exception.class) public Long copyReportTemplate(ReportTemplateSaveReqVO createReqVO) { + boolean isSuperAdmin = SecurityFrameworkUtils.isSuperAdmin(); Long templateId = createReqVO.getId(); // 校验存在 ReportTemplateDO reportTemplateDO = validateTemplateExists(templateId); + // 校验模板名唯一性 + validateTemplateNameUnique(createReqVO, isSuperAdmin); // 校验内置模板操作权限 validateSystemTemplate(reportTemplateDO); ReportTemplateDO copyTemplateDO = BeanUtils.toBean(reportTemplateDO, ReportTemplateDO.class); // 重置id copyTemplateDO.setId(null); copyTemplateDO.setName(createReqVO.getName()); + // 超管创建的作为内置模板 + if (isSuperAdmin) { + copyTemplateDO.setType(ReportTemplateTypeEnum.SYSTEM); + } else { + copyTemplateDO.setType(ReportTemplateTypeEnum.CUSTOM); + } // 新增模版 templateMapper.insert(copyTemplateDO); Long newtemplateId = copyTemplateDO.getId(); @@ -217,6 +230,8 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { Long templateId = updateReqVO.getId(); // 校验存在 ReportTemplateDO reportTemplateDO = validateTemplateExists(templateId); + // 校验模板名唯一性 + validateTemplateNameUnique(updateReqVO, SecurityFrameworkUtils.isSuperAdmin()); // 校验内置模板操作权限 validateSystemTemplate(reportTemplateDO); // url解码xml @@ -257,8 +272,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { * 校验只有超管可以操作内置模板 */ private void validateSystemTemplate(ReportTemplateDO templateDO) { - LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); - boolean isSuperAdmin = loginUser != null && loginUser.getIsSupAdmin(); + boolean isSuperAdmin = SecurityFrameworkUtils.isSuperAdmin(); // 非超管不能操作内置模板 if (ReportTemplateTypeEnum.SYSTEM.equals(templateDO.getType()) && !isSuperAdmin) { throw exception(TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR); @@ -279,6 +293,26 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { } } + /** + * 校验唯一性约束 + * + * @param reqVO + */ + private void validateTemplateNameUnique(ReportTemplateSaveReqVO reqVO, boolean isSuperAdmin) { + Long templateId = reqVO.getId(); + String name = reqVO.getName(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapperX().eq(ReportTemplateDO::getName, name); + if (ObjectUtil.isNotNull(templateId)) { + wrapper.ne(ReportTemplateDO::getId, templateId); + } + if (isSuperAdmin) { + wrapper.eq(ReportTemplateDO::getType, ReportTemplateTypeEnum.SYSTEM); + } + if (templateMapper.exists(wrapper)) { + throw exception(TEMPLATE_NAME_UNIQE_ERROR, name); + } + } + @Override public ReportTemplateDO getReportTemplate(Long id) { // 校验模板 @@ -370,7 +404,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { .orderByDesc(ReportTemplateDO::getCreateTime) // 不返回content xml,点击具体的模板中返回xml .select(ReportTemplateDO::getId, ReportTemplateDO::getName, ReportTemplateDO::getCreateTime, ReportTemplateDO::getRemark); - if (loginUser != null && Boolean.FALSE.equals(loginUser.getIsSupAdmin())) { + if (ObjectUtil.isNotNull(loginUser) && Boolean.FALSE.equals(loginUser.getIsSupAdmin())) { // 普通用户查看机构下的和system模板 queryWrapper.or(wrapper -> wrapper .eq(ReportTemplateDO::getOrganId, loginUser.getOrganId()) @@ -401,12 +435,12 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { report.setChartImages(chartImages); try { OutputStream out = response.getOutputStream(); - response.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding(UTF8_CHARSET); response.setContentType("application/pdf; charset=UTF-8"); // 创建下载文件 ProducerEnum p = ProducerEnum.PDF; String downFileName = com.bstek.common.utils.StringUtils.randomFileName() + com.bstek.common.utils.StringUtils.getFileSuffix(p); - response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, "UTF-8")); + response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, UTF8_CHARSET)); response.setHeader("code", "20000"); ExportUtils.export(out, report, p); long end = System.currentTimeMillis(); @@ -425,12 +459,12 @@ public class ReportTemplateServiceImpl implements ReportTemplateService { report.setChartImages(chartImages); try { OutputStream out = response.getOutputStream(); - response.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding(UTF8_CHARSET); response.setContentType("application/octet-stream; charset=UTF-8"); // 创建下载文件 ProducerEnum p = ProducerEnum.valueOf(type.toUpperCase()); String downFileName = com.bstek.common.utils.StringUtils.randomFileName() + com.bstek.common.utils.StringUtils.getFileSuffix(p); - response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, "UTF-8")); + response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, UTF8_CHARSET)); response.setHeader("code", "20000"); long start = System.currentTimeMillis(); ExportUtils.export(out, report, p);