mirror of
https://github.com/dataease/dataease.git
synced 2026-05-23 22:08:34 +08:00
fix(数据集): 数据集设置规则并导出,导出失败
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { inject, computed, ref, nextTick, provide } from 'vue'
|
||||
import RowAuth from '@/views/chart/components/editor/filter/auth-tree/RowAuth.vue'
|
||||
import RowAuth from '@/views/chart/components/editor/filter/auth-tree-chart/RowAuth.vue'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
|
||||
const emits = defineEmits(['filter-data'])
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
<script lang="ts">
|
||||
import icon_down_outlined from '@/assets/svg/icon_down_outlined.svg'
|
||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||
export default {
|
||||
name: 'logic-relation'
|
||||
}
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { PropType, computed, toRefs } from 'vue'
|
||||
import FilterFiled from './FilterFiled.vue'
|
||||
import type { Item } from './FilterFiled.vue'
|
||||
export type Logic = 'or' | 'and'
|
||||
export type Relation = {
|
||||
child?: Relation[]
|
||||
logic: Logic
|
||||
x: number
|
||||
} & Item
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
relationList: {
|
||||
type: Array as PropType<Relation[]>,
|
||||
default: () => []
|
||||
},
|
||||
x: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
logic: {
|
||||
type: String as PropType<Logic>,
|
||||
default: 'or'
|
||||
}
|
||||
})
|
||||
|
||||
const marginLeft = computed(() => {
|
||||
return {
|
||||
marginLeft: props.x ? '20px' : 0
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits([
|
||||
'addCondReal',
|
||||
'changeAndOrDfs',
|
||||
'update:logic',
|
||||
'removeRelationList',
|
||||
'del'
|
||||
])
|
||||
|
||||
const { relationList } = toRefs(props)
|
||||
|
||||
const handleCommand = type => {
|
||||
emits('update:logic', type)
|
||||
emits('changeAndOrDfs', type)
|
||||
}
|
||||
|
||||
const removeRelationList = index => {
|
||||
relationList.value.splice(index, 1)
|
||||
}
|
||||
const addCondReal = type => {
|
||||
emits('addCondReal', type, props.logic === 'or' ? 'and' : 'or')
|
||||
}
|
||||
const add = (type, child, logic) => {
|
||||
child.push(
|
||||
type === 'condition'
|
||||
? {
|
||||
fieldId: '',
|
||||
value: '',
|
||||
enumValue: '',
|
||||
term: '',
|
||||
filterType: 'logic',
|
||||
name: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
timeValue: '',
|
||||
dynamicTimeSetting: {},
|
||||
deType: ''
|
||||
}
|
||||
: { child: [], logic }
|
||||
)
|
||||
}
|
||||
const del = (index, child) => {
|
||||
child.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="logic" :style="marginLeft">
|
||||
<div class="logic-left">
|
||||
<div class="operate-title">
|
||||
<span style="color: #bfbfbf" class="mrg-title" v-if="x">
|
||||
{{ logic === 'or' ? 'OR' : 'AND' }}
|
||||
</span>
|
||||
<el-dropdown @command="handleCommand" trigger="click" v-else>
|
||||
<span style="color: rgba(0 0 0 / 65%)" class="mrg-title fir">
|
||||
{{ logic === 'or' ? 'OR' : 'AND' }}
|
||||
<el-icon>
|
||||
<Icon name="icon_down_outlined"><icon_down_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="and">AND</el-dropdown-item>
|
||||
<el-dropdown-item command="or">OR</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<span class="operate-icon" v-if="x">
|
||||
<el-icon @click="emits('removeRelationList')">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</span>
|
||||
</div>
|
||||
<div class="logic-right">
|
||||
<template :key="index" v-for="(item, index) in relationList">
|
||||
<logic-relation
|
||||
v-if="item.child"
|
||||
:x="item.x"
|
||||
@del="idx => del(idx, item.child)"
|
||||
@addCondReal="(type, logic) => add(type, item.child, logic)"
|
||||
:logic="item.logic"
|
||||
@removeRelationList="removeRelationList(index)"
|
||||
:relationList="item.child"
|
||||
>
|
||||
</logic-relation>
|
||||
<filter-filed v-else :item="item" @del="emits('del', index)" :index="index"></filter-filed>
|
||||
</template>
|
||||
<div class="logic-right-add">
|
||||
<button @click="addCondReal('condition')" class="operand-btn">
|
||||
+ {{ t('auth.add_condition') }}
|
||||
</button>
|
||||
<button v-if="x < 2" @click="addCondReal('relation')" class="operand-btn">
|
||||
+ {{ t('auth.add_relationship') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.logic {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
|
||||
.logic-left {
|
||||
box-sizing: border-box;
|
||||
width: 48px;
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
|
||||
.operate-title {
|
||||
font-family: var(--de-custom_font, 'PingFang');
|
||||
word-wrap: break-word;
|
||||
box-sizing: border-box;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
font-size: 12px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 65px;
|
||||
background-color: #f8f8fa;
|
||||
line-height: 28px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 28px;
|
||||
|
||||
.mrg-title {
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-left: 11px;
|
||||
margin-right: 11px;
|
||||
line-height: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.operate-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.operate-title {
|
||||
.mrg-title:not(.fir) {
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operate-icon {
|
||||
width: 40px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
background-color: #f8f8fa;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
display: unset;
|
||||
padding: 5px 3px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logic-right-add {
|
||||
display: flex;
|
||||
height: 41.4px;
|
||||
align-items: center;
|
||||
padding-left: 26px;
|
||||
|
||||
.operand-btn {
|
||||
box-sizing: border-box;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
outline: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
margin-right: 10px;
|
||||
font-size: 12px;
|
||||
color: #246dff;
|
||||
background: #fff;
|
||||
border: 1px solid #246dff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,447 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import AuthTree from './AuthTree.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const errorMessage = ref('')
|
||||
const logic = ref<'or' | 'and'>('or')
|
||||
const relationList = ref([])
|
||||
|
||||
const svgRealinePath = computed(() => {
|
||||
const lg = relationList.value.length
|
||||
let a = { x: 0, y: 0, child: relationList.value }
|
||||
a.y = Math.floor(dfsXY(a, 0) / 2)
|
||||
if (!lg) return ''
|
||||
let path = calculateDepth(a)
|
||||
return path
|
||||
})
|
||||
|
||||
const svgDashinePath = computed(() => {
|
||||
const lg = relationList.value.length
|
||||
let a = { x: 0, y: 0, child: relationList.value }
|
||||
a.y = Math.floor(dfsXY(a, 0) / 2)
|
||||
if (!lg) return `M48 20 L68 20`
|
||||
let path = calculateDepthDash(a)
|
||||
return path
|
||||
})
|
||||
|
||||
const init = expressionTree => {
|
||||
const { items } = expressionTree
|
||||
logic.value = expressionTree.logic || 'or'
|
||||
relationList.value = dfsInit(items || [])
|
||||
}
|
||||
const submit = () => {
|
||||
errorMessage.value = ''
|
||||
emits('save', {
|
||||
logic: logic.value,
|
||||
items: dfsSubmit(relationList.value),
|
||||
errorMessage: errorMessage.value
|
||||
})
|
||||
}
|
||||
const errorDetected = ({
|
||||
enumValue,
|
||||
deType,
|
||||
filterType,
|
||||
term,
|
||||
value,
|
||||
name,
|
||||
timeValue,
|
||||
filterTypeTime
|
||||
}) => {
|
||||
if (!name) {
|
||||
errorMessage.value = t('data_set.cannot_be_empty_')
|
||||
return
|
||||
}
|
||||
if (filterType === 'logic') {
|
||||
if (!term) {
|
||||
errorMessage.value = t('data_set.cannot_be_empty_de_ruler')
|
||||
return
|
||||
}
|
||||
if (
|
||||
!term.includes('null') &&
|
||||
!term.includes('empty') &&
|
||||
['', null, undefined].includes(value) &&
|
||||
deType !== 1
|
||||
) {
|
||||
errorMessage.value = t('chart.filter_value_can_null')
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
!term.includes('null') &&
|
||||
!term.includes('empty') &&
|
||||
['', null, undefined].includes(timeValue) &&
|
||||
deType === 1 &&
|
||||
filterTypeTime === 'dynamicDate'
|
||||
) {
|
||||
errorMessage.value = t('chart.filter_value_can_null')
|
||||
return
|
||||
}
|
||||
if ([2, 3].includes(deType)) {
|
||||
if (parseFloat(value).toString() === 'NaN') {
|
||||
errorMessage.value = t('chart.filter_value_can_not_str')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterType === 'enum') {
|
||||
if (enumValue.length < 1) {
|
||||
errorMessage.value = t('chart.enum_value_can_not_null')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getTimeValue = dynamicTimeSetting => {
|
||||
const relativeToCurrentTypeMap = {
|
||||
year: '年',
|
||||
month: '月',
|
||||
date: '日',
|
||||
datetime: '日'
|
||||
}
|
||||
let timeValue = ''
|
||||
const {
|
||||
timeGranularity,
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
around,
|
||||
arbitraryTime,
|
||||
relativeToCurrent
|
||||
} = dynamicTimeSetting || {}
|
||||
if (relativeToCurrent !== 'custom') {
|
||||
timeValue = [
|
||||
{
|
||||
label: '今年',
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
value: 'lastYear'
|
||||
},
|
||||
{
|
||||
label: '本月',
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
label: '今天',
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
].find(ele => ele.value === relativeToCurrent)?.label
|
||||
return timeValue
|
||||
}
|
||||
timeValue = `${timeNum}${relativeToCurrentTypeMap[relativeToCurrentType]}${
|
||||
around === 'f' ? '前' : '后'
|
||||
}`
|
||||
if (timeGranularity === 'datetime') {
|
||||
timeValue += new Date(arbitraryTime).toLocaleString().split(' ')[1]
|
||||
}
|
||||
|
||||
return timeValue
|
||||
}
|
||||
const dfsInit = arr => {
|
||||
const elementList = []
|
||||
arr.forEach(ele => {
|
||||
const { subTree } = ele
|
||||
if (subTree) {
|
||||
const { items = [], logic } = subTree
|
||||
const child = dfsInit(items)
|
||||
elementList.push({ logic, child })
|
||||
} else {
|
||||
const {
|
||||
enumValue,
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
fieldId,
|
||||
filterType,
|
||||
term,
|
||||
value,
|
||||
field
|
||||
} = ele
|
||||
const { name, deType } = field || {}
|
||||
elementList.push({
|
||||
enumValue: enumValue.join(','),
|
||||
fieldId,
|
||||
filterType,
|
||||
term,
|
||||
timeValue: getTimeValue(dynamicTimeSetting),
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
value,
|
||||
name,
|
||||
deType
|
||||
})
|
||||
}
|
||||
})
|
||||
return elementList
|
||||
}
|
||||
const dfsSubmit = arr => {
|
||||
const items = []
|
||||
arr.forEach(ele => {
|
||||
const { child = [] } = ele
|
||||
if (child.length) {
|
||||
const { logic } = ele
|
||||
const subTree = dfsSubmit(child)
|
||||
items.push({
|
||||
enumValue: [],
|
||||
fieldId: '',
|
||||
filterType: '',
|
||||
term: '',
|
||||
type: 'tree',
|
||||
value: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
timeValue: '',
|
||||
dynamicTimeSetting: {},
|
||||
subTree: { logic, items: subTree }
|
||||
})
|
||||
} else {
|
||||
const {
|
||||
enumValue,
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
fieldId,
|
||||
filterType,
|
||||
deType,
|
||||
term,
|
||||
value,
|
||||
name,
|
||||
timeValue
|
||||
} = ele
|
||||
errorDetected({ deType, enumValue, filterType, term, value, name, timeValue, filterTypeTime })
|
||||
if (fieldId) {
|
||||
items.push({
|
||||
enumValue: enumValue ? enumValue.split(',') : [],
|
||||
fieldId,
|
||||
timeValue,
|
||||
filterType,
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
term,
|
||||
value,
|
||||
type: 'item',
|
||||
subTree: null
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return items
|
||||
}
|
||||
const removeRelationList = () => {
|
||||
relationList.value = []
|
||||
}
|
||||
const getY = arr => {
|
||||
const [a] = arr
|
||||
if (a.child?.length) {
|
||||
return getY(a.child)
|
||||
}
|
||||
return a.y
|
||||
}
|
||||
const calculateDepthDash = obj => {
|
||||
const lg = obj.child?.length
|
||||
let path = ''
|
||||
if (!lg && Array.isArray(obj.child)) {
|
||||
const { x, y } = obj
|
||||
path += `M${48 + x * 68} ${y * 41.4 + 20} L${88 + x * 68} ${y * 41.4 + 20}`
|
||||
} else if (obj.child?.length) {
|
||||
let y = Math.max(dfsY(obj, 0), dfs(obj.child, 0) + getY(obj.child) - 1)
|
||||
let parent = (dfs(obj.child, 0) * 41.4) / 2 + (getY(obj.child) || 0) * 41.4
|
||||
const { x } = obj
|
||||
path += `M${24 + x * 68} ${parent} L${24 + x * 68} ${y * 41.4 + 20} L${64 + x * 68} ${
|
||||
y * 41.4 + 20
|
||||
}`
|
||||
obj.child.forEach(item => {
|
||||
path += calculateDepthDash(item)
|
||||
})
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
const calculateDepth = obj => {
|
||||
const lg = obj.child.length
|
||||
if (!lg) return ''
|
||||
let path = ''
|
||||
const { x: depth, y } = obj
|
||||
obj.child.forEach((item, index) => {
|
||||
const { y: sibingLg, z } = item
|
||||
if (item.child?.length) {
|
||||
let parent = (dfs(obj.child, 0) * 41.4) / 2 + (getY(obj.child) || 0) * 41.4
|
||||
let children = (dfs(item.child, 0) * 41.4) / 2 + getY(item.child) * 41.4
|
||||
let path1 = 0
|
||||
let path2 = 0
|
||||
if (parent < children) {
|
||||
path1 = parent
|
||||
path2 = children
|
||||
} else {
|
||||
;[path1, path2] = [children, parent]
|
||||
}
|
||||
if (y >= sibingLg) {
|
||||
path1 = parent
|
||||
path2 = children
|
||||
}
|
||||
path += `M${24 + depth * 68} ${path1} L${24 + depth * 68} ${path2} L${
|
||||
68 + depth * 68
|
||||
} ${path2}`
|
||||
path += calculateDepth(item)
|
||||
}
|
||||
if (!item.child?.length) {
|
||||
if (sibingLg >= y) {
|
||||
path += `M${24 + depth * 68} ${y * 40} L${24 + depth * 68} ${
|
||||
(sibingLg + 1) * 41.4 - 20.69921875
|
||||
} L${68 + depth * 68} ${(sibingLg + 1) * 41.4 - 20.69921875}`
|
||||
} else {
|
||||
path += `M${24 + depth * 68} ${
|
||||
(sibingLg +
|
||||
(lg === 1 && index === 0 ? 0 : 1) +
|
||||
(obj.child[index + 1]?.child?.length ? y - sibingLg - 1 : 0)) *
|
||||
41.4 +
|
||||
20 +
|
||||
(lg === 1 && index === 0 ? 26 : 0)
|
||||
} L${24 + depth * 68} ${
|
||||
(sibingLg + 1) * 41.4 - 20.69921875 - (lg === 1 && index === 0 ? (z || 0) * 1.4 : 0)
|
||||
} L${68 + depth * 68} ${
|
||||
(sibingLg + 1) * 41.4 - 20.69921875 - (lg === 1 && index === 0 ? (z || 0) * 1.4 : 0)
|
||||
}`
|
||||
}
|
||||
}
|
||||
})
|
||||
return path
|
||||
}
|
||||
const changeAndOrDfs = (arr, logic) => {
|
||||
arr.forEach(ele => {
|
||||
if (ele.child) {
|
||||
ele.logic = logic === 'and' ? 'or' : 'and'
|
||||
changeAndOrDfs(ele.child, ele.logic)
|
||||
}
|
||||
})
|
||||
}
|
||||
const dfs = (arr, count) => {
|
||||
arr.forEach(ele => {
|
||||
if (ele.child?.length) {
|
||||
count = dfs(ele.child, count)
|
||||
} else {
|
||||
count += 1
|
||||
}
|
||||
})
|
||||
count += 1
|
||||
return count
|
||||
}
|
||||
const dfsY = (obj, count) => {
|
||||
obj.child.forEach(ele => {
|
||||
if (ele.child?.length) {
|
||||
count = dfsY(ele, count)
|
||||
} else {
|
||||
count = Math.max(count, ele.y, obj.y)
|
||||
}
|
||||
})
|
||||
return count
|
||||
}
|
||||
const dfsXY = (obj, count) => {
|
||||
obj.child.forEach(ele => {
|
||||
ele.x = obj.x + 1
|
||||
if (ele.child?.length) {
|
||||
let l = dfs(ele.child, 0)
|
||||
ele.y = Math.floor(l / 2) + count
|
||||
count = dfsXY(ele, count)
|
||||
} else {
|
||||
count += 1
|
||||
ele.y = count - 1
|
||||
}
|
||||
})
|
||||
count += 1
|
||||
return count
|
||||
}
|
||||
const addCondReal = (type, logic) => {
|
||||
relationList.value.push(
|
||||
type === 'condition'
|
||||
? {
|
||||
fieldId: '',
|
||||
value: '',
|
||||
enumValue: '',
|
||||
term: '',
|
||||
filterType: 'logic',
|
||||
name: '',
|
||||
timeValue: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
dynamicTimeSetting: {},
|
||||
deType: ''
|
||||
}
|
||||
: { child: [], logic }
|
||||
)
|
||||
}
|
||||
const del = index => {
|
||||
relationList.value.splice(index, 1)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
init,
|
||||
submit
|
||||
})
|
||||
const emits = defineEmits(['save'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rowAuth">
|
||||
<auth-tree
|
||||
@del="idx => del(idx)"
|
||||
@addCondReal="addCondReal"
|
||||
@removeRelationList="removeRelationList"
|
||||
@changeAndOrDfs="type => changeAndOrDfs(relationList, type)"
|
||||
:relationList="relationList"
|
||||
v-model:logic="logic"
|
||||
/>
|
||||
<svg width="388" height="100%" class="real-line">
|
||||
<path
|
||||
stroke-linejoin="round"
|
||||
stroke-linecap="round"
|
||||
:d="svgRealinePath"
|
||||
fill="none"
|
||||
stroke="#CCCCCC"
|
||||
stroke-width="0.5"
|
||||
></path>
|
||||
</svg>
|
||||
<svg width="388" height="100%" class="dash-line">
|
||||
<path
|
||||
stroke-linejoin="round"
|
||||
stroke-linecap="round"
|
||||
:d="svgDashinePath"
|
||||
fill="none"
|
||||
stroke="#CCCCCC"
|
||||
stroke-width="0.5"
|
||||
stroke-dasharray="4,4"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.rowAuth {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
position: relative;
|
||||
}
|
||||
.real-line,
|
||||
.dash-line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
@@ -3,8 +3,6 @@ import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlin
|
||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||
import { ref, inject, computed, watch, onBeforeMount, toRefs, nextTick } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import type { SelectConfig } from '../TimeDialog.vue'
|
||||
import TimeDialog from '@/views/chart/components/editor/filter/TimeDialog.vue'
|
||||
import { multFieldValuesForPermissions } from '@/api/dataset'
|
||||
import {
|
||||
textOptions,
|
||||
@@ -23,9 +21,7 @@ export interface Item {
|
||||
enumValue: string
|
||||
name: string
|
||||
value: number
|
||||
filterTypeTime?: string
|
||||
timeValue: string
|
||||
dynamicTimeSetting?: SelectConfig
|
||||
}
|
||||
|
||||
type Props = {
|
||||
@@ -42,9 +38,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
deType: 0,
|
||||
enumValue: '',
|
||||
name: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
value: null,
|
||||
dynamicTimeSetting: null,
|
||||
timeValue: ''
|
||||
})
|
||||
})
|
||||
@@ -175,80 +169,6 @@ const initEnumOptions = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const timeDialog = ref()
|
||||
const handleClick = () => {
|
||||
dialogVisible.value = true
|
||||
nextTick(() => {
|
||||
timeDialog.value.init(item.value.dynamicTimeSetting || {})
|
||||
})
|
||||
}
|
||||
|
||||
const relativeToCurrentTypeMap = {
|
||||
year: '年',
|
||||
month: '月',
|
||||
date: '日',
|
||||
datetime: '日'
|
||||
}
|
||||
|
||||
const confirmTimeSelect = () => {
|
||||
item.value.dynamicTimeSetting = { ...timeDialog.value.curComponent }
|
||||
const {
|
||||
timeGranularity,
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
around,
|
||||
arbitraryTime,
|
||||
relativeToCurrent
|
||||
} = item.value.dynamicTimeSetting
|
||||
if (relativeToCurrent !== 'custom') {
|
||||
item.value.timeValue = [
|
||||
{
|
||||
label: '今年',
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
value: 'lastYear'
|
||||
},
|
||||
{
|
||||
label: '本月',
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
label: '今天',
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
].find(ele => ele.value === relativeToCurrent).label
|
||||
dialogVisible.value = false
|
||||
return
|
||||
}
|
||||
item.value.timeValue = `${timeNum}${relativeToCurrentTypeMap[relativeToCurrentType]}${
|
||||
around === 'f' ? '前' : '后'
|
||||
}`
|
||||
if (timeGranularity === 'datetime') {
|
||||
item.value.timeValue += new Date(arbitraryTime).toLocaleString().split(' ')[1]
|
||||
}
|
||||
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
const optionData = data => {
|
||||
if (!data) return null
|
||||
return data.filter(item => !!item)
|
||||
@@ -272,9 +192,7 @@ const selectItem = ({ name, id, deType }) => {
|
||||
enumValue: '',
|
||||
value: '',
|
||||
term: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
timeValue: '',
|
||||
dynamicTimeSetting: {}
|
||||
timeValue: ''
|
||||
})
|
||||
filterListInit(deType)
|
||||
checklist.value = []
|
||||
@@ -296,16 +214,6 @@ const filterListInit = deType => {
|
||||
}
|
||||
}
|
||||
|
||||
const filterListTime = [
|
||||
{
|
||||
value: 'dateValue',
|
||||
label: '固定值'
|
||||
},
|
||||
{
|
||||
value: 'dynamicDate',
|
||||
label: '动态值'
|
||||
}
|
||||
]
|
||||
const clearAll = () => {
|
||||
checklist.value = []
|
||||
}
|
||||
@@ -394,42 +302,22 @@ const emits = defineEmits(['update:item', 'del'])
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<div class="white-nowrap flex-align-center" style="position: relative" v-if="item.fieldId">
|
||||
<template v-if="item.deType !== 1">
|
||||
<span class="filed-title">{{ t('auth.screen_method') }}</span>
|
||||
<el-select
|
||||
size="small"
|
||||
@change="filterTypeChange"
|
||||
v-model="item.filterType"
|
||||
:placeholder="t('auth.select')"
|
||||
<span class="filed-title">{{ t('auth.screen_method') }}</span>
|
||||
<el-select
|
||||
size="small"
|
||||
@change="filterTypeChange"
|
||||
v-model="item.filterType"
|
||||
:placeholder="t('auth.select')"
|
||||
>
|
||||
<el-option
|
||||
v-for="ele in filterList"
|
||||
:key="ele.value"
|
||||
:label="ele.label"
|
||||
:value="ele.value"
|
||||
>
|
||||
<el-option
|
||||
v-for="ele in filterList"
|
||||
:key="ele.value"
|
||||
:label="ele.label"
|
||||
:value="ele.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<span class="filed-title">{{ t('auth.fixed_value') }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-select
|
||||
size="small"
|
||||
class="w100"
|
||||
style="margin-left: 16px"
|
||||
@change="filterTypeChangeTime"
|
||||
v-model="item.filterTypeTime"
|
||||
:placeholder="t('auth.select')"
|
||||
>
|
||||
<el-option
|
||||
v-for="ele in filterListTime"
|
||||
:key="ele.value"
|
||||
:label="ele.label"
|
||||
:value="ele.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<span class="filed-title">{{ t('auth.fixed_value') }}</span>
|
||||
<template v-if="item.filterType === 'logic'">
|
||||
<el-select
|
||||
class="w100"
|
||||
@@ -473,26 +361,13 @@ const emits = defineEmits(['update:item', 'del'])
|
||||
<div class="bottom-line"></div>
|
||||
</template>
|
||||
<template v-else-if="!['null', 'empty', 'not_null', 'not_empty'].includes(item.term)">
|
||||
<el-input
|
||||
v-if="item.deType === 1 && item.filterTypeTime === 'dynamicDate' && !item.timeValue"
|
||||
@click="handleClick"
|
||||
readonly
|
||||
class="w70 mar5"
|
||||
size="small"
|
||||
v-model="item.timeValue"
|
||||
/>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
v-else-if="item.deType === 1 && item.filterTypeTime === 'dynamicDate'"
|
||||
v-if="item.deType === 1"
|
||||
effect="light"
|
||||
:content="item.timeValue"
|
||||
placement="top"
|
||||
><el-input
|
||||
@click="handleClick"
|
||||
readonly
|
||||
class="w70 mar5"
|
||||
size="small"
|
||||
v-model="item.timeValue"
|
||||
><el-input class="w70 mar5" size="small" v-model="item.timeValue"
|
||||
/></el-tooltip>
|
||||
<el-input v-else class="w70 mar5" size="small" v-model="item.value" />
|
||||
<div class="bottom-line"></div>
|
||||
@@ -607,21 +482,6 @@ const emits = defineEmits(['update:item', 'del'])
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</div>
|
||||
<el-dialog
|
||||
class="create-dialog"
|
||||
append-to-body
|
||||
v-model="dialogVisible"
|
||||
title="日期设置"
|
||||
width="420"
|
||||
>
|
||||
<TimeDialog ref="timeDialog"></TimeDialog>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmTimeSelect"> 确定 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -40,16 +40,7 @@ const submit = () => {
|
||||
errorMessage: errorMessage.value
|
||||
})
|
||||
}
|
||||
const errorDetected = ({
|
||||
enumValue,
|
||||
deType,
|
||||
filterType,
|
||||
term,
|
||||
value,
|
||||
name,
|
||||
timeValue,
|
||||
filterTypeTime
|
||||
}) => {
|
||||
const errorDetected = ({ enumValue, deType, filterType, term, value, name, timeValue }) => {
|
||||
if (!name) {
|
||||
errorMessage.value = t('data_set.cannot_be_empty_')
|
||||
return
|
||||
@@ -73,8 +64,7 @@ const errorDetected = ({
|
||||
!term.includes('null') &&
|
||||
!term.includes('empty') &&
|
||||
['', null, undefined].includes(timeValue) &&
|
||||
deType === 1 &&
|
||||
filterTypeTime === 'dynamicDate'
|
||||
deType === 1
|
||||
) {
|
||||
errorMessage.value = t('chart.filter_value_can_null')
|
||||
return
|
||||
@@ -94,68 +84,6 @@ const errorDetected = ({
|
||||
}
|
||||
}
|
||||
|
||||
const getTimeValue = dynamicTimeSetting => {
|
||||
const relativeToCurrentTypeMap = {
|
||||
year: '年',
|
||||
month: '月',
|
||||
date: '日',
|
||||
datetime: '日'
|
||||
}
|
||||
let timeValue = ''
|
||||
const {
|
||||
timeGranularity,
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
around,
|
||||
arbitraryTime,
|
||||
relativeToCurrent
|
||||
} = dynamicTimeSetting || {}
|
||||
if (relativeToCurrent !== 'custom') {
|
||||
timeValue = [
|
||||
{
|
||||
label: '今年',
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
value: 'lastYear'
|
||||
},
|
||||
{
|
||||
label: '本月',
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
label: '今天',
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
].find(ele => ele.value === relativeToCurrent)?.label
|
||||
return timeValue
|
||||
}
|
||||
timeValue = `${timeNum}${relativeToCurrentTypeMap[relativeToCurrentType]}${
|
||||
around === 'f' ? '前' : '后'
|
||||
}`
|
||||
if (timeGranularity === 'datetime') {
|
||||
timeValue += new Date(arbitraryTime).toLocaleString().split(' ')[1]
|
||||
}
|
||||
|
||||
return timeValue
|
||||
}
|
||||
const dfsInit = arr => {
|
||||
const elementList = []
|
||||
arr.forEach(ele => {
|
||||
@@ -165,25 +93,14 @@ const dfsInit = arr => {
|
||||
const child = dfsInit(items)
|
||||
elementList.push({ logic, child })
|
||||
} else {
|
||||
const {
|
||||
enumValue,
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
fieldId,
|
||||
filterType,
|
||||
term,
|
||||
value,
|
||||
field
|
||||
} = ele
|
||||
const { enumValue, fieldId, filterType, term, value, timeValue, field } = ele
|
||||
const { name, deType } = field || {}
|
||||
elementList.push({
|
||||
enumValue: enumValue.join(','),
|
||||
fieldId,
|
||||
filterType,
|
||||
term,
|
||||
timeValue: getTimeValue(dynamicTimeSetting),
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
timeValue,
|
||||
value,
|
||||
name,
|
||||
deType
|
||||
@@ -206,33 +123,18 @@ const dfsSubmit = arr => {
|
||||
term: '',
|
||||
type: 'tree',
|
||||
value: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
timeValue: '',
|
||||
dynamicTimeSetting: {},
|
||||
subTree: { logic, items: subTree }
|
||||
})
|
||||
} else {
|
||||
const {
|
||||
enumValue,
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
fieldId,
|
||||
filterType,
|
||||
deType,
|
||||
term,
|
||||
value,
|
||||
name,
|
||||
timeValue
|
||||
} = ele
|
||||
errorDetected({ deType, enumValue, filterType, term, value, name, timeValue, filterTypeTime })
|
||||
const { enumValue, fieldId, filterType, deType, term, value, name, timeValue } = ele
|
||||
errorDetected({ deType, enumValue, filterType, term, value, name, timeValue })
|
||||
if (fieldId) {
|
||||
items.push({
|
||||
enumValue: enumValue ? enumValue.split(',') : [],
|
||||
fieldId,
|
||||
timeValue,
|
||||
filterType,
|
||||
filterTypeTime,
|
||||
dynamicTimeSetting,
|
||||
term,
|
||||
value,
|
||||
type: 'item',
|
||||
@@ -378,8 +280,6 @@ const addCondReal = (type, logic) => {
|
||||
filterType: 'logic',
|
||||
name: '',
|
||||
timeValue: '',
|
||||
filterTypeTime: 'dateValue',
|
||||
dynamicTimeSetting: {},
|
||||
deType: ''
|
||||
}
|
||||
: { child: [], logic }
|
||||
|
||||
Reference in New Issue
Block a user