文件上传参数修改

This commit is contained in:
wangxk 2025-03-23 12:55:06 +08:00
parent 7741240bc6
commit 88e0ce82cd
7 changed files with 457 additions and 185 deletions

View File

@ -16,6 +16,15 @@
"@kangc/v-md-editor": "^2.3.15", "@kangc/v-md-editor": "^2.3.15",
"@soerenmartius/vue3-clipboard": "^0.1.2", "@soerenmartius/vue3-clipboard": "^0.1.2",
"@tinymce/tinymce-vue": "^5.1.1", "@tinymce/tinymce-vue": "^5.1.1",
"@tiptap/extension-blockquote": "^2.11.5",
"@tiptap/extension-code-block": "^2.11.5",
"@tiptap/extension-document": "^2.11.5",
"@tiptap/extension-paragraph": "^2.11.5",
"@tiptap/extension-strike": "^2.11.5",
"@tiptap/extension-text": "^2.11.5",
"@tiptap/extension-underline": "^2.11.5",
"@tiptap/starter-kit": "^2.11.5",
"@tiptap/vue-3": "^2.11.5",
"@types/js-cookie": "^3.0.2", "@types/js-cookie": "^3.0.2",
"@vueuse/core": "^9.1.1", "@vueuse/core": "^9.1.1",
"@vueuse/integrations": "^9.13.0", "@vueuse/integrations": "^9.13.0",
@ -23,7 +32,7 @@
"@wangeditor/editor-for-vue": "^5.1.10", "@wangeditor/editor-for-vue": "^5.1.10",
"aplayer": "^1.10.1", "aplayer": "^1.10.1",
"artplayer": "^4.6.1", "artplayer": "^4.6.1",
"axios": "^1.2.0", "axios": "^1.8.4",
"beautify-qrcode": "^1.0.3", "beautify-qrcode": "^1.0.3",
"better-scroll": "^2.4.2", "better-scroll": "^2.4.2",
"d3": "^7.9.0", "d3": "^7.9.0",
@ -61,6 +70,7 @@
"vue-i18n": "^9.1.9", "vue-i18n": "^9.1.9",
"vue-pdf-embed": "^1.1.4", "vue-pdf-embed": "^1.1.4",
"vue-router": "^4.1.6", "vue-router": "^4.1.6",
"vue-virtual-scroller": "^2.0.0-beta.1",
"vue3-print-nb": "^0.1.4", "vue3-print-nb": "^0.1.4",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"

View File

