feat: 新增数据集标签功能

新增数据集标签功能
main
hong.yang 2 years ago
parent 4790b9702f
commit 8384004d4b

@ -0,0 +1,7 @@
import LabelConfig from './src/index.vue'
LabelConfig.install = function (Vue) {
Vue.component(LabelConfig.name, LabelConfig)
}
export default LabelConfig

@ -0,0 +1,382 @@
<template>
<el-dialog
:append-to-body="true"
:before-close="handleClose"
:title="dataForm.id!==''?'编辑标签':'新增标签'"
:visible.sync="dialogFormVisible"
:width="relVisible?'1100px':'450px'"
>
<el-row>
<el-col :span="relVisible?8:24">
<el-divider content-position="left">属性信息</el-divider>
<el-form ref="ruleForm" :model="dataForm" :rules="rules" label-position="right" label-width="90px">
<el-form-item label="标签名称" prop="labelName">
<el-input v-model="dataForm.labelName" clearable maxlength="200"/>
</el-form-item>
<el-form-item label="标签类型" prop="labelType">
<el-select ref="searchSelect"
v-model="dataForm.labelType"
allow-create
clearable
filterable
placeholder="请选择或输入标签类型"
@blur="selectBlur"
@input.native="filterData">
<el-option v-for="(item,K) in labelTypeList" :key="K" :label="item"
:value="item"/>
</el-select>
</el-form-item>
<el-form-item label="标签说明" prop="labelDesc">
<el-input v-model="dataForm.labelDesc" clearable type="text"/>
</el-form-item>
</el-form>
<el-divider content-position="left">关联数据集信息</el-divider>
<el-form>
<el-form-item align="center">
<el-tag effect="plain">标签</el-tag>
<span></span>
<el-button round size="mini" type="primary" @click="buildRel"></el-button>
</el-form-item>
</el-form>
</el-col>
<el-col v-if="relVisible" :span="8">
<div>
<el-divider content-position="left">添加关联</el-divider>
<div class="tree-box full-box--position" style="padding: 0 8px 24px 0">
<Tree
ref="tree"
:treeData="categoryData"
style="height: 300px;overflow: auto"
@handleNodeClick="handleNodeClick"
>
</Tree>
</div>
</div>
</el-col>
<el-col v-if="relVisible" :span="8">
<el-divider content-position="left">数据集列表:</el-divider>
<div>
<el-table
ref="mytable"
v-loading="loading"
:data="datasetList"
height="300"
@select="handleSelect"
@select-all="handleSelectionAll"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="数据集名称"
prop="name"
show-overflow-tooltip
></el-table-column>
</el-table>
</div>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel"></el-button>
<el-button type="primary" @click="submitForm('ruleForm')"></el-button>
</span>
</el-dialog>
</template>
<script>
import {pageMixins} from 'packages/js/mixins/page'
import Tree from './Tree'
import {addOrUpdateLabel, checkRepeatLabel, getDataSetIdListByLabelId} from 'packages/js/utils/LabelConfigService'
import {datasetList, getCategoryTree} from 'packages/js/utils/datasetConfigService'
export default {
name: "labelConfigAddOrUpdate",
mixins: [pageMixins],
data() {
return {
loading: false,
datasetList: [],
typeId: '',
dataForm: {
id: '',
labelName: '',
labelType: '',
labelDesc: '',
relList: []
},
dialogFormVisible: false,
rules: {
labelName: [
{required: true, message: '标签名称不能为空', trigger: 'blur'},
{validator: this.validateLabelName, trigger: 'blur'}
],
labelType: [
{required: true, message: '标签类型不能为空', trigger: 'change'},
],
},
//
categoryData: [],
relVisible: false,
//
labelTypeList: [],
// id
datasetIdList: []
}
},
components: {
Tree
},
watch: {
"dataForm.labelType": function (val) {
if (val.length > 20) {
this.dataForm.labelType = val.substring(0, 20);
}
},
// datasetListdatasetIdList
datasetList: {
handler: function (val) {
this.$nextTick(() => {
if (this.$refs.mytable) {
this.$refs.mytable.clearSelection();
}
this.datasetList.forEach((item) => {
if (this.datasetIdList.includes(item.id)) {
this.$refs.mytable.toggleRowSelection(item, true);
}
})
})
},
deep: true
}
},
methods: {
/**
* 初始化
* @param row 标签信息
*/
init(row) {
this.dataForm.id = row ? row.id : '';
this.dialogFormVisible = true;
if (row) {
this.dataForm.id = row.id;
this.dataForm.labelName = row.labelName;
this.dataForm.labelType = row.labelType;
this.dataForm.labelDesc = row.labelDesc;
// id
getDataSetIdListByLabelId(row.id).then((list) => {
this.datasetIdList = list;
this.buildRel();
})
}
this.$nextTick(() => {
this.getDataList();
})
},
/**
* 获取数据集列表
*/
getDataList() {
this.loading = true;
let params = {
typeId: this.typeId
};
datasetList(params).then((list) => {
this.datasetList = list;
if (!this.relVisible) {
this.loading = false;
return
}
this.loading = false;
}).catch(() => {
this.loading = false;
})
},
/**
* 获取分类树
*/
getTreeList() {
getCategoryTree({type: 'dataset'}).then((categoryTree) => {
this.categoryData = categoryTree;
})
},
/**
* 标签名称校验
* @param rule
* @param value
* @param callback
*/
validateLabelName(rule, value, callback) {
checkRepeatLabel({'id': this.dataForm.id, 'labelName': this.dataForm.labelName}).then(repeat => {
if (repeat) {
callback(new Error('标签名称已存在'))
} else {
callback();
}
});
},
/**
* 树节点点击事件
* @param row
* @param value
*/
handleNodeClick(row, value) {
this.$nextTick(() => {
this.typeId = row.id;
this.getDataList();
})
},
/**
* 选中数据集
* @param selection 选中的数据集列表
* @param row 操作行
*/
handleSelect(selection, row) {
// row.iddatasetIdListdatasetIdList
if (this.datasetIdList.includes(row.id)) {
const index = this.datasetIdList.indexOf(row.id);
if (index > -1) {
this.datasetIdList.splice(index, 1);
}
return
}
// row.iddatasetIdListdatasetIdList
if (!this.datasetIdList.includes(row.id)) {
this.datasetIdList.push(row.id);
}
},
/**
* 数据集全选
* @param selection
*/
handleSelectionAll(selection) {
// datasetListdatasetIdList
if (selection.length === 0) {
this.datasetList.forEach((dataset) => {
const index = this.datasetIdList.indexOf(dataset.id);
if (index > -1) {
this.datasetIdList.splice(index, 1);
}
});
return
}
// datasetListdatasetIdList
if (selection.length > 0) {
this.datasetList.forEach((dataset) => {
if (!this.datasetIdList.includes(dataset.id)) {
this.datasetIdList.push(dataset.id);
}
});
}
},
/**
* 表单关闭
*/
handleClose() {
this.$parent.addOrUpdateVisible = false
},
/**
* 取消按钮
*/
cancel() {
this.dialogFormVisible = false;
this.$nextTick(() => {
this.handleClose();
})
},
/**
* 提交按钮
* @param formName
*/
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.saveForm(true);
} else {
return false;
}
});
},
/**
* 保存标签信息
* @param flag
*/
saveForm(flag) {
this.dataForm.relList = [];
this.datasetIdList.forEach(id => {
let param = {
'datasetId': id,
'labelId': this.dataForm.id
};
this.dataForm.relList.push(param);
});
addOrUpdateLabel(this.dataForm).then((r) => {
this.$message.success('保存成功');
this.cancel();
this.$parent.getDataList();
//
this.$parent.getLabelType();
})
},
/**
* 添加关联按钮
*/
buildRel() {
this.relVisible = !this.relVisible;
if (this.relVisible) {
this.getTreeList();
this.$nextTick(() => {
this.getDataList();
})
}
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1
},
ellipsis(value, len) {
if (!value) return '';
if (value.length > len) {
return value.slice(0, len) + '...'
}
return value
},
selectBlur(e) {
this.dataForm.labelType = e.target.value
},
//
filterData() {
//
var str = this.$refs.searchSelect.$data.selectedLabel;
// js
if (str.length > 20) {
this.$refs.searchSelect.$data.selectedLabel = str.substr(0, 20)
}
}
}
}
</script>
<style scoped>
.el-col {
height: 358px;
}
.tree-box {
overflow-x: auto;
}
</style>

