标注时手动增加类型
This commit is contained in:
parent
3a2f0a0417
commit
06a68a14c5
|
|
@ -21,6 +21,7 @@
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
|
allow-create
|
||||||
style="width: 240px"
|
style="width: 240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
:visible-tags="visibleTags"
|
:visible-tags="visibleTags"
|
||||||
:selected-tag="selectedTag"
|
:selected-tag="selectedTag"
|
||||||
@toggle-tag="$emit('toggle-tag', $event)"
|
@toggle-tag="$emit('toggle-tag', $event)"
|
||||||
|
@new-tag-change="$emit('new-tag-change', $event)"
|
||||||
@toggle-all-tags="$emit('toggle-all-tags')"
|
@toggle-all-tags="$emit('toggle-all-tags')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,35 @@
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
|
||||||
|
<!-- 增加一个tags标签新增 每次可以新增一个 -->
|
||||||
|
<div>
|
||||||
|
<el-tag
|
||||||
|
:key="tag"
|
||||||
|
closable
|
||||||
|
v-for="tag in newTagsList"
|
||||||
|
:disable-transitions="false"
|
||||||
|
@close="handleClose(tag)"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
<el-input
|
||||||
|
class="input-new-tag"
|
||||||
|
v-if="inputVisible"
|
||||||
|
v-model="inputValue"
|
||||||
|
ref="saveTagInput"
|
||||||
|
size="small"
|
||||||
|
@blur="handleInputConfirm"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
class="button-new-tag"
|
||||||
|
size="small"
|
||||||
|
@click="showInput"
|
||||||
|
>+ 其他</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="annotation-info">
|
<div class="annotation-info">
|
||||||
|
|
@ -446,6 +475,9 @@ export default {
|
||||||
|
|
||||||
imgSrc: '',
|
imgSrc: '',
|
||||||
isSure: null,
|
isSure: null,
|
||||||
|
newTagsList: [],
|
||||||
|
inputVisible: false,
|
||||||
|
inputValue: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
@ -962,6 +994,49 @@ export default {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleClose(tag) {
|
||||||
|
this.newTagsList.splice(this.newTagsList.indexOf(tag), 1)
|
||||||
|
// 根据value删除annotationTypeOptions中的数据
|
||||||
|
this.annotationTypeOptions = this.annotationTypeOptions.filter(
|
||||||
|
(item) => item.value !== tag,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
showInput() {
|
||||||
|
this.inputVisible = true
|
||||||
|
this.$nextTick((_) => {
|
||||||
|
this.$refs.saveTagInput.$refs.input.focus()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleInputConfirm() {
|
||||||
|
let inputValue = this.inputValue
|
||||||
|
|
||||||
|
// 根据inputValue在annotationTypeOptions中查找是否存在
|
||||||
|
const index = this.annotationTypeOptions.findIndex(
|
||||||
|
(item) => item.value === inputValue,
|
||||||
|
)
|
||||||
|
if (index === -1) {
|
||||||
|
this.newTagsList.push(inputValue)
|
||||||
|
this.annotationTypeOptions.push({
|
||||||
|
label: inputValue,
|
||||||
|
value: inputValue,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.warning('标签已存在')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if (inputValue) {
|
||||||
|
// this.newTagsList.push(inputValue)
|
||||||
|
// this.annotationTypeOptions.push({
|
||||||
|
// label: inputValue,
|
||||||
|
// value: inputValue,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
this.inputVisible = false
|
||||||
|
this.inp
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1067,6 +1142,7 @@ export default {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.annotation-type .label {
|
.annotation-type .label {
|
||||||
|
|
@ -1262,4 +1338,20 @@ el-image {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-new-tag {
|
||||||
|
width: 90px;
|
||||||
|
margin-left: 10px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
.el-tag + .el-tag {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.button-new-tag {
|
||||||
|
margin-left: 10px;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 30px;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,95 +1,164 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="tag-container">
|
<div class="tag-container">
|
||||||
<template v-for="(tag, index) in visibleTags">
|
<template v-for="(tag, index) in visibleTags">
|
||||||
<div
|
<div
|
||||||
:key="'tag-' + tag.id"
|
:key="'tag-' + tag.id"
|
||||||
class="tag-item"
|
class="tag-item"
|
||||||
:class="{ active: isSelected(tag) }"
|
:class="{ active: isSelected(tag) }"
|
||||||
@click="$emit('toggle-tag', tag)"
|
@click="$emit('toggle-tag', tag)"
|
||||||
>
|
>
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
v-if="index < visibleTags.length - 1"
|
v-if="index < visibleTags.length - 1"
|
||||||
:key="'sep-' + index"
|
:key="'sep-' + index"
|
||||||
class="separator"
|
class="separator"
|
||||||
>
|
>
|
||||||
|
|
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div v-if="tags.length > 3" class="more-btn" @click="$emit('toggle-all-tags')">
|
<div>
|
||||||
<i class="el-icon-menu"></i>
|
<el-tag
|
||||||
<span>更多</span>
|
:key="tag"
|
||||||
|
closable
|
||||||
|
v-for="tag in newTagsList"
|
||||||
|
:disable-transitions="false"
|
||||||
|
@close="handleClose(tag)"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
<el-input
|
||||||
|
class="input-new-tag"
|
||||||
|
v-if="inputVisible"
|
||||||
|
v-model="inputValue"
|
||||||
|
ref="saveTagInput"
|
||||||
|
size="small"
|
||||||
|
@keyup.enter.native="handleInputConfirm"
|
||||||
|
@blur="handleInputConfirm"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
class="button-new-tag"
|
||||||
|
size="small"
|
||||||
|
@click="showInput"
|
||||||
|
>+ 其他</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "TagSelector",
|
name: 'TagSelector',
|
||||||
props: {
|
props: {
|
||||||
tags: {
|
tags: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => [],
|
||||||
|
},
|
||||||
|
visibleTags: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
selectedTag: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
visibleTags: {
|
data() {
|
||||||
type: Array,
|
return {
|
||||||
default: () => []
|
newTagsList: [],
|
||||||
|
inputVisible: false,
|
||||||
|
inputValue: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 检查标签是否被选中
|
||||||
|
isSelected(tag) {
|
||||||
|
return this.selectedTag.some((item) => item.id === tag.id)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClose(tag) {
|
||||||
|
this.newTagsList.splice(this.newTagsList.indexOf(tag), 1)
|
||||||
|
this.$emit('new-tag-change', this.newTagsList)
|
||||||
|
},
|
||||||
|
|
||||||
|
showInput() {
|
||||||
|
this.inputVisible = true
|
||||||
|
this.$nextTick((_) => {
|
||||||
|
this.$refs.saveTagInput.$refs.input.focus()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleInputConfirm() {
|
||||||
|
let inputValue = this.inputValue
|
||||||
|
if (inputValue) {
|
||||||
|
this.newTagsList.push(inputValue)
|
||||||
|
this.$emit('new-tag-change', this.newTagsList)
|
||||||
|
}
|
||||||
|
this.inputVisible = false
|
||||||
|
this.inputValue = ''
|
||||||
|
},
|
||||||
},
|
},
|
||||||
selectedTag: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 检查标签是否被选中
|
|
||||||
isSelected(tag) {
|
|
||||||
return this.selectedTag.some(item => item.id === tag.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.tag-container {
|
.tag-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
margin-bottom: 20px;
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-item {
|
.tag-item {
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-item.active {
|
.tag-item.active {
|
||||||
color: #0060EF;
|
color: #0060ef;
|
||||||
background: #FFFFFF;
|
background: #ffffff;
|
||||||
border-radius: 40px 40px 40px 40px;
|
border-radius: 40px 40px 40px 40px;
|
||||||
border: 1px solid #0060EF;
|
border: 1px solid #0060ef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-btn {
|
.more-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.separator {
|
.separator {
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
}
|
||||||
|
.input-new-tag {
|
||||||
|
width: 90px;
|
||||||
|
margin-left: 10px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
.el-tag + .el-tag {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.button-new-tag {
|
||||||
|
margin-left: 10px;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 30px;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
<template>
|
||||||
|
<div class="tag-container">
|
||||||
|
<template v-for="(tag, index) in visibleTags">
|
||||||
|
<div
|
||||||
|
:key="'tag-' + tag.id"
|
||||||
|
class="tag-item"
|
||||||
|
:class="{ active: isSelected(tag) }"
|
||||||
|
@click="$emit('toggle-tag', tag)"
|
||||||
|
>
|
||||||
|
{{ tag.name }}
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
v-if="index < visibleTags.length - 1"
|
||||||
|
:key="'sep-' + index"
|
||||||
|
class="separator"
|
||||||
|
>
|
||||||
|
|
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div v-if="tags.length > 3" class="more-btn" @click="$emit('toggle-all-tags')">
|
||||||
|
<i class="el-icon-menu"></i>
|
||||||
|
<span>更多</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TagSelector",
|
||||||
|
props: {
|
||||||
|
tags: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
visibleTags: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
selectedTag: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 检查标签是否被选中
|
||||||
|
isSelected(tag) {
|
||||||
|
return this.selectedTag.some(item => item.id === tag.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tag-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item {
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item.active {
|
||||||
|
color: #0060EF;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 40px 40px 40px 40px;
|
||||||
|
border: 1px solid #0060EF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
margin: 0 5px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
:visible-tags="visibleTags"
|
:visible-tags="visibleTags"
|
||||||
:selected-tag="selectedTag"
|
:selected-tag="selectedTag"
|
||||||
@toggle-tag="toggleTag"
|
@toggle-tag="toggleTag"
|
||||||
|
@new-tag-change="newTagChange"
|
||||||
@toggle-all-tags="toggleAllTags"
|
@toggle-all-tags="toggleAllTags"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -61,6 +62,7 @@
|
||||||
@hand-click="handleHandClick"
|
@hand-click="handleHandClick"
|
||||||
@confirm-results="confirmResults"
|
@confirm-results="confirmResults"
|
||||||
@toggle-tag="toggleTag"
|
@toggle-tag="toggleTag"
|
||||||
|
@new-tag-change="newTagChange"
|
||||||
@toggle-all-tags="toggleAllTags"
|
@toggle-all-tags="toggleAllTags"
|
||||||
@file-change="handleFileChange"
|
@file-change="handleFileChange"
|
||||||
@remove-image="removeImage"
|
@remove-image="removeImage"
|
||||||
|
|
@ -119,6 +121,8 @@ export default {
|
||||||
groupedImageResults: [], // 新增分组数据
|
groupedImageResults: [], // 新增分组数据
|
||||||
|
|
||||||
remarkInfo: '', // 备注信息
|
remarkInfo: '', // 备注信息
|
||||||
|
|
||||||
|
newTagsList: [], // 新增标签列表
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -140,7 +144,9 @@ export default {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
}))
|
}))
|
||||||
this.visibleTags = this.tags.slice(0, 3)
|
// this.visibleTags = this.tags.slice(0, 3)
|
||||||
|
console.log('this.tags:', this.tags)
|
||||||
|
this.visibleTags = this.tags
|
||||||
} else {
|
} else {
|
||||||
console.error('获取标签列表失败:', res)
|
console.error('获取标签列表失败:', res)
|
||||||
this.tags = []
|
this.tags = []
|
||||||
|
|
@ -190,9 +196,16 @@ export default {
|
||||||
const selectedTagIds = this.selectedTag
|
const selectedTagIds = this.selectedTag
|
||||||
.map((tag) => tag.id)
|
.map((tag) => tag.id)
|
||||||
.join(',')
|
.join(',')
|
||||||
const selectedTagNames = this.selectedTag
|
let selectedTagNames = this.selectedTag
|
||||||
.map((tag) => tag.name)
|
.map((tag) => tag.name)
|
||||||
.join(',')
|
.join(',')
|
||||||
|
|
||||||
|
let newTagsNames = ''
|
||||||
|
if (this.newTagsList.length > 0) {
|
||||||
|
newTagsNames = this.newTagsList.join(',')
|
||||||
|
selectedTagNames = `${selectedTagNames},${newTagsNames}`
|
||||||
|
}
|
||||||
|
|
||||||
console.log('选中的标签IDs:', selectedTagIds)
|
console.log('选中的标签IDs:', selectedTagIds)
|
||||||
console.log('选中的标签名称:', selectedTagNames)
|
console.log('选中的标签名称:', selectedTagNames)
|
||||||
if (this.fileList.length === 0) {
|
if (this.fileList.length === 0) {
|
||||||
|
|
@ -344,10 +357,14 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.showAllTags) {
|
if (!this.showAllTags) {
|
||||||
this.updateVisibleTagsInCollapsedState()
|
// this.updateVisibleTagsInCollapsedState()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
newTagChange(newTagsList) {
|
||||||
|
this.newTagsList = newTagsList
|
||||||
|
},
|
||||||
|
|
||||||
updateVisibleTagsInCollapsedState() {
|
updateVisibleTagsInCollapsedState() {
|
||||||
const selectedTags = this.selectedTag || []
|
const selectedTags = this.selectedTag || []
|
||||||
const defaultTags = this.tags.slice(0, 3)
|
const defaultTags = this.tags.slice(0, 3)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue