You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

469 lines
14 KiB
Vue

<template>
<div>
<div class="title"> 详细信息 </div>
<div class="infoDiv">
<a-row>
<a-col :span="7">
<span class="infotitle">图片名称</span>
</a-col>
<a-col :span="17">
<span class="infovalue_name" v-if="editNameFlag">
{{ props.nowPreviewRecord.name }}
<EditOutlined style="font-size: 20px; color: #07aaed" @click="editNameChange" />
</span>
<span class="infovalue_name" v-if="!editNameFlag">
<a-input v-model:value="editName" size="small" />
<CheckOutlined style="margin-left: 5px; color: green" @click="pressEnterNameFunction" />
<CloseOutlined style="margin-left: 5px; color: red" @click="editNameBlur" />
</span>
</a-col>
<a-col :span="7">
<span class="infotitle">照片类型</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.imgtype }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">任务名称</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.taskname }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">航线名称</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.airlineName }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">照片分辨率</span>
</a-col>
<a-col :span="17">
<span class="infovalue">
{{ props.nowPreviewRecord.width + ' x ' + props.nowPreviewRecord.height }}
</span>
</a-col>
<a-col :span="7">
<span class="infotitle">照片大小</span>
</a-col>
<a-col :span="17">
<span class="infovalue">
{{
props.nowPreviewRecord.size
? (props.nowPreviewRecord.size / 1024 / 1024).toFixed(2) + 'M'
: 0
}}
</span>
</a-col>
<a-col :span="7">
<span class="infotitle">拍摄飞机</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.photographFeiji }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">拍摄负载</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.payloadName }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">拍摄人员</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.photographMan }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">拍摄时间</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.createTime }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">标签</span>
</a-col>
<a-col :span="17">
<span class="infovalue_graffitiNum">
<a-tag color="success" v-for="la in props.nowPreviewRecord.fileTags" :key="la">
{{ la }}
</a-tag>
<PlusSquareOutlined
style="font-size: 20px; color: #07aaed"
@click="addFileTagsChange"
/>
</span>
<a-modal
title="标签设置"
:open="addFileTagsFlag"
:mask="false"
:maskClosable="false"
:closable="false"
:footer="null"
>
<div style="display: block">
<div
style="display: flex; flex-wrap: wrap; gap: 5px; width: 96%; margin: 10px"
v-if="props.nowPreviewRecord.fileTags.length > 0"
>
已添加的标签:
<div
v-for="la in props.nowPreviewRecord.fileTags"
:key="la"
style="border: 1px solid #595959; border-radius: 3px"
>
<span style="margin-left: 5px">{{ la }}</span>
<CloseOutlined
style="margin-left: 5px; margin-right: 5px"
@click="deleteFileTags(la)"
/>
</div>
</div>
<div style="display: inline-flex; gap: 5px; width: 96%; margin: 10px">
<a-input v-model:value="newFileTagsName" size="small" placeholder="请输入标签" />
<a-button type="primary" @click="pressEnterFileTagsFunction">添加</a-button>
</div>
<div
style="
display: inline-flex;
gap: 5px;
width: 96%;
margin: 5px 10px 20px 10px;
justify-content: flex-end;
"
>
<a-button
@click="
addFileTagsFlag = false;
newFileTagsName = '';
"
>
关闭
</a-button>
</div>
</div>
</a-modal>
</a-col>
<a-col :span="7">
<span class="infotitle">涂鸦总数</span>
</a-col>
<a-col
:span="17"
style="
position: relative;
display: flex;
align-items: center;
justify-content: flex-start;
"
@mouseenter="showGraffitiNum = true"
@mouseleave="showGraffitiNum = false"
>
<div class="graffitiNum">
<EditOutlined style="color: #ffffff" />
<span>
{{
props.nowPreviewRecord.graffitiJson ? props.nowPreviewRecord.graffitiJson.length : 0
}}
</span>
</div>
<div
v-if="showGraffitiNum"
style="position: absolute; top: 36px; left: 5px; width: 60%; z-index: 1000"
:style="{
height: `${options.length * 30}px`,
}"
>
<div v-for="op in options" :key="op.text" style="width: 100%; height: 30px">
<div class="graffitiNum2">
<span>
{{ op.text }}
</span>
<span>
{{ op.num }}
</span>
</div>
</div>
</div>
</a-col>
<a-col :span="7">
<span class="infotitle">照片位置</span>
</a-col>
<a-col :span="17">
<span class="infobutton">
<a-tooltip placement="top">
<template #title>
<div>查看地图图片历史路径</div>
<div>只展示在地图上加载的图片</div>
</template>
<EnvironmentOutlined
v-if="props.nowPreviewRecord.showOnMap == 1"
style="font-size: 20px; color: #07aaed"
@click="openPathModal"
/>
</a-tooltip>
</span>
</a-col>
<a-col :span="24">
<div class="map">
<Map
:nowPreviewRecord="props.nowPreviewRecord"
:previewRecordList="props.previewRecordList"
@chooseNowPreviewRecord="chooseNowPreviewRecord"
:hideOrShowTextboxFlag="props.hideOrShowTextboxFlag"
/>
</div>
</a-col>
</a-row>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, computed } from 'vue';
import {
EditOutlined,
PlusSquareOutlined,
EnvironmentOutlined,
CheckOutlined,
CloseOutlined,
} from '@ant-design/icons-vue';
import { UpdatePicStatus, UpdatePicName } from '@/api/demo/mediaLibrary';
import { Map } from './preview';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['nowPreviewRecord', 'previewRecordList', 'hideOrShowTextboxFlag']);
const emits = defineEmits(['chooseNowPreviewRecord', 'handleSuccess', 'openPathModal']);
// 修改名称--------------------------------
const editNameFlag = ref(true);
const editName = ref(props.nowPreviewRecord.name.split('.').slice(0, -1).join('.'));
function editNameChange() {
if (props.nowPreviewRecord.name.split('.').length <= 1) {
editName.value = props.nowPreviewRecord.name;
}
editNameFlag.value = false;
}
// 修改名称方法
async function pressEnterNameFunction() {
let newName: any = null;
if (props.nowPreviewRecord.name.split('.').length <= 1) {
newName = editName.value;
} else {
newName = editName.value + '.' + props.nowPreviewRecord.name.split('.').pop();
}
let query = {
id: props.nowPreviewRecord.id,
name: newName,
};
UpdatePicName(query).then((res) => {
props.nowPreviewRecord.name = newName;
editNameFlag.value = true;
createMessage.success(res);
emits('handleSuccess');
});
}
function editNameBlur() {
editNameFlag.value = true;
editName.value = props.nowPreviewRecord.name.split('.').slice(0, -1).join('.');
}
// 标签--------------------------------
const addFileTagsFlag = ref(false);
const newFileTagsName = ref('');
const graffitiJson: any = ref([]);
const fileTags: any = ref([]);
watch(
() => props.nowPreviewRecord,
() => {
graffitiJson.value = props.nowPreviewRecord.graffitiJson
? props.nowPreviewRecord.graffitiJson
: [];
fileTags.value = props.nowPreviewRecord.fileTags ? props.nowPreviewRecord.fileTags : [];
},
{
deep: true,
immediate: true,
},
);
function addFileTagsChange() {
addFileTagsFlag.value = true;
}
// 添加标签方法
async function pressEnterFileTagsFunction() {
if (!newFileTagsName.value) {
return;
}
if (!fileTags.value.includes(newFileTagsName.value)) {
fileTags.value.push(newFileTagsName.value);
UpdatePicStatus({
id: props.nowPreviewRecord.id,
fileTags: JSON.stringify(fileTags.value),
graffitiJson: JSON.stringify(graffitiJson.value),
display: props.nowPreviewRecord.display,
showOnMap: props.nowPreviewRecord.showOnMap,
}).then((res) => {
addFileTagsFlag.value = true;
newFileTagsName.value = '';
createMessage.success('添加标签成功');
emits('handleSuccess');
});
} else {
return createMessage.error('此标签已存在!');
}
}
// 删除标签
function deleteFileTags(value) {
createConfirm({
iconType: 'info',
title: '提醒',
content: '删除标签【' + value + '】,同标签名的涂鸦标记都会被删除!',
onOk: () => {
fileTags.value = fileTags.value.filter((item) => item !== value);
let json = graffitiJson.value;
if (json.some((item) => item.text == value)) {
json = json.filter((item) => item.text !== value);
graffitiJson.value = json;
}
UpdatePicStatus({
id: props.nowPreviewRecord.id,
fileTags: JSON.stringify(fileTags.value),
graffitiJson: JSON.stringify(graffitiJson.value),
display: props.nowPreviewRecord.display,
showOnMap: props.nowPreviewRecord.showOnMap,
}).then((res) => {
createMessage.success('删除标签成功');
emits('handleSuccess');
});
},
onCancel: () => {},
});
}
const showGraffitiNum = ref(false);
const options = computed(() => {
if (props.nowPreviewRecord.graffitiJson) {
const map = {};
// 遍历数组,统计每个 text 出现的次数
props.nowPreviewRecord.graffitiJson.forEach((item) => {
const key = item.text;
if (map[key]) {
map[key].num += 1;
} else {
map[key] = { text: key, num: 1 };
}
});
// 将 map 的值转成数组返回
return Object.values(map);
} else {
return [];
}
});
// 选择
function chooseNowPreviewRecord(value) {
emits('chooseNowPreviewRecord', value);
}
// 打开路径弹窗
function openPathModal() {
emits('openPathModal', props.nowPreviewRecord);
}
</script>
<style lang="less" scoped>
.title {
position: relative;
width: 50%;
height: 60px;
font-size: 15px;
color: white;
display: flex;
align-items: center;
}
.infoDiv {
position: relative;
width: 90%;
height: 480px;
.infotitle {
font-size: 15px;
color: #ffffff;
display: flex;
align-items: center;
height: 40px;
margin-left: 10px;
}
.infovalue {
font-size: 15px;
color: #ffffff;
display: flex;
align-items: center;
height: 40px;
max-width: 250px;
flex-wrap: wrap;
}
.infovalue_name {
font-size: 15px;
color: #ffffff;
display: flex;
align-items: center;
height: 40px;
max-width: 250px;
}
.infovalue_graffitiNum {
font-size: 15px;
color: #ffffff;
display: flex;
align-items: center;
height: auto;
min-height: 40px;
max-width: 250px;
flex-wrap: wrap;
}
.infobutton {
font-size: 10px;
color: #ffffff;
display: flex;
align-items: center;
justify-content: right;
height: 40px;
}
}
.map {
width: 100%;
height: 240px;
margin-left: 5px;
border-radius: 5px;
}
.graffitiNum {
display: flex;
align-items: center;
justify-content: space-between;
color: #ffffff;
width: 60%;
background: #3c3c3c;
height: 30px;
border-radius: 5px;
padding-left: 10px;
padding-right: 10px;
}
.graffitiNum2 {
display: flex;
align-items: center;
justify-content: space-between;
color: #ffffff;
width: 95%;
background: #1c1c1c;
height: 40px;
padding-left: 10px;
padding-right: 10px;
}
</style>