feat(数据集): 【SQL数据集】增加执行记录

This commit is contained in:
taojinlong 2022-10-28 18:22:01 +08:00
parent ecd534dcf4
commit c59585ac5b
7 changed files with 296 additions and 12 deletions

View File

@ -1,5 +1,7 @@
package io.dataease.controller.dataset;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.auth.annotation.DeLog;
import io.dataease.auth.annotation.DePermission;
@ -7,10 +9,14 @@ import io.dataease.auth.annotation.DePermissions;
import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.constants.ResourceAuthLevel;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.controller.ResultHolder;
import io.dataease.controller.request.dataset.DataSetTableRequest;
import io.dataease.controller.response.DataSetDetail;
import io.dataease.dto.dataset.DataSetTableDTO;
import io.dataease.dto.dataset.ExcelFileData;
import io.dataease.plugins.common.base.domain.DatasetSqlLog;
import io.dataease.plugins.common.base.domain.DatasetTable;
import io.dataease.plugins.common.base.domain.DatasetTableField;
import io.dataease.plugins.common.base.domain.DatasetTableIncrementalConfig;
@ -152,10 +158,21 @@ public class DataSetTableController {
@DePermission(type = DePermissionType.DATASET, value = "id", level = ResourceAuthLevel.DATASET_LEVEL_USE),
@DePermission(type = DePermissionType.DATASOURCE, value = "dataSourceId", level = ResourceAuthLevel.DATASOURCE_LEVEL_USE)
}, logical = Logical.AND)
public Map<String, Object> getSQLPreview(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception {
public ResultHolder getSQLPreview(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception {
return dataSetTableService.getSQLPreview(dataSetTableRequest);
}
@ApiOperation("根据sql查询预览数据")
@PostMapping("sqlLog/{goPage}/{pageSize}")
@DePermissions(value = {
@DePermission(type = DePermissionType.DATASET, value = "id", level = ResourceAuthLevel.DATASET_LEVEL_USE),
@DePermission(type = DePermissionType.DATASOURCE, value = "dataSourceId", level = ResourceAuthLevel.DATASOURCE_LEVEL_USE)
}, logical = Logical.AND)
public Pager<List<DatasetSqlLog>> getSQLLog(@RequestBody DataSetTableRequest dataSetTableRequest, @PathVariable int goPage, @PathVariable int pageSize) throws Exception {
Page<DatasetSqlLog> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, dataSetTableService.getSQLLog(dataSetTableRequest));
}
@ApiOperation("预览自定义数据数据")
@PostMapping("customPreview")
public Map<String, Object> customPreview(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception {

View File

@ -10,6 +10,7 @@ import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.constants.*;
import io.dataease.commons.exception.DEException;
import io.dataease.commons.utils.*;
import io.dataease.controller.ResultHolder;
import io.dataease.controller.request.dataset.DataSetGroupRequest;
import io.dataease.controller.request.dataset.DataSetTableRequest;
import io.dataease.controller.request.dataset.DataSetTaskRequest;
@ -131,6 +132,8 @@ public class DataSetTableService {
private PermissionsTreeService permissionsTreeService;
@Resource
private DatasourceService datasourceService;
@Resource
private DatasetSqlLogMapper datasetSqlLogMapper;
private static boolean isUpdatingDatasetTableStatus = false;
private static final String lastUpdateTime = "${__last_update_time__}";
@ -1175,9 +1178,22 @@ public class DataSetTableService {
return map;
}
public Map<String, Object> getSQLPreview(DataSetTableRequest dataSetTableRequest) throws Exception {
public List<DatasetSqlLog> getSQLLog(DataSetTableRequest dataSetTableRequest) {
if (StringUtils.isEmpty(dataSetTableRequest.getId())) {
return new ArrayList<>();
}
DatasetSqlLogExample example = new DatasetSqlLogExample();
example.createCriteria().andDatasetIdEqualTo(dataSetTableRequest.getId());
example.setOrderByClause(" start_time desc ");
return datasetSqlLogMapper.selectByExample(example);
}
public ResultHolder getSQLPreview(DataSetTableRequest dataSetTableRequest) throws Exception {
DatasetSqlLog datasetSqlLog = new DatasetSqlLog();
DataTableInfoDTO dataTableInfo = new Gson().fromJson(dataSetTableRequest.getInfo(), DataTableInfoDTO.class);
String sql = dataTableInfo.isBase64Encryption() ? new String(java.util.Base64.getDecoder().decode(dataTableInfo.getSql())) : dataTableInfo.getSql();
datasetSqlLog.setSql(sql);
Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId());
if (ds == null) {
throw new Exception(Translator.get("i18n_invalid_ds"));
@ -1202,7 +1218,25 @@ public class DataSetTableService {
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
String sqlAsTable = qp.createSQLPreview(sql, null);
datasourceRequest.setQuery(sqlAsTable);
Map<String, List> result = datasourceProvider.fetchResultAndField(datasourceRequest);
Map<String, List> result = new HashMap<>();
try {
datasetSqlLog.setStartTime(System.currentTimeMillis());
result = datasourceProvider.fetchResultAndField(datasourceRequest);
datasetSqlLog.setEndTime(System.currentTimeMillis());
datasetSqlLog.setSpend(datasetSqlLog.getEndTime() - datasetSqlLog.getStartTime());
datasetSqlLog.setStatus("Completed");
} catch (Exception e) {
datasetSqlLog.setStatus("Error");
return ResultHolder.error(e.getMessage(), datasetSqlLog);
} finally {
if (StringUtils.isNotEmpty(dataSetTableRequest.getId())) {
datasetSqlLog.setDatasetId(dataSetTableRequest.getId());
datasetSqlLog.setId(UUID.randomUUID().toString());
datasetSqlLogMapper.insert(datasetSqlLog);
}
}
List<String[]> data = result.get("dataList");
List<TableField> fields = result.get("fieldList");
String[] fieldArray = fields.stream().map(TableField::getFieldName).toArray(String[]::new);
@ -1223,8 +1257,9 @@ public class DataSetTableService {
Map<String, Object> map = new HashMap<>();
map.put("fields", fields);
map.put("data", jsonArray);
map.put("log", datasetSqlLog);
return map;
return ResultHolder.success(map);
}
public Map<String, Object> getUnionPreview(DataSetTableRequest dataSetTableRequest) throws Exception {

View File

@ -42,3 +42,14 @@ VALUES ('Apache Kylin 数据源插件', 'default', '0', '0', 'datasource', 'Apac
INSERT INTO `sys_msg_channel` (`msg_channel_id`, `channel_name`, `service_name`) VALUES ('6', 'webmsg.channel_larksuite_msg', 'sendLarksuite');
CREATE TABLE `dataset_sql_log` (
`id` varchar(50) NOT NULL DEFAULT '' COMMENT 'ID',
`dataset_id` varchar(50) NOT NULL DEFAULT '' COMMENT '数据集ID',
`start_time` bigint(13) DEFAULT NULL COMMENT '开始时间',
`end_time` bigint(13) DEFAULT NULL COMMENT '结束时间',
`spend` bigint(13) DEFAULT NULL COMMENT '耗时(毫秒)',
`sql` longtext NOT NULL COMMENT '详细信息',
`status` varchar(45) DEFAULT NULL COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1436,6 +1436,9 @@ export default {
percent: 'Percent'
},
dataset: {
spend_time: 'Spend',
sql: 'SQL',
sql_result: 'Result',
parse_filed: 'Parse Field',
field_rename: 'Rename Field',
params_work: 'Effective only when editing SQL',

View File

@ -1436,6 +1436,9 @@ export default {
percent: '占比'
},
dataset: {
spend_time: '耗時',
sql: 'SQL 語句',
sql_result: '運行結果',
parse_filed: '解析字段',
field_rename: '字段重命名',
params_work: '僅在編輯 sql 時生效',

View File

@ -1435,6 +1435,9 @@ export default {
percent: '占比'
},
dataset: {
spend_time: '耗时',
sql: 'SQL 语句',
sql_result: '运行结果',
parse_filed: '解析字段',
field_rename: '字段重命名',
params_work: '仅在编辑sql时生效',

View File

@ -208,8 +208,149 @@
@input="onCmCodeChange"
/>
</div>
<el-tabs
v-model="tabActive"
@tab-click="changeTab"
>
<el-tab-pane
:label="$t('dataset.task.list')"
name="result"
/>
<el-tab-pane
:label="$t('dataset.task.record')"
name="execLog"
/>
</el-tabs>
<div class="sql-result">
<div
v-show="tabActive === 'execLog'"
class="table-container"
>
<grid-table
v-if="param.tableId"
v-loading="loading"
:table-data="data"
:columns="[]"
:pagination="paginationConfig"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
<el-table-column
key="startTime"
min-width="200px"
prop="startTime"
:label="$t('dataset.start_time')"
>
<template slot-scope="scope">
<span>{{ scope.row.startTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
key="startTime"
min-width="200px"
prop="sql"
:label="$t('dataset.sql')"
/>
<el-table-column
key="startTime"
min-width="200px"
prop="spend"
:label="$t('dataset.spend_time')"
/>
<el-table-column
key="startTime"
min-width="200px"
prop="status"
:label="$t('dataset.sql_result')"
>
<template slot-scope="scope">
<span
v-if="scope.row.status"
:class="[`de-${scope.row.status}-pre`, 'de-status']"
>{{ $t(`dataset.${scope.row.status.toLocaleLowerCase()}`) }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
slot="__operation"
key="__operation"
:label="$t('commons.operating')"
fixed="right"
width="100"
>
<template slot-scope="scope">
<el-button
class="de-text-btn mar3 mar6"
type="text"
@click="copy(scope.row.sql)"
>
{{ $t("commons.copy") }}
</el-button>
</template>
</el-table-column>
</grid-table>
<ux-grid
v-else
ref="tableLog"
size="mini"
style="width: 100%"
:height="height"
:checkbox-config="{ highlight: true }"
:width-resize="true"
>
<ux-table-column
key="startTime"
min-width="200px"
field="startTime"
:title="$t('dataset.start_time')"
:resizable="true"
>
<template slot-scope="scope">
<span>{{ scope.row.startTime | timestampFormatDate }}</span>
</template>
</ux-table-column>
<ux-table-column
key="startTime"
min-width="200px"
field="sql"
:title="$t('dataset.sql')"
:resizable="true"
/>
<ux-table-column
key="startTime"
min-width="200px"
field="spend"
:title="$t('dataset.spend_time')"
:resizable="true"
/>
<ux-table-column
key="startTime"
min-width="200px"
field="status"
:title="$t('dataset.sql_result')"
:resizable="true"
>
<template slot-scope="scope">
<span
v-if="scope.row.status"
:class="[`de-${scope.row.status}-pre`, 'de-status']"
>{{ $t(`dataset.${scope.row.status.toLocaleLowerCase()}`) }}
</span>
<span v-else>-</span>
</template>
</ux-table-column>
</ux-grid>
</div>
<div
v-show="tabActive === 'result'"
class="sql-result"
>
<div class="sql-title">
{{ $t('deDataset.running_results') }}
<span class="result-num">{{
@ -456,9 +597,10 @@ import { engineMode } from '@/api/system/engine'
import msgCfm from '@/components/msgCfm/index'
import cancelMix from './cancelMix'
import _ from 'lodash'
import GridTable from '@/components/gridTable/index.vue'
export default {
name: 'AddSQL',
components: { codemirror },
components: { codemirror, GridTable },
mixins: [msgCfm, cancelMix],
props: {
param: {
@ -468,6 +610,13 @@ export default {
},
data() {
return {
tabActive: 'result',
paginationConfig: {
currentPage: 1,
pageSize: 10,
total: 0
},
data: [],
dataSource: '',
loading: false,
dataTable: '',
@ -586,12 +735,31 @@ export default {
this.initTableInfo()
},
created() {
console.log(this.param)
this.kettleState()
engineMode().then((res) => {
this.engineMode = res.data
})
},
methods: {
copy(text) {
this.$copyText(text).then((e) => {
this.openMessageSuccess('commons.copy_success')
}, (e) => {
this.openMessageSuccess('commons.copy_success')
})
},
changeTab() {
},
handleSizeChange(pageSize) {
this.paginationConfig.currentPage = 1
this.paginationConfig.pageSize = pageSize
this.listSqlLog()
},
handleCurrentChange(currentPage) {
this.paginationConfig.currentPage = currentPage
this.listSqlLog()
},
getField(name) {
post('/dataset/table/getFields', {
dataSourceId: this.dataSource,
@ -687,7 +855,6 @@ export default {
})
}
},
getSQLPreview() {
this.errMsg = false
this.errMsgCont = ''
@ -700,6 +867,7 @@ export default {
this.fields = []
this.$refs.plxTable?.reloadData([])
post('/dataset/table/sqlPreview', {
id: this.param.tableId,
dataSourceId: this.dataSource,
type: 'sql',
mode: parseInt(this.mode),
@ -710,17 +878,49 @@ export default {
})
}, true, 60000, true)
.then((response) => {
this.fields = response.data.fields
this.$nextTick(() => {
this.$refs.plxTable?.reloadData(response.data.data)
})
if (response.success) {
this.fields = response.data.fields
this.$nextTick(() => {
this.$refs.plxTable?.reloadData(response.data.data)
})
if (!this.param.tableId) {
this.data.unshift(response.data.log)
this.$refs.tableLog?.reloadData(this.data)
} else {
this.listSqlLog()
}
} else {
this.errMsgCont = response.message
this.errMsg = true
if (!this.param.tableId) {
this.data.unshift(response.data)
this.$refs.tableLog?.reloadData(this.data)
} else {
this.listSqlLog()
}
}
})
.catch((err, msg) => {
.catch((err, msg, response) => {
this.errMsgCont = err
this.errMsg = true
if (!this.param.tableId) {
this.data.unshift(response.data)
this.$refs.tableLog?.reloadData(this.data)
} else {
this.listSqlLog()
}
})
},
listSqlLog() {
post('/dataset/table/sqlLog/' + this.paginationConfig.currentPage + '/' + this.paginationConfig.pageSize, { id: this.param.tableId, dataSourceId: this.dataSource })
.then((response) => {
this.data = response.data.listObject
this.paginationConfig.total = response.data.itemCount
})
.catch(() => {
})
},
save() {
if (!this.dataSource || this.datasource === '') {
this.openMessageSuccess('dataset.pls_slc_data_source', 'error')
@ -1062,5 +1262,17 @@ export default {
}
}
}
.table-container {
height: calc(100% - 50px);
.mar6 {
margin-right: 6px;
}
.mar3 {
margin-left: -3px;
}
}
.table-container-filter {
height: calc(100% - 110px);
}
}
</style>