@ -16,10 +16,6 @@ let common = useCommon();
let route = useRoute(); let route = useRoute();
// import IconPrev from '~icons/custom/prev'; // import IconPrev from '~icons/custom/prev';
// import IconNext from '~icons/custom/next'; // import IconNext from '~icons/custom/next';
let currentVideo = ref(null); let currentVideo = ref(null);
const openTarget = (mode) => { const openTarget = (mode) => {

View File

@ -0,0 +1,147 @@
<!-- src/components/RichTextEditor.vue -->
<template>
<div class="editor-wrapper">
<!-- 工具栏 -->
<div v-if="editor" class="toolbar">
<button @click="editor.chain().focus().toggleBold().run()"
:class="{ 'is-active': editor.isActive('bold') }">
<strong>B</strong>
</button>
<button @click="editor.chain().focus().toggleItalic().run()"
:class="{ 'is-active': editor.isActive('italic') }">
<em>I</em>
</button>
<button @click="editor.chain().focus().toggleHeading({ level: 2 }).run()"
:class="{ 'is-active': editor.isActive('heading') }">
H2
</button>
</div>
<el-scrollbar height="600px">
<!-- 编辑器主体 -->
<editor-content :editor="editor" class="editor-content" />
</el-scrollbar>
<!-- 操作按钮 -->
<div class="actions">
<button @click="loadContent" class="btn-load">加载文件</button>
<button @click="saveContent" class="btn-save">保存文件</button>
</div>
<!-- 状态提示 -->
<div v-if="statusMessage" class="status">
{{ statusMessage }}
</div>
</div>
</template>
<script setup>
import { EditorContent, useEditor } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
import axios from 'axios'
import { ref } from 'vue'
const statusMessage = ref('')
//
const editor = useEditor({
content: '',
extensions: [
StarterKit.configure({
heading: {
levels: [2, 3],
},
}),
],
})
//
const loadContent = async () => {
try {
// const response = await axios.get('/api/files', {
// params: { filePath: 'demo.txt' }
// })
const data = "<p>124535</p><p>4554</p><p>4545ljgljk</p><p><strong>lk'k;'k;'l;k'</strong></p><h2><strong><em>;l'kl;'kl;'</em></strong></h2><h2><strong><em>;'kl;';kl'kl;'l;k'k;l'k';lk';';k'l;'k;'kl;</em></strong></h2>"
editor.value.commands.setContent(data)
// statusMessage.value = ''
// setTimeout(() => statusMessage.value = '', 2000)
} catch (error) {
statusMessage.value = `加载失败: ${error.response?.data || error.message}`
}
}
//
const saveContent = async () => {
try {
const content = editor.value.getHTML()
await axios.post('/api/files', {
filePath: 'demo.txt',
content: content
})
statusMessage.value = '保存成功'
setTimeout(() => statusMessage.value = '', 2000)
} catch (error) {
statusMessage.value = `保存失败: ${error.response?.data || error.message}`
}
}
</script>
<style scoped>
.editor-wrapper {
max-width: 100%;
margin: 20px auto;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
}
.toolbar {
margin-bottom: 10px;
padding: 8px;
background: #f5f5f5;
border-radius: 4px;
}
.toolbar button {
margin-right: 8px;
padding: 6px 12px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
background: white;
}
.toolbar button.is-active {
background: #007bff;
color: white;
border-color: #007bff;
}
.editor-content {
min-height: 600px;
padding: 15px;
border: 1px solid #eee;
border-radius: 4px;
}
.actions {
margin-top: 20px;
text-align: right;
}
.btn-save {
background: #28a745;
color: white;
}
.btn-load {
background: #17a2b8;
color: white;
}
.status {
margin-top: 10px;
color: #666;
font-size: 0.9em;
}
</style>

View File

@ -1,112 +1,139 @@
<template> <template>
<div ref="chartContainer" class="chart-container"></div> <div ref="chartContainer" class="chart-container"></div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, onMounted } from 'vue'; import { ref, watch, onMounted } from 'vue';
import * as d3 from 'd3'; import * as d3 from 'd3';
const props = defineProps<{ const props = defineProps<{
chartData: Array<{ x: number; y: number }>; chartData: Array<{ x: number; y: number }>;
}>(); }>();
const chartContainer = ref<HTMLElement | null>(null); const chartContainer = ref<HTMLElement | null>(null);
let svg: d3.Selection<SVGSVGElement, unknown, null, undefined>; let svg: d3.Selection<SVGSVGElement, unknown, null, undefined>;
let xScale: d3.ScaleLinear<number, number>; let xScale: d3.ScaleLinear<number, number>;
let yScale: d3.ScaleLinear<number, number>; let yScale: d3.ScaleLinear<number, number>;
let line: d3.Line<{ x: number; y: number }>; let line: d3.Line<{ x: number; y: number }>;
const initChart = () => { const initChart = () => {
if (!chartContainer.value) return; if (!chartContainer.value) return;
// //
d3.select(chartContainer.value).select("svg").remove(); d3.select(chartContainer.value).select("svg").remove();
// SVG // SVG
svg = d3.select(chartContainer.value) svg = d3.select(chartContainer.value)
.append('svg') .append('svg')
.attr('width', '100%') .attr('width', '100%')
.attr('height', '100%'); .attr('height', '100%');
// //
xScale = d3.scaleLinear() xScale = d3.scaleLinear()
.range([50, 750]); .range([50, 750]);
yScale = d3.scaleLinear() yScale = d3.scaleLinear()
.range([400, 50]); .range([400, 50]);
// 线 // 线
line = d3.line<{ x: number; y: number }>() line = d3.line<{ x: number; y: number }>()
.x(d => xScale(d.x)) .x(d => xScale(d.x))
.y(d => yScale(d.y)); .y(d => yScale(d.y));
// //
svg.append('g') svg.append('g')
.attr('class', 'x-axis') .attr('class', 'x-axis')
.attr('transform', 'translate(0, 400)'); .attr('transform', 'translate(0, 400)');
svg.append('g') svg.append('g')
.attr('class', 'y-axis') .attr('class', 'y-axis')
.attr('transform', 'translate(50, 0)'); .attr('transform', 'translate(50, 0)');
// //
svg.append('path') svg.append('path')
.attr('class', 'line') .attr('class', 'line')
.attr('fill', 'none') .attr('fill', 'none')
.attr('stroke', 'steelblue') .attr('stroke', 'steelblue')
.attr('stroke-width', 2); .attr('stroke-width', 2);
svg.append("text") svg.append("text")
.attr("class", "x-axis-label") // class .attr("class", "x-axis-label") // class
.attr("transform", "translate(400,440)") .attr("transform", "translate(400,440)")
.style("text-anchor", "middle") .style("text-anchor", "middle")
.text("时间 (s)"); .text("时间 (s)");
svg.append("text") svg.append("text")
.attr("class", "y-axis-label") .attr("class", "y-axis-label")
.attr("transform", "rotate(-90) translate(-220, 15)") // .attr("transform", "rotate(-90) translate(-220, 15)") //
.style("text-anchor", "middle") .style("text-anchor", "middle")
.text("高度 (m)"); .text("高度 (m)");
svg.call(d3.zoom()
// .scaleExtent([1, 8])
.on('zoom', (event) => {
xScale.eventTransform.rescaleX(xScale);
yScale.eventTransform.rescaleY(yScale);
updateChart(); updateChart();
}; }));
//
updateChart();
};
const updateChart = () => { const updateChart = () => {
// svg.attr('key', Date.now());
xScale.domain(d3.extent(props.chartData, d => d.x) as [number, number]); //
yScale.domain([0, d3.max(props.chartData, d => d.y)!]); svg.select('.x-axis').remove();
svg.select('.y-axis').remove();
// 线 //
svg.select('.line') const xAxis = svg.append('g')
.datum(props.chartData) .attr('class', 'x-axis')
.transition() .attr('transform', `translate(0, ${yScale.range()[0]})`);
.duration(500)
.attr('d', line);
// const yAxis = svg.append('g')
svg.select('.x-axis') .attr('class', 'y-axis')
.transition() .attr('transform', `translate(${xScale.range()[0]}, 0)`);
.duration(500) //
.call(d3.axisBottom(xScale)); const xDomain = props.chartData.length > 0 ?
d3.extent(props.chartData, d => d.x) : [0, 1];
xScale.domain(xDomain as [number, number]);
yScale.domain([0, d3.max(props.chartData, d => d.y)!]);
svg.select('.y-axis') // 线
.transition() svg.select('.line')
.duration(500) .datum(props.chartData)
.call(d3.axisLeft(yScale)); .transition()
}; .duration(500)
.attr('d', line);
onMounted(initChart); //
watch(() => props.chartData, updateChart, { deep: true }); svg.select('.x-axis')
</script> .transition()
.duration(500)
.call(d3.axisBottom(xScale));
<style scoped> svg.select('.y-axis')
.chart-container { .transition()
width: 800px; .duration(500)
height: 600px; .call(d3.axisLeft(yScale));
border: 1px solid #eee; };
margin: 20px;
padding: 10px; onMounted(initChart);
} watch(() => props.chartData, updateChart, { deep: true });
</script>
<style scoped>
.chart-container {
width: 800px;
height: 600px;
border: 1px solid #eee;
margin: 20px;
padding: 10px;
}
.x-axis text {
font-size: 10px;
transform: rotate(-45deg);
text-anchor: end;
}
.x-axis-label, .x-axis-label,
.y-axis-label { .y-axis-label {
@ -114,4 +141,4 @@
fill: #666; fill: #666;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
} }
</style> </style>

View File

@ -22,7 +22,7 @@
<!-- 预览文件的地方用于渲染 --> <!-- 预览文件的地方用于渲染 -->
<div ref="file" :class="{ 'fullscreen-doc': fullscreen }"></div> <div ref="file" :class="{ 'fullscreen-doc': fullscreen }"></div>
</div> </div>
<div v-if="props.type == 'xlsx' || props.type == 'xls' " v-loading="loading" element-loading-text="正在加载报告..." <div v-if="props.type == 'xlsx' || props.type == 'xls'" v-loading="loading" element-loading-text="正在加载报告..."
element-loading-background="rgba(122, 122, 122, 0.8)" class="docWrap"> element-loading-background="rgba(122, 122, 122, 0.8)" class="docWrap">
<div class="tab"> <div class="tab">
<el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable"> <el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable">
@ -35,13 +35,22 @@
</div> </div>
</div> </div>
<div v-if="props.type == 'pdf'"> <div v-if="props.type == 'pdf'">
<iframe :src="pdfurl" :class="{ 'fullscreen-iframe': fullscreen }" type="application/x-google-chrome-pdf" <iframe :src="pdfurl" :class="{ 'fullscreen-iframe': fullscreen }" type="application/x-google-chrome-pdf"
width="100%" :height="fullscreen ? 'calc(100vh - 55px)' : '800px'" /> width="100%" :height="fullscreen ? 'calc(100vh - 55px)' : '800px'" />
</div> </div>
<div v-if="props.type === 'bin'" v-loading="loading" class="hex-container" <div v-if="props.type === 'bin'" v-loading="loading" class="hex-container"
:class="{ 'fullscreen-bin': fullscreen }"> :class="{ 'fullscreen-bin': fullscreen }">
<pre>{{ hexContent }}</pre> <div class="scroller">
<el-scrollbar :height="fullscreen?'90vh':'54vh'">
<pre v-for="(item, index) in visibleChunks" :key="hexContent.currentChunk + '-' + index"
class="hex-content">{{ item.content }}</pre>
</el-scrollbar>
</div>
<div class="pagination-control">
<el-pagination layout="prev, pager, next" :current-page="hexContent.currentChunk + 1"
:page-size="hexContent.chunkSize" :total="hexContent.rawData.length" :pager-count="5"
@current-change="handlePageChange" />
</div>
</div> </div>
<div v-if="props.type === 'pptx'" v-loading="loading" class="ppt-container"> <div v-if="props.type === 'pptx'" v-loading="loading" class="ppt-container">
<div class="ppt-controls"> <div class="ppt-controls">
@ -58,11 +67,13 @@
</template> </template>
<script setup> <script setup>
import { ref, nextTick, onMounted, getCurrentInstance, reactive, toRefs } from 'vue' import { ref, nextTick, onMounted, getCurrentInstance, reactive, toRefs, onBeforeUnmount, computed } from 'vue'
import * as docx from 'docx-preview' import * as docx from 'docx-preview'
import * as XLSX from "xlsx"; import * as XLSX from "xlsx";
import PptxGenJS from 'pptxgenjs'; import PptxGenJS from 'pptxgenjs';
import axios from 'axios'; import axios from 'axios';
// import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const props = defineProps({ const props = defineProps({
showTime: { showTime: {
type: Boolean, type: Boolean,
@ -92,7 +103,12 @@ const dialogVisible = ref(props.showTime);
const emits = defineEmits(); const emits = defineEmits();
const emptyTips = ref('暂无内容'); const emptyTips = ref('暂无内容');
const fullscreen = ref(false); const fullscreen = ref(false);
const hexContent = ref(''); const hexContent = ref({
rawData: new Uint8Array(0), //
chunkSize: 1024,
totalChunks: 0,
currentChunk: 0
});
const data = reactive({ const data = reactive({
excel: { excel: {
// //
@ -112,30 +128,56 @@ const currentSlide = ref(0);
const totalSlides = ref(0); const totalSlides = ref(0);
const prevSlide = () => { const prevSlide = () => {
if (currentSlide.value > 0) { if (currentSlide.value > 0) {
currentSlide.value--; currentSlide.value--;
scrollToSlide(); scrollToSlide();
} }
}; };
const nextSlide = () => { const nextSlide = () => {
if (currentSlide.value < totalSlides.value - 1) { if (currentSlide.value < totalSlides.value - 1) {
currentSlide.value++; currentSlide.value++;
scrollToSlide(); scrollToSlide();
} }
}; };
const visibleChunks = computed(() => {
// debugger
if (!hexContent.value.rawData?.length) {
console.log('No raw data available');
return [];
}
const start = hexContent.value.currentChunk * hexContent.value.chunkSize;
const end = start + hexContent.value.chunkSize;
const chunkData = hexContent.value.rawData.subarray(start, end);
const content = arrayBufferToHex(chunkData);
return [{
index: hexContent.value.currentChunk,
content: content
}];
});
const handlePageChange = (currentPage) => {
hexContent.value.currentChunk = currentPage - 1;
hexContent.value = { ...hexContent.value }; //
};
const scrollToSlide = () => { const scrollToSlide = () => {
const slides = proxy.$refs.pptViewer.querySelectorAll('.slide-container'); const slides = proxy.$refs.pptViewer.querySelectorAll('.slide-container');
slides[currentSlide.value].scrollIntoView({ slides[currentSlide.value].scrollIntoView({
behavior: 'smooth', behavior: 'smooth',
block: 'center' block: 'center'
}); });
}; };
onMounted(() => { onMounted(() => {
init(props.type); init(props.type);
// if (buffer.length === 0) {
// hexContent.value.rawData = new Uint8Array(0);
// }
})
onBeforeUnmount(() => {
if (hexContent.value.rawData) {
hexContent.value.rawData = null; //
}
}) })
// init // init
function init(type) { function init(type) {
typeName.value = type; typeName.value = type;
@ -191,7 +233,7 @@ function init(type) {
loading.value = false; loading.value = false;
}); });
} else if (type == "xlsx"|| type == "xls") { } else if (type == "xlsx" || type == "xls") {
// // // //
loading.value = true; loading.value = true;
axios.request({ axios.request({
@ -245,6 +287,7 @@ function init(type) {
loading.value = false; loading.value = false;
}); });
} else if (type === "bin") { } else if (type === "bin") {
loading.value = true; loading.value = true;
axios.request({ axios.request({
method: "GET", method: "GET",
@ -253,15 +296,16 @@ function init(type) {
}).then((res) => { }).then((res) => {
if (res.data) { if (res.data) {
const buffer = new Uint8Array(res.data); const buffer = new Uint8Array(res.data);
hexContent.value = arrayBufferToHex(buffer); hexContent.value.rawData = new Uint8Array(buffer); //
hexContent.value.totalChunks = Math.ceil(buffer.length / 1024);
hexContent.value.currentChunk = 0;
loading.value = false; loading.value = false;
} }
}).catch(() => { }).catch(() => {
loading.value = false; loading.value = false;
//
}); });
} else if (type === "pptx") { } else if (type === "pptx") {
debugger // debugger
loading.value = true; loading.value = true;
axios.request({ axios.request({
method: "GET", method: "GET",
@ -322,12 +366,12 @@ function getSheetNameTable(sheetName) {
} }
// //
function arrayBufferToHex(buffer) { function arrayBufferToHex(buffer) {
// debugger
return Array.from(buffer) return Array.from(buffer)
.map(byte => byte.toString(16).padStart(2, '0')) .map(byte => byte.toString(16).padStart(2, '0'))
.join(' ') .join(' ')
.replace(/([\da-f]{2} ){16}/g, '$&\n'); // 16 .replace(/([\da-f]{2} ){16}/g, '$&\n'); // 16
} }
function handleClose() { function handleClose() {
emits('update', false) emits('update', false)
} }
@ -617,4 +661,35 @@ html body {
background: white; background: white;
overflow: auto; overflow: auto;
} }
.hex-container {
.scroller {
// height: calc(54vh);
border: 1px solid #ebeef5;
border-radius: 4px;
.hex-content {
// font-family: 'Fira Code', monospace;
font-size: 14px;
line-height: 1.5;
padding: 12px;
background-color: #fafafa;
counter-increment: line;
color: #333;
&::before {
content: counter(line, decimal-leading-zero) ": ";
color: #666;
margin-right: 1em;
}
}
}
.pagination-control {
margin-top: 12px;
padding: 8px;
background: #fff;
border-top: 1px solid #ebeef5;
}
}
</style> </style>

View File

@ -582,7 +582,6 @@ const title1 = ref('')
const isViewfile = ref(false) const isViewfile = ref(false)
const fileType = ref('') const fileType = ref('')
function openPreview(row: any) { function openPreview(row: any) {
if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'xlsx'|| getFileExtension(row.fileName) == 'xls' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') { if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'xlsx'|| getFileExtension(row.fileName) == 'xls' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') {
title1.value = row.fileName title1.value = row.fileName
ViewfileUrl.value = row.url ViewfileUrl.value = row.url
@ -667,14 +666,13 @@ const fileIcon = (row:any) => {
const ext = row.fileName.split('.').pop()?.toLowerCase() || 'unknown'; const ext = row.fileName.split('.').pop()?.toLowerCase() || 'unknown';
return FILE_ICONS[ext as keyof typeof FILE_ICONS] || (row.type == 'ZIP' ? ZipImg : TextImg); return FILE_ICONS[ext as keyof typeof FILE_ICONS] || (row.type == 'ZIP' ? ZipImg : TextImg);
}; };
// // //
const shouldPreview = (filename: string): boolean => { // const shouldPreview = (filename: string): boolean => {
// // //
const fileExtension = filename.split('.').pop()?.toLowerCase() || ''; // const fileExtension = filename.split('.').pop()?.toLowerCase() || '';
// // keyof
// keyof // return Object.keys(FILE_ICONS).includes(fileExtension);
return Object.keys(FILE_ICONS).includes(fileExtension); // };
};
</script> </script>
<template> <template>
@ -750,7 +748,7 @@ const shouldPreview = (filename: string): boolean => {
<template #default="{ row }"> <template #default="{ row }">
<div class="preview-icon"> <div class="preview-icon">
<img :src="fileIcon(row)" alt="file icon" class="file-icon" <img :src="fileIcon(row)" alt="file icon" class="file-icon"
@click="shouldPreview(row.fileName) && openPreview(row)"> @click=" openPreview(row)">
</div> </div>
</template> </template>
</el-table-column> </el-table-column>

View File

@ -5,7 +5,7 @@ export default {
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, nextTick, defineAsyncComponent,onUnmounted } from "vue"; import { ref, onMounted, nextTick, defineAsyncComponent, onUnmounted } from "vue";
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import { useAppStore } from '@/store/modules/app'; import { useAppStore } from '@/store/modules/app';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
@ -18,6 +18,8 @@ import ZUpload from '@/components/file/ZUpload.vue'
import useFileUpload from "@/components/file/file/useFileUpload"; import useFileUpload from "@/components/file/file/useFileUpload";
import useHeaderStorageList from "@/components/header/useHeaderStorageList"; import useHeaderStorageList from "@/components/header/useHeaderStorageList";
import useFileData from "@/components/file/file/useFileData"; import useFileData from "@/components/file/file/useFileData";
//text
import textEdit from '@/components/textEditing/index.vue'
// //
import MapChart from '@/components/trajectory/index.vue'; import MapChart from '@/components/trajectory/index.vue';
import Echart from '@/components/trajectory/echarts.vue'; import Echart from '@/components/trajectory/echarts.vue';
@ -48,8 +50,8 @@ const userStore = useUserStore();
onMounted(() => { onMounted(() => {
getProject() getProject()
}); });
onUnmounted(()=>{ onUnmounted(() => {
closeSSE() closeSSE()
}) })
// //
const vMove = { const vMove = {
@ -269,7 +271,7 @@ const fileObj: any = ref({
const upfile = ref(false) const upfile = ref(false)
function openFile() { function openFile() {
title.value = "上传文件" title.value = "上传文件"
localStorage.setItem('filepath', creatform.value.workPath ? creatform.value.workPath : '/'); localStorage.setItem('filepath', creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/');
localStorage.setItem('storageKey', JSON.stringify(['local'])); localStorage.setItem('storageKey', JSON.stringify(['local']));
upfile.value = true upfile.value = true
fileObj.value = { fileObj.value = {
@ -312,7 +314,7 @@ function delfileOne(row: any) {
{ {
name: row.name, name: row.name,
password: "", password: "",
path: creatform.value.workPath ? creatform.value.workPath : '/', path: creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/',
type: "FILE" type: "FILE"
} }
], ],
@ -330,6 +332,7 @@ function submitfile() {
// console.log( ) // console.log( )
if (fileObj.value.id) { if (fileObj.value.id) {
fileObj.value.workPath = '/' + pathid.value + fileObj.value.workPath
updateTsFiles(fileObj.value).then((res: any) => { updateTsFiles(fileObj.value).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
closeDialog() closeDialog()
@ -360,7 +363,7 @@ function submitfile() {
} }
fileObj.value.taskId = projectId.value fileObj.value.taskId = projectId.value
fileObj.value.nodeId = pathid.value fileObj.value.nodeId = pathid.value
fileObj.value.workPath = creatform.value.workPath ? creatform.value.workPath : '/' fileObj.value.workPath = creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/'
fileObj.value.fileName = fileName.join(',') fileObj.value.fileName = fileName.join(',')
fileObj.value.fileSize = fileSize.join(',') fileObj.value.fileSize = fileSize.join(',')
fileObj.value.parentId = creatform.value.parentId ? creatform.value.parentId : '00' fileObj.value.parentId = creatform.value.parentId ? creatform.value.parentId : '00'
@ -587,7 +590,9 @@ const title1 = ref('')
const isViewfile = ref(false) const isViewfile = ref(false)
const fileType = ref('') const fileType = ref('')
function openPreview(row: any) { function openPreview(row: any) {
// debugger?
if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'pptx' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') { if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'pptx' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') {
// debugger
title1.value = row.fileName title1.value = row.fileName
ViewfileUrl.value = row.url ViewfileUrl.value = row.url
isViewfile.value = true isViewfile.value = true
@ -648,7 +653,7 @@ function getFileSuffix(name: any) {
function openNode(row: any) { function openNode(row: any) {
loading.value = true loading.value = true
creatform.value.parentId = row.id creatform.value.parentId = row.id
creatform.value.workPath = row.workPath + row.fileName + '/' creatform.value.workPath = '/' + pathid.value + row.workPath + row.fileName + '/'
patharr.value.push({ fileName: row.fileName, id: row.id }) patharr.value.push({ fileName: row.fileName, id: row.id })
getdata() getdata()
} }
@ -767,7 +772,7 @@ function paste() {
rename: '', rename: '',
type: '', type: '',
} }
repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/'
repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00' repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00'
repeatObj.type = '0' repeatObj.type = '0'
@ -816,7 +821,7 @@ function paste() {
const arr2Ids = new Set(copytable.value.map(item => item.id)); const arr2Ids = new Set(copytable.value.map(item => item.id));
norepeat = copyarr.value.filter(item => !arr2Ids.has(item.id)); norepeat = copyarr.value.filter(item => !arr2Ids.has(item.id));
norepeat.forEach((items: any) => { norepeat.forEach((items: any) => {
repeatObj.oldpaths = items.workPath repeatObj.oldpaths = '/' + pathid.value + items.workPath
repeatObj.newFileName.push(items.fileName) repeatObj.newFileName.push(items.fileName)
}) })
repeatObj.newFileName = repeatObj.newFileName.join(',') repeatObj.newFileName = repeatObj.newFileName.join(',')
@ -880,10 +885,10 @@ function copycover(row: any) {
rename: '', rename: '',
type: '', type: '',
} }
repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/'
repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00' repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00'
repeatObj.type = '0' repeatObj.type = '0'
repeatObj.oldpaths = row.workPath repeatObj.oldpaths = '/' + pathid.value + row.workPath
repeatObj.newFileName.push(row.fileName) repeatObj.newFileName.push(row.fileName)
repeatObj.newFileName = repeatObj.newFileName.join(',') repeatObj.newFileName = repeatObj.newFileName.join(',')
if (copytype.value == "move") { if (copytype.value == "move") {
@ -955,11 +960,11 @@ function copysomefile() {
rename: '', rename: '',
type: '', type: '',
} }
repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/'
repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00' repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00'
repeatObj.type = '0' repeatObj.type = '0'
copyhandArr.value.forEach((items: any) => { copyhandArr.value.forEach((items: any) => {
repeatObj.oldpaths = items.workPath repeatObj.oldpaths = '/' + pathid.value + items.workPath
repeatObj.newFileName.push(items.fileName) repeatObj.newFileName.push(items.fileName)
}) })
repeatObj.newFileName = repeatObj.newFileName.join(',') repeatObj.newFileName = repeatObj.newFileName.join(',')
@ -1019,10 +1024,10 @@ async function submitrename(formEl: any) {
rename: '', rename: '',
type: '', type: '',
} }
repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' repeatObj.newPath = creatform.value.workPath ? creatform.value.workPath : '/' + pathid.value + '/'
repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00' repeatObj.parentId = creatform.value.parentId ? creatform.value.parentId : '00'
repeatObj.type = '1' repeatObj.type = '1'
repeatObj.oldpaths = rowarr.value.workPath repeatObj.oldpaths = '/' + pathid.value + rowarr.value.workPath
repeatObj.rename = (renameobj.value.fileName) repeatObj.rename = (renameobj.value.fileName)
repeatObj.newFileName.push(rowarr.value.fileName) repeatObj.newFileName.push(rowarr.value.fileName)
repeatObj.newFileName = repeatObj.newFileName.join(',') repeatObj.newFileName = repeatObj.newFileName.join(',')
@ -1095,7 +1100,7 @@ async function submitcreat(formEl: any) {
if (creatform.value.workPath) { if (creatform.value.workPath) {
creatObj.value.workPath = creatform.value.workPath creatObj.value.workPath = creatform.value.workPath
} else { } else {
creatObj.value.workPath = '/' creatObj.value.workPath = '/' + pathid.value + '/'
} }
addTsFile(creatObj.value).then((res: any) => { addTsFile(creatObj.value).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
@ -1113,7 +1118,7 @@ function pathclick(row: any, index: any) {
patharr.value.splice(index + 1) patharr.value.splice(index + 1)
creatform.value.parentId = row.id creatform.value.parentId = row.id
creatform.value.workPath = convertArrayToPath1(patharr.value) creatform.value.workPath = '/' + pathid.value + convertArrayToPath1(patharr.value)
getdata() getdata()
} }
// //
@ -1148,7 +1153,6 @@ function zipFile(row: any) {
title.value = '压缩' title.value = '压缩'
if (tableIdarr.value.length == 1) { if (tableIdarr.value.length == 1) {
zipObj.value.compressedName = removeSuffix(tableIdarr.value[0].fileName) zipObj.value.compressedName = removeSuffix(tableIdarr.value[0].fileName)
} else { } else {
zipObj.value.compressedName = generateRandomName() zipObj.value.compressedName = generateRandomName()
} }
@ -1180,6 +1184,8 @@ async function submitzip(formEl: any) {
// gettreedata() // gettreedata()
getdata() getdata()
zipfiles.value = false zipfiles.value = false
// debugger
zipObj.value.compressedPath= '/' + pathid.value +zipObj.value.compressedPath
compress(zipObj.value).then((res: any) => { compress(zipObj.value).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
zipfiles.value = false zipfiles.value = false
@ -1191,7 +1197,7 @@ async function submitzip(formEl: any) {
}) })
} else { } else {
// loading.value = true // 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 ? '/' + pathid.value + jieFilearr.value.workPath : '/' + pathid.value + filetsobj.value.path }).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
ElMessage.success('解压成功') ElMessage.success('解压成功')
// // gettreedata() // // gettreedata()
@ -1224,13 +1230,14 @@ const jiepatharr: any = ref([])
function gettsfiles() { function gettsfiles() {
filetsobj.value.nodeId = pathid.value filetsobj.value.nodeId = pathid.value
filetsobj.value.taskId = projectId.value filetsobj.value.taskId = projectId.value
// filetsobj.value.path ='/' + pathid.value + filetsobj.value.path
listTsFiles(filetsobj.value).then((res: any) => { listTsFiles(filetsobj.value).then((res: any) => {
listFilesarr.value = res.data listFilesarr.value = res.data
if (res.data[0]) { if (res.data[0]) {
jieFilearr.value = res.data[0] jieFilearr.value = res.data[0]
jiepatharr.value = convertPathToArray(jieFilearr.value.workPath) jiepatharr.value = convertPathToArray(jieFilearr.value.workPath)
creatform.value.parentId = res.data[0].parentId creatform.value.parentId = res.data[0].parentId
creatform.value.workPath = jieFilearr.value.workPath creatform.value.workPath = '/' + pathid.value + jieFilearr.value.workPath
} }
}) })
@ -1239,7 +1246,7 @@ function openfiles(row: any) {
filetsobj.value.path = row.workPath + row.fileName + '/' filetsobj.value.path = row.workPath + row.fileName + '/'
jieFilearr.value.workPath = filetsobj.value.path jieFilearr.value.workPath = filetsobj.value.path
jiepatharr.value = convertPathToArray(jieFilearr.value.workPath) jiepatharr.value = convertPathToArray(jieFilearr.value.workPath)
creatform.value.workPath = jieFilearr.value.workPath creatform.value.workPath = '/' + pathid.value + jieFilearr.value.workPath
zipParentid.value = row.id zipParentid.value = row.id
creatform.value.parentId = row.id creatform.value.parentId = row.id
filetsobj.value.id = '' filetsobj.value.id = ''
@ -1268,7 +1275,7 @@ function pathFile(index: any) {
gettsfiles() gettsfiles()
} }
function pathqveding() { function pathqveding() {
zipObj.value.compressedPath = jieFilearr.value.workPath zipObj.value.compressedPath = jieFilearr.value.workPath
creatform.value.parentId = '' creatform.value.parentId = ''
creatform.value.workPath = '' creatform.value.workPath = ''
visible.value = !visible.value visible.value = !visible.value
@ -1376,15 +1383,6 @@ const fileIcon = (row: any) => {
const ext = row.fileName.split('.').pop()?.toLowerCase() || 'unknown'; const ext = row.fileName.split('.').pop()?.toLowerCase() || 'unknown';
return FILE_ICONS[ext as keyof typeof FILE_ICONS] || (row.type == 'ZIP' ? ZipImg : TextImg); 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 mapTrajectory = ref(false)
const fredid = ref('') const fredid = ref('')
@ -1435,13 +1433,16 @@ const options = ref([
]) ])
const maptime: any = ref(1) const maptime: any = ref(1)
// //
const qvehuan = ref(false) const qvehuan: any = ref(false)
const qvehuan1: any = ref(false)
function frequency(row: any) { function frequency(row: any) {
startSimpleNavi({ samTimes: maptime.value, id: fredid.value, token: userStore.userId }).then((res: any) => { startSimpleNavi({ samTimes: maptime.value, id: fredid.value, token: userStore.userId }).then((res: any) => {
if (res.code == '0' && row) { if (res.code == '0' && row) {
ElMessage.success("切换成功") ElMessage.success("切换成功")
getSSELink() getSSELink()
qvehuan.value = true qvehuan.value = true
qvehuan1.value = true
lineData.value.length = 0
} }
}) })
} }
@ -1449,14 +1450,14 @@ function frequency(row: any) {
const eventSource = ref(null) const eventSource = ref(null)
let index = 0 let index = 0
const dynamicCoordinates = ref([]) const dynamicCoordinates = ref([])
function closeSSE(){ function closeSSE() {
dynamicCoordinates.value.length = 0 dynamicCoordinates.value.length = 0
// SSEclose :any // SSEclose :any
let SSEclose = new EventSource(userStore.webApiBaseUrl + '/sse/disconnect/' + userStore.userId) let SSEclose = new EventSource(userStore.webApiBaseUrl + '/sse/disconnect/' + userStore.userId)
eventSource.value?.close() eventSource.value?.close()
} }
function getSSELink() { function getSSELink() {
closeSSE() closeSSE()
eventSource.value = new EventSource(userStore.webApiBaseUrl + '/sse/connect/' + userStore.userId) eventSource.value = new EventSource(userStore.webApiBaseUrl + '/sse/connect/' + userStore.userId)
eventSource.value.addEventListener('open', () => { eventSource.value.addEventListener('open', () => {
frequency(false) frequency(false)
@ -1467,12 +1468,13 @@ function getSSELink() {
try { try {
const data = JSON.parse(e.data) const data = JSON.parse(e.data)
console.log('SSE消息:', data) console.log('SSE消息:', data)
if(data){ if (data) {
dynamicCoordinates.value.push([data.lon, data.lat]) dynamicCoordinates.value.push([data.lon, data.lat])
if(dynamicCoordinates.value.length>2){ if (dynamicCoordinates.value.length > 2) {
dynamicCoordinates.value.shift() dynamicCoordinates.value.shift()
} }
lineData.value.push({x:data.UtcTime,y:data.alt})
lineData.value.push({ x: data.UtcTime, y: data.alt })
} }
} catch (err) { } catch (err) {
console.error('消息解析失败:', err) console.error('消息解析失败:', err)
@ -1485,11 +1487,20 @@ function getSSELink() {
} }
} }
// //
const lineData:any = ref([]) const lineData: any = ref([])
const tabbas = ref('1') const tabbas = ref('1')
function handleCustomEvent(row:any){ function handleCustomEvent(row: any) {
qvehuan.value = row qvehuan.value = row
} }
//
const textedit = ref(false)
function testClick(row: any) {
textedit.value = true
title.value = '编辑 - ' + row.workPath + row.fileName
}
function textClose() {
textedit.value = false
}
</script> </script>
<template> <template>
@ -1583,7 +1594,7 @@ function handleCustomEvent(row:any){
<img v-if="row.isFile == 'FOLDER'" src="@/assets/fileimg/wenjianjia.png" alt="" <img v-if="row.isFile == 'FOLDER'" src="@/assets/fileimg/wenjianjia.png" alt=""
@click="openNode(row)" style="cursor: pointer;"> @click="openNode(row)" style="cursor: pointer;">
<img v-else :src="fileIcon(row)" alt="file icon" class="file-icon" <img v-else :src="fileIcon(row)" alt="file icon" class="file-icon"
@click="shouldPreview(row) && openPreview(row)"> @click=" openPreview(row)">
</div> </div>
</template> </template>
@ -1594,6 +1605,8 @@ function handleCustomEvent(row:any){
<template #default="scope"> <template #default="scope">
<span <span
style="display: flex;display: -webkit-flex;justify-content: space-between;-webkit-justify-content: space-between; "> style="display: flex;display: -webkit-flex;justify-content: space-between;-webkit-justify-content: space-between; ">
<img src="@/assets/project/chong.png" alt="" title="编辑文本" @click="testClick(scope.row)"
style="cursor: pointer;">
<img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)" <img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)"
style="cursor: pointer;"> style="cursor: pointer;">
<img v-if="scope.row.fileName.includes('ins_img')" src="@/assets/MenuIcon/guiji.png" alt="" <img v-if="scope.row.fileName.includes('ins_img')" src="@/assets/MenuIcon/guiji.png" alt=""
@ -1919,6 +1932,12 @@ function handleCustomEvent(row:any){
<AudioPlayer></AudioPlayer> <AudioPlayer></AudioPlayer>
<Viewfile v-if="isViewfile" :showTime="true" :title="title1" :url="ViewfileUrl" :type="fileType" <Viewfile v-if="isViewfile" :showTime="true" :title="title1" :url="ViewfileUrl" :type="fileType"
@update="CloseView" /> @update="CloseView" />
<el-dialog :title="title" v-model="textedit" :before-close="textClose" top="30px" draggable width="60%"
destroy-on-close>
<textEdit />
<!-- </el-scrollbar> -->
</el-dialog>
</div> </div>
</template> </template>