forked from github/dataease
feat(数据集): V2 数据集计算字段支持设置参数,跟过滤组件绑定
This commit is contained in:
parent
ca1b268c22
commit
9c4939a20a
1
core/core-frontend/src/assets/svg/caculate.svg
Normal file
1
core/core-frontend/src/assets/svg/caculate.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723085278911" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1923" id="mx_n_1723085278912" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M256 0H153.6v153.6H0v102.4h153.6v153.6h102.4V256h153.6V153.6H256V0zM313.344 637.952L204.8 747.008l-108.544-109.056-72.704 72.704L132.608 819.2 23.552 927.744l72.704 72.704L204.8 891.392l108.544 109.056 72.704-72.704L276.992 819.2l109.056-108.544-72.704-72.704zM614.4 153.6h409.6v102.4h-409.6zM614.4 768h409.6v102.4h-409.6z" p-id="1924"></path><path d="M819.2 972.8m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" p-id="1925"></path><path d="M819.2 665.6m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" p-id="1926"></path></svg>
|
After Width: | Height: | Size: 904 B |
@ -3,6 +3,7 @@ import { computed } from 'vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
import _401 from '@/assets/svg/401.svg'
|
||||
import caculate from '@/assets/svg/caculate.svg'
|
||||
import _403 from '@/assets/svg/403.svg'
|
||||
import APIDs from '@/assets/svg/API-ds.svg'
|
||||
import Apache_Hive from '@/assets/svg/Apache Hive.svg'
|
||||
@ -1330,6 +1331,7 @@ const iconMap = {
|
||||
'word-cloud-dark': wordCloudDark,
|
||||
'word-cloud-origin': wordCloudOrigin,
|
||||
'word-cloud': wordCloud,
|
||||
caculate,
|
||||
'icon_file-doc_colorful': icon_file_doc_colorful
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import { ref, reactive, onMounted, onBeforeUnmount, watch, unref, computed, nextTick } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import CodeMirror from './CodeMirror.vue'
|
||||
import { getFunction } from '@/api/dataset'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { guid } from './util'
|
||||
export interface CalcFieldType {
|
||||
id?: string
|
||||
datasourceId?: string // 数据源id
|
||||
@ -15,6 +16,7 @@ export interface CalcFieldType {
|
||||
dataeaseName?: string // 字段别名
|
||||
groupType: 'd' | 'q' // d=维度,q=指标
|
||||
type: string
|
||||
params?: Array<{ id: string; name: string; value: number }>
|
||||
checked: boolean
|
||||
deType: number // 字段类型
|
||||
deExtractType?: number // 字段原始类型
|
||||
@ -65,6 +67,60 @@ const state = reactive({
|
||||
quotaList: [],
|
||||
quotaData: []
|
||||
})
|
||||
const formQuotaRef = ref()
|
||||
const formQuota = reactive({
|
||||
id: null,
|
||||
name: '',
|
||||
value: null
|
||||
})
|
||||
const dialogFormVisible = ref(false)
|
||||
const formQuotaRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入参数名称', trigger: 'blur' },
|
||||
{ min: 1, max: 50, message: '请输入1-50个字符', trigger: 'blur' }
|
||||
],
|
||||
value: [{ required: true, message: '请输入参数默认值', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const formQuotaClose = () => {
|
||||
formQuotaRef.value.resetFields()
|
||||
dialogFormVisible.value = false
|
||||
}
|
||||
|
||||
const formQuotaConfirm = () => {
|
||||
formQuotaRef.value.validate(val => {
|
||||
if (val) {
|
||||
if (!formQuota.id) {
|
||||
formQuota.id = `params_${guid()}`
|
||||
}
|
||||
const q = cloneDeep(unref(formQuota))
|
||||
fieldForm.params = [q]
|
||||
const i = state.quotaData.find(ele => ele.id === formQuota.id)
|
||||
const j = state.quotaList.find(ele => ele.id === formQuota.id)
|
||||
if (i && j) {
|
||||
const str = mirror.value.state.doc.toString()
|
||||
const name2Auto = []
|
||||
fieldForm.originName = setNameIdTrans('name', 'id', str, name2Auto)
|
||||
Object.assign(i, cloneDeep(unref(formQuota)))
|
||||
Object.assign(j, cloneDeep(unref(formQuota)))
|
||||
|
||||
nextTick(() => {
|
||||
mirror.value.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: mirror.value.viewState.state.doc.length,
|
||||
insert: setNameIdTrans('id', 'name', fieldForm.originName)
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
state.quotaData.push(q)
|
||||
state.quotaList.push(q)
|
||||
}
|
||||
formQuotaClose()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const fieldForm = reactive<CalcFieldType>({ ...(defaultForm as CalcFieldType) })
|
||||
|
||||
@ -98,8 +154,8 @@ let dimensionDataList = []
|
||||
const initEdit = (obj, dimensionData, quotaData) => {
|
||||
Object.assign(fieldForm, { ...defaultForm, ...obj })
|
||||
state.dimensionData = dimensionData
|
||||
state.quotaData = quotaData
|
||||
quotaDataList = cloneDeep(quotaData)
|
||||
state.quotaData = quotaData.concat(fieldForm.params || [])
|
||||
quotaDataList = cloneDeep(quotaData.concat(fieldForm.params || []))
|
||||
dimensionDataList = cloneDeep(dimensionData)
|
||||
setTimeout(() => {
|
||||
formField.value.clearValidate()
|
||||
@ -114,12 +170,14 @@ const initEdit = (obj, dimensionData, quotaData) => {
|
||||
})
|
||||
return
|
||||
}
|
||||
mirror.value.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: mirror.value.viewState.state.doc.length,
|
||||
insert: setNameIdTrans('id', 'name', obj.originName)
|
||||
}
|
||||
nextTick(() => {
|
||||
mirror.value.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: mirror.value.viewState.state.doc.length,
|
||||
insert: setNameIdTrans('id', 'name', obj.originName)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -206,6 +264,40 @@ defineExpose({
|
||||
formField
|
||||
})
|
||||
|
||||
const addParmasToQuota = () => {
|
||||
if (disableCaParams.value) return
|
||||
if (!fieldForm.params) {
|
||||
fieldForm.params = []
|
||||
}
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
|
||||
const updateParmasToQuota = () => {
|
||||
const [o] = fieldForm.params
|
||||
Object.assign(formQuota, o || {})
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
|
||||
const disableCaParams = computed(() => {
|
||||
return !!fieldForm.params?.length
|
||||
})
|
||||
|
||||
const delParmasToQuota = () => {
|
||||
const [o] = fieldForm.params
|
||||
fieldForm.params = []
|
||||
const str = mirror.value.state.doc.toString()
|
||||
const name2Auto = []
|
||||
fieldForm.originName = setNameIdTrans('name', 'id', str, name2Auto).replaceAll(`[${o.id}]`, '')
|
||||
state.quotaData = state.quotaData.filter(ele => ele.id !== o.id)
|
||||
state.quotaList = state.quotaList.filter(ele => ele.id !== o.id)
|
||||
mirror.value.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: mirror.value.viewState.state.doc.length,
|
||||
insert: setNameIdTrans('id', 'name', fieldForm.originName)
|
||||
}
|
||||
})
|
||||
}
|
||||
initFunction()
|
||||
</script>
|
||||
|
||||
@ -358,7 +450,21 @@ initFunction()
|
||||
<div v-else class="class-na">{{ t('dataset.na') }}</div>
|
||||
</div>
|
||||
<div class="field-height">
|
||||
<span>{{ t('chart.quota') }}</span>
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<span>{{ t('chart.quota') }}</span>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="disableCaParams ? '仅支持添加一个计算参数。' : '添加计算参数'"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon class="hover-icon_quota" @click="addParmasToQuota">
|
||||
<Icon
|
||||
:class="[`field-icon-${fieldType[0]}`, disableCaParams && 'not-allow']"
|
||||
name="caculate"
|
||||
></Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div v-if="state.quotaData.length" class="field-list">
|
||||
<span
|
||||
v-for="item in state.quotaData"
|
||||
@ -367,13 +473,24 @@ initFunction()
|
||||
:title="item.name"
|
||||
@click="insertFieldToCodeMirror('[' + item.name + ']')"
|
||||
>
|
||||
<el-icon>
|
||||
<el-icon v-if="!item.groupType">
|
||||
<Icon name="caculate"></Icon>
|
||||
</el-icon>
|
||||
<el-icon v-else>
|
||||
<Icon
|
||||
:name="`field_${fieldType[item.deType]}`"
|
||||
:className="`field-icon-${fieldType[item.deType]}`"
|
||||
></Icon>
|
||||
</el-icon>
|
||||
{{ item.name }}
|
||||
<div v-if="!item.groupType" class="icon-right">
|
||||
<el-icon @click.stop="updateParmasToQuota" class="hover-icon">
|
||||
<Icon name="icon_edit_outlined"></Icon>
|
||||
</el-icon>
|
||||
<el-icon @click.stop="delParmasToQuota" class="hover-icon">
|
||||
<Icon name="icon_delete-trash_outlined"></Icon>
|
||||
</el-icon>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div v-else class="class-na">{{ t('dataset.na') }}</div>
|
||||
@ -440,6 +557,32 @@ initFunction()
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
:before-close="formQuotaClose"
|
||||
v-model="dialogFormVisible"
|
||||
title="添加计算参数"
|
||||
width="500"
|
||||
>
|
||||
<el-form label-position="top" ref="formQuotaRef" :model="formQuota" :rules="formQuotaRules">
|
||||
<el-form-item label="参数名称" prop="name">
|
||||
<el-input style="width: 100%" v-model="formQuota.name" placeholder="请输入1-50个字符" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数默认值" prop="value">
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
v-model="formQuota.value"
|
||||
placeholder="请输入一个数字"
|
||||
controls-position="right"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="formQuotaClose">取消</el-button>
|
||||
<el-button type="primary" @click="formQuotaConfirm"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -537,6 +680,30 @@ initFunction()
|
||||
& > :nth-child(1) {
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.hover-icon_quota {
|
||||
cursor: pointer;
|
||||
height: 20px !important;
|
||||
width: 20px !important;
|
||||
border-radius: 4px;
|
||||
|
||||
&[aria-expanded='true'] {
|
||||
background: rgba(31, 35, 41, 0.1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(31, 35, 41, 0.1);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: rgba(31, 35, 41, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.not-allow {
|
||||
cursor: not-allowed;
|
||||
color: #bbbfc4 !important;
|
||||
}
|
||||
}
|
||||
.item-dimension,
|
||||
.item-quota {
|
||||
@ -553,6 +720,15 @@ initFunction()
|
||||
margin-top: 4px;
|
||||
word-break: break-all;
|
||||
border-radius: 4px;
|
||||
|
||||
.icon-right {
|
||||
display: none;
|
||||
margin-left: auto;
|
||||
align-items: center;
|
||||
.ed-icon {
|
||||
margin: 0 0 0 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-dimension:hover {
|
||||
@ -571,6 +747,9 @@ initFunction()
|
||||
background: rgba(4, 180, 156, 0.1);
|
||||
border-color: #04b49c;
|
||||
cursor: pointer;
|
||||
.icon-right {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.function-style {
|
||||
|
@ -1462,7 +1462,7 @@ const getDsIconName = data => {
|
||||
:itemSize="40"
|
||||
:data="datasourceTableData"
|
||||
:total="datasourceTableData.length"
|
||||
:width="LeftWidth - 7"
|
||||
:width="LeftWidth - 17"
|
||||
:height="height - 305"
|
||||
:scrollbarAlwaysOn="false"
|
||||
class-name="el-select-dropdown__list"
|
||||
|
Loading…
Reference in New Issue
Block a user