mirror of
https://github.com/dataease/dataease.git
synced 2025-02-25 20:20:04 +08:00
feat: 数据集导出
This commit is contained in:
parent
a2da48f2dd
commit
e28b80f302
@ -190,7 +190,7 @@
|
|||||||
v-dialogDrag
|
v-dialogDrag
|
||||||
:visible.sync="showExport"
|
:visible.sync="showExport"
|
||||||
width="600px"
|
width="600px"
|
||||||
class="de-dialog-form"
|
class="de-dialog-form form-tree-cont"
|
||||||
:title="$t('dataset.export_dataset')"
|
:title="$t('dataset.export_dataset')"
|
||||||
append-to-body
|
append-to-body
|
||||||
>
|
>
|
||||||
@ -216,11 +216,9 @@
|
|||||||
:label="$t('dataset.export_filter')"
|
:label="$t('dataset.export_filter')"
|
||||||
prop="expressionTree"
|
prop="expressionTree"
|
||||||
>
|
>
|
||||||
<!--TODO 下面的input需用行权限的树形过滤组件替换-->
|
<div class="tree-cont">
|
||||||
<el-input
|
<rowAuth ref="rowAuth" />
|
||||||
v-model.trim="exportForm.expressionTree"
|
</div>
|
||||||
placeholder="请输入筛选条件"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<span class="tip">提示:最多支持导出10万条数据</span>
|
<span class="tip">提示:最多支持导出10万条数据</span>
|
||||||
@ -251,6 +249,8 @@ import FieldEdit from './FieldEdit'
|
|||||||
import { pluginLoaded } from '@/api/user'
|
import { pluginLoaded } from '@/api/user'
|
||||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||||
import UpdateRecords from './UpdateRecords'
|
import UpdateRecords from './UpdateRecords'
|
||||||
|
import rowAuth from './components/rowAuth.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ViewTable',
|
name: 'ViewTable',
|
||||||
components: {
|
components: {
|
||||||
@ -259,8 +259,14 @@ export default {
|
|||||||
UpdateInfo,
|
UpdateInfo,
|
||||||
TabDataPreview,
|
TabDataPreview,
|
||||||
UpdateRecords,
|
UpdateRecords,
|
||||||
|
rowAuth,
|
||||||
PluginCom
|
PluginCom
|
||||||
},
|
},
|
||||||
|
provide() {
|
||||||
|
return {
|
||||||
|
filedList: () => this.filedList
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
param: {
|
param: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -273,6 +279,7 @@ export default {
|
|||||||
name: ''
|
name: ''
|
||||||
},
|
},
|
||||||
fields: [],
|
fields: [],
|
||||||
|
filedList: [],
|
||||||
data: [],
|
data: [],
|
||||||
syncStatus: '',
|
syncStatus: '',
|
||||||
lastRequestComplete: true,
|
lastRequestComplete: true,
|
||||||
@ -289,8 +296,7 @@ export default {
|
|||||||
isPluginLoaded: false,
|
isPluginLoaded: false,
|
||||||
showExport: false,
|
showExport: false,
|
||||||
exportForm: {
|
exportForm: {
|
||||||
name: '',
|
name: ''
|
||||||
expressionTree: ''
|
|
||||||
},
|
},
|
||||||
exportFormRules: {
|
exportFormRules: {
|
||||||
name: [
|
name: [
|
||||||
@ -345,6 +351,13 @@ export default {
|
|||||||
this.initTable(this.param.id)
|
this.initTable(this.param.id)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
fetchFiledList() {
|
||||||
|
this.filedList = []
|
||||||
|
post('dataset/field/listForPermissionSeting/' + this.param.id,
|
||||||
|
{}).then((res) => {
|
||||||
|
this.filedList = res.data
|
||||||
|
})
|
||||||
|
},
|
||||||
initTable(id) {
|
initTable(id) {
|
||||||
this.resetPage()
|
this.resetPage()
|
||||||
this.tableViewRowForm.row = 1000
|
this.tableViewRowForm.row = 1000
|
||||||
@ -455,8 +468,8 @@ export default {
|
|||||||
|
|
||||||
exportDataset() {
|
exportDataset() {
|
||||||
this.showExport = true
|
this.showExport = true
|
||||||
|
this.fetchFiledList()
|
||||||
this.exportForm.name = this.table.name
|
this.exportForm.name = this.table.name
|
||||||
this.exportForm.expressionTree = ''
|
|
||||||
},
|
},
|
||||||
closeExport() {
|
closeExport() {
|
||||||
this.showExport = false
|
this.showExport = false
|
||||||
@ -467,7 +480,16 @@ export default {
|
|||||||
if (this.table.id) {
|
if (this.table.id) {
|
||||||
this.table.row = 100000
|
this.table.row = 100000
|
||||||
this.table.filename = this.exportForm.name
|
this.table.filename = this.exportForm.name
|
||||||
this.table.expressionTree = this.exportForm.expressionTree
|
const { logic, items, errorMessage } = this.$refs.rowAuth.submit()
|
||||||
|
if (errorMessage) {
|
||||||
|
this.$message({
|
||||||
|
message: errorMessage,
|
||||||
|
type: 'error',
|
||||||
|
showClose: true
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.table.expressionTree = JSON.stringify({ items, logic })
|
||||||
exportDataset(this.table).then((res) => {
|
exportDataset(this.table).then((res) => {
|
||||||
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
@ -488,7 +510,14 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss">
|
||||||
|
.form-tree-cont {
|
||||||
|
.tree-cont {
|
||||||
|
height: 200px;
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
.icon-class {
|
.icon-class {
|
||||||
color: #6c6c6c;
|
color: #6c6c6c;
|
||||||
}
|
}
|
||||||
|
1060
frontend/src/views/dataset/data/components/filterFiled.vue
Normal file
1060
frontend/src/views/dataset/data/components/filterFiled.vue
Normal file
File diff suppressed because it is too large
Load Diff
350
frontend/src/views/dataset/data/components/rowAuth.vue
Normal file
350
frontend/src/views/dataset/data/components/rowAuth.vue
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
<template>
|
||||||
|
<div class="rowAuth">
|
||||||
|
<rowAuthTree
|
||||||
|
:relation-list="relationList"
|
||||||
|
:logic.sync="logic"
|
||||||
|
@del="(idx) => del(idx)"
|
||||||
|
@addCondReal="addCondReal"
|
||||||
|
@removeRelationList="removeRelationList"
|
||||||
|
@changeAndOrDfs="(type) => changeAndOrDfs(relationList, type)"
|
||||||
|
/>
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
</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"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import rowAuthTree from './rowAuthTree.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'RowAuth',
|
||||||
|
components: {
|
||||||
|
rowAuthTree
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
relationList: [],
|
||||||
|
logic: 'or',
|
||||||
|
errorMessage: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
svgRealinePath() {
|
||||||
|
const lg = this.relationList.length
|
||||||
|
const a = { x: 0, y: 0, child: this.relationList }
|
||||||
|
a.y = Math.floor(this.dfsXY(a, 0) / 2)
|
||||||
|
if (!lg) return ''
|
||||||
|
const path = this.calculateDepth(a)
|
||||||
|
return path
|
||||||
|
},
|
||||||
|
svgDashinePath() {
|
||||||
|
const lg = this.relationList.length
|
||||||
|
const a = { x: 0, y: 0, child: this.relationList }
|
||||||
|
a.y = Math.floor(this.dfsXY(a, 0) / 2)
|
||||||
|
if (!lg) return `M48 20 L68 20`
|
||||||
|
const path = this.calculateDepthDash(a)
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init(expressionTree) {
|
||||||
|
const { logic = 'or', items = [] } = expressionTree
|
||||||
|
this.logic = logic
|
||||||
|
this.relationList = this.dfsInit(items)
|
||||||
|
},
|
||||||
|
submit() {
|
||||||
|
this.errorMessage = ''
|
||||||
|
return {
|
||||||
|
logic: this.logic,
|
||||||
|
items: this.dfsSubmit(this.relationList),
|
||||||
|
errorMessage: this.errorMessage
|
||||||
|
}
|
||||||
|
},
|
||||||
|
errorDetected({ enumValue, deType, filterType, term, value }) {
|
||||||
|
if (filterType === 'logic') {
|
||||||
|
if (
|
||||||
|
!term.includes('null') &&
|
||||||
|
!term.includes('empty') &&
|
||||||
|
(value === '')
|
||||||
|
) {
|
||||||
|
this.errorMessage = this.$t('chart.filter_value_can_null')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ([2, 3].includes(deType)) {
|
||||||
|
if (parseFloat(value).toString() === 'NaN') {
|
||||||
|
this.errorMessage = this.$t('chart.filter_value_can_not_str')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filterType === 'enum') {
|
||||||
|
if (enumValue.length < 1) {
|
||||||
|
this.errorMessage = this.$t('chart.enum_value_can_not_null')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dfsInit(arr) {
|
||||||
|
const elementList = []
|
||||||
|
arr.forEach((ele) => {
|
||||||
|
const { subTree } = ele
|
||||||
|
if (subTree) {
|
||||||
|
const { items, logic } = subTree
|
||||||
|
const child = this.dfsInit(items)
|
||||||
|
elementList.push({ logic, child })
|
||||||
|
} else {
|
||||||
|
const {
|
||||||
|
enumValue,
|
||||||
|
fieldId,
|
||||||
|
filterType,
|
||||||
|
term,
|
||||||
|
value,
|
||||||
|
field
|
||||||
|
} = ele
|
||||||
|
const { name, deType } = (field || {})
|
||||||
|
elementList.push({
|
||||||
|
enumValue: enumValue.join(','),
|
||||||
|
fieldId,
|
||||||
|
filterType,
|
||||||
|
term,
|
||||||
|
value,
|
||||||
|
name,
|
||||||
|
deType
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return elementList
|
||||||
|
},
|
||||||
|
dfsSubmit(arr) {
|
||||||
|
const items = []
|
||||||
|
arr.forEach((ele) => {
|
||||||
|
const { child = [] } = ele
|
||||||
|
if (child.length) {
|
||||||
|
const { logic } = ele
|
||||||
|
const subTree = this.dfsSubmit(child)
|
||||||
|
items.push({
|
||||||
|
enumValue: [],
|
||||||
|
fieldId: '',
|
||||||
|
filterType: '',
|
||||||
|
term: '',
|
||||||
|
type: 'tree',
|
||||||
|
value: '', subTree: { logic, items: subTree }})
|
||||||
|
} else {
|
||||||
|
const { enumValue, fieldId, filterType, deType, term, value } = ele
|
||||||
|
this.errorDetected({ deType, enumValue, filterType, term, value })
|
||||||
|
if (fieldId) {
|
||||||
|
items.push({
|
||||||
|
enumValue: enumValue ? enumValue.split(',') : [],
|
||||||
|
fieldId,
|
||||||
|
filterType,
|
||||||
|
term,
|
||||||
|
value,
|
||||||
|
type: 'item',
|
||||||
|
subTree: null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return items
|
||||||
|
},
|
||||||
|
removeRelationList() {
|
||||||
|
this.relationList = []
|
||||||
|
},
|
||||||
|
getY(arr) {
|
||||||
|
const [a] = arr
|
||||||
|
if (a.child?.length) {
|
||||||
|
return this.getY(a.child)
|
||||||
|
}
|
||||||
|
return a.y
|
||||||
|
},
|
||||||
|
getLastY(arr) {
|
||||||
|
const a = arr[arr.length]
|
||||||
|
if (a.child?.length) {
|
||||||
|
return this.getLastY(a.child)
|
||||||
|
}
|
||||||
|
return a.y
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
const y = Math.max(
|
||||||
|
this.dfsY(obj, 0),
|
||||||
|
this.dfs(obj.child, 0) + this.getY(obj.child) - 1
|
||||||
|
)
|
||||||
|
const parent =
|
||||||
|
(this.dfs(obj.child, 0) * 41.4) / 2 +
|
||||||
|
(this.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 += this.calculateDepthDash(item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return path
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
const parent =
|
||||||
|
(this.dfs(obj.child, 0) * 41.4) / 2 +
|
||||||
|
(this.getY(obj.child) || 0) * 41.4
|
||||||
|
const children =
|
||||||
|
(this.dfs(item.child, 0) * 41.4) / 2 + this.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 += this.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
|
||||||
|
},
|
||||||
|
changeAndOrDfs(arr, logic) {
|
||||||
|
arr.forEach((ele) => {
|
||||||
|
if (ele.child) {
|
||||||
|
ele.logic = logic === 'and' ? 'or' : 'and'
|
||||||
|
this.changeAndOrDfs(ele.child, ele.logic)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dfs(arr, count) {
|
||||||
|
arr.forEach((ele) => {
|
||||||
|
if (ele.child?.length) {
|
||||||
|
count = this.dfs(ele.child, count)
|
||||||
|
} else {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
count += 1
|
||||||
|
return count
|
||||||
|
},
|
||||||
|
dfsY(obj, count) {
|
||||||
|
obj.child.forEach((ele) => {
|
||||||
|
if (ele.child?.length) {
|
||||||
|
count = this.dfsY(ele, count)
|
||||||
|
} else {
|
||||||
|
count = Math.max(count, ele.y, obj.y)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return count
|
||||||
|
},
|
||||||
|
dfsXY(obj, count) {
|
||||||
|
obj.child.forEach((ele) => {
|
||||||
|
ele.x = obj.x + 1
|
||||||
|
if (ele.child?.length) {
|
||||||
|
const l = this.dfs(ele.child, 0)
|
||||||
|
ele.y = Math.floor(l / 2) + count
|
||||||
|
count = this.dfsXY(ele, count)
|
||||||
|
} else {
|
||||||
|
count += 1
|
||||||
|
ele.y = count - 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
count += 1
|
||||||
|
return count
|
||||||
|
},
|
||||||
|
addCondReal(type, logic) {
|
||||||
|
this.relationList.push(
|
||||||
|
type === 'condition'
|
||||||
|
? { fieldId: '', value: '', enumValue: '', term: '', filterType: 'logic', name: '', deType: '' }
|
||||||
|
: { child: [], logic }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
del(index) {
|
||||||
|
this.relationList.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.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>
|
251
frontend/src/views/dataset/data/components/rowAuthTree.vue
Normal file
251
frontend/src/views/dataset/data/components/rowAuthTree.vue
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="logic"
|
||||||
|
:style="marginLeft"
|
||||||
|
>
|
||||||
|
<div class="logic-left">
|
||||||
|
<div class="operate-title">
|
||||||
|
<span
|
||||||
|
v-if="x"
|
||||||
|
style="
|
||||||
|
{
|
||||||
|
color: '#bfbfbf';
|
||||||
|
}
|
||||||
|
"
|
||||||
|
class="mrg-title"
|
||||||
|
>
|
||||||
|
{{ logic === 'or' ? "OR" : "AND" }}
|
||||||
|
</span>
|
||||||
|
<el-dropdown
|
||||||
|
v-else
|
||||||
|
trigger="click"
|
||||||
|
@command="handleCommand"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style="
|
||||||
|
{
|
||||||
|
color: 'rgba(0,0,0,.65)';
|
||||||
|
}
|
||||||
|
"
|
||||||
|
class="mrg-title"
|
||||||
|
>
|
||||||
|
{{ logic === 'or' ? "OR" : "AND" }}<i class="el-icon-arrow-down" />
|
||||||
|
</span>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item command="and">AND</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="or">OR</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
v-if="x"
|
||||||
|
class="operate-icon"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="el-icon-delete"
|
||||||
|
@click="$emit('removeRelationList')"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="logic-right">
|
||||||
|
<template v-for="(item, index) in relationList">
|
||||||
|
<logic-relation
|
||||||
|
v-if="item.child"
|
||||||
|
:key="index"
|
||||||
|
:x="item.x"
|
||||||
|
:logic="item.logic"
|
||||||
|
:relation-list="item.child"
|
||||||
|
@del="(idx) => del(idx, item.child)"
|
||||||
|
@addCondReal="(type, logic) => add(type, item.child, logic)"
|
||||||
|
@removeRelationList="removeRelationList(index)"
|
||||||
|
/>
|
||||||
|
<filter-filed
|
||||||
|
v-else
|
||||||
|
:key="index"
|
||||||
|
:item="item"
|
||||||
|
:index="index"
|
||||||
|
@del="$emit('del', index)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<div class="logic-right-add">
|
||||||
|
<button
|
||||||
|
class="operand-btn"
|
||||||
|
@click="addCondReal('condition')"
|
||||||
|
>
|
||||||
|
+ {{ $t('auth.add_condition') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="x < 2"
|
||||||
|
class="operand-btn"
|
||||||
|
@click="addCondReal('relation')"
|
||||||
|
>
|
||||||
|
+ {{ $t('auth.add_relationship') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import filterFiled from './filterFiled'
|
||||||
|
export default {
|
||||||
|
name: 'LogicRelation',
|
||||||
|
components: {
|
||||||
|
filterFiled
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
relationList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
logic: {
|
||||||
|
type: String,
|
||||||
|
default: 'or'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
marginLeft() {
|
||||||
|
return {
|
||||||
|
marginLeft: this.x ? '20px' : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleCommand(type) {
|
||||||
|
this.$emit('update:logic', type)
|
||||||
|
this.$emit('changeAndOrDfs', type)
|
||||||
|
},
|
||||||
|
removeRelationList(index) {
|
||||||
|
this.relationList.splice(index, 1)
|
||||||
|
},
|
||||||
|
addCondReal(type) {
|
||||||
|
this.$emit('addCondReal', type, this.logic === 'or' ? 'and' : 'or')
|
||||||
|
},
|
||||||
|
add(type, child, logic) {
|
||||||
|
child.push(type === 'condition' ? { fieldId: '', value: '', enumValue: '', term: '', filterType: 'logic', name: '', deType: '' } : { child: [], logic })
|
||||||
|
},
|
||||||
|
del(index, child) {
|
||||||
|
child.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scope>
|
||||||
|
.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;
|
||||||
|
flex-direction: row;
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
.operate-title {
|
||||||
|
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif;
|
||||||
|
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;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.operate-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operate-title {
|
||||||
|
.mrg-title {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
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>
|
24
frontend/src/views/dataset/data/options.js
Normal file
24
frontend/src/views/dataset/data/options.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
function formatEnum(ele) {
|
||||||
|
return {
|
||||||
|
value: ele,
|
||||||
|
label: `chart.filter_${ele.replace(' ', '_')}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const textEnum = ['eq', 'not_eq', 'like', 'not like', 'null', 'not_null', 'empty', 'not_empty']
|
||||||
|
const textOptions = textEnum.map(formatEnum)
|
||||||
|
|
||||||
|
const dateEnum = ['eq', 'not_eq', 'lt', 'gt', 'le', 'ge']
|
||||||
|
const dateOptions = dateEnum.map(formatEnum)
|
||||||
|
|
||||||
|
const valueEnum = [...dateEnum]
|
||||||
|
const valueOptions = valueEnum.map(formatEnum)
|
||||||
|
|
||||||
|
const fieldEnum = ['text', 'time', 'value', 'value', '', 'location']
|
||||||
|
|
||||||
|
export {
|
||||||
|
textOptions,
|
||||||
|
dateOptions,
|
||||||
|
valueOptions,
|
||||||
|
fieldEnum
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user