刘妍 2 weeks ago
commit 09323f2d37

@ -11,7 +11,7 @@
</div>
</div>
<div class="drawer-content">
<img class="content-image" src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"/>
<img class="content-image" :src="`${VITE_GLOB_API_URL}/20250818\\2025081816060064980138.jpeg`"/>
<div class="content-item-name">
<div class="item-name-label">实例名称</div>
<div class="item-name-value">公路-隔离栏破损识别</div>
@ -60,6 +60,8 @@
<script setup lang="ts">
import {} from "vue"
import { EditOutlined, CloseOutlined } from '@ant-design/icons-vue'
import { getAppEnvConfig } from '@/utils/env';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
</script>
<style lang="scss" scoped>

@ -21,7 +21,7 @@
<div class="show-list">
<div class="item-list" v-for="value in 10">
<div class="image-div">
<img class="image-item" src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png">
<img class="image-item" :src="`${VITE_GLOB_API_URL}/20250818\\2025081816060064980138.jpeg`">
<div class="image-icon">盖板缺失</div>
</div>
<div class="show-info-div">
@ -97,6 +97,8 @@ import { ref, h, } from "vue"
import { PlusOutlined, } from '@ant-design/icons-vue';
import AddInstanceModal from "./AddInstanceModal.vue";
import ShowInfoDrawer from "./ShowInfoDrawer.vue";
import { getAppEnvConfig } from '@/utils/env';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const instanceName = ref('')
const instanceAlgorithm = ref()
const addInstanceModal = ref(false)

@ -27,30 +27,34 @@
id: 'meitiku',
name: '媒体库',
children: [
// {
// id: '',
// name: '',
// },
{
id: 'allResource',
name: '全部资源',
id: '1',
name: '可见光',
},
{
id: 'wideAngle',
name: '广角照片',
id: '2',
name: '红外照片',
},
{
id: 'zoom',
id: '3',
name: '变焦照片',
},
{
id: 'infrared',
name: '红外照片',
id: '4',
name: '广角照片',
},
// {
// id: 'alone',
// name: '',
// },
{
id: 'video',
id: '5',
name: '视频资源',
},
{
id: '0',
name: '其他文件',
},
],
},
];

