载体运动轨迹

This commit is contained in:
wangxk 2025-03-19 09:17:05 +08:00
parent 19c56700d0
commit 2839cfed41
18 changed files with 198256 additions and 79 deletions

1
web/public/heibei.json Normal file

File diff suppressed because one or more lines are too long

45333
web/public/newJson.json Normal file

File diff suppressed because it is too large Load Diff

76060
web/public/word.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@ export function deleteTsNodesById(params:any) {
params:params,
});
}
//分页查询验数据管理文档内容
//分页查询验数据管理文档内容
export function tsFilesPage(params:any) {
return request({
url: '/experimentalData/ts-files/page',
@ -135,7 +135,7 @@ export function list(params:any){
params:params
})
}
//查询验数据管理文件夹
//查询验数据管理文件夹
export function listTsFiles(params:any){
return request ({
url:'/experimentalData/ts-files/listTsFiles',
@ -159,3 +159,11 @@ export function copyFileFolder(params:any){
data:params
})
}
//定义频率
export function startSimpleNavi(params:any){
return request ({
url:'/experimentalData/ts-files/startSimpleNavi',
method:'post',
params:params
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,98 @@
<template>
<div ref="chartContainer" class="chart-container"></div>
</template>
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue';
import * as d3 from 'd3';
const props = defineProps<{
chartData: Array<{ x: number; y: number }>;
}>();
const chartContainer = ref<HTMLElement | null>(null);
let svg: d3.Selection<SVGSVGElement, unknown, null, undefined>;
let xScale: d3.ScaleLinear<number, number>;
let yScale: d3.ScaleLinear<number, number>;
let line: d3.Line<{ x: number; y: number }>;
const initChart = () => {
if (!chartContainer.value) return;
//
d3.select(chartContainer.value).select("svg").remove();
// SVG
svg = d3.select(chartContainer.value)
.append('svg')
.attr('width', '100%')
.attr('height', '100%');
//
xScale = d3.scaleLinear()
.range([50, 750]);
yScale = d3.scaleLinear()
.range([400, 50]);
// 线
line = d3.line<{ x: number; y: number }>()
.x(d => xScale(d.x))
.y(d => yScale(d.y));
//
svg.append('g')
.attr('class', 'x-axis')
.attr('transform', 'translate(0, 400)');
svg.append('g')
.attr('class', 'y-axis')
.attr('transform', 'translate(50, 0)');
//
svg.append('path')
.attr('class', 'line')
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 2);
//
updateChart();
};
const updateChart = () => {
//
xScale.domain(d3.extent(props.chartData, d => d.x) as [number, number]);
yScale.domain([0, d3.max(props.chartData, d => d.y)!]);
// 线
svg.select('.line')
.datum(props.chartData)
.transition()
.duration(500)
.attr('d', line);
//
svg.select('.x-axis')
.transition()
.duration(500)
.call(d3.axisBottom(xScale));
svg.select('.y-axis')
.transition()
.duration(500)
.call(d3.axisLeft(yScale));
};
onMounted(initChart);
watch(() => props.chartData, updateChart, { deep: true });
</script>
<style scoped>
.chart-container {
width: 800px;
height: 600px;
border: 1px solid #eee;
margin: 20px;
}
</style>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,140 @@
<template>
<div ref="mapContainer" class="map-container"></div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue'
import * as d3 from 'd3'
import chinaData from './newJson.json'
const props = defineProps({
coordinates: {
type: Array,
default: () => [
[116.405285, 39.904989], //
[121.472644, 31.231706] //
]
}
})
const mapContainer = ref(null)
let svg, mapGroup, markersGroup, zoom
const initMap = () => {
const width = 1000
const height = 800
const projection = d3.geoMercator()
.center([104, 37])
.scale(600)
.translate([width / 2, height / 2])
const path = d3.geoPath().projection(projection)
if (svg) svg.selectAll("*").remove()
svg = d3.select(mapContainer.value)
.append('svg')
.attr('width', width)
.attr('height', height)
//
const mainGroup = svg.append('g')
mapGroup = mainGroup.append('g')
markersGroup = mainGroup.append('g') //
mapGroup.append('g')
.selectAll('path')
.data(chinaData.features)
.enter()
.append('path')
.attr('d', path)
.attr('fill', '#e7e7e7')
.attr('stroke', '#fff')
zoom = d3.zoom()
.scaleExtent([0.2, 8])
.on('zoom', (event) => {
mainGroup.attr('transform', event.transform)
})
svg.call(zoom)
}
const updateRoute = () => {
const projection = d3.geoMercator()
.center([104, 37])
.scale(600)
.translate([1000 / 2, 800 / 2])
mapGroup.selectAll('.route-path').remove()
markersGroup.selectAll('*').remove()
const routeData = {
type: "LineString",
coordinates: props.coordinates
}
mapGroup.append('path')
.datum(routeData)
.attr('class', 'route-path')
.attr('d', d3.geoPath().projection(projection))
.attr('fill', 'none')
.attr('stroke', '#f00')
.attr('stroke-width', 2)
.attr('stroke-dasharray', function() {
return this.getTotalLength()
})
.attr('stroke-dashoffset', function() {
return this.getTotalLength()
})
.transition()
.duration(2000)
.attr('stroke-dashoffset', 0)
//
props.coordinates.forEach((coord, i) => {
if (!Array.isArray(coord) || coord.length !== 2) return
const lon = Number(coord[0])
const lat = Number(coord[1])
if (isNaN(lon) || isNaN(lat)) return
const [x, y] = projection([lon, lat])
//
const currentTransform = d3.zoomTransform(svg.node())
const baseRadius = 8
markersGroup.append('circle')
.attr('cx', x)
.attr('cy', y)
.attr('r', baseRadius / currentTransform.k) //
.attr('fill', '#ff4757')
.attr('stroke', 'white')
.attr('stroke-width', 2 / currentTransform.k) //
})
}
onMounted(() => {
if(props.coordinates){
initMap()
updateRoute()
}
})
watch(() => props.coordinates, () => {
updateRoute()
}, { deep: true })
</script>
<style>
/* 保持原有样式不变 */
.map-container {
background-color: #f0f8ff;
margin: 20px;
overflow: hidden;
touch-action: none;
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,16 @@ import ZUpload from '@/components/file/ZUpload.vue'
import useFileUpload from "@/components/file/file/useFileUpload";
import useHeaderStorageList from "@/components/header/useHeaderStorageList";
import useFileData from "@/components/file/file/useFileData";
//
import PDFImg from '@/assets/fileimg/PDF.png'
import WordImg from '@/assets/fileimg/word.png'
import ExcelImg from '@/assets/fileimg/excel.png'
import PPTImg from '@/assets/fileimg/ppt.png'
import ZipImg from '@/assets/fileimg/zip.png'
import Mp3Img from '@/assets/fileimg/mp3.png'
import Mp4Img from '@/assets/fileimg/mp4.png'
import ImageImg from '@/assets/fileimg/img.png'
import TextImg from '@/assets/fileimg/text_line.png'
//
import Viewfile from '@/views/component/Viewfile.vue'
import useFilePreview from "@/components/file/file/useFilePreview";
@ -106,6 +115,12 @@ const projectForme: any = ref({
const moderules = ref({
nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" }],
});
const moderqqqules = ref({
fileName: [{ required: true, message: "请输入文件/文件夹名称", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
],
});
//
function addSubItem(row: any) {
frame.value = true
@ -566,7 +581,7 @@ const isViewfile = ref(false)
const fileType = ref('')
function openPreview(row: any) {
if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin' ) {
if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') {
title1.value = row.fileName
ViewfileUrl.value = row.url
isViewfile.value = true
@ -625,6 +640,39 @@ function getFileSuffix(name: any) {
}
return name.substring(lastIndex + 1).toLowerCase();
}
//
const FILE_ICONS = {
pdf: PDFImg,
doc: WordImg,
docx: WordImg,
xls: ExcelImg,
xlsx: ExcelImg,
ppt: PPTImg,
pptx: PPTImg,
zip: ZipImg,
rar: ZipImg,
mp3: Mp3Img,
mp4: Mp4Img,
avi: Mp4Img,
png: ImageImg,
jpg: ImageImg,
jpeg: ImageImg,
gif: ImageImg,
txt: TextImg
};
//
const fileIcon = (filename: string) => {
const ext = filename.split('.').pop()?.toLowerCase() || 'unknown';
return FILE_ICONS[ext as keyof typeof FILE_ICONS] || require('@/assets/fileimg/text_line.png');
};
//
const shouldPreview = (filename: string): boolean => {
//
const fileExtension = filename.split('.').pop()?.toLowerCase() || '';
// keyof
return Object.keys(FILE_ICONS).includes(fileExtension);
};
</script>
<template>
@ -696,22 +744,12 @@ function getFileSuffix(name: any) {
</el-table-column>
<el-table-column prop="keywords" label="关键字"></el-table-column>
<el-table-column prop="description" label="文件描述"></el-table-column>
<el-table-column prop="fileName" label="预览" width="60px" align="center">
<template #default="scope">
<div style="display: flex;align-items: center;justify-content: center;">
<img v-if="getFileExtension(scope.row.fileName) == 'pdf' || getFileExtension(scope.row.fileName) == 'PDF'"
@click="openPreview(scope.row)" src="@/assets/fileimg/PDF.png" alt="" style="cursor: pointer;">
<img v-else-if="getFileExtension(scope.row.fileName) == 'docx'"
@click="openPreview(scope.row)" src="@/assets/fileimg/word.png" alt="" style="cursor: pointer;">
<img v-else-if="getFileExtension(scope.row.fileName) == 'mp4'"
@click="openPreview(scope.row)" src="@/assets/fileimg/mp4.png" alt="" style="cursor: pointer;">
<img v-else-if="getFileExtension(scope.row.fileName) == 'zip'" src="@/assets/fileimg/zip.png" alt="" style="cursor: pointer;">
<img v-else-if="getFileExtension(scope.row.fileName) == 'mp3'"
@click="openPreview(scope.row)" src="@/assets/fileimg/mp3.png" alt="" style="cursor: pointer;">
<img v-else src="@/assets/fileimg/text_line.png" alt="" style="cursor: pointer;" @click="openPreview(scope.row)">
<el-table-column prop="fileName" label="预览" width="80" align="center">
<template #default="{ row }">
<div class="preview-icon">
<img :src="fileIcon(row.fileName)" alt="file icon" class="file-icon"
@click="shouldPreview(row.fileName) && openPreview(row)">
</div>
<!-- {{ getFileExtension(scope.row.fileName) }} -->
</template>
</el-table-column>
<el-table-column prop="uploader" width="80" label="上传人"></el-table-column>
@ -722,7 +760,7 @@ function getFileSuffix(name: any) {
style="display: flex;display: -webkit-flex;justify-content: space-between;-webkit-justify-content: space-between; ">
<img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" @click="editfile(scope.row,true)" title="修改"
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" @click="editfile(scope.row, true)" title="修改"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_sc.png" alt="" @click="delfile(scope.row)" title="删除"
style="cursor: pointer;">
@ -755,14 +793,14 @@ function getFileSuffix(name: any) {
<el-dialog title="上传文件" v-model="upfile" width="50%" :before-close="fileClose" top="30px" draggable
destroy-on-close>
<el-scrollbar :height="!fileObj.id ? '400px' : ''">
<el-form ref="ruleFormRef" style="max-width: 100%" :model="fileObj" :rules="moderules"
<el-form ref="ruleFormRef" style="max-width: 100%" :model="fileObj" :rules="moderqqqules"
label-width="auto" class="demo-ruleForm" status-icon>
<el-form-item v-if="!fileObj.id" label="文件:" prop="taskCode">
<!-- <el-button @click="openUploadDialog" type="primary">上传文件</el-button>
<el-button @click="openUploadFolderDialog" type="primary">上传文件夹</el-button> -->
<ZUpload />
</el-form-item>
<el-form-item v-else label="文件名称:">
<el-form-item v-else prop="fileName" label="文件名称:">
<el-input v-model="fileObj.fileName" />
</el-form-item>
<el-form-item v-if="judge" label="关键字:" prop="taskName">
@ -902,7 +940,7 @@ function getFileSuffix(name: any) {
align-items: center;
justify-content: space-between;
font-size: 14px;
padding:8px;
padding: 8px;
.img_tree {
display: flex;
@ -946,4 +984,20 @@ function getFileSuffix(name: any) {
padding: 0px !important;
}
}
.preview-icon {
display: flex;
align-items: center;
justify-content: center;
}
.file-icon {
cursor: pointer;
width: 20px;
height: 20px;
transition: opacity 0.2s;
}
.file-icon:hover {
opacity: 0.8;
}
</style>

View File

@ -9,6 +9,7 @@ import { onMounted, ref } from "vue";
import { ElMessage, ElMessageBox } from 'element-plus'
import Page from '@/components/Pagination/page.vue'
import { projectPage, addSdproject, updateSdproject, deleteSdprojectById, deleteSdprojectByIds } from "@/api/project";
import { getDict } from '@/api/dict'
//
const tableData: any = ref([{}, {}]);
//
@ -33,6 +34,13 @@ function getdata() {
total.value = res.data.total
})
}
//
const dictType = ref([])
function getDictOne() {
getDict({ dictcode: 'zxxmlx' }).then((res: any) => {
dictType.value = res.data
})
}
//
const title = ref("")
//
@ -104,7 +112,7 @@ function delprojectArr() {
)
.then(() => {
deleteSdprojectByIds({ ids: ids.join(',') }).then((res: any) => {
if(res.code == 0){
if (res.code == 0) {
ElMessage({
type: 'success',
message: '删除成功',
@ -164,8 +172,18 @@ const moderules = ref({
});
onMounted(() => {
getdata()
getDictOne()
});
//
function typeName(arr:any,itemCode:any){
let nameone:any
arr.forEach((item:any) => {
if(item.itemcode==itemCode){
nameone = item.dictname
}
});
return nameone
}
</script>
@ -176,8 +194,11 @@ onMounted(() => {
<div class="sou_title_left">
<el-input style="margin-right: 10px ;" v-model="queryParams.projectCode" clearable
@change="getdata()" placeholder="项目编号"></el-input>
<el-input style="margin-right: 10px ;" v-model="queryParams.projectType" clearable
@change="getdata()" placeholder="项目类型"></el-input>
<el-select v-model="queryParams.projectType" placeholder="项目类型" style="margin-right: 10px ;" clearable @change="getdata()" >
<el-option v-for="item in dictType" :key="item.itemcode" :label="item.dictname" :value="item.itemcode" />
</el-select>
<!-- <el-input style="margin-right: 10px ;" v-model="queryParams.projectType" clearable
@change="getdata()" placeholder="项目类型"></el-input> -->
<el-input style="margin-right: 10px ;" v-model="queryParams.projectName" clearable
@change="getdata()" placeholder="项目名称"></el-input>
<el-button type="primary" @click="getdata()">搜索</el-button>
@ -195,7 +216,11 @@ onMounted(() => {
<!-- <el-table-column type="index" label="序号" width="70" align="center"></el-table-column> -->
<el-table-column prop="projectCode" label="项目编号" width="90" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" width="200"></el-table-column>
<el-table-column prop="projectType" label="项目类型" width="200"></el-table-column>
<el-table-column prop="projectType" label="项目类型" width="200">
<template #default="scope">
<span>{{ typeName(dictType,scope.row.projectType) }}</span>
</template>
</el-table-column>
<el-table-column prop="description" label="项目描述"></el-table-column>
<el-table-column prop="projectProps" label="项目信息"></el-table-column>
<el-table-column prop="projectTime" label="项目启动时间" width="165" align="center"></el-table-column>
@ -223,7 +248,10 @@ onMounted(() => {
<el-input v-model="projectForme.projectCode" />
</el-form-item>
<el-form-item label=" 项目类型" prop="projectType">
<el-input v-model="projectForme.projectType" />
<el-select v-model="projectForme.projectType" clearable placeholder=" " style="margin-right: 10px ;" @change="getdata()" >
<el-option v-for="item in dictType" :key="item.itemcode" :label="item.dictname" :value="item.itemcode" />
</el-select>
<!-- <el-input v-model="projectForme.projectType" /> -->
</el-form-item>
<el-form-item label=" 项目名称" prop="projectName">
<el-input v-model="projectForme.projectName" />

View File

@ -1,6 +1,6 @@
<script lang="ts">
export default {
name: "datamanagement",//
name: "datamanagement",//
};
</script>
@ -8,15 +8,29 @@ export default {
import { ref, onMounted, nextTick, defineAsyncComponent } from "vue";
import { Search } from '@element-plus/icons-vue'
import { useAppStore } from '@/store/modules/app';
import { useUserStore } from '@/store/modules/user';
import { ElMessageBox, ElMessage, ElMain } from "element-plus";
import Page from '@/components/Pagination/page.vue';
import AudioPlayer from '@/components/file/preview/AudioPlayer.vue';
import { batchDeleteReq } from "@/api/file-operator";
import { tstaskList, getTsNodesTree, addTsNodes, updateTsNodes, deleteTsNodesById, tsFilesPage, addTsFiles, updateTsFiles, deleteTsFilesById, listTsFiles, deleteTsFilesByIds, compress, Decompression, compare, downloadToLocal, uploadToBackup, addTsFile, list, moveFileFolder, copyFileFolder } from "@/api/datamanagement";
import { tstaskList, getTsNodesTree, addTsNodes, updateTsNodes, deleteTsNodesById, tsFilesPage, addTsFiles, updateTsFiles, deleteTsFilesById, listTsFiles, deleteTsFilesByIds, compress, Decompression, compare, downloadToLocal, uploadToBackup, addTsFile, list, moveFileFolder, copyFileFolder, startSimpleNavi } from "@/api/datamanagement";
import ZUpload from '@/components/file/ZUpload.vue'
import useFileUpload from "@/components/file/file/useFileUpload";
import useHeaderStorageList from "@/components/header/useHeaderStorageList";
import useFileData from "@/components/file/file/useFileData";
//
import MapChart from '@/components/trajectory/index.vue';
import Echart from '@/components/trajectory/echarts.vue';
//
import PDFImg from '@/assets/fileimg/PDF.png'
import WordImg from '@/assets/fileimg/word.png'
import ExcelImg from '@/assets/fileimg/excel.png'
import PPTImg from '@/assets/fileimg/ppt.png'
import ZipImg from '@/assets/fileimg/zip.png'
import Mp3Img from '@/assets/fileimg/mp3.png'
import Mp4Img from '@/assets/fileimg/mp4.png'
import ImageImg from '@/assets/fileimg/img.png'
import TextImg from '@/assets/fileimg/text_line.png'
//
import Viewfile from '@/views/component/Viewfile.vue'
@ -30,6 +44,7 @@ const { dialogVideoVisible, dialogTextVisible, dialogPdfVisible, dialogOfficeVis
const { clearALlFinishedUploadFile } = useFileUpload();
const { currentStorageKey } = useHeaderStorageList();
const { openRow } = useFileData();
const userStore = useUserStore();
onMounted(() => {
getProject()
});
@ -107,7 +122,9 @@ const projectForme: any = ref({
})
//
const moderules = ref({
nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" }],
nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
],
});
//
function addSubItem(row: any) {
@ -379,7 +396,7 @@ function delfile(row: any) {
}
)
.then(() => {
deleteTsFilesById({ id: row.id,type:'local' }).then((res: any) => {
deleteTsFilesById({ id: row.id, type: 'local' }).then((res: any) => {
if (res.code == 0) {
getdata()
ElMessage({
@ -414,7 +431,7 @@ function delprojectArr() {
}
)
.then(() => {
deleteTsFilesByIds({ ids: ids.join(','),type:'local' }).then((res: any) => {
deleteTsFilesByIds({ ids: ids.join(','), type: 'local' }).then((res: any) => {
if (res.code == 0) {
ElMessage({
type: 'success',
@ -973,7 +990,9 @@ const renameobj = ref({
fileName: ''
})
const renameRules = ref({
fileName: [{ required: true, message: "请输入文件名称", trigger: "blur" }],
fileName: [{ required: true, message: "请输入文件名称", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
],
});
const rowarr: any = ref()
function renames(row: any) {
@ -1047,7 +1066,9 @@ const creatform = ref({
workPath: ''
})
const creatrules = ref({
fileName: [{ required: true, message: "请输入文件/文件夹名称", trigger: "blur" }],
fileName: [{ required: true, message: "请输入文件/文件夹名称", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
],
});
function creatFile() {
creat.value = true
@ -1099,9 +1120,16 @@ const visible = ref(false)
const ziprules = ref({
ids: [{ required: true, message: "请选择文件", trigger: "blur" }],
compressedFormat: [{ required: true, message: "请选择压缩格式", trigger: "blur" }],
compressedName: [{ required: true, message: "请输入压缩文件名", trigger: "blur" }],
compressedName: [{ required: true, message: "请输入压缩文件名", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
],
compressedPath: [{ required: true, message: "请输入压缩文件路径", trigger: "blur" }],
})
const modelarules = ref({
fileName: [{ required: true, message: "请输入文件/文件夹名称", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
]
})
const ziptypearr = ref([])
const zipObj: any = ref({
ids: '',
@ -1160,7 +1188,7 @@ async function submitzip(formEl: any) {
})
} else {
// loading.value = true
Decompression({ id: jiezip.value.id, parentId: zipParentid.value, decompressionPath: jieFilearr.value.workPath?jieFilearr.value.workPath : filetsobj.value.path }).then((res: any) => {
Decompression({ id: jiezip.value.id, parentId: zipParentid.value, decompressionPath: jieFilearr.value.workPath ? jieFilearr.value.workPath : filetsobj.value.path }).then((res: any) => {
if (res.code == 0) {
ElMessage.success('解压成功')
// // gettreedata()
@ -1183,7 +1211,7 @@ function zipClose() {
}
//
const listFilesarr = ref([])
const filetsobj:any = ref({
const filetsobj: any = ref({
id: '',
path: '',
})
@ -1298,7 +1326,7 @@ function convertArrayToPath1(segments: string[]): string {
//
return '/' + segments.map((item:any) => item.fileName).join('/') + '/'
return '/' + segments.map((item: any) => item.fileName).join('/') + '/'
}
function removeSuffix(filename: any) {
// 使
@ -1315,6 +1343,137 @@ function removeSuffix(filename: any) {
//
return filename;
}
//
const FILE_ICONS = {
pdf: PDFImg,
doc: WordImg,
docx: WordImg,
xls: ExcelImg,
xlsx: ExcelImg,
ppt: PPTImg,
pptx: PPTImg,
zip: ZipImg,
rar: ZipImg,
gz: ZipImg,
bz2: ZipImg,
tar: ZipImg,
// tar.gz: ZipImg,
xz: ZipImg,
mp3: Mp3Img,
mp4: Mp4Img,
avi: Mp4Img,
png: ImageImg,
jpg: ImageImg,
jpeg: ImageImg,
gif: ImageImg,
txt: TextImg
};
//
const fileIcon = (row: any) => {
const ext = row.fileName.split('.').pop()?.toLowerCase() || 'unknown';
return FILE_ICONS[ext as keyof typeof FILE_ICONS] || (row.type == 'ZIP' ? ZipImg : TextImg);
};
//
const shouldPreview = (rwo: any): boolean => {
//
const fileExtension = rwo.fileName.split('.').pop()?.toLowerCase() || '';
// keyof
return Object.keys(FILE_ICONS).includes(fileExtension);
};
const mapTrajectory = ref(false)
const fredid = ref('')
function openMap(row: any) {
fredid.value = row.id
getSSELink()
// setInterval(() => {
// lineData.value = lineData.value.map(d => ({
// x: d.x,
// y: Math.random() * 10
// }));
// }, 2000);
mapTrajectory.value = true
}
function mapClose() {
mapTrajectory.value = false
eventSource.value?.close()
}
// 1s/10s/30s/1m/2m/5m
const options = ref([
{
name: '1秒'
, id: 1
},
{
name: '10秒'
, id: 10
},
{
name: '30秒'
, id: 30
},
{
name: '1分钟'
, id: 60
},
{
name: '2分钟'
, id: 120
},
{
name: '5分钟'
, id: 300
},
])
const maptime: any = ref(300)
//
function frequency(row: any) {
startSimpleNavi({ samTimes: maptime.value, id: fredid.value, token: userStore.Token }).then((res: any) => {
if (res.code == '0' && row) {
ElMessage.success("切换成功")
}
})
}
//sse
const eventSource = ref(null)
const dynamicCoordinates = ref([])
function getSSELink() {
if (eventSource.value) {
eventSource.value?.close()
}
eventSource.value = new EventSource(userStore.webApiBaseUrl + '/sse/connect/' + userStore.Token)
eventSource.value.addEventListener('open', () => {
frequency(false)
console.log('链接成功')
});
//
eventSource.value.addEventListener('message', (e: MessageEvent) => {
try {
const data = JSON.parse(e.data)
console.log('SSE消息:', data)
if(data){
data.forEach((item: any) => {
dynamicCoordinates.value.push([item.lon, item.lat])
lineData.value.push({x:item.UtcTime,y:item.alt})
})
}
} catch (err) {
console.error('消息解析失败:', err)
}
})
//
eventSource.value.onerror = (err: any) => {
console.error('SSE Error:', err)
setTimeout(getSSELink, 5000)
}
}
//
const lineData:any = ref([])
const tabbas = ref('1')
</script>
<template>
@ -1394,7 +1553,7 @@ function removeSuffix(filename: any) {
style="width: 100%; height: calc(66vh);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<!-- <el-table-column type="index" label="序号" width="70" align="center"></el-table-column> -->
<el-table-column prop="fileName" label="文件名称">
<el-table-column prop="fileName" label="文件名称" width="200">
<template #default="scope">
<div class="tableweight" v-if="scope.row.isFile == 'FOLDER'">{{ scope.row.fileName }} </div>
<div v-else-if="scope.row.isFile == 'FILE'">{{ scope.row.fileName }} </div>
@ -1403,32 +1562,26 @@ function removeSuffix(filename: any) {
<el-table-column prop="keywords" label="关键字"></el-table-column>
<el-table-column prop="workPath" label="路径"></el-table-column>
<el-table-column prop="fileName" label="预览" width="60px" align="center">
<template #default="scope">
<div style="display: flex;align-items: center;justify-content: center;">
<img v-if="getFileExtension(scope.row.fileName) == 'pdf' || getFileExtension(scope.row.fileName) == 'PDF'"
@click="openPreview(scope.row)" src="@/assets/fileimg/PDF.png" alt="" style="cursor: pointer;">
<img v-else-if="getFileExtension(scope.row.fileName) == 'mp4'"
@click="openPreview(scope.row)" src="@/assets/fileimg/mp4.png" alt="" style="cursor: pointer;">
<img v-else-if="scope.row.isFile == 'FOLDER'" src="@/assets/fileimg/wenjianjia.png" alt="" @click="openNode(scope.row)"
style="cursor: pointer;">
<img v-else-if="scope.row.type == 'ZIP'"
@click="openPreview(scope.row)" src="@/assets/fileimg/zip.png" alt="" style="cursor: pointer;">
<img v-else-if="getFileExtension(scope.row.fileName) == 'mp3'"
@click="openPreview(scope.row)" src="@/assets/fileimg/mp3.png" alt="" style="cursor: pointer;">
<img v-else src="@/assets/fileimg/text_line.png" alt="" style="cursor: pointer;" @click="openPreview(scope.row)">
<template #default="{ row }">
<div class="preview-icon">
<img v-if="row.isFile == 'FOLDER'" src="@/assets/fileimg/wenjianjia.png" alt=""
@click="openNode(row)" style="cursor: pointer;">
<img v-else :src="fileIcon(row)" alt="file icon" class="file-icon"
@click="shouldPreview(row) && openPreview(row)">
</div>
<!-- {{ getFileExtension(scope.row.fileName) }} -->
</template>
</el-table-column>
<el-table-column prop="uploader" width="80" label="上传人"></el-table-column>
<el-table-column prop="updateTime" width="170" label="修改日期"></el-table-column>
<el-table-column fixed="right" label="操作" width="120" align="center">
<el-table-column label="操作" width="140" align="center">
<template #default="scope">
<span
style="display: flex;display: -webkit-flex;justify-content: space-between;-webkit-justify-content: space-between; ">
<img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)"
style="cursor: pointer;">
<img v-if="scope.row.fileName.includes('ins_img')" src="@/assets/MenuIcon/guiji.png" alt=""
@click="openMap(scope.row)" title="轨迹预览图" style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" @click="editfile(scope.row, true)"
title="修改" style="cursor: pointer;">
<img v-if="scope.row.type == 'ZIP'" src="@/assets/images/jieyasuo.png" alt=""
@ -1437,8 +1590,6 @@ function removeSuffix(filename: any) {
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_sc.png" alt="" @click="delfile(scope.row)" title="删除"
style="cursor: pointer;">
</span>
</template>
</el-table-column>
@ -1466,14 +1617,14 @@ function removeSuffix(filename: any) {
<el-dialog :title="title" v-model="upfile" width="50%" :before-close="fileClose" top="30px" draggable
destroy-on-close>
<el-scrollbar :height="!fileObj.id ? '400px' : ''">
<el-form ref="ruleFormRef" style="max-width: 100%" :model="fileObj" :rules="moderules"
<el-form ref="ruleFormRef" style="max-width: 100%" :model="fileObj" :rules="modelarules"
label-width="auto" class="demo-ruleForm" status-icon>
<el-form-item v-if="!fileObj.id" label="文件:" prop="taskCode">
<!-- <el-button @click="openUploadDialog" type="primary">上传文件</el-button>
<el-button @click="openUploadFolderDialog" type="primary">上传文件夹</el-button> -->
<ZUpload />
</el-form-item>
<el-form-item v-else label="文件名称:">
<el-form-item v-else prop="fileName" label="文件名称:">
<el-input v-model="fileObj.fileName" />
</el-form-item>
<el-form-item v-if="judge" label="关键字:" prop="taskName">
@ -1576,7 +1727,7 @@ function removeSuffix(filename: any) {
<template #prepend>
<el-popover :visible="visible" placement="right" :width="400" trigger="click">
<template #reference>
<el-icon style="cursor: pointer;" @click="visible = !visible,pathFile(-1)">
<el-icon style="cursor: pointer;" @click="visible = !visible, pathFile(-1)">
<Folder />
</el-icon>
</template>
@ -1694,6 +1845,30 @@ function removeSuffix(filename: any) {
</div>
</div>
</el-dialog>
<!-- 轨迹地图 -->
<el-dialog title="轨迹地图/图表" v-model="mapTrajectory" :before-close="mapClose" top="30px" draggable
destroy-on-close>
<div style="margin:0px 0px 15px 0px ;">
<span>设定采样频率</span>
<span>
<el-select v-model="maptime" placeholder=" " size="large" @change="frequency(true)"
style="width: 240px">
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</span>
</div>
<div class="mapbox">
<div @click="tabbas = '1'" :class="tabbas == '1' ? 'mapbox_border' : 'mapbox_border1'">载体运动轨迹</div>
<div @click="tabbas = '2'" :class="tabbas == '2' ? 'mapbox_border' : 'mapbox_border1'">高程变化动态图</div>
</div>
<div v-show="tabbas == '1'" style="width: 800px;height:600px;overflow: hidden;">
<MapChart :coordinates="dynamicCoordinates" />
</div>
<div v-show="tabbas == '2'" style="width: 800px;height:600px;overflow: hidden;">
<Echart :chart-data="lineData" />
</div>
</el-dialog>
<!-- 组件预览 -->
<!-- 视频播放器 -->
@ -1728,7 +1903,6 @@ function removeSuffix(filename: any) {
<AudioPlayer></AudioPlayer>
<Viewfile v-if="isViewfile" :showTime="true" :title="title1" :url="ViewfileUrl" :type="fileType"
@update="CloseView" />
<!-- <audio-player></audio-player> -->
</div>
</template>
@ -1941,4 +2115,44 @@ function removeSuffix(filename: any) {
color: #303133;
font-size: 16px;
}
.preview-icon {
display: flex;
align-items: center;
justify-content: center;
}
.file-icon {
cursor: pointer;
width: 20px;
height: 20px;
transition: opacity 0.2s;
}
.file-icon:hover {
opacity: 0.8;
}
.mapbox {
display: flex;
align-items: center;
.mapbox_border {
padding: 5px 10px;
font-size: 16px;
background-color: #409eff;
color: #fff;
border-radius: 5px;
cursor: pointer;
}
.mapbox_border1 {
padding: 5px 10px;
font-size: 16px;
// background-color: #409eff;
// color: #fff;
border-radius: 5px;
cursor: pointer;
}
}
</style>

View File

@ -1,6 +1,6 @@
<script lang="ts">
export default {
name: "datamanagement",//
name: "datamanagement",//
};
</script>

View File

@ -1,6 +1,6 @@
<script lang="ts">
export default {
name: "testtask",//
name: "testtask",//
};
</script>
@ -69,7 +69,7 @@ const frame = ref(false)
//
function addproject() {
frame.value = true
title.value = "新增验任务"
title.value = "新增验任务"
projectForme.value = {
taskName: "",//
taskDate: "",//