Merge remote-tracking branch 'origin/master' into master

chenkening 3 years ago
commit 7f92febe7d

7
.gitignore vendored

@ -0,0 +1,7 @@
.idea
target
*.iml
/view/flutter/**/gen/*
**/*.log
dist
logs

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-gaea-parent</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea</artifactId>
<description>anjiplus-template-gaea</description>
<version>1.0.0-SNAPSHOT</version>
<name>template-gaea</name>
<packaging>pom</packaging>
<modules>
<module>report-core</module>
</modules>
<properties>
<gaea.version>1.0.0-SNAPSHOT</gaea.version>
<gaea.security.version>1.0.0-SNAPSHOT</gaea.security.version>
<gaea.export.version>1.0.0-SNAPSHOT</gaea.export.version>
<gaea.generator.version>1.0.0-SNAPSHOT</gaea.generator.version>
<gaea.log.version>1.0.0-SNAPSHOT</gaea.log.version>
<maven.test.skip>true</maven.test.skip>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea-auth</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea-business</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea-generator</artifactId>
<version>${gaea.generator.version}</version>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-gaea</artifactId>
<version>${gaea.version}</version>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-gaea-security</artifactId>
<version>${gaea.security.version}</version>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-gaea-export</artifactId>
<version>${gaea.export.version}</version>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-gaea-log</artifactId>
<version>${gaea.log.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>dev</id>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<url>http://nexus.anji-plus.com:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://nexus.anji-plus.com:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>aj-report</artifactId>
<name>aj-report</name>
<dependencies>
<dependency>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea-common</artifactId>
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
</dependency>
<dependency>
<groupId>com.anjiplus.template.gaea</groupId>
<artifactId>template-gaea-generator</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-gaea-export</artifactId>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-gaea-log</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<!--kudu impala驱动-->
<dependency>
<groupId>owinfo</groupId>
<artifactId>impalajdbc41</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/ImpalaJDBC41.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty.aggregate</groupId>
<artifactId>jetty-all</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,27 @@
package com.anjiplus.template.gaea.business;
import com.anji.plus.gaea.annotation.enabled.EnabledGaeaConfiguration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
* @author lr
* @since 2021-02-03
*/
@EnabledGaeaConfiguration
@SpringBootApplication(scanBasePackages = {
"com.anjiplus.template.gaea",
"com.anji.plus"
})
@MapperScan(basePackages = {
"com.anjiplus.template.gaea.business.modules.*.dao",
"com.anjiplus.template.gaea.business.modules.*.**.dao",
"com.anji.plus.gaea.*.module.*.dao"
})
public class ReportApplication {
public static void main( String[] args ) {
SpringApplication.run(ReportApplication.class);
}
}

@ -0,0 +1,25 @@
package com.anjiplus.template.gaea.business.base;
import org.springframework.context.i18n.LocaleContextHolder;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.dto.BaseDTO;
import com.anji.plus.gaea.curd.entity.BaseEntity;
import com.anji.plus.gaea.curd.params.PageParam;
/**
* Controller
*
* @author WongBin
* @date 2021/3/26
*/
public abstract class BaseController<P extends PageParam, T extends BaseEntity, D extends BaseDTO>
extends GaeaBaseController<P,T,D> {
/**
*
* @return
*/
public String getI18nLang(){
return LocaleContextHolder.getLocale().getLanguage();
}
}

@ -0,0 +1,15 @@
package com.anjiplus.template.gaea.business.base;
import com.anji.plus.gaea.curd.entity.BaseEntity;
import com.anji.plus.gaea.curd.params.PageParam;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import org.springframework.context.i18n.LocaleContextHolder;
/**
* Service
* @author WongBin
* @date 2021/3/26
*/
public interface BaseService<P extends PageParam, T extends BaseEntity> extends GaeaBaseService<P, T> {
}

@ -0,0 +1,68 @@
package com.anjiplus.template.gaea.business.code;
/**
*
* @author lr
* @since 2021-02-22
*/
public interface ResponseCode {
/**
*
*/
String DICT_ITEM_REPEAT = "Dict.item.code.exist";
/**
* null
*/
String DICT_CODE_LOCALE_NULL = "500-00002";
/**
*
*/
String PARAM_IS_NULL = "Rule.execute.param.null";
/**
*
*/
String RULE_CONTENT_COMPILE_ERROR = "Rule.content.compile.error";
/**
*
*/
String RULE_CONTENT_EXECUTE_ERROR = "Rule.content.execute.error";
/**
*
*/
String RULE_CODE_EXIST = "Rule.code.exist";
/**
*
*/
String RULE_CONTENT_NOT_EXIST = "Rule.content.not.exist";
/**
*
*/
String RULE_FIELDS_NOT_EXIST = "Rule.fields.not.exist";
/**
*
*/
String RULE_FIELD_VALUE_IS_REQUIRED = "Rule.field.value.is.required";
/**
*
*/
String RULE_FIELD_VALUE_TYPE_ERROR = "Rule.field.value.type.error";
/**
*
*/
String RULE_FIELDS_CHECK_ERROR = "Rule.fields.check.error";
/**
*
*/
String COMPONENT_NOT_LOAD = "Component.load.check.error";
}

@ -0,0 +1,29 @@
package com.anjiplus.template.gaea.business.config;
import com.anjiplus.template.gaea.business.runner.ApplicationInitRunner;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* business
* @author lr
* @since 2021-04-08
*/
@Configuration
@MapperScan(basePackages = {
"com.anjiplus.template.gaea.business.modules.*.dao",
"com.anjiplus.template.gaea.business.modules.*.**.dao"
})
public class BusinessAutoConfiguration {
/**
*
* @return
*/
@Bean
public ApplicationInitRunner applicationInitRunner() {
return new ApplicationInitRunner();
}
}

@ -0,0 +1,14 @@
package com.anjiplus.template.gaea.business.constant;
/**
*
* @author lr
* @since 2021-03-26
*/
public interface BusinessConstant {
/**
*
*/
String DICT_ITEM_EXIST_GROUP = "dictItemExist";
}

@ -0,0 +1,64 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.controller;
import com.anji.plus.gaea.annotation.Permission;
import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardObjectDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ReportDashboardService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @desc controller
* @website https://gitee.com/anji-plus/gaea
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@RestController
@Api(tags = "大屏设计管理")
@RequestMapping("/reportDashboard")
public class ReportDashboardController {
@Autowired
private ReportDashboardService reportDashboardService;
/**
*
* @param reportCode
* @return
*/
@GetMapping({"/{reportCode}"})
@Permission(code = "DETAIL", name = "明细")
public ResponseBean detail(@PathVariable("reportCode") String reportCode) {
return ResponseBean.builder().data(reportDashboardService.getDetail(reportCode)).build();
}
/**
*
* @param dto
* @return
*/
@PostMapping
@Permission(code = "INSERT", name = "新增")
@GaeaAuditLog(pageTitle = "新增")
public ResponseBean insert(@RequestBody ReportDashboardObjectDto dto) {
reportDashboardService.insertDashboard(dto);
return ResponseBean.builder().build();
}
/**
*
* @param dto
* @return
*/
@PostMapping("/getData")
@Permission(code = "DETAIL", name = "明细图表数据")
public ResponseBean getData(@RequestBody ChartDto dto) {
return ResponseBean.builder().data(reportDashboardService.getChartData(dto)).build();
}
}

@ -0,0 +1,51 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
*
* @description dto
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@Data
public class ChartDto implements Serializable {
private String chartType;
/**数据集编码*/
private String setCode;
/** 传入的自定义参数*/
private Map<String, Object> contextData;
/**图表属性*/
private Map<String, String> chartProperties;
/**时间字段*/
private String timeLineFiled;
/**时间颗粒度*/
private String particles;
/**时间格式化*/
private String dataTimeFormat;
/**时间展示层*/
private String timeLineFormat;
private int timeUnit;
/**时间区间*/
private String startTime;
/**时间区间*/
private String endTime;
}

@ -0,0 +1,55 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
*
* @description dto
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@Data
public class ReportDashboardDto extends GaeaBaseDTO implements Serializable {
/** 报表编码 */
private String reportCode;
/** 看板标题 */
private String title;
/** 宽度px */
private Long width;
/** 高度px */
private Long height;
/** 背景色 */
private String backgroundColor;
/** 背景图片 */
private String backgroundImage;
/** 工作台中的辅助线 */
private String presetLine;
/** 自动刷新间隔秒数据字典REFRESH_TYPE */
private Integer refreshSeconds;
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag;
/** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
private Integer deleteFlag;
/** 排序,降序 */
private Integer sort;
private List<ReportDashboardWidgetDto> widgets;
}

@ -0,0 +1,32 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
*
* @description dto
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@Data
public class ReportDashboardObjectDto implements Serializable {
/** 报表编码 */
private String reportCode;
/**
*
*/
private ReportDashboardDto dashboard;
/**
*
*/
private List<ReportDashboardWidgetDto> widgets;
}

@ -0,0 +1,20 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.param;
import lombok.Data;
import java.io.Serializable;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import java.util.List;
/**
* @desc ReportDashboard
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@Data
public class ReportDashboardParam extends PageParam implements Serializable{
}

@ -0,0 +1,16 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.dao;
import org.apache.ibatis.annotations.Mapper;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity.ReportDashboard;
/**
* ReportDashboard Mapper
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@Mapper
public interface ReportDashboardMapper extends GaeaBaseMapper<ReportDashboard> {
}

@ -0,0 +1,58 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity;
import com.anji.plus.gaea.annotation.Unique;
import com.anjiplus.template.gaea.common.RespCommonCode;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import javax.validation.constraints.*;
import java.sql.Timestamp;
/**
* @description entity
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
@TableName(value="gaea_report_dashboard")
@Data
public class ReportDashboard extends GaeaBaseEntity {
@ApiModelProperty(value = "报表编码")
@Unique(code = RespCommonCode.REPORT_CODE_ISEXIST)
private String reportCode;
@ApiModelProperty(value = "看板标题")
private String title;
@ApiModelProperty(value = "宽度px")
private Long width;
@ApiModelProperty(value = "高度px")
private Long height;
@ApiModelProperty(value = "背景色")
private String backgroundColor;
@ApiModelProperty(value = "背景图片")
private String backgroundImage;
@ApiModelProperty(value = "工作台中的辅助线")
private String presetLine;
@ApiModelProperty(value = "自动刷新间隔秒数据字典REFRESH_TYPE")
private Integer refreshSeconds;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
private Integer deleteFlag;
@ApiModelProperty(value = "排序,降序")
private Integer sort;
}

@ -0,0 +1,26 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import java.util.List;
/**
* Created by raodeming on 2021/4/26.
*/
public interface ChartStrategy {
/**
*
* @return
*/
String type();
/**
*
*
* @param dto
* @return
*/
Object transform(ChartDto dto, List<JSONObject> data);
}

@ -0,0 +1,38 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardObjectDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.param.ReportDashboardParam;
import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity.ReportDashboard;
/**
* @desc ReportDashboard
* @author Raod
* @date 2021-04-12 14:52:21.761
**/
public interface ReportDashboardService extends GaeaBaseService<ReportDashboardParam, ReportDashboard> {
/***
*
*
* @param reportCode
*/
ReportDashboardObjectDto getDetail(String reportCode);
/***
*
*
* @param dto
*/
void insertDashboard(ReportDashboardObjectDto dto);
/**
*
* @param dto
* @return
*/
Object getChartData(ChartDto dto);
}

@ -0,0 +1,81 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 线
* Created by raodeming on 2021/4/26.
*/
@Component
public class BarChartServiceImpl implements ChartStrategy {
/**
*
*
* @return
*/
@Override
public String type() {
return "widget-barchart|widget-linechart";
}
/**
*
*
* @param dto
* @param data
* @return
*/
@Override
public Object transform(ChartDto dto, List<JSONObject> data) {
// JSONObject json = new JSONObject();
// List<Object> xAxis = new ArrayList<>();
// List<Object> series = new ArrayList<>();
// data.forEach(jsonObject -> {
// jsonObject.forEach((s, o) -> {
// if ("xAxis".equals(s)) {
// xAxis.add(o);
// } else {
// series.add(o);
// }
// });
// });
//
// json.put("xAxis", xAxis);
// JSONArray objects = new JSONArray();
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("data", series);
// objects.add(jsonObject);
// json.put("series", objects);
// return json.toJSONString();
return data;
}
/* {
"xAxis": [
"哈哈",
"洗洗",
"来了",
"问问",
"天天"
],
"series": [
{
"data": [
1,
2,
3,
4,
5
]
}
]
}*/
}

@ -0,0 +1,108 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* Created by raodeming on 2021/4/26.
*/
@Component
public class BarLineChartServiceImpl implements ChartStrategy {
/**
*
*
* @return
*/
@Override
public String type() {
return "widget-barlinechart";
}
/**
*
*
* @param dto
* @param data
* @return
*/
@Override
public Object transform(ChartDto dto, List<JSONObject> data) {
// JSONObject json = new JSONObject();
// List<Object> xAxis = new ArrayList<>();
// Map<String, List<Object>> series = new HashMap<>();
// data.forEach(jsonObject -> {
// jsonObject.forEach((s, o) -> {
// if ("xAxis".equals(s)) {
// xAxis.add(o);
// } else {
// List<Object> objects;
// if (series.containsKey(s)) {
// objects = series.get(s);
// } else {
// objects = new ArrayList<>();
//
// }
// objects.add(o);
// series.put(s, objects);
//
// }
// });
// });
//
// json.put("xAxis", xAxis);
// List<JSONObject> result = new ArrayList<>();
// series.forEach((s, objects) -> {
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("name", s);
// if (s.endsWith("bar")) {
// jsonObject.put("type", "bar");
// } else {
// jsonObject.put("type", "line");
// }
// jsonObject.put("data", objects);
// result.add(jsonObject);
// });
// json.put("series", result);
// return json.toJSONString();
return data;
}
/*{
"xAxis": [
"1月",
"2月",
"3月"
],
"series": [
{
"name": "指标1", //暂时用不上
"type": "bar", //需要处理
"data": [
2,
49,
2
]
},
{
"name": "指标2",
"type": "line",
"yAxisIndex": 1,
"data": [
2,
32,
4
]
}
]
}*/
}

@ -0,0 +1,43 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
* Created by raodeming on 2021/4/26.
*/
@Component
public class GaugeChartServiceImpl implements ChartStrategy {
/**
*
*
* @return
*/
@Override
public String type() {
return "widget-gauge";
}
/**
*
*
* @param dto
* @param data
* @return
*/
@Override
public Object transform(ChartDto dto, List<JSONObject> data) {
// return "{\"value\": 50, \"name\": \"名称1\", \"unit\": \"%\"}";
return data;
}
}

@ -0,0 +1,52 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
* Created by raodeming on 2021/4/26.
*/
@Component
public class PieChartServiceImpl implements ChartStrategy {
/**
*
*
* @return
*/
@Override
public String type() {
return "widget-piechart|widget-hollow-piechart|widget-funnel";
}
/**
*
*
* @param dto
* @param data
* @return
*/
@Override
public Object transform(ChartDto dto, List<JSONObject> data) {
return data;
}
/* [
{
"value": 11,
"name": "指标1"
},
{
"value": 10,
"name": "指标2"
}
]*/
}

@ -0,0 +1,314 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.gaea.utils.GaeaAssert;
import com.anji.plus.gaea.utils.GaeaBeanUtils;
import com.anjiplus.template.gaea.business.code.ResponseCode;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardObjectDto;
import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.ReportDashboardMapper;
import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity.ReportDashboard;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ReportDashboardService;
import com.anjiplus.template.gaea.business.modules.data.dashboard.util.DateUtil;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetValueDto;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service.ReportDashboardWidgetService;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.OriginalDataDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.service.DataSetService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Raod
* @desc ReportDashboard
* @date 2021-04-12 14:52:21.761
**/
@Service
//@RequiredArgsConstructor
public class ReportDashboardServiceImpl implements ReportDashboardService, InitializingBean, ApplicationContextAware {
@Autowired
private ReportDashboardMapper reportDashboardMapper;
@Autowired
private ReportDashboardWidgetService reportDashboardWidgetService;
@Autowired
private DataSetService dataSetService;
private Map<String, ChartStrategy> queryServiceImplMap = new HashMap<>();
private ApplicationContext applicationContext;
@Override
public GaeaBaseMapper<ReportDashboard> getMapper() {
return reportDashboardMapper;
}
@Override
public ReportDashboardObjectDto getDetail(String reportCode) {
ReportDashboardObjectDto result = new ReportDashboardObjectDto();
ReportDashboardDto reportDashboardDto = new ReportDashboardDto();
ReportDashboard reportDashboard = this.selectOne("report_code", reportCode);
GaeaAssert.notNull(reportDashboard, ResponseCode.RULE_CONTENT_NOT_EXIST, "reportDashboard");
GaeaBeanUtils.copyAndFormatter(reportDashboard, reportDashboardDto);
List<ReportDashboardWidget> list = reportDashboardWidgetService.list(
new QueryWrapper<ReportDashboardWidget>().lambda()
.eq(ReportDashboardWidget::getReportCode, reportCode)
.orderByAsc(ReportDashboardWidget::getSort)
);
List<ReportDashboardWidgetDto> reportDashboardWidgetDtoList = new ArrayList<>();
list.forEach(reportDashboardWidget -> {
ReportDashboardWidgetDto reportDashboardWidgetDto = new ReportDashboardWidgetDto();
ReportDashboardWidgetValueDto value = new ReportDashboardWidgetValueDto();
value.setSetup(StringUtils.isNotBlank(reportDashboardWidget.getSetup()) ? JSONObject.parseObject(reportDashboardWidget.getSetup()) : new JSONObject());
value.setData(StringUtils.isNotBlank(reportDashboardWidget.getData()) ? JSONObject.parseObject(reportDashboardWidget.getData()) : new JSONObject());
value.setPosition(StringUtils.isNotBlank(reportDashboardWidget.getPosition()) ? JSONObject.parseObject(reportDashboardWidget.getPosition()) : new JSONObject());
value.setCollapse(StringUtils.isNotBlank(reportDashboardWidget.getCollapse()) ? JSONObject.parseObject(reportDashboardWidget.getCollapse()) : new JSONObject());
//实时数据的替换
analysisData(value);
reportDashboardWidgetDto.setType(reportDashboardWidget.getType());
reportDashboardWidgetDto.setValue(value);
reportDashboardWidgetDtoList.add(reportDashboardWidgetDto);
});
reportDashboardDto.setWidgets(reportDashboardWidgetDtoList);
result.setDashboard(reportDashboardDto);
result.setReportCode(reportCode);
return result;
}
/***
*
*
* @param dto
*/
@Override
@Transactional
public void insertDashboard(ReportDashboardObjectDto dto) {
String reportCode = dto.getReportCode();
GaeaAssert.notEmpty(reportCode, ResponseCode.PARAM_IS_NULL, "reportCode");
//查询ReportDashboard
ReportDashboard reportDashboard = this.selectOne("report_code", reportCode);
ReportDashboard dashboard = new ReportDashboard();
GaeaBeanUtils.copyAndFormatter(dto.getDashboard(), dashboard);
BeanUtils.copyProperties(dto.getDashboard(), dashboard);
dashboard.setReportCode(reportCode);
if (null == reportDashboard) {
//新增
this.insert(dashboard);
} else {
//更新
dashboard.setId(reportDashboard.getId());
this.update(dashboard);
}
//删除reportDashboardWidget
reportDashboardWidgetService.delete(new QueryWrapper<ReportDashboardWidget>()
.lambda().eq(ReportDashboardWidget::getReportCode, reportCode));
List<ReportDashboardWidgetDto> widgets = dto.getWidgets();
List<ReportDashboardWidget> reportDashboardWidgetList = new ArrayList<>();
for (int i = 0; i < widgets.size(); i++) {
ReportDashboardWidget reportDashboardWidget = new ReportDashboardWidget();
ReportDashboardWidgetDto reportDashboardWidgetDto = widgets.get(i);
String type = reportDashboardWidgetDto.getType();
ReportDashboardWidgetValueDto value = reportDashboardWidgetDto.getValue();
reportDashboardWidget.setReportCode(reportCode);
reportDashboardWidget.setType(type);
reportDashboardWidget.setSetup(value.getSetup() != null ? JSONObject.toJSONString(value.getSetup()) : "");
reportDashboardWidget.setData(value.getData() != null ? JSONObject.toJSONString(value.getData()) : "");
reportDashboardWidget.setPosition(value.getPosition() != null ? JSONObject.toJSONString(value.getPosition()) : "");
reportDashboardWidget.setCollapse(value.getCollapse() != null ? JSONObject.toJSONString(value.getCollapse()) : "");
reportDashboardWidget.setEnableFlag(1);
reportDashboardWidget.setDeleteFlag(0);
reportDashboardWidget.setSort((long) (i + 1));
reportDashboardWidgetList.add(reportDashboardWidget);
}
reportDashboardWidgetService.insertBatch(reportDashboardWidgetList);
}
@Override
public Object getChartData(ChartDto dto) {
// String chartType = dto.getChartType();
DataSetDto setDto = new DataSetDto();
setDto.setSetCode(dto.getSetCode());
setDto.setContextData(dto.getContextData());
OriginalDataDto result = dataSetService.getData(setDto);
List<JSONObject> data = result.getData();
//处理时间轴
List<JSONObject> resultData = buildTimeLine(data, dto);
return resultData;
// return getTarget(chartType).transform(dto, result.getData());
}
public ChartStrategy getTarget(String type) {
for (String s : queryServiceImplMap.keySet()) {
if (s.contains(type)) {
return queryServiceImplMap.get(s);
}
}
throw BusinessExceptionBuilder.build(ResponseCode.RULE_CONTENT_NOT_EXIST);
}
@Override
public void afterPropertiesSet() {
Map<String, ChartStrategy> beanMap = applicationContext.getBeansOfType(ChartStrategy.class);
//遍历该接口的所有实现将其放入map中
for (ChartStrategy serviceImpl : beanMap.values()) {
queryServiceImplMap.put(serviceImpl.type(), serviceImpl);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
*
*
* @param dto
*/
public void analysisData(ReportDashboardWidgetValueDto dto) {
// if (StringUtils.isBlank(reportDashboardWidgetDto.getSetCode())) {
// return;
// }
// DataSetDto dto = new DataSetDto();
// dto.setSetCode(reportDashboardWidgetDto.getSetCode());
// if (reportDashboardWidgetDto.getContextData() != null && reportDashboardWidgetDto.getContextData().size() > 0) {
// dto.setContextData(reportDashboardWidgetDto.getContextData());
// }
// OriginalDataDto data = dataSetService.getData(dto);
// reportDashboardWidgetDto.setData(JSONObject.toJSONString(data.getData()));
}
public List<JSONObject> buildTimeLine(List<JSONObject> data, ChartDto dto) {
Map<String, String> chartProperties = dto.getChartProperties();
if (null == chartProperties || chartProperties.size() < 1) {
return data;
}
Map<String, Object> contextData = dto.getContextData();
if (null == contextData || contextData.size() < 1) {
return data;
}
if (contextData.containsKey("startTime") && contextData.containsKey("endTime")) {
dto.setStartTime(contextData.get("startTime").toString());
dto.setEndTime(contextData.get("endTime").toString());
}
if (StringUtils.isBlank(dto.getStartTime()) || StringUtils.isBlank(dto.getEndTime())) {
return data;
}
//获取时间轴字段和解析时间颗粒度
chartProperties.forEach((key, value) -> {
dto.setParticles(value);
setTimeLineFormat(dto);
if (StringUtils.isNotBlank(dto.getDataTimeFormat())) {
dto.setTimeLineFiled(key);
return;
}
});
if (StringUtils.isBlank(dto.getDataTimeFormat())) {
return data;
}
Date beginTime = DateUtil.parseHmsTime(dto.getStartTime());
Date endTime = DateUtil.parseHmsTime(dto.getEndTime());
SimpleDateFormat showFormat = new SimpleDateFormat(dto.getTimeLineFormat());
SimpleDateFormat dataFormat = new SimpleDateFormat(dto.getDataTimeFormat());
Calendar calendar = Calendar.getInstance();
calendar.setTime(beginTime);
Calendar calendarEnd = Calendar.getInstance();
calendarEnd.setTime(endTime);
List<String> timeLine = new ArrayList<>();
List<String> dataTimeline = new ArrayList<>();
timeLine.add(showFormat.format(calendar.getTime()));
dataTimeline.add(dataFormat.format(calendar.getTime()));
//添加时间轴数据
while (true) {
calendar.add(dto.getTimeUnit(), 1);
timeLine.add(showFormat.format(calendar.getTime()));
dataTimeline.add(dataFormat.format(calendar.getTime()));
if (showFormat.format(calendar.getTime()).equals(showFormat.format(calendarEnd.getTime()))) {
break;
}
}
//根据时间轴生成对应的时间线,数据不存在,补数据
List<JSONObject> result = new ArrayList<>();
JSONObject jsonDemo = data.get(0);
String timeLineFiled = dto.getTimeLineFiled();
for (String dateFormat : dataTimeline) {
boolean flag = true;
for (JSONObject datum : data) {
if (datum.containsKey(timeLineFiled) && datum.getString(timeLineFiled).equals(dateFormat)) {
result.add(datum);
flag = false;
}
}
if (flag) {
//补数据
JSONObject json = new JSONObject();
jsonDemo.forEach((s, o) -> {
if (s.equals(timeLineFiled)) {
json.put(timeLineFiled, dateFormat);
} else {
json.put(s, 0);
}
});
result.add(json);
}
}
return result;
}
//设置时间格式
private void setTimeLineFormat(ChartDto dto) {
String particles = dto.getParticles();
if ("xAxis-hour".equals(particles)) {
dto.setDataTimeFormat("yyyy-MM-dd HH");
dto.setTimeLineFormat("MM-dd HH");
dto.setTimeUnit(Calendar.HOUR);
} else if ("xAxis-day".equals(particles)) {
dto.setDataTimeFormat("yyyy-MM-dd");
dto.setTimeLineFormat("yyyy-MM-dd");
dto.setTimeUnit(Calendar.DATE);
} else if ("xAxis-month".equals(particles)) {
dto.setDataTimeFormat("yyyy-MM");
dto.setTimeLineFormat("yyyy-MM");
dto.setTimeUnit(Calendar.MONTH);
} else if ("xAxis-year".equals(particles)) {
dto.setDataTimeFormat("yyyy");
dto.setTimeLineFormat("yyyy");
dto.setTimeUnit(Calendar.YEAR);
}
}
}

@ -0,0 +1,47 @@
package com.anjiplus.template.gaea.business.modules.data.dashboard.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by raodeming on 2021/4/29.
*/
public class DateUtil {
private static String defaultDatePattern = "yyyy-MM-dd";
private static String defaultDateTimePattern = "yyyy-MM-dd HH:mm:ss.SSS";
private static String defaultyyyyMMddPattern = "yyyyMMdd";
private static String defaultYmdHmsPattern = "yyyy-MM-dd HH:mm:ss";
private static String defaultHmsPattern = "HH:mm:ss";
/**yyyy-MM-dd HH:mm:ss
* @param dateStr yyyy-MM-dd HH:mm:ss
* @return
*/
public static Date parseHmsTime(String dateStr) {
return parse(dateStr, defaultYmdHmsPattern);
}
/**
* @param dateStr
* @param pattern
* @return
*/
public static Date parse(String dateStr, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
if (dateStr == null || "".equals(dateStr)) {
return null;
}
try {
Date d = sdf.parse(dateStr);
return d;
} catch (ParseException e) {
System.out.println("日期转换错误: " + e.getMessage());
return null;
}
}
}

@ -0,0 +1,28 @@
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto;
import lombok.Data;
import java.io.Serializable;
/**
*
* @description dto
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
@Data
public class ReportDashboardWidgetDto implements Serializable {
/**
* DASHBOARD_PANEL_TYPE
*/
private String type;
/**
* value
*/
private ReportDashboardWidgetValueDto value;
}

@ -0,0 +1,42 @@
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
/**
*
* @description dto
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
@Data
public class ReportDashboardWidgetValueDto implements Serializable {
/** 报表编码 */
private String reportCode;
/** 组件的渲染属性json */
private JSONObject setup;
/** 组件的数据属性json */
private JSONObject data;
/** 组件的配置属性json */
private JSONObject collapse;
/** 组件的大小位置属性json */
private JSONObject position;
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag;
/** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
private Integer deleteFlag;
/** 排序,图层的概念 */
private Long sort;
}

@ -0,0 +1,20 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.param;
import lombok.Data;
import java.io.Serializable;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import java.util.List;
/**
* @desc ReportDashboardWidget
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
@Data
public class ReportDashboardWidgetParam extends PageParam implements Serializable{
}

@ -0,0 +1,16 @@
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao;
import org.apache.ibatis.annotations.Mapper;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
/**
* ReportDashboardWidget Mapper
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
@Mapper
public interface ReportDashboardWidgetMapper extends GaeaBaseMapper<ReportDashboardWidget> {
}

@ -0,0 +1,45 @@
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description entity
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
@TableName(value="gaea_report_dashboard_widget")
@Data
public class ReportDashboardWidget extends GaeaBaseEntity {
@ApiModelProperty(value = "报表编码")
private String reportCode;
@ApiModelProperty(value = "组件类型参考字典DASHBOARD_PANEL_TYPE")
private String type;
@ApiModelProperty(value = "组件的渲染属性json")
private String setup;
@ApiModelProperty(value = "组件的数据属性json")
private String data;
@ApiModelProperty(value = "组件的配置属性json")
private String collapse;
@ApiModelProperty(value = "组件的大小位置属性json")
private String position;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
private Integer deleteFlag;
@ApiModelProperty(value = "排序,图层的概念")
private Long sort;
}

@ -0,0 +1,21 @@
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.param.ReportDashboardWidgetParam;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
/**
* @desc ReportDashboardWidget
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
public interface ReportDashboardWidgetService extends GaeaBaseService<ReportDashboardWidgetParam, ReportDashboardWidget> {
/***
*
*
* @param id
*/
ReportDashboardWidget getDetail(Long id);
}

@ -0,0 +1,34 @@
package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service.impl;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service.ReportDashboardWidgetService;
import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.ReportDashboardWidgetMapper;
/**
* @desc ReportDashboardWidget
* @author Raod
* @date 2021-04-12 15:12:43.724
**/
@Service
//@RequiredArgsConstructor
public class ReportDashboardWidgetServiceImpl implements ReportDashboardWidgetService {
@Autowired
private ReportDashboardWidgetMapper reportDashboardWidgetMapper;
@Override
public GaeaBaseMapper<ReportDashboardWidget> getMapper() {
return reportDashboardWidgetMapper;
}
@Override
public ReportDashboardWidget getDetail(Long id) {
ReportDashboardWidget reportDashboardWidget = this.selectOne(id);
return reportDashboardWidget;
}
}

@ -0,0 +1,149 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.controller;
import com.anji.plus.gaea.annotation.AccessKey;
import com.anji.plus.gaea.annotation.Permission;
import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anji.plus.gaea.holder.UserContentHolder;
import com.anji.plus.gaea.utils.GaeaUtils;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param.DataSetParam;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param.DataSetTestTransformParam;
import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
import com.anjiplus.template.gaea.business.modules.data.dataSet.service.DataSetService;
import io.swagger.annotations.Api;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @desc controller
* @website https://gitee.com/anji-plus/gaea
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@RestController
@Api(tags = "数据集管理")
@RequestMapping("/dataSet")
public class DataSetController extends GaeaBaseController<DataSetParam, DataSet, DataSetDto> {
@Autowired
private DataSetService dataSetService;
@Override
public GaeaBaseService<DataSetParam, DataSet> getService() {
return dataSetService;
}
@Override
public DataSet getEntity() {
return new DataSet();
}
@Override
public DataSetDto getDTO() {
return new DataSetDto();
}
@GetMapping("/detailBysetId/{id}")
@Permission(
code = "DETAIL",
name = "明细"
)
public ResponseBean detailBysetId(@PathVariable("id") Long id) {
this.logger.info("{}根据ID查询服务开始id为{}", this.getClass().getSimpleName(), id);
ResponseBean responseBean = this.responseSuccessWithData(dataSetService.detailSet(id));
this.logger.info("{}根据ID查询结束结果{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(responseBean));
return responseBean;
}
@GetMapping({"/detailBysetCode/{setCode}"})
@Permission(
code = "DETAIL",
name = "明细"
)
@AccessKey
public ResponseBean detailBysetCode(@PathVariable("setCode") String setCode) {
this.logger.info("{}根据setCode查询服务开始setCode为{}", this.getClass().getSimpleName(), setCode);
ResponseBean responseBean = this.responseSuccessWithData(dataSetService.detailSet(setCode));
this.logger.info("{}根据setCode查询结束结果{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(responseBean));
return responseBean;
}
@PostMapping
@Permission(
code = "INSERT",
name = "新增"
)
@GaeaAuditLog(
pageTitle = "新增"
)
@Override
public ResponseBean insert(@RequestBody DataSetDto dto) {
this.logger.info("{}新增服务开始,参数:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(dto));
DataSetDto dataSetDto = dataSetService.insertSet(dto);
this.logger.info("{}新增服务结束,结果:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(dataSetDto));
return ResponseBean.builder().data(dataSetDto).build();
}
@PutMapping
@Permission(
code = "UPDATE",
name = "更新"
)
@GaeaAuditLog(
pageTitle = "修改"
)
@Override
public ResponseBean update(@RequestBody DataSetDto dto) {
String username = UserContentHolder.getContext().getUsername();
this.logger.info("{}更新服务开始,更新人:{},参数:{}", this.getClass().getSimpleName(), username, GaeaUtils.toJSONString(dto));
ResponseBean responseBean = this.responseSuccess();
dataSetService.updateSet(dto);
this.logger.info("{}更新服务结束,结果:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(responseBean));
return this.responseSuccess();
}
@DeleteMapping({"/{id}"})
@Permission(
code = "DELETE",
name = "删除"
)
@GaeaAuditLog(
pageTitle = "删除"
)
@Override
public ResponseBean deleteById(@PathVariable("id") Long id) {
this.logger.info("{}删除服务开始参数ID{}", this.getClass().getSimpleName(), id);
dataSetService.deleteSet(id);
this.logger.info("{}删除服务结束", this.getClass().getSimpleName());
return this.responseSuccess();
}
/**
*
* @param param
* @return
*/
@PostMapping("/testTransform")
public ResponseBean testTransform(@Validated @RequestBody DataSetTestTransformParam param) {
DataSetDto dto = new DataSetDto();
BeanUtils.copyProperties(param, dto);
return responseSuccessWithData(dataSetService.testTransform(dto));
}
/**
*
* @return
*/
@GetMapping("/queryAllDataSet")
public ResponseBean queryAllDataSet() {
return responseSuccessWithData(dataSetService.queryAllDataSet());
}
}

@ -0,0 +1,58 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* @description dto
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@Data
public class DataSetDto extends GaeaBaseDTO implements Serializable {
/** 数据集编码 */
private String setCode;
/** 数据集名称 */
private String setName;
/** 数据集描述 */
private String setDesc;
/** 数据源编码 */
private String sourceCode;
/** 动态查询sql或者接口中的请求体 */
private String dynSentence;
/** 结果案例 */
private String caseResult;
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag;
/** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
private Integer deleteFlag;
/** 请求参数集合 */
private List<DataSetParamDto> dataSetParamDtoList;
/** 数据转换集合 */
private List<DataSetTransformDto> dataSetTransformDtoList;
/** 传入的自定义参数*/
private Map<String, Object> contextData;
private Set<String> setParamList;
}

@ -0,0 +1,32 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* Created by raodeming on 2021/3/26.
*/
@Data
public class OriginalDataDto implements Serializable {
/**总数*/
private long total;
/**获取的数据详情*/
private List<JSONObject> data;
public OriginalDataDto(List<JSONObject> data) {
this.data = data;
}
public OriginalDataDto(long total, List<JSONObject> data) {
this.total = total;
this.data = data;
}
public OriginalDataDto() {
}
}

@ -0,0 +1,30 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
/**
* @desc DataSet
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@Data
public class DataSetParam extends PageParam implements Serializable{
/** 数据集编码 */
@Query(QueryEnum.LIKE)
private String setCode;
/** 数据集名称 */
@Query(QueryEnum.LIKE)
private String setName;
/** 数据源编码 */
@Query(QueryEnum.EQ)
private String sourceCode;
}

@ -0,0 +1,34 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.List;
/**
* @desc DataSet
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@Data
public class DataSetTestTransformParam implements Serializable{
/** 数据源编码 */
@NotBlank(message = "sourceCode not empty")
private String sourceCode;
/** 动态查询sql或者接口中的请求体 */
private String dynSentence;
/** 请求参数集合 */
private List<DataSetParamDto> dataSetParamDtoList;
/** 数据转换集合 */
private List<DataSetTransformDto> dataSetTransformDtoList;
}

@ -0,0 +1,16 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.dao;
import org.apache.ibatis.annotations.Mapper;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
/**
* DataSet Mapper
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@Mapper
public interface DataSetMapper extends GaeaBaseMapper<DataSet> {
}

@ -0,0 +1,45 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity;
import com.anji.plus.gaea.annotation.Unique;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.anjiplus.template.gaea.common.RespCommonCode;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description entity
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@TableName(value="gaea_report_data_set")
@Data
public class DataSet extends GaeaBaseEntity {
@ApiModelProperty(value = "数据集编码")
@Unique(code = RespCommonCode.SET_CODE_ISEXIST)
private String setCode;
@ApiModelProperty(value = "数据集名称")
private String setName;
@ApiModelProperty(value = "数据集描述")
private String setDesc;
@ApiModelProperty(value = "数据源编码")
private String sourceCode;
@ApiModelProperty(value = "动态查询sql或者接口中的请求体")
private String dynSentence;
@ApiModelProperty(value = "结果案例")
private String caseResult;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag;
}

@ -0,0 +1,70 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.service;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.OriginalDataDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param.DataSetParam;
import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
import java.util.List;
/**
* @desc DataSet
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
public interface DataSetService extends GaeaBaseService<DataSetParam, DataSet> {
/**
*
* @param id
* @return
*/
DataSetDto detailSet(Long id);
/**
*
* @param setCode
* @return
*/
DataSetDto detailSet(String setCode);
/**
*
* @param dto
*/
DataSetDto insertSet(DataSetDto dto);
/**
*
* @param dto
*/
void updateSet(DataSetDto dto);
/**
*
* @param id
*/
void deleteSet(Long id);
/**
*
* @param dto
* @return
*/
OriginalDataDto getData(DataSetDto dto);
/**
*
* @param dto
* @return
*/
OriginalDataDto testTransform(DataSetDto dto);
/**
*
* @return
*/
List<DataSet> queryAllDataSet();
}

@ -0,0 +1,343 @@
package com.anjiplus.template.gaea.business.modules.data.dataSet.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.constant.Enabled;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.gaea.utils.GaeaBeanUtils;
import com.anjiplus.template.gaea.business.code.ResponseCode;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.OriginalDataDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.DataSetMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
import com.anjiplus.template.gaea.business.modules.data.dataSet.service.DataSetService;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.DataSetTransformService;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.service.DataSourceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @desc DataSet
* @author Raod
* @date 2021-03-18 12:11:31.150755900
**/
@Service
//@RequiredArgsConstructor
public class DataSetServiceImpl implements DataSetService {
@Autowired
private DataSetMapper dataSetMapper;
@Autowired
private DataSetParamService dataSetParamService;
@Autowired
private DataSetTransformService dataSetTransformService;
@Autowired
private DataSourceService dataSourceService;
@Override
public GaeaBaseMapper<DataSet> getMapper() {
return dataSetMapper;
}
/**
*
*
* @param id
* @return
*/
@Override
public DataSetDto detailSet(Long id) {
DataSetDto dto = new DataSetDto();
DataSet result = selectOne(id);
String setCode = result.getSetCode();
GaeaBeanUtils.copyAndFormatter(result, dto);
return getDetailSet(dto, setCode);
}
/**
*
*
* @param setCode
* @return
*/
@Override
public DataSetDto detailSet(String setCode) {
DataSetDto dto = new DataSetDto();
DataSet result = selectOne("set_code", setCode);
GaeaBeanUtils.copyAndFormatter(result, dto);
return getDetailSet(dto, setCode);
}
public DataSetDto getDetailSet(DataSetDto dto, String setCode) {
//查询参数
List<DataSetParam> dataSetParamList = dataSetParamService.list(
new QueryWrapper<DataSetParam>()
.lambda()
.eq(DataSetParam::getSetCode, setCode)
);
List<DataSetParamDto> dataSetParamDtoList = new ArrayList<>();
dataSetParamList.forEach(dataSetParam -> {
DataSetParamDto dataSetParamDto = new DataSetParamDto();
GaeaBeanUtils.copyAndFormatter(dataSetParam, dataSetParamDto);
dataSetParamDtoList.add(dataSetParamDto);
});
dto.setDataSetParamDtoList(dataSetParamDtoList);
//数据转换
List<DataSetTransform> dataSetTransformList = dataSetTransformService.list(
new QueryWrapper<DataSetTransform>()
.lambda()
.eq(DataSetTransform::getSetCode, setCode)
.orderByAsc(DataSetTransform::getOrderNum)
);
List<DataSetTransformDto> dataSetTransformDtoList = new ArrayList<>();
dataSetTransformList.forEach(dataSetTransform -> {
DataSetTransformDto dataSetTransformDto = new DataSetTransformDto();
GaeaBeanUtils.copyAndFormatter(dataSetTransform, dataSetTransformDto);
dataSetTransformDtoList.add(dataSetTransformDto);
});
dto.setDataSetTransformDtoList(dataSetTransformDtoList);
if (StringUtils.isNotBlank(dto.getCaseResult())) {
try {
JSONArray jsonArray = JSONArray.parseArray(dto.getCaseResult());
JSONObject jsonObject = jsonArray.getJSONObject(0);
dto.setSetParamList(jsonObject.keySet());
} catch (Exception e) {
}
}
return dto;
}
/**
*
*
* @param dto
*/
@Override
@Transactional
public DataSetDto insertSet(DataSetDto dto) {
List<DataSetParamDto> dataSetParamDtoList = dto.getDataSetParamDtoList();
List<DataSetTransformDto> dataSetTransformDtoList = dto.getDataSetTransformDtoList();
//1.新增数据集
DataSet dataSet = new DataSet();
BeanUtils.copyProperties(dto, dataSet);
insert(dataSet);
//2.更新查询参数
dataSetParamBatch(dataSetParamDtoList, dto.getSetCode());
//3.更新数据转换
dataSetTransformBatch(dataSetTransformDtoList, dto.getSetCode());
return dto;
}
/**
*
*
* @param dto
*/
@Override
@Transactional
public void updateSet(DataSetDto dto) {
List<DataSetParamDto> dataSetParamDtoList = dto.getDataSetParamDtoList();
List<DataSetTransformDto> dataSetTransformDtoList = dto.getDataSetTransformDtoList();
//1.更新数据集
DataSet dataSet = new DataSet();
BeanUtils.copyProperties(dto, dataSet);
update(dataSet);
//2.更新查询参数
dataSetParamBatch(dataSetParamDtoList, dto.getSetCode());
//3.更新数据转换
dataSetTransformBatch(dataSetTransformDtoList, dto.getSetCode());
}
/**
*
*
* @param id
*/
@Override
public void deleteSet(Long id) {
DataSet dataSet = selectOne(id);
String setCode = dataSet.getSetCode();
//1.删除数据集
deleteById(id);
//2.删除查询参数
dataSetParamService.delete(
new QueryWrapper<DataSetParam>()
.lambda()
.eq(DataSetParam::getSetCode, setCode)
);
//3.删除数据转换
dataSetTransformService.delete(
new QueryWrapper<DataSetTransform>()
.lambda()
.eq(DataSetTransform::getSetCode, setCode)
);
}
/**
*
*
* @param dto
* @return
*/
@Override
public OriginalDataDto getData(DataSetDto dto) {
OriginalDataDto originalDataDto = new OriginalDataDto();
String setCode = dto.getSetCode();
//1.获取数据集、参数替换、数据转换
DataSetDto dataSetDto = detailSet(setCode);
//2.获取数据源
DataSource dataSource = dataSourceService.selectOne("source_code", dataSetDto.getSourceCode());
//3.参数替换
//3.1参数校验
boolean verification = dataSetParamService.verification(dataSetDto.getDataSetParamDtoList(), dto.getContextData());
if (!verification) {
throw BusinessExceptionBuilder.build(ResponseCode.RULE_FIELDS_CHECK_ERROR);
}
String dynSentence = dataSetParamService.transform(dto.getContextData(), dataSetDto.getDynSentence());
//4.获取数据
DataSourceDto dataSourceDto = new DataSourceDto();
BeanUtils.copyProperties(dataSource, dataSourceDto);
dataSourceDto.setDynSentence(dynSentence);
dataSourceDto.setContextData(dto.getContextData());
//获取total,判断contextData中是否传入分页参数
if (null != dto.getContextData()
&& dto.getContextData().containsKey("pageNumber")
&& dto.getContextData().containsKey("pageSize")) {
long total = dataSourceService.total(dataSourceDto, dto);
originalDataDto.setTotal(total);
}
List<JSONObject> data = dataSourceService.execute(dataSourceDto);
//5.数据转换
List<JSONObject> transform = dataSetTransformService.transform(dataSetDto.getDataSetTransformDtoList(), data);
originalDataDto.setData(transform);
return originalDataDto;
}
/**
* @param dto
* @return
*/
@Override
public OriginalDataDto testTransform(DataSetDto dto) {
OriginalDataDto originalDataDto = new OriginalDataDto();
String sourceCode = dto.getSourceCode();
//1.获取数据源
DataSource dataSource = dataSourceService.selectOne("source_code", sourceCode);
//3.参数替换
//3.1参数校验
boolean verification = dataSetParamService.verification(dto.getDataSetParamDtoList(), null);
if (!verification) {
throw BusinessExceptionBuilder.build(ResponseCode.RULE_FIELDS_CHECK_ERROR);
}
String dynSentence = dataSetParamService.transform(dto.getDataSetParamDtoList(), dto.getDynSentence());
//4.获取数据
DataSourceDto dataSourceDto = new DataSourceDto();
BeanUtils.copyProperties(dataSource, dataSourceDto);
dataSourceDto.setDynSentence(dynSentence);
dataSourceDto.setContextData(dto.getContextData());
//获取total,判断DataSetParamDtoList中是否传入分页参数
Map<String, Object> collect = dto.getDataSetParamDtoList().stream().collect(Collectors.toMap(DataSetParamDto::getParamName, DataSetParamDto::getSampleItem));
if (collect.containsKey("pageNumber") && collect.containsKey("pageSize")) {
dto.setContextData(collect);
long total = dataSourceService.total(dataSourceDto, dto);
originalDataDto.setTotal(total);
}
List<JSONObject> data = dataSourceService.execute(dataSourceDto);
//5.数据转换
List<JSONObject> transform = dataSetTransformService.transform(dto.getDataSetTransformDtoList(), data);
originalDataDto.setData(transform);
return originalDataDto;
}
/**
*
*
* @return
*/
@Override
public List<DataSet> queryAllDataSet() {
LambdaQueryWrapper<DataSet> wrapper = Wrappers.lambdaQuery();
wrapper.select(DataSet::getSetCode, DataSet::getSetName, DataSet::getSetDesc, DataSet::getId)
.eq(DataSet::getEnableFlag, Enabled.YES.getValue());
return dataSetMapper.selectList(wrapper);
}
public void dataSetParamBatch(List<DataSetParamDto> dataSetParamDtoList,String setCode){
dataSetParamService.delete(
new QueryWrapper<DataSetParam>()
.lambda()
.eq(DataSetParam::getSetCode, setCode)
);
if (null == dataSetParamDtoList || dataSetParamDtoList.size() <= 0) {
return;
}
List<DataSetParam> dataSetParamList = new ArrayList<>();
dataSetParamDtoList.forEach(dataSetParamDto -> {
DataSetParam dataSetParam = new DataSetParam();
BeanUtils.copyProperties(dataSetParamDto, dataSetParam);
dataSetParam.setSetCode(setCode);
dataSetParamList.add(dataSetParam);
});
dataSetParamService.insertBatch(dataSetParamList);
}
public void dataSetTransformBatch(List<DataSetTransformDto> dataSetTransformDtoList,String setCode){
dataSetTransformService.delete(
new QueryWrapper<DataSetTransform>()
.lambda()
.eq(DataSetTransform::getSetCode, setCode)
);
if (null == dataSetTransformDtoList || dataSetTransformDtoList.size() <= 0) {
return;
}
List<DataSetTransform> dataSetTransformList = new ArrayList<>();
for (int i = 0; i < dataSetTransformDtoList.size(); i++) {
DataSetTransform dataSetTransform = new DataSetTransform();
BeanUtils.copyProperties(dataSetTransformDtoList.get(i), dataSetTransform);
dataSetTransform.setOrderNum(i + 1);
dataSetTransform.setSetCode(setCode);
dataSetTransformList.add(dataSetTransform);
}
dataSetTransformService.insertBatch(dataSetTransformList);
}
}

@ -0,0 +1,62 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param.DataSetParamParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param.DataSetParamValidationParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @desc controller
* @website https://gitee.com/anji-plus/gaea
* @author Raod
* @date 2021-03-18 12:12:33.108033200
**/
@RestController
@Api(tags = "数据集动态参数管理")
@RequestMapping("/dataSetParam")
public class DataSetParamController extends GaeaBaseController<DataSetParamParam, DataSetParam, DataSetParamDto> {
@Autowired
private DataSetParamService dataSetParamService;
@Override
public GaeaBaseService<DataSetParamParam, DataSetParam> getService() {
return dataSetParamService;
}
@Override
public DataSetParam getEntity() {
return new DataSetParam();
}
@Override
public DataSetParamDto getDTO() {
return new DataSetParamDto();
}
/**
*
* @param param
* @return
*/
@PostMapping("/verification")
public ResponseBean verification(@Validated @RequestBody DataSetParamValidationParam param) {
DataSetParamDto dto = new DataSetParamDto();
dto.setSampleItem(param.getSampleItem());
dto.setValidationRules(param.getValidationRules());
return responseSuccessWithData(dataSetParamService.verification(dto));
}
}

@ -0,0 +1,48 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import lombok.Data;
import java.io.Serializable;
/**
*
* @description dto
* @author Raod
* @date 2021-03-18 12:12:33.108033200
**/
@Data
public class DataSetParamDto extends GaeaBaseDTO implements Serializable {
/** 数据集编码 */
private String setCode;
/** 参数名 */
private String paramName;
/** 参数描述 */
private String paramDesc;
/** 参数类型,字典= */
private String paramType;
/** 参数示例项 */
private String sampleItem;
/** 0--非必填 1--必填 DIC_NAME=REQUIRED_FLAG */
private Integer requiredFlag;
/** js校验字段值规则满足校验返回 true */
private String validationRules;
/** 排序 */
private Integer orderNum;
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag;
/** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
private Integer deleteFlag;
}

@ -0,0 +1,17 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
/**
* @desc DataSetParam
* @author Raod
* @date 2021-03-18 12:12:33.108033200
**/
@Data
public class DataSetParamParam extends PageParam implements Serializable{
}

@ -0,0 +1,22 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* Created by raodeming on 2021/3/24.
*/
@Data
public class DataSetParamValidationParam implements Serializable {
/** 参数示例项 */
@NotBlank(message = "sampleItem not empty")
private String sampleItem;
/** js校验字段值规则满足校验返回 true */
@NotBlank(message = "validationRules not empty")
private String validationRules;
}

@ -0,0 +1,15 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
import org.apache.ibatis.annotations.Mapper;
/**
* DataSetParam Mapper
* @author Raod
* @date 2021-03-18 12:12:33.108033200
**/
@Mapper
public interface DataSetParamMapper extends GaeaBaseMapper<DataSetParam> {
}

@ -0,0 +1,48 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description entity
* @author Raod
* @date 2021-03-18 12:12:33.108033200
**/
@TableName(value="gaea_report_data_set_param")
@Data
public class DataSetParam extends GaeaBaseEntity {
@ApiModelProperty(value = "数据集编码")
private String setCode;
@ApiModelProperty(value = "参数名")
private String paramName;
@ApiModelProperty(value = "参数描述")
private String paramDesc;
@ApiModelProperty(value = "参数类型,字典=")
private String paramType;
@ApiModelProperty(value = "参数示例项")
private String sampleItem;
@ApiModelProperty(value = "0--非必填 1--必填 DIC_NAME=REQUIRED_FLAG")
private Integer requiredFlag;
@ApiModelProperty(value = "js校验字段值规则满足校验返回 true")
private String validationRules;
@ApiModelProperty(value = "排序")
private Integer orderNum;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag;
}

@ -0,0 +1,52 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.service;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param.DataSetParamParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
import java.util.List;
import java.util.Map;
/**
* @author Raod
* @desc DataSetParam
* @date 2021-03-18 12:12:33.108033200
**/
public interface DataSetParamService extends GaeaBaseService<DataSetParamParam, DataSetParam> {
/**
*
*
* @param contextData
* @param dynSentence
* @return
*/
String transform(Map<String, Object> contextData, String dynSentence);
/**
*
*
* @param dataSetParamDtoList
* @param dynSentence
* @return
*/
String transform(List<DataSetParamDto> dataSetParamDtoList, String dynSentence);
/**
* js
* @param dataSetParamDto
* @return
*/
boolean verification(DataSetParamDto dataSetParamDto);
/**
* js
*
* @param dataSetParamDtoList
* @return
*/
boolean verification(List<DataSetParamDto> dataSetParamDtoList, Map<String, Object> contextData);
}

@ -0,0 +1,136 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.impl;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.DataSetParamMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.util.ParamsResolverHelper;
import com.anjiplus.template.gaea.common.RespCommonCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @desc DataSetParam
* @author Raod
* @date 2021-03-18 12:12:33.108033200
**/
@Service
//@RequiredArgsConstructor
@Slf4j
public class DataSetParamServiceImpl implements DataSetParamService {
private ScriptEngine engine;
{
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("JavaScript");
}
@Autowired
private DataSetParamMapper dataSetParamMapper;
@Override
public GaeaBaseMapper<DataSetParam> getMapper() {
return dataSetParamMapper;
}
/**
*
*
* @param contextData
* @param dynSentence
* @return
*/
@Override
public String transform(Map<String, Object> contextData, String dynSentence) {
if (StringUtils.isBlank(dynSentence)) {
return dynSentence;
}
if (dynSentence.contains("${")) {
dynSentence = ParamsResolverHelper.resolveParams(contextData, dynSentence);
}
if (dynSentence.contains("${")) {
throw BusinessExceptionBuilder.build(RespCommonCode.INCOMPLETE_PARAMETER_REPLACEMENT_VALUES, dynSentence);
}
return dynSentence;
}
/**
*
*
* @param dataSetParamDtoList
* @param dynSentence
* @return
*/
@Override
public String transform(List<DataSetParamDto> dataSetParamDtoList, String dynSentence) {
Map<String, Object> contextData = new HashMap<>();
if (null == dataSetParamDtoList || dataSetParamDtoList.size() <= 0) {
return dynSentence;
}
dataSetParamDtoList.forEach(dataSetParamDto -> {
contextData.put(dataSetParamDto.getParamName(), dataSetParamDto.getSampleItem());
});
return transform(contextData, dynSentence);
}
/**
* js
*
* @param dataSetParamDto
* @return
*/
@Override
public boolean verification(DataSetParamDto dataSetParamDto) {
String sampleItem = dataSetParamDto.getSampleItem();
String validationRules = dataSetParamDto.getValidationRules();
if (StringUtils.isNotBlank(validationRules)) {
validationRules = validationRules + "\nvar result = verification('" + sampleItem + "');";
try {
engine.eval(validationRules);
return Boolean.parseBoolean(engine.get("result").toString());
} catch (Exception ex) {
throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_JS_ERROR, ex.getMessage());
}
}
return true;
}
/**
* js
*
* @param dataSetParamDtoList
* @return
*/
@Override
public boolean verification(List<DataSetParamDto> dataSetParamDtoList, Map<String, Object> contextData) {
if (null == dataSetParamDtoList || dataSetParamDtoList.size() == 0) {
return true;
}
for (DataSetParamDto dataSetParamDto : dataSetParamDtoList) {
if (null != contextData) {
String value = contextData.getOrDefault(dataSetParamDto.getParamName(), "").toString();
dataSetParamDto.setSampleItem(value);
}
if (!verification(dataSetParamDto)) {
return false;
}
}
return true;
}
}

@ -0,0 +1,36 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetParam.util;
import org.springframework.util.PropertyPlaceholderHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by raodeming on 2021/3/23.
*/
public class ParamsResolverHelper {
private static String placeholderPrefix = "${";
private static String placeholderSuffix = "}";
private static PropertyPlaceholderHelper helper =
new PropertyPlaceholderHelper(placeholderPrefix, placeholderSuffix);
public static String resolveParams(final Map<String, Object> param, String con) {
con = helper.replacePlaceholders(con, (key -> param.get(key) + ""));
return con;
}
private static Pattern key = Pattern.compile("\\$\\{(.*?)\\}");
public static List<String> findParamKeys(String con) {
Matcher m = key.matcher(con);
List ret = new ArrayList();
while (m.find()) {
ret.add(m.group(1));
}
return ret;
}
}

@ -0,0 +1,44 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.param.DataSetTransformParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.DataSetTransformService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @desc controller
* @website https://gitee.com/anji-plus/gaea
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
@RestController
@Api(tags = "数据集数据转换管理")
@RequestMapping("/dataSetTransform")
public class DataSetTransformController extends GaeaBaseController<DataSetTransformParam, DataSetTransform, DataSetTransformDto> {
@Autowired
private DataSetTransformService dataSetTransformService;
@Override
public GaeaBaseService<DataSetTransformParam, DataSetTransform> getService() {
return dataSetTransformService;
}
@Override
public DataSetTransform getEntity() {
return new DataSetTransform();
}
@Override
public DataSetTransformDto getDTO() {
return new DataSetTransformDto();
}
}

@ -0,0 +1,36 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import lombok.Data;
import java.io.Serializable;
/**
*
* @description dto
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
@Data
public class DataSetTransformDto extends GaeaBaseDTO implements Serializable {
/** 数据集编码 */
private String setCode;
/** 数据转换类型DIC_NAME=TRANSFORM_TYPE; jsjavaBean字典转换 */
private String transformType;
/** 数据转换script,处理逻辑 */
private String transformScript;
/** 排序,执行数据转换顺序 */
private Integer orderNum;
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag;
/** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
private Integer deleteFlag;
}

@ -0,0 +1,17 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.param;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
/**
* @desc DataSetTransform
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
@Data
public class DataSetTransformParam extends PageParam implements Serializable{
}

@ -0,0 +1,15 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
import org.apache.ibatis.annotations.Mapper;
/**
* DataSetTransform Mapper
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
@Mapper
public interface DataSetTransformMapper extends GaeaBaseMapper<DataSetTransform> {
}

@ -0,0 +1,36 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description entity
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
@TableName(value="gaea_report_data_set_transform")
@Data
public class DataSetTransform extends GaeaBaseEntity {
@ApiModelProperty(value = "数据集编码")
private String setCode;
@ApiModelProperty(value = "数据转换类型DIC_NAME=TRANSFORM_TYPE; jsjavaBean字典转换")
private String transformType;
@ApiModelProperty(value = "数据转换script,处理逻辑")
private String transformScript;
@ApiModelProperty(value = "排序,执行数据转换顺序")
private Integer orderNum;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag;
}

@ -0,0 +1,21 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.param.DataSetTransformParam;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
import java.util.List;
/**
* @desc DataSetTransform
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
public interface DataSetTransformService extends GaeaBaseService<DataSetTransformParam, DataSetTransform> {
List<JSONObject> transform(List<DataSetTransformDto> dataSetTransformDtoList, List<JSONObject> data);
}

@ -0,0 +1,25 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import java.util.List;
/**
* Created by raodeming on 2021/3/23.
*/
public interface TransformStrategy {
/**
*
* @return
*/
String type();
/***
*
* @param def
* @param data
* @return
*/
List<JSONObject> transform(DataSetTransformDto def, List<JSONObject> data);
}

@ -0,0 +1,71 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.DataSetTransformMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.DataSetTransformService;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.TransformStrategy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @desc DataSetTransform
* @author Raod
* @date 2021-03-18 12:13:15.591309400
**/
@Service
//@RequiredArgsConstructor
public class DataSetTransformServiceImpl implements DataSetTransformService, InitializingBean, ApplicationContextAware {
private final Map<String, TransformStrategy> queryServiceImplMap = new HashMap<>();
private ApplicationContext applicationContext;
@Autowired
private DataSetTransformMapper dataSetTransformMapper;
@Override
public GaeaBaseMapper<DataSetTransform> getMapper() {
return dataSetTransformMapper;
}
public TransformStrategy getTarget(String type) {
return queryServiceImplMap.get(type);
}
@Override
public void afterPropertiesSet() {
Map<String, TransformStrategy> beanMap = applicationContext.getBeansOfType(TransformStrategy.class);
//遍历该接口的所有实现将其放入map中
for (TransformStrategy serviceImpl : beanMap.values()) {
queryServiceImplMap.put(serviceImpl.type(), serviceImpl);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public List<JSONObject> transform(List<DataSetTransformDto> dataSetTransformDtoList, List<JSONObject> data) {
if (dataSetTransformDtoList == null || dataSetTransformDtoList.size() <= 0) {
return data;
}
for (DataSetTransformDto dataSetTransformDto : dataSetTransformDtoList) {
data = getTarget(dataSetTransformDto.getTransformType()).transform(dataSetTransformDto, data);
}
return data;
}
}

@ -0,0 +1,56 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.TransformStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
/**
*
* Created by raodeming on 2021/3/29.
*/
@Component
@Slf4j
public class DictTransformServiceImpl implements TransformStrategy {
/**
*
*
* @return
*/
@Override
public String type() {
return "dict";
}
/***
*
* @param def
* @param data
* @return
*/
@Override
public List<JSONObject> transform(DataSetTransformDto def, List<JSONObject> data) {
String transformScript = def.getTransformScript();
if (StringUtils.isBlank(transformScript)) {
return data;
}
JSONObject jsonObject = JSONObject.parseObject(transformScript);
Set<String> keys = jsonObject.keySet();
data.forEach(dataDetail -> dataDetail.forEach((key, value) -> {
if (keys.contains(key)) {
String string = jsonObject.getJSONObject(key).getString(value.toString());
if (StringUtils.isNotBlank(string)) {
dataDetail.put(key, string);
}
}
}));
return data;
}
}

@ -0,0 +1,62 @@
package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.TransformStrategy;
import com.anjiplus.template.gaea.common.RespCommonCode;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by raodeming on 2021/3/23.
*/
@Component
@Slf4j
public class JsTransformServiceImpl implements TransformStrategy {
private ScriptEngine engine;
{
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("JavaScript");
}
/**
*
*
* @return
*/
@Override
public String type() {
return "js";
}
/***
*
* @param def
* @param data
* @return
*/
@Override
public List<JSONObject> transform(DataSetTransformDto def, List<JSONObject> data) {
return getValueFromJS(def,data);
}
private List<JSONObject> getValueFromJS(DataSetTransformDto def, List<JSONObject> data) {
String js = def.getTransformScript();
js = js + "\nvar result = dataTransform(eval(" + data.toString() + "));";
try {
engine.eval(js);
ScriptObjectMirror result = (ScriptObjectMirror) engine.get("result");
return result.values().stream().map(o -> JSONObject.parseObject(JSONObject.toJSONString(o))).collect(Collectors.toList());
} catch (Exception ex) {
throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_JS_ERROR, ex.getMessage());
}
}
}

@ -0,0 +1,214 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.config;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* Created by raodeming on 2021/3/24.
*/
@Configuration
@Slf4j
public class HttpClientConfig {
@Autowired
private HttpClientPoolConfig httpClientPoolConfig;
/**
* HTTP
*/
@Bean(name = "clientHttpRequestFactory")
public ClientHttpRequestFactory clientHttpRequestFactory() {
/**
* maxTotalConnection maxConnectionPerRoute
*/
if (httpClientPoolConfig.getMaxTotalConnect() <= 0) {
throw new IllegalArgumentException("invalid maxTotalConnection: " + httpClientPoolConfig.getMaxTotalConnect());
}
if (httpClientPoolConfig.getMaxConnectPerRoute() <= 0) {
throw new IllegalArgumentException("invalid maxConnectionPerRoute: " + httpClientPoolConfig.getMaxConnectPerRoute());
}
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());
// 连接超时
clientHttpRequestFactory.setConnectTimeout(httpClientPoolConfig.getConnectTimeout());
// 数据读取超时时间即SocketTimeout
clientHttpRequestFactory.setReadTimeout(httpClientPoolConfig.getReadTimeout());
// 从连接池获取请求连接的超时时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的
clientHttpRequestFactory.setConnectionRequestTimeout(httpClientPoolConfig.getConnectionRequestTimout());
return clientHttpRequestFactory;
}
/**
* RestTemplate,springBeanspring
*/
@Bean(name = "dataSourceRestTemplate")
public RestTemplate restTemplate(@Qualifier("clientHttpRequestFactory") ClientHttpRequestFactory factory) {
return createRestTemplate(factory);
}
/**
* httpClient
*
* @return
*/
@Bean
public HttpClient httpClient() {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
try {
//设置信任ssl访问
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (arg0, arg1) -> true).build();
httpClientBuilder.setSSLContext(sslContext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
// 注册http和https请求
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory).build();
//使用Httpclient连接池的方式配置(推荐)同时支持nettyokHttp以及其他http框架
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
// 最大连接数
poolingHttpClientConnectionManager.setMaxTotal(httpClientPoolConfig.getMaxTotalConnect());
// 同路由并发数
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(httpClientPoolConfig.getMaxConnectPerRoute());
//配置连接池
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
// 重试次数
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(httpClientPoolConfig.getRetryTimes(), true));
//设置默认请求头
List<Header> headers = getDefaultHeaders();
httpClientBuilder.setDefaultHeaders(headers);
//设置长连接保持策略
httpClientBuilder.setKeepAliveStrategy(connectionKeepAliveStrategy());
return httpClientBuilder.build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
log.error("初始化HTTP连接池出错", e);
}
return null;
}
/**
*
*
* @return
*/
public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
return (response, context) -> {
// Honor 'keep-alive' header
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
log.info("HeaderElement:{}", JSON.toJSONString(he));
String param = he.getName();
String value = he.getValue();
if (value != null && "timeout".equalsIgnoreCase(param)) {
try {
return Long.parseLong(value) * 1000;
} catch (NumberFormatException ignore) {
log.error("解析长连接过期时间异常", ignore);
}
}
}
HttpHost target = (HttpHost) context.getAttribute(
HttpClientContext.HTTP_TARGET_HOST);
//如果请求目标地址,单独配置了长连接保持时间,使用该配置
Optional<Map.Entry<String, Integer>> any = Optional.ofNullable(httpClientPoolConfig.getKeepAliveTargetHost()).orElseGet(HashMap::new)
.entrySet().stream().filter(
e -> e.getKey().equalsIgnoreCase(target.getHostName())).findAny();
//否则使用默认长连接保持时间
return any.map(en -> en.getValue() * 1000L).orElse(httpClientPoolConfig.getKeepAliveTime() * 1000L);
};
}
/**
*
*
* @return
*/
private List<Header> getDefaultHeaders() {
List<Header> headers = new ArrayList<>();
headers.add(new BasicHeader("User-Agent",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"));
headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN"));
headers.add(new BasicHeader("Connection", "Keep-Alive"));
return headers;
}
private RestTemplate createRestTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
//我们采用RestTemplate内部的MessageConverter
//重新设置StringHttpMessageConverter字符集解决中文乱码问题
modifyDefaultCharset(restTemplate);
//设置错误处理器
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
return restTemplate;
}
/**
* utf-8
*
* @param restTemplate
*/
private void modifyDefaultCharset(RestTemplate restTemplate) {
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
HttpMessageConverter<?> converterTarget = null;
for (HttpMessageConverter<?> item : converterList) {
if (StringHttpMessageConverter.class == item.getClass()) {
converterTarget = item;
break;
}
}
if (null != converterTarget) {
converterList.remove(converterTarget);
}
Charset defaultCharset = Charset.forName(httpClientPoolConfig.getCharset());
converterList.add(1, new StringHttpMessageConverter(defaultCharset));
}
}

@ -0,0 +1,53 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* Created by raodeming on 2021/3/24.
*/
@Component
@ConfigurationProperties(prefix = "spring.http-client.pool")
@Data
public class HttpClientPoolConfig {
/**
* javaymlymljava
*/
/**
*
*/
private int maxTotalConnect = 1000;
/**
*
*/
private int maxConnectPerRoute = 200;
/**
* 2s
*/
private int connectTimeout = 2 * 1000;
/**
* ,30s
*/
private int readTimeout = 30 * 1000;
private String charset = "UTF-8";
/**
* ,2
*/
private int retryTimes = 2;
/**
* ,,ms
*/
private int connectionRequestTimout = 200;
/**
* ,
*/
private Map<String,Integer> keepAliveTargetHost;
/**
* ,, s
*/
private int keepAliveTime = 60;
}

@ -0,0 +1,67 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.controller;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.DataSourceParam;
import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.service.DataSourceService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @desc controller
* @website https://gitee.com/anji-plus/gaea
* @author Raod
* @date 2021-03-18 12:09:57.728203200
**/
@RestController
@Api(tags = "数据源管理")
@RequestMapping("/dataSource")
public class DataSourceController extends GaeaBaseController<DataSourceParam, DataSource, DataSourceDto> {
@Autowired
private DataSourceService dataSourceService;
@Override
public GaeaBaseService<DataSourceParam, DataSource> getService() {
return dataSourceService;
}
@Override
public DataSource getEntity() {
return new DataSource();
}
@Override
public DataSourceDto getDTO() {
return new DataSourceDto();
}
/**
*
* @return
*/
@GetMapping("/queryAllDataSource")
public ResponseBean queryAllDataSource() {
return responseSuccessWithData(dataSourceService.queryAllDataSource());
}
/**
*
* @param connectionParam
* @return
*/
@PostMapping("/testConnection")
public ResponseBean testConnection(@Validated @RequestBody ConnectionParam connectionParam) {
return responseSuccessWithData(dataSourceService.testConnection(connectionParam));
}
}

@ -0,0 +1,74 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
*
* @description dto
* @author Raod
* @date 2021-03-18 12:09:57.728203200
**/
@Data
public class DataSourceDto extends GaeaBaseDTO implements Serializable {
/** 数据源编码 */
private String sourceCode;
/** 数据源名称 */
private String sourceName;
/** 数据源描述 */
private String sourceDesc;
/** 数据源类型 DIC_NAME=SOURCE_TYPE; mysqloracesqlserverelasticsearch接口javaBean数据源类型字典中item-extend动态生成表单 */
private String sourceType;
/** 数据源连接配置json关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{"query":"select 1"}' } 接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' } */
private String sourceConfig;
/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
private Integer enableFlag;
/** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
private Integer deleteFlag;
/**************************************************************/
/**关系型数据库jdbcUrl */
private String jdbcUrl;
/** 关系型数据库用户名 */
private String username;
/** 关系型数据库密码 */
private String password;
/** 关系型数据库驱动类 */
private String driverName;
/** 关系型数据库sql */
private String sql;
/** http requestUrl */
private String apiUrl;
/** http method */
private String method;
/** http header */
private String header;
/** http 请求体 */
private String body;
/** 动态查询sql或者接口中的请求体 */
private String dynSentence;
/** 传入的自定义参数解决url中存在的动态参数*/
private Map<String, Object> contextData;
}

@ -0,0 +1,21 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* Created by raodeming on 2021/3/19.
*/
@Data
public class ConnectionParam implements Serializable {
/** 数据源类型 DIC_NAME=SOURCE_TYPE; mysqloracesqlserverelasticsearch接口javaBean数据源类型字典中item-extend动态生成表单 */
@NotBlank(message = "sourceType not empty")
private String sourceType;
/** 数据源连接配置json关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{"query":"select 1"}' } 接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' } */
@NotBlank(message = "sourceConfig not empty")
private String sourceConfig;
}

@ -0,0 +1,31 @@
/**/
package com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
/**
* @desc DataSource
* @author Raod
* @date 2021-03-18 12:09:57.728203200
**/
@Data
public class DataSourceParam extends PageParam implements Serializable{
/** 数据源名称 */
@Query(QueryEnum.LIKE)
private String sourceName;
/** 数据源编码 */
@Query(QueryEnum.LIKE)
private String sourceCode;
/** 数据源类型 DIC_NAME=SOURCE_TYPE; mysqloracesqlserverelasticsearch接口javaBean数据源类型字典中item-extend动态生成表单 */
@Query(QueryEnum.EQ)
private String sourceType;
}

@ -0,0 +1,16 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.dao;
import org.apache.ibatis.annotations.Mapper;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
/**
* DataSource Mapper
* @author Raod
* @date 2021-03-18 12:09:57.728203200
**/
@Mapper
public interface DataSourceMapper extends GaeaBaseMapper<DataSource> {
}

@ -0,0 +1,42 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity;
import com.anji.plus.gaea.annotation.Unique;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.anjiplus.template.gaea.common.RespCommonCode;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description entity
* @author Raod
* @date 2021-03-18 12:09:57.728203200
**/
@TableName(value="gaea_report_data_source")
@Data
public class DataSource extends GaeaBaseEntity {
@ApiModelProperty(value = "数据源编码")
@Unique(code = RespCommonCode.SOURCE_CODE_ISEXIST)
private String sourceCode;
@ApiModelProperty(value = "数据源名称")
private String sourceName;
@ApiModelProperty(value = "数据源描述")
private String sourceDesc;
@ApiModelProperty(value = "数据源类型 DIC_NAME=SOURCE_TYPE; mysqloracesqlserverelasticsearch接口javaBean数据源类型字典中item-extend动态生成表单")
private String sourceType;
@ApiModelProperty(value = "数据源连接配置json关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{\"query\":\"select 1\"}' } 接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' }")
private String sourceConfig;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag;
}

@ -0,0 +1,39 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
/**
*
* @author binbin.hou
* @since 1.0.0
*/
public interface IConfig {
/**
*
*
* @param driverClass
* @since 1.0.0
*/
void setDriverClass(final String driverClass);
/**
* jdbc url
* @param jdbcUrl url
* @since 1.0.0
*/
void setJdbcUrl(final String jdbcUrl);
/**
*
* @param user
* @since 1.0.0
*/
void setUser(final String user);
/**
*
* @param password
* @since 1.0.0
*/
void setPassword(final String password);
}

@ -0,0 +1,13 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
import javax.sql.DataSource;
/**
*
* @author binbin.hou
* @since 1.0.0
*/
public interface IDataSourceConfig extends IConfig, DataSource {
}

@ -0,0 +1,21 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
/**
*
* @since 1.1.0
*/
public interface ILifeCycle {
/**
*
* @since 1.1.0
*/
void init();
/**
*
* @since 1.1.0
*/
void destroy();
}

@ -0,0 +1,93 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection.IPooledConnection;
/**
*
* @author binbin.hou
* @since 1.0.0
*/
public interface IPooledDataSourceConfig extends IDataSourceConfig {
/**
*
* @param pooledConnection
* @since 1.5.0
*/
void returnConnection(IPooledConnection pooledConnection);
/**
*
*
* @param minSize
* @since 1.1.0
*/
void setMinSize(final int minSize);
/**
*
*
* @param maxSize
* @since 1.1.0
*/
void setMaxSize(final int maxSize);
/**
*
* @param maxWaitMills
* @since 1.1.0
*/
void setMaxWaitMills(final long maxWaitMills);
/**
*
*
* {@link #setTestOnBorrow(boolean)}
* {@link #setTestOnIdle(boolean)}}
* {@link #setTestOnReturn(boolean)}
*
* @param validQuery
* @since 1.5.0
*/
void setValidQuery(final String validQuery);
/**
*
* @param validTimeOutSeconds
* @since 1.5.0
*/
void setValidTimeOutSeconds(final int validTimeOutSeconds);
/**
*
*
*
* @param testOnBorrow
* @since 1.5.0
*/
void setTestOnBorrow(final boolean testOnBorrow);
/**
*
*
*
* @param testOnReturn
* @since 1.5.0
*/
void setTestOnReturn(final boolean testOnReturn);
/**
*
* @param testOnIdle
* @since 1.5.0
*/
void setTestOnIdle(final boolean testOnIdle);
/**
*
* @param testOnIdleIntervalSeconds
* @since 1.5.0
*/
void setTestOnIdleIntervalSeconds(final long testOnIdleIntervalSeconds);
}

@ -0,0 +1,56 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IPooledDataSourceConfig;
import java.sql.Connection;
/**
*
* @since 1.1.0
*/
public interface IPooledConnection extends Connection {
/**
*
* @since 1.1.0
* @return
*/
boolean isBusy();
/**
*
* @param busy
* @since 1.1.0
*/
void setBusy(boolean busy);
/**
*
* @return
* @since 1.1.0
*/
Connection getConnection();
/**
*
* @param connection
* @since 1.1.0
*/
void setConnection(Connection connection);
/**
*
* @param dataSource
* @since 1.5.0
*/
void setDataSource(final IPooledDataSourceConfig dataSource);
/**
*
* @return
* @since 1.5.0
*/
IPooledDataSourceConfig getDataSource();
}

@ -0,0 +1,457 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IPooledDataSourceConfig;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.exception.JdbcPoolException;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
/**
*
*
* @since 1.1.0
*/
@Slf4j
public class PooledConnection implements IPooledConnection {
/**
*
* @since 1.1.0
*/
private volatile boolean isBusy;
/**
*
* @since 1.1.0
*/
private Connection connection;
/**
*
*
* @since 1.1.0
*/
private IPooledDataSourceConfig dataSource;
@Override
public Statement createStatement() throws SQLException {
checkStatus();
return connection.createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
checkStatus();
return connection.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
checkStatus();
return connection.prepareCall(sql);
}
@Override
public String nativeSQL(String sql) throws SQLException {
checkStatus();
return connection.nativeSQL(sql);
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
checkStatus();
connection.setAutoCommit(autoCommit);
}
@Override
public boolean getAutoCommit() throws SQLException {
checkStatus();
return connection.getAutoCommit();
}
@Override
public void commit() throws SQLException {
checkStatus();
connection.commit();
}
@Override
public void rollback() throws SQLException {
checkStatus();
connection.rollback();
}
@Override
public void close() throws SQLException {
checkStatus();
this.dataSource.returnConnection(this);
}
@Override
public boolean isClosed() throws SQLException {
checkStatus();
return connection.isClosed();
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
checkStatus();
return connection.getMetaData();
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
checkStatus();
connection.setReadOnly(readOnly);
}
@Override
public boolean isReadOnly() throws SQLException {
checkStatus();
return connection.isReadOnly();
}
@Override
public void setCatalog(String catalog) throws SQLException {
checkStatus();
connection.setCatalog(catalog);
}
@Override
public String getCatalog() throws SQLException {
checkStatus();
return connection.getCatalog();
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
checkStatus();
connection.setTransactionIsolation(level);
}
@Override
public int getTransactionIsolation() throws SQLException {
checkStatus();
return connection.getTransactionIsolation();
}
@Override
public SQLWarning getWarnings() throws SQLException {
checkStatus();
return connection.getWarnings();
}
@Override
public void clearWarnings() throws SQLException {
checkStatus();
connection.clearWarnings();
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
checkStatus();
return connection.createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
checkStatus();
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
checkStatus();
return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
checkStatus();
return connection.getTypeMap();
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
checkStatus();
connection.setTypeMap(map);
}
@Override
public void setHoldability(int holdability) throws SQLException {
checkStatus();
connection.setHoldability(holdability);
}
@Override
public int getHoldability() throws SQLException {
checkStatus();
return connection.getHoldability();
}
@Override
public Savepoint setSavepoint() throws SQLException {
checkStatus();
return connection.setSavepoint();
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
checkStatus();
return connection.setSavepoint(name);
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
checkStatus();
connection.rollback(savepoint);
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
checkStatus();
connection.releaseSavepoint(savepoint);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
checkStatus();
return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
checkStatus();
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
checkStatus();
return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
checkStatus();
return connection.prepareStatement(sql, autoGeneratedKeys);
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
checkStatus();
return connection.prepareStatement(sql, columnIndexes);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
checkStatus();
return connection.prepareStatement(sql, columnNames);
}
@Override
public Clob createClob() throws SQLException {
checkStatus();
return connection.createClob();
}
@Override
public Blob createBlob() throws SQLException {
checkStatus();
return connection.createBlob();
}
@Override
public NClob createNClob() throws SQLException {
checkStatus();
return connection.createNClob();
}
@Override
public SQLXML createSQLXML() throws SQLException {
checkStatus();
return connection.createSQLXML();
}
@Override
public boolean isValid(int timeout) throws SQLException {
checkStatus();
return connection.isValid(timeout);
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
checkStatus();
connection.setClientInfo(name, value);
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
checkStatus();
connection.setClientInfo(properties);
}
@Override
public String getClientInfo(String name) throws SQLException {
checkStatus();
return connection.getClientInfo(name);
}
@Override
public Properties getClientInfo() throws SQLException {
checkStatus();
return connection.getClientInfo();
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
checkStatus();
return connection.createArrayOf(typeName, elements);
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
checkStatus();
return connection.createStruct(typeName, attributes);
}
@Override
public void setSchema(String schema) throws SQLException {
checkStatus();
connection.setSchema(schema);
}
@Override
public String getSchema() throws SQLException {
checkStatus();
return connection.getSchema();
}
@Override
public void abort(Executor executor) throws SQLException {
checkStatus();
connection.abort(executor);
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
checkStatus();
connection.setNetworkTimeout(executor, milliseconds);
}
@Override
public int getNetworkTimeout() throws SQLException {
checkStatus();
return connection.getNetworkTimeout();
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
checkStatus();
return connection.unwrap(iface);
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
checkStatus();
return connection.isWrapperFor(iface);
}
@Override
public boolean isBusy() {
return isBusy;
}
@Override
public void setBusy(boolean busy) {
isBusy = busy;
}
@Override
public Connection getConnection() {
return connection;
}
@Override
public void setConnection(Connection connection) {
this.connection = connection;
}
@Override
public IPooledDataSourceConfig getDataSource() {
return dataSource;
}
@Override
public void setDataSource(IPooledDataSourceConfig dataSource) {
this.dataSource = dataSource;
}
/**
*
* @since 1.4.0
*/
private void checkStatus() {
if(!isBusy) {
throw new JdbcPoolException("Connection has been closed");
}
}
}

@ -0,0 +1,71 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant;
/**
* Created by raodeming on 2021/3/19.
*/
public class JdbcConstants {
public final static String JTDS = "jtds";
public final static String MOCK = "mock";
public final static String HSQL = "hsql";
public final static String DB2 = "db2";
public final static String DB2_DRIVER = "COM.ibm.db2.jdbc.app.DB2Driver";
public final static String POSTGRESQL = "postgresql";
public final static String POSTGRESQL_DRIVER = "org.postgresql.Driver";
public final static String SYBASE = "sybase";
public final static String SQL_SERVER = "sqlserver";
public final static String SQL_SERVER_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
public final static String SQL_SERVER_DRIVER_SQLJDBC4 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
public final static String SQL_SERVER_DRIVER_JTDS = "net.sourceforge.jtds.jdbc.Driver";
public final static String ORACLE = "oracle";
public final static String ORACLE_DRIVER = "oracle.jdbc.OracleDriver";
public final static String ORACLE_DRIVER2 = "oracle.jdbc.driver.OracleDriver";
public final static String ALI_ORACLE = "AliOracle";
public final static String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver";
public final static String MYSQL = "mysql";
public final static String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
public final static String MYSQL_DRIVER_6 = "com.mysql.cj.jdbc.Driver";
public final static String MYSQL_DRIVER_REPLICATE = "com.mysql.jdbc.";
public final static String MARIADB = "mariadb";
public final static String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
public final static String DERBY = "derby";
public final static String HBASE = "hbase";
public final static String HIVE = "hive";
public final static String HIVE_DRIVER = "org.apache.hive.jdbc.HiveDriver";
public final static String H2 = "h2";
public final static String H2_DRIVER = "org.h2.Driver";
public final static String DM = "dm";
public final static String DM_DRIVER = "dm.jdbc.driver.DmDriver";
public final static String KINGBASE = "kingbase";
public final static String KINGBASE_DRIVER = "com.kingbase.Driver";
public final static String GBASE = "gbase";
public final static String GBASE_DRIVER = "com.gbase.jdbc.Driver";
public final static String XUGU = "xugu";
public final static String XUGU_DRIVER = "com.xugu.cloudjdbc.Driver";
public final static String OCEANBASE = "oceanbase";
public final static String OCEANBASE_DRIVER = "com.mysql.jdbc.Driver";
public final static String INFORMIX = "informix";
public final static String ODPS = "odps";
public final static String ODPS_DRIVER = "com.aliyun.odps.jdbc.OdpsDriver";
public final static String TERADATA = "teradata";
public final static String TERADATA_DRIVER = "com.teradata.jdbc.TeraDriver";
public final static String LOG4JDBC = "log4jdbc";
public final static String LOG4JDBC_DRIVER = "net.sf.log4jdbc.DriverSpy";
public final static String PHOENIX = "phoenix";
public final static String PHOENIX_DRIVER = "org.apache.phoenix.jdbc.PhoenixDriver";
public final static String ENTERPRISEDB = "edb";
public final static String ENTERPRISEDB_DRIVER = "com.edb.Driver";
public final static String KYLIN = "kylin";
public final static String KYLIN_DRIVER = "org.apache.kylin.jdbc.Driver";
public final static String SQLITE = "sqlite";
public final static String SQLITE_DRIVER = "org.sqlite.JDBC";
public final static String ALIYUN_ADS = "aliyun_ads";
public final static String ALIYUN_DRDS = "aliyun_drds";
public final static String PRESTO = "presto";
public final static String ELASTIC_SEARCH = "elasticsearch";
public final static String ELASTIC_SEARCH_SQL = "elasticsearch_sql";
public final static String ELASTIC_SEARCH_DRIVER = "com.alibaba.xdriver.elastic.jdbc.ElasticDriver";
public final static String CLICKHOUSE = "clickhouse";
public final static String CLICKHOUSE_DRIVER = "ru.yandex.clickhouse.ClickHouseDriver";
public final static String KUDU_IMAPLA = "kudu_impala";
public final static String HTTP = "http";
}

@ -0,0 +1,71 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant;
/**
* 线
* @since 1.1.0
*/
public final class PooledConst {
private PooledConst(){}
/**
*
* @since 1.1.0
*/
public static final int DEFAULT_MIN_SIZE = 10;
/**
*
* @since 1.1.0
*/
public static final int DEFAULT_MAX_SIZE = 300;
/**
*
*
* 1 min
*
* @since 1.3.0
*/
public static final int DEFAULT_MAX_WAIT_MILLS = 60 * 1000;
/**
*
* @since 1.5.0
*/
public static final String DEFAULT_VALID_QUERY = "select 1 from dual";
/**
*
* @since 1.5.0
*/
public static final int DEFAULT_VALID_TIME_OUT_SECONDS = 5;
/**
*
* @since 1.5.0
*/
public static final boolean DEFAULT_TEST_ON_BORROW = false;
/**
*
* @since 1.5.0
*/
public static final boolean DEFAULT_TEST_ON_RETURN = false;
/**
*
*
* @since 1.5.0
*/
public static final boolean DEFAULT_TEST_ON_IDLE = true;
/**
* 1min
*
* @since 1.5.0
*/
public static final long DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS = 60;
}

