图像评估的功能

This commit is contained in:
lSun 2025-09-29 19:11:23 +08:00
parent 7e42679767
commit e5f9814aeb
4 changed files with 286 additions and 56 deletions

View File

@ -0,0 +1,49 @@
import request from '@/utils/request'
import request_formdata from "@/utils/request_formdata";
// 查询标签列表
export function getSelectedAPI(data) {
return request({
url: '/image/caption/getSelected',
method: 'POST',
data,
})
}
// 查询左侧历史记录
export function getImageListAPI(data) {
return request({
url: '/image/caption/getImageList',
method: 'POST',
data,
})
}
//查询右侧的历史记录详情
export function getImageListDetailsAPI(data) {
return request({
url: '/image/caption/getImageListDetails',
method: 'POST',
data,
})
}
//新增标注
export function addImageEvaluateAPI(data) {
return request_formdata({
url: '/image/caption/addImageEvaluate',
method: 'POST',
data,
})
}
//修改图片
export function updateImageSureAPI(data) {
return request_formdata({
url: '/image/caption/updateImageSure',
method: 'POST',
data,
})
}

View File

@ -3,6 +3,7 @@
<!-- 可滚动区域 --> <!-- 可滚动区域 -->
<div class="scrollable-content"> <div class="scrollable-content">
<ImageResults <ImageResults
:is-evaluate="1"
:upload-info="uploadInfo" :upload-info="uploadInfo"
:image-results="imageResults" :image-results="imageResults"
:selected-images="selectedImages" :selected-images="selectedImages"

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="image-results-container"> <div class="image-results-container">
<!-- 上传信息提示 --> <!-- 上传信息提示 -->
<div class="upload-info"> <div class="upload-info" v-if ="isEvaluate ==0">
<img src="@/assets/images/imageCaptioning/photography.png" alt="" class="icon-photography"> <img src="@/assets/images/imageCaptioning/photography.png" alt="" class="icon-photography">
<span>{{ uploadInfo }}</span> <span>{{ uploadInfo }}</span>
</div> </div>
@ -11,12 +11,12 @@
<div <div
v-for="(result, index) in imageResults" v-for="(result, index) in imageResults"
:key="index" :key="index"
class="image-item" :class="isEvaluate == '1' ? 'image-item-evaluate' : 'image-item'"
> >
<img <img
:src="result.url" :src="result.url"
alt="" alt=""
class="result-image" :class="isEvaluate == '1' ? 'result-image-evaluate' : 'result-image-item'"
> >
<!-- 右上角的hand图标 --> <!-- 右上角的hand图标 -->
<img <img
@ -33,6 +33,29 @@
class="icon-hand" class="icon-hand"
@click="$emit('hand-click', result, index)" @click="$emit('hand-click', result, index)"
> >
<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>
</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>
</div>
<div class="tag-row">
<span class="tag-item">明暗均衡: 10</span>
<span class="tag-item">整体观感: 15</span>
<span class="tag-item">细节体验: 15</span>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
@ -62,7 +85,11 @@ export default {
isSure: { isSure: {
type: String, type: String,
default: '0' default: '0'
} },
isEvaluate: {
type: String,
default: '0'
},
}, },
watch: { watch: {
isSure(newValue) { isSure(newValue) {
@ -109,11 +136,25 @@ export default {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 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 { .result-image {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.result-image-evaluate {
width: 100%;
height: 260px;
}
.icon-hand { .icon-hand {
position: absolute; position: absolute;
top: 25px; top: 25px;
@ -133,4 +174,68 @@ export default {
text-align: right; text-align: right;
margin-bottom: 20px; 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> </style>

View File

@ -16,7 +16,7 @@
<div class="add-content"> <div class="add-content">
<!-- 标题 --> <!-- 标题 -->
<div class="welcome-message"> <div class="welcome-message">
我是你的图像标注助理 我是你的图像评估助理
</div> </div>
<!-- 图片上传区域 --> <!-- 图片上传区域 -->
@ -32,10 +32,10 @@
<!-- 主内容区域-历史 --> <!-- 主内容区域-历史 -->
<div class="main-content" v-if="showNewAnnotationAdd"> <div class="main-content" v-if="showNewAnnotationAdd">
<HistoryView <HistoryView
:upload-info="uploadInfo"
:image-results="imageResults" :image-results="imageResults"
:selected-images="selectedImages" :selected-images="selectedImages"
:file-list="fileList" :file-list="fileList"
:is-sure="isSure"
@hand-click="handleHandClick" @hand-click="handleHandClick"
@confirm-results="confirmResults" @confirm-results="confirmResults"
@file-change="handleFileChange" @file-change="handleFileChange"
@ -47,6 +47,13 @@
</template> </template>
<script> <script>
import {
getImageListAPI,
getImageListDetailsAPI,
addImageEvaluateAPI,
updateImageSureAPI
} from "@/api/imageCaptioning/imageEvaluate";
import Sidebar from "../image-captioning/components/Sidebar"; import Sidebar from "../image-captioning/components/Sidebar";
import FileUploader from "../image-captioning/components/FileUploaderUn"; import FileUploader from "../image-captioning/components/FileUploaderUn";
import HistoryView from "../image-captioning/components/HistoryViewUn"; import HistoryView from "../image-captioning/components/HistoryViewUn";
@ -63,29 +70,48 @@ export default {
showNewAnnotationAdd: false, // showNewAnnotationAdd: false, //
// //
labelList: [ labelList: [],
{id: 1, date: '2025-09-13', name: '安全帽、绝缘子...'},
{id: 2, date: '2025-09-10', name: '安全帽'}
],
selectedItem: null, selectedItem: null,
// //
fileList: [], fileList: [],
showImageResults: false, showImageResults: false,
uploadInfo: '',
// //
imageResults: [], imageResults: [],
selectedImages: {}, // selectedImages: {}, //
isSidebarVisible: true, // / isSidebarVisible: true, // /
isSure:'', // 0- 1-
} }
}, },
created() {
//
this.getImageListAPI()
},
methods: { methods: {
async getImageListAPI() {
try {
const res = await getImageListAPI({operaType: 1})
//
if (res.code === 200 && res.data && Array.isArray(res.data)) {
this.labelList = res.data.map(item => ({
id: item.id,
date: item.operaTime,
name: item.operaName
}))
}
} catch (error) {
console.error('获取列表异常:', error)
}
},
createNewLabel() { createNewLabel() {
this.selectedItem = null; this.selectedItem = null;
this.fileList = []; this.fileList = [];
this.showImageResults = false; this.showImageResults = false;
this.uploadInfo = '';
this.imageResults = []; this.imageResults = [];
this.selectedImages = {}; this.selectedImages = {};
this.showNewAnnotation = true; this.showNewAnnotation = true;
@ -117,32 +143,45 @@ export default {
// //
this.fileList = []; this.fileList = [];
// // FormData
setTimeout(() => { const formData = new FormData();
//
originalFileList.forEach(file => {
formData.append('files', file.raw); // 使 raw
});
addImageEvaluateAPI(formData)
.then(res => {
loading.close(); loading.close();
// if (res.code === 200 && res.data && Array.isArray(res.data)) {
const recognizedCount = Math.floor(originalFileList.length * 0.7); //
const unrecognizedCount = originalFileList.length - recognizedCount; const record = res.data[0]; //
this.uploadInfo = `上传${originalFileList.length}张图片,可识别标注${recognizedCount}张,${unrecognizedCount}张无法识别标注。已识别标注图片如下,请确认。`; //
this.imageResults = record.fileVoList.map(item => ({
// status url: item.bjUrl || "未找到图片地址",
this.imageResults = originalFileList.map((file, index) => ({ id: item.imageId || item.id,
url: file.url, name: item.originalName,
id: index, contentImage: item.contentImage,
// status: 1 0 fileSize: item.fileSize,
status: index < recognizedCount ? 1 : 0 operId: res.data[0].id , // ID
})); }));
console.log(this.imageResults); this.isSure = record.isSure;
this.showImageResults = true;
// this.showImageResults = true;
this.showNewAnnotation = false; this.showNewAnnotation = false;
this.showNewAnnotationAdd = true; this.showNewAnnotationAdd = true;
this.$message.success('上传和识别完成'); this.$message.success('上传和识别完成');
}, 1500); // 1.5 } else {
this.$message.error('上传失败');
}
})
.catch(error => {
loading.close();
console.error('上传异常:', error);
this.$message.error('上传过程中出现错误');
});
}, },
selectItem(item) { selectItem(item) {
@ -163,7 +202,7 @@ export default {
this.fileList = []; // this.fileList = []; //
this.showImageResults = true; // this.showImageResults = true; //
this.selectedImages = {}; // this.selectedImages = {}; //
// //
this.generateTestData(recordId); this.generateTestData(recordId);
} }
}, },
@ -200,32 +239,68 @@ export default {
} }
}, },
generateTestData(recordId) { async generateTestData(recordId) {
// //
const testData = { try {
id: recordId, const res = await getImageListDetailsAPI({id: recordId, operaType: 1})
date: '2025-09-13', //
name: '安全帽、绝缘子...', if (res.code === 200 && res.data && Array.isArray(res.data)) {
uploadInfo: `上传10张图片可识别标注6张4张无法识别标注。已识别标注图片如下请确认。`, //
imageResults: [ this.imageResults = res.data[0].fileVoList.map((item, index) => ({
{ url: item.bjUrl || item.url, // 使 bjUrl URL
url: 'https://fastly.picsum.photos/id/830/200/200.jpg?hmac=3ce7zNUn5yg_XKy7dHgIHta7t_0vghPQnAGUSGJuBZE', id: item.imageId || index, // 使 imageId ID
name: 'image1.jpg', name: item.originalName, //
}, contentImage: item.contentImage, //
{ fileSize: item.fileSize, //
url: 'https://example.com/image2.jpg', operId: res.data[0].id , // ID
name: 'image1.jpg', }));
},
]
};
this.uploadInfo = testData.uploadInfo; this.isSure = res.data[0].isSure;
this.imageResults = testData.imageResults; }
} catch (error) {
console.error('获取列表异常:', error)
}
}, },
confirmResults(){ confirmResults(){
console.log("确定") 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
//
this.handleConfirm(operId,imageIds);
}, },
async handleConfirm(operId,imageIds) {
try {
//
const res = await updateImageSureAPI({
id: operId,
imageId:imageIds
});
if (res.code === 200) {
this.$message.success('确认成功');
//
await this.generateTestData(operId);
} else {
this.$message.error('确认失败');
}
} catch (error) {
console.error('确认异常:', error);
this.$message.error('确认过程中出现错误');
}
},
toggleSidebar() { toggleSidebar() {
this.isSidebarVisible = !this.isSidebarVisible; this.isSidebarVisible = !this.isSidebarVisible;
} }