图像评估的功能
This commit is contained in:
parent
e5f9814aeb
commit
4d09b1e008
|
|
@ -0,0 +1,10 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询参数列表
|
||||
export function getAllImagelist(query) {
|
||||
return request({
|
||||
url: '/image/caption/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
<div>
|
||||
<el-image
|
||||
:src="src1"
|
||||
fit="cover"
|
||||
:style="`width:${realWidth};height:${realHeight};border-radius: ${borderRadius}px;`"
|
||||
v-if="!isShowMask"
|
||||
>
|
||||
|
|
@ -14,7 +13,6 @@
|
|||
<el-image
|
||||
:src="src1"
|
||||
v-else
|
||||
fit="cover"
|
||||
:preview-src-list="realSrcList"
|
||||
:style="`width:${realWidth};height:${realHeight};border-radius: ${borderRadius}px;`"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@
|
|||
<!-- 图片区域 -->
|
||||
<div class="card-image">
|
||||
<ImagePreview
|
||||
style="margin-top: 10px"
|
||||
style="margin-top: 10px;"
|
||||
:height="192"
|
||||
:borderRadius="10"
|
||||
:width="itemWidth"
|
||||
:src1="item.image"
|
||||
:src1="item.bjUrl"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -58,12 +58,12 @@
|
|||
<div class="card-content">
|
||||
<div class="card-footer">
|
||||
<div class="person-info">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<span class="name">{{ item.userName }}</span>
|
||||
<span class="date">{{ item.date }}</span>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<el-tooltip :content="item.description" placement="top" :effect="'light'" :enterable="false">
|
||||
<span class="title-desc">{{ item.description }}</span>
|
||||
<el-tooltip :content="item.contentImage" placement="top" :effect="'light'" :enterable="false">
|
||||
<span class="title-desc">{{ item.contentImage }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div style="border-top: 1px solid #CFD4D7;"></div>
|
||||
|
|
@ -96,17 +96,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getRole,
|
||||
delRole,
|
||||
addRole,
|
||||
updateRole,
|
||||
dataScope,
|
||||
changeRoleStatus,
|
||||
deptTreeSelect
|
||||
} from "@/api/system/role"
|
||||
import {treeselect as menuTreeselect, roleMenuTreeselect} from "@/api/system/menu"
|
||||
import {getMaterialListAPI} from "@/api/publicService/proMaterials";
|
||||
import {getAllImagelist} from "@/api/imageCaptioning/imageLibrary";
|
||||
|
||||
export default {
|
||||
name: "imageCaptioningLibrary",
|
||||
|
|
@ -117,10 +107,11 @@ export default {
|
|||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 8,
|
||||
roleName: undefined,
|
||||
roleKey: undefined,
|
||||
status: undefined
|
||||
status: undefined,
|
||||
operaType: 1
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
|
|
@ -144,10 +135,9 @@ export default {
|
|||
},
|
||||
/** 查询角色列表 */
|
||||
getList() {
|
||||
getMaterialListAPI().then(response => {
|
||||
getAllImagelist(this.queryParams).then(response => {
|
||||
this.proMaterialsListAll = response.rows;
|
||||
this.total = response.total || 0;
|
||||
console.log(this.proMaterialsListAll)
|
||||
this.showProMaterialsDuctList = this.proMaterialsListAll;
|
||||
})
|
||||
},
|
||||
|
|
@ -226,6 +216,7 @@ export default {
|
|||
border-radius: 10px;
|
||||
align-content: flex-start;
|
||||
justify-items: center;
|
||||
height: 47%;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
|
|
@ -276,7 +267,7 @@ export default {
|
|||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 10px 18px 0 18px;
|
||||
margin: 10px 18px 5px 18px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
@click="$emit('start-upload')"
|
||||
:disabled="fileList.length === 0"
|
||||
>
|
||||
开始标注
|
||||
开始评估
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<ImageResults
|
||||
:upload-info="uploadInfo"
|
||||
:image-results="imageResults"
|
||||
:grouped-image-results="groupedImageResults"
|
||||
:selected-images="selectedImages"
|
||||
:is-sure="isSure"
|
||||
@hand-click="handleHandClickFromChild"
|
||||
|
|
@ -59,6 +60,10 @@ export default {
|
|||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
groupedImageResults: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
selectedImages: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import ImageResults from './ImageResults.vue';
|
||||
import ImageResults from './ImageResultsUn.vue';
|
||||
import TagSelector from './TagSelector.vue';
|
||||
import FileUploader from './FileUploaderUn.vue';
|
||||
import axios from 'axios'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,86 @@
|
|||
<template>
|
||||
<div class="image-results-container">
|
||||
<!-- 按下标分组显示 -->
|
||||
<template v-if="groupedImageResults && groupedImageResults.length > 0">
|
||||
<div v-for="(group, groupIndex) in groupedImageResults" :key="group.index" class="group-section">
|
||||
<!-- 每组的上传信息提示 -->
|
||||
<div class="upload-info" v-if="isEvaluate == '0'">
|
||||
<img src="@/assets/images/imageCaptioning/photography.png" alt="" class="icon-photography">
|
||||
<span>
|
||||
第{{ group.index + 1 }}组 - {{ group.operaName }}:
|
||||
上传{{ group.totalCount }}张图片,可识别标注{{ group.recognizedCount }}张,
|
||||
{{ group.unrecognizedCount }}张无法识别标注。已识别标注图片如下,请确认。
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 每组的图片展示 -->
|
||||
<div class="image-results-grid">
|
||||
<div
|
||||
v-for="(result, imageIndex) in group.images"
|
||||
:key="imageIndex"
|
||||
:class="isEvaluate == '1' ? 'image-item-evaluate' : 'image-item'"
|
||||
>
|
||||
<img
|
||||
:src="result.url"
|
||||
alt=""
|
||||
:class="isEvaluate == '1' ? 'result-image-evaluate' : 'result-image'"
|
||||
>
|
||||
<!-- 右上角的hand图标 -->
|
||||
<img
|
||||
v-if="isGroupImageSelected(groupIndex, imageIndex) && isEvaluate == '0'"
|
||||
src="@/assets/images/imageCaptioning/hand-yellow.png"
|
||||
alt="selected"
|
||||
class="icon-hand"
|
||||
@click="handleGroupImageClick(groupIndex, imageIndex, group.isSure)"
|
||||
>
|
||||
<img
|
||||
v-else-if="!isGroupImageSelected(groupIndex, imageIndex) && isEvaluate == '0'"
|
||||
src="@/assets/images/imageCaptioning/hand.png"
|
||||
alt="hand"
|
||||
class="icon-hand"
|
||||
@click="handleGroupImageClick(groupIndex, imageIndex, group.isSure)"
|
||||
>
|
||||
|
||||
<div class="card-content" v-if="isEvaluate == '1'">
|
||||
<div class="card-footer">
|
||||
<div class="person-info">
|
||||
<span class="name">综合得分:{{ overallScore }}</span>
|
||||
<span class="date">{{ contentImage }}</span>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="tag-row">
|
||||
<span class="tag-item" style="padding-left: 16px;">清晰度: {{ clarity }}分</span>
|
||||
<span class="tag-item" style="padding-left: 16px;">干净度: {{ cleanliness }}分</span>
|
||||
<span class="tag-item">压缩痕迹: {{ compressMarks }}分</span>
|
||||
</div>
|
||||
<div class="tag-row">
|
||||
<span class="tag-item">明暗均衡: {{ balance }}分</span>
|
||||
<span class="tag-item">整体观感: {{ impression }}分</span>
|
||||
<span class="tag-item">细节体验: {{ detail }}分</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 每组的操作按钮 -->
|
||||
<div class="action-buttons" v-if="isEvaluate == '0'">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="confirmGroup(groupIndex)"
|
||||
:disabled="group.isSure === '1'"
|
||||
>
|
||||
{{ group.isSure === '1' ? '已确认' : '确认' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 保持原有的单一展示方式 -->
|
||||
<template v-else>
|
||||
<!-- 上传信息提示 -->
|
||||
<div class="upload-info" v-if ="isEvaluate ==0">
|
||||
<div class="upload-info" v-if ="isEvaluate == '0'">
|
||||
<img src="@/assets/images/imageCaptioning/photography.png" alt="" class="icon-photography">
|
||||
<span>{{ uploadInfo }}</span>
|
||||
</div>
|
||||
|
|
@ -16,53 +95,54 @@
|
|||
<img
|
||||
:src="result.url"
|
||||
alt=""
|
||||
:class="isEvaluate == '1' ? 'result-image-evaluate' : 'result-image-item'"
|
||||
:class="isEvaluate == '1' ? 'result-image-evaluate' : 'result-image'"
|
||||
>
|
||||
<!-- 右上角的hand图标 -->
|
||||
<img
|
||||
v-if="selectedImages[index] && isSure == '0'"
|
||||
v-if="selectedImages[index] && isEvaluate == '0'"
|
||||
src="@/assets/images/imageCaptioning/hand-yellow.png"
|
||||
alt="selected"
|
||||
class="icon-hand"
|
||||
@click="$emit('hand-click', result, index)"
|
||||
@click="handleImageClick(index, isSure)"
|
||||
>
|
||||
<img
|
||||
v-else-if="!selectedImages[index] && isSure == '0'"
|
||||
v-else-if="!selectedImages[index] && isEvaluate == '0'"
|
||||
src="@/assets/images/imageCaptioning/hand.png"
|
||||
alt="hand"
|
||||
class="icon-hand"
|
||||
@click="$emit('hand-click', result, index)"
|
||||
@click="handleImageClick(index, isSure)"
|
||||
>
|
||||
|
||||
|
||||
<div class="card-content" v-if="isEvaluate == '1'">
|
||||
<div class="card-footer">
|
||||
<div class="person-info">
|
||||
<span class="name">综合得分:80</span>
|
||||
<span class="date">2025-08-12</span>
|
||||
<span class="name">综合得分:{{ overallScore }}</span>
|
||||
<span class="date">{{ contentImage }}</span>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="tag-row">
|
||||
<span class="tag-item" style="padding-left: 16px;">清晰度: 20分</span>
|
||||
<span class="tag-item" style="padding-left: 16px;">干净度: 10分</span>
|
||||
<span class="tag-item">压缩痕迹: 10分</span>
|
||||
<span class="tag-item" style="padding-left: 16px;">清晰度: {{ clarity }}分</span>
|
||||
<span class="tag-item" style="padding-left: 16px;">干净度: {{ cleanliness }}分</span>
|
||||
<span class="tag-item">压缩痕迹: {{ compressMarks }}分</span>
|
||||
</div>
|
||||
<div class="tag-row">
|
||||
<span class="tag-item">明暗均衡: 10分</span>
|
||||
<span class="tag-item">整体观感: 15分</span>
|
||||
<span class="tag-item">细节体验: 15分</span>
|
||||
<span class="tag-item">明暗均衡: {{ balance }}分</span>
|
||||
<span class="tag-item">整体观感: {{ impression }}分</span>
|
||||
<span class="tag-item">细节体验: {{ detail }}分</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="action-buttons">
|
||||
<el-button type="primary" @click="$emit('confirm-results')" v-if="isSure == '0'">确认</el-button>
|
||||
<div class="action-buttons" v-if="isEvaluate == '0'">
|
||||
<el-button type="primary" @click="$emit('confirm-results')" :disabled="isSure === '1'">
|
||||
{{ isSure === '1' ? '已确认' : '确认' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -78,27 +158,55 @@ export default {
|
|||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
groupedImageResults: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
selectedImages: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
isSure: {
|
||||
type: String,
|
||||
default: '0'
|
||||
},
|
||||
isEvaluate: {
|
||||
type: String,
|
||||
default: '0'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isSure(newValue) {
|
||||
console.log('isSure changed to:', newValue);
|
||||
isSure: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 打印初始 isSure 的值
|
||||
console.log('Initial isSure:', this.isSure);
|
||||
methods: {
|
||||
isGroupImageSelected(groupIndex, imageIndex) {
|
||||
// 根据分组索引和图片索引判断是否选中
|
||||
const key = `${groupIndex}-${imageIndex}`;
|
||||
return !!this.selectedImages[key];
|
||||
},
|
||||
|
||||
handleGroupImageClick(groupIndex, imageIndex, groupIsSure) {
|
||||
// 如果该组已确认,则不允许更改选择
|
||||
if (groupIsSure === '1') {
|
||||
this.$message.warning('该组已确认,无法更改选择');
|
||||
return;
|
||||
}
|
||||
|
||||
const key = `${groupIndex}-${imageIndex}`;
|
||||
this.$emit('hand-click', {groupIndex, imageIndex, key});
|
||||
},
|
||||
|
||||
handleImageClick(index, isSure) {
|
||||
// 如果已确认,则不允许更改选择
|
||||
if (isSure === '1') {
|
||||
this.$message.warning('已确认,无法更改选择');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$emit('hand-click', {index, isSingle: true});
|
||||
},
|
||||
|
||||
confirmGroup(groupIndex) {
|
||||
// 可以在这里处理特定组的确认逻辑
|
||||
this.$emit('confirm-results', groupIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,196 @@
|
|||
<template>
|
||||
<div class="image-results-container">
|
||||
<!-- 保持原有的单一展示方式 -->
|
||||
<template >
|
||||
<!-- 图片识别结果展示 -->
|
||||
<div class="image-results-grid">
|
||||
<div
|
||||
v-for="(result, index) in imageResults"
|
||||
:key="index"
|
||||
class="image-item-evaluate"
|
||||
>
|
||||
<img
|
||||
:src="result.url"
|
||||
alt=""
|
||||
class="result-image-evaluate"
|
||||
>
|
||||
|
||||
<div class="card-content" >
|
||||
<div class="card-footer">
|
||||
<div class="person-info">
|
||||
<span class="name">综合得分:{{ result.overallScore }}</span>
|
||||
<span class="date">{{ result.contentImage }}</span>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="tag-row">
|
||||
<span class="tag-item" style="padding-left: 16px;">清晰度: {{ result.clarity }}分</span>
|
||||
<span class="tag-item" style="padding-left: 16px;">干净度: {{ result.cleanliness }}分</span>
|
||||
<span class="tag-item">压缩痕迹: {{ result.compressMarks }}分</span>
|
||||
</div>
|
||||
<div class="tag-row">
|
||||
<span class="tag-item">明暗均衡: {{ result.balance }}分</span>
|
||||
<span class="tag-item">整体观感: {{ result.impression }}分</span>
|
||||
<span class="tag-item">细节体验: {{ result.detail }}分</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ImageResults",
|
||||
props: {
|
||||
|
||||
imageResults: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.upload-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
color: #54646C;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.icon-photography {
|
||||
width: 47px;
|
||||
height: 47px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.image-results-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.image-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 260px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.image-item-evaluate {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 360px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.result-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.result-image-evaluate {
|
||||
width: 100%;
|
||||
height: 260px;
|
||||
}
|
||||
|
||||
.icon-hand {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 25px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.icon-hand:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
text-align: right;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
.card-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.person-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 10px 18px 0 18px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.date {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 10px 18px 0 18px;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.tag-row {
|
||||
display: table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
margin:3px 0 0 0;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
display: table-cell;
|
||||
width: 33.33%;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 10px 18px 10px 18px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
<HistoryView
|
||||
:upload-info="uploadInfo"
|
||||
:image-results="imageResults"
|
||||
:grouped-image-results="groupedImageResults"
|
||||
:selected-images="selectedImages"
|
||||
:tags="tags"
|
||||
:visible-tags="visibleTags"
|
||||
|
|
@ -106,6 +107,9 @@ export default {
|
|||
selectedImages: {}, // 用于跟踪选中的图片
|
||||
isSidebarVisible: true, // 控制左侧导航栏显示/隐藏
|
||||
isSure:'', //小图标,确定按钮 0-未确定 1-已确定
|
||||
addId:'', //新增id
|
||||
|
||||
groupedImageResults: [], // 新增分组数据
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -166,6 +170,7 @@ export default {
|
|||
this.selectedImages = {};
|
||||
this.showNewAnnotation = true;
|
||||
this.showNewAnnotationAdd = false;
|
||||
this.addId ='';
|
||||
},
|
||||
|
||||
startUpload() {
|
||||
|
|
@ -204,33 +209,44 @@ export default {
|
|||
formData.append('files', file.raw); // 使用 raw 字段获取原始文件对象
|
||||
});
|
||||
formData.append('param', selectedTagNames);
|
||||
formData.append('id', this.addId);
|
||||
//调用上传的接口,传递文件列表和标签IDs,name
|
||||
addImageInfoAPI(formData)
|
||||
.then(res => {
|
||||
loading.close();
|
||||
if (res.code === 200 && res.data && Array.isArray(res.data)) {
|
||||
// 处理成功响应
|
||||
const record = res.data[0]; // 获取第一条记录
|
||||
const totalCount = record.imageNum || originalFileList.length;
|
||||
const recognizedCount = record.bzNum || 0;
|
||||
const unrecognizedCount = record.wbzNum || (totalCount - recognizedCount);
|
||||
// 处理成功响应 - 获取全部记录
|
||||
const records = res.data;
|
||||
this.addId = records[0]?.operaId || '';
|
||||
console.log('this.addId:', this.addId)
|
||||
|
||||
this.uploadInfo = `上传${totalCount}张图片,可识别标注${recognizedCount}张,${unrecognizedCount}张无法识别标注。已识别标注图片如下,请确认。`;
|
||||
|
||||
// 设置图片结果
|
||||
this.imageResults = record.fileVoList.map(item => ({
|
||||
// 按下标分组存储数据
|
||||
this.groupedImageResults = records.map((record, index) => ({
|
||||
index: index, // 下标
|
||||
operaName: record.operaName,
|
||||
images: record.fileVoList.map(item => ({
|
||||
url: item.bjUrl || "未找到图片地址",
|
||||
id: item.imageId || item.id,
|
||||
name: item.originalName,
|
||||
contentImage: item.contentImage,
|
||||
fileSize: item.fileSize,
|
||||
operId: res.data[0].id , // 操作ID
|
||||
operId: record.id,
|
||||
})),
|
||||
totalCount: record.imageNum || originalFileList.length,
|
||||
recognizedCount: record.bzNum || 0,
|
||||
unrecognizedCount: record.wbzNum || 0,
|
||||
isSure: record.isSure,
|
||||
operId: record.id
|
||||
}));
|
||||
// 初始化选中状态 - 根据 isActive 字段
|
||||
this.initializeSelectedImages(records);
|
||||
|
||||
this.isSure = record.isSure;
|
||||
// this.isSure = record.isSure;
|
||||
|
||||
// 刷新左侧标签文本并选中对应标签
|
||||
this.refreshSidebarLabel(record.operaName, record.id);
|
||||
if (records.length > 0) {
|
||||
this.refreshSidebarLabel(records[0].operaName, records[0].id);
|
||||
}
|
||||
|
||||
this.showImageResults = true;
|
||||
this.showNewAnnotation = false;
|
||||
|
|
@ -354,67 +370,163 @@ export default {
|
|||
this.$message.success('已删除文件');
|
||||
},
|
||||
|
||||
// 处理手图标点击事件
|
||||
// 处理手图标点击事件
|
||||
handleHandClick(result, index) {
|
||||
console.log(result)
|
||||
console.log("点击了图片:", index)
|
||||
// 使用对象属性的方式跟踪选中状态
|
||||
if (this.selectedImages[index]) {
|
||||
console.log("取消选中:", index)
|
||||
this.$set(this.selectedImages, index, false)
|
||||
// 判断是分组模式还是普通模式
|
||||
if (typeof result === 'object' && result.hasOwnProperty('groupIndex') && result.hasOwnProperty('imageIndex')) {
|
||||
// 分组模式
|
||||
const { groupIndex, imageIndex, key } = result;
|
||||
|
||||
console.log("点击了分组图片:", groupIndex, imageIndex);
|
||||
|
||||
// 检查是否已有其他未确认分组的选中项
|
||||
const hasOtherUnconfirmedGroupSelection = Object.keys(this.selectedImages).some(k => {
|
||||
if (k.includes('-')) {
|
||||
const [otherGroupIndex, otherImageIndex] = k.split('-').map(Number);
|
||||
// 获取其他分组的信息
|
||||
const otherGroup = this.groupedImageResults[otherGroupIndex];
|
||||
// 只有当其他分组未确认且与当前分组不同时,才限制选择
|
||||
if (otherGroup && otherGroup.isSure !== '1' && otherGroupIndex !== groupIndex && this.selectedImages[k]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// 如果已有其他未确认分组的选中项,提示用户
|
||||
if (hasOtherUnconfirmedGroupSelection) {
|
||||
this.$message.warning('当前版本不支持跨组选择,请先取消其他组的选择');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selectedImages[key]) {
|
||||
console.log("取消选中分组图片:", groupIndex, imageIndex);
|
||||
this.$set(this.selectedImages, key, false);
|
||||
} else {
|
||||
console.log("选中:", index)
|
||||
this.$set(this.selectedImages, index, true)
|
||||
console.log("选中分组图片:", groupIndex, imageIndex);
|
||||
this.$set(this.selectedImages, key, true);
|
||||
}
|
||||
} else if (typeof result === 'object' && result.hasOwnProperty('index') && result.isSingle) {
|
||||
// 普通模式
|
||||
const { index } = result;
|
||||
console.log("点击了图片:", index);
|
||||
|
||||
if (this.selectedImages[index]) {
|
||||
console.log("取消选中:", index);
|
||||
this.$set(this.selectedImages, index, false);
|
||||
} else {
|
||||
console.log("选中:", index);
|
||||
this.$set(this.selectedImages, index, true);
|
||||
}
|
||||
} else {
|
||||
// 兼容旧的处理方式
|
||||
console.log(result);
|
||||
console.log("点击了图片:", index);
|
||||
|
||||
if (this.selectedImages[index]) {
|
||||
console.log("取消选中:", index);
|
||||
this.$set(this.selectedImages, index, false);
|
||||
} else {
|
||||
console.log("选中:", index);
|
||||
this.$set(this.selectedImages, index, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async generateTestData(recordId) {
|
||||
// 后端获取的数据
|
||||
try {
|
||||
const res = await getImageListDetailsAPI({id: recordId, operaType: 1})
|
||||
// 判断返回码和数据
|
||||
if (res.code === 200 && res.data && Array.isArray(res.data)) {
|
||||
// 处理图片结果数据
|
||||
this.imageResults = res.data[0].fileVoList.map((item, index) => ({
|
||||
url: item.bjUrl || item.url, // 使用 bjUrl 作为图片URL
|
||||
id: item.imageId || index, // 使用 imageId 作为ID
|
||||
name: item.originalName, // 原始文件名
|
||||
contentImage: item.contentImage, // 图片内容标签
|
||||
fileSize: item.fileSize, // 文件大小
|
||||
operId: res.data[0].id , // 操作ID
|
||||
this.addId = res.data[0].operaId;
|
||||
console.log('addId:', this.addId);
|
||||
// 按下标分组存储数据
|
||||
this.groupedImageResults = res.data.map((record, index) => ({
|
||||
index: index, // 下标
|
||||
operaName: record.operaName,
|
||||
images: record.fileVoList.map(item => ({
|
||||
url: item.bjUrl || item.url,
|
||||
id: item.imageId || item.id,
|
||||
name: item.originalName,
|
||||
contentImage: item.contentImage,
|
||||
fileSize: item.fileSize,
|
||||
operId: record.id
|
||||
})),
|
||||
totalCount: record.imageNum || 0,
|
||||
recognizedCount: record.bzNum || 0,
|
||||
unrecognizedCount: record.wbzNum || 0,
|
||||
isSure: record.isSure,
|
||||
operId: record.operaId
|
||||
}));
|
||||
|
||||
this.isSure = res.data[0].isSure;
|
||||
|
||||
const totalCount = res.data[0].imageNum || 0;
|
||||
const recognizedCount = res.data[0].bzNum || 0;
|
||||
const unrecognizedCount = res.data[0].wbzNum ;
|
||||
this.uploadInfo = `上传${totalCount}张图片,可识别标注${recognizedCount}张,${unrecognizedCount}张无法识别标注。已识别标注图片如下,请确认。`;
|
||||
// 初始化选中状态 - 根据 isActive 字段
|
||||
this.initializeSelectedImages(res.data);
|
||||
// 设置第一条记录的状态用于界面显示
|
||||
this.isSure = res.data[0]?.isSure || '';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取列表异常:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 获取选中图片的ID和operId
|
||||
getSelectedImageInfo() {
|
||||
const selectedImageInfo = [];
|
||||
|
||||
// 遍历选中的图片
|
||||
for (let key in this.selectedImages) {
|
||||
if (this.selectedImages[key]) {
|
||||
// 判断是分组模式还是普通模式
|
||||
if (key.includes('-')) {
|
||||
// 分组模式: key格式为 "groupIndex-imageIndex"
|
||||
const [groupIndex, imageIndex] = key.split('-').map(Number);
|
||||
const group = this.groupedImageResults[groupIndex];
|
||||
if (group && group.images[imageIndex]) {
|
||||
selectedImageInfo.push({
|
||||
imageId: group.images[imageIndex].id,
|
||||
operId: group.operId,
|
||||
imageName: group.images[imageIndex].name
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 普通模式: key是数字索引
|
||||
const index = parseInt(key);
|
||||
if (this.imageResults[index]) {
|
||||
selectedImageInfo.push({
|
||||
imageId: this.imageResults[index].id,
|
||||
operId: this.imageResults[index].operId,
|
||||
imageName: this.imageResults[index].name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selectedImageInfo;
|
||||
},
|
||||
|
||||
confirmResults() {
|
||||
console.log('当前 selectedImages 状态:', this.selectedImages);
|
||||
// 获取所有被选中的图片(基于 index 判断)
|
||||
const selectedItems = [];
|
||||
for (let index in this.selectedImages) {
|
||||
const idx = parseInt(index);
|
||||
if (this.selectedImages[idx]) {
|
||||
selectedItems.push(this.imageResults[idx]); // 根据 index 取出 imageResults 中对应图片
|
||||
}
|
||||
}
|
||||
if (selectedItems.length === 0) {
|
||||
this.$message.warning('请至少选择一张图片');
|
||||
return;
|
||||
}
|
||||
// 提取 operId 和 imageId
|
||||
const imageIds = selectedItems.map(item => item.id);
|
||||
const operId = selectedItems[0].operId; // 所有图片的 operId 应该一致
|
||||
const selectedInfo = this.getSelectedImageInfo();
|
||||
|
||||
if (selectedInfo.length === 0) {
|
||||
// this.$message.warning('请至少选择一张图片');
|
||||
// return;
|
||||
this.handleConfirm(this.addId, );
|
||||
}else{
|
||||
// 获取图片ID数组
|
||||
const imageIds = selectedInfo.map(item => item.imageId);
|
||||
|
||||
// 获取operId(假设所有选中图片属于同一组,使用第一个)
|
||||
const operId = selectedInfo[0].operId;
|
||||
|
||||
console.log('选中的图片IDs:', imageIds);
|
||||
console.log('操作ID:', operId);
|
||||
|
||||
// 调用确认接口
|
||||
this.handleConfirm(operId,imageIds);
|
||||
this.handleConfirm(operId, imageIds);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
async handleConfirm(operId,imageIds) {
|
||||
|
|
@ -439,7 +551,26 @@ export default {
|
|||
|
||||
toggleSidebar() {
|
||||
this.isSidebarVisible = !this.isSidebarVisible;
|
||||
},
|
||||
|
||||
|
||||
initializeSelectedImages(records) {
|
||||
// 清空当前选中状态
|
||||
this.selectedImages = {};
|
||||
// 遍历所有分组和图片
|
||||
records.forEach((record, groupIndex) => {
|
||||
if (record.fileVoList && Array.isArray(record.fileVoList)) {
|
||||
record.fileVoList.forEach((fileItem, imageIndex) => {
|
||||
// 如果 isActive 为 "1",则默认选中
|
||||
if (fileItem.isActive === "1") {
|
||||
const key = `${groupIndex}-${imageIndex}`;
|
||||
this.$set(this.selectedImages, key, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -83,17 +83,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getRole,
|
||||
delRole,
|
||||
addRole,
|
||||
updateRole,
|
||||
dataScope,
|
||||
changeRoleStatus,
|
||||
deptTreeSelect
|
||||
} from "@/api/system/role"
|
||||
import {treeselect as menuTreeselect, roleMenuTreeselect} from "@/api/system/menu"
|
||||
import {getMaterialListAPI} from "@/api/publicService/proMaterials";
|
||||
import {getAllImagelist} from "@/api/imageCaptioning/imageLibrary";
|
||||
|
||||
export default {
|
||||
name: "imageCaptioningLibrary",
|
||||
|
|
@ -107,7 +97,8 @@ export default {
|
|||
pageSize: 10,
|
||||
roleName: undefined,
|
||||
roleKey: undefined,
|
||||
status: undefined
|
||||
status: undefined,
|
||||
operaType: 2
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
|
|
@ -131,7 +122,7 @@ export default {
|
|||
},
|
||||
/** 查询角色列表 */
|
||||
getList() {
|
||||
getMaterialListAPI().then(response => {
|
||||
getAllImagelist(this.queryParams).then(response => {
|
||||
this.proMaterialsListAll = response.rows;
|
||||
this.total = response.total || 0;
|
||||
console.log(this.proMaterialsListAll)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
:image-results="imageResults"
|
||||
:selected-images="selectedImages"
|
||||
:file-list="fileList"
|
||||
:is-sure="isSure"
|
||||
@hand-click="handleHandClick"
|
||||
@confirm-results="confirmResults"
|
||||
@file-change="handleFileChange"
|
||||
|
|
@ -81,7 +80,7 @@ export default {
|
|||
imageResults: [],
|
||||
selectedImages: {}, // 用于跟踪选中的图片
|
||||
isSidebarVisible: true, // 控制左侧导航栏显示/隐藏
|
||||
isSure:'', //小图标,确定按钮 0-未确定 1-已确定
|
||||
addId: null,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -91,10 +90,9 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
|
||||
async getImageListAPI() {
|
||||
try {
|
||||
const res = await getImageListAPI({operaType: 1})
|
||||
const res = await getImageListAPI({operaType: 2})
|
||||
// 判断返回码和数据
|
||||
if (res.code === 200 && res.data && Array.isArray(res.data)) {
|
||||
this.labelList = res.data.map(item => ({
|
||||
|
|
@ -116,6 +114,7 @@ export default {
|
|||
this.selectedImages = {};
|
||||
this.showNewAnnotation = true;
|
||||
this.showNewAnnotationAdd = false;
|
||||
this.addId ='';
|
||||
},
|
||||
|
||||
startUpload() {
|
||||
|
|
@ -149,26 +148,39 @@ export default {
|
|||
originalFileList.forEach(file => {
|
||||
formData.append('files', file.raw); // 使用 raw 字段获取原始文件对象
|
||||
});
|
||||
|
||||
formData.append("id", this.addId)
|
||||
addImageEvaluateAPI(formData)
|
||||
.then(res => {
|
||||
loading.close();
|
||||
if (res.code === 200 && res.data && Array.isArray(res.data)) {
|
||||
// 处理成功响应
|
||||
const record = res.data[0]; // 获取第一条记录
|
||||
|
||||
// 设置图片结果
|
||||
this.imageResults = record.fileVoList.map(item => ({
|
||||
url: item.bjUrl || "未找到图片地址",
|
||||
id: item.imageId || item.id,
|
||||
this.addId = res.data[0].operaId;
|
||||
let allImageResults = [];
|
||||
res.data.forEach(record => {
|
||||
this.addId = record.operaId;
|
||||
const fileResults = record.fileVoList.map((item, index) => ({
|
||||
url: item.bjUrl || item.url,
|
||||
id: item.imageId || index,
|
||||
name: item.originalName,
|
||||
contentImage: item.contentImage,
|
||||
fileSize: item.fileSize,
|
||||
operId: res.data[0].id , // 操作ID
|
||||
operId: record.id,
|
||||
|
||||
overallScore: item.overallScore,
|
||||
clarity: item.clarity,
|
||||
cleanliness: item.cleanliness,
|
||||
compressMarks: item.compressMarks,
|
||||
impression: item.impression,
|
||||
balance: item.balance,
|
||||
detail: item.detail,
|
||||
}));
|
||||
|
||||
this.isSure = record.isSure;
|
||||
|
||||
allImageResults = allImageResults.concat(fileResults);
|
||||
});
|
||||
this.imageResults = allImageResults;
|
||||
// 刷新左侧标签文本并选中对应标签
|
||||
if (res.data.length > 0) {
|
||||
this.refreshSidebarLabel(res.data[0].operaName, res.data[0].id);
|
||||
}
|
||||
this.showImageResults = true;
|
||||
this.showNewAnnotation = false;
|
||||
this.showNewAnnotationAdd = true;
|
||||
|
|
@ -184,6 +196,18 @@ export default {
|
|||
});
|
||||
},
|
||||
|
||||
refreshSidebarLabel(operaName, recordId) {
|
||||
this.getImageListAPI()
|
||||
setTimeout(() => {
|
||||
const index = this.labelList.findIndex(item => item.id === recordId);
|
||||
if (index !== -1) {
|
||||
this.labelList[index].name = operaName;
|
||||
}
|
||||
// 选中对应的标签
|
||||
this.selectedItem = recordId;
|
||||
}, 500); // 延迟确保数据加载完成
|
||||
},
|
||||
|
||||
selectItem(item) {
|
||||
this.selectedItem = item.id;
|
||||
// 这里可以添加加载历史记录数据的逻辑
|
||||
|
|
@ -242,20 +266,32 @@ export default {
|
|||
async generateTestData(recordId) {
|
||||
// 后端获取的数据
|
||||
try {
|
||||
const res = await getImageListDetailsAPI({id: recordId, operaType: 1})
|
||||
const res = await getImageListDetailsAPI({id: recordId, operaType: 2})
|
||||
// 判断返回码和数据
|
||||
if (res.code === 200 && res.data && Array.isArray(res.data)) {
|
||||
// 处理图片结果数据
|
||||
this.imageResults = res.data[0].fileVoList.map((item, index) => ({
|
||||
url: item.bjUrl || item.url, // 使用 bjUrl 作为图片URL
|
||||
id: item.imageId || index, // 使用 imageId 作为ID
|
||||
name: item.originalName, // 原始文件名
|
||||
contentImage: item.contentImage, // 图片内容标签
|
||||
fileSize: item.fileSize, // 文件大小
|
||||
operId: res.data[0].id , // 操作ID
|
||||
}));
|
||||
this.addId = res.data[0].operaId;
|
||||
|
||||
this.isSure = res.data[0].isSure;
|
||||
let allImageResults = [];
|
||||
res.data.forEach(record => {
|
||||
const fileResults = record.fileVoList.map((item, index) => ({
|
||||
url: item.bjUrl || item.url,
|
||||
id: item.imageId || index,
|
||||
name: item.originalName,
|
||||
contentImage: item.contentImage,
|
||||
fileSize: item.fileSize,
|
||||
operId: record.id,
|
||||
|
||||
overallScore: item.overallScore,
|
||||
clarity: item.clarity,
|
||||
cleanliness: item.cleanliness,
|
||||
compressMarks: item.compressMarks,
|
||||
impression: item.impression,
|
||||
balance: item.balance,
|
||||
detail: item.detail,
|
||||
}));
|
||||
allImageResults = allImageResults.concat(fileResults);
|
||||
});
|
||||
this.imageResults = allImageResults;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取列表异常:', error)
|
||||
|
|
|
|||
Loading…
Reference in New Issue