工程导入

This commit is contained in:
2025-10-20 17:00:58 +08:00
parent 2a7eda5ee3
commit a2f81dbe29
10 changed files with 822 additions and 179 deletions

View File

@ -10,18 +10,19 @@
</template>
<script setup lang="ts">
import {ref, onMounted} from "vue";
import {useRouter} from "vue-router";
import cabin from "./cabin.vue"
import element from "./element.vue"
//@ts-nocheck
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import cabin from './cabin.vue'
import element from './element.vue'
const router = useRouter()
const closeSituationEdit = () => {
router.back()
}
const createEarth = async () => {
window.earth_ts = await new YJ.YJEarth('earthContainer', {navigationHelpButton: false})
YJ.Global.CesiumContainer(earth_ts, {compass: false, legend: false});
window.earth_ts = await new YJ.YJEarth('earthContainer', { navigationHelpButton: false })
YJ.Global.CesiumContainer(earth_ts, { compass: false, legend: false })
setTimeout(() => {
new YJ.Tools(window.earth_ts).flyHome()
}, 1000)
@ -29,7 +30,7 @@ const createEarth = async () => {
onMounted(async () => {
let baseURL = localStorage.getItem('service')
// getAuthInfo()
await YJ.on({host: baseURL})
await YJ.on({ host: baseURL })
createEarth()
})
</script>

View File

@ -13,37 +13,35 @@
</div>-->
<div class="tabsBox">
<div class="tabs">
<div v-for="(item,index) in tabs" @click="handleTabClick(item,index)" :class="index==activIndex?'active':''">
<div
v-for="(item, index) in tabs"
@click="handleTabClick(item, index)"
:class="index == activIndex ? 'active' : ''"
>
{{ item.name }}
</div>
</div>
<div class="panel">
<div class="treeOrList">
<template v-if="dataType=='tree'">
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
/>
<template v-if="dataType == 'tree'">
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick" />
</template>
<template v-if="dataType=='list'">
<template v-if="dataType == 'list'">
<div v-for="item in lists">
{{ item.name }}
</div>
</template>
</div>
<div class="list" v-if="showList">
</div>
<div class="list" v-if="showList"></div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue";
import {Search} from '@element-plus/icons-vue'
//@ts-nocheck
import { ref } from 'vue'
import { Search } from '@element-plus/icons-vue'
interface Tree {
label: string
@ -52,21 +50,16 @@ interface Tree {
const activIndex = ref(0)
const tabs = [
{name: "人工模型", dataType: 'tree',},
{name: "军事标绘", dataType: 'tree',},
{ name: '人工模型', dataType: 'tree' },
{ name: '军事标绘', dataType: 'tree' },
{
name: "基础标绘", dataType: 'list', children:
[
{name: "点"},
{name: "线"},
{name: "面"},
{name: "圆"}
]
name: '基础标绘',
dataType: 'list',
children: [{ name: '点' }, { name: '线' }, { name: '面' }, { name: '圆' }]
},
{name: "特效", dataType: 'list', children: [{name: "火焰"}]},
{ name: '特效', dataType: 'list', children: [{ name: '火焰' }] }
]
const data: Tree[] = [
{
label: 'Level one 1',
@ -74,13 +67,12 @@ const data: Tree[] = [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
},
],
},
],
label: 'Level three 1-1-1'
}
]
}
]
},
{
label: 'Level one 2',
@ -89,19 +81,19 @@ const data: Tree[] = [
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
label: 'Level three 2-1-1'
}
]
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
label: 'Level three 2-2-1'
}
]
}
]
},
{
label: 'Level one 3',
@ -110,25 +102,25 @@ const data: Tree[] = [
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
label: 'Level three 3-1-1'
}
]
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
},
label: 'Level three 3-2-1'
}
]
}
]
}
]
const defaultProps = {
children: 'children',
label: 'label',
label: 'label'
}
const lists = ref([])
let input2 = ref('')
@ -149,8 +141,6 @@ const handleNodeClick = (data: Tree) => {
console.log(data)
showList.value = true
}
</script>
<style lang="scss" scoped>
@ -162,7 +152,9 @@ const handleNodeClick = (data: Tree) => {
top: 13.4259259259vh;
left: 1.5625vw;
border: 0.078125vw solid rgb(0, 255, 255);
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.5);
background:
linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
rgba(0, 0, 0, 0.5);
color: #fff;
padding: 0 5px;
//display: flex;
@ -219,19 +211,18 @@ const handleNodeClick = (data: Tree) => {
overflow-y: auto;
}
}
}
}
:deep(.el-input__wrapper), :deep(.el-input__inner ) {
:deep(.el-input__wrapper),
:deep(.el-input__inner) {
background: transparent;
--el-input-placeholder-color: #fff;
color: #fff;
//border: 1px solid #0ff;
}
:deep(.el-tree-node__content:hover ) {
:deep(.el-tree-node__content:hover) {
--el-tree-node-hover-bg-color: rgba(0, 255, 255, 0.38);
//--el-tree-node-hover-bg-color: linear-gradient(90deg, rgba(0, 255, 255, 0.5) 0%, rgba(0, 255, 255, 0) 100%) !important;
@ -244,8 +235,7 @@ const handleNodeClick = (data: Tree) => {
//--el-tree-expand-icon-color: #fff;
}
:deep(.el-tree-node.is-current ) {
:deep(.el-tree-node.is-current) {
& > .el-tree-node__content {
background: linear-gradient(90deg, rgba(0, 255, 255, 0.5) 0%, rgba(0, 255, 255, 0) 100%);
@ -255,7 +245,7 @@ const handleNodeClick = (data: Tree) => {
}
}
:deep(.el-text ) {
:deep(.el-text) {
--el-text-color: #fff !important;
}
</style>

View File

@ -16,27 +16,33 @@
</svg>
</div>
<div class="search">
<span>推演名称 <el-input
v-model="searchParams.name"
style="width: 240px"
placeholder="请输入推演名称"
clearable
<span
>推演名称
<el-input
v-model="searchParams.name"
style="width: 240px"
placeholder="请输入推演名称"
clearable
/></span>
<span>创建人 <el-input
v-model="searchParams.create_by"
style="width: 240px"
placeholder="请输入创建人姓名"
clearable
<span
>创建人
<el-input
v-model="searchParams.create_by"
style="width: 240px"
placeholder="请输入创建人姓名"
clearable
/></span>
<span>创建时间 <el-date-picker
v-model="searchParams.datetime"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY-MM-DD ddd"
time-format="A hh:mm:ss"
value-format="x"
<span
>创建时间
<el-date-picker
v-model="searchParams.datetime"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY-MM-DD ddd"
time-format="A hh:mm:ss"
value-format="x"
/></span>
<el-button @click="search">搜索</el-button>
<el-button @click="reset">重置</el-button>
@ -52,13 +58,15 @@
:default-sort="{ prop: 'date', order: 'descending' }"
style="width: 100%"
>
<el-table-column align="center" prop="name" label="推演名称"/>
<el-table-column align="center" prop="description" label="推演描述"/>
<el-table-column align="center" prop="create_by" label="创建人"/>
<el-table-column align="center" prop="date" label="创建日期" sortable/>
<el-table-column align="center" prop="name" label="推演名称" />
<el-table-column align="center" prop="description" label="推演描述" />
<el-table-column align="center" prop="create_by" label="创建人" />
<el-table-column align="center" prop="date" label="创建日期" sortable />
<el-table-column align="center" label="操作">
<template #default="scope">
<el-button text size="small" type="primary" :icon="Edit" @click="toTSEdit">编辑</el-button>
<el-button text size="small" type="primary" :icon="Edit" @click="toTSEdit"
>编辑</el-button
>
<el-button text size="small" type="primary" :icon="Delete">删除</el-button>
</template>
</el-table-column>
@ -90,18 +98,19 @@
</template>
<script setup lang="ts">
import {ref} from "vue";
import {useRouter} from "vue-router";
import {Delete, Edit, CirclePlus, Download, Upload} from '@element-plus/icons-vue'
import {TableV2SortOrder} from 'element-plus'
import type {SortBy} from 'element-plus'
//@ts-nocheck
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { Delete, Edit, CirclePlus, Download, Upload } from '@element-plus/icons-vue'
import { TableV2SortOrder } from 'element-plus'
import type { SortBy } from 'element-plus'
const {ipcRenderer} = require('electron')
const { ipcRenderer } = require('electron')
const router = useRouter()
let searchParams = ref({
name: "",
create_by: "",
datetime: "",
name: '',
create_by: '',
datetime: ''
})
let pageSize = ref(5)
@ -109,15 +118,15 @@ let pageNum = ref(1)
let total = ref(0)
const back = () => {
ipcRenderer.send('toggle-fullscreen', false)
router.push({path: '/home'})
router.push({ path: '/home' })
}
const handleSizeChange = (val) => {
pageSize = val
getList();
getList()
}
const handleCurrentChange = (val) => {
pageNum = val
getList();
getList()
}
const getList = () => {
console.log(pageSize, pageNum)
@ -126,37 +135,36 @@ const tableData: User[] = [
{
date: '2016-05-03',
name: '测试',
description: "这是一个方案描述",
create_by: "admin",
description: '这是一个方案描述',
create_by: 'admin'
},
{
date: '2016-05-02',
name: '协同方案',
description: "这是一个方案描述",
create_by: "admin",
description: '这是一个方案描述',
create_by: 'admin'
},
{
date: '2016-05-04',
name: '1990',
description: "这是一个方案描述",
create_by: "admin",
description: '这是一个方案描述',
create_by: 'admin'
},
{
date: '2016-05-01',
name: '2025',
description: "这是一个方案描述",
create_by: "admin",
},
description: '这是一个方案描述',
create_by: 'admin'
}
]
const search = () => {
console.log(searchParams)
}
const reset = () => {
searchParams.value = {name: "", create_by: "", datetime: ""}
searchParams.value = { name: '', create_by: '', datetime: '' }
}
const toTSEdit = () => {
router.push({path: '/tsEdit'})
router.push({ path: '/tsEdit' })
}
/*
const generateData = (
@ -203,10 +211,8 @@ const onSort = (sortBy: SortBy) => {
</script>
<style lang="scss" scoped>
.index {
background: url("../../assets/img/bkgif@3x.gif") no-repeat;
background: url('../../assets/img/bkgif@3x.gif') no-repeat;
background-size: 100% 100%;
width: 100vw;
height: 100vh !important;
@ -218,7 +224,7 @@ const onSort = (sortBy: SortBy) => {
font-size: 40px;
top: 19px;
line-height: 50px;
font-family: "alimamashuheiti";
font-family: 'alimamashuheiti';
z-index: 999;
position: absolute;
color: #fff;
@ -253,8 +259,11 @@ const onSort = (sortBy: SortBy) => {
height: 72vh;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.6);
border-image: linear-gradient(137.95deg, rgba(0, 255, 255, 1) 6.25%, rgba(0, 200, 255, 1) 100%) 2;
background:
linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
rgba(0, 0, 0, 0.6);
border-image: linear-gradient(137.95deg, rgba(0, 255, 255, 1) 6.25%, rgba(0, 200, 255, 1) 100%)
2;
backdrop-filter: blur(2px);
& > div {
@ -300,15 +309,16 @@ const onSort = (sortBy: SortBy) => {
}
//将表格所有的背景色都改为透明色,字体改为白色
:deep(.el-table), :deep(.el-table tr), :deep(.el-table .el-table__cell) {
:deep(.el-table),
:deep(.el-table tr),
:deep(.el-table .el-table__cell) {
background-color: transparent;
color: #fff;
}
//表格行hover和表头的背景色
:deep(.el-table__header-wrapper),
:deep(.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell ) {
:deep(.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell) {
background-color: rgba(0, 255, 255, 0.2);
}
@ -327,7 +337,9 @@ const onSort = (sortBy: SortBy) => {
background: rgba(0, 255, 255, 0.2) !important;
}
:deep(.el-input__wrapper), :deep(.el-range-input), :deep(.el-range-separator) {
:deep(.el-input__wrapper),
:deep(.el-range-input),
:deep(.el-range-separator) {
background: transparent;
--el-input-placeholder-color: #fff;
--el-text-color-placeholder: #fff;

View File

@ -123,13 +123,17 @@
</template>
<span>工程覆盖导入</span>
</el-button>
<el-button color="#004b4b" style="border: 1px solid rgba(0, 255, 255, 0.5)">
<el-button
@click="importProject"
color="#004b4b"
style="border: 1px solid rgba(0, 255, 255, 0.5)"
>
<template #icon>
<svg-icon name="leading_in" />
</template>
<span>工程合并导入</span>
</el-button>
<el-button color="#004b4b" style="border: 1px solid rgba(0, 255, 255, 0.5)">
<el-button @click="derive" color="#004b4b" style="border: 1px solid rgba(0, 255, 255, 0.5)">
<template #icon>
<svg-icon name="leading_out" />
</template>
@ -141,15 +145,18 @@
</template>
<script setup lang="ts">
//@ts-nocheck
import { ref } from 'vue'
import { GisApi } from '@/api/gisApi'
import { RouteApi } from '@/api/route'
import { format } from 'date-fns'
import {
$sendElectronChanel,
$recvElectronChanel,
$changeComponentShow
} from '@/utils/communication'
import { ElMessage, ElMessageBox } from 'element-plus'
import { dialog } from 'electron'
// 上传状态
const isUploading = ref(false)
@ -302,6 +309,203 @@ const handleError = (error: Error) => {
isUploading.value = false
ElMessage.error('文件上传失败')
}
//工程导入(单机)
// import { Loading } from "element-plus";
let importWin = false
const importProject = () => {
if (!importWin) {
importWin = true
let option = {
properties: ['openFile'],
filters: [{ name: '工程包', extensions: ['zip'] }]
}
$sendElectronChanel('open-directory-dialog', option)
$recvElectronChanel('selectedItem', (e, paths) => {
if (paths.length > 0) {
// let loadingInstance = this.$openLoading('拼命导入中...')
importWin = false
// let arr = getElectronPath().replaceAll('\\', '/').split('/')
// arr.pop()
let path: any = 'C:/Users/Administrator/AppData/Roaming/yjearth'
unzip_file(paths[0], path)
.then((res) => {
// loadingInstance.close()
ElMessage({
message: '导入成功',
type: 'success'
})
setTimeout(() => {
ElMessage({
message: '载入成功将在2s后自动重启',
type: 'success'
})
}, 1000)
setTimeout(() => {
$sendElectronChanel('restart')
}, 3000)
})
.catch((err) => {
console.log(err)
})
} else {
importWin = false
}
})
}
}
// import Store from 'electron-store'
const getElectronPath = () => {
const Store = require('electron-store')
const store = new Store()
console.log(store.path)
return store.path
}
// function openLoading(
// text = "拼命加载中...",
// option = {
// fullscreen: true,
// background: "rgba(0,0,0,0.63)",
// lock: true,
// // spinner: 'el-icon-loading'
// }
// ) {
// option.text = text;
// let loadingInstance = Loading.service(option);
// return loadingInstance;
// }
const fs = require('fs')
const archiver = require('archiver')
function zip_file(arr = [], dst, cb) {
// create a file to stream archive data to.
const output = fs.createWriteStream(dst)
// archiver.registerFormat('zip-encrypted', require("archiver-zip-encrypted"));
const archive = archiver.create('zip', {
zlib: {
level: 9
} // Sets the compression level.
// encryptionMethod: 'aes256',//加密方法
// password: '123',//解压密码
})
output.on('close', function () {
cb()
console.log(archive.pointer() + ' total bytes')
console.log('archiver has been finalized and the output file descriptor has closed.')
})
output.on('end', function () {
console.log('Data has been drained')
})
archive.on('warning', function (err) {
if (err.code === 'ENOENT') {
// log warning
} else {
// throw error
throw err
}
})
archive.on('error', function (err) {
throw err
})
archive.pipe(output)
arr.forEach((item: any) => {
let state = fs.statSync(item)
if (state.isFile())
archive.append(fs.createReadStream(item), {
name: item.replaceAll('\\', '/').split('/').pop()
})
if (state.isDirectory()) archive.directory(item, item.replaceAll('\\', '/').split('/').pop())
})
archive.finalize()
let cur = 0
let timer = setInterval(() => {
console.log(archive.pointer())
if (archive.pointer() === cur) {
clearInterval(timer)
} else {
cur = archive.pointer()
}
}, 100)
}
const compressing = require('compressing')
function unzip_file(srcZipFile, dst) {
console.log(srcZipFile)
console.log(dst)
return compressing.zip.uncompress(srcZipFile, dst)
// fs.createReadStream(srcZipFile).pipe(unzip.Extract({path: dst}));
}
//工程导出
let exportWin = false
function derive() {
if (!exportWin) {
exportWin = !exportWin
const date = new Date()
const formattedDate = format(date, 'yyyyMMdd HHmmss')
let option = {
title: '请选择要保存的文件名',
buttonLabel: '保存',
filename: `工程${formattedDate}.zip`,
filters: [{ name: '文件类型', extensions: ['zip'] }]
}
$sendElectronChanel('saveFile', option)
$recvElectronChanel('selectedFileItem', (e, path) => {
if (path) {
// if (result.canceled) {
// this.exportWin = !this.exportWin
// return
// }
// let loadingInstance = this.$openLoading('拼命导出中...')
exportWin = !exportWin
console.log('111111')
// let arr = getElectronPath().replaceAll('\\', '/').split('/')
// console.log(arr, '222222')
// arr[arr.length - 1] = 'database.ydb'
// let db_path: any = arr.join('/')
let db_path: any = 'C:/Users/Administrator/AppData/Roaming/yjearth/app.db'
zip_file([db_path], path, () => {
// loadingInstance.close()
ElMessage({
message: '导出完成',
type: 'success'
})
})
}
})
// dialog
// .showSaveDialog({
// title: '请选择要保存的文件名',
// buttonLabel: '保存',
// defaultPath: `工程${formattedDate}.zip`,
// filters: [{ name: '文件类型', extensions: ['zip'] }]
// })
// .then((result) => {
// if (result.canceled) {
// exportWin = !exportWin
// return
// }
// // let loadingInstance = this.$openLoading('拼命导出中...')
// exportWin = !exportWin
// let arr = getElectronPath().replaceAll('\\', '/').split('/')
// arr[arr.length - 1] = 'database.ydb'
// let db_path: any = arr.join('/')
// zip_file([db_path], result.filePath, () => {
// // loadingInstance.close()
// ElMessage({
// message: '导出完成',
// type: 'success'
// })
// })
// })
// .catch((err) => {
// console.log(err)
// })
}
}
</script>
<style lang="scss" scoped>

View File

@ -4,7 +4,7 @@
<el-button
color="#004b4b"
style="border: 1px solid rgba(0, 255, 255, 0.5)"
@click="edit('添加设备')"
@click="edit('添加设备', 0)"
>
<template #icon>
<svg-icon name="leading_in" />
@ -113,16 +113,16 @@ let pages: any = reactive({
// })
// }
var statusTrans = (id) => {
switch (id) {
case '1':
return '海康'
case '2':
return '大华'
case '3':
return '手动录入'
}
}
// var statusTrans = (id) => {
// switch (id) {
// case '1':
// return '海康'
// case '2':
// return '大华'
// case '3':
// return '手动录入'
// }
// }
const getTableList = async () => {
let params = {
@ -172,32 +172,22 @@ var edit = (type, row) => {
eventBus.emit('openAddDevice', { title: type, data: addForm })
}
var submitProtal = () => {
peopleFormRef.value.validate(async (valid) => {
if (valid) {
if (
addForm.value.channel === undefined ||
addForm.value.channel === '' ||
addForm.value.channel === null
) {
addForm.value.channel = 1
}
// const res = await cameraDataAdd(this.addForm)
// if (res.code === 50) {
// ElMessage.warning(res.message)
// return
// }
// if (res.code === 0) {
// ElMessage.success('添加成功')
// pDialogVisible.value = false
// // this.getList()
// }
} else {
console.log('error submit!!')
return false
}
})
}
// var submitProtal = () => {
// peopleFormRef.value.validate(async (valid) => {
// if (valid) {
// if (
// addForm.value.channel === undefined ||
// addForm.value.channel === '' ||
// addForm.value.channel === null
// ) {
// addForm.value.channel = 1
// }
// } else {
// console.log('error submit!!')
// return false
// }
// })
// }
var delFun = (row) => {
ElMessageBox.confirm(
`删除该设备将在系统中永久消失,且及其所有关联数据将从系统中永久移除,您确定要执行该操作吗?`,

View File

@ -72,14 +72,14 @@
地理坐标系
<svg-icon
v-if="isHotGroupOpen"
name="arrow1"
name="arrow2"
:size="10"
color="rgba(0, 255, 255, 1)"
style="margin-left: 10px"
></svg-icon>
<svg-icon
v-else
name="arrow2"
name="arrow1"
:size="10"
color="rgba(255, 255, 255, 1)"
style="margin-left: 10px"
@ -101,14 +101,14 @@
投影坐标系
<svg-icon
v-if="isHotGroupOpen2"
name="arrow1"
name="arrow2"
:size="10"
color="rgba(0, 255, 255, 1)"
style="margin-left: 10px"
></svg-icon>
<svg-icon
v-else
name="arrow2"
name="arrow1"
:size="10"
color="rgba(255, 255, 255, 1)"
style="margin-left: 10px"

View File

@ -126,6 +126,7 @@ var submitProtal = () => {
}
}
baseDialog.value?.close()
return true
} else {
console.log('error submit!!')
return false