@ -0,0 +1,299 @@
<template>
<div
v-if="dialogFormVisible"
class="inner-container"
>
<el-page-header
style="padding-top: 8px"
@back="goBack"
/>
<el-divider content-position="left">
属性信息
</el-divider>
<el-row :gutter="5">
<el-col
:span="8"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.labelName.length > 20"
:content="dataForm.labelName"
class="item"
effect="dark"
placement="bottom-start"
>
<span>标签名称 {{ ellipsis(dataForm.labelName, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.labelName, 20) }}</span>
</el-col>
<el-col
:span="8"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.labelType.length > 20"
:content="dataForm.labelType"
class="item"
effect="dark"
placement="bottom-start"
>
<span>标签类型 {{ ellipsis(dataForm.labelType, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.labelType, 20) }}</span>
</el-col>
<el-col
:span="8"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.labelDesc.length > 20"
:content="dataForm.labelDesc"
class="item"
effect="dark"
placement="bottom-start"
>
<span>标签说明 {{ ellipsis(dataForm.labelDesc, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.labelDesc, 20) }}</span>
</el-col>
<el-col
:span="8"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.createBy && dataForm.createBy.length > 20"
:content="dataForm.createBy"
class="item"
effect="dark"
placement="bottom-start"
>
<span>创建人 {{ ellipsis(dataForm.createBy, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.createBy, 20) }}</span>
</el-col>
<el-col
:span="16"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.createDate.length > 20"
:content="dataForm.createDate"
class="item"
effect="dark"
placement="bottom-start"
>
<span>创建时间 {{ ellipsis(dataForm.createDate, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.createDate, 20) }}</span>
</el-col>
<el-col
:span="8"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.updateBy && dataForm.updateBy.length > 20"
:content="dataForm.updateBy"
class="item"
effect="dark"
placement="bottom-start"
>
<span>修改人 {{ ellipsis(dataForm.updateBy, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.updateBy, 20) }}</span>
</el-col>
<el-col
:span="8"
class="attrInfo"
>
<el-tooltip
v-if="dataForm.updateDate.length > 20"
:content="dataForm.updateDate"
class="item"
effect="dark"
placement="bottom-start"
>
<span>修改时间 {{ ellipsis(dataForm.updateDate, 20) }}</span>
</el-tooltip>
<span v-else> {{ ellipsis(dataForm.updateDate, 20) }}</span>
</el-col>
</el-row>
<el-divider content-position="left">
关联数据集信息
</el-divider>
<div style="width:90%" id="container" />
</div>
</template>
<script>
import G6 from '@antv/g6'
import { getLabelDetail } from 'packages/js/utils/LabelConfigService'
export default {
name: 'LabelConfigDetails',
data () {
return {
dialogFormVisible: false,
dataForm: {
createBy: '',
createDate: '',
updateBy: '',
updateDate: '',
labelDesc: '',
labelName: '',
labelType: ''
},
jsonData: {},
chartHeight: 0,
chartWidth: 0
}
},
methods: {
ellipsis (value, len) {
if (!value) return ''
if (value.length > len) {
return value.slice(0, len) + '...'
}
return value
},
init (row) {
this.dialogFormVisible = true
getLabelDetail(row.id).then((r) => {
this.jsonData = r.jsonData
if (r.jsonData.nodes.length > 1) {
this.chartHeight = r.jsonData.nodes.length * 100
} else {
this.chartHeight = 200
}
this.dataForm = r
this.chartWidth = r.labelName.length * 20
this.$nextTick(() => {
this.initG6(r.jsonData)
})
})
},
goBack () {
this.dialogFormVisible = false
this.$nextTick(() => {
this.$parent.labelVisible = true
this.$parent.getDataList()
})
},
nodeEach (nodes) {
nodes.forEach(node => {
if (!node.style) {
node.style = {}
}
switch (node.class) {
case 'c1': {
node.shape = 'circle'
node.size = 40
break
}
case 'c3': {
node.shape = 'rect'
// node.size = [80, 50];
node.style = {
stroke: '#FFFFFF',
fill: '#DFE1E3'
}
break
}
case 'c0': {
node.shape = 'ellipse'
node.size = [80, 40]
break
}
case 'c2': {
node.shape = 'diamond'
node.size = [60, 60]
break
}
}
})
},
// G6
initG6 (json) {
const data = json
const width = document.getElementById('container').scrollWidth
this.nodeEach(data.nodes)
const tooltip = new G6.Tooltip({
offsetX: 10,
offsetY: 0,
fixToNode: [1, 0],
itemTypes: ['node', 'edge'],
getContent: (e) => {
const outDiv = document.createElement('div')
outDiv.style.width = 'fit-content'
outDiv.innerHTML = `<div style='width: 200px;'>${e.item.getModel()._label}</div>`
return outDiv
},
shouldBegin: (e) => {
let res = true
if (e.item.getModel()._label && e.item.getModel()._label.length > 12) {
res = true
} else {
res = false
}
return res
}
})
const graph = new G6.Graph({
container: 'container',
// width: '800',
height: this.chartHeight,
plugins: [tooltip],
// modes: {
// default: ['drag-canvas', 'zoom-canvas', 'click-select']
// },
defaultNode: {
type: 'rect',
size: [150, 50],
style: {
fill: '#9ACAFF',
stroke: '#FFFFFF'
}
},
// 线
defaultEdge: {
type: 'line',
style: {
offset: 25,
endArrow: true,
lineWidth: 2,
stroke: '#333'
}
}
})
data.nodes.forEach(node => {
node._label = node.label
if (node.label.length > 12) {
node.label = node.label.substr(0, 9) + '...'
}
})
graph.data(data)
graph.render()
}
}
}
</script>
<style scoped>
.inner-container{
overflow-x: hidden;
}
.el-col {
height: 35px;
}
.attrInfo {
padding-left: 20px !important;
}
</style>

