diff --git a/sql/mysql/Ureport.sql b/sql/mysql/Ureport.sql new file mode 100644 index 000000000..86687372c --- /dev/null +++ b/sql/mysql/Ureport.sql @@ -0,0 +1,55 @@ +-- 菜单 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status, component_name +) +VALUES ( + 'Ureport2报表管理', '', 2, 0, 1281, + 'ureport-file', '', 'report/ureport/index', 0, 'UreportFile' + ); + +-- 按钮父菜单ID +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + 'Ureport2报表查询', 'report:ureport-file:query', 3, 1, @parentId, + '', '', '', 0 + ); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + 'Ureport2报表创建', 'report:ureport-file:create', 3, 2, @parentId, + '', '', '', 0 + ); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + 'Ureport2报表更新', 'report:ureport-file:update', 3, 3, @parentId, + '', '', '', 0 + ); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + 'Ureport2报表删除', 'report:ureport-file:delete', 3, 4, @parentId, + '', '', '', 0 + ); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + 'Ureport2报表导出', 'report:ureport-file:export', 3, 5, @parentId, + '', '', '', 0 + ); diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index b71244f71..15851837e 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -74,6 +74,7 @@ 1.6.1 2.12.2 4.5.7.B + 2.2.9 @@ -647,12 +648,14 @@ xercesImpl ${xercesImpl.version} - + + - org.springframework.boot - spring-boot-starter-websocket - ${spring.boot.version} + com.bstek.ureport + ureport2-console + ${ureport2.version} + diff --git a/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java b/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java index 16eff831c..39edb84be 100644 --- a/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java +++ b/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java @@ -12,4 +12,6 @@ public interface ErrorCodeConstants { // ========== AUTH 模块 1-003-000-000 ========== ErrorCode GO_VIEW_PROJECT_NOT_EXISTS = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode UREPORT_FILE_NOT_EXISTS = new ErrorCode(1_003_001_000, "打印文件不存在,请检查Ureport报表文件"); + ErrorCode UREPORT_FILE_EXISTS = new ErrorCode(1_003_001_001, "报表名字已存在,请修改后再保存"); } diff --git a/yudao-module-report/yudao-module-report-biz/pom.xml b/yudao-module-report/yudao-module-report-biz/pom.xml index 9308fc386..83461f5fe 100644 --- a/yudao-module-report/yudao-module-report-biz/pom.xml +++ b/yudao-module-report/yudao-module-report-biz/pom.xml @@ -74,5 +74,15 @@ xercesImpl + + com.bstek.ureport + ureport2-console + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/UreportFileController.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/UreportFileController.java new file mode 100644 index 000000000..0ea93f22e --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/UreportFileController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.report.controller.admin.ureport; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*; +import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO; +import cn.iocoder.yudao.module.report.service.ureport.UreportFileService; + +@Tag(name = "管理后台 - Ureport2报表") +@RestController +@RequestMapping("/report/ureport-file") +@Validated +public class UreportFileController { + + @Resource + private UreportFileService ureportFileService; + + @PostMapping("/create") + @Operation(summary = "创建Ureport2报表") + @PreAuthorize("@ss.hasPermission('report:ureport-file:create')") + public CommonResult createUreportFile(@Valid @RequestBody UreportFileSaveReqVO createReqVO) { + return success(ureportFileService.createUreportFile(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新Ureport2报表") + @PreAuthorize("@ss.hasPermission('report:ureport-file:update')") + public CommonResult updateUreportFile(@Valid @RequestBody UreportFileSaveReqVO updateReqVO) { + ureportFileService.updateUreportFile(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除Ureport2报表") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('report:ureport-file:delete')") + public CommonResult deleteUreportFile(@RequestParam("id") Long id) { + ureportFileService.deleteUreportFile(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得Ureport2报表") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('report:ureport-file:query')") + public CommonResult getUreportFile(@RequestParam("id") Long id) { + UreportFileDO ureportFile = ureportFileService.getUreportFile(id); + return success(BeanUtils.toBean(ureportFile, UreportFileRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得Ureport2报表分页") + @PreAuthorize("@ss.hasPermission('report:ureport-file:query')") + public CommonResult> getUreportFilePage(@Valid UreportFilePageReqVO pageReqVO) { + PageResult pageResult = ureportFileService.getUreportFilePage(pageReqVO); + return success(BeanUtils.toBean(pageResult, UreportFileRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出Ureport2报表 Excel") + @PreAuthorize("@ss.hasPermission('report:ureport-file:export')") + @OperateLog(type = EXPORT) + public void exportUreportFileExcel(@Valid UreportFilePageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = ureportFileService.getUreportFilePage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "Ureport2报表.xls", "数据", UreportFileRespVO.class, + BeanUtils.toBean(list, UreportFileRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFilePageReqVO.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFilePageReqVO.java new file mode 100644 index 000000000..558b50fbf --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFilePageReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.report.controller.admin.ureport.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - Ureport2报表分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class UreportFilePageReqVO extends PageParam { + + @Schema(description = "文件名称", example = "赵六") + private String fileName; + + @Schema(description = "状态", example = "1") + private Integer status; + + @Schema(description = "备注", example = "随便") + private String remark; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFileRespVO.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFileRespVO.java new file mode 100644 index 000000000..739369a26 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFileRespVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.report.controller.admin.ureport.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - Ureport2报表 Response VO") +@Data +@ExcelIgnoreUnannotated +public class UreportFileRespVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "9948") + @ExcelProperty("ID") + private Long id; + + @Schema(description = "文件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + @ExcelProperty("文件名称") + private String fileName; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("状态") + private Integer status; + + @Schema(description = "备注", example = "随便") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFileSaveReqVO.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFileSaveReqVO.java new file mode 100644 index 000000000..fc8baa33b --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/controller/admin/ureport/vo/UreportFileSaveReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.report.controller.admin.ureport.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.util.*; + +@Schema(description = "管理后台 - Ureport2报表新增/修改 Request VO") +@Data +public class UreportFileSaveReqVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "9948") + private Long id; + + @Schema(description = "文件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + @NotEmpty(message = "文件名称不能为空") + private String fileName; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "文件内容") + private String fileContent; + + @Schema(description = "备注", example = "随便") + private String remark; + +} diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/dal/dataobject/ureport/UreportFileDO.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/dal/dataobject/ureport/UreportFileDO.java new file mode 100644 index 000000000..c9872f8ca --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/dal/dataobject/ureport/UreportFileDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.report.dal.dataobject.ureport; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * Ureport2报表 DO + * + * @author 芋道源码 + */ +@TableName("ureport_file") +@KeySequence("ureport_file_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UreportFileDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 文件名称 + */ + private String fileName; + /** + * 状态 + */ + private Integer status; + /** + * 文件内容 + */ + private byte[] fileContent; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/dal/mysql/ureport/UreportFileMapper.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/dal/mysql/ureport/UreportFileMapper.java new file mode 100644 index 000000000..618b80414 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/dal/mysql/ureport/UreportFileMapper.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.report.dal.mysql.ureport; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*; + +/** + * Ureport2报表 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface UreportFileMapper extends BaseMapperX { + + default PageResult selectPage(UreportFilePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(UreportFileDO::getFileName, reqVO.getFileName()) + .eqIfPresent(UreportFileDO::getStatus, reqVO.getStatus()) + .eqIfPresent(UreportFileDO::getRemark, reqVO.getRemark()) + .betweenIfPresent(UreportFileDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(UreportFileDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/security/config/SecurityConfiguration.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/security/config/SecurityConfiguration.java index 5b73cd274..82ded0d23 100644 --- a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/security/config/SecurityConfiguration.java +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/security/config/SecurityConfiguration.java @@ -20,6 +20,7 @@ public class SecurityConfiguration { public void customize(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry) { //积木报表 registry.antMatchers("/jmreport/**").permitAll(); + registry.antMatchers("/ureport/**").permitAll(); } }; diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/config/UreportConfig.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/config/UreportConfig.java new file mode 100644 index 000000000..47841e101 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/config/UreportConfig.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.report.framework.ureport.config; + +import com.bstek.ureport.console.UReportServlet; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.context.annotation.PropertySource; + +import javax.servlet.Servlet; + +/** + * Ureport 配置类 + * 加载ureport对应的xml配置文件 + */ +@PropertySource(value = {"classpath:ureport.properties"}) +@ImportResource("classpath:ureport-console-context.xml") +@Configuration +public class UreportConfig{ + + /** + * ureport2报表Servlet配置 + */ + @Bean + public ServletRegistrationBean ureport2Servlet(){ + return new ServletRegistrationBean<>(new UReportServlet(), "/ureport/*"); + } + +} diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/config/UreportDataSource.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/config/UreportDataSource.java new file mode 100644 index 000000000..30c0be2df --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/config/UreportDataSource.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.report.framework.ureport.config; + +import com.bstek.ureport.definition.datasource.BuildinDatasource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * ureport内置数据源 + */ +@Slf4j +@Component +public class UreportDataSource implements BuildinDatasource { + + private static final String NAME = "本机数据源"; + + @Resource + private DataSource dataSource; + + /** + * 数据源名称 + * + **/ + @Override + public String name() { + return NAME; + } + + /** + * * 获取连接 + * + **/ + @Override + public Connection getConnection() { + try { + return dataSource.getConnection(); + } catch (SQLException e) { + log.error("Ureport 数据源 获取连接失败!"); + e.printStackTrace(); + } + return null; + } + +} diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/provider/UreportDatabaseProvider.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/provider/UreportDatabaseProvider.java new file mode 100644 index 000000000..f0949e7e7 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/provider/UreportDatabaseProvider.java @@ -0,0 +1,129 @@ +/* +package cn.iocoder.yudao.module.report.framework.ureport.provider; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO; +import cn.iocoder.yudao.module.report.dal.mysql.ureport.UreportFileMapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.bstek.ureport.provider.report.ReportFile; +import com.bstek.ureport.provider.report.ReportProvider; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.UREPORT_FILE_EXISTS; +import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.UREPORT_FILE_NOT_EXISTS; + +*/ +/** + * 提供数据库的存储方式 + * @author 赤焰 + *//* + +@Slf4j +@Component +@ConfigurationProperties(prefix = "ureport.provider.database") +public class UreportDatabaseProvider implements ReportProvider{ + + private static final String NAME = "数据库存储系统"; + + private String prefix = "db:"; + + private boolean disabled; + + @Resource + private UreportFileMapper ureportFileMapper; + + @Override + public InputStream loadReport(String file) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(UreportFileDO::getFileName, getCorrectName(file)); + UreportFileDO reportDo = ureportFileMapper.selectOne(queryWrapper); + if (reportDo == null) { + throw exception(UREPORT_FILE_NOT_EXISTS); + } + byte[] content = reportDo.getFileContent(); + return new ByteArrayInputStream(content); + } + + @Override + public void deleteReport(String file) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(UreportFileDO::getFileName, getCorrectName(file)); + ureportFileMapper.delete(queryWrapper); + } + + @Override + public List getReportFiles() { + LambdaQueryWrapper reportFileQueryWrapper = new LambdaQueryWrapper<>(); + List list = ureportFileMapper.selectList(reportFileQueryWrapper); + List reportList = new ArrayList<>(); + if(CollUtil.isEmpty(list)){ + return reportList; + } + for (UreportFileDO reportFile : list) { + LocalDateTime updateTime = reportFile.getUpdateTime(); + ZonedDateTime zdt = updateTime.atZone(ZoneId.systemDefault()); + Date date = Date.from(zdt.toInstant()); + reportList.add(new ReportFile(reportFile.getFileName(),date)); + } + return reportList; + + } + + @Override + public void saveReport(String file, String content) { + file = getCorrectName(file); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(UreportFileDO::getFileName, file); + Long count = ureportFileMapper.selectCount(queryWrapper); + if(count>1){ + throw exception(UREPORT_FILE_EXISTS); + } + UreportFileDO ureportFileDO = ureportFileMapper.selectOne(queryWrapper); + if (ureportFileDO == null) { + ureportFileDO = new UreportFileDO(); + ureportFileDO.setFileName(file); + ureportFileDO.setFileContent(content.getBytes()); + ureportFileMapper.insert(ureportFileDO); + } else { + ureportFileDO.setFileContent(content.getBytes()); + ureportFileMapper.update(ureportFileDO, queryWrapper); + } + } + + @Override + public String getName() { + return NAME; + } + + @Override + public boolean disabled() { + return disabled; + } + + @Override + public String getPrefix() { + return prefix; + } + + private String getCorrectName(String name) { + if (name.startsWith(prefix)) { + name = name.substring(prefix.length(), name.length()); + } + return name; + } +} +*/ diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/provider/UreportFileReportProvider.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/provider/UreportFileReportProvider.java new file mode 100644 index 000000000..504ba19e8 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/ureport/provider/UreportFileReportProvider.java @@ -0,0 +1,119 @@ +/* +package cn.iocoder.yudao.module.report.framework.ureport.provider; + +import com.bstek.ureport.exception.ReportException; +import com.bstek.ureport.provider.report.ReportFile; +import com.bstek.ureport.provider.report.ReportProvider; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Objects; + +*/ +/** + * 自定义文件存储,可接入oss等 + * @author 赤焰 + *//* + +@Slf4j +@Component +@ConfigurationProperties(prefix = "ureport.provider.file") +public class UreportFileReportProvider implements ReportProvider{ + + private String prefix="reportFile:"; + private String fileStoreDir; + private boolean disabled; + + @Override + public InputStream loadReport(String file) { + if(file.startsWith(prefix)){ + file=file.substring(prefix.length(),file.length()); + } + String fullPath=fileStoreDir+"/"+file; + try { + return new FileInputStream(fullPath); + } catch (FileNotFoundException e) { + throw new ReportException(e); + } + } + + @Override + public void deleteReport(String file) { + if(file.startsWith(prefix)){ + file=file.substring(prefix.length(),file.length()); + } + String fullPath=fileStoreDir+"/"+file; + File f=new File(fullPath); + if(f.exists()){ + f.delete(); + } + } + + @Override + public List getReportFiles() { + File file=new File(fileStoreDir); + List list= new ArrayList<>(); + for(File f: Objects.requireNonNull(file.listFiles())){ + Calendar calendar=Calendar.getInstance(); + calendar.setTimeInMillis(f.lastModified()); + list.add(new ReportFile(f.getName(),calendar.getTime())); + } + list.sort((f1, f2) -> f2.getUpdateDate().compareTo(f1.getUpdateDate())); + return list; + } + + @Override + public String getName() { + return "文件存储系统"; + } + + @Override + public void saveReport(String file,String content) { + if(file.startsWith(prefix)){ + file=file.substring(prefix.length(),file.length()); + } + String fullPath=fileStoreDir+"/"+file; + FileOutputStream outStream=null; + try{ + outStream=new FileOutputStream(new File(fullPath)); + IOUtils.write(content, outStream,"utf-8"); + }catch(Exception ex){ + throw new ReportException(ex); + }finally{ + if(outStream!=null){ + try { + outStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } + + @Override + public boolean disabled() { + return disabled; + } + + public void setDisabled(boolean disabled) { + this.disabled = disabled; + } + + public void setFileStoreDir(String fileStoreDir) { + this.fileStoreDir = fileStoreDir; + } + + @Override + public String getPrefix() { + return prefix; + } + +} +*/ diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileService.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileService.java new file mode 100644 index 000000000..a7be5c1c6 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.report.service.ureport; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*; +import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * Ureport2报表 Service 接口 + * + * @author 芋道源码 + */ +public interface UreportFileService { + + /** + * 创建Ureport2报表 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createUreportFile(@Valid UreportFileSaveReqVO createReqVO); + + /** + * 更新Ureport2报表 + * + * @param updateReqVO 更新信息 + */ + void updateUreportFile(@Valid UreportFileSaveReqVO updateReqVO); + + /** + * 删除Ureport2报表 + * + * @param id 编号 + */ + void deleteUreportFile(Long id); + + /** + * 获得Ureport2报表 + * + * @param id 编号 + * @return Ureport2报表 + */ + UreportFileDO getUreportFile(Long id); + + /** + * 获得Ureport2报表分页 + * + * @param pageReqVO 分页查询 + * @return Ureport2报表分页 + */ + PageResult getUreportFilePage(UreportFilePageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileServiceImpl.java b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileServiceImpl.java new file mode 100644 index 000000000..3a6608f83 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.report.service.ureport; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*; +import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.report.dal.mysql.ureport.UreportFileMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.*; + +/** + * Ureport2报表 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class UreportFileServiceImpl implements UreportFileService { + + @Resource + private UreportFileMapper ureportFileMapper; + + @Override + public Long createUreportFile(UreportFileSaveReqVO createReqVO) { + // 插入 + UreportFileDO ureportFile = BeanUtils.toBean(createReqVO, UreportFileDO.class); + ureportFileMapper.insert(ureportFile); + // 返回 + return ureportFile.getId(); + } + + @Override + public void updateUreportFile(UreportFileSaveReqVO updateReqVO) { + // 校验存在 + validateUreportFileExists(updateReqVO.getId()); + // 更新 + UreportFileDO updateObj = BeanUtils.toBean(updateReqVO, UreportFileDO.class); + ureportFileMapper.updateById(updateObj); + } + + @Override + public void deleteUreportFile(Long id) { + // 校验存在 + validateUreportFileExists(id); + // 删除 + ureportFileMapper.deleteById(id); + } + + private void validateUreportFileExists(Long id) { + if (ureportFileMapper.selectById(id) == null) { + throw exception(UREPORT_FILE_NOT_EXISTS); + } + } + + @Override + public UreportFileDO getUreportFile(Long id) { + return ureportFileMapper.selectById(id); + } + + @Override + public PageResult getUreportFilePage(UreportFilePageReqVO pageReqVO) { + return ureportFileMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/resources/mapper/ureport/UreportFileMapper.xml b/yudao-module-report/yudao-module-report-biz/src/main/resources/mapper/ureport/UreportFileMapper.xml new file mode 100644 index 000000000..0a948a604 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/resources/mapper/ureport/UreportFileMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/main/resources/ureport.properties b/yudao-module-report/yudao-module-report-biz/src/main/resources/ureport.properties new file mode 100644 index 000000000..c84e00dc1 --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/main/resources/ureport.properties @@ -0,0 +1,4 @@ +ureport.disableHttpSessionReportCache=false +ureport.disableFileProvider=false +ureport.fileStoreDir=D:\\ureport\\files +ureport.debug=true diff --git a/yudao-module-report/yudao-module-report-biz/src/test/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileServiceImplTest.java b/yudao-module-report/yudao-module-report-biz/src/test/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileServiceImplTest.java new file mode 100644 index 000000000..b9bc1ac6e --- /dev/null +++ b/yudao-module-report/yudao-module-report-biz/src/test/java/cn/iocoder/yudao/module/report/service/ureport/UreportFileServiceImplTest.java @@ -0,0 +1,142 @@ +package cn.iocoder.yudao.module.report.service.ureport; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*; +import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO; +import cn.iocoder.yudao.module.report.dal.mysql.ureport.UreportFileMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link UreportFileServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(UreportFileServiceImpl.class) +public class UreportFileServiceImplTest extends BaseDbUnitTest { + + @Resource + private UreportFileServiceImpl ureportFileService; + + @Resource + private UreportFileMapper ureportFileMapper; + + @Test + public void testCreateUreportFile_success() { + // 准备参数 + UreportFileSaveReqVO createReqVO = randomPojo(UreportFileSaveReqVO.class).setId(null); + + // 调用 + Long ureportFileId = ureportFileService.createUreportFile(createReqVO); + // 断言 + assertNotNull(ureportFileId); + // 校验记录的属性是否正确 + UreportFileDO ureportFile = ureportFileMapper.selectById(ureportFileId); + assertPojoEquals(createReqVO, ureportFile, "id"); + } + + @Test + public void testUpdateUreportFile_success() { + // mock 数据 + UreportFileDO dbUreportFile = randomPojo(UreportFileDO.class); + ureportFileMapper.insert(dbUreportFile);// @Sql: 先插入出一条存在的数据 + // 准备参数 + UreportFileSaveReqVO updateReqVO = randomPojo(UreportFileSaveReqVO.class, o -> { + o.setId(dbUreportFile.getId()); // 设置更新的 ID + }); + + // 调用 + ureportFileService.updateUreportFile(updateReqVO); + // 校验是否更新正确 + UreportFileDO ureportFile = ureportFileMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, ureportFile); + } + + @Test + public void testUpdateUreportFile_notExists() { + // 准备参数 + UreportFileSaveReqVO updateReqVO = randomPojo(UreportFileSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> ureportFileService.updateUreportFile(updateReqVO), UREPORT_FILE_NOT_EXISTS); + } + + @Test + public void testDeleteUreportFile_success() { + // mock 数据 + UreportFileDO dbUreportFile = randomPojo(UreportFileDO.class); + ureportFileMapper.insert(dbUreportFile);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbUreportFile.getId(); + + // 调用 + ureportFileService.deleteUreportFile(id); + // 校验数据不存在了 + assertNull(ureportFileMapper.selectById(id)); + } + + @Test + public void testDeleteUreportFile_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> ureportFileService.deleteUreportFile(id), UREPORT_FILE_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetUreportFilePage() { + // mock 数据 + UreportFileDO dbUreportFile = randomPojo(UreportFileDO.class, o -> { // 等会查询到 + o.setFileName(null); + o.setStatus(null); + o.setRemark(null); + o.setCreateTime(null); + }); + ureportFileMapper.insert(dbUreportFile); + // 测试 fileName 不匹配 + ureportFileMapper.insert(cloneIgnoreId(dbUreportFile, o -> o.setFileName(null))); + // 测试 status 不匹配 + ureportFileMapper.insert(cloneIgnoreId(dbUreportFile, o -> o.setStatus(null))); + // 测试 remark 不匹配 + ureportFileMapper.insert(cloneIgnoreId(dbUreportFile, o -> o.setRemark(null))); + // 测试 createTime 不匹配 + ureportFileMapper.insert(cloneIgnoreId(dbUreportFile, o -> o.setCreateTime(null))); + // 准备参数 + UreportFilePageReqVO reqVO = new UreportFilePageReqVO(); + reqVO.setFileName(null); + reqVO.setStatus(null); + reqVO.setRemark(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = ureportFileService.getUreportFilePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbUreportFile, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/clean.sql b/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/clean.sql index 4a0268afc..6ffc3c6ac 100644 --- a/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/clean.sql @@ -1 +1,2 @@ DELETE FROM "report_go_view_project"; +DELETE FROM "ureport_file"; diff --git a/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/create_tables.sql b/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/create_tables.sql index a77397fea..1c2dab730 100644 --- a/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-report/yudao-module-report-biz/src/test/resources/sql/create_tables.sql @@ -12,3 +12,16 @@ CREATE TABLE IF NOT EXISTS "report_go_view_project" ( "deleted" bit NOT NULL DEFAULT FALSE, PRIMARY KEY ("id") ) COMMENT 'GoView 项目表'; +CREATE TABLE IF NOT EXISTS "ureport_file" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "file_name" varchar NOT NULL, + "status" int NOT NULL, + "file_content" varchar, + "remark" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT 'Ureport2报表'; diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 8a8a334f4..4a277d5ff 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -264,3 +264,16 @@ justauth: prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 +#ureport配置 +#ureport: +# disableHttpSessionReportCache: true #是否禁用 +# disableFileProvider: true #是否禁用 +# debug: true +# fileStoreDir: D://ureport//files +# provider: +# database: +# disabled: true +# file: +# disabled: true + +