提交 4891c38a authored 作者: taojinlong's avatar taojinlong

Merge branch 'main' of github.com:dataease/dataease into main

# Conflicts: # frontend/src/lang/zh.js # frontend/src/views/dataset/common/DatasetGroupSelector.vue
......@@ -73,6 +73,11 @@ public class DataSetTableController {
return dataSetTableService.getSQLPreview(dataSetTableRequest);
}
@PostMapping("customPreview")
public Map<String, Object> customPreview(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception {
return dataSetTableService.getCustomPreview(dataSetTableRequest);
}
@PostMapping("incrementalConfig")
public DatasetTableIncrementalConfig incrementalConfig(@RequestBody DatasetTableIncrementalConfig datasetTableIncrementalConfig) throws Exception {
return dataSetTableService.incrementalConfig(datasetTableIncrementalConfig);
......
package io.dataease.dto.dataset;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @Author gin
* @Date 2021/5/9 10:08 上午
*/
@Getter
@Setter
public class DataTableInfoCustomUnion {
private String tableId;
private List<String> checkedFields;
}
......@@ -3,6 +3,8 @@ package io.dataease.dto.dataset;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @Author gin
* @Date 2021/2/23 8:47 下午
......@@ -13,4 +15,5 @@ public class DataTableInfoDTO {
private String table;
private String sql;
private String data;// file path
private List<DataTableInfoCustomUnion> list;
}
......@@ -812,7 +812,9 @@ export default {
target_field: '被关联字段',
union_relation: '关联关系',
pls_setting_union_success: '请正确设置关联关系',
invalid_dataset:'Kettle未运行,无效数据集'
invalid_dataset:'Kettle未运行,无效数据集',
check_all: '全选',
can_not_union_self: '被关联表不能与关联表相同'
},
datasource: {
datasource: '数据源',
......
<template>
<el-col>
<el-row>
<el-row style="height: 26px;">
<span style="line-height: 26px;">
{{ $t('dataset.add_custom_table') }}
......@@ -9,29 +8,57 @@
<el-button size="mini" @click="cancel">
{{ $t('dataset.cancel') }}
</el-button>
<el-button size="mini" type="primary" :disabled="checkTableList.length < 1" @click="save">
<el-button :disabled="!name || checkedList.length === 0" size="mini" type="primary" @click="save">
{{ $t('dataset.confirm') }}
</el-button>
</el-row>
</el-row>
<el-divider />
<el-row>
<el-col>
自助数据集
<el-form :inline="true">
<el-form-item class="form-item">
<el-input v-model="name" size="mini" :placeholder="$t('commons.name')" />
</el-form-item>
</el-form>
</el-row>
<el-col style="display: flex;flex-direction: row">
<el-col class="panel-height" style="width: 220px;border-right:solid 1px #dcdfe6;border-top:solid 1px #dcdfe6;padding-right: 15px;overflow-y: auto;">
<dataset-group-selector :mode="1" :checked-list="checkedList" :union-data="unionData" @getTable="getTable" />
</el-col>
<el-col class="panel-height" style="width: 235px;border-top:solid 1px #dcdfe6;padding: 0 15px;overflow-y: auto;">
<dataset-custom-field :table="table" :checked-list="checkedList" @getChecked="getChecked" />
</el-col>
<el-col class="panel-height" style="flex: 1;">
<ux-grid
ref="plxTable"
size="mini"
style="width: 100%;"
:height="height"
:checkbox-config="{highlight: true}"
:width-resize="true"
>
<ux-table-column
v-for="field in fields"
:key="field.fieldName"
min-width="200px"
:field="field.fieldName"
:title="field.remarks"
:resizable="true"
/>
</ux-grid>
</el-col>
<el-col>
TODO
</el-col>
</el-row>
</el-row>
</el-col>
</template>
<script>
import { post } from '@/api/dataset/dataset'
import DatasetGroupSelector from '../common/DatasetGroupSelector'
import DatasetCustomField from '../common/DatasetCustomField'
export default {
name: 'AddCustom',
components: { DatasetCustomField, DatasetGroupSelector },
props: {
param: {
type: Object,
......@@ -40,62 +67,104 @@ export default {
},
data() {
return {
searchTable: '',
options: [],
dataSource: '',
tables: [],
checkTableList: [],
mode: '0',
tableData: []
name: '自助数据集',
table: {},
checkedList: [],
unionData: [],
height: 500,
data: [],
fields: []
}
},
watch: {
// dataSource(val) {
// if (val) {
// post('/datasource/getTables', { id: val }).then(response => {
// this.tables = response.data
// this.tableData = JSON.parse(JSON.stringify(this.tables))
// })
// }
// },
// searchTable(val) {
// if (val && val !== '') {
// this.tableData = JSON.parse(JSON.stringify(this.tables.filter(ele => { return ele.includes(val) })))
// } else {
// this.tableData = JSON.parse(JSON.stringify(this.tables))
// }
// }
'checkedList': function() {
// console.log(this.checkedList)
if (this.checkedList && this.checkedList.length > 0) {
// 根据第一个选择的数据集找到关联视图
post('dataset/union/listByTableId/' + this.checkedList[0].tableId, {}).then(response => {
// console.log(response)
this.unionData = response.data
})
} else {
this.unionData = []
}
}
},
mounted() {
// this.initDataSource()
},
activated() {
// this.initDataSource()
window.onresize = () => {
this.calHeight()
}
this.calHeight()
},
methods: {
// initDataSource() {
// listDatasource().then(response => {
// this.options = response.data
// })
// },
calHeight() {
const that = this
setTimeout(function() {
const currentHeight = document.documentElement.clientHeight
that.height = currentHeight - 56 - 15 - 26 - 25 - 43
}, 10)
},
save() {
// console.log(this.checkTableList);
// console.log(this.scene);
const sceneId = this.param.id
const dataSourceId = this.dataSource
const tables = []
// const mode = this.mode
this.checkTableList.forEach(function(name) {
tables.push({
name: name,
sceneId: sceneId,
dataSourceId: dataSourceId,
type: 'excel',
mode: 1
getTable(table) {
// console.log(table)
this.table = table
},
getChecked(tableCheckedField) {
// console.log(tableCheckedField)
if (tableCheckedField.checkedFields && tableCheckedField.checkedFields.length > 0) {
if (!this.checkedList.some(ele => ele.tableId === tableCheckedField.tableId)) {
this.checkedList.push(tableCheckedField)
} else {
this.checkedList.forEach(ele => {
if (ele.tableId === tableCheckedField.tableId) {
ele.checkedFields = tableCheckedField.checkedFields
}
})
}
} else {
let index = -1
for (let i = 0; i < this.checkedList.length; i++) {
if (this.checkedList[i].tableId === tableCheckedField.tableId) {
index = i
break
}
}
if (index > -1) {
this.checkedList.splice(index, 1)
}
}
// console.log(this.checkedList)
// request to get data
if (this.checkedList.length > 0) {
const table = {
id: this.param.tableId,
name: this.name,
sceneId: this.param.id,
dataSourceId: null,
type: 'custom',
mode: 1,
info: '{"list":' + JSON.stringify(this.checkedList) + '}'
}
post('/dataset/table/customPreview', table).then(response => {
console.log(response)
this.fields = response.data.fields
this.data = response.data.data
const datas = this.data
this.$refs.plxTable.reloadData(datas)
})
post('/dataset/table/batchAdd', tables).then(response => {
}
},
save() {
const table = {
id: this.param.tableId,
name: this.name,
sceneId: this.param.id,
dataSourceId: null,
type: 'custom',
mode: 1,
info: '{"list":' + JSON.stringify(this.checkedList) + '}'
}
post('/dataset/table/update', table).then(response => {
this.$store.dispatch('dataset/setSceneData', new Date().getTime())
this.cancel()
})
......@@ -103,16 +172,11 @@ export default {
cancel() {
this.dataReset()
// this.$router.push('/dataset/home')
this.$emit('switchComponent', { name: '' })
},
dataReset() {
this.searchTable = ''
this.options = []
this.dataSource = ''
this.tables = []
this.checkTableList = []
}
}
......@@ -141,4 +205,8 @@ export default {
span{
font-size: 14px;
}
.panel-height{
height: calc(100vh - 56px - 15px - 26px - 25px - 43px);
}
</style>
<template>
<el-col>
<el-checkbox v-model="checkAll" :disabled="!(fields.length > 0)" :indeterminate="isIndeterminate" @change="handleCheckAllChange">{{ $t('dataset.check_all') }}</el-checkbox>
<el-checkbox-group v-model="checkedFields" @change="handleCheckedFieldsChange">
<el-checkbox v-for="f in fields" :key="f.id" :label="f.id" style="display: block;margin-top: 4px;width: 100%;">
<span style="display: flex;flex-direction: row;flex: 1;">
<span>
<span v-if="f.deType === 0">
<svg-icon v-if="f.deType === 0" icon-class="field_text" class="field-icon-text" />
</span>
<span v-if="f.deType === 1">
<svg-icon v-if="f.deType === 1" icon-class="field_time" class="field-icon-time" />
</span>
<span v-if="f.deType === 2 || f.deType === 3">
<svg-icon v-if="f.deType === 2 || f.deType === 3" icon-class="field_value" class="field-icon-value" />
</span>
</span>
<span style="display: flex;flex: 1;width: 100%;">
<span style="text-overflow: ellipsis;white-space: nowrap;overflow: hidden;width: 160px;">{{ f.name }}</span>
</span>
</span>
</el-checkbox>
</el-checkbox-group>
</el-col>
</template>
<script>
import { fieldList } from '../../../api/dataset/dataset'
export default {
name: 'DatasetCustomField',
props: {
table: {
type: Object,
required: true
},
checkedList: {
type: Array,
required: true
}
},
data() {
return {
fields: [],
checkAll: false,
checkedFields: [],
isIndeterminate: false
}
},
watch: {
'table': function() {
fieldList(this.table.id).then(response => {
this.fields = response.data
this.checkedFields = []
this.checkedList.forEach(ele => {
if (ele.tableId === this.table.id) {
this.checkedFields = ele.checkedFields
}
})
const checkedCount = this.checkedFields.length
this.checkAll = checkedCount === this.fields.length
this.isIndeterminate = checkedCount > 0 && checkedCount < this.fields.length
})
}
},
mounted() {
this.initField()
},
methods: {
initField() {
if (this.table.id) {
fieldList(this.table.id).then(response => {
this.fields = response.data
})
}
},
handleCheckAllChange(val) {
this.checkedFields = val ? this.fields.map(ele => {
return ele.id
}) : []
this.isIndeterminate = false
this.getChecked()
},
handleCheckedFieldsChange(value) {
const checkedCount = value.length
this.checkAll = checkedCount === this.fields.length
this.isIndeterminate = checkedCount > 0 && checkedCount < this.fields.length
this.getChecked()
},
getChecked() {
this.$emit('getChecked', { tableId: this.table.id, checkedFields: this.checkedFields })
}
}
}
</script>
<style scoped>
</style>
......@@ -83,7 +83,7 @@
@node-click="sceneClick"
>
<span slot-scope="{ node, data }" class="custom-tree-node-list">
<span style="display: flex;flex: 1;width: 0;">
<span :id="data.id" style="display: flex;flex: 1;width: 0;">
<span>
<svg-icon v-if="data.type === 'db'" icon-class="ds-db" class="ds-icon-db" />
<svg-icon v-if="data.type === 'sql'" icon-class="ds-sql" class="ds-icon-sql" />
......@@ -107,6 +107,23 @@ import {isKettleRunning, post} from '@/api/dataset/dataset'
export default {
name: 'DatasetGroupSelector',
props: {
mode: {
type: Number,
required: false,
default: -1
},
unionData: {
type: Array,
required: false,
default: null
},
checkedList: {
type: Array,
required: false,
default: null
}
},
data() {
return {
isKettleRunning: false,
......@@ -133,6 +150,9 @@ export default {
},
computed: {},
watch: {
'unionData': function() {
this.unionDataChange()
},
search(val) {
if (val && val !== '') {
this.tableData = JSON.parse(JSON.stringify(this.tables.filter(ele => { return ele.name.includes(val) })))
......@@ -188,7 +208,8 @@ export default {
if (this.currGroup) {
post('/dataset/table/list', {
sort: 'type asc,create_time desc,name asc',
sceneId: this.currGroup.id
sceneId: this.currGroup.id,
mode: this.mode < 0 ? null : this.mode
}).then(response => {
this.tables = response.data
for (let i = 0; i < this.tables.length; i++) {
......@@ -197,6 +218,10 @@ export default {
}
}
this.tableData = JSON.parse(JSON.stringify(this.tables))
this.$nextTick(function() {
this.unionDataChange()
})
})
}
},
......@@ -232,6 +257,40 @@ export default {
return
}
this.$emit('getTable', data)
},
unionDataChange() {
if (!this.sceneMode) {
return
}
if (!this.checkedList || this.checkedList.length === 0) {
this.tableData.forEach(ele => {
const span = document.getElementById(ele.id).parentNode
const div1 = span.parentNode
const div2 = div1.parentNode
span.style.removeProperty('color')
div1.style.removeProperty('cursor')
div2.style.removeProperty('pointer-events')
})
return
}
const tableList = this.tableData.map(ele => {
return ele.id
})
const unionList = this.unionData.map(ele => {
return ele.targetTableId
})
unionList.push(this.checkedList[0].tableId)
const notUnionList = tableList.concat(unionList).filter(v => tableList.includes(v) && !unionList.includes(v))
notUnionList.forEach(ele => {
const span = document.getElementById(ele).parentNode
const div1 = span.parentNode
const div2 = div1.parentNode
span.style.setProperty('color', '#c0c4cc')
div1.style.setProperty('cursor', 'not-allowed')
div2.style.setProperty('pointer-events', 'none')
})
}
}
}
......
......@@ -90,7 +90,7 @@
width="500"
trigger="click"
>
<dataset-group-selector @getTable="getTable" />
<dataset-group-selector :mode="1" @getTable="getTable" />
<el-button slot="reference" size="mini">{{ targetTable.name || $t('dataset.pls_slc_union_table') }}</el-button>
</el-popover>
......@@ -169,10 +169,12 @@ export default {
},
methods: {
initUnion() {
if (this.table.id) {
post('dataset/union/listByTableId/' + this.table.id, {}).then(response => {
// console.log(response)
this.unionData = response.data
})
}
},
showUnionEdit() {
......@@ -183,7 +185,7 @@ export default {
this.editUnion = true
},
saveUnion() {
console.log(this.union)
// console.log(this.union)
if (!this.union.sourceTableFieldId || !this.union.sourceUnionRelation || !this.union.targetTableId || !this.union.targetTableFieldId) {
this.$message({
type: 'error',
......@@ -245,6 +247,14 @@ export default {
},
getTable(param) {
// console.log(param)
if (param.id === this.table.id) {
this.$message({
type: 'error',
message: this.$t('dataset.can_not_union_self'),
showClose: true
})
return
}
this.targetTable = param
this.union.targetTableId = param.id
this.union.targetTableFieldId = ''
......
......@@ -31,7 +31,7 @@
<el-tab-pane :label="$t('dataset.data_preview')" name="dataPreview">
<tab-data-preview :table="table" :fields="fields" :data="data" :page="page" :form="tableViewRowForm" @reSearch="reSearch" />
</el-tab-pane>
<el-tab-pane :label="$t('dataset.join_view')" name="joinView">
<el-tab-pane v-if="table.type !== 'custom'" :label="$t('dataset.join_view')" name="joinView">
<union-view :table="table" />
</el-tab-pane>
<el-tab-pane v-if="table.mode === 1 && (table.type === 'db' || table.type === 'sql')" :label="$t('dataset.update_info')" name="updateInfo">
......
......@@ -76,6 +76,7 @@ export default {
.ms-main-container {
height: calc(100vh - 56px);
padding: 15px 15px 0 15px;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论