1、报表基础模块:内置模板相关的操作权限限制、新增模板名称唯一性限制;2、分析页统计:排单面积统计关联表修改;

This commit is contained in:
gaoqr
2024-09-05 12:20:46 +08:00
parent 54ce827f9a
commit 72c418544c
6 changed files with 139 additions and 19 deletions
@@ -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();
}
}
@@ -161,9 +161,8 @@
,CONCAT(YEAR(p.create_time), '-', MONTH(p.create_time), '-', DAY(p.create_time)) as date
</if>
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;
@@ -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, "报表数据源不存在");
@@ -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);
}
}
@@ -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);
}
}
}
@@ -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<ReportTemplateDO> wrapper = new LambdaQueryWrapperX<ReportTemplateDO>().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);