mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-12-04 04:59:00 +08:00
[Metadata] Remove invalid metadata manager (#465)
This commit is contained in:
commit
353eca6c27
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -1,219 +0,0 @@
|
||||
package io.edurt.datacap.server.scheduled;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import io.edurt.datacap.common.enums.Type;
|
||||
import io.edurt.datacap.common.utils.JsonUtils;
|
||||
import io.edurt.datacap.schedule.ScheduledRunnable;
|
||||
import io.edurt.datacap.service.common.PluginUtils;
|
||||
import io.edurt.datacap.service.entity.SourceEntity;
|
||||
import io.edurt.datacap.service.entity.TemplateSqlEntity;
|
||||
import io.edurt.datacap.service.itransient.SqlConfigure;
|
||||
import io.edurt.datacap.service.repository.SourceRepository;
|
||||
import io.edurt.datacap.service.repository.TemplateSqlRepository;
|
||||
import io.edurt.datacap.spi.Plugin;
|
||||
import io.edurt.datacap.spi.model.Configure;
|
||||
import io.edurt.datacap.spi.model.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION")
|
||||
public class SourceScheduledRunnable
|
||||
extends ScheduledRunnable
|
||||
{
|
||||
public static final String DATABASE = "database";
|
||||
public static final String TABLE = "table";
|
||||
private static final String GET_ALL_DATABASES = "getAllDatabase";
|
||||
private static final String GET_ALL_TABLES = "getAllTablesFromDatabase";
|
||||
private static final String GET_ALL_COLUMNS = "getAllColumnsFromDatabaseAndTable";
|
||||
|
||||
private final Injector injector;
|
||||
private final SourceRepository sourceRepository;
|
||||
private final TemplateSqlRepository templateSqlRepository;
|
||||
private final RedisTemplate redisTemplate;
|
||||
private final Environment environment;
|
||||
|
||||
private int maxSuggestions;
|
||||
|
||||
public SourceScheduledRunnable(String name, Injector injector, SourceRepository sourceRepository, TemplateSqlRepository templateSqlRepository, RedisTemplate redisTemplate, Environment environment)
|
||||
{
|
||||
super(name);
|
||||
this.injector = injector;
|
||||
this.sourceRepository = sourceRepository;
|
||||
this.templateSqlRepository = templateSqlRepository;
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.environment = environment;
|
||||
this.maxSuggestions = Integer.parseInt(environment.getProperty("datacap.editor.sugs.maxSize"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
this.sourceRepository.findAll().forEach(entity -> {
|
||||
log.info("==================== {} ---> {} started =================", this.getName(), entity.getName());
|
||||
Optional<Plugin> pluginOptional = PluginUtils.getPluginByNameAndType(this.injector, entity.getType(), entity.getProtocol());
|
||||
if (!pluginOptional.isPresent()) {
|
||||
log.warn("The scheduled task <{}> source {} protocol {} is not available", this.getName(), entity.getType(), entity.getProtocol());
|
||||
}
|
||||
else {
|
||||
long startTime = System.currentTimeMillis();
|
||||
String name = String.format("%s_%s", entity.getName(), entity.getId());
|
||||
log.info("The scheduled task <{}> execution start - child:{} start with {}", this.getName(), name, startTime);
|
||||
// Get all databases
|
||||
TemplateSqlEntity getAllDatabaseEntity = this.templateSqlRepository.findByNameAndPluginContaining(GET_ALL_DATABASES, entity.getType());
|
||||
if (ObjectUtils.isEmpty(getAllDatabaseEntity)) {
|
||||
log.warn("The scheduled task {} template {} is not available", this.getName(), entity.getName(), GET_ALL_DATABASES);
|
||||
}
|
||||
else {
|
||||
// Clear redis cache
|
||||
String key = String.join("_", entity.getType(), entity.getId().toString());
|
||||
long counter = redisTemplate.opsForSet().size(key);
|
||||
redisTemplate.delete(key);
|
||||
log.info("The scheduled task {} child {} type {} find keys counter: {} is cleaned", this.getName(), entity.getName(), entity.getType(), counter);
|
||||
this.processDatabase(entity, getContent(getAllDatabaseEntity, null), pluginOptional.get(), DATABASE, key);
|
||||
}
|
||||
long endTime = System.currentTimeMillis();
|
||||
long times = endTime - startTime;
|
||||
log.info("The scheduled task <{}> execution end - child:{} end with {} consuming:{} millisecond", this.getName(), name, endTime, times);
|
||||
}
|
||||
log.info("==================== {} ---> {} end =================", this.getName(), entity.getName());
|
||||
});
|
||||
}
|
||||
|
||||
private Configure getConfigure(SourceEntity entity)
|
||||
{
|
||||
Configure configure = new Configure();
|
||||
configure.setHost(entity.getHost());
|
||||
configure.setPort(entity.getPort());
|
||||
configure.setUsername(Optional.ofNullable(entity.getUsername()));
|
||||
configure.setPassword(Optional.ofNullable(entity.getPassword()));
|
||||
Optional<String> database = StringUtils.isNotEmpty(entity.getDatabase()) ? Optional.ofNullable(entity.getDatabase()) : Optional.empty();
|
||||
configure.setDatabase(database);
|
||||
configure.setSsl(Optional.ofNullable(entity.getSsl()));
|
||||
configure.setEnv(Optional.ofNullable(entity.getConfigures()));
|
||||
return configure;
|
||||
}
|
||||
|
||||
private String getContent(TemplateSqlEntity entity, Map<String, String> configure)
|
||||
{
|
||||
try {
|
||||
if (ObjectUtils.isNotEmpty(entity.getConfigure())) {
|
||||
final String[] content = {entity.getContent()};
|
||||
List<LinkedHashMap> configures = JsonUtils.objectmapper.readValue(entity.getConfigure(), List.class);
|
||||
configure.entrySet().forEach(value -> {
|
||||
Optional<SqlConfigure> sqlConfigure = configures.stream().filter(v -> String.valueOf(v.get("column")).equalsIgnoreCase(value.getKey())).map(v -> {
|
||||
SqlConfigure configure1 = new SqlConfigure();
|
||||
configure1.setColumn(v.get("column").toString());
|
||||
configure1.setType(Type.valueOf(String.valueOf(v.get("type"))));
|
||||
configure1.setExpression(String.valueOf(v.get("expression")));
|
||||
return configure1;
|
||||
}).findFirst();
|
||||
if (sqlConfigure.isPresent()) {
|
||||
content[0] = content[0].replace(sqlConfigure.get().getExpression(), String.valueOf(value.getValue()));
|
||||
}
|
||||
});
|
||||
return content[0];
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Failed to analysis");
|
||||
return entity.getContent();
|
||||
}
|
||||
return entity.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all databases of the configuration data source and buffer them to Redis
|
||||
*/
|
||||
private void processDatabase(SourceEntity entity, String content, Plugin plugin, String type, String key)
|
||||
{
|
||||
plugin.connect(getConfigure(entity));
|
||||
Response response = plugin.execute(content);
|
||||
if (response.getIsSuccessful()) {
|
||||
TemplateSqlEntity getAllTableEntity = templateSqlRepository.findByNameAndPluginContaining(GET_ALL_TABLES, entity.getType());
|
||||
if (ObjectUtils.isEmpty(getAllTableEntity)) {
|
||||
log.warn("The scheduled task {} template {} is not available", this.getName(), entity.getName(), GET_ALL_TABLES);
|
||||
}
|
||||
else {
|
||||
response.getColumns()
|
||||
.stream()
|
||||
.limit(maxSuggestions)
|
||||
.forEach(column -> {
|
||||
String database = ((List<String>) column).get(0);
|
||||
log.info("The scheduled task {} child {} sync data from source : {}", this.getName(), entity.getName(), database);
|
||||
Map<String, String> configure = new HashMap<>();
|
||||
configure.put("database", database);
|
||||
this.processTable(entity, this.getContent(getAllTableEntity, configure), database, plugin, key);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("The scheduled task {} child {} type {} sync data from source is failed {}", this.getName(), entity.getName(), type, response.getMessage());
|
||||
}
|
||||
plugin.destroy();
|
||||
}
|
||||
|
||||
private void processTable(SourceEntity entity, String content, String database, Plugin plugin, String key)
|
||||
{
|
||||
plugin.connect(getConfigure(entity));
|
||||
Response response = plugin.execute(content);
|
||||
if (response.getIsSuccessful()) {
|
||||
TemplateSqlEntity getAllChildEntity = templateSqlRepository.findByNameAndPluginContaining(GET_ALL_COLUMNS, entity.getType());
|
||||
if (ObjectUtils.isEmpty(getAllChildEntity)) {
|
||||
log.warn("The scheduled task {} template {} is not available", this.getName(), entity.getName(), GET_ALL_COLUMNS);
|
||||
}
|
||||
else {
|
||||
response.getColumns()
|
||||
.stream()
|
||||
.limit(maxSuggestions)
|
||||
.forEach(column -> {
|
||||
String table = ((List<String>) column).get(0);
|
||||
log.info("The scheduled task {} child {} database {} sync data from source is : {}", this.getName(), entity.getName(), database, table);
|
||||
Map<String, String> configure = new HashMap<>();
|
||||
configure.put("table", String.join(".", database, table));
|
||||
this.processColumn(entity, this.getContent(getAllChildEntity, configure), database, table, plugin, key);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("The scheduled task {} child {} database {} sync data from source is failed {}", this.getName(), entity.getName(), database, response.getMessage());
|
||||
}
|
||||
plugin.destroy();
|
||||
}
|
||||
|
||||
private void processColumn(SourceEntity entity, String content, String database, String table, Plugin plugin, String key)
|
||||
{
|
||||
plugin.connect(getConfigure(entity));
|
||||
Response response = plugin.execute(content);
|
||||
if (response.getIsSuccessful()) {
|
||||
TemplateSqlEntity getAllChildEntity = templateSqlRepository.findByNameAndPluginContaining(GET_ALL_COLUMNS, entity.getType());
|
||||
if (ObjectUtils.isEmpty(getAllChildEntity)) {
|
||||
log.warn("The scheduled task {} template {} is not available", this.getName(), entity.getName(), GET_ALL_COLUMNS);
|
||||
}
|
||||
else {
|
||||
response.getColumns()
|
||||
.stream()
|
||||
.limit(maxSuggestions)
|
||||
.forEach(column -> {
|
||||
String value = ((List<String>) column).get(0);
|
||||
log.info("The scheduled task {} child {} database {} table {} sync data from source is : {}", this.getName(), entity.getName(), database, table, value);
|
||||
redisTemplate.opsForSet().add(key, String.join(".", database, table, value));
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("The scheduled task {} child {} database {} table {} sync data from source is failed {}", this.getName(), entity.getName(), database, table, response.getMessage());
|
||||
}
|
||||
plugin.destroy();
|
||||
}
|
||||
}
|
3
core/datacap-server/src/main/schema/1.17.0/schema.sql
Normal file
3
core/datacap-server/src/main/schema/1.17.0/schema.sql
Normal file
@ -0,0 +1,3 @@
|
||||
DELETE
|
||||
FROM `template_sql`
|
||||
WHERE `name` in ('getAllDatabase', 'getAllDatabaseAndTable', 'getAllTablesFromDatabase', 'getAllColumnsFromDatabaseAndTable');
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "datacap-console",
|
||||
"description": "DataCap console",
|
||||
"version": "1.16.0",
|
||||
"version": "1.17.0-SNAPSHOT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
|
@ -1,139 +0,0 @@
|
||||
<template>
|
||||
<div style="max-height: 500px; max-width: 200px; overflow: auto;">
|
||||
<SkeletonItem v-if="loading" :animated="true" type="rect" size="large" style="width: 165px;"/>
|
||||
<Tree v-else :data="dataTreeArray" :load-data="handlerLoadChildData" @on-select-change="handlerSelectNode"/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent, watch} from "vue";
|
||||
import MangerService from "@/services/source/MangerService";
|
||||
import useClipboard from "vue-clipboard3";
|
||||
|
||||
const {toClipboard} = useClipboard();
|
||||
|
||||
export enum DataTreeLevel
|
||||
{
|
||||
database,
|
||||
table,
|
||||
column
|
||||
}
|
||||
|
||||
export class DataTree
|
||||
{
|
||||
title: null;
|
||||
database: null;
|
||||
table: null;
|
||||
level: DataTreeLevel = DataTreeLevel.database;
|
||||
loading = false;
|
||||
children: DataTree[] = [];
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: "DataLazyTree",
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
loading: false,
|
||||
dataTreeArray: []
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.handlerInitialize();
|
||||
watch(() => this.id, () => {
|
||||
this.handlerInitialize();
|
||||
}
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
handlerInitialize()
|
||||
{
|
||||
this.dataTreeArray = [];
|
||||
this.loading = true;
|
||||
MangerService.getDatabases(this.id)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const header = response.data.headers[0];
|
||||
response.data.columns.forEach(column => {
|
||||
const data = new DataTree();
|
||||
data.title = column[header];
|
||||
this.dataTreeArray.push(data);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handlerLoadChildData(item: DataTree, callback)
|
||||
{
|
||||
const dataChildArray = [];
|
||||
if (item.level === DataTreeLevel.database) {
|
||||
MangerService.getTables(this.id, item.title)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const header = response.data.headers[0];
|
||||
response.data.columns.forEach(column => {
|
||||
const data = new DataTree();
|
||||
data.title = column[header];
|
||||
data.database = item.title;
|
||||
data.level = DataTreeLevel.table;
|
||||
dataChildArray.push(data);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
callback(dataChildArray);
|
||||
});
|
||||
}
|
||||
else if (item.level === DataTreeLevel.table) {
|
||||
MangerService.getColumns(this.id, item.database, item.title)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const header = response.data.headers[0];
|
||||
response.data.columns.forEach(column => {
|
||||
const data = {
|
||||
title: column[header],
|
||||
database: item.database,
|
||||
table: item.title,
|
||||
level: DataTreeLevel.column
|
||||
};
|
||||
dataChildArray.push(data);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
callback(dataChildArray);
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback(dataChildArray);
|
||||
}
|
||||
},
|
||||
handlerSelectNode(item: DataTree)
|
||||
{
|
||||
const target = item[0];
|
||||
let text: string = target.title;
|
||||
switch (target.level) {
|
||||
case DataTreeLevel.table:
|
||||
text = target.database + '.' + text;
|
||||
break
|
||||
case DataTreeLevel.column:
|
||||
text = target.database + '.' + target.table + '.' + text;
|
||||
break
|
||||
}
|
||||
toClipboard(text).finally(() => this.$Message.success('Copy successful!'));
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -1,106 +0,0 @@
|
||||
<template>
|
||||
<div style="max-height: 500px; max-width: 200px; overflow: auto;">
|
||||
<SkeletonItem v-if="loading" :animated="true" type="rect" size="large" style="width: 165px;"/>
|
||||
<Tree v-else :data="treeData" :render="renderContent"/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent, resolveComponent, watch} from "vue";
|
||||
import {TreeService} from "@/services/TreeService";
|
||||
import {TreeData} from "@/model/TreeData";
|
||||
import useClipboard from 'vue-clipboard3';
|
||||
import TemplateSqlService from "@/services/template/TemplateSqlService";
|
||||
import {SqlBody} from "@/model/template/SqlBody";
|
||||
|
||||
const {toClipboard} = useClipboard();
|
||||
|
||||
export default defineComponent({
|
||||
name: "DatabaseTree",
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
treeData: [] as TreeData[],
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.handlerInitialize();
|
||||
watch(() => this.id, () => {
|
||||
this.handlerInitialize();
|
||||
}
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
renderContent(h, {data})
|
||||
{
|
||||
return h('span',
|
||||
{
|
||||
style: {
|
||||
display: 'inline-block',
|
||||
width: '100%'
|
||||
}
|
||||
},
|
||||
[
|
||||
h(resolveComponent('Ellipsis'), {
|
||||
text: data.title,
|
||||
length: 15,
|
||||
tooltip: true,
|
||||
transfer: true,
|
||||
onClick: () => {
|
||||
this.handlerCopy(data.database, data.table, data.value, data.dataType);
|
||||
}
|
||||
})
|
||||
]);
|
||||
},
|
||||
handlerInitialize()
|
||||
{
|
||||
this.treeData = [];
|
||||
this.loading = true;
|
||||
const sqlBody: SqlBody = {
|
||||
templateName: 'getAllDatabaseAndTable',
|
||||
sourceId: this.id,
|
||||
configure: {}
|
||||
}
|
||||
TemplateSqlService.execute(sqlBody)
|
||||
.then((response) => {
|
||||
if (response.status) {
|
||||
this.treeData = new TreeService().getTree(response);
|
||||
}
|
||||
else {
|
||||
this.$Message.error(response.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handlerCopy(database: string, table: string, value: string, dataType: string)
|
||||
{
|
||||
let text: string = value;
|
||||
switch (dataType) {
|
||||
case 'database':
|
||||
text = database;
|
||||
break;
|
||||
case 'table':
|
||||
text = database + '.' + table;
|
||||
break
|
||||
case 'column':
|
||||
text = database + '.' + table + '.' + value;
|
||||
break
|
||||
}
|
||||
toClipboard(text).finally(() => this.$Message.success('Copy successful!'));
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -130,12 +130,6 @@ const createDefaultRouter = (router: any) => {
|
||||
meta: {title: 'common.source'},
|
||||
layout: LayoutContainer,
|
||||
component: () => import("../views/admin/source/SourceManager.vue")
|
||||
},
|
||||
{
|
||||
path: "source/:id/managerBeta",
|
||||
meta: {title: 'common.source'},
|
||||
layout: LayoutContainer,
|
||||
component: () => import("../views/admin/source/SourceManagerBeta.vue")
|
||||
}
|
||||
]
|
||||
})
|
||||
|
@ -1,174 +0,0 @@
|
||||
import {ResponseModel} from "@/model/ResponseModel";
|
||||
import TemplateSqlService from "@/services/template/TemplateSqlService";
|
||||
import {SqlBody} from "@/model/template/SqlBody";
|
||||
import {ExecuteService} from "@/services/ExecuteService";
|
||||
import {Sql} from "@/model/sql/Sql";
|
||||
import {ExecuteDslBodyBuilder} from "@/model/ExecuteDslBody";
|
||||
import {SqlBodyBuilder} from "@/model/builder/SqlBody";
|
||||
import {SqlType} from "@/model/builder/SqlType";
|
||||
import {SqlColumn, SqlColumnBuilder} from "@/model/builder/SqlColumn";
|
||||
import {SqlOrder} from "@/model/builder/SqlOrder";
|
||||
|
||||
class ManagerService
|
||||
{
|
||||
getDatabases(id: number): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: undefined,
|
||||
sourceId: id,
|
||||
templateName: 'getAllDatabase'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all table types under the database according to the database
|
||||
* Template: FindTableTypeByDatabase
|
||||
* @param id The selected data source tag, which is stored in the database
|
||||
* @param database The query database name
|
||||
*/
|
||||
findTableTypeByDatabase(id: number, database: string): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
database: database
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'FindTableTypeByDatabase'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a collection of related data based on the specified database and data type
|
||||
* Template: FindTableByDatabaseAndType
|
||||
* @param id The selected data source tag, which is stored in the database
|
||||
* @param database The query database name
|
||||
* @param type The query table type
|
||||
*/
|
||||
getTableDataByDatabaseAndType(id: number, database: string, type: string): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
database: database,
|
||||
type: type
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'FindTableByDatabaseAndType'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data column classification collection based on the provided database and data table
|
||||
* Template: FindColumnTypeByDatabaseAndTable
|
||||
* @param id The selected data source tag, which is stored in the database
|
||||
* @param database The query database name
|
||||
* @param table The query table name
|
||||
*/
|
||||
findColumnTypeByDatabaseAndTable(id: number, database: string, table: string): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
database: database,
|
||||
table: table
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'FindColumnTypeByDatabaseAndTable'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a collection of related data based on the specified database, table, and data type
|
||||
* Template: FindColumnByDatabaseAndTableAndType
|
||||
* @param id The selected data source tag, which is stored in the database
|
||||
* @param database The query database name
|
||||
* @param table The query table name
|
||||
* @param type The query table type
|
||||
*/
|
||||
getColumnDataByDatabaseAndTableAndType(id: number, database: string, table: string, type: string): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
database: database,
|
||||
table: table,
|
||||
type: type
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'FindColumnByDatabaseAndTableAndType'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
getTables(id: number, database: string): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
database: database
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'getAllTablesFromDatabase'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
getColumns(id: number, database: string, table): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
table: database + '.' + table
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'getAllColumnsFromDatabaseAndTable'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
getData(id: number, database: string, table: string, page: number, size: number): Promise<ResponseModel>
|
||||
{
|
||||
const configure: SqlBody = {
|
||||
configure: {
|
||||
table: database + '.' + table,
|
||||
page: page,
|
||||
size: size
|
||||
},
|
||||
sourceId: id,
|
||||
templateName: 'getDataFromDatabaseAndTableLimited'
|
||||
};
|
||||
return TemplateSqlService.execute(configure);
|
||||
}
|
||||
|
||||
getDataByConfigure(id: string, sql: Sql): Promise<ResponseModel>
|
||||
{
|
||||
const columns: SqlColumn[] = new Array<SqlColumn>();
|
||||
if (sql.columns.length > 0) {
|
||||
sql.columns.forEach(column => columns.push(new SqlColumnBuilder(column).build()));
|
||||
}
|
||||
else {
|
||||
columns.push(new SqlColumnBuilder('*').build());
|
||||
}
|
||||
// The default offset is 1, and the database index defaults to 0, which needs to be subtracted by 1
|
||||
const orders: SqlColumn[] = new Array();
|
||||
if (sql.sort) {
|
||||
sql.sort.forEach(order => {
|
||||
orders.push(new SqlColumnBuilder(order.column).setOrder(SqlOrder[order.sort.toUpperCase()]).build());
|
||||
});
|
||||
}
|
||||
|
||||
const sqlBody = new SqlBodyBuilder(sql.database, sql.table)
|
||||
.setColumns(columns)
|
||||
.setOrders(orders)
|
||||
.setType(SqlType.SELECT)
|
||||
.setLimit(sql.limit)
|
||||
.setOffset(sql.offset - 1)
|
||||
.setWhere(sql.where)
|
||||
.build();
|
||||
const configure = new ExecuteDslBodyBuilder(id, 'JSON')
|
||||
.setConfigure(sqlBody)
|
||||
.build();
|
||||
return new ExecuteService().executeDsl(configure);
|
||||
}
|
||||
}
|
||||
|
||||
export default new ManagerService();
|
@ -67,14 +67,6 @@
|
||||
<Button :disabled="currentUserId !== row.user.id" shape="circle" type="error" size="small" icon="md-trash"/>
|
||||
</Poptip>
|
||||
</Tooltip>
|
||||
<Tooltip :content="$t('common.admin')" transfer>
|
||||
<Button :disabled="currentUserId !== row.user.id || !row.available"
|
||||
shape="circle" type="info"
|
||||
size="small"
|
||||
icon="md-construct"
|
||||
:to="'/admin/source/' + row.id + '/manager'">
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip :content="$t('common.admin') + $t('common.beta')"
|
||||
transfer>
|
||||
<Button :disabled="currentUserId !== row.user.id || !row.available"
|
||||
@ -82,7 +74,7 @@
|
||||
type="info"
|
||||
size="small"
|
||||
icon="md-construct"
|
||||
:to="'/admin/source/' + row.id + '/managerBeta'">
|
||||
:to="'/admin/source/' + row.id + '/manager'">
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
|
@ -1,177 +1,145 @@
|
||||
<template>
|
||||
<div style="padding: 0">
|
||||
<SourceNotSupported v-if="!isSupported" :templateName="templateArray" style="margin-top: 50px;"></SourceNotSupported>
|
||||
<div v-else ref="splitContainer" class="split-container">
|
||||
<Split v-model="splitModel" :min="0.15">
|
||||
<CircularLoading v-if="loading"
|
||||
:show="loading">
|
||||
</CircularLoading>
|
||||
<div v-else
|
||||
ref="splitContainer"
|
||||
class="split-container">
|
||||
<Split v-model="splitValue"
|
||||
:min="0.15">
|
||||
<template #left>
|
||||
<div ref="splitContainerLeftPane" class="split-container-pane">
|
||||
<Card style="width:100%;" :padding="0" :bordered="false" dis-hover>
|
||||
<div ref="splitContainerLeftPane"
|
||||
class="split-container-pane">
|
||||
<Card style="width:100%;"
|
||||
:padding="0"
|
||||
:bordered="false"
|
||||
dis-hover>
|
||||
<template #title>
|
||||
<Row>
|
||||
<Col span="4" style="margin-top: 3px;">
|
||||
<Tooltip v-if="data" transfer :content="data.name" placement="bottom-start">
|
||||
<Avatar :src="'/static/images/plugin/' + data.type + '.png'" size="small"/>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
<Col span="20">
|
||||
<Select v-model="currentDatabase" @on-change="handlerChangeDatabase">
|
||||
<Option v-for="database in databaseArray" :value="database" :key="database">
|
||||
{{ database }}
|
||||
</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Select v-model="applyValue.database"
|
||||
@on-change="handlerChangeDatabase">
|
||||
<Option v-for="item in databaseArray"
|
||||
:value="item.applyId"
|
||||
:key="item.title">
|
||||
<FontAwesomeIcon icon="database"
|
||||
style="margin-right: 6px;">
|
||||
</FontAwesomeIcon>
|
||||
{{ item.title }}
|
||||
</Option>
|
||||
</Select>
|
||||
</template>
|
||||
<div style="height: 470px; overflow: auto;">
|
||||
<Tree :data="dataTreeArray" :load-data="handlerLoadChild" @on-select-change="handlerSelectNode"></Tree>
|
||||
<Spin size="large" fix :show="tableLoading"></Spin>
|
||||
<Tree :data="dataTreeArray"
|
||||
style="margin-left: 6px;"
|
||||
:load-data="handlerLoadChildData"
|
||||
@on-select-change="handlerSelectNode">
|
||||
</Tree>
|
||||
<CircularLoading v-if="dataTreeLoading"
|
||||
:show="dataTreeLoading">
|
||||
</CircularLoading>
|
||||
</div>
|
||||
<Spin size="large" fix :show="loading"></Spin>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
<template #right>
|
||||
<div ref="splitContainerRightPane" class="split-container-pane">
|
||||
<Card v-if="!isShowData" dis-hover :bordered="false">
|
||||
<Result type="warning" style="margin-top: 10px;">
|
||||
<template #desc>
|
||||
{{ $t('alert.managerRequiredTreeData') }}
|
||||
</template>
|
||||
</Result>
|
||||
</Card>
|
||||
<div v-if="isShowData && !dataLoading && tableConfigure">
|
||||
<!-- Paging related components -->
|
||||
<div style="margin: 3px 0px 3px 10px;">
|
||||
<Space>
|
||||
<Button :disabled="currentPageNumber === 1" shape="circle" type="text"
|
||||
size="small" icon="md-arrow-back" @click="handlerChangePage(false)"/>
|
||||
<Select v-model="configure.limit" size="small" style="width: 60px" @on-change="handlerExecute">
|
||||
<Option v-for="item in limitOptions" :value="item" :key="item">{{ item }}</Option>
|
||||
</Select>
|
||||
<Input v-model="currentPageNumber" size="small" style="max-width: 50px;"/>
|
||||
<Button :disabled="tableConfigure?.columns.length < configure.limit" shape="circle" type="text"
|
||||
size="small" icon="md-arrow-forward" @click="handlerChangePage(true)"/>
|
||||
<Tooltip :content="$t('common.elapsed')">
|
||||
<Button size="small" icon="md-clock" type="default">{{ tableConfigure.elapsed }} ms</Button>
|
||||
</Tooltip>
|
||||
<Tooltip content="DDL">
|
||||
<Button size="small" icon="md-eye" type="text" shape="circle" @click="handlerControlModal(false)"></Button>
|
||||
</Tooltip>
|
||||
<Dropdown v-if="selectedRows.length > 0" placement="bottom-start">
|
||||
<Button style="margin-top: -8px;" size="small" type="text" icon="ios-download">
|
||||
[<span style="font-size: 12px; color: #19BE6B; font-weight: bold;">{{ selectedRows.length }}</span>]
|
||||
</Button>
|
||||
<template #list>
|
||||
<DropdownMenu>
|
||||
<DropdownItem @click="handlerCopyWith(true)">
|
||||
<Icon type="md-copy"/>
|
||||
{{ $t('copy.copyWithHeadersRow') }}
|
||||
</DropdownItem>
|
||||
<DropdownItem @click="handlerCopyWith(false)">
|
||||
<Icon type="md-copy"/>
|
||||
{{ $t('copy.copyDataOnlyRow') }}
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</div>
|
||||
<!-- Filter component -->
|
||||
<div style="margin: 3px 0px -4px 10px;">
|
||||
<Space>
|
||||
<Input v-model="currentOrder.inputValue" size="small" clearable style="width: auto;" @on-enter="handlerGetValue">
|
||||
<template #prepend>
|
||||
<Icon type="md-list"/>
|
||||
ORDER BY
|
||||
</template>
|
||||
</Input>
|
||||
<Input v-model="currentWhere" size="small" clearable style="width: auto;" @on-enter="handlerGetValue">
|
||||
<template #prepend>
|
||||
<FontAwesomeIcon icon="filter" />
|
||||
WHERE
|
||||
</template>
|
||||
</Input>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
<TablePreview v-if="tableConfigure"
|
||||
:configure="tableConfigure"
|
||||
:sortColumns="tableSortColumns"
|
||||
@on-sorted="handlerOnSorted"
|
||||
@on-selected="handlerOnSelected">
|
||||
</TablePreview>
|
||||
<Spin size="large" fix :show="dataLoading"></Spin>
|
||||
</div>
|
||||
<Card v-if="!applyValue.node"
|
||||
padding="0 10"
|
||||
:bordered="false"
|
||||
dis-hover>
|
||||
<Result type="warning"
|
||||
:title="$t('tooltip.notSelectedNodeTitle')">
|
||||
<template #desc>
|
||||
<span>{{ $t('tooltip.notSelectedNodeDesc') }}</span>
|
||||
</template>
|
||||
</Result>
|
||||
</Card>
|
||||
<Card v-else
|
||||
style="width:100%;"
|
||||
padding="0 10"
|
||||
:bordered="false"
|
||||
:title="null"
|
||||
dis-hover>
|
||||
<Tabs v-model="applyValue.tabType"
|
||||
:animated="false">
|
||||
<TabPane :label="tabPane.info"
|
||||
name="info">
|
||||
<TableInfo v-if="applyValue.tabType === 'info'"
|
||||
:id="applyValue.node.applyId">
|
||||
</TableInfo>
|
||||
</TabPane>
|
||||
<TabPane :label="tabPane.data"
|
||||
name="data">
|
||||
<TableData v-if="applyValue.tabType === 'data'"
|
||||
:id="applyValue.node.applyId">
|
||||
</TableData>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</template>
|
||||
</Split>
|
||||
</div>
|
||||
<SqlDetail v-if="modalVisible"
|
||||
:isVisible="modalVisible"
|
||||
:content="tableConfigure.context"
|
||||
@close="handlerControlModal(true)">
|
||||
</SqlDetail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from "vue";
|
||||
import {defineComponent, resolveComponent} from "vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {SourceService} from "@/services/SourceService";
|
||||
import {join, toNumber} from "lodash";
|
||||
import {SourceModel} from "@/model/SourceModel";
|
||||
import MangerService from "@/services/source/MangerService";
|
||||
import {Sql} from "@/model/sql/Sql";
|
||||
import {toNumber} from "lodash";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import SourceNotSupported from "@/components/common/SourceNotSupported.vue";
|
||||
import {TableConfigure} from "@/components/table/TableConfigure";
|
||||
import TablePreview from "@/views/admin/source/components/TablePreview.vue";
|
||||
import {Sort} from "@/model/sql/Sort";
|
||||
import SqlDetail from "@/components/sql/SqlDetail.vue";
|
||||
import useClipboard from "vue-clipboard3";
|
||||
import DatabaseService from "@/services/Database";
|
||||
import TableService from "@/services/Table";
|
||||
import ColumnService from "@/services/Column";
|
||||
import CircularLoading from "@/components/loading/CircularLoading.vue";
|
||||
import {DataStructureModel} from "@/model/DataStructure";
|
||||
import {DataStructureEnum} from "@/enum/DataStructure";
|
||||
import TableInfo from "@/views/admin/source/components/TableInfo.vue";
|
||||
import TableData from "@/views/admin/source/components/TableData.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "SourceManager",
|
||||
components: {SqlDetail, TablePreview, SourceNotSupported},
|
||||
name: "SourceManagerBeta",
|
||||
components: {TableData, TableInfo, CircularLoading},
|
||||
setup()
|
||||
{
|
||||
const i18n = useI18n();
|
||||
const resolveTabPaneComponent = (h, icon: string, key: string) => {
|
||||
return h('div', [
|
||||
h(resolveComponent('FontAwesomeIcon'), {
|
||||
icon: icon,
|
||||
style: {fontSize: '25px'}
|
||||
}),
|
||||
h('p', {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
}
|
||||
},
|
||||
i18n.t(key))
|
||||
])
|
||||
}
|
||||
return {
|
||||
i18n
|
||||
i18n,
|
||||
resolveTabPaneComponent
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
templateArray: ['getAllDatabase', 'getAllTablesFromDatabase', 'getAllColumnsFromDatabaseAndTable'],
|
||||
sourceId: 0,
|
||||
loading: false,
|
||||
tableLoading: false,
|
||||
dataLoading: false,
|
||||
isSupported: false,
|
||||
isShowData: false,
|
||||
data: null as SourceModel,
|
||||
currentDatabase: null,
|
||||
currentTable: null,
|
||||
currentItem: null,
|
||||
currentPageNumber: 1,
|
||||
currentOrder: {
|
||||
inputValue: null
|
||||
dataTreeLoading: false,
|
||||
splitValue: 0.15,
|
||||
databaseArray: Array<DataStructureModel>(),
|
||||
dataTreeArray: Array<DataStructureModel>(),
|
||||
applyValue: {
|
||||
database: null,
|
||||
node: null as DataStructureModel,
|
||||
tabType: 'info'
|
||||
},
|
||||
currentWhere: null,
|
||||
databaseArray: [],
|
||||
dataTreeArray: [],
|
||||
configure: null as Sql,
|
||||
splitModel: 0.15,
|
||||
tableConfigure: null as TableConfigure,
|
||||
tableSortColumns: [],
|
||||
modalVisible: false,
|
||||
limitOptions: [5, 10, 15, 20, 50, 100],
|
||||
selectedRows: []
|
||||
tabPane: {
|
||||
info: (h) => this.resolveTabPaneComponent(h, 'circle-info', 'common.info'),
|
||||
data: (h) => this.resolveTabPaneComponent(h, 'table', 'common.data'),
|
||||
}
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.configure = new Sql();
|
||||
this.handlerInitialize();
|
||||
},
|
||||
methods: {
|
||||
@ -180,306 +148,190 @@ export default defineComponent({
|
||||
this.loading = true;
|
||||
const router = useRouter();
|
||||
const id = router.currentRoute?.value?.params['id'];
|
||||
this.sourceId = toNumber(id);
|
||||
new SourceService().getById(this.sourceId)
|
||||
DatabaseService.getAllBySource(toNumber(id))
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
if (response.data) {
|
||||
this.data = response.data;
|
||||
this.isSupported = true;
|
||||
}
|
||||
response.data.forEach((item: { name: null; catalog: null; id: null }) => {
|
||||
const structure = new DataStructureModel();
|
||||
structure.title = item.name;
|
||||
structure.catalog = item.catalog;
|
||||
structure.applyId = item.id;
|
||||
this.databaseArray.push(structure);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
|
||||
MangerService.getDatabases(this.sourceId)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const header = response.data.headers[0];
|
||||
response.data.columns.forEach(column => {
|
||||
this.databaseArray.push(column[header]);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.isSupported = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
handlerChangeDatabase()
|
||||
{
|
||||
this.tableLoading = true;
|
||||
MangerService.findTableTypeByDatabase(this.sourceId, this.currentDatabase)
|
||||
this.dataTreeLoading = true;
|
||||
this.dataTreeArray = [];
|
||||
TableService.getAllByDatabase(this.applyValue.database)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const header = response.data.headers[0];
|
||||
this.dataTreeArray = [];
|
||||
response.data.columns.forEach(column => {
|
||||
this.dataTreeArray.push({
|
||||
title: this.i18n.t('common.' + column[header]),
|
||||
level: 'GetDataForTableType',
|
||||
action: column[header],
|
||||
loading: false,
|
||||
type: 'action',
|
||||
children: []
|
||||
});
|
||||
response.data.forEach((item: {
|
||||
name: null;
|
||||
title: null;
|
||||
catalog: null;
|
||||
id: null;
|
||||
type: null;
|
||||
engine: null;
|
||||
comment: null;
|
||||
database: { name: null };
|
||||
}) => {
|
||||
const structure = new DataStructureModel();
|
||||
structure.title = item.name;
|
||||
structure.database = item.database.name;
|
||||
structure.catalog = item.catalog;
|
||||
structure.applyId = item.id;
|
||||
structure.type = item.type;
|
||||
structure.level = DataStructureEnum.TABLE;
|
||||
structure.engine = item.engine;
|
||||
structure.comment = item.comment;
|
||||
structure.origin = item;
|
||||
structure.render = (h, {data}) => {
|
||||
return h('div', [
|
||||
h('span', [
|
||||
h(resolveComponent('FontAwesomeIcon'), {
|
||||
icon: "table",
|
||||
style: {marginRight: '6px'}
|
||||
}),
|
||||
this.resolveTableComponent(h, data)
|
||||
])
|
||||
]);
|
||||
}
|
||||
this.dataTreeArray.push(structure);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.tableLoading = false;
|
||||
this.dataTreeLoading = false;
|
||||
});
|
||||
},
|
||||
handlerLoadChild(item, callback)
|
||||
handlerLoadChildData(item: DataStructureModel, callback)
|
||||
{
|
||||
this.currentTable = item.title;
|
||||
// Load all tables under the database according to type
|
||||
if (item.level === 'GetDataForTableType') {
|
||||
MangerService.getTableDataByDatabaseAndType(this.sourceId, this.currentDatabase, item.action)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const dataTreeColumnArray = [];
|
||||
// Add the total amount of data to the parent class header
|
||||
item.title = item.title + ' [' + response.data.columns.length + ']';
|
||||
response.data.columns.forEach(column => {
|
||||
dataTreeColumnArray.push({
|
||||
title: column['TABLE_NAME'],
|
||||
level: 'FindColumnType',
|
||||
database: this.currentDatabase,
|
||||
catalog: column['TABLE_CATALOG'],
|
||||
loading: false,
|
||||
type: 'data',
|
||||
children: []
|
||||
});
|
||||
});
|
||||
callback(dataTreeColumnArray);
|
||||
}
|
||||
else {
|
||||
this.$Message.error(response.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.tableLoading = false;
|
||||
});
|
||||
}
|
||||
// Gets a collection of related data based on the specified database and data type
|
||||
else if (item.level === 'FindColumnType') {
|
||||
MangerService.findColumnTypeByDatabaseAndTable(this.sourceId, item.catalog, this.currentTable)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const dataTreeColumnArray = [];
|
||||
const types = [];
|
||||
response.data.columns.forEach(column => {
|
||||
column['COLUMN_TYPE'].split(',').forEach(type => {
|
||||
if (types.indexOf(type) === -1) {
|
||||
dataTreeColumnArray.push({
|
||||
title: this.i18n.t('common.' + type),
|
||||
level: 'GetColumnDataForTableType',
|
||||
action: type,
|
||||
catalog: column['TABLE_CATALOG'],
|
||||
database: this.currentDatabase,
|
||||
table: this.currentTable,
|
||||
loading: false,
|
||||
type: 'action',
|
||||
children: []
|
||||
});
|
||||
}
|
||||
types.push(type);
|
||||
})
|
||||
});
|
||||
callback(dataTreeColumnArray);
|
||||
}
|
||||
else {
|
||||
this.$Message.error(response.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.tableLoading = false;
|
||||
});
|
||||
}
|
||||
// Gets a collection of related data based on the specified database, table, and data type
|
||||
else if (item.level === 'GetColumnDataForTableType') {
|
||||
MangerService.getColumnDataByDatabaseAndTableAndType(this.sourceId, item.catalog, item.table, item.action)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
const dataTreeColumnArray = [];
|
||||
item.title = item.title + ' [' + response.data.columns.length + ']';
|
||||
response.data.columns.forEach(column => {
|
||||
dataTreeColumnArray.push({
|
||||
catalog: column['TABLE_CATALOG'],
|
||||
database: this.currentDatabase,
|
||||
table: column['TABLE_NAME'],
|
||||
column: column['COLUMN_NAME'],
|
||||
title: column['COLUMN_NAME'] + ' [' + column['DATA_TYPE'] + ']',
|
||||
level: 'GetColumnDataForTable',
|
||||
type: 'data',
|
||||
dataType: column['DATA_TYPE'],
|
||||
children: []
|
||||
});
|
||||
})
|
||||
callback(dataTreeColumnArray);
|
||||
}
|
||||
else {
|
||||
this.$Message.error(response.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.tableLoading = false;
|
||||
});
|
||||
const dataChildArray = [];
|
||||
if (item.level === DataStructureEnum.COLUMN) {
|
||||
callback(dataChildArray);
|
||||
return;
|
||||
}
|
||||
ColumnService.getAllByTable(item.applyId)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
response.data.forEach((item: {
|
||||
name: null;
|
||||
title: null;
|
||||
catalog: null;
|
||||
id: null;
|
||||
type: null;
|
||||
dataType: null;
|
||||
extra: null;
|
||||
engine: null;
|
||||
isKey: null;
|
||||
defaultValue: null;
|
||||
table: { name: null, database: { name: null } };
|
||||
}) => {
|
||||
const structure = new DataStructureModel();
|
||||
structure.title = item.name;
|
||||
structure.database = item.table.database.name;
|
||||
structure.table = item.table.name;
|
||||
structure.catalog = item.catalog;
|
||||
structure.applyId = item.id;
|
||||
structure.level = DataStructureEnum.COLUMN;
|
||||
structure.type = item.type;
|
||||
structure.extra = item.extra;
|
||||
structure.dataType = item.dataType;
|
||||
structure.engine = item.engine;
|
||||
structure.isKey = item.isKey;
|
||||
structure.defaultValue = item.defaultValue;
|
||||
structure.render = (h, {data}) => {
|
||||
return h('div', [
|
||||
h('span', [
|
||||
h(resolveComponent('FontAwesomeIcon'), {
|
||||
icon: this.getColumnIcon(data.isKey),
|
||||
style: {marginRight: '6px'}
|
||||
}),
|
||||
h('span', data.title),
|
||||
h('span', {
|
||||
style: {
|
||||
marginLeft: '6px',
|
||||
color: '#c5c8ce'
|
||||
},
|
||||
},
|
||||
this.getColumnTitle(data.type, data.extra, data.isKey, data.defaultValue)),
|
||||
])
|
||||
]);
|
||||
}
|
||||
dataChildArray.push(structure);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
callback(dataChildArray);
|
||||
});
|
||||
},
|
||||
handlerSelectNode(item)
|
||||
handlerSelectNode(node: Array<DataStructureModel>)
|
||||
{
|
||||
if (item.length > 0) {
|
||||
const data = item[0];
|
||||
if (data.type === 'action') {
|
||||
return
|
||||
}
|
||||
this.currentItem = item;
|
||||
this.headers = [];
|
||||
this.columns = [];
|
||||
this.isShowData = true;
|
||||
this.dataLoading = true;
|
||||
this.selectedRows = [];
|
||||
// Reinitialize when switching to a new table
|
||||
if (this.currentTable !== data.title) {
|
||||
this.configure = new Sql();
|
||||
this.currentPageNumber = 1;
|
||||
this.currentOrder.inputValue = null;
|
||||
this.currentWhere = null;
|
||||
this.configure.offset = this.currentPageNumber;
|
||||
this.tableSortColumns = null;
|
||||
}
|
||||
this.currentTable = data.title;
|
||||
this.configure.database = data.catalog;
|
||||
this.configure.table = this.currentTable;
|
||||
if (data.level === 'GetColumnDataForTable') {
|
||||
this.configure.table = data.table;
|
||||
this.configure.columns = [data.column];
|
||||
}
|
||||
this.handlerExecute();
|
||||
if (node.length === 0) {
|
||||
// Prevent selection clearing after repeated clicks
|
||||
this.applyValue.node.selected = true;
|
||||
return;
|
||||
}
|
||||
const currentNode = node[0];
|
||||
if (currentNode.level === DataStructureEnum.COLUMN) {
|
||||
this.applyValue.node.selected = true;
|
||||
currentNode.selected = false;
|
||||
return;
|
||||
}
|
||||
this.applyValue.node = currentNode;
|
||||
},
|
||||
handlerChangePage(nexted: boolean)
|
||||
getColumnIcon(type: string)
|
||||
{
|
||||
if (nexted) {
|
||||
this.configure.offset = this.currentPageNumber * this.configure.limit + 1;
|
||||
this.currentPageNumber += 1;
|
||||
if (type === 'PRI') {
|
||||
return 'key';
|
||||
}
|
||||
else if (type === 'MUL') {
|
||||
return 'repeat';
|
||||
}
|
||||
else if (type === 'UNI') {
|
||||
return 'circle';
|
||||
}
|
||||
else {
|
||||
this.currentPageNumber -= 1;
|
||||
this.configure.offset = (this.currentPageNumber - 1) * this.configure.limit + 1;
|
||||
return 'columns';
|
||||
}
|
||||
this.handlerSelectNode(this.currentItem);
|
||||
},
|
||||
handlerExecute()
|
||||
getColumnTitle(dataType: string, extra: string, isKey: string, defaultValue: string)
|
||||
{
|
||||
this.tableConfigure = null;
|
||||
this.dataLoading = true;
|
||||
const splitContainerLeftPane: HTMLElement = this.$refs.splitContainerLeftPane as HTMLElement;
|
||||
const splitContainer: HTMLElement = this.$refs.splitContainer as HTMLElement;
|
||||
MangerService.getDataByConfigure(this.sourceId, this.configure)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
response.data.headers.forEach(header => {
|
||||
this.headers.push(
|
||||
{
|
||||
title: header,
|
||||
key: header,
|
||||
'minWidth': 200,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
}
|
||||
);
|
||||
});
|
||||
const tConfigure: TableConfigure = {
|
||||
headers: response.data.headers,
|
||||
columns: response.data.columns,
|
||||
types: response.data.types,
|
||||
height: splitContainerLeftPane.offsetHeight - 57,
|
||||
width: splitContainer.offsetWidth - splitContainerLeftPane.offsetWidth,
|
||||
showSeriesNumber: false,
|
||||
elapsed: response?.data?.processor?.elapsed,
|
||||
context: response?.data?.content
|
||||
};
|
||||
this.tableConfigure = tConfigure;
|
||||
}
|
||||
else {
|
||||
this.$Message.error(response.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.tableLoading = false;
|
||||
this.dataLoading = false;
|
||||
});
|
||||
},
|
||||
handlerGetValue()
|
||||
{
|
||||
if (this.currentOrder.inputValue) {
|
||||
const value = this.currentOrder.inputValue;
|
||||
if (value) {
|
||||
const sort: Array<Sort> = new Array<Sort>();
|
||||
value.split(',').forEach(item => {
|
||||
const array = item.trim().split(' ')
|
||||
sort.push({
|
||||
column: array[0],
|
||||
sort: array[1]
|
||||
})
|
||||
})
|
||||
this.configure.sort = sort;
|
||||
let title = dataType;
|
||||
if (isKey === 'PRI') {
|
||||
if (extra) {
|
||||
title = `${title} (${extra.replace('_', ' ')})`;
|
||||
}
|
||||
else {
|
||||
const sort: Array<Sort> = new Array<Sort>();
|
||||
const array = value.trim().split(' ')
|
||||
sort.push({
|
||||
column: array[0],
|
||||
sort: array[1]
|
||||
})
|
||||
this.configure.sort = sort;
|
||||
title = `${title}`;
|
||||
}
|
||||
this.tableSortColumns = this.configure.sort;
|
||||
}
|
||||
|
||||
if (this.currentWhere) {
|
||||
this.configure.where = this.currentWhere;
|
||||
if (defaultValue && defaultValue !== 'null') {
|
||||
title = `${title} = ${defaultValue}`
|
||||
}
|
||||
this.handlerExecute();
|
||||
return title;
|
||||
},
|
||||
handlerOnSorted(sort: Array<Sort>)
|
||||
resolveTableComponent(h, data: { comment: undefined; title: undefined })
|
||||
{
|
||||
this.configure.sort = sort;
|
||||
this.tableSortColumns = sort;
|
||||
this.currentOrder.inputValue = join(sort.map(item => item.column + ' ' + item.sort));
|
||||
this.handlerExecute();
|
||||
},
|
||||
handlerControlModal(value: boolean)
|
||||
{
|
||||
this.modalVisible = !value;
|
||||
},
|
||||
handlerOnSelected(nodes: Array<any>)
|
||||
{
|
||||
this.selectedRows = nodes;
|
||||
},
|
||||
handlerCopyWith(withHeaders: boolean)
|
||||
{
|
||||
const headers = [];
|
||||
const copyRows = [];
|
||||
this.selectedRows.forEach(row => {
|
||||
const values = [];
|
||||
Object.keys(row)
|
||||
.forEach(key => {
|
||||
headers.push(key);
|
||||
values.push(row[key]);
|
||||
});
|
||||
copyRows.push(join(values, ','));
|
||||
});
|
||||
if (withHeaders) {
|
||||
copyRows.unshift(join(headers, ','));
|
||||
if (data.comment) {
|
||||
return h(resolveComponent('Tooltip'), {
|
||||
content: data.comment,
|
||||
placement: 'bottom-start',
|
||||
transfer: true,
|
||||
delay: 1000
|
||||
},
|
||||
h('span', data.title));
|
||||
}
|
||||
else {
|
||||
return h('span', data.title);
|
||||
}
|
||||
useClipboard()
|
||||
.toClipboard(join(copyRows, '\n'))
|
||||
.then(() => this.$Message.info('Copy Successfully'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,347 +0,0 @@
|
||||
<template>
|
||||
<div style="padding: 0">
|
||||
<CircularLoading v-if="loading"
|
||||
:show="loading">
|
||||
</CircularLoading>
|
||||
<div v-else
|
||||
ref="splitContainer"
|
||||
class="split-container">
|
||||
<Split v-model="splitValue"
|
||||
:min="0.15">
|
||||
<template #left>
|
||||
<div ref="splitContainerLeftPane"
|
||||
class="split-container-pane">
|
||||
<Card style="width:100%;"
|
||||
:padding="0"
|
||||
:bordered="false"
|
||||
dis-hover>
|
||||
<template #title>
|
||||
<Select v-model="applyValue.database"
|
||||
@on-change="handlerChangeDatabase">
|
||||
<Option v-for="item in databaseArray"
|
||||
:value="item.applyId"
|
||||
:key="item.title">
|
||||
<FontAwesomeIcon icon="database"
|
||||
style="margin-right: 6px;">
|
||||
</FontAwesomeIcon>
|
||||
{{ item.title }}
|
||||
</Option>
|
||||
</Select>
|
||||
</template>
|
||||
<div style="height: 470px; overflow: auto;">
|
||||
<Tree :data="dataTreeArray"
|
||||
style="margin-left: 6px;"
|
||||
:load-data="handlerLoadChildData"
|
||||
@on-select-change="handlerSelectNode">
|
||||
</Tree>
|
||||
<CircularLoading v-if="dataTreeLoading"
|
||||
:show="dataTreeLoading">
|
||||
</CircularLoading>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
<template #right>
|
||||
<Card v-if="!applyValue.node"
|
||||
padding="0 10"
|
||||
:bordered="false"
|
||||
dis-hover>
|
||||
<Result type="warning"
|
||||
:title="$t('tooltip.notSelectedNodeTitle')">
|
||||
<template #desc>
|
||||
<span>{{ $t('tooltip.notSelectedNodeDesc') }}</span>
|
||||
</template>
|
||||
</Result>
|
||||
</Card>
|
||||
<Card v-else
|
||||
style="width:100%;"
|
||||
padding="0 10"
|
||||
:bordered="false"
|
||||
:title="null"
|
||||
dis-hover>
|
||||
<Tabs v-model="applyValue.tabType"
|
||||
:animated="false">
|
||||
<TabPane :label="tabPane.info"
|
||||
name="info">
|
||||
<TableInfo v-if="applyValue.tabType === 'info'"
|
||||
:id="applyValue.node.applyId">
|
||||
</TableInfo>
|
||||
</TabPane>
|
||||
<TabPane :label="tabPane.data"
|
||||
name="data">
|
||||
<TableData v-if="applyValue.tabType === 'data'"
|
||||
:id="applyValue.node.applyId">
|
||||
</TableData>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</template>
|
||||
</Split>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent, resolveComponent} from "vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {toNumber} from "lodash";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import DatabaseService from "@/services/Database";
|
||||
import TableService from "@/services/Table";
|
||||
import ColumnService from "@/services/Column";
|
||||
import CircularLoading from "@/components/loading/CircularLoading.vue";
|
||||
import {DataStructureModel} from "@/model/DataStructure";
|
||||
import {DataStructureEnum} from "@/enum/DataStructure";
|
||||
import TableInfo from "@/views/admin/source/components/TableInfo.vue";
|
||||
import TableData from "@/views/admin/source/components/TableData.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "SourceManagerBeta",
|
||||
components: {TableData, TableInfo, CircularLoading},
|
||||
setup()
|
||||
{
|
||||
const i18n = useI18n();
|
||||
const resolveTabPaneComponent = (h, icon: string, key: string) => {
|
||||
return h('div', [
|
||||
h(resolveComponent('FontAwesomeIcon'), {
|
||||
icon: icon,
|
||||
style: {fontSize: '25px'}
|
||||
}),
|
||||
h('p', {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
}
|
||||
},
|
||||
i18n.t(key))
|
||||
])
|
||||
}
|
||||
return {
|
||||
i18n,
|
||||
resolveTabPaneComponent
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
loading: false,
|
||||
dataTreeLoading: false,
|
||||
splitValue: 0.15,
|
||||
databaseArray: Array<DataStructureModel>(),
|
||||
dataTreeArray: Array<DataStructureModel>(),
|
||||
applyValue: {
|
||||
database: null,
|
||||
node: null as DataStructureModel,
|
||||
tabType: 'info'
|
||||
},
|
||||
tabPane: {
|
||||
info: (h) => this.resolveTabPaneComponent(h, 'circle-info', 'common.info'),
|
||||
data: (h) => this.resolveTabPaneComponent(h, 'table', 'common.data'),
|
||||
}
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.handlerInitialize();
|
||||
},
|
||||
methods: {
|
||||
handlerInitialize()
|
||||
{
|
||||
this.loading = true;
|
||||
const router = useRouter();
|
||||
const id = router.currentRoute?.value?.params['id'];
|
||||
DatabaseService.getAllBySource(toNumber(id))
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
response.data.forEach((item: { name: null; catalog: null; id: null }) => {
|
||||
const structure = new DataStructureModel();
|
||||
structure.title = item.name;
|
||||
structure.catalog = item.catalog;
|
||||
structure.applyId = item.id;
|
||||
this.databaseArray.push(structure);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handlerChangeDatabase()
|
||||
{
|
||||
this.dataTreeLoading = true;
|
||||
this.dataTreeArray = [];
|
||||
TableService.getAllByDatabase(this.applyValue.database)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
response.data.forEach((item: {
|
||||
name: null;
|
||||
title: null;
|
||||
catalog: null;
|
||||
id: null;
|
||||
type: null;
|
||||
engine: null;
|
||||
comment: null;
|
||||
database: { name: null };
|
||||
}) => {
|
||||
const structure = new DataStructureModel();
|
||||
structure.title = item.name;
|
||||
structure.database = item.database.name;
|
||||
structure.catalog = item.catalog;
|
||||
structure.applyId = item.id;
|
||||
structure.type = item.type;
|
||||
structure.level = DataStructureEnum.TABLE;
|
||||
structure.engine = item.engine;
|
||||
structure.comment = item.comment;
|
||||
structure.origin = item;
|
||||
structure.render = (h, {data}) => {
|
||||
return h('div', [
|
||||
h('span', [
|
||||
h(resolveComponent('FontAwesomeIcon'), {
|
||||
icon: "table",
|
||||
style: {marginRight: '6px'}
|
||||
}),
|
||||
this.resolveTableComponent(h, data)
|
||||
])
|
||||
]);
|
||||
}
|
||||
this.dataTreeArray.push(structure);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.dataTreeLoading = false;
|
||||
});
|
||||
},
|
||||
handlerLoadChildData(item: DataStructureModel, callback)
|
||||
{
|
||||
const dataChildArray = [];
|
||||
if (item.level === DataStructureEnum.COLUMN) {
|
||||
callback(dataChildArray);
|
||||
return;
|
||||
}
|
||||
ColumnService.getAllByTable(item.applyId)
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
response.data.forEach((item: {
|
||||
name: null;
|
||||
title: null;
|
||||
catalog: null;
|
||||
id: null;
|
||||
type: null;
|
||||
dataType: null;
|
||||
extra: null;
|
||||
engine: null;
|
||||
isKey: null;
|
||||
defaultValue: null;
|
||||
table: { name: null, database: { name: null } };
|
||||
}) => {
|
||||
const structure = new DataStructureModel();
|
||||
structure.title = item.name;
|
||||
structure.database = item.table.database.name;
|
||||
structure.table = item.table.name;
|
||||
structure.catalog = item.catalog;
|
||||
structure.applyId = item.id;
|
||||
structure.level = DataStructureEnum.COLUMN;
|
||||
structure.type = item.type;
|
||||
structure.extra = item.extra;
|
||||
structure.dataType = item.dataType;
|
||||
structure.engine = item.engine;
|
||||
structure.isKey = item.isKey;
|
||||
structure.defaultValue = item.defaultValue;
|
||||
structure.render = (h, {data}) => {
|
||||
return h('div', [
|
||||
h('span', [
|
||||
h(resolveComponent('FontAwesomeIcon'), {
|
||||
icon: this.getColumnIcon(data.isKey),
|
||||
style: {marginRight: '6px'}
|
||||
}),
|
||||
h('span', data.title),
|
||||
h('span', {
|
||||
style: {
|
||||
marginLeft: '6px',
|
||||
color: '#c5c8ce'
|
||||
},
|
||||
},
|
||||
this.getColumnTitle(data.type, data.extra, data.isKey, data.defaultValue)),
|
||||
])
|
||||
]);
|
||||
}
|
||||
dataChildArray.push(structure);
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
callback(dataChildArray);
|
||||
});
|
||||
},
|
||||
handlerSelectNode(node: Array<DataStructureModel>)
|
||||
{
|
||||
if (node.length === 0) {
|
||||
// Prevent selection clearing after repeated clicks
|
||||
this.applyValue.node.selected = true;
|
||||
return;
|
||||
}
|
||||
const currentNode = node[0];
|
||||
if (currentNode.level === DataStructureEnum.COLUMN) {
|
||||
this.applyValue.node.selected = true;
|
||||
currentNode.selected = false;
|
||||
return;
|
||||
}
|
||||
this.applyValue.node = currentNode;
|
||||
},
|
||||
getColumnIcon(type: string)
|
||||
{
|
||||
if (type === 'PRI') {
|
||||
return 'key';
|
||||
}
|
||||
else if (type === 'MUL') {
|
||||
return 'repeat';
|
||||
}
|
||||
else if (type === 'UNI') {
|
||||
return 'circle';
|
||||
}
|
||||
else {
|
||||
return 'columns';
|
||||
}
|
||||
},
|
||||
getColumnTitle(dataType: string, extra: string, isKey: string, defaultValue: string)
|
||||
{
|
||||
let title = dataType;
|
||||
if (isKey === 'PRI') {
|
||||
if (extra) {
|
||||
title = `${title} (${extra.replace('_', ' ')})`;
|
||||
}
|
||||
else {
|
||||
title = `${title}`;
|
||||
}
|
||||
}
|
||||
if (defaultValue && defaultValue !== 'null') {
|
||||
title = `${title} = ${defaultValue}`
|
||||
}
|
||||
return title;
|
||||
},
|
||||
resolveTableComponent(h, data: { comment: undefined; title: undefined })
|
||||
{
|
||||
if (data.comment) {
|
||||
return h(resolveComponent('Tooltip'), {
|
||||
content: data.comment,
|
||||
placement: 'bottom-start',
|
||||
transfer: true,
|
||||
delay: 1000
|
||||
},
|
||||
h('span', data.title));
|
||||
}
|
||||
else {
|
||||
return h('span', data.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.split-container {
|
||||
height: 510px;
|
||||
}
|
||||
|
||||
.split-container-pane {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@ -20,17 +20,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>${plugin.maven.nexus.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>datacap</artifactId>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
4
pom.xml
4
pom.xml
@ -4,7 +4,7 @@
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
|
||||
<modules>
|
||||
<module>client/datacap-cli</module>
|
||||
@ -152,7 +152,7 @@
|
||||
<plugin.maven.javadoc.version>3.6.0</plugin.maven.javadoc.version>
|
||||
<plugin.maven.gpg.version>1.6</plugin.maven.gpg.version>
|
||||
<plugin.maven.nexus.version>1.6.13</plugin.maven.nexus.version>
|
||||
<plugin.maven.dokka.version>1.8.10</plugin.maven.dokka.version>
|
||||
<plugin.maven.dokka.version>1.9.10</plugin.maven.dokka.version>
|
||||
<environment.compile.java.version>1.8</environment.compile.java.version>
|
||||
</properties>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap</artifactId>
|
||||
<version>1.16.0</version>
|
||||
<version>1.17.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user