@ -0,0 +1,68 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class AbstractDataSourceConfig extends DataSourceConfigAdaptor {
/**
*
* @since 1.0.0
*/
protected String driverClass;
/**
* jdbc url
* @since 1.0.0
*/
protected String jdbcUrl;
/**
*
* @since 1.0.0
*/
protected String user;
/**
*
* @since 1.0.0
*/
protected String password;
public String getDriverClass() {
return driverClass;
}
@Override
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
public String getJdbcUrl() {
return jdbcUrl;
}
@Override
public void setJdbcUrl(String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
public String getUser() {
return user;
}
@Override
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
@Override
public void setPassword(String password) {
this.password = password;
}
}

@ -0,0 +1,159 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.ILifeCycle;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IPooledDataSourceConfig;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant.PooledConst;
/**
* @author binbin.hou
* @since 1.1.0
*/
public abstract class AbstractPooledDataSourceConfig extends AbstractDataSourceConfig
implements IPooledDataSourceConfig, ILifeCycle {
/**
*
* @since 1.1.0
*/
protected int minSize = PooledConst.DEFAULT_MIN_SIZE;
/**
*
* @since 1.1.0
*/
protected int maxSize = PooledConst.DEFAULT_MAX_SIZE;
/**
*
* @since 1.3.0
*/
protected long maxWaitMills = PooledConst.DEFAULT_MAX_WAIT_MILLS;
/**
*
* @since 1.5.0
*/
protected String validQuery = PooledConst.DEFAULT_VALID_QUERY;
/**
*
* @since 1.5.0
*/
protected int validTimeOutSeconds = PooledConst.DEFAULT_VALID_TIME_OUT_SECONDS;
/**
*
* @since 1.5.0
*/
protected boolean testOnBorrow = PooledConst.DEFAULT_TEST_ON_BORROW;
/**
*
* @since 1.5.0
*/
protected boolean testOnReturn = PooledConst.DEFAULT_TEST_ON_RETURN;
/**
*
* @since 1.5.0
*/
protected boolean testOnIdle = PooledConst.DEFAULT_TEST_ON_IDLE;
/**
*
* @since 1.5.0
*/
protected long testOnIdleIntervalSeconds = PooledConst.DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS;
public int getMinSize() {
return minSize;
}
@Override
public void setMinSize(int minSize) {
this.minSize = minSize;
}
public int getMaxSize() {
return maxSize;
}
@Override
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
public long getMaxWaitMills() {
return maxWaitMills;
}
@Override
public void setMaxWaitMills(long maxWaitMills) {
this.maxWaitMills = maxWaitMills;
}
public String getValidQuery() {
return validQuery;
}
@Override
public void setValidQuery(String validQuery) {
this.validQuery = validQuery;
}
public int getValidTimeOutSeconds() {
return validTimeOutSeconds;
}
@Override
public void setValidTimeOutSeconds(int validTimeOutSeconds) {
this.validTimeOutSeconds = validTimeOutSeconds;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
@Override
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
@Override
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestOnIdle() {
return testOnIdle;
}
@Override
public void setTestOnIdle(boolean testOnIdle) {
this.testOnIdle = testOnIdle;
}
public long getTestOnIdleIntervalSeconds() {
return testOnIdleIntervalSeconds;
}
@Override
public void setTestOnIdleIntervalSeconds(long testOnIdleIntervalSeconds) {
this.testOnIdleIntervalSeconds = testOnIdleIntervalSeconds;
}
@Override
public void init() {
}
@Override
public void destroy() {
}
}

@ -0,0 +1,82 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IDataSourceConfig;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class DataSourceConfigAdaptor implements IDataSourceConfig {
@Override
public Connection getConnection() throws SQLException {
return null;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public void setDriverClass(String driverClass) {
}
@Override
public void setJdbcUrl(String jdbcUrl) {
}
@Override
public void setUser(String user) {
}
@Override
public void setPassword(String password) {
}
}

@ -0,0 +1,240 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection.IPooledConnection;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection.PooledConnection;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.exception.JdbcPoolException;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util.DriverClassUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author binbin.hou
* @since 1.1.0
*/
@Slf4j
public class PooledDataSource extends AbstractPooledDataSourceConfig {
/**
*
*
* @since 1.1.0
*/
private List<IPooledConnection> pool = new ArrayList<>();
@Override
public synchronized void init() {
DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl);
this.initJdbcPool();
// 初始化 idle check
this.initTestOnIdle();
}
@Override
public synchronized Connection getConnection() throws SQLException {
//1. 获取第一个不是 busy 的连接
Optional<IPooledConnection> connectionOptional = getFreeConnectionFromPool();
if (connectionOptional.isPresent()) {
return connectionOptional.get();
}
//2. 考虑是否可以扩容
if (pool.size() >= maxSize) {
//2.1 立刻返回
if (maxWaitMills <= 0) {
throw new JdbcPoolException("Can't get connection from pool!");
}
//2.2 循环等待
final long startWaitMills = System.currentTimeMillis();
final long endWaitMills = startWaitMills + maxWaitMills;
while (System.currentTimeMillis() < endWaitMills) {
Optional<IPooledConnection> optional = getFreeConnectionFromPool();
if (optional.isPresent()) {
return optional.get();
}
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
log.debug("等待连接池归还wait for 1 mills");
}
//2.3 等待超时
throw new JdbcPoolException("Can't get connection from pool, wait time out for mills: " + maxWaitMills);
}
//3. 扩容(暂时只扩容一个)
log.debug("开始扩容连接池大小step: 1");
IPooledConnection pooledConnection = createPooledConnection();
pooledConnection.setBusy(true);
this.pool.add(pooledConnection);
log.debug("从扩容后的连接池中获取连接");
return pooledConnection;
}
@Override
public void returnConnection(IPooledConnection pooledConnection) {
// 验证状态
if (testOnReturn) {
checkValid(pooledConnection);
}
// 设置为不繁忙
pooledConnection.setBusy(false);
log.debug("归还连接,状态设置为不繁忙");
}
/**
*
*
* @return
* @since 1.3.0
*/
private Optional<IPooledConnection> getFreeConnectionFromPool() {
for (IPooledConnection pc : pool) {
if (!pc.isBusy()) {
pc.setBusy(true);
log.debug("从连接池中获取连接");
// 验证有效性
if (testOnBorrow) {
log.debug("Test on borrow start");
checkValid(pc);
log.debug("Test on borrow finish");
}
return Optional.of(pc);
}
}
// 空
return Optional.empty();
}
/**
* https://stackoverflow.com/questions/3668506/efficient-sql-test-query-or-validation-query-that-will-work-across-all-or-most
* <p>
* 使 {@link Connection#isValid(int)}
*
* @param pooledConnection
* @since 1.5.0
*/
private void checkValid(final IPooledConnection pooledConnection) {
if (StringUtils.isNotEmpty(super.validQuery)) {
Connection connection = pooledConnection.getConnection();
try {
// 如果连接无效,重新申请一个新的替代
if (!connection.isValid(super.validTimeOutSeconds)) {
log.debug("Old connection is inValid, start create one for it.");
Connection newConnection = createConnection();
pooledConnection.setConnection(newConnection);
log.debug("Old connection is inValid, finish create one for it.");
}
} catch (SQLException throwables) {
throw new JdbcPoolException(throwables);
}
} else {
log.debug("valid query is empty, ignore valid.");
}
}
/**
*
*
* @since 1.1.0
*/
private void initJdbcPool() {
final int minSize = super.minSize;
pool = new ArrayList<>(minSize);
for (int i = 0; i < minSize; i++) {
IPooledConnection pooledConnection = createPooledConnection();
pool.add(pooledConnection);
}
}
/**
*
*
* @return
* @since 1.1.0
*/
private IPooledConnection createPooledConnection() {
Connection connection = createConnection();
IPooledConnection pooledConnection = new PooledConnection();
pooledConnection.setBusy(false);
pooledConnection.setConnection(connection);
pooledConnection.setDataSource(this);
return pooledConnection;
}
/**
*
*
* @return
* @since 1.1.0
*/
private Connection createConnection() {
try {
if (StringUtils.isBlank(super.getUser()) && StringUtils.isBlank(super.getPassword())) {
return DriverManager.getConnection(super.getJdbcUrl());
}
return DriverManager.getConnection(super.getJdbcUrl(),
super.getUser(), super.getPassword());
} catch (SQLException e) {
throw new JdbcPoolException(e);
}
}
/**
*
*
* @since 1.5.0
*/
private void initTestOnIdle() {
if (StringUtils.isNotEmpty(validQuery)) {
ScheduledExecutorService idleExecutor = Executors.newSingleThreadScheduledExecutor();
idleExecutor.scheduleAtFixedRate(this::testOnIdleCheck, super.testOnIdleIntervalSeconds, testOnIdleIntervalSeconds, TimeUnit.SECONDS);
log.debug("Test on idle config with interval seonds: " + testOnIdleIntervalSeconds);
}
}
/**
*
*
* @since 1.5.0
*/
private void testOnIdleCheck() {
log.debug("start check test on idle");
for (IPooledConnection pc : this.pool) {
if (!pc.isBusy()) {
checkValid(pc);
}
}
log.debug("finish check test on idle");
}
}

@ -0,0 +1,26 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util.DriverClassUtil;
import org.apache.commons.lang3.StringUtils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class UnPooledDataSource extends AbstractDataSourceConfig {
@Override
public Connection getConnection() throws SQLException {
DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl);
if (StringUtils.isBlank(super.getUser()) && StringUtils.isBlank(super.getPassword())) {
return DriverManager.getConnection(super.jdbcUrl);
}
return DriverManager.getConnection(super.getJdbcUrl(),
super.getUser(), super.getPassword());
}
}

@ -0,0 +1,28 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.exception;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class JdbcPoolException extends RuntimeException {
public JdbcPoolException() {
}
public JdbcPoolException(String message) {
super(message);
}
public JdbcPoolException(String message, Throwable cause) {
super(message, cause);
}
public JdbcPoolException(Throwable cause) {
super(cause);
}
public JdbcPoolException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -0,0 +1,13 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util;
/**
* Created by raodeming on 2021/3/19.
*/
public class DataSourceHandleUtil {
public static void mysqlConnection() {
}
}

@ -0,0 +1,89 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anjiplus.template.gaea.common.RespCommonCode;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* Created by raodeming on 2021/4/19.
*/
public final class DriverClassUtil {
/**
*
*/
private static final Map<String, String> DRIVER_CLASS_MAP;
static {
DRIVER_CLASS_MAP = new HashMap<>(32);
DRIVER_CLASS_MAP.put("jdbc:db2", "COM.ibm.db2.jdbc.app.DB2Driver");
DRIVER_CLASS_MAP.put("jdbc:firebirdsql", "org.firebirdsql.jdbc.FBDriver");
DRIVER_CLASS_MAP.put("jdbc:edbc", "ca.edbc.jdbc.EdbcDriver");
DRIVER_CLASS_MAP.put("jdbc:pointbase", "com.pointbase.jdbc.jdbcUniversalDriver");
DRIVER_CLASS_MAP.put("jdbc:fake", "com.alibaba.druid.mock.MockDriver");
DRIVER_CLASS_MAP.put("jdbc:informix-sqli", "com.informix.jdbc.IfxDriver");
DRIVER_CLASS_MAP.put("jdbc:sqlite", "org.sqlite.JDBC");
DRIVER_CLASS_MAP.put("jdbc:microsoft", "com.microsoft.jdbc.sqlserver.SQLServerDriver");
DRIVER_CLASS_MAP.put("jdbc:hsqldb", "org.hsqldb.jdbcDriver");
DRIVER_CLASS_MAP.put("jdbc:postgresql", "org.postgresql.Driver");
DRIVER_CLASS_MAP.put("jdbc:ingres", "com.ingres.jdbc.IngresDriver");
DRIVER_CLASS_MAP.put("jdbc:cloudscape", "COM.cloudscape.core.JDBCDriver");
DRIVER_CLASS_MAP.put("jdbc:JSQLConnect", "com.jnetdirect.jsql.JSQLDriver");
DRIVER_CLASS_MAP.put("jdbc:derby", "org.apache.derby.jdbc.EmbeddedDriver");
DRIVER_CLASS_MAP.put("jdbc:timesten", "com.timesten.jdbc.TimesTenDriver");
DRIVER_CLASS_MAP.put("jdbc:interbase", "interbase.interclient.Driver");
DRIVER_CLASS_MAP.put("jdbc:h2", "org.h2.Driver");
DRIVER_CLASS_MAP.put("jdbc:as400", "com.ibm.as400.access.AS400JDBCDriver");
DRIVER_CLASS_MAP.put("jdbc:sybase:Tds", "com.sybase.jdbc2.jdbc.SybDriver");
DRIVER_CLASS_MAP.put("jdbc:mock", "com.alibaba.druid.mock.MockDriver");
DRIVER_CLASS_MAP.put("jdbc:oracle", "oracle.jdbc.driver.OracleDriver");
DRIVER_CLASS_MAP.put("jdbc:mysql", "com.mysql.jdbc.Driver");
DRIVER_CLASS_MAP.put("jdbc:odps", "com.aliyun.odps.jdbc.OdpsDriver");
DRIVER_CLASS_MAP.put("jdbc:mckoi", "com.mckoi.JDBCDriver");
DRIVER_CLASS_MAP.put("jdbc:jtds", "net.sourceforge.jtds.jdbc.Driver");
DRIVER_CLASS_MAP.put("jdbc:sapdb", "com.sap.dbtech.jdbc.DriverSapDB");
DRIVER_CLASS_MAP.put("jdbc:JTurbo", "com.newatlanta.jturbo.driver.Driver");
DRIVER_CLASS_MAP.put("jdbc:mimer:multi1", "com.mimer.jdbc.Driver");
}
/**
*
* @param driverClass
* @param url
*/
public static void loadDriverClass(String driverClass, final String url) {
if(StringUtils.isEmpty(driverClass)) {
driverClass = getDriverClassByUrl(url);
}
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
throw BusinessExceptionBuilder.build(RespCommonCode.CLASS_NOT_FOUND, e.getMessage());
}
}
/**
* URL
*
* 1. url
* 2.
* @param url url
* @return
*/
private static String getDriverClassByUrl(final String url) {
for(Map.Entry<String, String> entry : DRIVER_CLASS_MAP.entrySet()) {
String urlPrefix = entry.getKey();
if(url.startsWith(urlPrefix)) {
return entry.getValue();
}
}
throw BusinessExceptionBuilder.build(RespCommonCode.CLASS_NOT_FOUND, "Can't auto find match driver class for url: " + url);
}
}

@ -0,0 +1,100 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource.PooledDataSource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource.UnPooledDataSource;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by raodeming on 2021/3/18.
*/
@Slf4j
public class JdbcUtil {
private static Lock lock = new ReentrantLock();
private static Lock deleteLock = new ReentrantLock();
//所有数据源的连接池存在map里
static Map<Long, PooledDataSource> map = new HashMap<>();
public static PooledDataSource getJdbcConnectionPool(DataSourceDto dataSource) {
if (map.containsKey(dataSource.getId())) {
return map.get(dataSource.getId());
} else {
lock.lock();
try {
log.debug(Thread.currentThread().getName() + "获取锁");
if (!map.containsKey(dataSource.getId())) {
PooledDataSource pool = new PooledDataSource();
pool.setJdbcUrl(dataSource.getJdbcUrl());
pool.setUser(dataSource.getUsername());
pool.setPassword(dataSource.getPassword());
pool.setDriverClass(dataSource.getDriverName());
pool.init();
map.put(dataSource.getId(), pool);
log.info("创建连接池成功:{}", dataSource.getJdbcUrl());
}
return map.get(dataSource.getId());
} finally {
lock.unlock();
}
}
}
/**
*
* @param id
*/
public static void removeJdbcConnectionPool(Long id) {
deleteLock.lock();
try {
PooledDataSource pool = map.get(id);
if (pool != null) {
map.remove(id);
}
} catch (Exception e) {
log.error(e.toString());
} finally {
deleteLock.unlock();
}
}
/**
*
* @param dataSource
* @return
* @throws SQLException
*/
public static Connection getPooledConnection(DataSourceDto dataSource) throws SQLException {
PooledDataSource pool = getJdbcConnectionPool(dataSource);
return pool.getConnection();
}
/**
*
* @param dataSource
* @return
* @throws ClassNotFoundException driverName
* @throws SQLException
*/
public static Connection getUnPooledConnection(DataSourceDto dataSource) throws SQLException {
UnPooledDataSource source = new UnPooledDataSource();
source.setJdbcUrl(dataSource.getJdbcUrl());
source.setDriverClass(dataSource.getDriverName());
source.setUser(dataSource.getUsername());
source.setPassword(dataSource.getPassword());
return source.getConnection();
}
}

@ -0,0 +1,48 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.service;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.DataSourceParam;
import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
import java.util.List;
/**
* @desc DataSource
* @author Raod
* @date 2021-03-18 12:09:57.728203200
**/
public interface DataSourceService extends GaeaBaseService<DataSourceParam, DataSource> {
/**
*
* @return
*/
List<DataSource> queryAllDataSource();
/**
*
* @param connectionParam
* @return
*/
Boolean testConnection(ConnectionParam connectionParam);
/**
* sql
* @param dto
* @return
*/
List<JSONObject> execute(DataSourceDto dto);
/**
* sql,total
* @param dataSourceDto
* @param dto
* @return
*/
long total(DataSourceDto dataSourceDto, DataSetDto dto);
}

@ -0,0 +1,384 @@
package com.anjiplus.template.gaea.business.modules.data.dataSource.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.constant.Enabled;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.gaea.utils.GaeaAssert;
import com.anjiplus.template.gaea.business.code.ResponseCode;
import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.DataSourceMapper;
import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant.JdbcConstants;
import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util.JdbcUtil;
import com.anjiplus.template.gaea.business.modules.data.dataSource.service.DataSourceService;
import com.anjiplus.template.gaea.common.RespCommonCode;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Raod
* @desc DataSource
* @date 2021-03-18 12:09:57.728203200
**/
@Service
@Slf4j
public class DataSourceServiceImpl implements DataSourceService {
@Autowired
private DataSourceMapper dataSourceMapper;
@Resource(name = "dataSourceRestTemplate")
private RestTemplate restTemplate;
@Autowired
private DataSetParamService dataSetParamService;
@Override
public GaeaBaseMapper<DataSource> getMapper() {
return dataSourceMapper;
}
/**
*
* @return
*/
@Override
public List<DataSource> queryAllDataSource() {
LambdaQueryWrapper<DataSource> wrapper = Wrappers.lambdaQuery();
wrapper.select(DataSource::getSourceCode, DataSource::getSourceName)
.eq(DataSource::getEnableFlag, Enabled.YES.getValue());
return dataSourceMapper.selectList(wrapper);
}
/**
*
*
* @param connectionParam
* @return
*/
@Override
public Boolean testConnection(ConnectionParam connectionParam) {
String sourceType = connectionParam.getSourceType();
String sourceConfig = connectionParam.getSourceConfig();
DataSourceDto dto = new DataSourceDto();
dto.setSourceConfig(sourceConfig);
switch (sourceType) {
case JdbcConstants.ELASTIC_SEARCH_SQL:
testElasticsearchSqlConnection(dto);
break;
case JdbcConstants.MYSQL:
case JdbcConstants.KUDU_IMAPLA:
testRelationalDb(dto);
break;
case JdbcConstants.HTTP:
testHttp(dto);
break;
default:
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY);
}
return true;
}
@Override
public List<JSONObject> execute(DataSourceDto dto) {
String sourceType = dto.getSourceType();
switch (sourceType) {
case JdbcConstants.ELASTIC_SEARCH_SQL:
return executeElasticsearchSql(dto);
case JdbcConstants.MYSQL:
case JdbcConstants.KUDU_IMAPLA:
return executeRelationalDb(dto);
case JdbcConstants.HTTP:
return executeHttp(dto);
default:
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY);
}
}
/**
* sql,total
*
* @param dto
* @return
*/
@Override
public long total(DataSourceDto sourceDto, DataSetDto dto) {
//区分数据类型
String sourceType = sourceDto.getSourceType();
switch (sourceType) {
case JdbcConstants.ELASTIC_SEARCH_SQL:
return 0;
case JdbcConstants.MYSQL:
return mysqlTotal(sourceDto, dto);
default:
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY);
}
}
/**
* mysql count limit
* @param sourceDto
* @param dto
* @return
*/
public long mysqlTotal(DataSourceDto sourceDto, DataSetDto dto){
String dynSentence = sourceDto.getDynSentence();
String sql = "select count(1) as count from (" + dynSentence + ") as gaeaExecute";
sourceDto.setDynSentence(sql);
List<JSONObject> result = execute(sourceDto);
//sql 拼接 limit 分页信息
int pageNumber = Integer.parseInt(dto.getContextData().getOrDefault("pageNumber", "1").toString());
int pageSize = Integer.parseInt(dto.getContextData().getOrDefault("pageSize", "10").toString());
String sqlLimit = " limit " + (pageNumber - 1) * pageSize + "," + pageSize;
sourceDto.setDynSentence(dynSentence.concat(sqlLimit));
log.info("当前total{}, 添加分页参数,sql语句{}", JSONObject.toJSONString(result), sourceDto.getDynSentence());
return result.get(0).getLongValue("count");
}
public List<JSONObject> executeElasticsearchSql(DataSourceDto dto) {
analysisHttpConfig(dto);
HttpHeaders headers = new HttpHeaders();
headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
HttpEntity<String> entity = new HttpEntity<>(dto.getDynSentence(), headers);
ResponseEntity<JSONObject> exchange;
try {
exchange = restTemplate.exchange(dto.getApiUrl(), HttpMethod.valueOf(dto.getMethod()), entity, JSONObject.class);
} catch (Exception e) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
}
if (exchange.getStatusCode().isError()) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
}
List<JSONObject> result;
try {
JSONObject body = exchange.getBody();
//解析es sql数据
if (null == body) {
return null;
}
JSONArray columns = body.getJSONArray("columns");
JSONArray rows = body.getJSONArray("rows");
result = new ArrayList<>();
for (int i = 0; i < rows.size(); i++) {
JSONArray row = rows.getJSONArray(i);
JSONObject jsonObject = new JSONObject();
for (int j = 0; j < row.size(); j++) {
String name = columns.getJSONObject(j).getString("name");
String value = row.getString(j);
jsonObject.put(name, value);
}
result.add(jsonObject);
}
} catch (Exception e) {
throw BusinessExceptionBuilder.build(RespCommonCode.ANALYSIS_DATA_ERROR, e.getMessage());
}
return result;
}
public List<JSONObject> executeRelationalDb(DataSourceDto dto) {
analysisRelationalDbConfig(dto);
Connection pooledConnection = null;
try {
pooledConnection = JdbcUtil.getPooledConnection(dto);
PreparedStatement statement = pooledConnection.prepareStatement(dto.getDynSentence());
ResultSet rs = statement.executeQuery();
int columnCount = rs.getMetaData().getColumnCount();
List<String> columns = new ArrayList<>();
for (int i = 1; i <= columnCount; i++) {
String columnName = rs.getMetaData().getColumnLabel(i);
columns.add(columnName);
}
List<JSONObject> list = new ArrayList<>();
while (rs.next()) {
JSONObject jo = new JSONObject();
columns.forEach(t -> {
try {
Object value = rs.getObject(t);
jo.put(t, value);
} catch (SQLException throwable) {
throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_SQL_ERROR, throwable.getMessage());
}
});
list.add(jo);
}
return list;
} catch (Exception throwable) {
throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_SQL_ERROR, throwable.getMessage());
} finally {
try {
pooledConnection.close();
} catch (SQLException throwable) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, throwable.getMessage());
}
}
}
/**
* http
*
* @param dto
*/
public List<JSONObject> executeHttp(DataSourceDto dto) {
analysisHttpConfig(dto);
HttpHeaders headers = new HttpHeaders();
headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
HttpEntity<String> entity = new HttpEntity<>(dto.getDynSentence(), headers);
ResponseEntity<JSONObject> exchange;
try {
exchange = restTemplate.exchange(dto.getApiUrl(), HttpMethod.valueOf(dto.getMethod()), entity, JSONObject.class);
} catch (Exception e) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
}
if (exchange.getStatusCode().isError()) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
}
JSONObject body = exchange.getBody();
List<JSONObject> result = new ArrayList<>();
result.add(body);
return result;
}
/**
*
*
* @param dto
*/
public void testRelationalDb(DataSourceDto dto) {
analysisRelationalDbConfig(dto);
try {
Connection unPooledConnection = JdbcUtil.getUnPooledConnection(dto);
String catalog = unPooledConnection.getCatalog();
log.info("数据库测试连接成功:{}", catalog);
unPooledConnection.close();
} catch (Exception e) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
}
}
/**
* http
*
* @param dto
*/
public void testHttp(DataSourceDto dto) {
analysisHttpConfig(dto);
String apiUrl = dto.getApiUrl();
String method = dto.getMethod();
String body = dto.getBody();
HttpHeaders headers = new HttpHeaders();
headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
HttpEntity<String> entity = new HttpEntity<>(body, headers);
ResponseEntity<Object> exchange;
try {
exchange = restTemplate.exchange(apiUrl, HttpMethod.valueOf(method), entity, Object.class);
if (exchange.getStatusCode().isError()) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
}
} catch (RestClientException e) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
}
}
/**
*
*
* @param dto
*/
public void testElasticsearchSqlConnection(DataSourceDto dto) {
analysisHttpConfig(dto);
String apiUrl = dto.getApiUrl();
String method = dto.getMethod();
String body = dto.getBody();
HttpHeaders headers = new HttpHeaders();
headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
HttpEntity<String> entity = new HttpEntity<>(body, headers);
ResponseEntity<Object> exchange;
try {
exchange = restTemplate.exchange(apiUrl, HttpMethod.valueOf(method), entity, Object.class);
if (exchange.getStatusCode().isError()) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
}
} catch (RestClientException e) {
throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
}
}
public void analysisRelationalDbConfig(DataSourceDto dto) {
JSONObject json = JSONObject.parseObject(dto.getSourceConfig());
GaeaAssert.isFalse(json.containsKey("jdbcUrl"), ResponseCode.PARAM_IS_NULL,"jdbcUrl not empty");
GaeaAssert.isFalse(json.containsKey("driverName"), ResponseCode.PARAM_IS_NULL,"driverName not empty");
String jdbcUrl = json.getString("jdbcUrl");
String username = json.getString("username");
String password = json.getString("password");
String driverName = json.getString("driverName");
dto.setJdbcUrl(jdbcUrl);
dto.setDriverName(driverName);
dto.setUsername(username);
dto.setPassword(password);
}
/**
* esapi
*
* @param dto
* @return
*/
public void analysisHttpConfig(DataSourceDto dto) {
JSONObject json = JSONObject.parseObject(dto.getSourceConfig());
GaeaAssert.isFalse(json.containsKey("apiUrl"), ResponseCode.PARAM_IS_NULL,"apiUrl not empty");
GaeaAssert.isFalse(json.containsKey("method"), ResponseCode.PARAM_IS_NULL,"method not empty");
GaeaAssert.isFalse(json.containsKey("header"), ResponseCode.PARAM_IS_NULL,"header not empty");
GaeaAssert.isFalse(json.containsKey("body"), ResponseCode.PARAM_IS_NULL,"body not empty");
String apiUrl = json.getString("apiUrl");
String method = json.getString("method");
String header = json.getString("header");
String body = json.getString("body");
//解决url中存在的动态参数
apiUrl = dataSetParamService.transform(dto.getContextData(), apiUrl);
//请求头中动态参数
header = dataSetParamService.transform(dto.getContextData(), header);
dto.setApiUrl(apiUrl);
dto.setMethod(method);
dto.setHeader(header);
dto.setBody(body);
}
}

