image_captioning_platform_web/src/views/imageCaptioning/image-evaluate/index.vue

382 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="image-captioning-container">
<!-- 左侧导航栏 -->
<Sidebar
:is-sidebar-visible="isSidebarVisible"
:label-list="labelList"
:selected-item="selectedItem"
@toggle-sidebar="toggleSidebar"
@create-new-label="createNewLabel"
@select-item="selectItem"
/>
<!-- 主内容区域 -->
<div class="main-content" v-if="showNewAnnotation">
<!-- 主内容区域-新增的 -->
<div class="add-content">
<!-- 标题 -->
<div class="welcome-message">
我是你的图像评估助理
</div>
<!-- 图片上传区域 -->
<FileUploader
:file-list="fileList"
@file-change="handleFileChange"
@remove-image="removeImage"
@start-upload="startUpload"
/>
</div>
</div>
<!-- 主内容区域-历史 -->
<div class="main-content" v-if="showNewAnnotationAdd">
<HistoryView
:image-results="imageResults"
:selected-images="selectedImages"
:file-list="fileList"
@hand-click="handleHandClick"
@confirm-results="confirmResults"
@file-change="handleFileChange"
@remove-image="removeImage"
@start-upload="startUpload"
/>
</div>
</div>
</template>
<script>
import {
getImageListAPI,
getImageListDetailsAPI,
addImageEvaluateAPI,
updateImageSureAPI
} from "@/api/imageCaptioning/imageEvaluate";
import Sidebar from "../image-captioning/components/Sidebar";
import FileUploader from "../image-captioning/components/FileUploaderUn";
import HistoryView from "../image-captioning/components/HistoryViewUn";
export default {
name: "imageCaptioning",
components: {
Sidebar,
FileUploader,
HistoryView
},
data() {
return {
showNewAnnotation: true, // 控制新建标注界面的显示状态
showNewAnnotationAdd: false, // 控制历史界面的显示状态
// 导航栏数据
labelList: [],
selectedItem: null,
// 文件上传相关
fileList: [],
showImageResults: false,
// 图片识别结果
imageResults: [],
selectedImages: {}, // 用于跟踪选中的图片
isSidebarVisible: true, // 控制左侧导航栏显示/隐藏
addId: '',
}
},
created() {
//查询左侧历史记录
this.getImageListAPI()
},
methods: {
async getImageListAPI() {
try {
const res = await getImageListAPI({operaType: 2})
// 判断返回码和数据
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() {
this.selectedItem = null;
this.fileList = [];
this.showImageResults = false;
this.imageResults = [];
this.selectedImages = {};
this.showNewAnnotation = true;
this.showNewAnnotationAdd = false;
this.addId ='';
},
startUpload() {
console.log('开始上传')
if (this.fileList.length === 0) {
this.$message.warning('请上传图片')
return
}
// 初始化 selectedImages
this.selectedImages = {};
// 显示加载状态
const loading = this.$loading({
lock: true,
text: '正在上传和识别图片...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
// 保存原始文件列表用于显示结果
const originalFileList = [...this.fileList];
// 清空上传预览区域
this.fileList = [];
// 创建 FormData 对象
const formData = new FormData();
// 添加文件
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)) {
// 处理成功响应
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: record.id,
overallScore: item.overallScore,
clarity: item.clarity,
cleanliness: item.cleanliness,
compressMarks: item.compressMarks,
impression: item.impression,
balance: item.balance,
detail: item.detail,
dictValue:item.dictValue
}));
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;
this.$message.success('上传和识别完成');
} else {
this.$message.error('上传失败');
}
})
.catch(error => {
loading.close();
console.error('上传异常:', error);
this.$message.error('上传过程中出现错误');
});
},
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;
// 这里可以添加加载历史记录数据的逻辑
this.loadRecordData(item.id);
},
loadRecordData(recordId) {
// 模拟加载历史记录数据
const record = this.labelList.find(r => r.id === recordId);
if (record) {
this.showNewAnnotation = false;
this.showNewAnnotationAdd = true;
// 这里可以添加实际的数据加载逻辑
this.fileList = []; // 清空文件列表
this.showImageResults = true; // 显示识别结果
this.selectedImages = {}; // 初始化选中状态
// 生成数据
this.generateTestData(recordId);
}
},
handleFileChange(file, fileList) {
if (file.raw) {
const reader = new FileReader();
reader.onload = (e) => {
file.url = e.target.result;
};
reader.readAsDataURL(file.raw);
}
// 延迟设置fileList确保file.url已正确设置
setTimeout(() => {
this.fileList = fileList;
}, 100);
},
removeImage(index) {
this.fileList.splice(index, 1);
this.$message.success('已删除文件');
},
// 处理手图标点击事件
handleHandClick(result, index) {
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: 2})
// 判断返回码和数据
if (res.code === 200 && res.data && Array.isArray(res.data)) {
this.addId = res.data[0].operaId;
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,
dictValue:item.dictValue
}));
allImageResults = allImageResults.concat(fileResults);
});
this.imageResults = allImageResults;
}
} catch (error) {
console.error('获取列表异常:', error)
}
},
confirmResults(){
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() {
this.isSidebarVisible = !this.isSidebarVisible;
}
},
}
</script>
<style scoped>
.image-captioning-container {
display: flex;
overflow: hidden;
height: calc(100vh - 84px);
width: 100%;
background: url('../../../assets/images/imageCaptioning/login-bg-background.png') no-repeat center center;
background-size: 100% 100%;
}
.main-content {
flex: 1;
padding: 40px;
overflow-y: auto;
}
.add-content {
height: 55%;
width: 60%;
margin-top: 15%;
margin-left: 22%;
}
.welcome-message {
text-align: center;
font-size: 20px;
margin-bottom: 50px;
font-weight: 600;
color: #334249;
font-style: normal;
text-transform: none;
}
</style>