报表服务新增入参/枚举/错误码i18n国际化整理

This commit is contained in:
gaoqr
2025-12-04 15:20:47 +08:00
parent 24e192a895
commit 4240b1ca1f
37 changed files with 320 additions and 127 deletions
@@ -7,6 +7,11 @@ package com.cf.imes.framework.common.constants;
* @since 2025/11/21 11:33 * @since 2025/11/21 11:33
*/ */
public final class ResourceBundleConstants { public final class ResourceBundleConstants {
/**
* 错误码资源包
*/
public static final String MESSAGE_ERROR_PATH = "message_errorcode";
/** /**
* 枚举资源包 * 枚举资源包
*/ */
@@ -6,6 +6,8 @@ import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Locale;
/** /**
* 国际化工具类 * 国际化工具类
* *
@@ -29,4 +31,16 @@ public class I18nUtils {
public String getMessage(String code, Object... args) { public String getMessage(String code, Object... args) {
return messageSource.getMessage(code, args, code, LocaleContextHolder.getLocale()); return messageSource.getMessage(code, args, code, LocaleContextHolder.getLocale());
} }
/**
* 获取国际化描述
*
* @param locale
* @param code
* @param args
* @return
*/
public String getMessage(Locale locale, String code, Object... args) {
return messageSource.getMessage(code, args, code, locale);
}
} }
@@ -25,7 +25,7 @@ public class ResourceBundleUtils {
* @param args 占位符数组 * @param args 占位符数组
* @return * @return
*/ */
public static String getMessage(String baseName, String key, String defaultMessage, Locale locale, Object args) { public static String getMessage(String baseName, String key, String defaultMessage, Locale locale, Object... args) {
try { try {
ResourceBundle messageEnum = ResourceBundle.getBundle(baseName, locale); ResourceBundle messageEnum = ResourceBundle.getBundle(baseName, locale);
if (messageEnum != null) { if (messageEnum != null) {
@@ -2,8 +2,8 @@ package com.cf.imes.framework.web.core.filter;
import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import com.cf.imes.framework.common.util.servlet.ServletUtils; import com.cf.imes.framework.common.util.servlet.ServletUtils;
import com.cf.imes.framework.web.config.WebProperties; import com.cf.imes.framework.web.config.WebProperties;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -14,6 +14,9 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import static com.cf.imes.framework.common.constants.ResourceBundleConstants.MESSAGE_ERROR_PATH;
import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED;
/** /**
* @author there * @author there
* 多数据源过滤器 * 多数据源过滤器
@@ -27,7 +30,6 @@ public class DataSourceFilter extends OncePerRequestFilter {
*/ */
public static final String AUTHORIZATION_BEARER = "Bearer"; public static final String AUTHORIZATION_BEARER = "Bearer";
private WebProperties webProperties; private WebProperties webProperties;
public DataSourceFilter (WebProperties webProperties) { public DataSourceFilter (WebProperties webProperties) {
@@ -46,7 +48,7 @@ public class DataSourceFilter extends OncePerRequestFilter {
String dataCode = request.getHeader(DATA_SOURCE_CODE); String dataCode = request.getHeader(DATA_SOURCE_CODE);
if(CharSequenceUtil.isEmpty(dataCode)) { if(CharSequenceUtil.isEmpty(dataCode)) {
//TODO 如果要严谨一点,应该再去校验一下token //TODO 如果要严谨一点,应该再去校验一下token
ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "访问令牌已过期")); ServletUtils.writeJSON(response, CommonResult.error(UNAUTHORIZED.getCode(), ResourceBundleUtils.getMessage(MESSAGE_ERROR_PATH, UNAUTHORIZED.getMsg(), UNAUTHORIZED.getMsg(), request.getLocale())));
log.info("Let the user log in because there is no data-code! requestURI==>{}", request.getRequestURI()); log.info("Let the user log in because there is no data-code! requestURI==>{}", request.getRequestURI());
return; return;
} }
@@ -11,24 +11,28 @@ import com.cf.imes.framework.common.exception.ErrorCode;
public final class ErrorCodeConstants { public final class ErrorCodeConstants {
// ========== UREPORT template模块 1-003-001-000 ========== // ========== UREPORT template模块 1-003-001-000 ==========
public static final ErrorCode TEMPLATE_NOT_EXISTS = new ErrorCode(1_004_001_001, "报表模板信息不存在"); public static final ErrorCode TEMPLATE_NOT_EXISTS = new ErrorCode(1_004_001_001, "report.template.not_exists");
public static final ErrorCode TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR = new ErrorCode(1_004_001_002, "内置模板操作权限不足"); public static final ErrorCode TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR = new ErrorCode(1_004_001_002, "report.template.buildin_operation_permission_error");
public static final ErrorCode TEMPLATE_NAME_UNIQE_ERROR = new ErrorCode(1_004_001_003, "模板名【{}】已存在,请编辑模板名后重试"); public static final ErrorCode TEMPLATE_NAME_UNIQE_ERROR = new ErrorCode(1_004_001_003, "report.template.name_uniqe_error");
public static final ErrorCode TEMPLATE_PREIVEW_QUERYPARAM_EMPTY = new ErrorCode(1_004_001_004, "查询参数不能为空:{}"); public static final ErrorCode TEMPLATE_PREIVEW_QUERYPARAM_EMPTY = new ErrorCode(1_004_001_004, "report.template.preview_queryparam_empty");
public static final ErrorCode TEMPLATE_IMPORT_CONTENT_EMPTY_ERROR = new ErrorCode(1_004_001_005, "导入模板内容不能为空,请检查"); public static final ErrorCode TEMPLATE_IMPORT_CONTENT_EMPTY_ERROR = new ErrorCode(1_004_001_005, "report.template.import_content_empty_error");
public static final ErrorCode TEMPLATE_PREVIEW_TEMPLATE_CONTENT_EMPTY_ERROR = new ErrorCode(1_004_001_006, "报表模板内容为空,请检查"); public static final ErrorCode TEMPLATE_PREVIEW_TEMPLATE_CONTENT_EMPTY_ERROR = new ErrorCode(1_004_001_006, "report.template.preview_template_content_empty_error");
public static final ErrorCode TEMPLATE_IMPORT_EXCEL_FILE_NOT_SUPPORT_ERROR = new ErrorCode(1_004_001_007, "report.template.import.excel.file.not.support");
public static final ErrorCode TEMPLATE_PREVIEW_PRINT_ERROR = new ErrorCode(1_004_001_008, "report.template.preview.print_error");
public static final ErrorCode TEMPLATE_PREVIEW_DOWNLOAD_ERROR = new ErrorCode(1_004_001_009, "report.template.preview.download_error");
public static final ErrorCode TEMPLATE_EXPORT_ERROR = new ErrorCode(1_004_001_010, "report.template.export_error");
public static final ErrorCode TEMPLATE_IMPORT_ERROR = new ErrorCode(1_004_001_011, "report.template.import_error");
// ========== UREPORT datasource模块 1-003-002-000 ========== // ========== UREPORT datasource模块 1-003-002-000 ==========
public static final ErrorCode DATASOURCE_NOT_EXISTS = new ErrorCode(1_004_002_001, "报表数据源不存在"); public static final ErrorCode DATASOURCE_NOT_EXISTS = new ErrorCode(1_004_002_001, "report.datasource.not_exists");
public static final ErrorCode DATASOURCE_CONNECT_FAIL = new ErrorCode(1_004_002_002, "报表数据源连接失败"); public static final ErrorCode DATASOURCE_CONNECT_FAIL = new ErrorCode(1_004_002_002, "report.datasource.connect_fail");
public static final ErrorCode DATASOURCE_SPRINGBEAN_GET_FAIL = new ErrorCode(1_004_002_003, "无法获取springbean【{}】"); public static final ErrorCode DATASOURCE_SPRINGBEAN_GET_FAIL = new ErrorCode(1_004_002_003, "report.datasource.springbean_get_fail");
public static final ErrorCode DATASOURCE_SPRINGBEAN_METHODS_GET_FAIL = new ErrorCode(1_004_002_004, "获取springbean方法列表失败,请检查】"); public static final ErrorCode DATASOURCE_SPRINGBEAN_METHODS_GET_FAIL = new ErrorCode(1_004_002_004, "report.datasource.springbean_methods_get_fail");
public static final ErrorCode DATASOURCE_BUILDIN_OPERATION_PERMISSION_ERROR = new ErrorCode(1_004_002_005, "内置数据源操作权限不足"); public static final ErrorCode DATASOURCE_BUILDIN_OPERATION_PERMISSION_ERROR = new ErrorCode(1_004_002_005, "report.datasource.buildin_operation_permission_error");
// ========== UREPORT dataset模块 1-003-003-000 ========== // ========== UREPORT dataset模块 1-003-003-000 ==========
public static final ErrorCode DATASET_NOT_EXISTS = new ErrorCode(1_004_003_001, "报表数据集不存在或权限不足"); public static final ErrorCode DATASET_NOT_EXISTS = new ErrorCode(1_004_003_001, "report.dataset.not_exists");
public static final ErrorCode DATASET_SQL_INJECTION_RISK = new ErrorCode(1_004_003_002, "存在SQL注入风险"); public static final ErrorCode DATASET_SQL_INJECTION_RISK = new ErrorCode(1_004_003_002, "report.dataset.sql_injection_risk");
public static final ErrorCode DATASET_SQL_REQUIRED = new ErrorCode(1_004_003_003, "SQL语句不能为空"); public static final ErrorCode DATASET_SQL_REQUIRED = new ErrorCode(1_004_003_003, "report.dataset.sql_required");
public static final ErrorCode DATASET_GET_FIELDS_ERROR = new ErrorCode(1_004_003_004, "获取表字段异常"); public static final ErrorCode DATASET_GET_FIELDS_ERROR = new ErrorCode(1_004_003_004, "report.dataset.get_fields_error");
} }
@@ -23,6 +23,6 @@ public class ReportDatasetFieldVO implements Serializable {
* 字段名称 * 字段名称
*/ */
@Schema(description = "字段名称") @Schema(description = "字段名称")
@NotBlank(message = "字段名称不能为空") @NotBlank(message = "report.dataset.save.fields.name.notBlank")
private String name; private String name;
} }
@@ -24,14 +24,14 @@ public class ReportDatasetParameterVO implements Serializable {
* 参数名称 * 参数名称
*/ */
@Schema(description = "参数名称") @Schema(description = "参数名称")
@NotBlank(message = "参数名称不能为空") @NotBlank(message = "report.dataset.save.param.name.notBlank")
private String name; private String name;
/** /**
* 类型 * 类型
*/ */
@Schema(description = "参数类型") @Schema(description = "参数类型")
@NotBlank(message = "参数类型不能为空") @NotBlank(message = "report.dataset.save.param.type.notBlank")
private String type; private String type;
/** /**
@@ -34,12 +34,12 @@ public class ReportDatasetSaveReqVO implements Serializable {
private Long id; private Long id;
@Schema(description = "数据集名称", example = "测试数据集") @Schema(description = "数据集名称", example = "测试数据集")
@NotBlank @NotBlank(message = "report.dataset.save.name.notBlank")
@Length(min = 1, max = 64, message = "数据集名称长度不能超过64个字符") @Length(min = 1, max = 64, message = "report.dataset.save.name.length")
private String name; private String name;
@Schema(description = "数据源id", example = "1") @Schema(description = "数据源id", example = "1")
@NotNull(message = "数据源id不能为空") @NotNull(message = "report.dataset.save.datasourceId.notNull")
private Long datasourceId; private Long datasourceId;
@Schema(description = "动态查询SQL") @Schema(description = "动态查询SQL")
@@ -47,16 +47,16 @@ public class ReportDatasetSaveReqVO implements Serializable {
private String sql; private String sql;
@Schema(description = "bean数据源方法名") @Schema(description = "bean数据源方法名")
@Length(min = 1, max = 64, message = "bean数据源方法名长度不能超过64个字符") @Length(min = 1, max = 64, message = "report.dataset.save.method.length")
private String method; private String method;
@Schema(description = "参数列表") @Schema(description = "参数列表")
@Size(max = 30, message = "参数列表数量不能超过30个") @Size(max = 30, message = "report.dataset.save.parameters.size")
@Valid @Valid
private List<ReportDatasetParameterVO> parameters = new ArrayList<>(); private List<ReportDatasetParameterVO> parameters = new ArrayList<>();
@Schema(description = "字段列表") @Schema(description = "字段列表")
@Size(max = 100, message = "字段列表数量不能超过100个") @Size(max = 100, message = "report.dataset.save.fields.size")
@Valid @Valid
private List<ReportDatasetFieldVO> fields = new ArrayList<>(); private List<ReportDatasetFieldVO> fields = new ArrayList<>();
} }
@@ -105,7 +105,7 @@ public class ReportDatasourceController {
@Operation(summary = "获取springbean数据源返回对象") @Operation(summary = "获取springbean数据源返回对象")
@Parameter(name = "clazz", description = "返回对象类路径全名不能为空", required = true) @Parameter(name = "clazz", description = "返回对象类路径全名不能为空", required = true)
@PreAuthorize("@ss.hasPermission('report:design')") @PreAuthorize("@ss.hasPermission('report:design')")
public List<Field> springbeanFieldList(@RequestParam(value = "clazz") @NotEmpty(message = "类路径全名不能为空") @Size(max = 100, message = "类路径全名不能超过100个字符") String clazz) { public List<Field> springbeanFieldList(@RequestParam(value = "clazz") @NotEmpty(message = "report.datasource.spring.bean.field.clazz.notEmpty") @Size(max = 100, message = "report.datasource.spring.bean.field.clazz.size") String clazz) {
return datasourceService.getSpringBeanResultFieldList(clazz); return datasourceService.getSpringBeanResultFieldList(clazz);
} }
@@ -113,7 +113,7 @@ public class ReportDatasourceController {
@Operation(summary = "获取springbean数据源方法类表") @Operation(summary = "获取springbean数据源方法类表")
@Parameter(name = "beanId", description = "springbeanId", required = true) @Parameter(name = "beanId", description = "springbeanId", required = true)
@PreAuthorize("@ss.hasPermission('report:design')") @PreAuthorize("@ss.hasPermission('report:design')")
public CommonResult<List<String>> getBeanDatasourceList(@RequestParam(value = "beanId") @NotEmpty(message = "beanId不能为空") @Size(max = 100, message = "beanId不能超过100个字符") String beanId) { public CommonResult<List<String>> getBeanDatasourceList(@RequestParam(value = "beanId") @NotEmpty(message = "report.datasource.bean.methods.query.beanId.notEmpty") @Size(max = 100, message = "report.datasource.bean.methods.query.beanId.size") String beanId) {
return success(datasourceService.loadBeanMethods(beanId)); return success(datasourceService.loadBeanMethods(beanId));
} }
@@ -25,14 +25,14 @@ public class ReportDatasourceParameterVO implements Serializable {
* 参数名称 * 参数名称
*/ */
@Schema(description = "参数名称") @Schema(description = "参数名称")
@NotBlank(message = "参数名称不能为空") @NotBlank(message = "report.datasource.query.param.name.notBlank")
private String name; private String name;
/** /**
* 类型 * 类型
*/ */
@Schema(description = "参数类型") @Schema(description = "参数类型")
@NotBlank(message = "参数类型不能为空") @NotBlank(message = "report.datasource.query.param.type.notBlank")
private String type; private String type;
/** /**
@@ -24,21 +24,21 @@ import java.util.List;
@NoArgsConstructor @NoArgsConstructor
public class ReportDatasourcePreviewReqVO { public class ReportDatasourcePreviewReqVO {
@Schema(description = "数据源连接信息") @Schema(description = "数据源连接信息")
@NotNull(message = "数据源连接信息不能为空") @NotNull(message = "report.datasource.preview.conn.test.info.notNull")
@Valid @Valid
private ReportDatasourceTestConnReqVO info; private ReportDatasourceTestConnReqVO info;
@Schema(description = "查询语句") @Schema(description = "查询语句")
@NotBlank(message = "查询语句不能为空") @NotBlank(message = "report.datasource.preview.sql.notBlank")
@SqlIllegalValid @SqlIllegalValid
private String sql; private String sql;
@Schema(description = "查询参数列表") @Schema(description = "查询参数列表")
@Size(max = 30, message = "查询参数列表数量不能超过30个") @Size(max = 30, message = "report.datasource.preview.parameters.size")
@Valid @Valid
private List<ReportDatasourceParameterVO> parameters; private List<ReportDatasourceParameterVO> parameters;
@Schema(description = "数据源编号") @Schema(description = "数据源编号")
@NotNull(message = "数据源编号不能为空") @NotNull(message = "report.datasource.preview.datasourceId.notNull")
private Long datasourceId; private Long datasourceId;
} }
@@ -33,8 +33,8 @@ public class ReportDatasourceSaveReqVO implements Serializable {
private Long id; private Long id;
@Schema(description = "数据源名称", example = "测试库") @Schema(description = "数据源名称", example = "测试库")
@NotBlank @NotBlank(message = "report.datasource.save.name.notBlank")
@Length(min = 1, max = 64, message = "数据源名称长度不能超过64个字符") @Length(min = 1, max = 64, message = "report.datasource.save.name.length")
private String name; private String name;
@Schema(description = "数据源类型,jdbc、spring、api", example = "1") @Schema(description = "数据源类型,jdbc、spring、api", example = "1")
@@ -46,30 +46,30 @@ public class ReportDatasourceSaveReqVO implements Serializable {
private Integer buildinType; private Integer buildinType;
@Schema(description = "spring型数据源id") @Schema(description = "spring型数据源id")
@Length(max = 64, message = "spring型数据源id长度不能超过64个字符") @Length(max = 64, message = "report.datasource.save.beanId.length")
private String beanId; private String beanId;
@Schema(description = "数据源驱动类",example = "com.mysql.cj.jdbc.Driver") @Schema(description = "数据源驱动类",example = "com.mysql.cj.jdbc.Driver")
@Length(max = 64, message = "数据源驱动类长度不能超过64个字符") @Length(max = 64, message = "report.datasource.save.driver.length")
private String driver; private String driver;
@Schema(description = "数据源地址", example = "https://www.cf.com") @Schema(description = "数据源地址", example = "https://www.cf.com")
@Length(max = 255, message = "数据源地址长度不能超过255个字符") @Length(max = 255, message = "report.datasource.save.url.length")
private String url; private String url;
@Schema(description = "数据源用户名", example = "晨丰") @Schema(description = "数据源用户名", example = "晨丰")
@Length(max = 64, message = "数据源用户名长度不能超过64个字符") @Length(max = 64, message = "report.datasource.save.username.length")
private String username; private String username;
@Schema(description = "数据源密码", example = "晨丰") @Schema(description = "数据源密码", example = "晨丰")
@Length(max = 64, message = "数据源密码长度不能超过64个字符") @Length(max = 64, message = "report.datasource.save.password.length")
private String password; private String password;
@Schema(description = "备注", example = "该模板仅供生产使用") @Schema(description = "备注", example = "该模板仅供生产使用")
@Length(max = 64, message = "备注长度不能超过64个字符") @Length(max = 64, message = "report.datasource.save.remark.size")
private String remark; private String remark;
@Schema(description = "请求头参数") @Schema(description = "请求头参数")
@Size(max = 30, message = "请求头参数数量不能超过30个") @Size(max = 30, message = "report.datasource.save.headers.size")
private List<Map<String, String>> headers; private List<Map<String, String>> headers;
} }
@@ -20,18 +20,18 @@ import jakarta.validation.constraints.NotBlank;
public class ReportDatasourceTestConnReqVO { public class ReportDatasourceTestConnReqVO {
@Schema(description = "数据源驱动类", example = "com.mysql.cj.jdbc.Driver") @Schema(description = "数据源驱动类", example = "com.mysql.cj.jdbc.Driver")
@NotBlank(message = "数据源驱动类不能为空") @NotBlank(message = "report.datasource.conn.test.driverClassName.notBlank")
private String driverClassName; private String driverClassName;
@Schema(description = "数据源地址", example = "https://www.cf.com") @Schema(description = "数据源地址", example = "https://www.cf.com")
@NotBlank(message = "数据源地址不能为空") @NotBlank(message = "report.datasource.conn.test.url.notBlank")
private String url; private String url;
@Schema(description = "数据源用户名", example = "晨丰") @Schema(description = "数据源用户名", example = "晨丰")
@NotBlank(message = "数据源用户名不能为空") @NotBlank(message = "report.datasource.conn.test.username.notBlank")
private String userName; private String userName;
@Schema(description = "数据源密码", example = "晨丰") @Schema(description = "数据源密码", example = "晨丰")
@NotBlank(message = "数据源密码不能为空") @NotBlank(message = "report.datasource.conn.test.password.notBlank")
private String password; private String password;
} }
@@ -23,7 +23,6 @@ import lombok.extern.slf4j.Slf4j;
import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.TerminalNode; import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -41,6 +40,7 @@ import java.util.Map;
import static com.cf.imes.framework.common.pojo.CommonResult.success; import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.*; import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.*;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_IMPORT_EXCEL_FILE_NOT_SUPPORT_ERROR;
/** /**
* 报表模板信息控制器 * 报表模板信息控制器
@@ -101,7 +101,7 @@ public class ReportTemplateController {
@Operation(summary = "获取报表模板信息列表") @Operation(summary = "获取报表模板信息列表")
@PreAuthorize("@ss.hasPermission('report:design')") @PreAuthorize("@ss.hasPermission('report:design')")
public CommonResult<List<ReportTemplateRespVO>> getTemplatePage( public CommonResult<List<ReportTemplateRespVO>> getTemplatePage(
@RequestParam(value = "name", required = false) @Size(max = 64, message = "模板名称长度不能超过64个字符") String name, @RequestParam(value = "name", required = false) @Size(max = 64, message = "report.template.page.name.size") String name,
@RequestParam(value = "organId", required = false) Long organId) { @RequestParam(value = "organId", required = false) Long organId) {
ReportTemplateReqVO reqVO = new ReportTemplateReqVO(name, null, organId); ReportTemplateReqVO reqVO = new ReportTemplateReqVO(name, null, organId);
return success(BeanUtils.toBean(templateService.getReportTemplateList(reqVO), ReportTemplateRespVO.class)); return success(BeanUtils.toBean(templateService.getReportTemplateList(reqVO), ReportTemplateRespVO.class));
@@ -139,14 +139,14 @@ public class ReportTemplateController {
@PostMapping("/template/download/{type}") @PostMapping("/template/download/{type}")
@Operation(summary = "模板预览下载") @Operation(summary = "模板预览下载")
@PreAuthorize("@ss.hasAnyPermissions('system:report:preview','base:report:preview')") @PreAuthorize("@ss.hasAnyPermissions('system:report:preview','base:report:preview')")
public void print(@PathVariable @ReportTemplateProducerTypeInEnum @NotBlank(message = "模板下载类型不能为空") String type, @RequestBody ReportTemplatePreviewReqVO reqVO, HttpServletResponse response) { public void print(@PathVariable @ReportTemplateProducerTypeInEnum @NotBlank(message = "report.template.preview.download.type.notBlank") String type, @RequestBody ReportTemplatePreviewReqVO reqVO, HttpServletResponse response) {
templateService.download(type, reqVO, response); templateService.download(type, reqVO, response);
} }
@PostMapping("/template/download/{type}/common") @PostMapping("/template/download/{type}/common")
@Operation(summary = "模板预览下载") @Operation(summary = "模板预览下载")
@PreAuthorize("@ss.hasAnyPermissions('system:report:preview','base:report:preview')") @PreAuthorize("@ss.hasAnyPermissions('system:report:preview','base:report:preview')")
public void commonPrint(@PathVariable @ReportTemplateProducerTypeInEnum @NotBlank(message = "模板下载类型不能为空") String type, @RequestBody ReportTemplateCommonPreviewReqVO reqVO, HttpServletResponse response) { public void commonPrint(@PathVariable @ReportTemplateProducerTypeInEnum @NotBlank(message = "report.template.preview.download.type.notBlank") String type, @RequestBody ReportTemplateCommonPreviewReqVO reqVO, HttpServletResponse response) {
templateService.commonDownload(type, reqVO, response); templateService.commonDownload(type, reqVO, response);
} }
@@ -160,14 +160,14 @@ public class ReportTemplateController {
report.setReportFullName(""); report.setReportFullName("");
return new ReportDefinitionWrapper(report); return new ReportDefinitionWrapper(report);
} }
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "文件未识别"); throw new ServiceException(TEMPLATE_IMPORT_EXCEL_FILE_NOT_SUPPORT_ERROR);
} }
@GetMapping("/scriptValidation") @GetMapping("/scriptValidation")
@Operation(summary = "校验表达式") @Operation(summary = "校验表达式")
@Parameter(name = "content", description = "表达式", required = true) @Parameter(name = "content", description = "表达式", required = true)
@PreAuthorize("@ss.hasPermission('report:design')") @PreAuthorize("@ss.hasPermission('report:design')")
public List<ErrorInfo> scriptValidation(@RequestParam("content") @NotEmpty(message = "表达式不能为空") String content) { public List<ErrorInfo> scriptValidation(@RequestParam("content") @NotEmpty(message = "report.template.script.validate.content.notEmpty") String content) {
content = StringUtils.decode(content); content = StringUtils.decode(content);
ANTLRInputStream antlrInputStream = new ANTLRInputStream(content); ANTLRInputStream antlrInputStream = new ANTLRInputStream(content);
ReportParserLexer lexer = new ReportParserLexer(antlrInputStream); ReportParserLexer lexer = new ReportParserLexer(antlrInputStream);
@@ -190,7 +190,7 @@ public class ReportTemplateController {
@Operation(summary = "解析表达式中的数据集") @Operation(summary = "解析表达式中的数据集")
@Parameter(name = "expr", description = "表达式", required = true) @Parameter(name = "expr", description = "表达式", required = true)
@PreAuthorize("@ss.hasPermission('report:design')") @PreAuthorize("@ss.hasPermission('report:design')")
public Map<String, String> parseDatasetName(@RequestParam("expr") @NotEmpty(message = "表达式不能为空") String expr) { public Map<String, String> parseDatasetName(@RequestParam("expr") @NotEmpty(message = "report.template.script.validate.content.notEmpty") String expr) {
ANTLRInputStream antlrInputStream = new ANTLRInputStream(expr); ANTLRInputStream antlrInputStream = new ANTLRInputStream(expr);
ReportParserLexer lexer = new ReportParserLexer(antlrInputStream); ReportParserLexer lexer = new ReportParserLexer(antlrInputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer); CommonTokenStream tokenStream = new CommonTokenStream(lexer);
@@ -221,7 +221,7 @@ public class ReportTemplateController {
@Operation(summary = "导入模版") @Operation(summary = "导入模版")
@OperateLog(type = IMPORT) @OperateLog(type = IMPORT)
@PreAuthorize("@ss.hasAnyPermissions('system:report:import','base:report:import')") @PreAuthorize("@ss.hasAnyPermissions('system:report:import','base:report:import')")
public CommonResult<Boolean> importTemplate(@RequestParam("name") @NotEmpty(message = "模版名称不能为空") String name, @RequestParam("file") MultipartFile file) { public CommonResult<Boolean> importTemplate(@RequestParam("name") @NotEmpty(message = "report.template.import.name.notEmpty") String name, @RequestParam("file") MultipartFile file) {
templateService.importTemplate(name, file); templateService.importTemplate(name, file);
return success(true); return success(true);
} }
@@ -16,32 +16,32 @@ import java.util.Map;
@Schema(description = "管理后台 - 报表模板通用预览请求参数 Request VO") @Schema(description = "管理后台 - 报表模板通用预览请求参数 Request VO")
public class ReportTemplateCommonPreviewReqVO { public class ReportTemplateCommonPreviewReqVO {
@Schema(description = "页码",example = "1") @Schema(description = "页码",example = "1")
@Min(value = 1, message = "页码最小值为 1") @Min(value = 1, message = "page.pageNo.min")
private int pageIndex; private int pageIndex;
@Schema(description = "报表模板编号") @Schema(description = "报表模板编号")
@NotNull(message = "报表模板编号不能为空") @NotNull(message = "report.template.preview.templateId.notNull")
private Long templateId; private Long templateId;
/** /**
* 表单参数 * 表单参数
*/ */
@Schema(description = "表单参数") @Schema(description = "表单参数")
@Size(max = 30, message = "表单参数数量不能超过30个") @Size(max = 30, message = "report.template.preview.query.size")
private Map<String, Object> query; private Map<String, Object> query;
/** /**
* 表单对应组件唯一标识 * 表单对应组件唯一标识
*/ */
@Schema(description = "表单对应组件唯一标识") @Schema(description = "表单对应组件唯一标识")
@Size(max = 30, message = "表单对应组件唯一标识数量不能超过30个") @Size(max = 30, message = "report.template.preview.component.size")
private Map<String, String> component; private Map<String, String> component;
/** /**
* 图表图片目前用于PDF导出 * 图表图片目前用于PDF导出
*/ */
@Schema(description = "图表图片") @Schema(description = "图表图片")
@Size(max = 30, message = "图表图片数量不能超过30个") @Size(max = 30, message = "report.template.preview.chartImages.size")
private Map<String, String> chartImages; private Map<String, String> chartImages;
} }
@@ -16,32 +16,32 @@ import java.util.Map;
@Schema(description = "管理后台 - 报表模板预览请求参数 Request VO") @Schema(description = "管理后台 - 报表模板预览请求参数 Request VO")
public class ReportTemplatePreviewReqVO { public class ReportTemplatePreviewReqVO {
@Schema(description = "页码",example = "1") @Schema(description = "页码",example = "1")
@Min(value = 1, message = "页码最小值为 1") @Min(value = 1, message = "page.pageNo.min")
private int pageIndex; private int pageIndex;
@Schema(description = "报表内容") @Schema(description = "报表内容")
@NotNull(message = "预览报表内容不能为空") @NotNull(message = "report.template.preview.content.notNull")
private String content; private String content;
/** /**
* 表单参数 * 表单参数
*/ */
@Schema(description = "表单参数") @Schema(description = "表单参数")
@Size(max = 30, message = "表单参数数量不能超过30个") @Size(max = 30, message = "report.template.preview.query.size")
private Map<String, Object> query; private Map<String, Object> query;
/** /**
* 表单对应组件唯一标识 * 表单对应组件唯一标识
*/ */
@Schema(description = "表单对应组件唯一标识") @Schema(description = "表单对应组件唯一标识")
@Size(max = 30, message = "表单对应组件唯一标识数量不能超过30个") @Size(max = 30, message = "report.template.preview.component.size")
private Map<String, String> component; private Map<String, String> component;
/** /**
* 图表图片目前用于PDF导出 * 图表图片目前用于PDF导出
*/ */
@Schema(description = "图表图片") @Schema(description = "图表图片")
@Size(max = 30, message = "图表图片数量不能超过30个") @Size(max = 30, message = "report.template.preview.chartImages.size")
private Map<String, String> chartImages; private Map<String, String> chartImages;
} }
@@ -26,22 +26,22 @@ public class ReportTemplateSaveReqVO {
private Long id; private Long id;
@Schema(description = "模板名称", example = "生产单模板") @Schema(description = "模板名称", example = "生产单模板")
@NotBlank(message = "模板名称不能为空") @NotBlank(message = "report.template.save.name.notBlank")
@Length(min = 1, max = 30, message = "模板名称长度不能超过30个字符") @Length(min = 1, max = 30, message = "report.template.save.name.length")
private String name; private String name;
@Schema(description = "报表模板") @Schema(description = "报表模板")
private String content; private String content;
@Schema(description = "备注", example = "该模板仅供生产使用") @Schema(description = "备注", example = "该模板仅供生产使用")
@Length(max = 64, message = "备注长度不能超过64个字符") @Length(max = 64, message = "report.template.save.remark.size")
private String remark; private String remark;
@Schema(description = "数据源id列表") @Schema(description = "数据源id列表")
@Size(max = 30, message = "数据源数量不能超过30个") @Size(max = 30, message = "report.template.save.datasourceIds.size")
private Set<Long> datasourceIds; private Set<Long> datasourceIds;
@Schema(description = "数据集id列表") @Schema(description = "数据集id列表")
@Size(max = 30, message = "数据集数量不能超过30个") @Size(max = 30, message = "report.template.save.datasetIds.size")
private Set<Long> datasetIds; private Set<Long> datasetIds;
} }
@@ -1,6 +0,0 @@
/**
* 属于 report 模块的 framework 封装
*
* @author 晨丰科技
*/
package com.cf.imes.module.report.framework;
@@ -1,27 +0,0 @@
package com.cf.imes.module.report.framework.web.core.handler;
import com.bstek.ureport.exception.ReportException;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.pojo.CommonResult;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 自定义报表异常处理器
*
* @author Gqr
* @since 2024/9/2 14:52
*/
@RestControllerAdvice
@AllArgsConstructor
@Slf4j
public class ReportExceptionHandler {
@ExceptionHandler(value = ReportException.class)
public CommonResult reportExceptionHandler(ReportException ex) {
log.warn("[reportExceptionHandler]", ex);
return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), String.format("报表异常:%s", ex.getMessage()));
}
}
@@ -10,7 +10,6 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.ContentType; import cn.hutool.http.ContentType;
import cn.hutool.http.Header; import cn.hutool.http.Header;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bstek.common.exception.ReportDesignException; import com.bstek.common.exception.ReportDesignException;
@@ -30,7 +29,6 @@ import com.bstek.ureport.definition.searchform.InputComponent;
import com.bstek.ureport.definition.searchform.SearchForm; import com.bstek.ureport.definition.searchform.SearchForm;
import com.bstek.ureport.definition.searchform.TextInputComponent; import com.bstek.ureport.definition.searchform.TextInputComponent;
import com.bstek.ureport.exception.ReportComputeException; import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.export.ExportUtils; import com.bstek.ureport.export.ExportUtils;
import com.bstek.ureport.export.ProducerEnum; import com.bstek.ureport.export.ProducerEnum;
import com.bstek.ureport.export.ReportRender; import com.bstek.ureport.export.ReportRender;
@@ -87,10 +85,14 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_BUILDIN_OPERATION_PERMISSION_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_EXPORT_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_IMPORT_CONTENT_EMPTY_ERROR; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_IMPORT_CONTENT_EMPTY_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_IMPORT_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_NAME_UNIQE_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; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_NOT_EXISTS;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_PREIVEW_QUERYPARAM_EMPTY; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_PREIVEW_QUERYPARAM_EMPTY;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_PREVIEW_DOWNLOAD_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_PREVIEW_PRINT_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_PREVIEW_TEMPLATE_CONTENT_EMPTY_ERROR; import static com.cf.imes.module.report.enums.ErrorCodeConstants.TEMPLATE_PREVIEW_TEMPLATE_CONTENT_EMPTY_ERROR;
/** /**
@@ -450,8 +452,8 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
* @param reportDefinition 报表定义 * @param reportDefinition 报表定义
*/ */
private void queryPreviewDatasource(Map<String, Object> query, ReportDefinition reportDefinition) { private void queryPreviewDatasource(Map<String, Object> query, ReportDefinition reportDefinition) {
Object datasetIdsObj = query.get("datasetIds"); Object datasetIdsObj = query.get(DATASETIDS_FIELD_NAME);
Object datasourceIdsObj = query.get("datasourceIds"); Object datasourceIdsObj = query.get(DATASOURCEIDS_FIELD_NAME);
List<Long> datasetIds = new ArrayList<>(); List<Long> datasetIds = new ArrayList<>();
if (ObjectUtil.isNotNull(datasetIdsObj)) { if (ObjectUtil.isNotNull(datasetIdsObj)) {
@@ -614,7 +616,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
ToolUtils.logToConsole("获取打印文件耗时:" + (end - start) + "ms"); ToolUtils.logToConsole("获取打印文件耗时:" + (end - start) + "ms");
} catch (Exception ex) { } catch (Exception ex) {
log.error("模版预览打印异常", ex); log.error("模版预览打印异常", ex);
throw new ReportException(ex); throw new ServiceException(TEMPLATE_PREVIEW_PRINT_ERROR);
} }
} }
@@ -663,7 +665,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
ToolUtils.logToConsole("获取打印文件耗时:" + (end - start) + "ms"); ToolUtils.logToConsole("获取打印文件耗时:" + (end - start) + "ms");
} catch (Exception ex) { } catch (Exception ex) {
log.error("模版预览打印异常", ex); log.error("模版预览打印异常", ex);
throw new ReportException(ex); throw new ServiceException(TEMPLATE_PREVIEW_PRINT_ERROR);
} }
} }
@@ -700,7 +702,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
ToolUtils.logToConsole("下载 " + type + " 报表耗时:" + (end - start) + "ms"); ToolUtils.logToConsole("下载 " + type + " 报表耗时:" + (end - start) + "ms");
} catch (Exception ex) { } catch (Exception ex) {
log.error("模版预览下载文件异常", ex); log.error("模版预览下载文件异常", ex);
throw new ReportException(ex); throw new ServiceException(TEMPLATE_PREVIEW_DOWNLOAD_ERROR);
} }
} }
@@ -748,7 +750,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
ToolUtils.logToConsole("下载 " + type + " 报表耗时:" + (end - start) + "ms"); ToolUtils.logToConsole("下载 " + type + " 报表耗时:" + (end - start) + "ms");
} catch (Exception ex) { } catch (Exception ex) {
log.error("模版预览下载文件异常", ex); log.error("模版预览下载文件异常", ex);
throw new ReportException(ex); throw new ServiceException(TEMPLATE_PREVIEW_DOWNLOAD_ERROR);
} }
} }
@@ -779,7 +781,7 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
writer.flush(); writer.flush();
} catch (Exception ex) { } catch (Exception ex) {
log.error("模板导出异常", ex); log.error("模板导出异常", ex);
throw new ReportException(ex); throw new ServiceException(TEMPLATE_EXPORT_ERROR);
} finally { } finally {
IoUtil.close(writer); IoUtil.close(writer);
} }
@@ -817,13 +819,11 @@ public class ReportTemplateServiceImpl implements ReportTemplateService {
template.setType(ReportTemplateTypeEnum.CUSTOM); template.setType(ReportTemplateTypeEnum.CUSTOM);
} }
templateMapper.insert(template); templateMapper.insert(template);
} catch (JSONException je) {
throw new ReportException("文件解析失败,请检查文件格式和内容");
} catch (ServiceException sex) { } catch (ServiceException sex) {
throw sex; throw sex;
} catch (Exception ex) { } catch (Exception ex) {
log.error("模板导入异常", ex); log.error("模板导入异常", ex);
throw new ReportException(ex); throw new ServiceException(TEMPLATE_IMPORT_ERROR);
} }
} }
@@ -28,7 +28,7 @@ import java.lang.annotation.Target;
validatedBy = {ReportDatasourceTypeInEnumValidator.class} validatedBy = {ReportDatasourceTypeInEnumValidator.class}
) )
public @interface ReportDatasourceTypeInEnum { public @interface ReportDatasourceTypeInEnum {
String message() default "数据源类型[type]错误,请检查是否jdbc/spring/api"; String message() default "{report.datasource.type.invalid}";
Class<?>[] groups() default {}; Class<?>[] groups() default {};
@@ -24,7 +24,7 @@ import java.lang.annotation.Target;
validatedBy = {SqlIllegalValidator.class} validatedBy = {SqlIllegalValidator.class}
) )
public @interface SqlIllegalValid { public @interface SqlIllegalValid {
String message() default "sql语句非法输入,请检查"; String message() default "{report.datasource.sql.invalid}";
Class<?>[] groups() default {}; Class<?>[] groups() default {};
@@ -1,10 +1,14 @@
package com.cf.imes.module.report.validation.datasource; package com.cf.imes.module.report.validation.datasource;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.constants.ResourceBundleConstants;
import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext; import jakarta.validation.ConstraintValidatorContext;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@@ -24,6 +28,9 @@ public class SqlIllegalValidator implements ConstraintValidator<SqlIllegalValid,
private static final List<String> specialSymbolList = new ArrayList<>(); private static final List<String> specialSymbolList = new ArrayList<>();
private static final String REPORT_DATASOURCE_SQL_NOTE_INVALID_I18N_KEY = "report.datasource.sql.note.invalid";
private static final String REPORT_DATASOURCE_SQL_INJECT_RISKS_I18N_KEY = "report.datasource.sql.inject.risks";
static { static {
specialSymbolList.add(";"); specialSymbolList.add(";");
specialSymbolList.add("+"); specialSymbolList.add("+");
@@ -38,7 +45,7 @@ public class SqlIllegalValidator implements ConstraintValidator<SqlIllegalValid,
// 校验注释 // 校验注释
if (hasAnnotation(sql)) { if (hasAnnotation(sql)) {
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值 context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate("SQL中不允许包含注释,存在安全风险").addConstraintViolation(); context.buildConstraintViolationWithTemplate(ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, REPORT_DATASOURCE_SQL_NOTE_INVALID_I18N_KEY, REPORT_DATASOURCE_SQL_NOTE_INVALID_I18N_KEY, LocaleContextHolder.getLocale())).addConstraintViolation();
return false; return false;
} }
sql = sql.toLowerCase(); sql = sql.toLowerCase();
@@ -49,7 +56,7 @@ public class SqlIllegalValidator implements ConstraintValidator<SqlIllegalValid,
for (byte b = 0; b < arrayOfSensitiveKey.length; b++) { for (byte b = 0; b < arrayOfSensitiveKey.length; b++) {
if (checkSensitiveKey(sql, arrayOfSensitiveKey[b])) { if (checkSensitiveKey(sql, arrayOfSensitiveKey[b])) {
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值 context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate("SQL不合法,存在注入风险").addConstraintViolation(); context.buildConstraintViolationWithTemplate(ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, REPORT_DATASOURCE_SQL_INJECT_RISKS_I18N_KEY, REPORT_DATASOURCE_SQL_INJECT_RISKS_I18N_KEY, LocaleContextHolder.getLocale())).addConstraintViolation();
return false; return false;
} }
} }
@@ -58,7 +65,7 @@ public class SqlIllegalValidator implements ConstraintValidator<SqlIllegalValid,
String someKeywordStr = ".*" + skw + ".*"; String someKeywordStr = ".*" + skw + ".*";
if (Pattern.matches(someKeywordStr, sql)) { if (Pattern.matches(someKeywordStr, sql)) {
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值 context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate("SQL不合法,存在注入风险").addConstraintViolation(); context.buildConstraintViolationWithTemplate(ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ENUM_PATH, REPORT_DATASOURCE_SQL_INJECT_RISKS_I18N_KEY, REPORT_DATASOURCE_SQL_INJECT_RISKS_I18N_KEY, LocaleContextHolder.getLocale())).addConstraintViolation();
return false; return false;
} }
} }
@@ -24,7 +24,7 @@ import java.lang.annotation.Target;
validatedBy = {SqlParamInjectionValidator.class} validatedBy = {SqlParamInjectionValidator.class}
) )
public @interface SqlParamInjectionValid { public @interface SqlParamInjectionValid {
String message() default "sql查询参数默认值非法输入,请检查"; String message() default "{report.datasource.sql.param.invalid}";
Class<?>[] groups() default {}; Class<?>[] groups() default {};
@@ -28,7 +28,7 @@ import java.lang.annotation.Target;
validatedBy = {ReportTemplateProducerTypeInEnumValidator.class} validatedBy = {ReportTemplateProducerTypeInEnumValidator.class}
) )
public @interface ReportTemplateProducerTypeInEnum { public @interface ReportTemplateProducerTypeInEnum {
String message() default "类型错误,请检查是否PDF/WORD/EXCEL"; String message() default "{report.template.producer.type.invalid}";
Class<?>[] groups() default {}; Class<?>[] groups() default {};
@@ -28,7 +28,7 @@ import java.lang.annotation.Target;
validatedBy = {ReportTemplateTypeInEnumValidator.class} validatedBy = {ReportTemplateTypeInEnumValidator.class}
) )
public @interface ReportTemplateTypeInEnum { public @interface ReportTemplateTypeInEnum {
String message() default "类型错误,请检查是否0(内置)/1(自定义)"; String message() default "{report.template.type.invalid}";
Class<?>[] groups() default {}; Class<?>[] groups() default {};
@@ -90,6 +90,8 @@ spring:
redis: redis:
repositories: repositories:
enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度
messages:
basename: message,message_errorcode,message_enum
# 积木报表配置 # 积木报表配置
jeecg: jeecg:
@@ -0,0 +1,56 @@
number.float.length.error={0} 长度不合法,总长度不超过{1}位,小数点后不超过{2}位
number.greaterThanZero={0} 必须大于0
page.pageNo.min=页码最小值为 1
page.pageNo.notNull=页码不能为空
page.pageSize.max=每页条数最大值为 100
page.pageSize.min=每页条数最小值为 -1
page.pageSize.notNull=每页条数不能为空
report.template.save.name.notBlank=模板名称不能为空
report.template.save.name.length=模板名称长度不能超过30个字符
report.template.save.remark.size=备注长度不能超过64个字符
report.template.save.datasourceIds.size=数据源数量不能超过30个
report.template.save.datasetIds.size=数据集数量不能超过30个
report.template.page.name.size=模板名称长度不能超过64个字符
report.template.preview.content.notNull=预览报表内容不能为空
report.template.preview.query.size=表单参数数量不能超过30个
report.template.preview.component.size=表单对应组件唯一标识数量不能超过30个
report.template.preview.chartImages.size=图表图片数量不能超过30个
report.template.preview.templateId.notNull=报表模板编号不能为空
report.template.preview.download.type.notBlank=模板下载类型不能为空
report.template.script.validate.content.notEmpty=表达式不能为空
report.template.import.name.notEmpty=模版名称不能为空
report.datasource.save.name.notBlank=数据源名称不能为空
report.datasource.save.name.length=数据源名称长度不能超过64个字符
report.datasource.save.beanId.length=spring型数据源id长度不能超过64个字符
report.datasource.save.driver.length=数据源驱动类长度不能超过64个字符
report.datasource.save.url.length=数据源地址长度不能超过255个字符
report.datasource.save.username.length=数据源用户名长度不能超过64个字符
report.datasource.save.password.length=数据源密码长度不能超过64个字符
report.datasource.save.remark.size=备注长度不能超过64个字符
report.datasource.save.headers.size=请求头参数数量不能超过30个
report.datasource.spring.bean.field.clazz.notEmpty=类路径全名不能为空
report.datasource.spring.bean.field.clazz.size=类路径全名不能超过100个字符
report.datasource.bean.methods.query.beanId.notEmpty=beanId不能为空
report.datasource.bean.methods.query.beanId.size=beanId不能超过100个字符
report.datasource.conn.test.driverClassName.notBlank=数据源驱动类不能为空
report.datasource.conn.test.url.notBlank=数据源地址不能为空
report.datasource.conn.test.username.notBlank=数据源用户名不能为空
report.datasource.conn.test.password.notBlank=数据源密码不能为空
report.datasource.preview.conn.test.info.notNull=数据源连接信息不能为空
report.datasource.preview.sql.notBlank=查询语句不能为空
report.datasource.preview.parameters.size=查询参数列表数量不能超过30个
report.datasource.preview.datasourceId.notNull=数据源编号不能为空
report.datasource.query.param.name.notBlank=参数名称不能为空
report.datasource.query.param.type.notBlank=参数类型不能为空
report.dataset.save.name.notBlank=数据集名称不能为空
report.dataset.save.name.length=数据集名称长度不能超过64个字符
report.dataset.save.datasourceId.notNull=数据源id不能为空
report.dataset.save.method.length=bean数据源方法名长度不能超过64个字符
report.dataset.save.parameters.size=参数列表数量不能超过30个
report.dataset.save.fields.size=字段列表数量不能超过100个
report.dataset.save.fields.name.notBlank=字段名称不能为空
report.dataset.save.param.name.notBlank=参数名称不能为空
report.dataset.save.param.type.notBlank=参数类型不能为空
@@ -0,0 +1,56 @@
number.float.length.error={0} 長度不合法,總長度不能超過 {1} 位,小數點後不能超過 {2} 位
number.greaterThanZero={0} 必須大於 0
page.pageNo.min=頁碼最小值為 1
page.pageNo.notNull=頁碼不能為空
page.pageSize.max=每頁條數最大值為 100
page.pageSize.min=每頁條數最小值為 -1
page.pageSize.notNull=每頁條數不能為空
report.template.save.name.notBlank=模板名稱不能為空
report.template.save.name.length=模板名稱長度不能超過30個字元
report.template.save.remark.size=備註長度不能超過64個字元
report.template.save.datasourceIds.size=數據源數量不能超過30個
report.template.save.datasetIds.size=數據集數量不能超過30個
report.template.page.name.size=模板名稱長度不能超過64個字元
report.template.preview.content.notNull=預覽報表內容不能為空
report.template.preview.query.size=表單參數數量不能超過30個
report.template.preview.component.size=表單對應元件唯一標識數量不能超過30個
report.template.preview.chartImages.size=圖表圖片數量不能超過30個
report.template.preview.templateId.notNull=報表模板編號不能為空
report.template.preview.download.type.notBlank=模板下載類型不能為空
report.template.script.validate.content.notEmpty=表達式不能為空
report.template.import.name.notEmpty=模板名稱不能為空
report.datasource.save.name.notBlank=數據源名稱不能為空
report.datasource.save.name.length=數據源名稱長度不能超過64個字元
report.datasource.save.beanId.length=Spring型數據源ID長度不能超過64個字元
report.datasource.save.driver.length=數據源驅動類長度不能超過64個字元
report.datasource.save.url.length=數據源地址長度不能超過255個字元
report.datasource.save.username.length=數據源使用者名稱長度不能超過64個字元
report.datasource.save.password.length=數據源密碼長度不能超過64個字元
report.datasource.save.remark.size=備註長度不能超過64個字元
report.datasource.save.headers.size=請求頭參數數量不能超過30個
report.datasource.spring.bean.field.clazz.notEmpty=類路徑全名不能為空
report.datasource.spring.bean.field.clazz.size=類路徑全名不能超過100個字元
report.datasource.bean.methods.query.beanId.notEmpty=beanId不能為空
report.datasource.bean.methods.query.beanId.size=beanId不能超過100個字元
report.datasource.conn.test.driverClassName.notBlank=數據源驅動類不能為空
report.datasource.conn.test.url.notBlank=數據源地址不能為空
report.datasource.conn.test.username.notBlank=數據源使用者名稱不能為空
report.datasource.conn.test.password.notBlank=數據源密碼不能為空
report.datasource.preview.conn.test.info.notNull=數據源連線資訊不能為空
report.datasource.preview.sql.notBlank=查詢語句不能為空
report.datasource.preview.parameters.size=查詢參數列表數量不能超過30個
report.datasource.preview.datasourceId.notNull=數據源編號不能為空
report.datasource.query.param.name.notBlank=參數名稱不能為空
report.datasource.query.param.type.notBlank=參數類型不能為空
report.dataset.save.name.notBlank=數據集名稱不能為空
report.dataset.save.name.length=數據集名稱長度不能超過64個字元
report.dataset.save.datasourceId.notNull=數據源ID不能為空
report.dataset.save.method.length=bean數據源方法名長度不能超過64個字元
report.dataset.save.parameters.size=參數列表數量不能超過30個
report.dataset.save.fields.size=字段列表數量不能超過100個
report.dataset.save.fields.name.notBlank=字段名稱不能為空
report.dataset.save.param.name.notBlank=參數名稱不能為空
report.dataset.save.param.type.notBlank=參數類型不能為空
@@ -0,0 +1,56 @@
number.float.length.error={0} length is invalid. Total length must not exceed {1} digits, and decimal places must not exceed {2} digits
number.greaterThanZero={0} must be greater than 0
page.pageNo.min=Page number must be at least 1
page.pageNo.notNull=Page number cannot be empty
page.pageSize.max=Page size cannot exceed 100
page.pageSize.min=Page size must be at least -1
page.pageSize.notNull=Page size cannot be empty
report.template.save.name.notBlank=Template name cannot be empty
report.template.save.name.length=Template name cannot exceed 30 characters
report.template.save.remark.size=Remark cannot exceed 64 characters
report.template.save.datasourceIds.size=Number of data sources cannot exceed 30
report.template.save.datasetIds.size=Number of datasets cannot exceed 30
report.template.page.name.size=Template name cannot exceed 64 characters
report.template.preview.content.notNull=Preview content cannot be empty
report.template.preview.query.size=Number of form parameters cannot exceed 30
report.template.preview.component.size=Number of form component identifiers cannot exceed 30
report.template.preview.chartImages.size=Number of chart images cannot exceed 30
report.template.preview.templateId.notNull=Template ID cannot be empty
report.template.preview.download.type.notBlank=Template download type cannot be empty
report.template.script.validate.content.notEmpty=Expression cannot be empty
report.template.import.name.notEmpty=Template name cannot be empty
report.datasource.save.name.notBlank=Data source name cannot be empty
report.datasource.save.name.length=Data source name cannot exceed 64 characters
report.datasource.save.beanId.length=Spring data source ID cannot exceed 64 characters
report.datasource.save.driver.length=Driver class name cannot exceed 64 characters
report.datasource.save.url.length=Data source URL cannot exceed 255 characters
report.datasource.save.username.length=Username cannot exceed 64 characters
report.datasource.save.password.length=Password cannot exceed 64 characters
report.datasource.save.remark.size=Remark cannot exceed 64 characters
report.datasource.save.headers.size=Number of request headers cannot exceed 30
report.datasource.spring.bean.field.clazz.notEmpty=Class full path cannot be empty
report.datasource.spring.bean.field.clazz.size=Class full path cannot exceed 100 characters
report.datasource.bean.methods.query.beanId.notEmpty=beanId cannot be empty
report.datasource.bean.methods.query.beanId.size=beanId cannot exceed 100 characters
report.datasource.conn.test.driverClassName.notBlank=Driver class name cannot be empty
report.datasource.conn.test.url.notBlank=Data source URL cannot be empty
report.datasource.conn.test.username.notBlank=Username cannot be empty
report.datasource.conn.test.password.notBlank=Password cannot be empty
report.datasource.preview.conn.test.info.notNull=Connection information cannot be empty
report.datasource.preview.sql.notBlank=Query SQL cannot be empty
report.datasource.preview.parameters.size=Number of query parameters cannot exceed 30
report.datasource.preview.datasourceId.notNull=Data source ID cannot be empty
report.datasource.query.param.name.notBlank=Parameter name cannot be empty
report.datasource.query.param.type.notBlank=Parameter type cannot be empty
report.dataset.save.name.notBlank=Dataset name cannot be empty
report.dataset.save.name.length=Dataset name cannot exceed 64 characters
report.dataset.save.datasourceId.notNull=Data source ID cannot be empty
report.dataset.save.method.length=Bean method name cannot exceed 64 characters
report.dataset.save.parameters.size=Number of parameters cannot exceed 30
report.dataset.save.fields.size=Number of fields cannot exceed 100
report.dataset.save.fields.name.notBlank=Field name cannot be empty
report.dataset.save.param.name.notBlank=Parameter name cannot be empty
report.dataset.save.param.type.notBlank=Parameter type cannot be empty
@@ -0,0 +1,7 @@
report.template.producer.type.invalid=模版文件类型错误,请检查是否PDF/WORD/EXCEL
report.template.type.invalid=模版类型错误,请检查是否内置/自定义
report.datasource.type.invalid=数据源类型错误,请检查是否jdbc/spring/api
report.datasource.sql.param.invalid=sql查询参数默认值非法输入,请检查
report.datasource.sql.invalid=sql语句非法输入,请检查
report.datasource.sql.note.invalid=SQL中不允许包含注释,存在安全风险
report.datasource.sql.inject.risks=SQL不合法,存在注入风险
@@ -0,0 +1,7 @@
report.template.producer.type.invalid=模版文件類型錯誤,請檢查是否PDFWORDEXCEL
report.template.type.invalid=模版類型錯誤,請檢查是否內置自定義
report.datasource.type.invalid=數據源類型錯誤,請檢查是否jdbcspringapi
report.datasource.sql.param.invalid=sql查詢參數默認值非法輸入,請檢查
report.datasource.sql.invalid=sql語句非法輸入,請檢查
report.datasource.sql.note.invalid=SQL中不允許包含註釋,存在安全風險
report.datasource.sql.inject.risks=SQL不合法,存在注入風險
@@ -0,0 +1,7 @@
report.template.producer.type.invalid=Invalid template file type. Please check whether it is PDF/WORD/EXCEL.
report.template.type.invalid=Invalid template type. Please check whether it is built-in or custom.
report.datasource.type.invalid=Invalid datasource type. Please check whether it is jdbc/spring/api.
report.datasource.sql.param.invalid=Invalid default value for SQL query parameter. Please check.
report.datasource.sql.invalid=Invalid SQL statement input. Please check.
report.datasource.sql.note.invalid=Comments are not allowed in SQL due to security risks.
report.datasource.sql.inject.risks=Invalid SQL. Potential injection risk detected.
@@ -0,0 +1 @@
report.template.not_exists=报表模板信息不存在
@@ -0,0 +1 @@
report.template.not_exists=報表模板資訊不存在
@@ -0,0 +1 @@
report.template.not_exists=Report template does not exist
+1 -1
View File
@@ -23,7 +23,7 @@
<properties> <properties>
<dom4j.version>1.6.1</dom4j.version> <dom4j.version>1.6.1</dom4j.version>
<commons-io.version>2.11.0</commons-io.version> <commons-io.version>2.17.0</commons-io.version>
<antlr4.version>4.5.3</antlr4.version> <antlr4.version>4.5.3</antlr4.version>
<commons-text.version>1.10.0</commons-text.version> <commons-text.version>1.10.0</commons-text.version>
<poi-ooxml-full.version>5.2.0</poi-ooxml-full.version> <poi-ooxml-full.version>5.2.0</poi-ooxml-full.version>