@ -17,12 +17,37 @@
<a-button :icon="h(BorderHorizontalOutlined)" @click="openComparisonModal">
变化检测
</a-button>
<a-button :icon="h(PlusOutlined)" type="primary" @click="addFolder">
新建文件夹
</a-button>
<a-button :icon="h(PlusOutlined)" @click="addFolder"> </a-button>
<a-button :icon="h(ColumnHeightOutlined)" @click="moveFolderOrFile"></a-button>
<a-button :icon="h(DeleteOutlined)" @click="deleteFolderOrFile"> </a-button>
<!-- <a-button :icon="h(DownloadOutlined)" @click="compressFolderOrFile"></a-button> -->
<a-button
:icon="h(DownloadOutlined)"
:loading="downloadAloneLoading"
@click="downloadAloneFile"
>
单独下载
</a-button>
<a-popover trigger="hover">
<template #content>
<div v-if="!downloadZipLoading">
选择下载的文件/文件夹压缩下载成一个压缩包文件
</div>
<div v-if="downloadZipLoading">
<a-progress
type="circle"
:percent="downloadZipPercent"
:format="(downloadZipPercent) => `下载中\n${downloadZipPercent}%`"
/>
</div>
</template>
<a-button
:icon="h(DownloadOutlined)"
:loading="downloadZipLoading"
@click="downloadZipOpenMoadl"
>
批量下载
</a-button>
</a-popover>
<a-radio-group v-model:value="tableType">
<a-radio-button value="table"><BarsOutlined /></a-radio-button>
<a-radio-button value="store"><AppstoreOutlined /></a-radio-button>
@ -97,7 +122,15 @@
<span
style="width: 100%; display: flex; align-items: center; justify-content: center"
>
{{ record.size ? parseFloat((record.size / (1024 * 1024)).toFixed(2)) + 'M' : '-' }}
{{
record.size
? record.size > 1024 * 1024
? parseFloat((record.size / (1024 * 1024)).toFixed(2)) + 'MB'
: record.size > 1024
? parseFloat((record.size / 1024).toFixed(2)) + 'KB'
: parseFloat(record.size) + 'B'
: '-'
}}
</span>
</template>
<template v-if="column.key === 'airLineName'">
@ -284,6 +317,41 @@
<Comparison @closeComparisonModal="closeComparisonModal" />
</a-modal>
<!-- 下载文件命名窗口 -->
<a-modal
v-model:open="downloadZipOpen"
title="压缩"
width="30%"
:centered="true"
:closable="false"
:destroyOnClose="true"
:keyboard="false"
:mask="false"
:maskClosable="false"
@ok="downloadZipFile"
@cancel="((zipFileName = null), (downloadRows = []))"
>
<div style="width: 100%; margin: 10px; padding: 10px">
<a-row>
<a-col :span="24">
<div style="width: 100%; height: 40px">批量下载会先进行压缩成一个文件然后再下载</div>
</a-col>
<a-col :span="4">
<div style="width: 100%"> 压缩包名称: </div>
</a-col>
<a-col :span="20">
<div style="width: 80%">
<a-input
v-model:value="zipFileName"
placeholder="请输入压缩文件的名称"
allowClear
></a-input>
</div>
</a-col>
</a-row>
</div>
</a-modal>
<Path
v-if="pathDivShow"
:pathDivShow="pathDivShow"
@ -335,6 +403,8 @@
import { columns, searchFormSchema } from './modal.data';
import dayjs from 'dayjs';
import { cloneDeep } from 'lodash-es';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
const { VITE_GLOB_MEDIALIBRARY_IMAGE_URL } = getAppEnvConfig();
const { createConfirm, createMessage } = useMessage();
@ -348,88 +418,98 @@
const tableHeight: any = ref(0);
watch(
() => tableType.value,
(newval) => {
//
if (newval === 'store') {
//
let query = { ...searchParams.value, page: 1, limit: 1000 };
if (routeFlag.value) {
query = {
...query,
taskId: route.query.flightId,
objectKeyExist: 1,
};
} else {
query = {
...query,
parentKey: nowParentKey.value,
};
() => {
//
getShowTableData();
},
);
function getShowTableData() {
//
if (tableType.value === 'store') {
//
let query = { ...searchParams.value, page: 1, limit: 1000 };
if (routeFlag.value) {
query = {
...query,
taskId: route.query.flightId,
objectKeyExist: 1,
};
} else {
query = {
...query,
//
parentKey: searchInfo.type
? nowParentKey.value == '0'
? ''
: nowParentKey.value
: nowParentKey.value,
type: searchInfo.type,
};
}
GetMediaFile(query).then((res) => {
showTableData.value = res.items;
tableTypeAfterShow.value = tableType.value;
// -
const containers = document.querySelectorAll('.ant-table-container');
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
if (containers) {
containers.forEach((container) => {
container.style.display = 'none';
});
}
GetMediaFile(query).then((res) => {
showTableData.value = res.items;
tableTypeAfterShow.value = newval;
// -
const containers = document.querySelectorAll('.ant-table-container');
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
if (containers) {
containers.forEach((container) => {
container.style.display = 'none';
});
}
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'none';
});
}
//
let selectRowsIdArray = getSelectRows().map((item) => item.id);
showTableData.value.forEach((item) => {
if (selectRowsIdArray.includes(item.id)) {
item.checked = true;
changeStore(
{
target: {
checked: true,
},
},
item,
);
}
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'none';
});
});
}
//
if (newval === 'table') {
reload().then((res) => {
tableTypeAfterShow.value = newval;
// -
const containers = document.querySelectorAll('.ant-table-container');
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
if (containers) {
containers.forEach((container) => {
container.style.display = 'block';
});
}
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'block';
});
}
//
let selectRowsIdArray = getSelectRows().map((item) => item.id);
showTableData.value.forEach((item) => {
if (selectRowsIdArray.includes(item.id)) {
item.checked = true;
changeStore(
{
target: {
checked: true,
},
},
item,
);
}
//
let selectRowsIdArray = showTableData.value.filter((item) => item.checked);
setSelectedRows(selectRowsIdArray);
});
}
},
);
});
}
//
if (tableType.value === 'table') {
reload().then((res) => {
tableTypeAfterShow.value = tableType.value;
// -
const containers = document.querySelectorAll('.ant-table-container');
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
if (containers) {
containers.forEach((container) => {
container.style.display = 'block';
});
}
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'flex';
});
}
//
let selectRowsIdArray = showTableData.value.filter((item) => item.checked);
setSelectedRows(selectRowsIdArray);
});
}
}
//
const checkNameChecked = ref(false);
// or
// or-
function changeStore(e, record) {
if (typeof record == 'string') {
if (e.target.checked) {
@ -545,7 +625,12 @@
...data,
page: tableTypeAfterShow.value == 'table' ? data.page : 1,
limit: tableTypeAfterShow.value == 'table' ? data.limit : 1000,
parentKey: nowParentKey.value,
//
parentKey: searchInfo.type
? nowParentKey.value == '0'
? ''
: nowParentKey.value
: nowParentKey.value,
};
return temp;
}
@ -575,6 +660,19 @@
arr.graffitiJson = [];
}
});
showTableData.value = result;
setTimeout(() => {
//
if (tableType.value === 'store') {
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'none';
});
}
}
}, 100);
return result;
},
});
@ -606,9 +704,16 @@
// ----------------------------------------------------------------------
//
function handleSelect(orgId = '') {
searchInfo.orgId = orgId;
reload();
function handleSelect(type = '') {
searchInfo.type = type;
//
if (tableType.value == 'table') {
reload();
}
//
if (tableType.value === 'store') {
getShowTableData();
}
}
//
const childRef = ref<any>();
@ -641,7 +746,13 @@
} else {
query = {
...query,
parentKey: nowParentKey.value,
//
parentKey: searchInfo.type
? nowParentKey.value == '0'
? ''
: nowParentKey.value
: nowParentKey.value,
type: searchInfo.type,
};
}
GetMediaFile(query).then((res) => {
@ -725,6 +836,147 @@
});
}
//
const downloadAloneLoading = ref(false);
async function downloadAloneFile() {
//
let rows = getSelectRows();
if (tableType.value == 'store') {
rows = showTableData.value.filter((item) => item.checked);
}
if (rows.length != 1) {
return createMessage.warn('请选择一个文件进行下载');
}
if (!rows[0].objectKey) {
return createMessage.warn('单独下载只能下载非文件夹的文件');
}
try {
downloadAloneLoading.value = true;
const response = await fetch(VITE_GLOB_MEDIALIBRARY_IMAGE_URL + rows[0].objectKey, {
mode: 'cors',
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const blob = await response.blob();
const urlObject = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = urlObject;
link.download = rows[0].name || 'download';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(urlObject);
} catch (error) {
console.error('Error downloading image:', error);
} finally {
downloadAloneLoading.value = false;
}
}
//
const downloadZipOpen = ref(false);
const downloadZipLoading = ref(false);
const downloadZipPercent = ref(0);
//
let downloadRows: any = [];
const zipFileName = ref('');
// -
function downloadZipOpenMoadl() {
//
let rows = getSelectRows();
if (tableType.value == 'store') {
rows = showTableData.value.filter((item) => item.checked);
}
if (rows.length == 0) {
return createMessage.warn('请选择一个或者多个文件/文件夹进行下载');
}
zipFileName.value = '压缩文件' + dayjs().format('YYYY-MM-DD HH:mm:ss');
if (floders.value.length > 1) {
zipFileName.value = floders.value[floders.value.length - 1].name;
}
if (rows.length == 1 && !rows[0].objectKey) {
zipFileName.value = rows[0].name;
}
downloadRows = rows;
downloadZipOpen.value = true;
}
// -
async function downloadZipFile() {
if (!zipFileName.value) {
return createMessage.warn('压缩包名称不能为空');
}
downloadZipOpen.value = false;
downloadZipLoading.value = true;
getFileList(downloadRows).then(async (res) => {
let filelist: any = res;
const token = localStorage.getItem('X-Token');
const zip = new JSZip();
// ZIP
let index = 0;
for (const file of filelist) {
try {
const response = await fetch(file.url + '?t=' + Date.now(), {
headers: {
Authorization: `Bearer ${token}`,
},
mode: 'cors',
});
if (!response.ok) {
throw new Error(`HTTP 错误: ${response.status} - ${response.statusText}`);
}
const blob = await response.blob();
zip.file(`${file.path}/${file.name}`, blob, { binary: true });
} catch (error) {
console.error('请求失败:', error);
} finally {
index++;
downloadZipPercent.value = parseFloat(((index / filelist.length) * 100).toFixed(2));
}
}
// ZIP
try {
const blob = await zip.generateAsync({ type: 'blob' });
saveAs(blob, zipFileName.value + '.zip'); // ZIP
} catch (error) {
console.error('生成ZIP文件时出错:', error);
} finally {
downloadZipLoading.value = false;
}
});
}
// -
async function getFileList(rows) {
const filelist: any = [];
// 使 for...of await
for (const item of rows) {
if (item.objectKey) {
//
filelist.push({
name: item.name,
url: VITE_GLOB_MEDIALIBRARY_IMAGE_URL + item.objectKey,
path: '',
});
} else {
//
const res = await GetMediaFile({
parentKey: item.id,
page: 1,
limit: 1000,
});
res.items.forEach((r) => {
filelist.push({
name: r.name,
url: VITE_GLOB_MEDIALIBRARY_IMAGE_URL + r.objectKey,
path: item.name, //
});
});
}
}
return filelist;
}
// ----------------------------------------------------------------------------
const openPreview = ref(false);
//
@ -746,7 +998,13 @@
} else {
query = {
...query,
parentKey: nowParentKey.value,
//
parentKey: searchInfo.type
? nowParentKey.value == '0'
? ''
: nowParentKey.value
: nowParentKey.value,
type: searchInfo.type,
};
}
GetMediaFile(query).then((res) => {
@ -773,6 +1031,9 @@
showTableData.value = res;
});
}
setTimeout(() => {
clearSelectedRowKeys();
}, 500);
}
function uniqueByKey(arrlist, record) {
let resultList: any = [];
@ -851,7 +1112,13 @@
} else {
query = {
...query,
parentKey: nowParentKey.value,
//
parentKey: searchInfo.type
? nowParentKey.value == '0'
? ''
: nowParentKey.value
: nowParentKey.value,
type: searchInfo.type,
};
}
GetMediaFile(query).then((res) => {
@ -913,7 +1180,7 @@
flex-wrap: wrap;
}
.flodersname {
max-width: 120px;
max-width: 240px;
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 超出显示省略号 */
@ -1001,4 +1268,8 @@
::v-deep .ant-modal-body {
height: 100% !important;
}
::v-deep .ant-pagination {
justify-content: flex-end !important;
}
</style>

@ -24,34 +24,40 @@
</div>
<div class="titleTime">
<ClockCircleOutlined />
&nbsp;&nbsp;
<span>
{{
'&nbsp;&nbsp;' +
dayjs(props.nowShowImageData.createTime).format('YYYY-MM-DD HH:mm:ss (UTCZ)') +
'&nbsp;&nbsp;&nbsp;'
}}
{{ dayjs(props.nowShowImageData.createTime).format('YYYY-MM-DD HH:mm:ss (UTCZ)') }}
</span>
&nbsp;&nbsp;&nbsp;
<span>
{{
props.nowShowImageData.siz
? (props.nowShowImageData.size / 1024 / 1024).toFixed(2) + 'M' + '&nbsp;&nbsp;&nbsp;'
: imageSize + '&nbsp;&nbsp;&nbsp;'
props.nowShowImageData.size
? props.nowShowImageData.size > 1024 * 1024
? parseFloat((props.nowShowImageData.size / (1024 * 1024)).toFixed(2)) + 'MB'
: props.nowShowImageData.size > 1024
? parseFloat((props.nowShowImageData.size / 1024).toFixed(2)) + 'KB'
: parseFloat(props.nowShowImageData.size) + 'B'
: imageSize
}}
</span>
&nbsp;&nbsp;&nbsp;
<span>
{{ props.nowShowImageData.width + ' x ' + props.nowShowImageData.height }}
</span>
</div>
<div class="titleCoordinate">
<span>
{{ props.nowShowImageData.lat + '° E' + '&nbsp;&nbsp;&nbsp;&nbsp;' }}
{{ props.nowShowImageData.lat + '° E' }}
</span>
&nbsp;&nbsp;&nbsp;&nbsp;
<span>
{{ props.nowShowImageData.lng + '° N' + '&nbsp;&nbsp;&nbsp;&nbsp;' }}
{{ props.nowShowImageData.lng + '° N' }}
</span>
&nbsp;&nbsp;&nbsp;&nbsp;
<span>
{{ '拍摄高度' + props.nowShowImageData.relativeAltitude + 'm &nbsp;&nbsp;&nbsp;&nbsp;' }}
{{ '拍摄高度' + props.nowShowImageData.relativeAltitude + 'm' }}
</span>
&nbsp;&nbsp;&nbsp;&nbsp;
</div>
</div>
<!-- 标签 -->
@ -865,8 +871,15 @@
const contentLength = response.headers.get('Content-Length');
if (contentLength) {
const sizeInBytes = parseInt(contentLength, 10);
const sizeInMB = (sizeInBytes / (1024 * 1024)).toFixed(2);
imageSize.value = parseFloat(sizeInMB) + 'M';
if (sizeInBytes > 1024 * 1024) {
imageSize.value = (sizeInBytes / (1024 * 1024)).toFixed(2) + 'MB';
} else if (sizeInBytes > 1024) {
imageSize.value = (sizeInBytes / 1024).toFixed(2) + 'KB';
} else if (sizeInBytes > 0) {
imageSize.value = sizeInBytes + 'B';
} else {
imageSize.value = '--';
}
} else {
imageSize.value = '--';
}

@ -192,24 +192,20 @@
const imageTypeSelect = ref([]);
const imageOptions: any = ref([
{
value: '广角照片',
label: '广角照片',
},
{
value: '变焦照片',
label: '变焦照片',
value: 1,
label: '可见光照片',
},
{
value: '红外照片',
value: 2,
label: '红外照片',
},
{
value: '全景图',
label: '全景图',
value: 3,
label: '变焦照片',
},
{
value: '码流截图',
label: '码流截图',
value: 4,
label: '广角照片',
},
]);
//
@ -223,11 +219,9 @@
});
}
//
// if (tagSelect.value.length > 0) {
// imageTypeSelect.value.forEach((imagetype) => {
// filterImageData = filterImageData.filter((item) => item.fileTags.includes(imagetype));
// });
// }
if (imageTypeSelect.value.length > 0) {
filterImageData = filterImageData.filter((item) => imageTypeSelect.value.includes(item.type));
}
//
if (searchValue.value) {
filterImageData = filterImageData.filter((item) => item.name.includes(searchValue.value));

@ -21,7 +21,7 @@
<span class="infotitle">照片类型</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.imgtype || '--' }} </span>
<span class="infovalue">{{ getImageType(props.nowPreviewRecord.type) || '--' }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">任务名称</span>
@ -50,7 +50,11 @@
<span class="infovalue">
{{
props.nowPreviewRecord.size
? (props.nowPreviewRecord.size / 1024 / 1024).toFixed(2) + 'M'
? props.nowPreviewRecord.size > 1024 * 1024
? parseFloat((props.nowPreviewRecord.size / (1024 * 1024)).toFixed(2)) + 'MB'
: props.nowPreviewRecord.size > 1024
? parseFloat((props.nowPreviewRecord.size / 1024).toFixed(2)) + 'KB'
: parseFloat(props.nowPreviewRecord.size) + 'B'
: imageSize
}}
</span>
@ -266,6 +270,26 @@
editName.value = props.nowPreviewRecord.name.split('.').slice(0, -1).join('.');
}
//
function getImageType(type) {
let imageType = '';
switch (type) {
case 1:
imageType = '可见光照片';
break;
case 2:
imageType = '红外照片';
break;
case 3:
imageType = '变焦照片';
break;
case 4:
imageType = '广角照片';
break;
}
return imageType;
}
// --------------------------------
const addFileTagsFlag = ref(false);
const newFileTagsName = ref('');
@ -382,8 +406,15 @@
const contentLength = response.headers.get('Content-Length');
if (contentLength) {
const sizeInBytes = parseInt(contentLength, 10);
const sizeInMB = (sizeInBytes / (1024 * 1024)).toFixed(2);
imageSize.value = parseFloat(sizeInMB) + 'M';
if (sizeInBytes > 1024 * 1024) {
imageSize.value = (sizeInBytes / (1024 * 1024)).toFixed(2) + 'MB';
} else if (sizeInBytes > 1024) {
imageSize.value = (sizeInBytes / 1024).toFixed(2) + 'KB';
} else if (sizeInBytes > 0) {
imageSize.value = sizeInBytes + 'B';
} else {
imageSize.value = '--';
}
} else {
imageSize.value = '--';
}

Loading…
Cancel
Save