更新前端src/views/viewsnew/application/service/dataset目录文件

This commit is contained in:
limengnan 2025-06-24 14:58:42 +08:00
parent 2bbd4f5787
commit 56a68a0602
10 changed files with 394 additions and 212 deletions

View File

@ -3,7 +3,7 @@ import dvPreviewDownload from '@/assets/svg/icon_download_outlined.svg'
import deDelete from '@/assets/svg/de-delete.svg' import deDelete from '@/assets/svg/de-delete.svg'
import icon_fileExcel_colorful from '@/assets/svg/icon_file-excel_colorful.svg' import icon_fileExcel_colorful from '@/assets/svg/icon_file-excel_colorful.svg'
import icon_refresh_outlined from '@/assets/svg/icon_refresh_outlined.svg' import icon_refresh_outlined from '@/assets/svg/icon_refresh_outlined.svg'
import { ref, h, onUnmounted, computed } from 'vue' import { ref, h, onUnmounted, computed, reactive } from 'vue'
import { EmptyBackground } from '@/components/empty-background' import { EmptyBackground } from '@/components/empty-background'
import { ElButton, ElMessage, ElMessageBox, ElTabPane, ElTabs } from 'element-plus-secondary' import { ElButton, ElMessage, ElMessageBox, ElTabPane, ElTabs } from 'element-plus-secondary'
import { RefreshLeft } from '@element-plus/icons-vue' import { RefreshLeft } from '@element-plus/icons-vue'
@ -12,7 +12,9 @@ import {
exportRetry, exportRetry,
exportDelete, exportDelete,
exportDeleteAll, exportDeleteAll,
exportDeletePost exportDeletePost,
exportTasksRecords,
generateDownloadUri
} from '@/api/dataset' } from '@/api/dataset'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
@ -22,6 +24,13 @@ import { useLinkStoreWithOut } from '@/store/modules/link'
import { useAppStoreWithOut } from '@/store/modules/app' import { useAppStoreWithOut } from '@/store/modules/app'
const { t } = useI18n() const { t } = useI18n()
const state = reactive({
paginationConfig: {
currentPage: 1,
pageSize: 10,
total: 0
}
})
const tableData = ref([]) const tableData = ref([])
const drawerLoading = ref(false) const drawerLoading = ref(false)
const drawer = ref(false) const drawer = ref(false)
@ -59,7 +68,6 @@ const handleClose = () => {
} }
const { wsCache } = useCache() const { wsCache } = useCache()
const openType = wsCache.get('open-backend') === '1' ? '_self' : '_blank' const openType = wsCache.get('open-backend') === '1' ? '_self' : '_blank'
const xpack = wsCache.get('xpack-model-distributed')
const desktop = wsCache.get('app.desktop') const desktop = wsCache.get('app.desktop')
onUnmounted(() => { onUnmounted(() => {
@ -77,46 +85,29 @@ const handleClick = tab => {
description.value = t('data_export.no_task') description.value = t('data_export.no_task')
} }
drawerLoading.value = true drawerLoading.value = true
exportTasks(activeName.value) exportTasksRecords().then(res => {
.then(res => { tabList.value.forEach(item => {
tabList.value.forEach(item => { if (item.name === 'ALL') {
if (item.name === 'ALL') { item.label = t('data_set.all') + '(' + res.data.ALL + ')'
item.label = t('data_set.all') + '(' + res.data.length + ')'
}
if (item.name === 'IN_PROGRESS') {
item.label =
t('data_set.exporting') +
'(' +
res.data.filter(task => task.exportStatus === 'IN_PROGRESS').length +
')'
}
if (item.name === 'SUCCESS') {
item.label =
t('data_set.success') +
'(' +
res.data.filter(task => task.exportStatus === 'SUCCESS').length +
')'
}
if (item.name === 'FAILED') {
item.label =
t('data_set.fail') +
'(' +
res.data.filter(task => task.exportStatus === 'FAILED').length +
')'
}
if (item.name === 'PENDING') {
item.label =
t('data_set.waiting') +
'(' +
res.data.filter(task => task.exportStatus === 'PENDING').length +
')'
}
})
if (activeName.value === 'ALL') {
tableData.value = res.data
} else {
tableData.value = res.data.filter(task => task.exportStatus === activeName.value)
} }
if (item.name === 'IN_PROGRESS') {
item.label = t('data_set.exporting') + '(' + res.data.IN_PROGRESS + ')'
}
if (item.name === 'SUCCESS') {
item.label = t('data_set.success') + '(' + res.data.SUCCESS + ')'
}
if (item.name === 'FAILED') {
item.label = t('data_set.fail') + '(' + res.data.FAILED + ')'
}
if (item.name === 'PENDING') {
item.label = t('data_set.waiting') + '(' + res.data.PENDING + ')'
}
})
})
exportTasks(state.paginationConfig.currentPage, state.paginationConfig.pageSize, activeName.value)
.then(res => {
state.paginationConfig.total = res.data.total
tableData.value = res.data.records
}) })
.finally(() => { .finally(() => {
drawerLoading.value = false drawerLoading.value = false
@ -131,45 +122,32 @@ const init = params => {
handleClick() handleClick()
timer = setInterval(() => { timer = setInterval(() => {
if (activeName.value === 'IN_PROGRESS') { if (activeName.value === 'IN_PROGRESS') {
exportTasks(activeName.value).then(res => { exportTasksRecords().then(res => {
tabList.value.forEach(item => { tabList.value.forEach(item => {
if (item.name === 'ALL') { if (item.name === 'ALL') {
item.label = t('data_set.all') + '(' + res.data.length + ')' item.label = t('data_set.all') + '(' + res.data.ALL + ')'
} }
if (item.name === 'IN_PROGRESS') { if (item.name === 'IN_PROGRESS') {
item.label = item.label = t('data_set.exporting') + '(' + res.data.IN_PROGRESS + ')'
t('data_set.exporting') +
'(' +
res.data.filter(task => task.exportStatus === 'IN_PROGRESS').length +
')'
} }
if (item.name === 'SUCCESS') { if (item.name === 'SUCCESS') {
item.label = item.label = t('data_set.success') + '(' + res.data.SUCCESS + ')'
t('data_set.success') +
'(' +
res.data.filter(task => task.exportStatus === 'SUCCESS').length +
')'
} }
if (item.name === 'FAILED') { if (item.name === 'FAILED') {
item.label = item.label = t('data_set.fail') + '(' + res.data.FAILED + ')'
t('data_set.fail') +
'(' +
res.data.filter(task => task.exportStatus === 'FAILED').length +
')'
} }
if (item.name === 'PENDING') { if (item.name === 'PENDING') {
item.label = item.label = t('data_set.waiting') + '(' + res.data.PENDING + ')'
t('data_set.waiting') +
'(' +
res.data.filter(task => task.exportStatus === 'PENDING').length +
')'
} }
}) })
if (activeName.value === 'ALL') { })
tableData.value = res.data exportTasks(
} else { state.paginationConfig.currentPage,
tableData.value = res.data.filter(task => task.exportStatus === activeName.value) state.paginationConfig.pageSize,
} activeName.value
).then(res => {
state.paginationConfig.total = res.data.total
tableData.value = res.data.records
}) })
} }
}, 5000) }, 5000)
@ -242,12 +220,16 @@ const callbackExportSuc = () => {
const downLoadAll = () => { const downLoadAll = () => {
if (multipleSelection.value.length === 0) { if (multipleSelection.value.length === 0) {
tableData.value.forEach(item => { tableData.value.forEach(item => {
window.open(PATH_URL + '/exportCenter/download/' + item.id) generateDownloadUri(item.id).then(() => {
window.open(PATH_URL + '/exportCenter/download/' + item.id)
})
}) })
return return
} }
multipleSelection.value.map(ele => { multipleSelection.value.map(ele => {
window.open(PATH_URL + '/exportCenter/download/' + ele.id) generateDownloadUri(ele.id).then(() => {
window.open(PATH_URL + '/exportCenter/download/' + ele.id)
})
}) })
} }
const showMsg = item => { const showMsg = item => {
@ -262,8 +244,11 @@ const timestampFormatDate = value => {
return new Date(value).toLocaleString() return new Date(value).toLocaleString()
} }
import { PATH_URL } from '@/config/axios/service' import { PATH_URL } from '@/config/axios/service'
import GridTable from '../../../../components/grid-table/src/GridTable.vue'
const downloadClick = item => { const downloadClick = item => {
window.open(PATH_URL + '/exportCenter/download/' + item.id, openType) generateDownloadUri(item.id).then(() => {
window.open(PATH_URL + '/exportCenter/download/' + item.id, openType)
})
} }
const retry = item => { const retry = item => {
@ -294,6 +279,19 @@ const handleSelectionChange = val => {
multipleSelection.value = val multipleSelection.value = val
} }
const pageChange = index => {
if (typeof index !== 'number') {
return
}
state.paginationConfig.currentPage = index
handleClick()
}
const sizeChange = size => {
state.paginationConfig.currentPage = 1
state.paginationConfig.pageSize = size
handleClick()
}
const delAll = () => { const delAll = () => {
if (multipleSelection.value.length === 0) { if (multipleSelection.value.length === 0) {
ElMessageBox.confirm(t('data_export.sure_del_all'), { ElMessageBox.confirm(t('data_export.sure_del_all'), {
@ -344,7 +342,7 @@ defineExpose({
<template> <template>
<el-drawer <el-drawer
v-loading="drawerLoading" v-loading="drawerLoading"
custom-class="de-export-excel" modal-class="de-export-excel"
:title="$t('data_export.export_center')" :title="$t('data_export.export_center')"
v-model="drawer" v-model="drawer"
direction="rtl" direction="rtl"
@ -386,11 +384,13 @@ defineExpose({
>{{ $t('commons.delete') }} >{{ $t('commons.delete') }}
</el-button> </el-button>
<div class="table-container" :class="!tableData.length && 'hidden-bottom'"> <div class="table-container" :class="!tableData.length && 'hidden-bottom'">
<el-table <GridTable
ref="multipleTable" ref="multipleTable"
:data="tableData" :pagination="state.paginationConfig"
height="100%" :table-data="tableData"
style="width: 100%" class="popper-max-width"
@current-change="pageChange"
@size-change="sizeChange"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
@ -482,7 +482,7 @@ defineExpose({
<template #empty> <template #empty>
<empty-background :description="description" img-type="noneWhite" /> <empty-background :description="description" img-type="noneWhite" />
</template> </template>
</el-table> </GridTable>
</div> </div>
</el-drawer> </el-drawer>

View File

@ -384,6 +384,7 @@ const emits = defineEmits(['update:item', 'del'])
size="small" size="small"
@change="filterTypeChange" @change="filterTypeChange"
v-model="item.filterType" v-model="item.filterType"
class="w181"
:placeholder="t('auth.select')" :placeholder="t('auth.select')"
> >
<el-option <el-option

View File

@ -1,18 +1,18 @@
<script lang="tsx" setup> <script lang="tsx" setup>
import referencePlay from '@/assets/svg/reference-play.svg' import referencePlay from '@/assets/svg/reference-play.svg'
import referenceSetting1 from '@/assets/svg/reference-setting-white.svg' import referenceSetting1 from '@/assets/svg/reference-setting.svg'
import icon_preferences_outlined from '@/assets/svg/icon_preferences_outlined.svg' import icon_preferences_outlined from '@/assets/svg/icon_preferences_outlined.svg'
import icon_close_outlined from '@/assets/svg/icon_close_outlined.svg' import icon_close_outlined from '@/assets/svg/icon_close_outlined.svg'
import icon_right_outlined from '@/assets/svg/icon_right_outlined.svg' import icon_right_outlined from '@/assets/svg/icon_right_outlined.svg'
import icon_left_outlined from '@/assets/svg/icon_left_outlined.svg' import icon_left_outlined from '@/assets/svg/icon_left_outlined.svg'
import referenceTable from '@/assets/svg/reference-table.svg' import referenceTable from '@/assets/svg/reference-table.svg'
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg' import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
import icon_form_outlined_white from '@/assets/svg/icon_form_outlined_white.svg' import icon_form_outlined from '@/assets/svg/icon_form_outlined.svg'
import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg' import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg'
import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg' import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg'
import icon_textBox_outlined from '@/assets/svg/icon_text-box_outlined.svg' import icon_textBox_outlined from '@/assets/svg/icon_text-box_outlined.svg'
import icon_info_colorful from '@/assets/svg/icon_info_colorful.svg' import icon_info_colorful from '@/assets/svg/icon_info_colorful.svg'
import icon_play_round_outlined_white from '@/assets/svg/icon_play_round_outlined_white.svg' import icon_playRound_outlined from '@/assets/svg/icon_play-round_outlined.svg'
import { searchVariableApi } from '@/api/variable' import { searchVariableApi } from '@/api/variable'
import { import {
ref, ref,
@ -24,7 +24,9 @@ import {
onBeforeUnmount, onBeforeUnmount,
shallowRef, shallowRef,
computed, computed,
h inject,
h,
Ref
} from 'vue' } from 'vue'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
@ -106,7 +108,7 @@ const state = reactive({
}) })
const datasourceTableData = shallowRef([]) const datasourceTableData = shallowRef([])
const isCross = inject<Ref>('isCross')
const paginationConfig = reactive({ const paginationConfig = reactive({
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
@ -209,18 +211,25 @@ const insertFieldToCodeMirror = (value: string) => {
const setNameIdTrans = (from, to, originName, name2Auto?: string[]) => { const setNameIdTrans = (from, to, originName, name2Auto?: string[]) => {
let name2Id = originName let name2Id = originName
const ids = [...builtInList.value, ...fieldFormList.value].map(item => item.id)
const names = [...builtInList.value, ...fieldFormList.value].map(item => item.name)
const nameIdMap = [...builtInList.value, ...fieldFormList.value].reduce((pre, next) => { const nameIdMap = [...builtInList.value, ...fieldFormList.value].reduce((pre, next) => {
pre[next[from]] = next[to] pre[next[from]] = next[to]
return pre return pre
}, {}) }, {})
const on = originName.match(/\[(.+?)\]/g) const on = originName.match(/\$f2cde\[(.+?)\]/g)
if (on) { if (on) {
on.forEach(itm => { on.forEach(itm => {
const ele = itm.slice(1, -1) const ele = itm.slice(7, -1)
if (name2Auto) { if (name2Auto) {
name2Auto.push(nameIdMap[ele]) name2Auto.push(nameIdMap[ele])
} }
name2Id = name2Id.replace(`[${ele}]`, `[${nameIdMap[ele]}]`) if (from === 'id' && ids.includes(ele)) {
name2Id = name2Id.replace(`$f2cde[${ele}]`, `$f2cde[${nameIdMap[ele]}]`)
}
if (from === 'name' && names.includes(ele)) {
name2Id = name2Id.replace(`$f2cde[${ele}]`, `$f2cde[${nameIdMap[ele]}]`)
}
}) })
} }
return name2Id return name2Id
@ -259,7 +268,13 @@ const getNodeField = ({ datasourceId, tableName }) => {
table: tableName, table: tableName,
sql: '' sql: ''
} }
getTableField({ datasourceId, info: JSON.stringify(info), tableName, type: 'db' }) getTableField({
datasourceId,
info: JSON.stringify(info),
tableName,
type: 'db',
isCross: isCross.value
})
.then(res => { .then(res => {
gridData.value = res as unknown as Field[] gridData.value = res as unknown as Field[]
}) })
@ -417,6 +432,7 @@ const getSQLPreview = () => {
parseVariable() parseVariable()
dataPreviewLoading.value = true dataPreviewLoading.value = true
getPreviewSql({ getPreviewSql({
isCross: isCross.value,
sql: Base64.encode((sql = setNameIdTrans('name', 'id', codeCom.value.state.doc.toString()))), sql: Base64.encode((sql = setNameIdTrans('name', 'id', codeCom.value.state.doc.toString()))),
datasourceId: sqlNode.value.datasourceId, datasourceId: sqlNode.value.datasourceId,
sqlVariableDetails: JSON.stringify(state.variables) sqlVariableDetails: JSON.stringify(state.variables)
@ -432,7 +448,9 @@ const getSQLPreview = () => {
let tableList = [] let tableList = []
watch(searchTable, val => { watch(searchTable, val => {
datasourceTableData.value = tableList.filter(ele => ele.tableName.includes(val)) datasourceTableData.value = tableList.filter(ele =>
ele.tableName.toLowerCase().includes(val.toLowerCase())
)
}) })
const getIconName = (type: string) => { const getIconName = (type: string) => {
@ -494,37 +512,77 @@ const mouseupDrag = () => {
const parseVariable = () => { const parseVariable = () => {
state.variablesTmp = [] state.variablesTmp = []
const reg = new RegExp('\\${(.*?)}', 'gim') const variableReg = new RegExp('\\$DE_PARAM{(.*?)}', 'gim')
const match = codeCom.value.state.doc.toString().match(reg) const variableMatch = codeCom.value.state.doc.toString().match(variableReg)
const names = [] if (variableMatch !== null) {
if (match !== null) { const names = []
for (let index = 0; index < match.length; index++) { const reg = new RegExp('\\$\\[[^\\]]+\\]', 'gim')
let name = match[index].substring(2, match[index].length - 1) for (let index = 0; index < variableMatch.length; index++) {
if (names.indexOf(name) < 0) { let sqlItem = variableMatch[index].substring(10, variableMatch[index].length - 1)
names.push(name) const match = sqlItem.match(reg)
// eslint-disable-next-line if (match !== null) {
let obj = undefined for (let matchIndex = 0; matchIndex < match.length; matchIndex++) {
for (let i = 0; i < state.variables?.length; i++) { let name = match[matchIndex].substring(2, match[matchIndex].length - 1)
if (state.variables[i].variableName === name) { if (names.indexOf(name) < 0) {
obj = state.variables[i] names.push(name)
if (!obj.hasOwnProperty('defaultValueScope')) { let obj = undefined
obj.defaultValueScope = 'EDIT' for (let i = 0; i < state.variables?.length; i++) {
if (state.variables[i].variableName === name) {
obj = state.variables[i]
if (!obj.hasOwnProperty('defaultValueScope')) {
obj.defaultValueScope = 'EDIT'
}
}
}
if (obj === undefined) {
obj = {
variableName: name,
alias: '',
type: [],
required: false,
defaultValue: '',
details: '',
defaultValueScope: 'EDIT'
}
obj.type.push('TEXT')
}
state.variablesTmp.push(obj)
}
}
}
}
} else {
const reg = new RegExp('\\${(.*?)}', 'gim')
const match = codeCom.value.state.doc.toString().match(reg)
const names = []
if (match !== null) {
for (let index = 0; index < match.length; index++) {
let name = match[index].substring(2, match[index].length - 1)
if (names.indexOf(name) < 0) {
names.push(name)
let obj = undefined
for (let i = 0; i < state.variables?.length; i++) {
if (state.variables[i].variableName === name) {
obj = state.variables[i]
if (!obj.hasOwnProperty('defaultValueScope')) {
obj.defaultValueScope = 'EDIT'
}
} }
} }
} if (obj === undefined) {
if (obj === undefined) { obj = {
obj = { variableName: name,
variableName: name, alias: '',
alias: '', type: [],
type: [], required: false,
required: false, defaultValue: '',
defaultValue: '', details: '',
details: '', defaultValueScope: 'EDIT'
defaultValueScope: 'EDIT' }
obj.type.push('TEXT')
} }
obj.type.push('TEXT') state.variablesTmp.push(obj)
} }
state.variablesTmp.push(obj)
} }
} }
} }
@ -546,7 +604,7 @@ const mousedownDrag = () => {
<div class="add-sql-name"> <div class="add-sql-name">
<el-input class="name" ref="editerName" v-model="sqlNode.tableName" @change="setFlag" /> <el-input class="name" ref="editerName" v-model="sqlNode.tableName" @change="setFlag" />
<div class="save-or-cancel flex-align-center"> <div class="save-or-cancel flex-align-center">
<el-button @click="getSQLPreview" text style="color: #ffffff !important"> <el-button @click="getSQLPreview" text style="color: #1f2329">
<template #icon> <template #icon>
<el-icon> <el-icon>
<Icon name="reference-play"><referencePlay class="svg-icon" /></Icon> <Icon name="reference-play"><referencePlay class="svg-icon" /></Icon>
@ -554,9 +612,9 @@ const mousedownDrag = () => {
</template> </template>
{{ t('data_set.run') }} {{ t('data_set.run') }}
</el-button> </el-button>
<el-button @click="referenceSetting()" style="color: #ffffff !important" text> <el-button @click="referenceSetting()" style="color: #1f2329" text>
<template #icon> <template #icon>
<el-icon > <el-icon>
<Icon name="reference-setting"><referenceSetting1 class="svg-icon" /></Icon> <Icon name="reference-setting"><referenceSetting1 class="svg-icon" /></Icon>
</el-icon> </el-icon>
</template> </template>
@ -670,8 +728,8 @@ const mousedownDrag = () => {
:title="datasourceTableData[index].tableName" :title="datasourceTableData[index].tableName"
@click="setActiveName(datasourceTableData[index])" @click="setActiveName(datasourceTableData[index])"
> >
<el-icon> <el-icon class="icon-color">
<Icon name="icon_form_outlined_white"><icon_form_outlined_white class="svg-icon" /></Icon> <Icon name="icon_form_outlined"><icon_form_outlined class="svg-icon" /></Icon>
</el-icon> </el-icon>
<span class="label">{{ datasourceTableData[index].tableName }}</span> <span class="label">{{ datasourceTableData[index].tableName }}</span>
<span class="name-copy"> <span class="name-copy">
@ -784,6 +842,7 @@ const mousedownDrag = () => {
@change="changeFlagCode = true" @change="changeFlagCode = true"
:height="`${dragHeight}px`" :height="`${dragHeight}px`"
dom-id="sql-editor" dom-id="sql-editor"
:regexp="/\$f2cde\[(.*?)\]/g"
ref="myCm" ref="myCm"
:quotaMap="fieldFormList.filter(ele => ['num'].includes(ele.type)).map(ele => ele.name)" :quotaMap="fieldFormList.filter(ele => ['num'].includes(ele.type)).map(ele => ele.name)"
:dimensionMap=" :dimensionMap="
@ -827,8 +886,8 @@ const mousedownDrag = () => {
<div class="sql-tips flex-align-center"> <div class="sql-tips flex-align-center">
{{ t('data_set.click_above') }} {{ t('data_set.click_above') }}
<el-icon> <el-icon>
<icon name="icon_play_round_outlined_white" <icon name="icon_play-round_outlined"
><icon_play_round_outlined_white class="svg-icon" ><icon_playRound_outlined class="svg-icon"
/></icon> /></icon>
</el-icon> </el-icon>
{{ t('data_set.see_the_results') }} {{ t('data_set.see_the_results') }}
@ -911,7 +970,7 @@ const mousedownDrag = () => {
</div> </div>
<div <div
class="variable-item flex-align-center" class="variable-item flex-align-center"
@click="insertFieldToCodeMirror(`[${fieldForm.name}]`)" @click="insertFieldToCodeMirror(`$f2cde[${fieldForm.name}]`)"
v-for="fieldForm in builtInList" v-for="fieldForm in builtInList"
:key="fieldForm.id" :key="fieldForm.id"
> >
@ -924,7 +983,7 @@ const mousedownDrag = () => {
class="variable-item flex-align-center" class="variable-item flex-align-center"
v-for="fieldForm in fieldFormListComputed" v-for="fieldForm in fieldFormListComputed"
:key="fieldForm.id" :key="fieldForm.id"
@click="insertFieldToCodeMirror(`[${fieldForm.name}]`)" @click="insertFieldToCodeMirror(`$f2cde[${fieldForm.name}]`)"
:class="['num'].includes(fieldForm.type) && 'with-type'" :class="['num'].includes(fieldForm.type) && 'with-type'"
> >
<el-icon> <el-icon>
@ -936,7 +995,7 @@ const mousedownDrag = () => {
></component ></component
></Icon> ></Icon>
</el-icon> </el-icon>
<span :title="fieldForm.name">{{ fieldForm.name }}</span> <span :title="fieldForm.name" class="ellipsis">{{ fieldForm.name }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -946,7 +1005,7 @@ const mousedownDrag = () => {
<el-drawer <el-drawer
:title="dialogTitle" :title="dialogTitle"
v-model="showVariableMgm" v-model="showVariableMgm"
custom-class="sql-dataset-drawer" modal-class="sql-dataset-drawer"
size="870px" size="870px"
direction="rtl" direction="rtl"
> >
@ -1601,6 +1660,7 @@ const mousedownDrag = () => {
} }
.ed-input-group__prepend { .ed-input-group__prepend {
padding: 0 11px; padding: 0 11px;
width: 163px;
} }
.de-group__prepend { .de-group__prepend {
.ed-date-editor { .ed-date-editor {
@ -1615,7 +1675,6 @@ const mousedownDrag = () => {
.ed-date-editor { .ed-date-editor {
width: 100%; width: 100%;
display: inline-block;
} }
.select-type { .select-type {

View File

@ -136,11 +136,11 @@ const setFieldForm = () => {
const setNameIdTrans = (from, to, originName, name2Auto?: string[]) => { const setNameIdTrans = (from, to, originName, name2Auto?: string[]) => {
let name2Id = originName let name2Id = originName
const nameIdMap = [...state.dimensionData, ...state.quotaData].reduce((pre, next) => { const nameIdMap = [...dimensionDataList, ...quotaDataList].reduce((pre, next) => {
pre[next[from]] = next[to] pre[next[from]] = next[to]
return pre return pre
}, {}) }, {})
const on = originName.match(/\[(.+?)\]/g) const on = originName.match(/\[(.+?)\]/g) || []
if (on) { if (on) {
on.forEach(itm => { on.forEach(itm => {
const ele = itm.slice(1, -1) const ele = itm.slice(1, -1)
@ -235,10 +235,8 @@ watch(
) )
) )
} else { } else {
state.dimensionData = JSON.parse(JSON.stringify(dimensionDataList)).filter( state.dimensionData = JSON.parse(JSON.stringify(dimensionDataList))
ele => ele.extField === 0 state.quotaData = JSON.parse(JSON.stringify(quotaDataList))
)
state.quotaData = JSON.parse(JSON.stringify(quotaDataList)).filter(ele => ele.extField === 0)
} }
} }
) )
@ -627,7 +625,7 @@ initFunction()
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button secondary @click="formQuotaClose">{{ t('chart.cancel') }}</el-button> <el-button @click="formQuotaClose">{{ t('chart.cancel') }}</el-button>
<el-button type="primary" @click="formQuotaConfirm"> {{ t('chart.confirm') }} </el-button> <el-button type="primary" @click="formQuotaConfirm"> {{ t('chart.confirm') }} </el-button>
</div> </div>
</template> </template>
@ -652,10 +650,8 @@ initFunction()
.mr0 { .mr0 {
margin-right: 0; margin-right: 0;
:deep(.ed-select__prefix--light) { :deep(.ed-select__prefix::after) {
padding: 0; display: none;
border: none;
margin: 0;
} }
} }

View File

@ -16,9 +16,12 @@ const props = defineProps({
domId: propTypes.string.def('editor'), domId: propTypes.string.def('editor'),
height: propTypes.string.def('250px'), height: propTypes.string.def('250px'),
quotaMap: propTypes.arrayOf(String).def(() => []), quotaMap: propTypes.arrayOf(String).def(() => []),
dimensionMap: propTypes.arrayOf(String).def(() => []) dimensionMap: propTypes.arrayOf(String).def(() => []),
regexp: {
type: RegExp,
default: /\[(.*?)\]/g
}
}) })
const emits = defineEmits(['change']) const emits = defineEmits(['change'])
const codeComInit = (doc: string, sqlMode?: boolean) => { const codeComInit = (doc: string, sqlMode?: boolean) => {
@ -45,7 +48,7 @@ const codeComInit = (doc: string, sqlMode?: boolean) => {
} //!placeholderMatcher } //!placeholderMatcher
const placeholderMatcher = new MatchDecorator({ const placeholderMatcher = new MatchDecorator({
regexp: /\[(.*?)\]/g, regexp: new RegExp(props.regexp),
decoration: match => decoration: match =>
Decoration.replace({ Decoration.replace({
widget: new PlaceholderWidget(match[1]) widget: new PlaceholderWidget(match[1])

View File

@ -18,11 +18,11 @@ import nothingTree from '@/assets/img/nothing-tree.png'
import { BusiTreeRequest } from '@/models/tree/TreeNode' import { BusiTreeRequest } from '@/models/tree/TreeNode'
import { filterFreeFolder } from '@/utils/utils' import { filterFreeFolder } from '@/utils/utils'
export interface Tree { export interface Tree {
isCross: boolean
name: string name: string
value?: string | number value?: string | number
id: string | number id: string | number
nodeType: string nodeType: string
appId: string | number
createBy?: string createBy?: string
level: number level: number
leaf?: boolean leaf?: boolean
@ -42,13 +42,13 @@ const state = reactive({
const placeholder = ref('') const placeholder = ref('')
const nodeType = ref() const nodeType = ref()
const pid = ref() const pid = ref()
const appId:any = ref("")
const id = ref() const id = ref()
const cmd = ref('') const cmd = ref('')
const treeRef = ref() const treeRef = ref()
const filterText = ref('') const filterText = ref('')
let union = [] let union = []
let allfields = [] let allfields = []
let isCross = false
const datasetForm = reactive({ const datasetForm = reactive({
pid: '', pid: '',
name: '' name: ''
@ -162,6 +162,7 @@ const createInit = (type, data: Tree, exec, name: string) => {
if (type === 'dataset') { if (type === 'dataset') {
union = data.union union = data.union
allfields = data.allfields allfields = data.allfields
isCross = data.isCross
} }
if (data.id) { if (data.id) {
const request = { leaf: false, weight: 7,appId: data.appId } as BusiTreeRequest const request = { leaf: false, weight: 7,appId: data.appId } as BusiTreeRequest
@ -254,6 +255,7 @@ const saveDataset = () => {
name: datasetForm.name, name: datasetForm.name,
appId: appId.value appId: appId.value
} }
switch (cmd.value) { switch (cmd.value) {
case 'move': case 'move':
params.pid = activeAll.value ? '0' : (datasetForm.pid as string) params.pid = activeAll.value ? '0' : (datasetForm.pid as string)
@ -270,6 +272,7 @@ const saveDataset = () => {
if (nodeType.value === 'dataset') { if (nodeType.value === 'dataset') {
params.union = union params.union = union
params.allFields = allfields params.allFields = allfields
params.isCross = isCross
} }
if (cmd.value === 'move' && !checkPid(params.pid)) { if (cmd.value === 'move' && !checkPid(params.pid)) {
return return

View File

@ -43,6 +43,7 @@ const props = defineProps({
const primaryColor = computed(() => { const primaryColor = computed(() => {
return appearanceStore.themeColor === 'custom' ? appearanceStore.customColor : '#3370FF' return appearanceStore.themeColor === 'custom' ? appearanceStore.customColor : '#3370FF'
}) })
const isCross = inject<Ref>('isCross')
const iconName = { const iconName = {
left: icon_leftAssociation, left: icon_leftAssociation,
@ -62,7 +63,7 @@ const sqlNode = ref<SqlNode>()
const allfields = inject('allfields') as Ref const allfields = inject('allfields') as Ref
const getNodeField = ({ datasourceId, id, info, tableName, type, currentDsFields }) => { const getNodeField = ({ datasourceId, id, info, tableName, type, currentDsFields }) => {
return getTableField({ datasourceId, id, info, tableName, type }) return getTableField({ datasourceId, id, info, tableName, type, isCross: isCross.value })
.then(res => { .then(res => {
const idOriginNameMap = allfields.value.reduce((pre, next) => { const idOriginNameMap = allfields.value.reduce((pre, next) => {
pre[`${next.datasetTableId}${next.originName}`] = next.id pre[`${next.datasetTableId}${next.originName}`] = next.id
@ -230,7 +231,8 @@ const saveSqlNode = (val: SqlNode, cb) => {
id: id, id: id,
info: state.visualNode.info, info: state.visualNode.info,
tableName, tableName,
type: 'sql' type: 'sql',
isCross: isCross.value
}).then(res => { }).then(res => {
nodeField.value = res as unknown as Field[] nodeField.value = res as unknown as Field[]
nodeField.value.forEach(ele => { nodeField.value.forEach(ele => {
@ -244,7 +246,13 @@ const saveSqlNode = (val: SqlNode, cb) => {
} }
return return
} }
const obj = { info: JSON.stringify({ table: tableName, sql }), id, tableName, sqlVariableDetails } const obj = {
info: JSON.stringify({ table: tableName, sql }),
id,
datasourceId,
tableName,
sqlVariableDetails
}
dfsNodeBack([obj], [id], state.nodeList) dfsNodeBack([obj], [id], state.nodeList)
emits('reGetName') emits('reGetName')
} }
@ -261,13 +269,15 @@ const closeSqlNode = () => {
changeSqlId.value.length === 1 changeSqlId.value.length === 1
) { ) {
currentNode.value = state.nodeList[0] currentNode.value = state.nodeList[0]
const { datasourceId, id, info, tableName } = currentNode.value const { datasourceId, id, info, tableName, sqlVariableDetails } = currentNode.value
getTableField({ getTableField({
datasourceId, datasourceId,
id, id,
info, info,
tableName, tableName,
type: 'sql' type: 'sql',
isCross: isCross.value,
sqlVariableDetails: sqlVariableDetails
}).then(res => { }).then(res => {
const idOriginNameMap = allfields.value.reduce((pre, next) => { const idOriginNameMap = allfields.value.reduce((pre, next) => {
pre[`${next.datasetTableId}${next.originName}`] = next.id pre[`${next.datasetTableId}${next.originName}`] = next.id
@ -364,7 +374,7 @@ const confirmEditUnion = () => {
if (!!ids.length) { if (!!ids.length) {
const idArr = allfields.value.reduce((pre, next) => { const idArr = allfields.value.reduce((pre, next) => {
if (next.extField === 2) { if (next.extField === 2) {
let idMap = next.originName.match(/\[(.+?)\]/g) let idMap = next.originName.match(/\[(.+?)\]/g) || []
idMap = idMap.filter( idMap = idMap.filter(
itx => !next.params?.map(element => element.id).includes(itx.slice(1, -1)) itx => !next.params?.map(element => element.id).includes(itx.slice(1, -1))
) )
@ -452,7 +462,7 @@ const handleCommand = (ele, command) => {
if (!!fakeDelId.length) { if (!!fakeDelId.length) {
const idArr = allfields.value.reduce((pre, next) => { const idArr = allfields.value.reduce((pre, next) => {
if (next.extField === 2) { if (next.extField === 2) {
const idMap = next.originName.match(/\[(.+?)\]/g) const idMap = next.originName.match(/\[(.+?)\]/g) || []
const result = idMap.map(itm => { const result = idMap.map(itm => {
return itm.slice(1, -1) return itm.slice(1, -1)
}) })
@ -908,6 +918,7 @@ const drop_handler = ev => {
id: currentNode.value.id, id: currentNode.value.id,
info: currentNode.value.info, info: currentNode.value.info,
tableName, tableName,
isCross: isCross.value,
type type
}) })
.then(res => { .then(res => {
@ -1108,7 +1119,7 @@ const emits = defineEmits([
<span class="placeholder">{{ t('data_set.custom_sql_here') }}</span> <span class="placeholder">{{ t('data_set.custom_sql_here') }}</span>
<handle-more <handle-more
style="margin-left: auto" style="margin-left: auto"
:iconName="icon_moreVertical_outlined_white" :iconName="icon_moreVertical_outlined"
:menuList="ele.type === 'sql' ? [...sqlMenu, ...menuList] : menuList" :menuList="ele.type === 'sql' ? [...sqlMenu, ...menuList] : menuList"
@handle-command="command => handleCommand(ele, command)" @handle-command="command => handleCommand(ele, command)"
></handle-more> ></handle-more>
@ -1190,14 +1201,16 @@ const emits = defineEmits([
<el-drawer <el-drawer
:before-close="closeEditUnion" :before-close="closeEditUnion"
v-model="editUnion" v-model="editUnion"
custom-class="union-item-drawer" modal-class="union-item-drawer"
size="600px" size="600px"
direction="rtl" direction="rtl"
> >
<template #header v-if="currentNode"> <template #header v-if="currentNode">
<div style="width: 100%"> <div style="width: 100%">
<div class="info"> <div class="info">
<span :title="currentNode.tableName" class="label ellipsis">{{currentNode.tableName}}</span> <span :title="currentNode.tableName" class="label ellipsis">{{
currentNode.tableName
}}</span>
</div> </div>
<div class="info" style="margin-top: 4px"> <div class="info" style="margin-top: 4px">
<span <span
@ -1264,13 +1277,13 @@ const emits = defineEmits([
.label { .label {
font-weight: 500; font-weight: 500;
font-size: 16px; font-size: 16px;
color: #ffffff; color: #1f2329;
max-width: 500px; max-width: 500px;
} }
.name { .name {
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
color: #939393; color: #646a73;
line-height: 22px; line-height: 22px;
} }
} }

View File

@ -1,11 +1,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive } from 'vue' import { ref, reactive, inject, type Ref } from 'vue'
import UnionFieldList from './UnionFieldList.vue' import UnionFieldList from './UnionFieldList.vue'
import UnionItemEdit from './UnionItemEdit.vue' import UnionItemEdit from './UnionItemEdit.vue'
import type { Field, NodeType, UnionType, Node } from './util' import type { Field, NodeType, UnionType, Node } from './util'
import { getTableField } from '@/api/dataset' import { getTableField } from '@/api/dataset'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
const isCross = inject<Ref>('isCross')
const changeParentFields = val => { const changeParentFields = val => {
parent.currentDsFields = val parent.currentDsFields = val
} }
@ -69,10 +71,15 @@ const initState = () => {
} }
const getParams = (obj: Node) => { const getParams = (obj: Node) => {
return ['datasourceId', 'id', 'info', 'tableName', 'type'].reduce((pre, next) => { return ['datasourceId', 'id', 'info', 'tableName', 'type'].reduce(
pre[next] = obj[next] (pre, next) => {
return pre pre[next] = obj[next]
}, {}) return pre
},
{
isCross: isCross.value
}
)
} }
const getFields = async () => { const getFields = async () => {
const [n, p] = props.editArr as Node[] const [n, p] = props.editArr as Node[]

View File

@ -16,6 +16,10 @@ import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.s
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg' import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg' import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import {
iconFieldCalculatedMap,
iconFieldCalculatedQMap
} from '@/components/icon-group/field-calculated-list'
import { enumValueDs } from '@/api/dataset' import { enumValueDs } from '@/api/dataset'
import { import {
ref, ref,
@ -82,7 +86,12 @@ const appStore = useAppStoreWithOut()
const embeddedStore = useEmbedded() const embeddedStore = useEmbedded()
const { t } = useI18n() const { t } = useI18n()
const route = useRoute() const route = useRoute()
const { push } = useRouter() const { push } = useRouter() || {
push: val => {
if (embeddedStore.getToken) return
window.location.href = val as string
}
}
const quotaTableHeight = ref(238) const quotaTableHeight = ref(238)
const creatDsFolder = ref() const creatDsFolder = ref()
const editCalcField = ref(false) const editCalcField = ref(false)
@ -112,6 +121,7 @@ const currentField = ref({
name: '', name: '',
idArr: [] idArr: []
}) })
const isCross = ref(false)
let isUpdate = false let isUpdate = false
const appId:any = ref('') const appId:any = ref('')
if (route.query.appId) { if (route.query.appId) {
@ -252,14 +262,14 @@ const getDsName = (id: string) => {
} }
const pushDataset = () => { const pushDataset = () => {
wsCache.set(`dataset-info-id`, nodeInfo.id)
if (appStore.isDataEaseBi) { if (appStore.isDataEaseBi) {
embeddedStore.clearState() embeddedStore.clearState()
useEmitt().emitter.emit('changeCurrentComponent', 'Dataset') useEmitt().emitter.emit('changeCurrentComponent', 'Dataset')
return return
} }
const routeName = embeddedStore.getToken && appStore.getIsIframe ? 'dataset-embedded' : 'dataset' const routeName = embeddedStore.getToken && appStore.getIsIframe ? 'dataset-embedded' : 'dataset'
wsCache.set(`${routeName}-info-id`, nodeInfo.id) if (!!history.state.back && !appStore.getIsIframe) {
if (!!history.state.back) {
history.back() history.back()
} else { } else {
push({ push({
@ -357,12 +367,12 @@ const editeSave = () => {
const union = [] const union = []
loading.value = true loading.value = true
dfsNodeList(union, datasetDrag.value.getNodeList()) dfsNodeList(union, datasetDrag.value.getNodeList())
saveDatasetTree({ saveDatasetTree({
...nodeInfo, ...nodeInfo,
name: datasetName.value, name: datasetName.value,
appId:appId.value, appId:appId.value,
union, union,
isCross: isCross.value,
allFields: allfields.value, allFields: allfields.value,
nodeType: 'dataset' nodeType: 'dataset'
}) })
@ -487,7 +497,7 @@ const delFieldById = arr => {
const allfieldsId = allfields.value.map(ele => ele.id).concat(paramsId) const allfieldsId = allfields.value.map(ele => ele.id).concat(paramsId)
allfields.value = allfields.value.filter(ele => { allfields.value = allfields.value.filter(ele => {
if (![2, 3].includes(ele.extField)) return true if (![2, 3].includes(ele.extField)) return true
const idMap = ele.originName.match(/\[(.+?)\]/g) const idMap = ele.originName.match(/\[(.+?)\]/g) || []
if (!idMap) return true if (!idMap) return true
const result = idMap.every(itm => { const result = idMap.every(itm => {
const id = itm.slice(1, -1) const id = itm.slice(1, -1)
@ -512,7 +522,7 @@ const delFieldByIdFake = (arr, fakeAllfields) => {
const allfieldsId = fakeAllfields.map(ele => ele.id) const allfieldsId = fakeAllfields.map(ele => ele.id)
fakeAllfields = fakeAllfields.filter(ele => { fakeAllfields = fakeAllfields.filter(ele => {
if (![2, 3].includes(ele.extField)) return true if (![2, 3].includes(ele.extField)) return true
const idMap = ele.originName.match(/\[(.+?)\]/g) const idMap = ele.originName.match(/\[(.+?)\]/g) || []
if ( if (
!idMap || !idMap ||
idMap.every(itx => ele.params?.map(element => element.id).includes(itx.slice(1, -1))) idMap.every(itx => ele.params?.map(element => element.id).includes(itx.slice(1, -1)))
@ -732,6 +742,7 @@ const initEdite = async () => {
} }
datasetName.value = nodeInfo.name datasetName.value = nodeInfo.name
allfields.value = res.allFields || [] allfields.value = res.allFields || []
isCross.value = res.isCross || false
dfsUnion(arr, res.union || []) dfsUnion(arr, res.union || [])
const [fir] = res.union as { currentDs: { datasourceId: string } }[] const [fir] = res.union as { currentDs: { datasourceId: string } }[]
dataSource.value = fir?.currentDs?.datasourceId dataSource.value = fir?.currentDs?.datasourceId
@ -835,6 +846,7 @@ const getIconName = (type: number) => {
const allfields = ref([]) const allfields = ref([])
provide('allfields', allfields) provide('allfields', allfields)
provide('isCross', isCross)
let num = +new Date() let num = +new Date()
@ -963,7 +975,7 @@ const confirmEditUnion = () => {
if (!!idList.length) { if (!!idList.length) {
const idArr = allfields.value.reduce((pre, next) => { const idArr = allfields.value.reduce((pre, next) => {
if (idList.includes(next.id)) { if (idList.includes(next.id)) {
const idMap = next.originName.match(/\[(.+?)\]/g) const idMap = next.originName.match(/\[(.+?)\]/g) || []
const result = idMap.map(itm => { const result = idMap.map(itm => {
return itm.slice(1, -1) return itm.slice(1, -1)
}) })
@ -1094,7 +1106,7 @@ const handleFieldschange = val => {
const arr = [] const arr = []
const allfieldsCopy = cloneDeep(unref(allfields)) const allfieldsCopy = cloneDeep(unref(allfields))
dfsNodeList(arr, datasetDrag.value.getNodeList()) dfsNodeList(arr, datasetDrag.value.getNodeList())
enumValueDs({ dataset: { union: arr, allFields: allfieldsCopy }, field }) enumValueDs({ dataset: { union: arr, allFields: allfieldsCopy, isCross: isCross.value }, field })
.then(res => { .then(res => {
enumValue.value = res || [] enumValue.value = res || []
}) })
@ -1106,6 +1118,14 @@ const closeGroupField = () => {
editGroupField.value = false editGroupField.value = false
} }
const disabledEnumArr = computed(() => {
return currentGroupField.groupList?.map(ele => ele.text).flat()
})
const disabledEnum = (item, arr) => {
return disabledEnumArr.value.includes(item) && !arr.includes(item)
}
const titleForGroup = ref(t('dataset.create_grouping_field')) const titleForGroup = ref(t('dataset.create_grouping_field'))
const initGroupField = val => { const initGroupField = val => {
@ -1123,7 +1143,7 @@ const initGroupField = val => {
maxTerm, maxTerm,
time: [] time: []
} }
if (currentGroupField.deTypeOrigin === 1) { if (startTime && endTime) {
obj.time = [startTime, endTime] obj.time = [startTime, endTime]
} }
groupList.push(obj) groupList.push(obj)
@ -1139,7 +1159,6 @@ const initGroupField = val => {
const confirmGroupField = () => { const confirmGroupField = () => {
ruleGroupFieldRef.value.validate(val => { ruleGroupFieldRef.value.validate(val => {
let count = 0 let count = 0
let flag = false
let time let time
refsForm.value.forEach(ele => { refsForm.value.forEach(ele => {
ele?.validate(val => { ele?.validate(val => {
@ -1150,7 +1169,6 @@ const confirmGroupField = () => {
}) })
time = setTimeout(() => { time = setTimeout(() => {
clearTimeout(time) clearTimeout(time)
flag = true
time = null time = null
if (val && count === currentGroupField.groupList.length) { if (val && count === currentGroupField.groupList.length) {
const groupList = [] const groupList = []
@ -1241,7 +1259,7 @@ const verify = () => {
const arr = [] const arr = []
dfsNodeList(arr, datasetDrag.value.getNodeList()) dfsNodeList(arr, datasetDrag.value.getNodeList())
datasetPreviewLoading.value = true datasetPreviewLoading.value = true
getPreviewData({ union: arr, allFields: allfieldsCopy }) getPreviewData({ union: arr, allFields: allfieldsCopy, isCross: isCross.value })
.then(() => { .then(() => {
ElMessage.success(t('data_set.validation_succeeded')) ElMessage.success(t('data_set.validation_succeeded'))
}) })
@ -1409,7 +1427,7 @@ const datasetSave = () => {
creatDsFolder.value.createInit( creatDsFolder.value.createInit(
'dataset', 'dataset',
{ id: pid || '0', union,appId:appId.value, allfields: allfields.value }, { id: pid || '0', union,appId:appId.value, allfields: allfields.value, isCross: isCross.value },
'', '',
datasetName.value datasetName.value
) )
@ -1426,7 +1444,7 @@ const datasetPreview = () => {
const arr = [] const arr = []
dfsNodeList(arr, datasetDrag.value.getNodeList()) dfsNodeList(arr, datasetDrag.value.getNodeList())
datasetPreviewLoading.value = true datasetPreviewLoading.value = true
getPreviewData({ union: arr, allFields: allfields.value }) getPreviewData({ union: arr, allFields: allfields.value, isCross: isCross.value })
.then(res => { .then(res => {
columns.value = generateColumns((res.data.fields as Field[]) || []) columns.value = generateColumns((res.data.fields as Field[]) || [])
tableData.value = (res.data.data as Array<{}>) || [] tableData.value = (res.data.data as Array<{}>) || []
@ -1616,6 +1634,24 @@ const handleClick = () => {
}) })
} }
const sourceChange = val => {
if (val) return
if (crossDatasources.value) {
isCross.value = !val
ElMessageBox.confirm(t('common.source_tips'), {
confirmButtonText: t('dataset.confirm'),
cancelButtonText: t('common.cancel'),
showCancelButton: true,
confirmButtonType: 'primary',
type: 'warning',
autofocus: false,
showClose: false
}).then(() => {
isCross.value = val
})
}
}
const finish = res => { const finish = res => {
const { id, pid, name } = res const { id, pid, name } = res
datasetName.value = name datasetName.value = name
@ -1667,6 +1703,14 @@ const getDsIconName = data => {
if (!data.leaf) return dvFolder if (!data.leaf) return dvFolder
return iconDatasourceMap[data.type] return iconDatasourceMap[data.type]
} }
const getIconNameCalc = (deType, extField, dimension = false) => {
if (extField === 2) {
const iconFieldCalculated = dimension ? iconFieldCalculatedMap : iconFieldCalculatedQMap
return iconFieldCalculated[deType]
}
return iconFieldMap[fieldType[deType]]
}
</script> </script>
<template> <template>
@ -1703,7 +1747,7 @@ const getDsIconName = data => {
<div class="container dataset-db" @mouseup="mouseupDrag"> <div class="container dataset-db" @mouseup="mouseupDrag">
<p v-show="!showLeft" class="arrow-right" @click="showLeft = true"> <p v-show="!showLeft" class="arrow-right" @click="showLeft = true">
<el-icon> <el-icon>
<Icon name="icon_right_outlined"><icon_right_outlined class="svg-icon" /></Icon> <Icon><icon_right_outlined class="svg-icon" /></Icon>
</el-icon> </el-icon>
</p> </p>
<div <div
@ -1720,6 +1764,14 @@ const getDsIconName = data => {
:style="{ width: LeftWidth + 'px' }" :style="{ width: LeftWidth + 'px' }"
> >
<div class="table-list-top"> <div class="table-list-top">
<el-switch
style="margin-bottom: 8px"
v-model="isCross"
@change="sourceChange"
:active-text="$t('common.cross_source')"
:inactive-text="$t('common.single_source')"
/>
<p class="select-ds"> <p class="select-ds">
{{ t('data_set.select_data_source') }} {{ t('data_set.select_data_source') }}
<span class="left-outlined"> <span class="left-outlined">
@ -1924,7 +1976,7 @@ const getDsIconName = data => {
><component ><component
class="svg-icon" class="svg-icon"
:class="`field-icon-${fieldType[[2, 3].includes(data.deType) ? 2 : 0]}`" :class="`field-icon-${fieldType[[2, 3].includes(data.deType) ? 2 : 0]}`"
:is="iconFieldMap[fieldType[data.deType]]" :is="getIconNameCalc(data.deType, data.extField)"
></component ></component
></Icon> ></Icon>
</el-icon> </el-icon>
@ -1958,7 +2010,7 @@ const getDsIconName = data => {
><component ><component
class="svg-icon" class="svg-icon"
:class="`field-icon-${fieldType[[2, 3].includes(data.deType) ? 2 : 0]}`" :class="`field-icon-${fieldType[[2, 3].includes(data.deType) ? 2 : 0]}`"
:is="iconFieldMap[fieldType[data.deType]]" :is="getIconNameCalc(data.deType, data.extField, true)"
></component ></component
></Icon> ></Icon>
</el-icon> </el-icon>
@ -2092,6 +2144,7 @@ const getDsIconName = data => {
:class=" :class="
!!scope.row.deTypeArr && !!scope.row.deTypeArr.length && 'select-type' !!scope.row.deTypeArr && !!scope.row.deTypeArr.length && 'select-type'
" "
v-if="scope.row.extField !== 3"
popper-class="cascader-panel" popper-class="cascader-panel"
v-model="scope.row.deTypeArr" v-model="scope.row.deTypeArr"
@change="val => cascaderChange(scope.row, val)" @change="val => cascaderChange(scope.row, val)"
@ -2112,6 +2165,7 @@ const getDsIconName = data => {
<span>{{ data.label }}</span> <span>{{ data.label }}</span>
</template> </template>
</el-cascader> </el-cascader>
<div style="padding-left: 30px" v-else>{{ $t('data_set.text') }}</div>
<span class="select-svg-icon"> <span class="select-svg-icon">
<el-icon> <el-icon>
<Icon <Icon
@ -2135,7 +2189,13 @@ const getDsIconName = data => {
> >
<template #default="scope"> <template #default="scope">
<div class="column-style"> <div class="column-style">
<span class="flex-align-center icon" v-if="scope.row.extField === 0"> <span style="color: #8d9199" v-if="scope.row.extField === 2">{{
t('dataset.calc_field')
}}</span>
<span style="color: #8d9199" v-else-if="scope.row.extField === 3">{{
t('dataset.grouping_field')
}}</span>
<span class="flex-align-center icon" v-else-if="scope.row.extField === 0">
<el-icon> <el-icon>
<Icon className="primary-color" <Icon className="primary-color"
><component ><component
@ -2146,7 +2206,6 @@ const getDsIconName = data => {
</el-icon> </el-icon>
{{ fieldTypes(scope.row.deExtractType) }} {{ fieldTypes(scope.row.deExtractType) }}
</span> </span>
<span v-else style="color: #8d9199">{{ t('dataset.calc_field') }}</span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -2329,7 +2388,13 @@ const getDsIconName = data => {
> >
<template #default="scope"> <template #default="scope">
<div class="column-style"> <div class="column-style">
<span class="flex-align-center icon" v-if="scope.row.extField === 0"> <span style="color: #8d9199" v-if="scope.row.extField === 2">{{
t('dataset.calc_field')
}}</span>
<span style="color: #8d9199" v-else-if="scope.row.extField === 3">{{
t('dataset.grouping_field')
}}</span>
<span class="flex-align-center icon" v-else-if="scope.row.extField === 0">
<el-icon> <el-icon>
<Icon className="green-color" <Icon className="green-color"
><component ><component
@ -2340,7 +2405,6 @@ const getDsIconName = data => {
</el-icon> </el-icon>
{{ fieldTypes(scope.row.deExtractType) }} {{ fieldTypes(scope.row.deExtractType) }}
</span> </span>
<span v-else style="color: #8d9199">{{ t('dataset.calc_field') }}</span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -2491,7 +2555,7 @@ const getDsIconName = data => {
<el-drawer <el-drawer
:title="t('dataset.edit_union_relation')" :title="t('dataset.edit_union_relation')"
v-model="editUnion" v-model="editUnion"
custom-class="union-dataset-drawer" modal-class="union-dataset-drawer"
size="840px" size="840px"
:before-close="closeEditUnion" :before-close="closeEditUnion"
direction="rtl" direction="rtl"
@ -2509,7 +2573,7 @@ const getDsIconName = data => {
ref="creatDsFolder" ref="creatDsFolder"
></creat-ds-group> ></creat-ds-group>
<el-dialog <el-dialog
custom-class="calc-field-edit-dialog" modal-class="calc-field-edit-dialog"
v-model="editCalcField" v-model="editCalcField"
width="1000px" width="1000px"
:title="calcTitle" :title="calcTitle"
@ -2652,6 +2716,7 @@ const getDsIconName = data => {
style="width: 100%" style="width: 100%"
multiple multiple
collapse-tags collapse-tags
filterable
collapse-tags-tooltip collapse-tags-tooltip
:max-collapse-tags="2" :max-collapse-tags="2"
v-model="domain.text" v-model="domain.text"
@ -2660,6 +2725,7 @@ const getDsIconName = data => {
v-for="item in enumValue" v-for="item in enumValue"
:key="item" :key="item"
:label="item" :label="item"
:disabled="disabledEnum(item, domain.text)"
:value="item" :value="item"
/> </el-select /> </el-select
></el-form-item> ></el-form-item>
@ -2754,7 +2820,7 @@ const getDsIconName = data => {
{{ t('auth.add_condition') }} {{ t('auth.add_condition') }}
</el-button> </el-button>
<div class="line"></div> <div class="line"></div>
<div class="group-fields_item"> <div class="group-fields_item" style="align-items: center">
<el-input <el-input
:placeholder="t('common.inputText')" :placeholder="t('common.inputText')"
style="width: 278px; margin-right: 24px" style="width: 278px; margin-right: 24px"
@ -2764,7 +2830,7 @@ const getDsIconName = data => {
</div> </div>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button secondary @click="closeGroupField">{{ t('dataset.cancel') }}</el-button> <el-button secondary @click="closeGroupField">{{ t('dataset.cancel') }} </el-button>
<el-button type="primary" @click="confirmGroupField">{{ t('dataset.confirm') }} </el-button> <el-button type="primary" @click="confirmGroupField">{{ t('dataset.confirm') }} </el-button>
</template> </template>
</el-dialog> </el-dialog>
@ -2918,8 +2984,6 @@ const getDsIconName = data => {
} }
.table-list { .table-list {
background: #252626;
color: #ffffff;
.list-item_primary { .list-item_primary {
padding: 8px; padding: 8px;
} }
@ -3568,7 +3632,7 @@ border-right: 1px solid rgba(54, 54, 54, 1)
background: rgba(40, 40, 40, 1); background: rgba(40, 40, 40, 1);
color: #C9C9C9; color: #C9C9C9;
border-right: 1px solid rgba(54, 54, 54, 1); border-right: 1px solid rgba(54, 54, 54, 1);
} }
.ed-table-v2__header-row{ .ed-table-v2__header-row{
border-bottom: 1px solid rgba(54, 54, 54, 1) border-bottom: 1px solid rgba(54, 54, 54, 1)
@ -3655,4 +3719,4 @@ border-right: 1px solid rgba(54, 54, 54, 1)
.de-dataset-form .container .arrow-right:hover .ed-icon{ .de-dataset-form .container .arrow-right:hover .ed-icon{
color: #fff !important; color: #fff !important;
} }
</style> </style>

View File

@ -1,14 +1,16 @@
<script lang="tsx" setup> <script lang="tsx" setup>
import Header from '../header.vue'
import { findApplicationById } from "@/api/application/application";
import icon_copy_filled from '@/assets/svg/icon_copy_filled.svg' import icon_copy_filled from '@/assets/svg/icon_copy_filled.svg'
import icon_dataset from '@/assets/svg/icon_dataset.svg' import icon_dataset from '@/assets/svg/icon_dataset.svg'
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg' import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
import icon_intoItem_outlined from '@/assets/svg/icon_into-item_outlined.svg' import icon_intoItem_outlined from '@/assets/svg/icon_into-item_outlined.svg'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import icon_rename_outlined from '@/assets/svg/icon_rename_outlined.svg' import icon_rename_outlined from '@/assets/svg/icon_rename_outlined.svg'
import dvNewFolder from '@/assets/svg/dv-new-folder.svg'
import icon_fileAdd_outlined from '@/assets/svg/icon_file-add_outlined.svg'
import { moveDatasetTree } from '@/api/dataset' import { moveDatasetTree } from '@/api/dataset'
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg' import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
import dvSortAsc from '@/assets/svg/dv-sort-asc.svg'
import dvSortDesc from '@/assets/svg/dv-sort-desc.svg'
import dvFolder from '@/assets/svg/dv-folder.svg' import dvFolder from '@/assets/svg/dv-folder.svg'
import { treeDraggble } from '@/utils/treeDraggble' import { treeDraggble } from '@/utils/treeDraggble'
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg' import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
@ -28,8 +30,7 @@ import {
nextTick, nextTick,
unref, unref,
h, h,
provide, provide
onMounted
} from 'vue' } from 'vue'
import ArrowSide from '@/viewsnew/common/DeResourceArrow.vue' import ArrowSide from '@/viewsnew/common/DeResourceArrow.vue'
import { useEmbedded } from '@/store/modules/embedded' import { useEmbedded } from '@/store/modules/embedded'
@ -99,7 +100,7 @@ onMounted(() => {
}) })
} }
}) })
const projectInfo:any = ref({}) const projectInfo:any = ref({})
@ -151,7 +152,8 @@ const datasetTableFiled = ref([])
provide('filedList', datasetTableFiled) provide('filedList', datasetTableFiled)
const nickName = ref('') const nickName = ref('')
const router = useRouter()
const route = useRoute()
const state = reactive({ const state = reactive({
datasetTree: [] as BusiTreeNode[], datasetTree: [] as BusiTreeNode[],
curSortType: 'time_desc' curSortType: 'time_desc'
@ -416,6 +418,7 @@ const save = ({ logic, items, errorMessage }) => {
table.value.id = nodeInfo.id table.value.id = nodeInfo.id
table.value.row = 100000 table.value.row = 100000
table.value.filename = exportForm.value.name table.value.filename = exportForm.value.name
table.value.dataEaseBi = isDataEaseBi.value || appStore.getIsIframe
if (errorMessage) { if (errorMessage) {
ElMessage.error(errorMessage) ElMessage.error(errorMessage)
return return
@ -424,10 +427,17 @@ const save = ({ logic, items, errorMessage }) => {
exportDatasetLoading.value = true exportDatasetLoading.value = true
exportDatasetData(table.value) exportDatasetData(table.value)
.then(res => { .then(res => {
if (res.code === 0) { if (isDataEaseBi.value || appStore.getIsIframe) {
openMessageLoading(exportData) const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' })
const link = document.createElement('a')
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = table.value.filename + '.xlsx' //
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
} else { } else {
ElMessage.error(res.msg) openMessageLoading(exportData)
} }
}) })
.finally(() => { .finally(() => {
@ -652,6 +662,7 @@ const operation = (cmd: string, data: BusiTreeNode, nodeType: string) => {
creatDsFolder.value.createInit(nodeType, data, cmd) creatDsFolder.value.createInit(nodeType, data, cmd)
} }
} }
const handleDatasetTree = (cmd: string, data?: BusiTreeNode) => { const handleDatasetTree = (cmd: string, data?: BusiTreeNode) => {
data.appId = applicationId.value data.appId = applicationId.value
if (cmd === 'dataset') { if (cmd === 'dataset') {
@ -677,6 +688,7 @@ const menuList = [
}, },
{ {
label: t('common.delete'), label: t('common.delete'),
divided: true,
svgName: icon_deleteTrash_outlined, svgName: icon_deleteTrash_outlined,
command: 'delete' command: 'delete'
} }
@ -857,7 +869,7 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
placement="top" placement="top"
> >
<img src="@/assets/newimg/u43.png" alt="" style="cursor: pointer;" <img src="@/assets/newimg/u43.png" alt="" style="cursor: pointer;"
@click="createDataset"> @click="createDataset">
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
@ -875,6 +887,34 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
</el-icon> </el-icon>
</template> </template>
</el-input> </el-input>
<el-dropdown @command="handleSortTypeChange" trigger="click">
<el-icon class="filter-icon-span">
<el-tooltip :offset="16" effect="dark" :content="sortTypeTip" placement="top">
<Icon name="dv-sort-asc" class="opt-icon"
><dvSortAsc v-if="state.curSortType.includes('asc')" class="svg-icon opt-icon"
/></Icon>
</el-tooltip>
<el-tooltip :offset="16" effect="dark" :content="sortTypeTip" placement="top">
<Icon name="dv-sort-desc" class="opt-icon"
><dvSortDesc v-if="state.curSortType.includes('desc')" class="svg-icon"
/></Icon>
</el-tooltip>
</el-icon>
<template #dropdown>
<el-dropdown-menu style="width: 246px">
<template :key="ele.value" v-for="ele in sortList">
<el-dropdown-item
class="ed-select-dropdown__item"
:class="ele.value === state.curSortType && 'selected'"
:command="ele.value"
>
{{ ele.name }}
</el-dropdown-item>
<li v-if="ele.divided" class="ed-dropdown-menu__item--divided"></li>
</template>
</el-dropdown-menu>
</template>
</el-dropdown>
</div> </div>
<el-scrollbar class="custom-tree"> <el-scrollbar class="custom-tree">
@ -1013,7 +1053,9 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
</div> </div>
</div> </div>
<div class="dataset-table-info"> <div class="dataset-table-info">
<div v-if="activeName === 'dataPreview'" class="preview-num">
{{ t('data_set.pieces_in_total', { msg: total }) }}
</div>
<template v-if="['dataPreview', 'structPreview'].includes(activeName)"> <template v-if="['dataPreview', 'structPreview'].includes(activeName)">
<div class="info-table" :class="[{ 'struct-preview': activeName === 'structPreview' }]"> <div class="info-table" :class="[{ 'struct-preview': activeName === 'structPreview' }]">
<el-auto-resizer v-if="activeName === 'structPreview'"> <el-auto-resizer v-if="activeName === 'structPreview'">
@ -1022,12 +1064,11 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
key="structPreview" key="structPreview"
:columns="columns" :columns="columns"
v-loading="dataPreviewLoading" v-loading="dataPreviewLoading"
header-class="header-cell"
:data="tableData" :data="tableData"
header-class="excel-header-cell"
:width="width" :width="width"
:height="height" :height="height"
fixed fixed
border
><template #empty> ><template #empty>
<empty-background <empty-background
:description="t('data_set.no_data')" :description="t('data_set.no_data')"
@ -1040,7 +1081,6 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
<el-table <el-table
v-loading="dataPreviewLoading" v-loading="dataPreviewLoading"
class="dataset-preview_table" class="dataset-preview_table"
header-class="header-cell"
:data="tableData" :data="tableData"
@row-click="rowClick" @row-click="rowClick"
key="dataPreview" key="dataPreview"
@ -1093,9 +1133,6 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
/> />
</div> </div>
</template> </template>
<div v-if="activeName === 'dataPreview'" class="preview-num">
{{ t('data_set.pieces_in_total', { msg: total }) }}
</div>
</div> </div>
</template> </template>
<template v-else-if="mounted"> <template v-else-if="mounted">
@ -1202,6 +1239,10 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
background: #eff0f1; background: #eff0f1;
} }
} }
.custom-tree {
height: calc(100vh - 172px);
padding: 0 8px;
}
.dataset-manage { .dataset-manage {
display: flex; display: flex;
width: 100%; width: 100%;
@ -1384,11 +1425,6 @@ const proxyAllowDrop = debounce((arg1, arg2) => {
} }
} }
.custom-tree {
height: calc(100vh - 172px);
padding: 0 8px;
}
.custom-tree-node { .custom-tree-node {
width: calc(100% - 30px); width: calc(100% - 30px);
display: flex; display: flex;
@ -1742,4 +1778,4 @@ border-right: 1px solid rgba(54, 54, 54, 1)
.tree-cont::-webkit-scrollbar-corner { .tree-cont::-webkit-scrollbar-corner {
background: #3f3f3f !important; background: #3f3f3f !important;
} }
</style> </style>