report:code review ureport 的集成

This commit is contained in:
YunaiV 2023-11-24 22:18:59 +08:00
parent 8bcc732c33
commit fb8f5b6339
17 changed files with 117 additions and 104 deletions

View File

@ -653,7 +653,7 @@
<version>${spring.boot.version}</version>
</dependency>
<!--ureport2 报表-->
<!-- UReport2 报表-->
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-console</artifactId>

View File

@ -9,9 +9,11 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
*/
public interface ErrorCodeConstants {
// ========== AUTH 模块 1-003-000-000 ==========
// ========== GoView 模块 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报表文件");
// ========== UREPORT 模块 1-003-001-000 ==========
ErrorCode UREPORT_FILE_NOT_EXISTS = new ErrorCode(1_003_001_000, "打印文件不存在,请检查 UReport 报表文件");
ErrorCode UREPORT_FILE_EXISTS = new ErrorCode(1_003_001_001, "报表名字已存在,请修改后再保存");
}

View File

@ -1,35 +1,34 @@
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.CommonResult;
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.controller.admin.ureport.vo.UreportFilePageReqVO;
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UreportFileRespVO;
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UreportFileSaveReqVO;
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UreportFileDO;
import cn.iocoder.yudao.module.report.service.ureport.UreportFileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Tag(name = "管理后台 - Ureport2报表")
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
// TODO @赤焰: Ureport 改成 UReport
@Tag(name = "管理后台 - UReport2 报表")
@RestController
@RequestMapping("/report/ureport-file")
@Validated
@ -39,14 +38,14 @@ public class UreportFileController {
private UreportFileService ureportFileService;
@PostMapping("/create")
@Operation(summary = "创建Ureport2报表")
@Operation(summary = "创建 UReport2 报表")
@PreAuthorize("@ss.hasPermission('report:ureport-file:create')")
public CommonResult<Long> createUreportFile(@Valid @RequestBody UreportFileSaveReqVO createReqVO) {
return success(ureportFileService.createUreportFile(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新Ureport2报表")
@Operation(summary = "更新 UReport2 报表")
@PreAuthorize("@ss.hasPermission('report:ureport-file:update')")
public CommonResult<Boolean> updateUreportFile(@Valid @RequestBody UreportFileSaveReqVO updateReqVO) {
ureportFileService.updateUreportFile(updateReqVO);
@ -54,7 +53,7 @@ public class UreportFileController {
}
@DeleteMapping("/delete")
@Operation(summary = "删除Ureport2报表")
@Operation(summary = "删除 UReport2 报表")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('report:ureport-file:delete')")
public CommonResult<Boolean> deleteUreportFile(@RequestParam("id") Long id) {
@ -63,7 +62,7 @@ public class UreportFileController {
}
@GetMapping("/get")
@Operation(summary = "获得Ureport2报表")
@Operation(summary = "获得 UReport2 报表")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('report:ureport-file:query')")
public CommonResult<UreportFileRespVO> getUreportFile(@RequestParam("id") Long id) {
@ -72,15 +71,16 @@ public class UreportFileController {
}
@GetMapping("/page")
@Operation(summary = "获得Ureport2报表分页")
@Operation(summary = "获得 UReport2 报表分页")
@PreAuthorize("@ss.hasPermission('report:ureport-file:query')")
public CommonResult<PageResult<UreportFileRespVO>> getUreportFilePage(@Valid UreportFilePageReqVO pageReqVO) {
PageResult<UreportFileDO> pageResult = ureportFileService.getUreportFilePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, UreportFileRespVO.class));
}
// TODO @赤焰导出是必须的么没用可以删除哈
@GetMapping("/export-excel")
@Operation(summary = "导出Ureport2报表 Excel")
@Operation(summary = "导出 UReport2 报表 Excel")
@PreAuthorize("@ss.hasPermission('report:ureport-file:export')")
@OperateLog(type = EXPORT)
public void exportUreportFileExcel(@Valid UreportFilePageReqVO pageReqVO,

View File

@ -1,12 +1,13 @@
package cn.iocoder.yudao.module.report.controller.admin.ureport.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - Ureport2报表 Response VO")
@Data
@ -23,6 +24,7 @@ public class UreportFileRespVO {
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("状态")
@DictFormat(DictTypeConstants.COMMON_STATUS)
private Integer status;
@Schema(description = "备注", example = "随便")

View File

@ -1,10 +1,12 @@
package cn.iocoder.yudao.module.report.controller.admin.ureport.vo;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import java.util.*;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - Ureport2报表新增/修改 Request VO")
@Data
@ -19,6 +21,7 @@ public class UreportFileSaveReqVO {
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "文件内容")

View File

@ -1,11 +1,10 @@
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;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* Ureport2报表 DO
@ -27,6 +26,7 @@ public class UreportFileDO extends BaseDO {
*/
@TableId
private Long id;
// TODO @赤焰是不是用 name 就可以了
/**
* 文件名称
*/
@ -35,6 +35,7 @@ public class UreportFileDO extends BaseDO {
* 状态
*/
private Integer status;
// TODO @赤焰是不是用 string 就可以了然后字段名用 content
/**
* 文件内容
*/

View File

@ -18,9 +18,8 @@ public class SecurityConfiguration {
@Override
public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
//积木报表
registry.antMatchers("/jmreport/**").permitAll();
registry.antMatchers("/ureport/**").permitAll();
registry.antMatchers("/jmreport/**").permitAll(); // 积木报表
registry.antMatchers("/ureport/**").permitAll(); // UReport 报表
}
};

View File

@ -10,15 +10,16 @@ import org.springframework.context.annotation.PropertySource;
import javax.servlet.Servlet;
/**
* Ureport 配置类
* 加载ureport对应的xml配置文件
* @author 赤焰
* UReport2 配置类
*
* @author 赤焰
*/
@Configuration
@ImportResource({"classpath:ureport-console-context.xml"})
@PropertySource(value = {"classpath:ureport.properties"})
@ImportResource({"classpath:ureport-console-context.xml"}) // Bean 配置
@PropertySource(value = {"classpath:ureport.properties"}) // 配置文件
public class UreportConfiguration {
// TODO @赤焰bean 是不是取个和 ureport 相关的名字好点哈
@Bean
public ServletRegistrationBean<Servlet> registrationBean() {
return new ServletRegistrationBean<>(new UReportServlet(), "/ureport/*");

View File

@ -10,7 +10,7 @@ import java.sql.Connection;
import java.sql.SQLException;
/**
* ureport内置数据源
* UReport 内置数据源
*/
@Slf4j
@Component
@ -22,18 +22,17 @@ public class UreportDataSource implements BuildinDatasource {
private DataSource dataSource;
/**
* 数据源名称
*
**/
* @return 数据源名称
*/
@Override
public String name() {
return NAME;
}
// TODO @赤焰这个方法如果拿不到连接是不是抛出异常比较好
/**
* * 获取连接
*
**/
* @return 获取连接
*/
@Override
public Connection getConnection() {
try {

View File

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.report.framework.ureport.provider;
package cn.iocoder.yudao.module.report.framework.ureport.core;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UreportFileSaveReqVO;
@ -28,30 +27,37 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
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;
// TODO @赤焰有了这个功能是不是就不需要 UreportFileController
/**
* 提供数据库的存储方式
* 基于数据库的 {@link ReportProvider} 实现类
*
* @author 赤焰
*/
@Component
@Slf4j
@Setter
@Component
@ConfigurationProperties(prefix = "ureport.provider.database")
public class UreportDatabaseProvider implements ReportProvider{
@ConfigurationProperties(prefix = "ureport.provider.database") // TODO @赤焰是不是单独搞个 UReportProperties 用来注入 prefixdisabled 等属性
public class UreportDatabaseProvider implements ReportProvider {
private static final String NAME = "mysql-provider";
// TODO @赤焰IdTypeEnvironmentPostProcessor 参考下通过 primary 数据源获取
private String prefix = "mysql:";
private boolean disabled = false;
@Resource
private UreportFileService ureportFileService;
@Override
public InputStream loadReport(String file) {
// TODO @赤焰是不是不需要这个 check 接口直接使用 name 查询就 ok
// TODO @赤焰变量的命名要注意这里 reportDo 是不是叫 count 就好了还有这个方法的命名也不太对
Long reportDo = ureportFileService.checkExistByName(getCorrectName(file));
if (reportDo <=0) {
if (reportDo <=0) { // TODO 赤焰<= 0 注释空格
throw exception(UREPORT_FILE_NOT_EXISTS);
}
// TODO @赤焰queryUreportFileDoByName 改成 getUreportFileDoByName 更合适保持整个项目的命名风格一致性
UreportFileDO ureportFileDO = ureportFileService.queryUreportFileDoByName(getCorrectName(file));
byte[] content = ureportFileDO.getFileContent();
return new ByteArrayInputStream(content);
@ -64,12 +70,16 @@ public class UreportDatabaseProvider implements ReportProvider{
@Override
public List<ReportFile> getReportFiles() {
// TODO @赤焰queryReportFileList 改成 getReportFileList 更合适保持整个项目的命名风格一致性
List<UreportFileDO> list = ureportFileService.queryReportFileList();
List<ReportFile> reportList = new ArrayList<>();
if(CollUtil.isEmpty(list)){
if(CollUtil.isEmpty(list)){ // TODO 赤焰CollUtil.isEmpty(list) 注意空格
// TODO @赤焰这里可以直接返回 Collections.emptyList();
return reportList;
}
// TODO 赤焰可以使用 CollectionUtils.converList
for (UreportFileDO reportFile : list) {
// TODO 赤焰可以使用 DateUtils.of()
LocalDateTime updateTime = reportFile.getUpdateTime();
ZonedDateTime zdt = updateTime.atZone(ZoneId.systemDefault());
Date date = Date.from(zdt.toInstant());
@ -82,6 +92,7 @@ public class UreportDatabaseProvider implements ReportProvider{
@Override
public void saveReport(String file, String content) {
file = getCorrectName(file);
// TODO @赤焰这里的逻辑应该封装到 ureportFileService 这里只负责调用即可
LambdaQueryWrapper<UreportFileDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UreportFileDO::getFileName, file);
Long count = ureportFileService.checkExistByName(file);
@ -119,10 +130,13 @@ public class UreportDatabaseProvider implements ReportProvider{
return prefix;
}
// TODO @赤焰这个方法的注释最好写下哈
private String getCorrectName(String name) {
// TODO 赤焰一些常用方法可以用 hutool StrUtil.removePrefix()
if (name.startsWith(getPrefix())) {
name = name.substring(getPrefix().length());
}
return name;
}
}

View File

@ -15,6 +15,7 @@ import java.util.Calendar;
import java.util.List;
import java.util.Objects;
// TODO @赤焰这个类的作用是如果全部注释是不是可以删除哈
*/
/**
* 自定义文件存储可接入oss等

View File

@ -73,6 +73,7 @@ public class UreportFileServiceImpl implements UreportFileService {
@Override
public Long checkExistByName(String name) {
// TODO @赤焰Service 处理业务逻辑不能出现 Mapper 层的东西收敛成 mapper 的一个操作方法
LambdaQueryWrapper<UreportFileDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UreportFileDO::getFileName,name);
return ureportFileMapper.selectCount(queryWrapper);
@ -80,8 +81,10 @@ public class UreportFileServiceImpl implements UreportFileService {
@Override
public UreportFileDO queryUreportFileDoByName(String name) {
// TODO @赤焰Service 处理业务逻辑不能出现 Mapper 层的东西收敛成 mapper 的一个操作方法
LambdaQueryWrapper<UreportFileDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UreportFileDO::getFileName,name);
// TODO @赤焰这里可以用 selectByName 即可
List<UreportFileDO> list = ureportFileMapper.selectList(queryWrapper);
if(CollectionUtil.isNotEmpty(list)){
return list.get(0);
@ -91,14 +94,17 @@ public class UreportFileServiceImpl implements UreportFileService {
@Override
public List<UreportFileDO> queryReportFileList() {
// TODO @赤焰Service 处理业务逻辑不能出现 Mapper 层的东西收敛成 mapper 的一个操作方法
LambdaQueryWrapper<UreportFileDO> queryWrapper = new LambdaQueryWrapper<>();
return ureportFileMapper.selectList(queryWrapper);
}
@Override
public int deleteReportFileByName(String name) {
// TODO @赤焰Service 处理业务逻辑不能出现 Mapper 层的东西收敛成 mapper 的一个操作方法
LambdaQueryWrapper<UreportFileDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UreportFileDO::getFileName,name);
return ureportFileMapper.delete(queryWrapper);
}
}

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.report.dal.mysql.ureport.UreportFileMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

View File

@ -1,4 +1,5 @@
## TODO ????????? application.yaml ?????
ureport.disableHttpSessionReportCache=true
ureport.disableFileProvider=true
ureport.fileStoreDir=/WEB-INF/ureportfiles
ureport.debug=true
ureport.debug=true

View File

@ -1,33 +1,27 @@
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.common.pojo.PageResult;
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.controller.admin.ureport.vo.UreportFilePageReqVO;
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UreportFileSaveReqVO;
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 org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
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 cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.UREPORT_FILE_NOT_EXISTS;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
// TODO 芋艿但愿测试后面补
/**
* {@link UreportFileServiceImpl} 的单元测试类
*

View File

@ -264,6 +264,7 @@ justauth:
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
# TODO 赤焰:这个配置的目的是?
#ureport配置
#ureport:
# disableHttpSessionReportCache: true #是否禁用

View File

@ -182,7 +182,7 @@ yudao:
- /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号
- /admin-api/pay/notify/** # 支付回调通知,不携带租户编号
- /jmreport/* # 积木报表,无法携带租户编号
- /ureport/* # ureport报表,无法携带租户编号
- /ureport/* # UReport 报表,无法携带租户编号
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,无法携带租户编号
ignore-tables:
- system_tenant
@ -251,11 +251,12 @@ yudao:
debug: false
#积木报表配置
# 积木报表配置
minidao :
base-package: org.jeecg.modules.jmreport.desreport.dao*
db-type: mysql
#ureport配置
# UReport 配置
ureport:
provider:
database: