标注时手动增加类型

This commit is contained in:
BianLzhaoMin 2025-12-05 15:36:07 +08:00
parent 3a2f0a0417
commit 06a68a14c5
6 changed files with 345 additions and 70 deletions

View File

@ -21,6 +21,7 @@
placeholder="请选择"
clearable
filterable
allow-create
style="width: 240px"
>
<el-option

View File

@ -22,6 +22,7 @@
:visible-tags="visibleTags"
:selected-tag="selectedTag"
@toggle-tag="$emit('toggle-tag', $event)"
@new-tag-change="$emit('new-tag-change', $event)"
@toggle-all-tags="$emit('toggle-all-tags')"
/>

View File

@ -289,6 +289,35 @@
{{ option.label }}
</el-radio-button>
</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 class="annotation-info">
@ -446,6 +475,9 @@ export default {
imgSrc: '',
isSure: null,
newTagsList: [],
inputVisible: false,
inputValue: '',
}
},
created() {
@ -962,6 +994,49 @@ export default {
}))
})
},
handleClose(tag) {
this.newTagsList.splice(this.newTagsList.indexOf(tag), 1)
// valueannotationTypeOptions
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
// inputValueannotationTypeOptions
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>
@ -1067,6 +1142,7 @@ export default {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.annotation-type .label {
@ -1262,4 +1338,20 @@ el-image {
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>

View File

@ -18,36 +18,89 @@
</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>
<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"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
>
</el-input>
<el-button
v-else
class="button-new-tag"
size="small"
@click="showInput"
>+ 其他</el-button
>
</div>
</div>
</template>
<script>
export default {
name: "TagSelector",
name: 'TagSelector',
props: {
tags: {
type: Array,
default: () => []
default: () => [],
},
visibleTags: {
type: Array,
default: () => []
default: () => [],
},
selectedTag: {
type: Array,
default: () => []
default: () => [],
},
},
data() {
return {
newTagsList: [],
inputVisible: false,
inputValue: '',
}
},
methods: {
//
isSelected(tag) {
return this.selectedTag.some(item => item.id === tag.id)
}
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 = ''
},
},
}
</script>
@ -56,6 +109,7 @@ export default {
display: flex;
align-items: center;
gap: 5px;
flex-wrap: wrap;
margin-bottom: 20px;
}
@ -69,10 +123,10 @@ export default {
}
.tag-item.active {
color: #0060EF;
background: #FFFFFF;
color: #0060ef;
background: #ffffff;
border-radius: 40px 40px 40px 40px;
border: 1px solid #0060EF;
border: 1px solid #0060ef;
}
.more-btn {
@ -92,4 +146,19 @@ export default {
margin: 0 5px;
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>

View File

@ -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>

View File

@ -24,6 +24,7 @@
:visible-tags="visibleTags"
:selected-tag="selectedTag"
@toggle-tag="toggleTag"
@new-tag-change="newTagChange"
@toggle-all-tags="toggleAllTags"
/>
@ -61,6 +62,7 @@
@hand-click="handleHandClick"
@confirm-results="confirmResults"
@toggle-tag="toggleTag"
@new-tag-change="newTagChange"
@toggle-all-tags="toggleAllTags"
@file-change="handleFileChange"
@remove-image="removeImage"
@ -119,6 +121,8 @@ export default {
groupedImageResults: [], //
remarkInfo: '', //
newTagsList: [], //
}
},
@ -140,7 +144,9 @@ export default {
id: item.id,
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 {
console.error('获取标签列表失败:', res)
this.tags = []
@ -190,9 +196,16 @@ export default {
const selectedTagIds = this.selectedTag
.map((tag) => tag.id)
.join(',')
const selectedTagNames = this.selectedTag
let selectedTagNames = this.selectedTag
.map((tag) => tag.name)
.join(',')
let newTagsNames = ''
if (this.newTagsList.length > 0) {
newTagsNames = this.newTagsList.join(',')
selectedTagNames = `${selectedTagNames},${newTagsNames}`
}
console.log('选中的标签IDs:', selectedTagIds)
console.log('选中的标签名称:', selectedTagNames)
if (this.fileList.length === 0) {
@ -344,10 +357,14 @@ export default {
}
if (!this.showAllTags) {
this.updateVisibleTagsInCollapsedState()
// this.updateVisibleTagsInCollapsedState()
}
},
newTagChange(newTagsList) {
this.newTagsList = newTagsList
},
updateVisibleTagsInCollapsedState() {
const selectedTags = this.selectedTag || []
const defaultTags = this.tags.slice(0, 3)