@ -0,0 +1,345 @@
<template>
<div>
<el-tag
v-for="label in selectLabelListInitial"
:key="label.id"
:closable="isEdit"
:disable-transitions="false"
@close="handleCloseTag(label)"
>
{{ label.labelName }}
</el-tag>
<el-tooltip
class="item"
content="添加关联标签"
effect="dark"
placement="right"
>
<el-button
circle
icon="el-icon-plus"
style="margin-left: 10px"
@click="addLabel"
/>
</el-tooltip>
<!-- 标签列表弹窗 -->
<el-dialog
:append-to-body="true"
:before-close="handleClose"
:visible.sync="dialogFormVisible"
title="选择标签"
width="1000px"
>
<div v-loading="labelCheckLoading">
<el-form
:inline="true"
class="filter-container"
>
<el-form-item label="标签名称">
<el-input
v-model="searchForm.labelName"
clearable
placeholder="请输入标签名称"
/>
</el-form-item>
<el-form-item label="标签类型">
<el-select
v-model="searchForm.labelType"
clearable
filterable
placeholder="请选择标签类型"
@change="selectLabelType"
>
<el-option
label="全部"
value=""
/>
<el-option
v-for="(item, index) in labelTypeList"
:key="index"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="getDataList"
>
查询
</el-button>
</el-form-item>
</el-form>
<!-- 标签选项组 -->
<el-checkbox-group
v-model="checkLabelList"
style="padding-bottom: 10px"
>
<el-row :gutter="2">
<el-col
v-for="label in labelList"
:key="label.id"
:span="4"
style="padding-top: 10px"
>
<el-tooltip
v-if="label.labelDesc || getByteLength(label.labelName) > 18"
effect="light"
placement="top-start"
>
<div slot="content">
<div v-if="getByteLength(label.labelName) > 18">
名称: {{ label.labelName }}
</div>
<div v-if="label.labelDesc">
描述: {{ label.labelDesc }}
</div>
</div>
<el-checkbox
:label="label.id"
@change="labelCheckChange(label)"
>
{{ getByteLength(label.labelName) > 18 ? ellipsis(label.labelName, 18) : label.labelName }}
</el-checkbox>
</el-tooltip>
<el-checkbox
v-else
:label="label.id"
@change="labelCheckChange(label)"
>{{label.labelName}}</el-checkbox>
</el-col>
</el-row>
</el-checkbox-group>
<div class="page-container">
<el-pagination
:current-page="current"
:page-size="sizeLabel"
:page-sizes="[20, 40, 60, 80]"
:total="totalCount"
background
layout="total, prev, pager, next,sizes,jumper"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
/>
</div>
<div align="center">
<el-button @click="handleClose">
取消
</el-button>
<el-button
type="primary"
@click="commitLabel"
>
确定
</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { pageMixins } from 'packages/js/mixins/page'
import { getLabelType, labelList, getLabelListByDatasetId } from 'packages/js/utils/LabelConfigService'
export default {
name: 'LabelSelect',
components: {},
mixins: [pageMixins],
props: {
// id
idList: {
type: Array,
default: () => []
},
isEdit: {
type: Boolean,
default: true
},
datasetId: {
type: String,
default: ''
}
},
data () {
return {
idListCopy: this.idList,
selectLabelList: [],
//
selectLabelListInitial : [],
labelList: [],
dialogFormVisible: false,
searchForm: {
labelName: '',
labelType: ''
},
checkLabelList: [],
sizeLabel: 20,
labelTypeList: [],
labelCheckLoading: false
}
},
mounted() {
// id
if (this.datasetId) {
getLabelListByDatasetId(this.datasetId).then((data) => {
this.selectLabelListInitial = _.cloneDeep(data)
this.selectLabelList = _.cloneDeep(data)
})
}
},
watch: {
// labelListselectLabelListid
labelList: {
handler (val) {
this.checkLabelList = []
val.forEach((label) => {
this.selectLabelList.forEach((selected) => {
if (label.id === selected.id) {
this.checkLabelList.push(label.id)
}
})
})
},
deep: true
},
// selectLabelListididList
selectLabelList: {
handler (val) {
this.checkLabelList = []
this.idListCopy = []
val.forEach((item) => {
this.idListCopy.push(item.id)
this.checkLabelList.push(item.id)
})
},
deep: true
}
},
methods: {
/**
* 初始化方法
*/
init () {
this.dialogFormVisible = true
this.getDataList()
this.getLabelType()
},
/**
* 获取标签类型列表
*/
getLabelType () {
getLabelType().then((data) => {
this.labelTypeList = data
})
},
/**
* 获取标签列表
*/
getDataList () {
this.labelCheckLoading = true
let params = {
current: this.current,
size: this.sizeLabel,
labelName: this.searchForm.labelName,
labelType: this.searchForm.labelType
}
labelList(params).then((data) => {
this.totalCount = data.totalCount
this.labelList = data.list
this.labelCheckLoading = false
}).catch(() => {
this.labelCheckLoading = false
})
},
/**
* 标签选项组选中事件
*/
labelCheckChange(label) {
// selectLabelListidselectLabelList
if (this.selectLabelList.some(item => item.id === label.id)) {
this.selectLabelList = this.selectLabelList.filter(item => item.id !== label.id)
} else {
// selectLabelList
this.selectLabelList.push(label)
}
},
/**
* 移除选中的标签
*/
handleCloseTag (label) {
this.selectLabelListInitial.forEach((item, index) => {
if (item.id === label.id) {
this.selectLabelListInitial.splice(index, 1)
}
})
this.selectLabelList.forEach((item, index) => {
if (item.id === label.id) {
this.selectLabelList.splice(index, 1)
}
})
},
/**
* 点击添加标签按钮
*/
addLabel () {
//
this.init()
},
/**
* 选中标签类型
*/
selectLabelType () {
this.getDataList()
},
/**
* 弹窗关闭
*/
handleClose () {
this.selectLabelList = _.cloneDeep(this.selectLabelListInitial)
this.dialogFormVisible = false
},
/**
* 确认按钮
*/
commitLabel () {
this.labelCheckLoading = false
this.dialogFormVisible = false
this.selectLabelListInitial = _.cloneDeep(this.selectLabelList)
this.$emit('commit', this.idListCopy)
},
getByteLength (str) {
return unescape(encodeURIComponent(str)).length
},
ellipsis (str, len) {
if ((!str && typeof (str) !== 'undefined')) {
return ''
}
var num = 0
var str1 = str
var str = ''
for (var i = 0, lens = str1.length; i < lens; i++) {
num += ((str1.charCodeAt(i) > 255) ? 2 : 1)
if (num > len - 3) {
break
} else {
str = str1.substring(0, i + 1)
}
}
return str + '...'
},
}
}
</script>
<style lang="scss" scoped>
</style>

@ -0,0 +1,85 @@
<template>
<el-dialog
:append-to-body="true"
:before-close="handleClose"
:visible.sync="dialogFormVisible"
class="dialogClass"
title="标签类型修改"
width="500px"
>
<div style="margin: 20px;">
<el-form ref="ruleForm" :model="dataForm" :rules="rules" label-position="left" label-width="90px">
<el-form-item label="标签类型" prop="labelType">
<el-input v-model="dataForm.labelType"/>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel"></el-button>
<el-button type="primary" @click="submitForm('ruleForm')"></el-button>
</span>
</el-dialog>
</template>
<script>
import {updateLabelType} from 'packages/js/utils/LabelConfigService'
export default {
name: "labelTypeEdit",
data() {
return {
dialogFormVisible: false,
dataForm: {
labelType: '',
oldLabelType: ''
},
rules: {
labelType: [
{required: true, message: '标签类型不能为空', trigger: 'blur'},
]
}
}
},
methods: {
init(labelType) {
this.dataForm.labelType = labelType;
this.dataForm.oldLabelType = labelType;
},
handleClose() {
this.$parent.labelTypeEditVisible = false
},
cancel() {
this.dialogFormVisible = false;
this.$nextTick(() => {
this.handleClose();
})
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
updateLabelType(this.dataForm).then(() => {
if (this.$parent.queryForm.labelType !== '') {
this.$parent.queryForm.labelType = this.dataForm.labelType;
}
this.$parent.reSearch()
this.$parent.getLabelType();
this.cancel();
this.$message.success("保存成功")
});
} else {
return false;
}
});
},
}
}
</script>
<style>
.dialogClass .el-dialog__body {
min-height: auto;
}
</style>

@ -0,0 +1,162 @@
<template>
<el-tree
:ref="treeRef"
:data="treeData"
:default-expand-all="expandAll"
:expand-on-click-node="false"
:filter-node-method="filterNode"
:highlight-current="true"
:indent="0"
:props="defaultProps"
node-key="id"
style="width: fit-content;min-width: 100%;"
@node-click="handleNodeClick"
@node-contextmenu="rihgtClick"
>
<span
slot-scope="{ node,data }"
class="custom-tree-node"
style="width: 100%;position: relative;"
@mouseenter="mouseEnter(data)"
@mouseleave="mouseLeave(data)"
>
<span :style="data.children && data.children.length ? {} : {'padding-left': '12px'}">
<i :class="data.children && data.children.length ? 'el-icon el-icon-folder': 'el-icon el-icon-document'"
style="margin-right: 8px;"></i>
<span class="nodeText">{{ data.name }}</span>
</span>
<span v-if="optionShow" class="options">
<el-dropdown @command="(command) => { treeCommand(command, data) }">
<i class="el-icon-more"></i>
<el-dropdown-menu slot="dropdown">
<slot name="options"></slot>
</el-dropdown-menu>
</el-dropdown>
</span>
</span>
</el-tree>
</template>
<script>
export default {
name: 'Tree',
props: {
treeData: {
type: Array,
default: () => ([])
},
treeRef: {
type: String,
default: 'tree'
},
nodeWidth: {
type: String,
default: '280px'
},
expandAll: {
type: Boolean,
default: true
},
filterText: {
type: String,
default: ''
},
optionShow: {
type: Boolean,
default: false
}
},
data() {
return {
defaultProps: {
children: 'children',
label: 'name'
}
}
},
watch: {
'treeData': function (val) {
// console.log('valx', val)
},
filterText(val) {
this.$refs[this.treeRef].filter(val)
}
},
methods: {
treeCommand(command, nodeData) {
this.$emit('treeCommand', command, nodeData)
},
filterNode(value, data) {
if (!value) return true
return data.name.indexOf(value) !== -1
},
//
handleNodeClick(row, value) {
this.$emit('handleNodeClick', row, value)
},
//
rihgtClick(event, object, value, element) {
this.$emit('rihgtClick', event, object, value, element)
},
mouseEnter(data) {
// this.$set(data, 'show', true)
//
this.$emit('mouseEnter', data)
},
mouseLeave(data) {
// this.$set(data, 'show', false)
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-tree-node {
display: block;
min-width: 270px;
.el-tree-node__content {
width: 270px;
overflow: hidden;
}
.el-tree-node__children {
.el-tree-node {
display: block;
min-width: 270px;
.el-tree-node__content {
width: 270px;
overflow: hidden;
}
}
}
}
.custom-tree-node {
position: relative;
.nodeText {
display: inline-block;
width: 225px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 14px;
}
.options {
position: absolute;
right: 30px;
height: 16px;
top: 2px;
line-height: 16px;
transform: rotate(90deg);
}
}
// /deep/ .is-current .options{
// background: #fff;
// }
</style>

@ -0,0 +1,297 @@
<template>
<div class="db-container">
<div
v-if="labelVisible"
class="inner-container"
>
<el-form
ref="queryForm"
:model="queryForm"
class="filter-container"
>
<el-form-item
class="filter-item"
prop="labelName"
>
标签名称
<el-input
v-model="queryForm.labelName"
clearable
placeholder="请输入标签名称"
@clear="reSearch()"
@keyup.enter.native="reSearch()"
/>
</el-form-item>
<el-form-item
class="filter-item"
prop="labelType"
>
标签类型
<el-select
v-model="queryForm.labelType"
clearable
filterable
placeholder="请选择标签类型"
@change="reSearch()"
>
<el-option
key="all"
label="全部"
value=""
/>
<el-option
v-for="labelType in labelTypeList"
:key="labelType"
:label="labelType"
:value="labelType"
>
<span>
{{ labelType }}
</span>
<span style="float: right;padding-right: 20px">
<el-button
icon="el-icon-edit"
type="text"
@click.stop="editLabelType(labelType)"
/>
<el-button
icon="el-icon-delete"
type="text"
@click.stop="deleteLabelType(labelType)"
/>
</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item class="filter-item">
<el-button
:loading="dataListLoading"
icon="el-icon-search"
type="primary"
@click="reSearch"
>
查询
</el-button>
</el-form-item>
<el-form-item
class="filter-item"
>
<el-button
type="primary"
@click="addOrUpdateLabel(undefined)"
>
新增
</el-button>
</el-form-item>
</el-form>
<div class="db-table-box">
<el-table
v-table
v-loading="dataListLoading"
height="0"
:data="tableData"
class="db-el-table db-scrollbar"
:element-loading-text="loadingText"
:header-cell-style="sortStyle"
@sort-change="reSort"
>
<el-empty slot="empty" />
<el-table-column
label="标签名称"
prop="labelName"
show-overflow-tooltip
/>
<el-table-column
label="标签类型"
prop="labelType"
show-overflow-tooltip
/>
<el-table-column
label="标签说明"
prop="labelDesc"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="操作"
width="200"
>
<template slot-scope="scope">
<el-button @click="getDetail(scope.row)">
详情
</el-button>
<el-button
@click="addOrUpdateLabel(scope.row)"
>
编辑
</el-button>
<el-button
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="db-pagination">
<el-pagination
class="db-el-pagination"
popper-class="db-el-pagination"
:current-page="current"
:next-text="nextText"
:page-size="size"
:page-sizes="[10, 20, 50, 100]"
:prev-text="prevText"
:total="totalCount"
background
layout="total, prev, pager, next, sizes"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
/>
</div>
</div>
<label-config-add-or-update
v-if="addOrUpdateVisible"
ref="LabelConfigAddOrUpdate"
/>
<label-type-edit
v-if="labelTypeEditVisible"
ref="LabelTypeEdit"
/>
<label-config-details
ref="LabelConfigDetails"
>
</label-config-details>
</div>
</template>
<script>
import table from 'packages/js/utils/table.js'
import { pageMixins } from 'packages/js/mixins/page'
import LabelConfigAddOrUpdate from './LabelConfigAddOrUpdate.vue'
import LabelConfigDetails from './LabelConfigDetails.vue'
import LabelTypeEdit from './LabelTypeEdit.vue'
import { getLabelType, labelList, removeLabel, removeLabelByType } from 'packages/js/utils/LabelConfigService'
export default {
name: 'LabelConfig',
directives: {
table //
},
mixins: [pageMixins],
components: {
LabelConfigDetails,
LabelConfigAddOrUpdate,
LabelTypeEdit
},
data () {
return {
tableData: [],
addOrUpdateVisible: false,
addOrUpdateDetailVisible: false,
labelTypeEditVisible: false,
labelVisible: true,
labelTypeList: [],
dataListLoading: false,
loadingText: '',
queryForm: {
labelName: '',
labelType: ''
}
}
},
watch: {},
mounted () {
this.getDataList()
this.getLabelType()
},
methods: {
deleteLabelType (labelType) {
this.$confirm('是否删除当前标签类型? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeLabelByType({ labelType: labelType }).then(() => {
this.$nextTick(() => {
this.reSearch()
this.getLabelType()
this.$message.success('删除成功')
})
})
})
},
editLabelType (labelType) {
this.labelTypeEditVisible = true
this.$nextTick(() => {
this.$refs.LabelTypeEdit.dialogFormVisible = true
this.$refs.LabelTypeEdit.init(labelType)
})
},
handleDelete (id) {
this.$confirm('确定删除当前标签吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeLabel(id).then(() => {
this.getDataList()
this.$message.success('删除成功')
})
}).catch(() => {
})
},
// /
addOrUpdateLabel (row) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.LabelConfigAddOrUpdate.labelTypeList = this.labelTypeList
this.$refs.LabelConfigAddOrUpdate.init(row)
})
},
//
getDetail (row) {
this.addOrUpdateDetailVisible = true
this.labelVisible = false
this.$nextTick(() => {
this.$refs.LabelConfigDetails.init(row)
})
},
//
getLabelType () {
getLabelType().then((data) => {
this.labelTypeList = data
})
},
//
getDataList () {
this.dataListLoading = true
this.loadingText = '正在查询数据...'
const params = {
current: this.current,
size: this.size,
...this.queryForm
}
labelList(params).then((data) => {
this.totalCount = data.totalCount
this.tableData = data.list
this.dataListLoading = false
}).catch(() => {
this.dataListLoading = false
})
},
//
reSearch () {
//
this.current = 1
this.getDataList()
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-table{
border-color: var(--db-el-border) !important;
}
</style>

@ -73,6 +73,28 @@
@clear="handleSearch()"
/>
</el-form-item>
<el-form-item
class="filter-item"
prop="labelIds"
>
<el-select
class="bs-el-select"
v-model="queryForm.labelIds"
clearable
filterable
multiple
collapse-tags
placeholder="请选择数据集关联标签"
@clear="handleSearch()"
>
<el-option
v-for="labelItem in labelList"
:key="labelItem.id"
:label="labelItem.labelName"
:value="labelItem.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item class="filter-item">
<el-button
:loading="dataListLoading"
@ -225,6 +247,7 @@ import OriginalEditForm from './OriginalEditForm.vue'
import DatasetTypeDialog from './DatasetTypeDialog.vue'
import StoredProcedureEditForm from './StoredProcedureEditForm.vue'
import { datasetPage, datasetRemove } from 'packages/js/utils/datasetConfigService'
import { getLabelList } from 'packages/js/utils/LabelConfigService'
export default {
name: 'DataSetManagement',
directives: {
@ -276,10 +299,12 @@ export default {
queryForm: {
name: '',
datasetType: '',
typeId: '' // id
typeId: '', // id
labelIds: []
}, //
//
datasetTypeList: [],
labelList: [],
isPackUpTree: false,
transition: 0.1,
loadingText: '正在加载数据',
@ -488,6 +513,9 @@ export default {
})
}
this.getDataList()
getLabelList().then(res => {
this.labelList = res
})
},
//
addDataset () {

@ -0,0 +1,92 @@
/*!
* 标签管理
*/
import { get, post } from 'packages/js/utils/http'
/**
* 获取标签列表
* @returns {*}
*/
const getLabelList = () => get(`/label/getLabelList`)
/**
* 获取标签
* @param data
* @returns {*}
*/
const labelList = (data) => get(`/label/list`, data)
/**
* 获取标签分类
* @returns {*}
*/
const getLabelType = () => get(`/label/getLabelType`)
/**
* 根据种类移除标签
* @param data
* @returns {*}
*/
const removeLabelByType = (data) => post(`/label/removeLabelByType`, data)
/**
* 移除标签
* @param id
* @returns {*}
*/
const removeLabel = (id = '-1') => get(`/label/removeLabel/${id}`)
/**
* 检查重复标签
* @param data
* @returns {*}
*/
const checkRepeatLabel = (data) => post(`/label/checkRepeat`, data)
/**
* 新增/修改标签
* @param data
* @returns {*}
*/
const addOrUpdateLabel = (data) => post(`/label/addOrUpdateLabel`, data)
/**
* 获取标签详情
* @param id
* @returns {*}
*/
const getLabelDetail = (id = '-1') => get(`/label/getLabelDetail/${id}`)
/**
* 修改标签种类
* @param data
* @returns {*}
*/
const updateLabelType = (data) => post(`/label/updateLabelType`, data)
/**
* 根据标签id获取数据集id列表
* @param id
*/
const getDataSetIdListByLabelId = (id = '-1') => get(`/label/queryDataSetIdList/${id}`)
/**
* 根据数据集id获取标签列表
* @param id
*/
const getLabelListByDatasetId = (id = '-1') => get(`/label/queryDataSetLabelList/${id}`)
export {
getLabelList,
labelList,
getLabelType,
removeLabelByType,
removeLabel,
checkRepeatLabel,
addOrUpdateLabel,
getLabelDetail,
updateLabelType,
getDataSetIdListByLabelId,
getLabelListByDatasetId
}
Loading…
Cancel
Save