📈 REPORT:code review ureport2 实现
This commit is contained in:
parent
9eb4f49b4d
commit
9d10c74599
2
pom.xml
2
pom.xml
|
@ -17,7 +17,7 @@
|
||||||
<module>yudao-module-infra</module>
|
<module>yudao-module-infra</module>
|
||||||
<!-- <module>yudao-module-member</module>-->
|
<!-- <module>yudao-module-member</module>-->
|
||||||
<!-- <module>yudao-module-bpm</module>-->
|
<!-- <module>yudao-module-bpm</module>-->
|
||||||
<!-- <module>yudao-module-report</module>-->
|
<module>yudao-module-report</module>
|
||||||
<!-- <module>yudao-module-mp</module>-->
|
<!-- <module>yudao-module-mp</module>-->
|
||||||
<!-- <module>yudao-module-pay</module>-->
|
<!-- <module>yudao-module-pay</module>-->
|
||||||
<!-- <module>yudao-module-mall</module>-->
|
<!-- <module>yudao-module-mall</module>-->
|
||||||
|
|
|
@ -13,7 +13,7 @@ public interface ErrorCodeConstants {
|
||||||
ErrorCode GO_VIEW_PROJECT_NOT_EXISTS = new ErrorCode(1_003_000_000, "GoView 项目不存在");
|
ErrorCode GO_VIEW_PROJECT_NOT_EXISTS = new ErrorCode(1_003_000_000, "GoView 项目不存在");
|
||||||
|
|
||||||
// ========== UREPORT 模块 1-003-001-000 ==========
|
// ========== UREPORT 模块 1-003-001-000 ==========
|
||||||
ErrorCode REPORT_DATA_NOT_EXISTS = new ErrorCode(1_003_001_001, "Ureport2报表不存在");
|
ErrorCode UREPORT_DATA_NOT_EXISTS = new ErrorCode(1_003_001_001, "Ureport2 报表不存在");
|
||||||
|
ErrorCode UREPORT_DATABASE_NOT_EXISTS = new ErrorCode(1_003_001_002, "Ureport2 报表数据源不存在");
|
||||||
|
|
||||||
ErrorCode REPORT_DATABASE_NOT_EXISTS = new ErrorCode(1_003_001_001, "Ureport2报表数据源不存在");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,33 @@
|
||||||
package cn.iocoder.yudao.module.report.controller.admin.ureport;
|
package cn.iocoder.yudao.module.report.controller.admin.ureport;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
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.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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 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.excel.core.util.ExcelUtils;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
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.UReportDataPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataRespVO;
|
||||||
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*;
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
||||||
import cn.iocoder.yudao.module.report.service.ureport.UReportDataService;
|
import cn.iocoder.yudao.module.report.service.ureport.UReportDataService;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - Ureport2 报表")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/report/ureport-data")
|
@RequestMapping("/report/ureport-data")
|
||||||
@Validated
|
@Validated
|
||||||
|
@ -39,14 +37,14 @@ public class UReportDataController {
|
||||||
private UReportDataService uReportDataService;
|
private UReportDataService uReportDataService;
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建Ureport2报表")
|
@Operation(summary = "创建 Ureport2 报表")
|
||||||
@PreAuthorize("@ss.hasPermission('report:ureport-data:create')")
|
@PreAuthorize("@ss.hasPermission('report:ureport-data:create')")
|
||||||
public CommonResult<Long> createUReportData(@Valid @RequestBody UReportDataSaveReqVO createReqVO) {
|
public CommonResult<Long> createUReportData(@Valid @RequestBody UReportDataSaveReqVO createReqVO) {
|
||||||
return success(uReportDataService.createUReportData(createReqVO));
|
return success(uReportDataService.createUReportData(createReqVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
@Operation(summary = "更新Ureport2报表")
|
@Operation(summary = "更新 Ureport2 报表")
|
||||||
@PreAuthorize("@ss.hasPermission('report:ureport-data:update')")
|
@PreAuthorize("@ss.hasPermission('report:ureport-data:update')")
|
||||||
public CommonResult<Boolean> updateUReportData(@Valid @RequestBody UReportDataSaveReqVO updateReqVO) {
|
public CommonResult<Boolean> updateUReportData(@Valid @RequestBody UReportDataSaveReqVO updateReqVO) {
|
||||||
uReportDataService.updateUReportData(updateReqVO);
|
uReportDataService.updateUReportData(updateReqVO);
|
||||||
|
@ -54,7 +52,7 @@ public class UReportDataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
@DeleteMapping("/delete")
|
||||||
@Operation(summary = "删除Ureport2报表")
|
@Operation(summary = "删除 Ureport2 报表")
|
||||||
@Parameter(name = "id", description = "编号", required = true)
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
@PreAuthorize("@ss.hasPermission('report:ureport-data:delete')")
|
@PreAuthorize("@ss.hasPermission('report:ureport-data:delete')")
|
||||||
public CommonResult<Boolean> deleteUReportData(@RequestParam("id") Long id) {
|
public CommonResult<Boolean> deleteUReportData(@RequestParam("id") Long id) {
|
||||||
|
@ -80,7 +78,7 @@ public class UReportDataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/export-excel")
|
@GetMapping("/export-excel")
|
||||||
@Operation(summary = "导出Ureport2报表 Excel")
|
@Operation(summary = "导出 Ureport2 报表 Excel")
|
||||||
@PreAuthorize("@ss.hasPermission('report:ureport-data:export')")
|
@PreAuthorize("@ss.hasPermission('report:ureport-data:export')")
|
||||||
@OperateLog(type = EXPORT)
|
@OperateLog(type = EXPORT)
|
||||||
public void exportUReportDataExcel(@Valid UReportDataPageReqVO pageReqVO,
|
public void exportUReportDataExcel(@Valid UReportDataPageReqVO pageReqVO,
|
||||||
|
@ -88,7 +86,7 @@ public class UReportDataController {
|
||||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
List<UReportDataDO> list = uReportDataService.getUReportDataPage(pageReqVO).getList();
|
List<UReportDataDO> list = uReportDataService.getUReportDataPage(pageReqVO).getList();
|
||||||
// 导出 Excel
|
// 导出 Excel
|
||||||
ExcelUtils.write(response, "Ureport2报表.xls", "数据", UReportDataRespVO.class,
|
ExcelUtils.write(response, "Ureport2 报表.xls", "数据", UReportDataRespVO.class,
|
||||||
BeanUtils.toBean(list, UReportDataRespVO.class));
|
BeanUtils.toBean(list, UReportDataRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package cn.iocoder.yudao.module.report.controller.admin.ureport.vo;
|
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 cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - Ureport2报表分页 Request VO")
|
@Schema(description = "管理后台 - Ureport2 报表分页 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - Ureport2报表 Response VO")
|
@Schema(description = "管理后台 - Ureport2 报表 Response VO")
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class UReportDataRespVO {
|
public class UReportDataRespVO {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.report.controller.admin.ureport.vo;
|
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 io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.Data;
|
||||||
import java.util.*;
|
|
||||||
import javax.validation.constraints.*;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - Ureport2报表新增/修改 Request VO")
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - Ureport2 报表新增/修改 Request VO")
|
||||||
@Data
|
@Data
|
||||||
public class UReportDataSaveReqVO {
|
public class UReportDataSaveReqVO {
|
||||||
|
|
||||||
|
@ -19,6 +21,7 @@ public class UReportDataSaveReqVO {
|
||||||
|
|
||||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
@NotNull(message = "状态不能为空")
|
@NotNull(message = "状态不能为空")
|
||||||
|
@InEnum(CommonStatusEnum.class)
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@Schema(description = "文件内容")
|
@Schema(description = "文件内容")
|
||||||
|
|
|
@ -7,8 +7,9 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
// TODO @赤焰:这个是不是可以支持多租户?
|
||||||
/**
|
/**
|
||||||
* Ureport2报表 DO
|
* Ureport2 报表 DO
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +35,7 @@ public class UReportDataDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*
|
*
|
||||||
* 枚举 {@link CommonStatusEnum#getStatus()}
|
* 枚举 {@link CommonStatusEnum#getStatus()}
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.report.dal.mysql.ureport;
|
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.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.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataPageReqVO;
|
||||||
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ureport2报表 Mapper
|
* Ureport2报表 Mapper
|
||||||
|
@ -26,33 +26,17 @@ public interface UReportDataMapper extends BaseMapperX<UReportDataDO> {
|
||||||
.orderByDesc(UReportDataDO::getId));
|
.orderByDesc(UReportDataDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
default List<UReportDataDO> selectListByName(String name) {
|
||||||
* 根据名字查询报表
|
|
||||||
* @param name 报表名字
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
default List<UReportDataDO> selectByName(String name){
|
|
||||||
return selectList(new LambdaQueryWrapperX<UReportDataDO>()
|
return selectList(new LambdaQueryWrapperX<UReportDataDO>()
|
||||||
.eqIfPresent(UReportDataDO::getName,name));
|
.eqIfPresent(UReportDataDO::getName,name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
default UReportDataDO selectByName(String name){
|
||||||
* 根据名字查询报表
|
|
||||||
* @param name 报表名字
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
default UReportDataDO selectOneByName(String name){
|
|
||||||
return selectOne(new LambdaQueryWrapperX<UReportDataDO>()
|
return selectOne(new LambdaQueryWrapperX<UReportDataDO>()
|
||||||
.eqIfPresent(UReportDataDO::getName,name));
|
.eqIfPresent(UReportDataDO::getName,name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default int deleteByName(String name) {
|
||||||
/**
|
|
||||||
* 根据名字删除报表
|
|
||||||
* @param name 报表名字
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
default int deleteByName(String name){
|
|
||||||
return delete(new LambdaQueryWrapperX<UReportDataDO>()
|
return delete(new LambdaQueryWrapperX<UReportDataDO>()
|
||||||
.eqIfPresent(UReportDataDO::getName,name));
|
.eqIfPresent(UReportDataDO::getName,name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.yudao.module.report.framework.ureport.config;
|
package cn.iocoder.yudao.module.report.framework.ureport.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.report.framework.security.config.UReportProperties;
|
|
||||||
import com.bstek.ureport.console.UReportServlet;
|
import com.bstek.ureport.console.UReportServlet;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
|
@ -18,7 +17,7 @@ import javax.servlet.Servlet;
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportResource({"classpath:ureport-console-context.xml"})
|
@ImportResource({"classpath:ureport-console-context.xml"})
|
||||||
@PropertySource(value = {"classpath:ureport.properties"})
|
@PropertySource(value = {"classpath:ureport.properties"}) // TODO @赤焰:这个可以搞到 application.yaml 里么?
|
||||||
@EnableConfigurationProperties({UReportProperties.class})
|
@EnableConfigurationProperties({UReportProperties.class})
|
||||||
public class UReportConfiguration {
|
public class UReportConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
package cn.iocoder.yudao.module.report.framework.security.config;
|
package cn.iocoder.yudao.module.report.framework.ureport.config;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UReport配置类
|
* UReport2 配置类
|
||||||
*
|
*
|
||||||
* @author 赤焰
|
* @author 赤焰
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ConfigurationProperties(prefix = "ureport.provider.database")
|
@ConfigurationProperties(prefix = "ureport.provider.database")
|
||||||
public class UReportProperties {
|
public class UReportProperties {
|
||||||
|
|
||||||
|
// TODO @赤焰:每个字段的注释写下哈;
|
||||||
private String name = "数据库文件系统";
|
private String name = "数据库文件系统";
|
||||||
private String prefix = "db-";
|
|
||||||
|
private String prefix = "db-";
|
||||||
|
|
||||||
private boolean disabled = false;
|
private boolean disabled = false;
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.report.framework.ureport.config;
|
package cn.iocoder.yudao.module.report.framework.ureport.core;
|
||||||
|
|
||||||
import com.bstek.ureport.definition.datasource.BuildinDatasource;
|
import com.bstek.ureport.definition.datasource.BuildinDatasource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -10,10 +10,11 @@ import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.REPORT_DATABASE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.UREPORT_DATABASE_NOT_EXISTS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UReport 内置数据源
|
* UReport2 内置数据源
|
||||||
|
*
|
||||||
* @author 赤焰
|
* @author 赤焰
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -41,8 +42,8 @@ public class UReportDataSource implements BuildinDatasource {
|
||||||
try {
|
try {
|
||||||
return dataSource.getConnection();
|
return dataSource.getConnection();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("UReportDataSource获取连接失败!");
|
log.error("[getConnection][获取连接失败!]", e);
|
||||||
throw exception(REPORT_DATABASE_NOT_EXISTS);
|
throw exception(UREPORT_DATABASE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,10 @@ package cn.iocoder.yudao.module.report.framework.ureport.core;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataSaveReqVO;
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
||||||
import cn.iocoder.yudao.module.report.framework.security.config.UReportProperties;
|
import cn.iocoder.yudao.module.report.framework.ureport.config.UReportProperties;
|
||||||
import cn.iocoder.yudao.module.report.service.ureport.UReportDataService;
|
import cn.iocoder.yudao.module.report.service.ureport.UReportDataService;
|
||||||
import com.bstek.ureport.provider.report.ReportFile;
|
import com.bstek.ureport.provider.report.ReportFile;
|
||||||
import com.bstek.ureport.provider.report.ReportProvider;
|
import com.bstek.ureport.provider.report.ReportProvider;
|
||||||
|
@ -22,11 +21,14 @@ import java.io.InputStream;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于数据库的 {@link ReportProvider} 实现类
|
* 基于数据库的 {@link ReportProvider} 实现类
|
||||||
*
|
*
|
||||||
* @author 赤焰
|
* @author 赤焰
|
||||||
*/
|
*/
|
||||||
|
// TODO @赤焰:这个 bean 的注解,交给 UReportConfiguration 搞
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -53,15 +55,16 @@ public class UReportDatabaseProvider implements ReportProvider {
|
||||||
@Override
|
@Override
|
||||||
public List<ReportFile> getReportFiles() {
|
public List<ReportFile> getReportFiles() {
|
||||||
List<UReportDataDO> list = uReportDataService.getReportDataList();
|
List<UReportDataDO> list = uReportDataService.getReportDataList();
|
||||||
|
// TODO @赤焰:这里,不用判空,CollectionUtils.convertList 已经处理了哈。
|
||||||
if(CollUtil.isEmpty(list)) {
|
if(CollUtil.isEmpty(list)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return CollectionUtils.convertList(list, report -> new ReportFile(report.getName(), DateUtils.of(report.getUpdateTime())));
|
return convertList(list, report -> new ReportFile(report.getName(), DateUtils.of(report.getUpdateTime())));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveReport(String name, String content) {
|
public void saveReport(String name, String content) {
|
||||||
|
// TODO @赤焰:收到 uReportDataService 里面实现一个 saveUReportData 方法,然后这里调用即可。
|
||||||
name = getCorrectName(name);
|
name = getCorrectName(name);
|
||||||
UReportDataDO uReportDataDO = uReportDataService.selectOneByName(name);
|
UReportDataDO uReportDataDO = uReportDataService.selectOneByName(name);
|
||||||
UReportDataSaveReqVO saveReqVO = new UReportDataSaveReqVO();
|
UReportDataSaveReqVO saveReqVO = new UReportDataSaveReqVO();
|
||||||
|
@ -96,8 +99,9 @@ public class UReportDatabaseProvider implements ReportProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 去除存储媒介,获取报表名字
|
* 去除存储媒介,获取报表名字
|
||||||
|
*
|
||||||
* @param name 前端传入的报表带存储媒介的名字
|
* @param name 前端传入的报表带存储媒介的名字
|
||||||
* @return
|
* @return 表名字
|
||||||
*/
|
*/
|
||||||
private String getCorrectName(String name) {
|
private String getCorrectName(String name) {
|
||||||
return StrUtil.removePrefix(name,getPrefix());
|
return StrUtil.removePrefix(name,getPrefix());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.report.framework.security.config;
|
package cn.iocoder.yudao.module.report.framework.ureport.core;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||||
|
@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
|
import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
|
||||||
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||||
import lombok.Data;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
|
@ -9,14 +9,14 @@ import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ureport2报表 Service 接口
|
* Ureport2 报表 Service 接口
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
public interface UReportDataService {
|
public interface UReportDataService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建Ureport2报表
|
* 创建 Ureport2 报表
|
||||||
*
|
*
|
||||||
* @param createReqVO 创建信息
|
* @param createReqVO 创建信息
|
||||||
* @return 编号
|
* @return 编号
|
||||||
|
@ -24,58 +24,65 @@ public interface UReportDataService {
|
||||||
Long createUReportData(@Valid UReportDataSaveReqVO createReqVO);
|
Long createUReportData(@Valid UReportDataSaveReqVO createReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新Ureport2报表
|
* 更新 Ureport2 报表
|
||||||
*
|
*
|
||||||
* @param updateReqVO 更新信息
|
* @param updateReqVO 更新信息
|
||||||
*/
|
*/
|
||||||
void updateUReportData(@Valid UReportDataSaveReqVO updateReqVO);
|
void updateUReportData(@Valid UReportDataSaveReqVO updateReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除Ureport2报表
|
* 删除 Ureport2 报表
|
||||||
*
|
*
|
||||||
* @param id 编号
|
* @param id 编号
|
||||||
*/
|
*/
|
||||||
void deleteUReportData(Long id);
|
void deleteUReportData(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得Ureport2报表
|
* 获得 Ureport2 报表
|
||||||
*
|
*
|
||||||
* @param id 编号
|
* @param id 编号
|
||||||
* @return Ureport2报表
|
* @return Ureport2 报表
|
||||||
*/
|
*/
|
||||||
UReportDataDO getUReportData(Long id);
|
UReportDataDO getUReportData(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得Ureport2报表分页
|
* 获得 Ureport2 报表分页
|
||||||
*
|
*
|
||||||
* @param pageReqVO 分页查询
|
* @param pageReqVO 分页查询
|
||||||
* @return Ureport2报表分页
|
* @return Ureport2 报表分页
|
||||||
*/
|
*/
|
||||||
PageResult<UReportDataDO> getUReportDataPage(UReportDataPageReqVO pageReqVO);
|
PageResult<UReportDataDO> getUReportDataPage(UReportDataPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
// TODO @赤焰:可以不用返回 int。如果不需要哈。
|
||||||
/**
|
/**
|
||||||
* 根据名称删除报表
|
* 根据名称删除报表
|
||||||
* @param name
|
*
|
||||||
|
* @param name 报表名称
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int deleteByName(String name);
|
int deleteByName(String name);
|
||||||
|
|
||||||
|
// TODO @赤焰:这里直接返回 UReportDataDO 是不是更好?上层业务直接使用啦
|
||||||
/**
|
/**
|
||||||
* 根据名称校验报表是否存在
|
* 根据名称校验报表是否存在
|
||||||
* @param name
|
*
|
||||||
|
* @param name 报表名称
|
||||||
*/
|
*/
|
||||||
void validateUReportDataExists(String name);
|
void validateUReportDataExists(String name);
|
||||||
|
|
||||||
|
// TODO @赤焰:这里方法名改成 getUReportDataByName。select 只用于 mapper;
|
||||||
/**
|
/**
|
||||||
* 根据名称查询报表
|
* 根据名称查询报表
|
||||||
* @param name
|
*
|
||||||
* @return
|
* @param name 报表名称
|
||||||
|
* @return Ureport2 报表
|
||||||
*/
|
*/
|
||||||
UReportDataDO selectOneByName(String name);
|
UReportDataDO selectOneByName(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取全部报表
|
* 获取全部报表
|
||||||
* @return
|
*
|
||||||
|
* @return 全部报表
|
||||||
*/
|
*/
|
||||||
List<UReportDataDO> getReportDataList();
|
List<UReportDataDO> getReportDataList();
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
package cn.iocoder.yudao.module.report.service.ureport;
|
package cn.iocoder.yudao.module.report.service.ureport;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*;
|
|
||||||
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
||||||
import cn.iocoder.yudao.module.report.dal.mysql.ureport.UReportDataMapper;
|
import cn.iocoder.yudao.module.report.dal.mysql.ureport.UReportDataMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.UREPORT_DATA_NOT_EXISTS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ureport2报表 Service 实现类
|
* Ureport2报表 Service 实现类
|
||||||
|
@ -30,10 +29,9 @@ public class UReportDataServiceImpl implements UReportDataService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createUReportData(UReportDataSaveReqVO createReqVO) {
|
public Long createUReportData(UReportDataSaveReqVO createReqVO) {
|
||||||
// 插入
|
// TODO @赤焰:名字不要重复的校验,要加下
|
||||||
UReportDataDO uReportData = BeanUtils.toBean(createReqVO, UReportDataDO.class);
|
UReportDataDO uReportData = BeanUtils.toBean(createReqVO, UReportDataDO.class);
|
||||||
uReportDataMapper.insert(uReportData);
|
uReportDataMapper.insert(uReportData);
|
||||||
// 返回
|
|
||||||
return uReportData.getId();
|
return uReportData.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +39,7 @@ public class UReportDataServiceImpl implements UReportDataService {
|
||||||
public void updateUReportData(UReportDataSaveReqVO updateReqVO) {
|
public void updateUReportData(UReportDataSaveReqVO updateReqVO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
validateUReportDataExists(updateReqVO.getId());
|
validateUReportDataExists(updateReqVO.getId());
|
||||||
|
// TODO @赤焰:名字不要重复的校验,要加下
|
||||||
// 更新
|
// 更新
|
||||||
UReportDataDO updateObj = BeanUtils.toBean(updateReqVO, UReportDataDO.class);
|
UReportDataDO updateObj = BeanUtils.toBean(updateReqVO, UReportDataDO.class);
|
||||||
uReportDataMapper.updateById(updateObj);
|
uReportDataMapper.updateById(updateObj);
|
||||||
|
@ -56,14 +55,14 @@ public class UReportDataServiceImpl implements UReportDataService {
|
||||||
|
|
||||||
private void validateUReportDataExists(Long id) {
|
private void validateUReportDataExists(Long id) {
|
||||||
if (uReportDataMapper.selectById(id) == null) {
|
if (uReportDataMapper.selectById(id) == null) {
|
||||||
throw exception(REPORT_DATA_NOT_EXISTS);
|
throw exception(UREPORT_DATA_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateUReportDataExists(String name) {
|
public void validateUReportDataExists(String name) {
|
||||||
if (uReportDataMapper.selectByName(name) == null) {
|
if (uReportDataMapper.selectListByName(name) == null) {
|
||||||
throw exception(REPORT_DATA_NOT_EXISTS);
|
throw exception(UREPORT_DATA_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +83,12 @@ public class UReportDataServiceImpl implements UReportDataService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UReportDataDO selectOneByName(String name) {
|
public UReportDataDO selectOneByName(String name) {
|
||||||
return uReportDataMapper.selectOneByName(name);
|
return uReportDataMapper.selectByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UReportDataDO> getReportDataList() {
|
public List<UReportDataDO> getReportDataList() {
|
||||||
return uReportDataMapper.selectList();
|
return uReportDataMapper.selectList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.UReportDataMapper">
|
|
||||||
|
|
||||||
<!--
|
|
||||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
|
||||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
|
||||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
|
||||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
|
||||||
-->
|
|
||||||
|
|
||||||
</mapper>
|
|
|
@ -1,26 +1,27 @@
|
||||||
package cn.iocoder.yudao.module.report.service.ureport;
|
package cn.iocoder.yudao.module.report.service.ureport;
|
||||||
|
|
||||||
|
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.UReportDataPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.UReportDataSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
||||||
|
import cn.iocoder.yudao.module.report.dal.mysql.ureport.UReportDataMapper;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||||
import cn.iocoder.yudao.module.report.controller.admin.ureport.vo.*;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
import cn.iocoder.yudao.module.report.dal.dataobject.ureport.UReportDataDO;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||||
import cn.iocoder.yudao.module.report.dal.mysql.ureport.UReportDataMapper;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
import static cn.iocoder.yudao.module.report.enums.ErrorCodeConstants.UREPORT_DATA_NOT_EXISTS;
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
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 org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
// TODO 芋艿:最后搞单测
|
||||||
/**
|
/**
|
||||||
* {@link UReportDataServiceImpl} 的单元测试类
|
* {@link UReportDataServiceImpl} 的单元测试类
|
||||||
*
|
*
|
||||||
|
@ -72,7 +73,7 @@ public class UReportDataServiceImplTest extends BaseDbUnitTest {
|
||||||
UReportDataSaveReqVO updateReqVO = randomPojo(UReportDataSaveReqVO.class);
|
UReportDataSaveReqVO updateReqVO = randomPojo(UReportDataSaveReqVO.class);
|
||||||
|
|
||||||
// 调用, 并断言异常
|
// 调用, 并断言异常
|
||||||
assertServiceException(() -> uReportDataService.updateUReportData(updateReqVO), REPORT_DATA_NOT_EXISTS);
|
assertServiceException(() -> uReportDataService.updateUReportData(updateReqVO), UREPORT_DATA_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -95,7 +96,7 @@ public class UReportDataServiceImplTest extends BaseDbUnitTest {
|
||||||
Long id = randomLongId();
|
Long id = randomLongId();
|
||||||
|
|
||||||
// 调用, 并断言异常
|
// 调用, 并断言异常
|
||||||
assertServiceException(() -> uReportDataService.deleteUReportData(id), REPORT_DATA_NOT_EXISTS);
|
assertServiceException(() -> uReportDataService.deleteUReportData(id), UREPORT_DATA_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -44,11 +44,11 @@
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
|
|
||||||
<!-- 数据报表。默认注释,保证编译速度 -->
|
<!-- 数据报表。默认注释,保证编译速度 -->
|
||||||
<!-- <dependency>-->
|
<dependency>
|
||||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<!-- <artifactId>yudao-module-report-biz</artifactId>-->
|
<artifactId>yudao-module-report-biz</artifactId>
|
||||||
<!-- <version>${revision}</version>-->
|
<version>${revision}</version>
|
||||||
<!-- </dependency>-->
|
</dependency>
|
||||||
<!-- 工作流。默认注释,保证编译速度 -->
|
<!-- 工作流。默认注释,保证编译速度 -->
|
||||||
<!-- <dependency>-->
|
<!-- <dependency>-->
|
||||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||||
|
|
Loading…
Reference in New Issue