@ -0,0 +1,25 @@
package com.anjiplus.template.gaea.business.modules.data.report.constant;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class ExpConstant {
public static final String[] FUNCTION = new String[]{"=SUM(", "=AVERAGE(", "=MAX(", "=MIN(", "=IF(", "=AND(", "=OR(", "=CONCAT("};
public static List<Integer> getExpFunction(String e) {
List<Integer> counts = new ArrayList<>();
for (int i = 0; i < FUNCTION.length; i++) {
if(e.contains(FUNCTION[i])){
counts.add(i);
}
}
return counts;
}
}

@ -0,0 +1,60 @@
package com.anjiplus.template.gaea.business.modules.data.report.controller;
import com.anji.plus.gaea.annotation.Permission;
import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.report.controller.dto.ReportDto;
import com.anjiplus.template.gaea.business.modules.data.report.controller.param.ReportParam;
import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
import com.anjiplus.template.gaea.business.modules.data.report.service.ReportService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:19
*/
@RestController
@Api(tags = "报表数据管理")
@RequestMapping("/report")
public class ReportController extends GaeaBaseController<ReportParam, Report, ReportDto> {
@Autowired
private ReportService reportService;
@Override
public GaeaBaseService<ReportParam, Report> getService() {
return reportService;
}
@Override
public Report getEntity() {
return new Report();
}
@Override
public ReportDto getDTO() {
return new ReportDto();
}
@DeleteMapping("/delReport")
@Permission(
code = "DELETE",
name = "删除"
)
@GaeaAuditLog(
pageTitle = "删除"
)
public ResponseBean delReport(@RequestBody ReportDto reportDto) {
reportService.delReport(reportDto);
return ResponseBean.builder().build();
}
}

@ -0,0 +1,44 @@
package com.anjiplus.template.gaea.business.modules.data.report.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import lombok.Data;
import java.io.Serializable;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:34
*/
@Data
public class ReportDto extends GaeaBaseDTO implements Serializable {
/** 报表名称 */
private String reportName;
/** 报表编码 */
private String reportCode;
/**数据集编码,以|分割*/
private String setCodes;
/** 分组 */
private String reportGroup;
/** 备注 */
private String reportDesc;
/** 数据集查询参数 */
private String setParam;
/** 报表json字符串 */
private String jsonStr;
/** 报表类型 */
private String reportType;
/** 数据总计 */
private long total;
}

@ -0,0 +1,30 @@
package com.anjiplus.template.gaea.business.modules.data.report.controller.param;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:40
*/
@Data
public class ReportParam extends PageParam implements Serializable{
/** 报表名称 */
@Query(QueryEnum.LIKE)
private String reportName;
/** 报表编码 */
@Query(QueryEnum.LIKE)
private String reportCode;
/** 报表类型 */
@Query(QueryEnum.EQ)
private String reportType;
}

@ -0,0 +1,13 @@
package com.anjiplus.template.gaea.business.modules.data.report.dao;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:19
*/
public interface ReportMapper extends GaeaBaseMapper<Report> {
}

@ -0,0 +1,41 @@
package com.anjiplus.template.gaea.business.modules.data.report.dao.entity;
import com.anji.plus.gaea.annotation.Unique;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.anjiplus.template.gaea.common.RespCommonCode;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:20
*/
@TableName(value="gaea_report")
@Data
public class Report extends GaeaBaseEntity {
@ApiModelProperty(value = "名称")
private String reportName;
@ApiModelProperty(value = "报表编码")
@Unique(code = RespCommonCode.REPORT_CODE_ISEXIST)
private String reportCode;
@ApiModelProperty(value = "分组")
private String reportGroup;
@ApiModelProperty(value = "报表描述")
private String reportDesc;
@ApiModelProperty(value = "报表类型")
private String reportType;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag;
}

@ -0,0 +1,17 @@
package com.anjiplus.template.gaea.business.modules.data.report.service;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.report.controller.dto.ReportDto;
import com.anjiplus.template.gaea.business.modules.data.report.controller.param.ReportParam;
import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:35
*/
public interface ReportService extends GaeaBaseService<ReportParam, Report> {
void delReport(ReportDto reportDto);
}

@ -0,0 +1,45 @@
package com.anjiplus.template.gaea.business.modules.data.report.service.impl;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.report.controller.dto.ReportDto;
import com.anjiplus.template.gaea.business.modules.data.report.dao.ReportMapper;
import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
import com.anjiplus.template.gaea.business.modules.data.report.service.ReportService;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.ReportExcelMapper;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity.ReportExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* TODO
*
* @author chenkening
* @date 2021/3/26 10:35
*/
@Service
public class ReportServiceImpl implements ReportService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ReportMapper reportMapper;
@Autowired
private ReportExcelMapper reportExcelMapper;
@Override
public GaeaBaseMapper<Report> getMapper() {
return reportMapper;
}
@Override
public void delReport(ReportDto reportDto) {
deleteById(reportDto.getId());
QueryWrapper<ReportExcel> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("report_code" , reportDto.getReportCode());
reportExcelMapper.delete(queryWrapper);
}
}

@ -0,0 +1,97 @@
package com.anjiplus.template.gaea.business.modules.data.reportexcel.controller;
import com.anji.plus.gaea.annotation.Permission;
import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
import com.anji.plus.gaea.bean.ResponseBean;
import com.anji.plus.gaea.code.ResponseCode;
import com.anji.plus.gaea.curd.controller.GaeaBaseController;
import com.anji.plus.gaea.curd.service.GaeaBaseService;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.dto.ReportExcelDto;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.param.ReportExcelParam;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity.ReportExcel;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.service.ReportExcelService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author chenkening
* @date 2021/4/13 15:12
*/
@RestController
@Api(tags = "报表表格管理")
@RequestMapping("/reportExcel")
public class ReportExcelController extends GaeaBaseController<ReportExcelParam, ReportExcel, ReportExcelDto> {
@Autowired
private ReportExcelService reportExcelService;
@Override
public GaeaBaseService<ReportExcelParam, ReportExcel> getService() {
return reportExcelService;
}
@Override
public ReportExcel getEntity() {
return new ReportExcel();
}
@Override
public ReportExcelDto getDTO() {
return new ReportExcelDto();
}
@GetMapping("/detailByReportCode/{reportCode}")
@Permission(
code = "DETAIL",
name = "详情"
)
@GaeaAuditLog(
pageTitle = "详情"
)
public ResponseBean detailByReportCode(@PathVariable String reportCode) {
ReportExcelDto reportExcelDto = reportExcelService.detailByReportCode(reportCode);
return ResponseBean.builder().data(reportExcelDto).build();
}
@PostMapping("/preview")
@Permission(
code = "DETAIL",
name = "预览"
)
@GaeaAuditLog(
pageTitle = "预览"
)
public ResponseBean preview(@RequestBody ReportExcelDto reportExcelDto) {
ReportExcelDto result = reportExcelService.preview(reportExcelDto);
return ResponseBean.builder().data(result).build();
}
@PostMapping("/exportExcel")
@Permission(
code = "IMPORT",
name = "导出"
)
@GaeaAuditLog(
pageTitle = "报表导出"
)
public ResponseBean exportExcel(@RequestBody ReportExcelDto reportExcelDto) {
return ResponseBean.builder().code(ResponseCode.SUCCESS_CODE)
.data(reportExcelService.exportExcel(reportExcelDto))
.message("导出成功,请稍后在下载中心查看").build();
}
// @PostMapping("/exportPdf")
// public ResponseBean exportPdf(@RequestBody ReportExcelDto reportExcelDto) {
// reportExcelService.exportPdf(reportExcelDto);
// return ResponseBean.builder().code(ResponseCode.SUCCESS_CODE)
// .build();
// }
}

@ -0,0 +1,43 @@
package com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.dto;
import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
import lombok.Data;
import java.io.Serializable;
/**
* @author chenkening
* @date 2021/4/13 15:12
*/
@Data
public class ReportExcelDto extends GaeaBaseDTO implements Serializable {
/** 报表名称 */
private String reportName;
/** 报表编码 */
private String reportCode;
/**数据集编码,以|分割*/
private String setCodes;
/** 分组 */
private String reportGroup;
/** 数据集查询参数 */
private String setParam;
/** 报表json字符串 */
private String jsonStr;
/** 报表类型 */
private String reportType;
/** 数据总计 */
private long total;
/**导出类型*/
private String exportType;
}

@ -0,0 +1,18 @@
package com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.param;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
/**
* @author chenkening
* @date 2021/4/13 15:12
*/
@Data
public class ReportExcelParam extends PageParam implements Serializable{
}

@ -0,0 +1,11 @@
package com.anjiplus.template.gaea.business.modules.data.reportexcel.dao;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity.ReportExcel;
/**
* @author chenkening
* @date 2021/4/13 15:11
*/
public interface ReportExcelMapper extends GaeaBaseMapper<ReportExcel> {
}

@ -0,0 +1,33 @@
package com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity;
import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author chenkening
* @date 2021/4/13 15:11
*/
@TableName(value="gaea_report_excel")
@Data
public class ReportExcel extends GaeaBaseEntity {
@ApiModelProperty(value = "报表编码")
private String reportCode;
@ApiModelProperty(value = "数据集编码,以|分割")
private String setCodes;
@ApiModelProperty(value = "数据集查询参数")
private String setParam;
@ApiModelProperty(value = "报表json字符串")
private String jsonStr;
@ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
private Integer enableFlag;
@ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
private Integer deleteFlag;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save