Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl
This commit is contained in:
60
electron.vite.config.1761880900863.mjs
Normal file
60
electron.vite.config.1761880900863.mjs
Normal file
@ -0,0 +1,60 @@
|
||||
// electron.vite.config.ts
|
||||
import { resolve } from "path";
|
||||
import { defineConfig, externalizeDepsPlugin } from "electron-vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
import Components from "unplugin-vue-components/vite";
|
||||
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
|
||||
import path from "path";
|
||||
var electron_vite_config_default = defineConfig({
|
||||
main: {
|
||||
plugins: [externalizeDepsPlugin()]
|
||||
},
|
||||
preload: {
|
||||
plugins: [externalizeDepsPlugin()]
|
||||
},
|
||||
renderer: {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@renderer": resolve("src/renderer/src"),
|
||||
"@": resolve("src/renderer/src")
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
AutoImport({
|
||||
imports: ["vue"],
|
||||
dts: "src/auto-imports.d.ts",
|
||||
// 自动生成类型声明文件
|
||||
resolvers: [ElementPlusResolver()]
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()]
|
||||
}),
|
||||
// SVG图标插件配置
|
||||
// 配置SVG图标插件
|
||||
createSvgIconsPlugin({
|
||||
iconDirs: [path.resolve(process.cwd(), "src/renderer/src/icons/svg")],
|
||||
symbolId: "icon-[name]",
|
||||
// 自动清除 SVG 中的 fill 和 stroke 属性
|
||||
svgoOptions: {
|
||||
plugins: [{ name: "removeAttrs", params: { attrs: ["fill", "stroke", "stroke-width"] } }]
|
||||
}
|
||||
})
|
||||
]
|
||||
/*server: {
|
||||
port: 8848,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: localStorage.getItem('ip') || 'http://127.0.0.1:8848',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
});
|
||||
export {
|
||||
electron_vite_config_default as default
|
||||
};
|
||||
@ -41,16 +41,16 @@ export default defineConfig({
|
||||
plugins: [{name: 'removeAttrs', params: {attrs: ['fill', 'stroke', 'stroke-width']}}]
|
||||
}
|
||||
})
|
||||
]
|
||||
// server: {
|
||||
// port: 8848,
|
||||
// proxy: {
|
||||
// '/api': {
|
||||
// target: localStorage.getItem('ip') || 'http://127.0.0.1:8848',
|
||||
// changeOrigin: true,
|
||||
// rewrite: (path) => path.replace(/^\/api/, '')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
],
|
||||
/*server: {
|
||||
port: 8848,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: localStorage.getItem('ip') || 'http://127.0.0.1:8848',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
})
|
||||
|
||||
4076
package-lock.json
generated
4076
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
8
src/renderer/components.d.ts
vendored
8
src/renderer/components.d.ts
vendored
@ -11,6 +11,8 @@ declare module 'vue' {
|
||||
BaseDialog: typeof import('./src/components/dialog/baseDialog.vue')['default']
|
||||
Directory: typeof import('./src/components/dialog/directory.vue')['default']
|
||||
DirectoryEdit: typeof import('./src/components/dialog/directoryEdit.vue')['default']
|
||||
ElAutoResizer: typeof import('element-plus/es')['ElAutoResizer']
|
||||
ElBotton: typeof import('element-plus/es')['ElBotton']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
@ -20,18 +22,24 @@ declare module 'vue' {
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElImage: typeof import('element-plus/es')['ElImage']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSlider: typeof import('element-plus/es')['ElSlider']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTableV2: typeof import('element-plus/es')['ElTableV2']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
|
||||
ElTree: typeof import('element-plus/es')['ElTree']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default']
|
||||
|
||||
@ -9,7 +9,8 @@ export default {
|
||||
},
|
||||
btn: {
|
||||
search: '搜索',
|
||||
treePlaceholder: '关键词搜索',
|
||||
treePlaceholder: '请输入所需查找的地点',
|
||||
treeLayerholder: '请输入图层名称',
|
||||
selectPlaceholder: '请选择 ',
|
||||
selectNoText: '无数据',
|
||||
confirm: '确定'
|
||||
|
||||
23
src/renderer/src/api/ts/index.ts
Normal file
23
src/renderer/src/api/ts/index.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import request from '@/axios/request'
|
||||
import {data} from "jquery";
|
||||
|
||||
export const TsApi = {
|
||||
addPlan: async (data: any) => {
|
||||
return await request.post({
|
||||
url: '/tsPlan/add',
|
||||
data
|
||||
})
|
||||
},
|
||||
planList: async (data: any) => {
|
||||
return await request.post({
|
||||
url: '/tsPlan/list',
|
||||
data
|
||||
})
|
||||
},
|
||||
delPlan: async (data: any) => {
|
||||
return await request.post({
|
||||
url: '/tsPlan/delete',
|
||||
data
|
||||
})
|
||||
},
|
||||
}
|
||||
BIN
src/renderer/src/assets/img/tour.png
Normal file
BIN
src/renderer/src/assets/img/tour.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 973 B |
@ -644,3 +644,6 @@ img {
|
||||
.el-message--error svg {
|
||||
color: rgba(241, 108, 85, 1) !important;
|
||||
}
|
||||
.el-popup-parent--hidden{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@ if (window && window.process && window.process.type === 'renderer') {
|
||||
baseURL = localStorage.getItem('ip') || 'http://127.0.0.1:8848'
|
||||
// baseURL = 'http://127.0.0.1:8848'
|
||||
} else {
|
||||
localStorage.setItem('ip', 'http://192.168.110.25:8848')
|
||||
baseURL = 'http://192.168.110.25:8848'
|
||||
localStorage.setItem('ip', 'http://192.168.110.71:8848')
|
||||
baseURL = 'http://192.168.110.71:8848'
|
||||
}
|
||||
// localStorage.setItem('service', baseURL)
|
||||
|
||||
@ -75,7 +75,7 @@ service.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
const key = getRequestKey(response.config)
|
||||
pendingRequests.delete(key)
|
||||
console.log(response);
|
||||
// console.log(response);
|
||||
|
||||
// 统一处理HTTP状态码
|
||||
if (response.status === 200) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {TreeApi} from '@/api/tree'
|
||||
import {useTreeNode} from '../views/components/tree/hooks/treeNode'
|
||||
import {initMapData} from './initMapData'
|
||||
|
||||
export const addMapSource = async ({type, id, sourceName = '未命名对象', opt = {}}) => {
|
||||
const {cusAddNodes} = useTreeNode()
|
||||
if (!id) {
|
||||
@ -13,8 +14,7 @@ export const addMapSource = async ({ type, id, sourceName = '未命名对象', o
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {leftClick, rightClick} from '../../src/views/components/tree/entityClick'
|
||||
import {renderVector} from '../views/components/tree/components/hooks/renderVector'
|
||||
|
||||
export const initMapData = async (type, data, cd) => {
|
||||
let entityObject
|
||||
let options
|
||||
@ -51,7 +52,8 @@ export const initMapData = async (type, data, cd) => {
|
||||
break
|
||||
case 'military':
|
||||
entityObject = new YJ.Obj.GroundSvg(window.earth, data)
|
||||
entityObject.load(() => { })
|
||||
entityObject.load(() => {
|
||||
})
|
||||
break
|
||||
case 'terrain':
|
||||
data.host = baseURL
|
||||
@ -130,7 +132,8 @@ export const initMapData = async (type, data, cd) => {
|
||||
entityObject = new YJ.Obj.RadarScanStereoscopic(window.earth, data)
|
||||
break
|
||||
case 'textBox':
|
||||
entityObject = new YJ.Obj.TextBox(window.earth, data, () => { })
|
||||
entityObject = new YJ.Obj.TextBox(window.earth, data, () => {
|
||||
})
|
||||
break
|
||||
case 'polyhedronObject':
|
||||
entityObject = new YJ.Obj.PolyhedronObject(window.earth, data)
|
||||
@ -187,6 +190,7 @@ export const initMapData = async (type, data, cd) => {
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
options = getOptions()
|
||||
console.log('--------------------onClick')
|
||||
//鼠标左键点击事件
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
1
src/renderer/src/icons/svg/weatherBase.svg
Normal file
1
src/renderer/src/icons/svg/weatherBase.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 32 KiB |
@ -89,6 +89,7 @@ document.title = i18n.global.t('title');
|
||||
// 注册全局指令
|
||||
(window as any)._winMap = new Map();
|
||||
(window as any)._entityMap = new Map();
|
||||
(window as any).did_ts_Arr = [];
|
||||
const setApp = createApp(App)
|
||||
// 定义全局方法
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ const routes = [
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
hidden: true
|
||||
},
|
||||
{path: '/ts', component: () => import('@/views/TS/index.vue'), hidden: true},
|
||||
{path: '/tsEdit', component: () => import('@/views/TS/edit.vue'), hidden: true},
|
||||
{path: '/ts', component: () => import('@/views/TS/list.vue'), hidden: true},
|
||||
{path: '/tsEdit', name: 'tsEdit', component: () => import('@/views/TS/edit.vue'), hidden: true},
|
||||
{path: '/404', component: () => import('@/views/404.vue'), hidden: true},
|
||||
|
||||
{
|
||||
|
||||
@ -12,15 +12,102 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="treeBox">
|
||||
<ul id="treeDemos" class="ztree" :setting="setting"></ul>
|
||||
<ul id="treeDemos" class="ztree"></ul>
|
||||
<rightMenuTs ref="rightMenuRef" class="absolute zIndex99"></rightMenuTs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {onMounted, ref} from 'vue'
|
||||
import {onMounted, ref, nextTick} from 'vue'
|
||||
import {Search} from '@element-plus/icons-vue'
|
||||
import rightMenuTs from './components/rightMenuTs.vue'
|
||||
import {useTreeNode} from "../components/tree/hooks/treeNode";
|
||||
import {$changeComponentShow} from "../../utils/communication";
|
||||
|
||||
const {getSelectedNodes, cusSelectNode, getSameLevel, cusNodeIcon, nodeType} = useTreeNode()
|
||||
import {showRightMenuTs} from "./tree"
|
||||
|
||||
const rightMenuRef: any = ref()
|
||||
const treeObj = ref() //树形的实例
|
||||
const nodes: any = ref([])
|
||||
let input2 = ref('')
|
||||
onMounted(() => {
|
||||
let data = [
|
||||
{
|
||||
name: "88",
|
||||
sourceType: "directory"
|
||||
}
|
||||
]
|
||||
treeObj.value = $.fn.zTree.init($(`#treeDemos`), setting, data)
|
||||
window.treeObj = treeObj.value
|
||||
})
|
||||
const onClick = (event: MouseEvent, treeId: string, treeNode: any) => {
|
||||
console.log('selectNode', treeNode)
|
||||
|
||||
let isShift = event.shiftKey
|
||||
let isCtrl = event.ctrlKey
|
||||
if (!isCtrl || !isShift) {
|
||||
let source_ids: any = [];
|
||||
// 判断是否是图层文件
|
||||
if (treeNode.sourceType == "directory") {
|
||||
// 获取treeNode下面的所有souer_id
|
||||
if (treeNode.children) {
|
||||
treeNode.children.forEach((item) => {
|
||||
source_ids.push(item.id);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source_ids.push(treeNode.id);
|
||||
}
|
||||
// YJ.Global.splitScreen.setActiveId(source_ids);
|
||||
}
|
||||
}
|
||||
const onMouseDown = (event: MouseEvent, treeId: string, treeNode: any) => {
|
||||
console.log("onMouseDown")
|
||||
let isShift = event.shiftKey
|
||||
let isCtrl = event.ctrlKey
|
||||
if ((!isShift && !isCtrl) || !treeNode) {
|
||||
nodes.value = []
|
||||
}
|
||||
if (treeNode) {
|
||||
//判断是否是图层文件
|
||||
if (isCtrl) {
|
||||
let isSelected = treeObj.value
|
||||
.getSelectedNodes()
|
||||
.some((node: any) => node.id === treeNode.id)
|
||||
if (isSelected) {
|
||||
// 如果节点已选中,则取消选中
|
||||
nodes.value = nodes.value.filter((node: any) => node.id !== treeNode.id)
|
||||
} else {
|
||||
// 如果节点未选中,则添加到选中列表
|
||||
nodes.value.push(treeNode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
treeObj.value.cancelSelectedNode()
|
||||
$changeComponentShow('.rightMenuTs', false)
|
||||
}
|
||||
}
|
||||
let rightClick = (event: MouseEvent, treeId: string, treeNode: any) => {
|
||||
let selectNodes = getSelectedNodes(treeObj.value)
|
||||
let isnewSelect = true //是否为新选中
|
||||
selectNodes.forEach((item: any) => {
|
||||
if (treeNode && item.id == treeNode.id) isnewSelect = false
|
||||
})
|
||||
if (!event.ctrlKey && (selectNodes.length < 2 || isnewSelect))
|
||||
cusSelectNode(treeObj.value, treeNode)
|
||||
const menus = showRightMenuTs(event, treeObj.value, getSelectedNodes(treeObj.value), nodeType)
|
||||
console.log('menus', menus)
|
||||
if (menus.length == 0) {
|
||||
// $changeComponentShow('.rightMenu', false)
|
||||
return
|
||||
}
|
||||
nextTick(() => {
|
||||
rightMenuRef.value.initMenus(menus, treeNode)
|
||||
})
|
||||
console.log("树形节点右键点击", treeNode)
|
||||
}
|
||||
const setting = {
|
||||
edit: {
|
||||
enable: true,
|
||||
@ -55,7 +142,10 @@ const setting = {
|
||||
},
|
||||
},
|
||||
callback: {
|
||||
/*onRightClick: this.rightClick,
|
||||
onMouseDown: onMouseDown,
|
||||
onRightClick: rightClick,
|
||||
onClick: onClick,
|
||||
/*
|
||||
onClick: this.onClick,
|
||||
onDblClick: this.onDblClick,
|
||||
onCheck: this.onCheck,
|
||||
@ -74,13 +164,6 @@ const setting = {
|
||||
},
|
||||
}
|
||||
|
||||
let input2 = ref('')
|
||||
onMounted(() => {
|
||||
let data = [
|
||||
{name: "88"}
|
||||
]
|
||||
$.fn.zTree.init($(`#treeDemos`), setting, data)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -88,7 +171,7 @@ onMounted(() => {
|
||||
width: 16.3vw;
|
||||
height: 59.6vh;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
z-index: 999;
|
||||
top: 13.4259259259vh;
|
||||
right: 1.5625vw;
|
||||
border: 0.078125vw solid rgb(var(--color-base1));
|
||||
@ -101,6 +184,10 @@ onMounted(() => {
|
||||
.treeBox {
|
||||
border: 1px solid red;
|
||||
flex: auto;
|
||||
|
||||
.ztree {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
118
src/renderer/src/views/TS/components/chart.vue
Normal file
118
src/renderer/src/views/TS/components/chart.vue
Normal file
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="chart" @scroll="scroll">
|
||||
<div class="area">
|
||||
<!-- 给 hr 和 row 增加 key,确保更新时重新渲染 -->
|
||||
<template v-for="(_,index) in hr" :key="index">
|
||||
<hr :style="hrStyle(index)">
|
||||
</template>
|
||||
<template v-for="(event,index) in eventList" :key="index">
|
||||
<div class="row" :style="getStyle">
|
||||
<div class="bar" :style="progressStyle(event)">{{ event.name + event.duration_time }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref, watchEffect} from "vue";
|
||||
|
||||
const props = defineProps(['eventList', 'hr', 'originHrOffset', 'scrollLeft'])
|
||||
|
||||
// 1. 定义响应式变量,用于强制更新
|
||||
const refreshKey = ref(0)
|
||||
|
||||
// 2. 监听 preSecondPx 变化,触发更新
|
||||
// 注意:如果 preSecondPx 变化时没有触发此函数,需要在修改 preSecondPx 的地方手动调用 refresh()
|
||||
watchEffect(() => {
|
||||
// 访问外部变量,建立依赖关联
|
||||
const currentPreSecondPx = window['tsObj']._Store._scales.preSecondPx
|
||||
// 打印日志验证是否监听到变化(测试用)
|
||||
console.log('当前 preSecondPx:', currentPreSecondPx)
|
||||
})
|
||||
|
||||
// 3. 手动刷新函数(如果 watchEffect 不生效,需要在修改 preSecondPx 的地方调用此函数)
|
||||
const refresh = () => {
|
||||
refreshKey.value++ // 修改响应式变量,触发依赖更新
|
||||
}
|
||||
// 暴露给全局,方便外部调用(如果 preSecondPx 在外部修改)
|
||||
window['refreshChart'] = refresh
|
||||
|
||||
let scroll = (e) => {
|
||||
console.log("ssss")
|
||||
let scrollLeft = e.srcElement.scrollLeft
|
||||
let scrollTop = e.srcElement.scrollTop
|
||||
window['tsAction']({
|
||||
action: "scroll-chart",
|
||||
obj: {
|
||||
top: scrollTop,
|
||||
left: scrollLeft,
|
||||
deltaX: e.deltaX,
|
||||
deltaY: e.deltaY,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 4. 让 getStyle 依赖 refreshKey
|
||||
let getStyle = computed(() => {
|
||||
refreshKey.value // 加入依赖,确保 refreshKey 变化时重新计算
|
||||
let height = window['tsObj']._Store._scales.cellHeight
|
||||
return `height:${height}px;line-height:${height}px;`
|
||||
})
|
||||
|
||||
let hrStyle = (index) => {
|
||||
let cellHeight = window['tsObj']._Store._scales.cellHeight
|
||||
let top = (index + 1) * cellHeight
|
||||
return `top:${top + props.originHrOffset}px;left:${props.scrollLeft}px`
|
||||
}
|
||||
|
||||
// 5. 让 getWidth 依赖 refreshKey
|
||||
let getWidth = (durationTime) => {
|
||||
refreshKey.value // 加入依赖
|
||||
let width = (durationTime * window['tsObj']._Store._scales.preSecondPx) / 1000;
|
||||
return width;
|
||||
}
|
||||
|
||||
// 6. 让 progressStyle 间接依赖 refreshKey(通过 getWidth)
|
||||
let progressStyle = (task) => {
|
||||
let taskLeft = task.start_time - window['tsObj']._Store._startTimestamp;
|
||||
return {
|
||||
width: getWidth(task.duration_time) * 1000 + "px",
|
||||
left: getWidth(taskLeft) + "px",
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 样式不变 */
|
||||
.chart {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
|
||||
.area {
|
||||
position: relative;
|
||||
|
||||
.row {
|
||||
position: relative;
|
||||
|
||||
.bar {
|
||||
position: absolute;
|
||||
background: rgba(0, 255, 255, 0.5);
|
||||
color: #FFF;
|
||||
height: calc(100% - 1.1px);
|
||||
overflow: hidden;
|
||||
top: 1.1px;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
border: none;
|
||||
background: rgba(0, 255, 255, 0.28);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
116
src/renderer/src/views/TS/components/chart1.vue
Normal file
116
src/renderer/src/views/TS/components/chart1.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="chart" @scroll="scroll">
|
||||
<div class="area">
|
||||
<template v-for="(_,index) in hr">
|
||||
<hr :style="hrStyle(index)">
|
||||
</template>
|
||||
<template v-for="(event,index) in eventList">
|
||||
<div class="row" :style="getStyle">
|
||||
<div class="bar" :style="progressStyle(event)">{{ event.name + event.duration_time }}</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref, watchEffect, reactive} from "vue";
|
||||
|
||||
// const scales = reactive(window['tsObj']._Store._scales);
|
||||
const props = defineProps(['eventList', 'hr', 'originHrOffset', 'scrollLeft'])
|
||||
// 定义一个响应式变量,用于强制更新
|
||||
// const forceUpdate = ref(0);
|
||||
// // 监听 preSecondPx 变化,触发组件更新
|
||||
// watchEffect(() => {
|
||||
// console.log("访问外部变量,让 watchEffect 捕获依赖", window['tsObj']._Store._scales.preSecondPx)
|
||||
// // 访问外部变量,让 watchEffect 捕获依赖
|
||||
// window['tsObj']._Store._scales.preSecondPx;
|
||||
// // 强制组件重新渲染(通过修改一个响应式变量触发)
|
||||
// forceUpdate.value++;
|
||||
// });
|
||||
|
||||
let scroll = (e) => {
|
||||
console.log("ssss")
|
||||
let scrollLeft = e.srcElement.scrollLeft
|
||||
let scrollTop = e.srcElement.scrollTop
|
||||
window['tsAction']({
|
||||
action: "scroll-chart",
|
||||
obj: {
|
||||
top: scrollTop,
|
||||
left: scrollLeft,
|
||||
deltaX: e.deltaX,
|
||||
deltaY: e.deltaY,
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
let getStyle = computed(() => {
|
||||
let height = window['tsObj']._Store._scales.cellHeight
|
||||
return `height:${height}px;line-height:${height}px;`
|
||||
})
|
||||
let hrStyle = (index) => {
|
||||
|
||||
let cellHeight = window['tsObj']._Store._scales.cellHeight
|
||||
let top = (index + 1) * cellHeight
|
||||
|
||||
// top+scrollTop-scrollTop%cellHeight
|
||||
return `top:${top + props.originHrOffset}px;left:${props.scrollLeft}px`
|
||||
}
|
||||
let getWidth = (durationTime) => {
|
||||
// console.log("durationTime", durationTime)
|
||||
let width = (durationTime * window['tsObj']._Store._scales.preSecondPx) / 1000;
|
||||
//左偏移量中 竖线所占宽度
|
||||
// let widthOfTiny = Math.floor(width / this.Store.scales.distanceOfTicTiny)
|
||||
return width;
|
||||
}
|
||||
let progressStyle = (task) => {
|
||||
// console.log("task", task)
|
||||
|
||||
let taskLeft = task.start_time - window['tsObj']._Store._startTimestamp;
|
||||
/*console.log("task", {
|
||||
width: getWidth(task.duration_time) * 1000 + "px",
|
||||
left: getWidth(taskLeft) + "px",
|
||||
})*/
|
||||
return {
|
||||
width: getWidth(task.duration_time) * 1000 + "px",
|
||||
left: getWidth(taskLeft) + "px",
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart {
|
||||
flex: 1 1 auto;
|
||||
//background: #5fa5a97d;
|
||||
overflow: auto;
|
||||
|
||||
.area {
|
||||
position: relative;
|
||||
|
||||
.row {
|
||||
//border-bottom: 1px solid rgba(0, 255, 255, 0.28);
|
||||
position: relative;
|
||||
|
||||
.bar {
|
||||
position: absolute;
|
||||
background: rgba(0, 255, 255, 0.5);
|
||||
color: #FFF;
|
||||
height: calc(100% - 1.1px);
|
||||
overflow: hidden;
|
||||
top: 1.1px;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
//left: 50px;
|
||||
height: 1px;
|
||||
border: none;
|
||||
background: rgba(0, 255, 255, 0.28);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
36
src/renderer/src/views/TS/components/eventParams.vue
Normal file
36
src/renderer/src/views/TS/components/eventParams.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="eventParams">
|
||||
<template v-if="isNoEvent">
|
||||
<div class="tourBox">
|
||||
<img src="../../../assets/img/tour.png">
|
||||
<p>选中事件调整属性</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref} from 'vue'
|
||||
|
||||
let isNoEvent = ref(true)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.eventParams {
|
||||
width: 20%;
|
||||
|
||||
.tourBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 71.2px;
|
||||
height: 48.1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
91
src/renderer/src/views/TS/components/grid.vue
Normal file
91
src/renderer/src/views/TS/components/grid.vue
Normal file
@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div class="grid">
|
||||
<div class="grid-header row">
|
||||
<div v-for="item in columns" :style="item.style">{{ item.name }}</div>
|
||||
</div>
|
||||
<div class="grid-body">
|
||||
<div class="row" :style="getStyle" v-for="(event) in eventList">
|
||||
<span v-for="item in columns" :class="item.key" :style="item.style">{{
|
||||
format(item.key, event[item.key])
|
||||
}}</span>
|
||||
</div>
|
||||
<div :style="style">
|
||||
<!--aa-->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, onMounted, ref} from "vue"
|
||||
|
||||
let columns = ref([{name: '事件名称', key: "name", style: "flex:auto"},
|
||||
{name: '开始时间', key: "start_time", style: "width:120px"},
|
||||
{name: '持续时间', key: "duration_time", style: "width:70px"}])
|
||||
let eventList = ref([])
|
||||
let style = ref({})
|
||||
eventList.value = window['tsObj']._Store._tasks
|
||||
// 格式化时间
|
||||
let format = (key, val) => {
|
||||
if ('start_time' == key) {
|
||||
return window['tsObj'].parseTime(val, "{m}-{d} {h}:{i}:{s}")
|
||||
}
|
||||
return val
|
||||
}
|
||||
let getStyle = computed(() => {
|
||||
return "height:" + window['tsObj']._Store._scales.cellHeight + "px"
|
||||
})
|
||||
onMounted(() => {
|
||||
/* let doms = document.getElementsByClassName("start_time")
|
||||
for (let i = 0; i < doms.length; i++) {
|
||||
doms[i].style.lineHeight = "19px"
|
||||
}*/
|
||||
let panelHeight = window['tsObj']._Store.getDomElement(".chart", 0).getBoundingClientRect().height
|
||||
|
||||
// 转为字符串并按 "." 分割
|
||||
const [whole, decimalStr] = String(panelHeight).split('.');
|
||||
let rest = whole % window['tsObj']._Store.getScale('cellHeight')
|
||||
// 若有小数部分,拼接为 "0.xxx" 后转为数字;否则为 0
|
||||
const decimalPart = decimalStr ? Number(`${rest}.${decimalStr}`) : 0;
|
||||
style.value = {
|
||||
height: `${decimalPart + 10}px`,
|
||||
// opacity: 0
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.grid {
|
||||
width: 400px;
|
||||
border-right: 1px solid rgba(238, 238, 238, 0.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.grid-header {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
|
||||
& > div {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
border-bottom: 1px solid rgba(0, 255, 255, 0.28);
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-body {
|
||||
position: relative;
|
||||
overflow-y: inherit;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
134
src/renderer/src/views/TS/components/rightMenuTs.vue
Normal file
134
src/renderer/src/views/TS/components/rightMenuTs.vue
Normal file
@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<div class="rightMenuTs" id="rMenuTs">
|
||||
<div class="menuItem custom_scroll_bar">
|
||||
<div v-if="menus.length > 0">
|
||||
<!--@click="itemClick(item, eventBus)"-->
|
||||
<!--@mouseup="$changeComponentShow('#rMenu', false)"-->
|
||||
<div
|
||||
v-for="item in menus"
|
||||
class="itemBox"
|
||||
@click="itemClick(item, eventBus)"
|
||||
>
|
||||
<div class="itemIcon">
|
||||
<svg-icon :name="item.key" :size="14"></svg-icon>
|
||||
</div>
|
||||
<div class="itemText">
|
||||
{{ t(`rightMenu.${item.key}`) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="itemBox">
|
||||
<div class="itemText">无操作权限</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {ref} from 'vue'
|
||||
import {useRightOperate} from "./rightOperate";
|
||||
import {useRightMenu} from "../../components/tree/components/hooks/rightMenu";
|
||||
|
||||
const {t} = useI18n()
|
||||
const {rightMenus} = useRightOperate()
|
||||
const menus: any = ref([]) //右侧菜单
|
||||
const rightClickTreeNode: any = ref()
|
||||
const {itemClick} = useRightMenu()
|
||||
const initMenus = (arr: any, treeNode: any) => {
|
||||
let rightMenu: any = []
|
||||
console.log('rightMenu2222', rightMenu)
|
||||
if (treeNode) {
|
||||
rightClickTreeNode.value = treeNode
|
||||
arr.forEach((menuId: any) => {
|
||||
/*if (menuId == 'addResource' || menuId == 'addBIM') {
|
||||
if (['127.0.0.1', 'localhost'].includes(new URL(getIP()!).hostname)) {
|
||||
rightMenu.push(rightMenus[menuId])
|
||||
}
|
||||
} else {*/
|
||||
rightMenu.push(rightMenus[menuId])
|
||||
// }
|
||||
})
|
||||
} else rightMenu = [rightMenus.addDirectory]
|
||||
console.log('rightMenu', rightMenu)
|
||||
menus.value = rightMenu
|
||||
}
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
initMenus
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rightMenuTs {
|
||||
user-select: none;
|
||||
width: 8.5vw;
|
||||
height: 23vh;
|
||||
border: 1px solid red;
|
||||
visibility: hidden;
|
||||
|
||||
.menuItem {
|
||||
//padding: 1vh .5vw;
|
||||
font-size: 12px;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
// margin-top: 16px;
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
//span{
|
||||
line-height: 20px;
|
||||
|
||||
.itemBox {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
padding: 5px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 默认文字颜色 */
|
||||
color: #fff;
|
||||
// transition: all 0.2s ease; /* 添加过渡动画使效果更平滑 */
|
||||
}
|
||||
|
||||
.itemBox:hover {
|
||||
width: 100%;
|
||||
background: rgba(0, 255, 255, 0.2);
|
||||
/* 悬停时的文字颜色 */
|
||||
color: rgba(0, 255, 255, 1);
|
||||
}
|
||||
|
||||
.itemText {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.itemIcon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* 关键:通过currentColor继承父元素的文字颜色 */
|
||||
.itemIcon svg {
|
||||
color: inherit; /* 继承itemIcon的颜色 */
|
||||
}
|
||||
|
||||
/* 确保SVG图标正确继承颜色 */
|
||||
.svg-icon {
|
||||
fill: currentColor !important;
|
||||
stroke: currentColor !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
src/renderer/src/views/TS/components/rightOperate.ts
Normal file
38
src/renderer/src/views/TS/components/rightOperate.ts
Normal file
@ -0,0 +1,38 @@
|
||||
export const useRightOperate = () => {
|
||||
const addDirectory = () => {
|
||||
// $changeComponentPop('.adddirectoryBox', true)
|
||||
console.log("addDirectory")
|
||||
}
|
||||
const addResource = () => {
|
||||
console.log("addResource")
|
||||
}
|
||||
const addEvent = () => {
|
||||
$(".newEvent")[0].style.display = "block"
|
||||
}
|
||||
const rightMenus: any = reactive({
|
||||
addDirectory: {
|
||||
key: 'addDirectory',
|
||||
callback: addDirectory
|
||||
},
|
||||
addResource: {
|
||||
key: 'addResource',
|
||||
callback: addResource
|
||||
},
|
||||
edit: {
|
||||
key: 'edit',
|
||||
callback: addResource
|
||||
},
|
||||
del: {
|
||||
key: 'del',
|
||||
callback: addResource
|
||||
},
|
||||
addEvent: {
|
||||
key: 'addEvent',
|
||||
callback: addEvent
|
||||
}
|
||||
|
||||
})
|
||||
return {
|
||||
rightMenus
|
||||
}
|
||||
}
|
||||
78
src/renderer/src/views/TS/components/timeScale.vue
Normal file
78
src/renderer/src/views/TS/components/timeScale.vue
Normal file
@ -0,0 +1,78 @@
|
||||
<!--:style="'left:'+(index*Store.scales.distanceOfTicTiny+Store.scales.originOffset)+'px'"-->
|
||||
<template>
|
||||
<div class="timeScale">
|
||||
<!-- 循环数组,确保key唯一 -->
|
||||
<template v-for="(_, index) in ticTiny" :key="index">
|
||||
<span
|
||||
:style="{ left: `${index * distanceOfTicTiny+originOffset}px` }"
|
||||
class="timeline-ticTiny"
|
||||
></span>
|
||||
</template>
|
||||
<template v-for="(item, index) in ticMain">
|
||||
<span class="timeline-ticMain"
|
||||
:style="{ left: `${index * distanceOfTicMain+originMainOffset}px` }"></span>
|
||||
<span class="timeline-ticLabel"
|
||||
:style="{ left: `${index * distanceOfTicMain+originMainOffset}px` }">
|
||||
{{ ticLabel(index) }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, watchEffect} from 'vue'
|
||||
|
||||
const props = defineProps(['ticTiny', 'ticMain', 'distanceOfTicTiny', 'distanceOfTicMain', 'originOffset', 'originMainOffset'])
|
||||
|
||||
|
||||
let ticLabel = (val) => {
|
||||
let timeLabels = []
|
||||
/* console.log("timeLabels", this.Store.scales.ticMain)
|
||||
for (let i = 0; i < this.Store.scales.ticMain; i++) {
|
||||
// console.log("timeLabels", this.Store.scales.ticMain)
|
||||
}*/
|
||||
|
||||
// let stamp = this.Store.startTimestamp + val * this.Store.scales.preMains[this.Store.scales.preMainIndex] * 1000// this.Store.scales.preMains[this.Store.scales.preMainIndex] * 1000
|
||||
// return
|
||||
|
||||
// return this.Clock.makeLabel(this.Store.scales.timeLabels[val], "{y}-{m}-{d} {h}:{i}:{s}");
|
||||
return window['tsObj'].parseTime(window['tsObj']._Store.getScale("timeLabels")[val], '{h}:{i}:{s}')
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式不变 */
|
||||
.timeScale {
|
||||
height: 30px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
|
||||
.timeline-ticTiny {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
height: 25%;
|
||||
background: #888;
|
||||
}
|
||||
|
||||
.timeline-ticMain {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.timeline-ticLabel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
white-space: nowrap;
|
||||
font-size: 80%;
|
||||
color: #eee;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
266
src/renderer/src/views/TS/deduction.vue
Normal file
266
src/renderer/src/views/TS/deduction.vue
Normal file
@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<div class="deduction">
|
||||
<!--左侧元素事件面板-->
|
||||
<div class="layoutBox">
|
||||
<div class="control">
|
||||
<span>{{ formatTime(currentStamp) }}</span>
|
||||
<el-icon :size="20" @click="play">
|
||||
<ZoomOut/>
|
||||
</el-icon>
|
||||
<el-icon :size="20" @click="stop">
|
||||
<ZoomIn/>
|
||||
</el-icon>
|
||||
<span class="title">{{ TSOBJ.name }}</span>
|
||||
<span class="zoom">
|
||||
<el-icon :size="20" @click="add(-1)">
|
||||
<ZoomOut/>
|
||||
</el-icon>
|
||||
<el-slider :disabled="true" :max="maxLevel" :min="minLevel" v-model="level" :show-tooltip="false"
|
||||
style="width:80%;padding-right: 8px;"/>
|
||||
<el-icon :size="20" @click="add(1)">
|
||||
<ZoomIn/>
|
||||
</el-icon>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layoutBoxs">
|
||||
<div class="layout">
|
||||
<!-- 左侧事件列表 -->
|
||||
<grid></grid>
|
||||
<!--右侧时间轴容器-->
|
||||
<div class="TLContainer">
|
||||
<div class="timelineCursorBox" :style="{ left: `${cursorLeft || 0}px` }">
|
||||
<!--@mousedown="mousedown" :style="cursorStyle"-->
|
||||
<!--@mouseup="mouseup"-->
|
||||
<!--@mousemove="mousemove"-->
|
||||
<!--<span class="timeline-icon16" v-drags="timing"></span>-->
|
||||
</div>
|
||||
<!-- 时间轴刻度线 -->
|
||||
<timeScale
|
||||
:ticTiny="ticTiny"
|
||||
:ticMain="ticMain"
|
||||
:distanceOfTicTiny="distanceOfTicTiny"
|
||||
:distanceOfTicMain="distanceOfTicMain"
|
||||
:originOffset="originOffset"
|
||||
:originMainOffset="originMainOffset"
|
||||
></timeScale>
|
||||
<!-- 事件色块 -->
|
||||
<chart :eventList="TSOBJ._Store._tasks" :hr="hr" :originHrOffset="originHrOffset"
|
||||
:scrollLeft="scrollLeft"></chart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--右侧事件属性面板-->
|
||||
<eventParams></eventParams>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ZoomIn, ZoomOut} from '@element-plus/icons-vue'
|
||||
|
||||
import EventParams from "./components/eventParams.vue"
|
||||
import Grid from "./components/grid.vue"
|
||||
import TimeScale from "./components/timeScale.vue"
|
||||
import Chart from "./components/chart.vue"
|
||||
import {ref, onBeforeUnmount} from "vue"
|
||||
|
||||
let currentStamp = ref(window['tsObj']._Store._startTimestamp)
|
||||
let maxLevel = ref(24)
|
||||
let minLevel = ref(1)
|
||||
let hr = ref(0)
|
||||
let originHrOffset = ref(0)
|
||||
let scrollLeft = ref(0)
|
||||
let cursorLeft = ref(0)
|
||||
let ticTiny = ref(10)
|
||||
let ticMain = ref(10)
|
||||
let distanceOfTicTiny = ref(5)
|
||||
let distanceOfTicMain = ref(5)
|
||||
let originOffset = ref(0)
|
||||
let originMainOffset = ref(0)
|
||||
distanceOfTicMain.value = window['tsObj']._Store.getScale('numOfMain') * distanceOfTicTiny.value
|
||||
const propsMap = {
|
||||
ticTiny,
|
||||
distanceOfTicTiny,
|
||||
ticMain,
|
||||
distanceOfTicMain,
|
||||
originOffset,
|
||||
originMainOffset,
|
||||
hr,
|
||||
scrollLeft,
|
||||
cursorLeft,
|
||||
originHrOffset,
|
||||
currentStamp
|
||||
}
|
||||
// 更新数值触发视图更新
|
||||
window['updateProp'] = (key: string, val: any) => {
|
||||
if (propsMap[key])
|
||||
propsMap[key].value = val
|
||||
}
|
||||
|
||||
|
||||
const level = ref(20)
|
||||
const props = defineProps(['TSOBJ'])
|
||||
console.log(props.TSOBJ)
|
||||
let formatTime = (timeStamp) => {
|
||||
return props.TSOBJ.parseTime(timeStamp)
|
||||
}
|
||||
let play = () => {
|
||||
props.TSOBJ._Clock.animation(props.TSOBJ._Store, eventCallback)
|
||||
}
|
||||
let stop = () => {
|
||||
props.TSOBJ._Clock.stopAnimation()
|
||||
}
|
||||
|
||||
function todoEvent(timeId: number, res: any, isEnd: boolean) {
|
||||
// console.log("todoEvent", res)
|
||||
if (res) {
|
||||
|
||||
if (res.detail && typeof res.detail == "string") {
|
||||
res.detail = JSON.parse(res.detail);
|
||||
}
|
||||
console.log("执行事件对象", res, '1111111111111111111111111111');
|
||||
window['did_ts_Arr'].push(res.id)
|
||||
switch (res.callback) {
|
||||
case 'flicker':
|
||||
let tsEntity = window['earth_ts'].entityMap.get(res.source_id);
|
||||
tsEntity.flyTo()
|
||||
tsEntity.flicker(1000, 10)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let eventCallback = () => {
|
||||
// 将当前时间戳四舍五入掉毫秒部分
|
||||
let timeId = Math.round(props.TSOBJ._Store._currentTimestamp / 1000);
|
||||
timeId *= 1000;
|
||||
// console.log(timeId)
|
||||
let taskIds = [];
|
||||
let dataMap = props.TSOBJ._Store.dealData("start_time");
|
||||
console.log(dataMap)
|
||||
|
||||
let fun = (map, isEnd = false) => {
|
||||
let keys = Array.from(map.keys());
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let timestamp = keys[i].split("_")[0]
|
||||
|
||||
let event = Array.from(map.values())[i]
|
||||
let flag = props.TSOBJ._Store._currentTimestamp > timestamp && !window.did_ts_Arr.includes(event.id)
|
||||
if (String(keys[i]).indexOf(String(timeId)) > -1 || flag) {
|
||||
taskIds.push(keys[i]);
|
||||
}
|
||||
}
|
||||
taskIds.forEach((item) => {
|
||||
let res = map.get(item);
|
||||
todoEvent(timeId, res, isEnd);
|
||||
});
|
||||
}
|
||||
fun(dataMap)
|
||||
}
|
||||
let add = (num) => {
|
||||
// 大格12个取值,小格间距3个取值,level,8-1
|
||||
|
||||
let res = level.value + num
|
||||
if (res <= maxLevel.value && res >= minLevel.value) {
|
||||
level.value += num
|
||||
window['tsAction']({
|
||||
action: "wheel-timeLine",
|
||||
num: level.value
|
||||
})
|
||||
|
||||
window['refreshChart']()
|
||||
}
|
||||
}
|
||||
onBeforeUnmount(() => {
|
||||
// props.TSOBJ._Clock.stopAnimation()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.deduction {
|
||||
//border: 1px solid red;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
bottom: 5px;
|
||||
width: 100vw;
|
||||
left: 0;
|
||||
height: 24.5vh;
|
||||
display: flex;
|
||||
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.6);
|
||||
backdrop-filter: blur(3.47px);
|
||||
|
||||
.layoutBox {
|
||||
width: 80%;
|
||||
border-right: 1px solid rgba(238, 238, 238, 0.5);
|
||||
|
||||
.control {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
|
||||
.title {
|
||||
left: 62.5%;
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.zoom {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layoutBoxs {
|
||||
height: calc(100% - 30px);
|
||||
position: relative;
|
||||
border-top: 1px solid rgba(238, 238, 238, 0.5);
|
||||
|
||||
.layout {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.TLContainer {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.timelineCursorBox {
|
||||
position: absolute;
|
||||
border-right: 0.5px red solid;
|
||||
height: calc(100% - 16px);
|
||||
z-index: 9;
|
||||
//left: 10px;
|
||||
top: 16px;
|
||||
transition: transform 0.001s ease-in-out;
|
||||
|
||||
.timeline-icon16 {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
//width: vw(16);
|
||||
//height: vw(16);
|
||||
transform: translate(-50%, -16px);
|
||||
background: url("../../assets/img/indicator.png") no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@ -1,38 +1,88 @@
|
||||
<template>
|
||||
<div class="edit">
|
||||
<div class="edit ts-zyl ">
|
||||
<svg class="icon icon-tuichu" @click="closeSituationEdit" aria-hidden="true">
|
||||
<use xlink:href="#icon-tuichu"></use>
|
||||
</svg>
|
||||
<div id="earthContainer" class="fullSize"></div>
|
||||
<cabin></cabin>
|
||||
<element></element>
|
||||
<deduction :TSOBJ="tsOBJ"></deduction>
|
||||
<newEvent></newEvent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
//@ts-nocheck
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import cabin from './cabin.vue'
|
||||
import element from './element.vue'
|
||||
import {ref, reactive, onMounted, nextTick} from "vue";
|
||||
import {useRouter, useRoute} from "vue-router";
|
||||
import Cabin from "./cabin.vue"
|
||||
import Element from "./element.vue"
|
||||
import NewEvent from "./newEvent.vue"
|
||||
import Deduction from "./deduction.vue";
|
||||
import {TS} from "./sdk";
|
||||
import * as domain from "domain";
|
||||
|
||||
let tsOBJ = reactive({})
|
||||
const router = useRouter()
|
||||
const closeSituationEdit = () => {
|
||||
router.back()
|
||||
const route = useRoute()
|
||||
let params = {}
|
||||
// 将由列表页面传递过来的参数,数字化
|
||||
for (const routeQueryKey in route.query) {
|
||||
params[routeQueryKey] = route.query[routeQueryKey]
|
||||
if (Number(route.query[routeQueryKey])) {
|
||||
params[routeQueryKey] = Number(route.query[routeQueryKey])
|
||||
}
|
||||
const createEarth = async () => {
|
||||
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)
|
||||
}
|
||||
console.log("params", params)
|
||||
|
||||
// 通过planID获取方案包含的所有事件
|
||||
let getEventList = () => {
|
||||
let events = []
|
||||
for (let i = 0; i < 1; i++) {
|
||||
events.push({
|
||||
id: "task" + i,
|
||||
source_id: "777",
|
||||
name: "闪烁" + i,
|
||||
callback: "flicker",
|
||||
detail: JSON.stringify({}),
|
||||
start_time: params.start_time + (5 * i * (i - 1) / 2 + 10 * i) * 1000,
|
||||
duration_time: (i * 5 + 10)
|
||||
})
|
||||
}
|
||||
newTS(params, events)
|
||||
}
|
||||
// 新建态势推演对象
|
||||
let newTS = (params, events) => {
|
||||
|
||||
window['tsObj'] = new TS({name: params.name, tasks: events, startTimestamp: params.start_time})
|
||||
tsOBJ = window['tsObj']
|
||||
window['tsAction'] = window['tsObj'].initAction()
|
||||
|
||||
console.log("window['tsObj']", window['tsObj'])
|
||||
nextTick(() => {
|
||||
// dom加载完成后,通过宽度和间隔来计算出刻度线的数量
|
||||
window['tsObj']._Store.init()
|
||||
window['tsObj'].renderLabel({left: 0})
|
||||
})
|
||||
}
|
||||
getEventList()
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
let baseURL = localStorage.getItem('service')
|
||||
// getAuthInfo()
|
||||
await YJ.on({host: baseURL})
|
||||
createEarth()
|
||||
})
|
||||
const createEarth = async () => {
|
||||
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)
|
||||
}
|
||||
const closeSituationEdit = () => {
|
||||
router.back()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -13,134 +13,159 @@
|
||||
</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">
|
||||
<div class="treeOrList" :style="currentTypeId!=''?'height: calc(100% - 300px);':''">
|
||||
<template v-if="dataType=='tree'">
|
||||
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick" />
|
||||
<el-tree
|
||||
:data="treeData"
|
||||
:props="defaultProps"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="dataType=='list'">
|
||||
<div v-for="item in lists">
|
||||
<div v-for="item in lists" @click="addMarker(item)" class="markerItem">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<div class="list" v-if="currentTypeId!=''">
|
||||
<div v-for="item in elementList" class="itemBox">
|
||||
<div class="imgbg">
|
||||
<img :src="service + (item.posterDataUrl||item.militaryDataUrl)"/>
|
||||
</div>
|
||||
<!--fit="contain"-->
|
||||
|
||||
<div class="label">
|
||||
{{ item.modelName || item.militaryName }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list" v-if="showList"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
//@ts-nocheck
|
||||
import { ref } from 'vue'
|
||||
import {ref, onMounted} from "vue";
|
||||
import {Search} from '@element-plus/icons-vue'
|
||||
import {ModelApi} from "../../api/model";
|
||||
import {GraphApi} from "../../api/graphLabel";
|
||||
import {addMapSource} from "./entity";
|
||||
|
||||
const service = ref(localStorage.getItem('ip'))
|
||||
|
||||
interface Tree {
|
||||
label: string
|
||||
name: string
|
||||
children?: Tree[]
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
}
|
||||
|
||||
const activIndex = ref(0)
|
||||
const tabs = [
|
||||
{ name: '人工模型', dataType: 'tree' },
|
||||
{ name: '军事标绘', dataType: 'tree' },
|
||||
{name: "人工模型", dataType: 'tree', key: "model"},
|
||||
{name: "军事标绘", dataType: 'tree', key: "graph"},
|
||||
{
|
||||
name: '基础标绘',
|
||||
dataType: 'list',
|
||||
children: [{ name: '点' }, { name: '线' }, { name: '面' }, { name: '圆' }]
|
||||
},
|
||||
{ name: '特效', dataType: 'list', children: [{ name: '火焰' }] }
|
||||
name: "基础标绘", dataType: 'list', children:
|
||||
[
|
||||
{name: "点", source_name: "点标注", funName: 'DrawPoint', type: "point"},
|
||||
{name: "线", source_name: "", funName: 'DrawPolyline', type: ""},
|
||||
{name: "面", source_name: "", funName: 'DrawPolygon', type: ""},
|
||||
{name: "圆", source_name: "", funName: 'DrawCircle', type: ""},
|
||||
{name: "攻击箭头", source_name: "", funName: 'DrawAttackArrow', type: ""},
|
||||
{name: "钳形箭头", source_name: "", funName: 'DrawPincerArrow', type: ""}
|
||||
]
|
||||
},
|
||||
{name: "特效", dataType: 'list', children: [{name: "火焰"}]},
|
||||
]
|
||||
let treeData = ref<Tree[]>([])
|
||||
// 模型类型
|
||||
let modelTypes = ref<Tree[]>([])
|
||||
// 军标类型
|
||||
let graphTypes = ref<Tree[]>([])
|
||||
|
||||
const data: Tree[] = [
|
||||
{
|
||||
label: 'Level one 1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level two 1-1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 1-1-1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level one 2',
|
||||
children: [
|
||||
{
|
||||
label: 'Level two 2-1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 2-1-1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level two 2-2',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 2-2-1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level one 3',
|
||||
children: [
|
||||
{
|
||||
label: 'Level two 3-1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 3-1-1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level two 3-2',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 3-2-1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
}
|
||||
const lists = ref([])
|
||||
const elementList = ref([])
|
||||
let input2 = ref('')
|
||||
// 显示某类型下的元素
|
||||
const showList = ref(false)
|
||||
// 当前选择类型的Id
|
||||
const currentTypeId = ref('')
|
||||
// 是否为树结构
|
||||
const dataType = ref('tree')
|
||||
// 树形结构节点点击
|
||||
const handleTabClick = (item, index) => {
|
||||
activIndex.value = index
|
||||
currentTypeId.value = ""
|
||||
elementList.value = []
|
||||
|
||||
console.log(item)
|
||||
dataType.value = item.dataType
|
||||
if (item.children) {
|
||||
if (item.key == 'model') {
|
||||
treeData.value = modelTypes.value
|
||||
} else if (item.key == 'graph') {
|
||||
treeData.value = graphTypes.value
|
||||
} else if (item.children) {
|
||||
lists.value = item.children
|
||||
}
|
||||
}
|
||||
const handleNodeClick = (data: Tree) => {
|
||||
console.log(data)
|
||||
showList.value = true
|
||||
const handleNodeClick = (data) => {
|
||||
// console.log(data)
|
||||
currentTypeId.value = currentTypeId.value == data.id ? '' : data.id
|
||||
elementList.value = []
|
||||
if (currentTypeId.value)
|
||||
getModelListByType(currentTypeId.value)
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getModelTypeList()
|
||||
await getGraphTypeList()
|
||||
// console.log("modelTypes.value", modelTypes.value)
|
||||
treeData.value = modelTypes.value
|
||||
})
|
||||
// 根据类型获取模型列表
|
||||
const getModelListByType = (id) => {
|
||||
let formData = new FormData()
|
||||
if (activIndex.value == 0) {
|
||||
formData.append('modelTypeId', id)
|
||||
ModelApi.showModelByType(formData).then((res) => {
|
||||
elementList.value = res.data
|
||||
})
|
||||
} else {
|
||||
formData.append('militaryTypeId', id)
|
||||
GraphApi.showModelByType(formData).then((res) => {
|
||||
elementList.value = res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
// 获取模型类型列表
|
||||
let getModelTypeList = async () => {
|
||||
let res = await ModelApi.modelTypeList()
|
||||
if (res.code == 200) {
|
||||
modelTypes.value = res.data
|
||||
}
|
||||
}
|
||||
let getGraphTypeList = async () => {
|
||||
let res = await GraphApi.modelTypeList()
|
||||
if (res.code == 200) {
|
||||
graphTypes.value = res.data
|
||||
}
|
||||
}
|
||||
// 添加标绘
|
||||
let addMarker = (item) => {
|
||||
console.log("绘制" + item.name)
|
||||
window.draw = new YJ.Draw[item.funName](earth_ts)
|
||||
window.draw.start((a, position) => {
|
||||
console.log(position)
|
||||
addMapSource({id: 777, type: item.type, name: item.source_name, position})
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -151,10 +176,8 @@ const handleNodeClick = (data: Tree) => {
|
||||
z-index: 99;
|
||||
top: 13.4259259259vh;
|
||||
left: 1.5625vw;
|
||||
border: 0.078125vw solid rgb(var(--color-base1));
|
||||
background:
|
||||
linear-gradient(180deg, rgba(var(--color-base1), 0.2) 0%, rgba(var(--color-base1), 0) 100%),
|
||||
rgba(0, 0, 0, 0.5);
|
||||
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);
|
||||
color: #fff;
|
||||
padding: 0 5px;
|
||||
//display: flex;
|
||||
@ -184,7 +207,7 @@ const handleNodeClick = (data: Tree) => {
|
||||
}
|
||||
|
||||
.active {
|
||||
border-bottom: 2px solid rgba(var(--color-base1), 1);
|
||||
border-bottom: 2px solid #0ff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,12 +219,22 @@ const handleNodeClick = (data: Tree) => {
|
||||
|
||||
.treeOrList {
|
||||
//flex: auto;
|
||||
height: calc(100% - 300px);
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
.el-tree {
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.markerItem {
|
||||
cursor: pointer;
|
||||
padding-left: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 255, 255, 0.38);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,21 +242,54 @@ const handleNodeClick = (data: Tree) => {
|
||||
border: 1px solid #eee;
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
|
||||
.itemBox {
|
||||
//border: 1px solid red;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
white-space: normal; /* 允许文本换行(默认值,但需确保未被覆盖) */
|
||||
word-break: break-all;
|
||||
|
||||
.imgbg {
|
||||
width: 80px;
|
||||
height: 79px;
|
||||
margin: 0 auto;
|
||||
background: url("../../assets/images/model-bg.png") no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: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>.el-tree-node__expand-icon) {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node__content:hover ) {
|
||||
--el-tree-node-hover-bg-color: rgba(var(--color-base1), 0.38);
|
||||
--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;
|
||||
|
||||
/* &:hover {
|
||||
@ -236,11 +302,12 @@ const handleNodeClick = (data: Tree) => {
|
||||
}
|
||||
|
||||
:deep(.el-tree-node.is-current ) {
|
||||
|
||||
& > .el-tree-node__content {
|
||||
background: linear-gradient(90deg, rgba(var(--color-base1), 0.5) 0%, rgba(var(--color-base1), 0) 100%);
|
||||
background: linear-gradient(90deg, rgba(0, 255, 255, 0.5) 0%, rgba(0, 255, 255, 0) 100%);
|
||||
|
||||
& > .el-tree-node__label {
|
||||
color: rgba(var(--color-base1), 1);
|
||||
color: #0ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
src/renderer/src/views/TS/entity.ts
Normal file
28
src/renderer/src/views/TS/entity.ts
Normal file
@ -0,0 +1,28 @@
|
||||
export function addMapSource(option) {
|
||||
console.log("添加到地球上", option)
|
||||
let id = option.id || new YJ.Tools().randomString()
|
||||
let name = option.name
|
||||
let entityObject
|
||||
let options
|
||||
let baseURL = localStorage.getItem('ip')
|
||||
switch (option.type) {
|
||||
case 'point':
|
||||
console.log({id, name, position: option.position})
|
||||
entityObject = new YJ.Obj.BillboardObject(window['earth_ts'], {id, name, position: option.position})
|
||||
console.log("添加dian")
|
||||
break;
|
||||
}
|
||||
|
||||
if (entityObject) {
|
||||
function getOptions() {
|
||||
let opt = structuredClone(entityObject.options)
|
||||
delete opt.host
|
||||
return opt
|
||||
}
|
||||
|
||||
options = getOptions()
|
||||
}
|
||||
console.log('options', options)
|
||||
// 进数据库
|
||||
// 上树
|
||||
}
|
||||
@ -16,25 +16,19 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="search">
|
||||
<span
|
||||
>推演名称
|
||||
<el-input
|
||||
<span>推演名称 <el-input
|
||||
v-model="searchParams.name"
|
||||
style="width: 240px"
|
||||
placeholder="请输入推演名称"
|
||||
clearable
|
||||
/></span>
|
||||
<span
|
||||
>创建人
|
||||
<el-input
|
||||
v-model="searchParams.create_by"
|
||||
<span>创建人 <el-input
|
||||
v-model="searchParams.createdBy"
|
||||
style="width: 240px"
|
||||
placeholder="请输入创建人姓名"
|
||||
clearable
|
||||
/></span>
|
||||
<span
|
||||
>创建时间
|
||||
<el-date-picker
|
||||
<span>创建时间 <el-date-picker
|
||||
v-model="searchParams.datetime"
|
||||
type="datetimerange"
|
||||
start-placeholder="开始日期"
|
||||
@ -42,13 +36,13 @@
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
date-format="YYYY-MM-DD ddd"
|
||||
time-format="A hh:mm:ss"
|
||||
value-format="x"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/></span>
|
||||
<el-button @click="search">搜索</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</div>
|
||||
<div class="option">
|
||||
<el-button :icon="CirclePlus">新建推演</el-button>
|
||||
<el-button :icon="CirclePlus" @click="addPlan">新建推演</el-button>
|
||||
<el-button :icon="Download">导入</el-button>
|
||||
<el-button :icon="Upload">导出</el-button>
|
||||
</div>
|
||||
@ -59,15 +53,26 @@
|
||||
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="desc" label="推演描述"/>
|
||||
<el-table-column align="center" prop="createdBy" label="创建人"/>
|
||||
<el-table-column align="center" prop="createdAt" 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(scope.row)">编辑</el-button>
|
||||
<el-popconfirm
|
||||
confirm-button-text="确定"
|
||||
cancel-button-text="取消"
|
||||
icon-color="#626AEF"
|
||||
title="确定删除吗?"
|
||||
@confirm="delPlan(scope.row.id)"
|
||||
>
|
||||
<el-button text size="small" type="primary" :icon="Delete">删除</el-button>
|
||||
<template #reference>
|
||||
<el-button text size="small" type="primary" :icon="Delete">删除
|
||||
</el-button>
|
||||
|
||||
<!--<el-button>Delete</el-button>-->
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -94,23 +99,26 @@
|
||||
</el-pagination>
|
||||
</div>-->
|
||||
</div>
|
||||
<NewPlan @addCallback="getList(searchParams.value)"></NewPlan>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
//@ts-nocheck
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
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 {ElMessage, TableV2SortOrder} from 'element-plus'
|
||||
import type {SortBy} from 'element-plus'
|
||||
import {TsApi} from "../../api/ts";
|
||||
import NewPlan from "./newPlan.vue"
|
||||
|
||||
const eventBus: any = inject('bus')
|
||||
const {ipcRenderer} = require('electron')
|
||||
const router = useRouter()
|
||||
let searchParams = ref({
|
||||
name: '',
|
||||
create_by: '',
|
||||
datetime: ''
|
||||
name: "",
|
||||
createdBy: "",
|
||||
datetime: "",
|
||||
})
|
||||
|
||||
let pageSize = ref(5)
|
||||
@ -122,49 +130,72 @@ const back = () => {
|
||||
}
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize = val
|
||||
getList()
|
||||
getList();
|
||||
}
|
||||
const handleCurrentChange = (val) => {
|
||||
pageNum = val
|
||||
getList();
|
||||
}
|
||||
const getList = (params = null) => {
|
||||
console.log(params)
|
||||
let formData = new FormData()
|
||||
formData.append('pageSize', pageSize.value)
|
||||
formData.append('pageNum', pageNum.value)
|
||||
if (params) {
|
||||
for (const paramsKey in params) {
|
||||
if (params[paramsKey]) {
|
||||
if (paramsKey == 'datetime') {
|
||||
formData.append('startTime', params[paramsKey][0])
|
||||
formData.append('endTime', params[paramsKey][1])
|
||||
} else {
|
||||
formData.append(paramsKey, params[paramsKey])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TsApi.planList(formData).then(res => {
|
||||
console.log(res)
|
||||
if (res.code == 200) {
|
||||
tableData.value = res.data.records
|
||||
}
|
||||
})
|
||||
}
|
||||
getList()
|
||||
}
|
||||
const getList = () => {
|
||||
console.log(pageSize, pageNum)
|
||||
}
|
||||
const tableData: User[] = [
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '测试',
|
||||
description: '这是一个方案描述',
|
||||
create_by: 'admin'
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '协同方案',
|
||||
description: '这是一个方案描述',
|
||||
create_by: 'admin'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '1990',
|
||||
description: '这是一个方案描述',
|
||||
create_by: 'admin'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '2025',
|
||||
description: '这是一个方案描述',
|
||||
create_by: 'admin'
|
||||
}
|
||||
]
|
||||
const tableData = ref([])
|
||||
const search = () => {
|
||||
console.log(searchParams)
|
||||
getList(searchParams.value)
|
||||
}
|
||||
const reset = () => {
|
||||
searchParams.value = { name: '', create_by: '', datetime: '' }
|
||||
searchParams.value = {name: "", createdBy: "", datetime: ""}
|
||||
getList(searchParams.value)
|
||||
}
|
||||
const toTSEdit = () => {
|
||||
router.push({ path: '/tsEdit' })
|
||||
const toTSEdit = (row) => {
|
||||
// router.push({path: '/tsEdit'})
|
||||
console.log("当前推演方案", row)
|
||||
router.push({
|
||||
name: 'tsEdit', // 必须用 name 匹配路由,不能用 path
|
||||
query: {id: 123, name: "战时推演", start_time: 946684800000}
|
||||
})
|
||||
}
|
||||
const delPlan = (id) => {
|
||||
|
||||
let formData = new FormData()
|
||||
formData.append('id', id)
|
||||
TsApi.delPlan(formData).then(res => {
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '操作成功!',
|
||||
type: 'success'
|
||||
})
|
||||
getList(searchParams.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
const addPlan = () => {
|
||||
// $(".newPlan")[0].style.display = 'block'
|
||||
// $(".el-overlay")[0].style.display = 'block'
|
||||
eventBus.emit('openAddPlan', true)
|
||||
}
|
||||
/*
|
||||
const generateData = (
|
||||
@ -211,8 +242,10 @@ 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;
|
||||
@ -224,7 +257,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;
|
||||
@ -250,7 +283,7 @@ const onSort = (sortBy: SortBy) => {
|
||||
}
|
||||
|
||||
.list-container {
|
||||
border: 1px solid rgba(var(--color-base1), 1);
|
||||
border: 1px solid #0ff;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
@ -259,11 +292,8 @@ const onSort = (sortBy: SortBy) => {
|
||||
height: 72vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(var(--color-base1), 0.2) 0%, rgba(var(--color-base1), 0) 100%),
|
||||
rgba(0, 0, 0, 0.6);
|
||||
border-image: linear-gradient(137.95deg, rgba(var(--color-base1), 1) 6.25%, var(--color-border1) 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 {
|
||||
@ -309,17 +339,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 ) {
|
||||
background-color: rgba(var(--color-base1), 0.2);
|
||||
background-color: rgba(0, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
:deep(.el-button) {
|
||||
@ -327,19 +356,17 @@ const onSort = (sortBy: SortBy) => {
|
||||
}
|
||||
|
||||
:deep(.el-button:not(.is-text)) {
|
||||
border: 1px solid rgba(var(--color-base1), 1);
|
||||
background: rgba(var(--color-base1), 0.2);
|
||||
border: 1px solid #0ff;
|
||||
background: rgba(0, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
:deep(.el-button:hover) {
|
||||
color: rgba(var(--color-base1), 1);
|
||||
color: #0ff;
|
||||
//background-color: transparent !important;
|
||||
background: rgba(var(--color-base1), 0.2) !important;
|
||||
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;
|
||||
@ -374,6 +401,6 @@ background-color: transparent;
|
||||
}
|
||||
|
||||
:deep(.el-table-v2__header-wrapper) {
|
||||
background-color: rgba(var(--color-base1), 0.2);
|
||||
background-color: rgba(0, 255, 255, 0.2);
|
||||
}*/
|
||||
</style>
|
||||
325
src/renderer/src/views/TS/newEvent.vue
Normal file
325
src/renderer/src/views/TS/newEvent.vue
Normal file
@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<div class="newEvent">
|
||||
<el-dialog v-model="isShowPup" :modal="true" draggable :close-on-click-modal="false">
|
||||
<template #header>
|
||||
<div class="set_pup_header">
|
||||
<div class="system_title">
|
||||
<!--{{ t('model.title') }}-->
|
||||
态势事件
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="set_detail">
|
||||
<div class="sort">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
style="max-width: 600px"
|
||||
:data="eventTree"
|
||||
:props="defaultProps"
|
||||
node-key="id"
|
||||
:check-on-click-node="true"
|
||||
@node-click="handleNodeClick"
|
||||
:default-expanded-keys="['normal']"
|
||||
:current-node-key="currentKey"
|
||||
:class="{'custom-tree': true}"
|
||||
/>
|
||||
</div>
|
||||
<div class="eventDetail">
|
||||
<template v-if="currentKey&¤tKey!='normal'">
|
||||
<el-form label-width="auto" :model="form" style="max-width: 600px">
|
||||
<el-form-item label="事件名称">
|
||||
<el-input v-model="form.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker
|
||||
v-model="form.datetime"
|
||||
type="datetime"
|
||||
placeholder="Select date and time"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="持续时间">
|
||||
<div class="duration">
|
||||
<span>
|
||||
<el-input v-model="hour"/>时
|
||||
</span>
|
||||
<span>
|
||||
<el-input v-model="minute"/>分
|
||||
</span><span>
|
||||
<el-input v-model="second"/>秒
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
</el-form-item>
|
||||
<template v-if="currentKey=='flicker'">
|
||||
<el-form-item label="闪烁间隔">
|
||||
<div class="duration">
|
||||
<span>
|
||||
<el-input v-model="times"/>秒
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="闪烁次数">
|
||||
<div class="duration">
|
||||
<span>
|
||||
<el-input v-model="numbers"/>次
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="currentKey=='move'">
|
||||
<el-form-item label="路径是否包含元素点位" label-width="160">
|
||||
<el-switch v-model="isContainModelPosition"/>
|
||||
</el-form-item>
|
||||
<el-button>绘制路径</el-button>
|
||||
</template>
|
||||
|
||||
|
||||
<el-form-item>
|
||||
<div class="optionbtn">
|
||||
<el-button>确定</el-button>
|
||||
<el-button>取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<div class="placeholder"></div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive} from "vue";
|
||||
import type {RenderContentContext, TreeInstance} from 'element-plus'
|
||||
|
||||
const treeRef = ref<TreeInstance>()
|
||||
// 存储当前需要高亮的节点 key(初始为空)
|
||||
const currentKey = ref<number | null>(1);
|
||||
|
||||
interface Tree {
|
||||
label: string
|
||||
children?: Tree[]
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
name: '',
|
||||
})
|
||||
const hour = ref(0)
|
||||
const minute = ref(0)
|
||||
const second = ref(0)
|
||||
const times = ref(0)//闪烁间隔
|
||||
const numbers = ref(0)//闪烁次数
|
||||
const isContainModelPosition = ref(true)
|
||||
|
||||
form['datetime'] = new Date(2000, 1, 1, 12, 0, 0)
|
||||
const isShowPup = ref(true)
|
||||
const eventTree: { children: ({ label: string } | { label: string })[]; id: string; label: string }[] = [
|
||||
{
|
||||
id: "normal",
|
||||
label: '常用推演事件',
|
||||
children: [
|
||||
{
|
||||
id: "flicker",
|
||||
label: '闪烁事件',
|
||||
},
|
||||
{
|
||||
id: "move",
|
||||
label: '机动事件',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
}
|
||||
const handleNodeClick = (data: Tree, node, TreeNode, event) => {
|
||||
currentKey.value = data.id; // data.id 为节点的唯一 key(需与 tree 的 node-key 对应)
|
||||
form.name = data.label
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.newEvent {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
//bottom: 200px;
|
||||
//left: 50%;
|
||||
//width: 40vw;
|
||||
//height: 50vh;
|
||||
display: none;
|
||||
|
||||
.set_detail {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
.sort {
|
||||
height: 100%;
|
||||
//width: 8vw;
|
||||
width: 150px;
|
||||
overflow-y: auto;
|
||||
|
||||
.el-tree {
|
||||
background: transparent !important;
|
||||
--el-tree-node-hover-bg-color: rgba(var(--color-sdk-base-rgb), 0.2) !important;
|
||||
color: rgba(255, 255, 255, 1) !important;
|
||||
/* font-size: 12px !important; */
|
||||
//width: 130px;
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.eventDetail {
|
||||
//flex: auto;
|
||||
width: calc(100% - 170px);
|
||||
overflow-y: auto;
|
||||
|
||||
:deep(.el-input ) {
|
||||
--el-date-editor-width: 100%;
|
||||
}
|
||||
|
||||
:deep(.el-button) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-button:not(.is-text)) {
|
||||
border: 1px solid #0ff;
|
||||
background: rgba(0, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
:deep(.el-button:hover) {
|
||||
color: #0ff;
|
||||
//background-color: transparent !important;
|
||||
background: rgba(0, 255, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
.duration {
|
||||
display: flex;
|
||||
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
|
||||
.el-input {
|
||||
width: 75%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.optionbtn {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog) {
|
||||
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
|
||||
rgba(0, 0, 0, 0.6);
|
||||
border: 1px solid #00c9ff;
|
||||
padding: 0 !important;
|
||||
width: 30vw;
|
||||
height: 30vh;
|
||||
|
||||
width: 570px;
|
||||
height: 323px;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0 !important;
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
:deep(.el-dialog__headerbtn) {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-bottom-left-radius: 80%;
|
||||
background-color: #008989;
|
||||
|
||||
&:hover {
|
||||
background-color: #00ffff;
|
||||
|
||||
.el-dialog__close {
|
||||
color: rgba(0, 66, 66, 1); // 悬停时改变关闭图标为红色
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__headerbtn .el-dialog__close) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.set_pup_header {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// background-color: #00ffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
//padding-bottom: 20px;
|
||||
|
||||
.system_title {
|
||||
background: url('@/assets/images/titlebg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 229px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
font-family: 'alimamashuheiti';
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
//font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: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__children .is-checked) {
|
||||
background: red;
|
||||
}
|
||||
*/
|
||||
/* 自定义高亮样式(替代默认的高亮) */
|
||||
.custom-tree {
|
||||
&:deep(.el-tree-node.is-current > .el-tree-node__content) {
|
||||
//background-color: #e6f7ff; /* 浅蓝色高亮,可自定义 */
|
||||
|
||||
}
|
||||
|
||||
&:deep(.el-tree-node.is-current > .el-tree-node__content>.el-tree-node__label ) {
|
||||
//background-color: #e6f7ff; /* 浅蓝色高亮,可自定义 */
|
||||
--el-text-color: #0ff !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
:deep(.el-text ) {
|
||||
--el-text-color: #fff !important;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
215
src/renderer/src/views/TS/newPlan.vue
Normal file
215
src/renderer/src/views/TS/newPlan.vue
Normal file
@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div class="newPlan">
|
||||
<el-dialog v-model="isShowPup" draggable :close-on-click-modal="false" :modal="true">
|
||||
<template #header>
|
||||
<div class="set_pup_header">
|
||||
<div class="system_title">
|
||||
<!--{{ t('model.title') }}-->
|
||||
新建推演
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="set_detail">
|
||||
<el-form
|
||||
style="max-width: 600px"
|
||||
:model="sizeForm"
|
||||
label-width="auto"
|
||||
:label-position="'top'"
|
||||
|
||||
>
|
||||
<el-form-item label="推演名称">
|
||||
<el-input v-model="sizeForm.name" placeholder="请填写名称"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="仿真开始时间">
|
||||
<el-date-picker
|
||||
v-model="sizeForm.date1"
|
||||
type="datetime"
|
||||
placeholder="请选择日期时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="推演描述" prop="desc">
|
||||
<el-input v-model="sizeForm.desc" type="textarea" placeholder="请输入内容描述"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div class="optionbtn">
|
||||
<el-button @click="addPlan">确定</el-button>
|
||||
<el-button>取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive,} from "vue";
|
||||
import {ElMessage} from 'element-plus'
|
||||
import {TsApi} from "../../api/ts";
|
||||
|
||||
const eventBus: any = inject('bus')
|
||||
const emit = defineEmits(['addCallback']);
|
||||
const isShowPup = ref(false)
|
||||
const sizeForm = reactive({
|
||||
name: '',
|
||||
// date1: '',
|
||||
desc: '',
|
||||
})
|
||||
const addPlan = () => {
|
||||
TsApi.addPlan({name: sizeForm.name, desc: sizeForm.desc}).then(res => {
|
||||
console.log(res)
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
emit('addCallback');
|
||||
}
|
||||
$(".newPlan")[0].style.display = "none"
|
||||
})
|
||||
}
|
||||
eventBus.on('openAddPlan', (data, cb, type) => {
|
||||
// selectCallback = cb
|
||||
// addType.value = type
|
||||
isShowPup.value = data
|
||||
// if (data) {
|
||||
// getModelList()
|
||||
// getSetting()
|
||||
// }
|
||||
})
|
||||
const close = () => {
|
||||
|
||||
isShowPup.value = false
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.newPlan {
|
||||
width: 40vw;
|
||||
height: 50vh;
|
||||
|
||||
:deep(.el-dialog) {
|
||||
background: linear-gradient(180deg, rgba(var(--color-base1), 0.2) 0%, rgba(var(--color-base1), 0) 100%),
|
||||
rgba(0, 0, 0, 0.6);
|
||||
border: 1px solid var(--color-border1);
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__headerbtn) {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-bottom-left-radius: 80%;
|
||||
background-color: rgba(var(--color-base1), 0.5);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(var(--color-base1), 1);
|
||||
|
||||
.el-dialog__close {
|
||||
color: rgba(0, 66, 66, 1); // 悬停时改变关闭图标为红色
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__headerbtn .el-dialog__close) {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.set_detail {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
:deep(.el-dialog) {
|
||||
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
|
||||
rgba(0, 0, 0, 0.6);
|
||||
border: 1px solid #00c9ff;
|
||||
padding: 0 !important;
|
||||
|
||||
|
||||
width: 380px;
|
||||
//height: 630px;
|
||||
height: 480px;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__headerbtn) {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-bottom-left-radius: 80%;
|
||||
background-color: #008989;
|
||||
|
||||
&:hover {
|
||||
background-color: #00ffff;
|
||||
|
||||
.el-dialog__close {
|
||||
color: rgba(0, 66, 66, 1); // 悬停时改变关闭图标为红色
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__headerbtn .el-dialog__close) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.set_pup_header {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// background-color: #00ffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
//padding-bottom: 20px;
|
||||
|
||||
.system_title {
|
||||
background: url('@/assets/images/titlebg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 229px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
font-family: 'alimamashuheiti';
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
//font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.optionbtn {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper), :deep(.el-input__inner ) {
|
||||
background: transparent;
|
||||
--el-input-placeholder-color: #fff;
|
||||
color: #fff;
|
||||
//border: 1px solid #0ff;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-input ) {
|
||||
--el-date-editor-width: 100%;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0 !important;
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
:deep(.el-textarea__inner) {
|
||||
height: 150px;
|
||||
}
|
||||
</style>
|
||||
60
src/renderer/src/views/TS/sdk/Clock.ts
Normal file
60
src/renderer/src/views/TS/sdk/Clock.ts
Normal file
@ -0,0 +1,60 @@
|
||||
export class Clock {
|
||||
_timer1
|
||||
_timer
|
||||
|
||||
constructor() {
|
||||
this._timer1 = null//
|
||||
this._timer = null//
|
||||
}
|
||||
|
||||
animation(store, eventCallback) {
|
||||
let multiplier = 1
|
||||
console.log("开始播放推演")
|
||||
//点击播放按钮时的时间戳
|
||||
let nowTime = Date.now()
|
||||
//每次循环的时间戳差异
|
||||
let diff = 0
|
||||
let timeStamp = 0
|
||||
eventCallback()//立即执行一次回调
|
||||
// 默认每秒执行一次回调(受倍数播放影响)
|
||||
this._timer1 = setInterval((function run() {
|
||||
setTimeout(() => {
|
||||
eventCallback()
|
||||
}, 1000 / multiplier)
|
||||
return run
|
||||
})(), 1000 / multiplier)
|
||||
//每毫米执行,
|
||||
this._timer = setInterval(() => {
|
||||
let now = Date.now()
|
||||
diff = (now - nowTime) * multiplier
|
||||
store._currentTimestamp += diff
|
||||
// 更新UI层的当前时间戳变量
|
||||
window['updateProp']('currentStamp', store._currentTimestamp)
|
||||
nowTime = now
|
||||
// 设置时间指示器位置
|
||||
store.setCursorLeft(store._currentTimestamp)
|
||||
|
||||
/*let now = Date.now()
|
||||
// a+=now-upTime
|
||||
diff = (now - nowTime) * multiplier
|
||||
|
||||
let num = (currentTimestamp += diff)
|
||||
for (let i = 0; i < (now - nowTime) * multiplier; i++) {
|
||||
timeStamp += 1
|
||||
}
|
||||
|
||||
// console.log((now-upTime)*multiplier)
|
||||
nowTime = now
|
||||
// cb(num, diff, timeStamp)*/
|
||||
|
||||
}, 1)
|
||||
}
|
||||
|
||||
stopAnimation() {
|
||||
// this.status=timeStatus.STOP
|
||||
|
||||
this._timer1 && clearInterval(this._timer1)
|
||||
|
||||
this._timer && clearInterval(this._timer)
|
||||
}
|
||||
}
|
||||
156
src/renderer/src/views/TS/sdk/Store.ts
Normal file
156
src/renderer/src/views/TS/sdk/Store.ts
Normal file
@ -0,0 +1,156 @@
|
||||
type ScaleKey = keyof Store['_scales']; // 提取_scales的属性键类型
|
||||
export class Store {
|
||||
|
||||
_scales = {
|
||||
fullWidth: 0,//总宽度
|
||||
fullHeight: 0,//总高度
|
||||
cellHeight: 32,//行高度
|
||||
scrollTop: 0,//面板竖向滚动位置
|
||||
scrollLeft: 0,//面板横向滚动位置
|
||||
cursorLeft: 0,//时间指示器
|
||||
ticTiny: 10,//小格数量
|
||||
distanceOfTicTinyRange: [6, 4, 5],//单个小格子的宽度可选值
|
||||
distanceOfTicTiny: 5, //单个小格子的宽度
|
||||
preMains: this.getPreMains(),// 时间线上大格之间的时间跨度的可选值
|
||||
preMainIndex: 6,//即为60s
|
||||
|
||||
ticMain: 10,//大格数量
|
||||
numOfMain: 30,// 多少小格为一大格子
|
||||
distanceOfTicMain: 30 * 5,//大格之间的距离
|
||||
|
||||
originMainOffset: 0,//起始大格偏移量
|
||||
originOffset: 0,//起始小格偏移量
|
||||
preSecondPx: 0,//一秒所占的宽度
|
||||
timeLabels: [], // 时间
|
||||
//竖向横线的数量,由面板高度和行高度决定
|
||||
hr: 0,
|
||||
//竖向横线的偏移量
|
||||
originHrOffset: 0,
|
||||
};
|
||||
_startTimestamp
|
||||
_currentTimestamp
|
||||
_tasks
|
||||
private _panelWidth //面板宽度
|
||||
|
||||
constructor(option) {
|
||||
this._panelWidth = option.panelWidth
|
||||
this._tasks = option.tasks
|
||||
this._startTimestamp = option.startTimestamp
|
||||
this._currentTimestamp = option.currentTimestamp || option.startTimestamp
|
||||
this._scales = {...this._scales, ...option.scales}
|
||||
let num = this.getScale("distanceOfTicMain") / this.getScale("preMains")[this.getScale("preMainIndex")]
|
||||
console.log(num)
|
||||
this._scales.preSecondPx = num
|
||||
// this.setScale("preSecondPx", num)
|
||||
}
|
||||
|
||||
init() {
|
||||
console.log("初始化:必要dom加载完成后,才能计算出某些值(刻度数量)")
|
||||
let dom = this.getDomElement(".timeScale", 0)
|
||||
if (dom instanceof Element) { // 缩小类型范围
|
||||
let panel = dom.getBoundingClientRect();// 安全调用
|
||||
// console.log(dom.getBoundingClientRect())
|
||||
this._panelWidth = Math.floor(panel.width);
|
||||
dom['style'].width = this._panelWidth + "px"
|
||||
this.setScale("ticTiny", this.ceil(this._panelWidth / this.getScale("distanceOfTicTiny")))
|
||||
this.setScale("ticMain", this.ceil(this._panelWidth / this.getScale("distanceOfTicMain")) + 1)
|
||||
|
||||
|
||||
// this.getMinTimeOfPanel()
|
||||
}
|
||||
let doms = this.getDomElement(".chart", 0)
|
||||
if (doms instanceof Element) {
|
||||
let height = doms.getBoundingClientRect().height
|
||||
this.setScale("hr", Math.floor(height / this._scales.cellHeight))
|
||||
}
|
||||
}
|
||||
|
||||
// 封装对_scales属性的访问器(getter)
|
||||
getScale(key: ScaleKey): any {
|
||||
return this._scales[key];
|
||||
}
|
||||
|
||||
// 封装对_scales属性的修改器(setter),在此处触发监听 tsObj._Store.setScale('ticTiny', 10);
|
||||
setScale(key: ScaleKey, value: any) {
|
||||
const oldValue = this._scales[key];
|
||||
if (oldValue === value) return; // 值未变化则不触发
|
||||
this._scales[key] = value;
|
||||
// 触发回调通知变化
|
||||
// console.log(`属性 ${key} 变化:${oldValue} → ${value}`);
|
||||
let val = value
|
||||
switch (key) {
|
||||
case "distanceOfTicMain":
|
||||
this.setScale("ticMain", this.ceil(this._panelWidth / val))
|
||||
break
|
||||
case "distanceOfTicTiny":
|
||||
// val = Math.ceil(this._panelWidth / value)
|
||||
// window['updateProp'](key, val)
|
||||
this.setScale("distanceOfTicMain", this._scales.numOfMain * this._scales.distanceOfTicTiny)
|
||||
this.setScale("ticTiny", this.ceil(this._panelWidth / val))
|
||||
window['tsObj'].renderLabel({left: this._scales.scrollLeft})
|
||||
break
|
||||
case "ticTiny":
|
||||
val = value
|
||||
|
||||
break
|
||||
case "ticMain":
|
||||
this._scales.timeLabels = this._scales.timeLabels.slice(0, this._scales.ticMain)
|
||||
break
|
||||
}
|
||||
window['updateProp'](key, val)
|
||||
}
|
||||
|
||||
getDomElement(selector, index = -1) {
|
||||
let selectors = '.ts-zyl ' + selector
|
||||
let doms = document.querySelectorAll(selectors)
|
||||
return index == -1 ? doms : doms[index]
|
||||
}
|
||||
|
||||
//面板占满所表示终点时间
|
||||
getMinTimeOfPanel() {
|
||||
// minTime=width*每秒所占宽度
|
||||
console.log(this._panelWidth / this._scales.preSecondPx)
|
||||
// return this._startTimestamp + parseInt(this._panelWidth / this._scales.preSecondPx) * 3000
|
||||
}
|
||||
|
||||
getPreMains() {
|
||||
let s = 1//一秒
|
||||
let m = 60 * s//一分
|
||||
let h = 60 * m//一小时
|
||||
let d = 24 * h//一天
|
||||
return [30 * s, 1 * m, 2 * m, 5 * m, 10 * m, 1 * h, 2 * h, 5 * h/*, 10 * h, 1 * d, 2 * d, 5 * d*/].reverse()
|
||||
}
|
||||
|
||||
ceil(num) {
|
||||
return Math.ceil(num)
|
||||
}
|
||||
|
||||
// 通过时间戳来设置位置
|
||||
setCursorLeft(stamp) {
|
||||
let newLeft = ((stamp - this._startTimestamp) / 1000) * this._scales.preSecondPx - this._scales.scrollLeft
|
||||
this.setScale('cursorLeft', newLeft)
|
||||
// console.log("newLeft", newLeft)
|
||||
}
|
||||
|
||||
dealData(key = "start_time", value = []) {
|
||||
let map = new Map()
|
||||
for (let j = 0; j < this._tasks.length; j++) {
|
||||
|
||||
let obj;
|
||||
if (value.length == 0) {
|
||||
obj = this._tasks[j]
|
||||
} else {
|
||||
let o = {}
|
||||
let key;
|
||||
value.forEach(item => {
|
||||
key = item
|
||||
o[key] = this._tasks[j][item]
|
||||
})
|
||||
obj = o
|
||||
}
|
||||
map.set(this._tasks[j][key] + "_" + this._tasks[j].id, obj)
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
}
|
||||
48
src/renderer/src/views/TS/sdk/Tools.ts
Normal file
48
src/renderer/src/views/TS/sdk/Tools.ts
Normal file
@ -0,0 +1,48 @@
|
||||
export class Tools {
|
||||
// 将时间戳转换为字符串
|
||||
parseTime(time, cFormat = '') {
|
||||
if (arguments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}.{M}";
|
||||
let date;
|
||||
if (typeof time === "object") {
|
||||
date = time;
|
||||
} else {
|
||||
if (("" + time).length === 10)
|
||||
time = parseInt(time) * 1000;
|
||||
date = new Date(time);
|
||||
}
|
||||
const formatObj = {
|
||||
y: date.getFullYear(),
|
||||
m: date.getMonth() + 1,
|
||||
d: date.getDate(),
|
||||
h: date.getHours(),
|
||||
i: date.getMinutes(),
|
||||
s: date.getSeconds(),
|
||||
M: date.getMilliseconds(),
|
||||
a: date.getDay()
|
||||
};
|
||||
const time_str = format.replace(/{(y|m|d|h|i|s|M|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key];
|
||||
if (key === "a")
|
||||
return ["一", "二", "三", "四", "五", "六", "日"][value - 1];
|
||||
if (result.length > 0 && value < 10) {
|
||||
value = "0" + value;
|
||||
}
|
||||
if (key === "M") {
|
||||
let letters = ""
|
||||
for (let i = 0; i < 3 - ("" + value).length; i++) {
|
||||
letters += "0";
|
||||
}
|
||||
value = letters + value;
|
||||
}
|
||||
return value || 0;
|
||||
});
|
||||
return time_str;
|
||||
}
|
||||
|
||||
test() {
|
||||
console.log("测试方法")
|
||||
}
|
||||
}
|
||||
74
src/renderer/src/views/TS/sdk/index.ts
Normal file
74
src/renderer/src/views/TS/sdk/index.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import {Tools} from "./Tools";
|
||||
|
||||
import {Store} from "./Store"
|
||||
import {Clock} from "./Clock"
|
||||
|
||||
export class TS extends Tools {
|
||||
private _Store: Store;
|
||||
private _Clock: Clock;
|
||||
private name;
|
||||
|
||||
constructor(option) {
|
||||
super();
|
||||
this._Store = new Store(option)
|
||||
this._Clock = new Clock()
|
||||
this.name = option.name
|
||||
this._Store._scales.fullHeight = this._Store._tasks.length * this._Store._scales.cellHeight
|
||||
|
||||
}
|
||||
|
||||
tuningLine() {
|
||||
let a = this._Store._scales.scrollLeft * -1
|
||||
this._Store.setScale("originMainOffset", a % this._Store._scales.distanceOfTicMain)
|
||||
this._Store.setScale("originOffset", a % this._Store._scales.distanceOfTicTiny)
|
||||
}
|
||||
|
||||
// 根据大格最大数,算出所有时间label
|
||||
renderLabel(obj) {
|
||||
let nums = Math.floor(obj.left / this._Store.getScale('distanceOfTicMain'))
|
||||
let all = this._Store.getScale('ticMain') + nums + 1
|
||||
console.log("renderLabel", nums)
|
||||
let allTimeLabels = []
|
||||
for (let i = 0; i < all; i++) {
|
||||
let timeOfMain = this._Store.getScale('preMains')[this._Store.getScale('preMainIndex')]
|
||||
// @ts-ignore
|
||||
allTimeLabels.push(i * timeOfMain * 1000 + this._Store._startTimestamp)
|
||||
}
|
||||
allTimeLabels.splice(0, nums)
|
||||
this._Store.setScale('timeLabels', allTimeLabels)
|
||||
}
|
||||
|
||||
initAction() {
|
||||
return (l) => {
|
||||
console.log("action的参数", l)
|
||||
const {action, obj, cb} = l
|
||||
switch (action) {
|
||||
|
||||
case "wheel-timeLine":
|
||||
const value = l.num
|
||||
// 第几个大格,小标-=1
|
||||
let num = Math.ceil(value / 3)
|
||||
// 小格宽度的选值,【3,5,8】
|
||||
let index = value % 3
|
||||
this._Store.setScale('preMainIndex', num - 1)
|
||||
this._Store.setScale('distanceOfTicTiny', this._Store.getScale("distanceOfTicTinyRange")[index])
|
||||
this._Store.setScale('preSecondPx', this._Store.getScale("distanceOfTicMain") / this._Store.getScale("preMains")[this._Store.getScale("preMainIndex")])
|
||||
|
||||
break;
|
||||
case "scroll-chart":
|
||||
this._Store._scales.scrollTop = obj.top
|
||||
this._Store.setScale('scrollLeft', obj.left)
|
||||
this.renderLabel(obj)
|
||||
if (obj.deltaX != 0) {
|
||||
this.tuningLine()
|
||||
}
|
||||
if (obj.deltaY != 0) {
|
||||
let cellHeight = this._Store._scales.cellHeight
|
||||
document.getElementsByClassName("grid-body")[0].scrollTop = obj.top
|
||||
this._Store.setScale('originHrOffset', obj.top - obj.top % cellHeight)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/renderer/src/views/TS/tree.ts
Normal file
57
src/renderer/src/views/TS/tree.ts
Normal file
@ -0,0 +1,57 @@
|
||||
export const showRightMenuTs = (event: any, treeObj: any, selectedNodes, nodeType) => {
|
||||
console.log("selectNodes", selectedNodes)
|
||||
let arr: any = []
|
||||
let rightMenuHeight = window.getComputedStyle($('#rMenuTs')[0]).getPropertyValue('height')
|
||||
let rightMenuWidth = window.getComputedStyle($('#rMenuTs')[0]).getPropertyValue('width')
|
||||
console.log("selectNodes", rightMenuHeight)
|
||||
console.log("selectNodes", rightMenuWidth)
|
||||
// 切割取得数字部分
|
||||
let getNumber = (string: any) => {
|
||||
return Number(string.replace('px', ''))
|
||||
}
|
||||
let x = Math.abs(event.clientX - $('.cabin')[0].getBoundingClientRect().left)
|
||||
let y = Math.abs(event.clientY - $('.cabin')[0].getBoundingClientRect().top)
|
||||
y += document.body.scrollTop + 20
|
||||
x += document.body.scrollLeft + 40
|
||||
const bodyWidth = $('body')?.width() || 0
|
||||
const bodyHeight = $('body')?.height() || 0
|
||||
if (event.screenX + getNumber(rightMenuWidth) + 40 > bodyWidth) {
|
||||
x =
|
||||
bodyWidth -
|
||||
getNumber(rightMenuWidth) -
|
||||
$('.cabin')[0].getBoundingClientRect().left
|
||||
}
|
||||
if (event.screenY + getNumber(rightMenuHeight) + 20 > bodyHeight) {
|
||||
y = (bodyHeight - $('.cabin')[0].getBoundingClientRect().top) / 2
|
||||
}
|
||||
|
||||
$('#rMenuTs').css({
|
||||
top: y + 'px',
|
||||
left: x + 'px',
|
||||
visibility: 'visible'
|
||||
})
|
||||
if (
|
||||
Object.prototype.toString.call(selectedNodes) === '[object Array]' &&
|
||||
selectedNodes.length > 1
|
||||
) {
|
||||
arr = ['del']
|
||||
} else {
|
||||
if (selectedNodes.length == 0) arr = ['addDirectory']
|
||||
else {
|
||||
try {
|
||||
arr = [...nodeType[selectedNodes[0].sourceType].rightMenus]
|
||||
console.log("rightMenus", nodeType[selectedNodes[0].sourceType].rightMenus)
|
||||
arr.push('addEvent')
|
||||
} catch (e) {
|
||||
console.log('e', e, selectedNodes[0].sourceType)
|
||||
arr = []
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = arr.length - 1; i >= 0; i--) {
|
||||
if (['pictureLocation', 'importPanorama'].includes(arr[i])) {
|
||||
arr.splice(i, 1); // 从索引 i 开始删除 1 个元素
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
@ -240,11 +240,29 @@ const poiImport = () => {
|
||||
path: path[0]
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
PoiApi.getPoiList().then((list) => {
|
||||
poiList.splice(0, poiList.length, ...list.data)
|
||||
//只有一个poi时默认启用
|
||||
if (poiList.length == 1) {
|
||||
|
||||
let formData = new FormData()
|
||||
formData.append('id', poiList[0].id)
|
||||
PoiApi.enablePoi(formData).then((res) => {
|
||||
if (res.code === 200) {
|
||||
ElMessage({
|
||||
message: '上传并启用成功',
|
||||
type: 'success'
|
||||
})
|
||||
getPoiList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
message: '上传成功',
|
||||
type: 'success'
|
||||
})
|
||||
getPoiList()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
<div class="seting_content">
|
||||
<!-- 语言设置 -->
|
||||
<div class="detailSkin">
|
||||
<span>{{ t('systemSetting.setLanguage') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.setLanguage') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.language"
|
||||
@ -22,7 +22,7 @@
|
||||
<!-- 主题色 -->
|
||||
<div class="detailSkin"></div>
|
||||
<div class="detailSkin">
|
||||
<span>{{ t('systemSetting.theme') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.theme') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.skinInfo"
|
||||
@ -48,7 +48,7 @@
|
||||
<div class="seting_content">
|
||||
<!-- 坐标系 -->
|
||||
<div class="detailSkin">
|
||||
<span>{{ t('systemSetting.coordinateSystem') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.coordinateSystem') }}</span>
|
||||
<!-- <el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.coordinate"
|
||||
@ -126,7 +126,7 @@
|
||||
</div>
|
||||
<div class="detailSkin"></div>
|
||||
<div class="detailSkin" v-show="showPosiType">
|
||||
<span>{{ t('systemSetting.latitude') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.latitude') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.positionType"
|
||||
@ -151,7 +151,7 @@
|
||||
</div>
|
||||
<div class="seting_content1">
|
||||
<div class="detailSkin1">
|
||||
<span>{{ t('systemSetting.lengthUnit') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.lengthUnit') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.coordinate"
|
||||
@ -169,7 +169,7 @@
|
||||
</div>
|
||||
<div class="detailSkin1"></div>
|
||||
<div class="detailSkin1">
|
||||
<span>{{ t('systemSetting.areaUnit') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.areaUnit') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.coordinate"
|
||||
@ -186,7 +186,7 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="detailSkin1">
|
||||
<span>{{ t('systemSetting.heightUnit') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.heightUnit') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.coordinate"
|
||||
@ -204,7 +204,7 @@
|
||||
</div>
|
||||
<div class="detailSkin1"></div>
|
||||
<div class="detailSkin1">
|
||||
<span>{{ t('systemSetting.speedUnit') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.speedUnit') }}</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="systemSetting.coordinate"
|
||||
@ -229,21 +229,21 @@
|
||||
</div>
|
||||
<div class="seting_switch">
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.defaultViewLabel') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.defaultViewLabel') }}</span>
|
||||
<el-button @click="setView"
|
||||
><svg-icon name="sitting" :size="12" style="margin-right: 5px"></svg-icon>
|
||||
{{ t('systemSetting.defaultView') }}</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.defaultDataLabel') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.defaultDataLabel') }}</span>
|
||||
<el-button color="#005c5c" @click="setData"
|
||||
><svg-icon name="add" :size="12" style="margin-right: 5px"></svg-icon
|
||||
>{{ t('systemSetting.defaultData') }}</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.management') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.management') }}</span>
|
||||
<el-button color="#005c5c" @click="intoBack"
|
||||
><svg-icon name="out_login" :size="12" style="margin-right: 5px"></svg-icon
|
||||
>{{ t('systemSetting.intoBack') }}</el-button
|
||||
@ -252,7 +252,7 @@
|
||||
</div>
|
||||
<div class="seting_content1">
|
||||
<div class="detailSkin1">
|
||||
<span>{{ t('searchWay.title') }}:</span>
|
||||
<span class="titleLabel">{{ t('searchWay.title') }}</span>
|
||||
<el-select
|
||||
style="width: 150px"
|
||||
v-model="searchWay"
|
||||
@ -270,7 +270,7 @@
|
||||
</div>
|
||||
<div class="detailSkin1"></div>
|
||||
<div class="detailSkin1">
|
||||
<span>{{ t('ConcurrencyControl') }}:</span>
|
||||
<span class="titleLabel">{{ t('ConcurrencyControl') }}</span>
|
||||
<el-select
|
||||
style="width: 150px"
|
||||
v-model="concurrentcode"
|
||||
@ -289,7 +289,7 @@
|
||||
</div>
|
||||
<div class="seting_switch">
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showCompass') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showCompass') }}</span>
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
v-model="systemSetting.showCompass"
|
||||
@ -301,7 +301,7 @@
|
||||
</el-switch>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showToolBar') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showToolBar') }}</span>
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
v-model="systemSetting.showToolBar"
|
||||
@ -313,7 +313,7 @@
|
||||
</el-switch>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showDistanceLegend') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showDistanceLegend') }}</span>
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
v-model="systemSetting.showDistanceLegend"
|
||||
@ -325,7 +325,7 @@
|
||||
</el-switch>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showMapX') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showMapX') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -339,7 +339,7 @@
|
||||
</div>
|
||||
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showFPS') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showFPS') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -353,7 +353,7 @@
|
||||
</div>
|
||||
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.administrativeArea') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.administrativeArea') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -367,7 +367,7 @@
|
||||
</div>
|
||||
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showLatitudeLongitudeNetwork') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showLatitudeLongitudeNetwork') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -380,7 +380,7 @@
|
||||
</el-switch>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.showFangliNet') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.showFangliNet') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -393,7 +393,7 @@
|
||||
</el-switch>
|
||||
</div>
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.sheetIndexStatusSwitch') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.sheetIndexStatusSwitch') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -407,7 +407,7 @@
|
||||
</div>
|
||||
|
||||
<div class="detailSkin2">
|
||||
<span>{{ t('systemSetting.occlusion') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.occlusion') }}</span>
|
||||
|
||||
<el-switch
|
||||
@change="sysChange"
|
||||
@ -421,7 +421,7 @@
|
||||
</div>
|
||||
|
||||
<div v-if="false" class="detailSkin2">
|
||||
<span>{{ t('systemSetting.battery') }}:</span>
|
||||
<span class="titleLabel">{{ t('systemSetting.battery') }}</span>
|
||||
<el-switch
|
||||
@change="batteryChange"
|
||||
v-model="showBattery"
|
||||
@ -790,4 +790,7 @@ onMounted(() => {
|
||||
.arrowActive {
|
||||
color: rgba(var(--color-base1), 1);
|
||||
}
|
||||
.titleLabel {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -515,7 +515,7 @@ var shadowChange = () => {
|
||||
margin-top: 4px;
|
||||
font-size: 12px !important;
|
||||
font-weight: 400 !important;
|
||||
line-height: 24px !important;
|
||||
line-height: 20px !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@ -597,4 +597,13 @@ var shadowChange = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 隐藏Webkit内核浏览器中的上下箭头及白色背景 */
|
||||
.input ::v-deep(input::-webkit-outer-spin-button),
|
||||
.input ::v-deep(input::-webkit-inner-spin-button) {
|
||||
-webkit-appearance: none !important;
|
||||
appearance: none !important;
|
||||
margin: 0;
|
||||
background: none; /* 移除白色背景 */
|
||||
display: none; /* 彻底隐藏元素 */
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,7 +3,12 @@
|
||||
<div class="head_box">
|
||||
<!-- <span class="head_title">实景三维电子沙盘系统</span> -->
|
||||
<!-- <headSvg style="width: 100%;height: 100%;"></headSvg> -->
|
||||
<img width="100%" height="100%" :src="headImg" alt="" />
|
||||
<img
|
||||
width="100%"
|
||||
height="100%"
|
||||
:src="`../../../src/assets/images/theme/${skinInfo}/head.png`"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div class="dateTime">
|
||||
<span>{{ date.hms }}</span>
|
||||
@ -12,7 +17,12 @@
|
||||
<span>{{ t(`week.4`) }}</span>
|
||||
</div>
|
||||
<div class="weather">
|
||||
<svg-icon name="weather" :size="40" @click="clickFun"></svg-icon>
|
||||
<svg-icon
|
||||
name="weatherBase"
|
||||
:class="weatherClick ? 'weatherIcon' : ''"
|
||||
:size="40"
|
||||
@click="clickFun"
|
||||
></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
<setTool ref="setToolRef"></setTool>
|
||||
@ -53,8 +63,7 @@ const headImg = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const skinInfo = ref(JSON.parse(localStorage.getItem("systemSetting") || '{}').skinInfo || 'color1')
|
||||
const skinInfo = ref(JSON.parse(localStorage.getItem('systemSetting') || '{}').skinInfo || 'color1')
|
||||
|
||||
const { t } = useI18n()
|
||||
const date = ref({
|
||||
@ -62,26 +71,25 @@ const date = ref({
|
||||
hms: '',
|
||||
week: 0
|
||||
})
|
||||
window.addEventListener("setItemEvent", (e: any) => {
|
||||
window.addEventListener('setItemEvent', (e: any) => {
|
||||
console.log('e', e)
|
||||
if (e.key == "systemSetting") {
|
||||
let obj = JSON.parse(e.newValue);
|
||||
skinInfo.value = obj.skinInfo;
|
||||
if (e.key == 'systemSetting') {
|
||||
let obj = JSON.parse(e.newValue)
|
||||
skinInfo.value = obj.skinInfo
|
||||
|
||||
let setting = JSON.parse(e.newValue)
|
||||
let dialogElm: any = document.getElementsByClassName('YJ-custom-base-dialog')
|
||||
if (setting.language === 'zh-EN') {
|
||||
for (let i = 0; i < dialogElm.length; i++) {
|
||||
dialogElm[i].classList.add('dialog-en');
|
||||
dialogElm[i].classList.add('dialog-en')
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (let i = 0; i < dialogElm.length; i++) {
|
||||
dialogElm[i].classList.remove('dialog-en');
|
||||
dialogElm[i].classList.remove('dialog-en')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
var weatherClick = ref(false)
|
||||
const setTime = () => {
|
||||
let date1 = new Date()
|
||||
@ -200,9 +208,12 @@ var clickFun = () => {
|
||||
|
||||
.weather {
|
||||
margin-left: 15px;
|
||||
.weatherIcon {
|
||||
fill: rgba(var(--color-base1), 1) !important;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: rgba(var(--color-base1), 1) !important;
|
||||
// fill: rgba(var(--color-base1), 1) !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,26 @@
|
||||
<template>
|
||||
<Dialog
|
||||
v-if="show"
|
||||
ref="baseDialog"
|
||||
title="物质统计"
|
||||
left="180px"
|
||||
top="100px"
|
||||
:closeCallback="closeCallBack"
|
||||
>
|
||||
<Dialog ref="baseDialog" title="物质统计" left="180px" top="100px" :closeCallback="closeCallBack">
|
||||
<template #content>
|
||||
<div id="goodSearchEchart" style="width: 100%; height: 100%"></div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button>绘制</button>
|
||||
<div id="goodSearchEchart" style="width: 650px; height: 400px"></div>
|
||||
</template>
|
||||
</Dialog>
|
||||
|
||||
<!-- <el-dialog
|
||||
v-model="show"
|
||||
title="物质统计"
|
||||
width="500"
|
||||
draggable
|
||||
:before-close="closeCallBack"
|
||||
:modal="false"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div id="goodSearchEchart" style="width: 300px; height: 200px"></div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button>绘制</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -22,32 +29,50 @@ import { inject } from 'vue'
|
||||
import { nextTick } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { MaterialApi } from '@/api/material/index'
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
const shpTotalDict: any = reactive({
|
||||
shlwz_jzzp: '救灾帐篷',
|
||||
mb: '棉被',
|
||||
mymdy: '棉衣、棉大衣',
|
||||
mjb: '毛巾被',
|
||||
mt: '毛毯',
|
||||
dgnsd: '睡袋',
|
||||
zdc: '折叠床',
|
||||
jycs: '简易厕所',
|
||||
xpct: '橡皮船(艇)',
|
||||
cfz: '冲锋舟',
|
||||
jsc: '救生船',
|
||||
jsy: '救生衣',
|
||||
jsq: '救生圈',
|
||||
bzd: '编织袋',
|
||||
md: '麻袋',
|
||||
csb: '抽水泵',
|
||||
fdj: '发电机',
|
||||
yjd: '应急灯',
|
||||
jzzp: '救灾帐篷',
|
||||
jzyb: '救灾衣被',
|
||||
jygj: '救援工具'
|
||||
const shpTotalDict: any = reactive(
|
||||
// {
|
||||
// shlwz_jzzp: '救灾帐篷',
|
||||
// mb: '棉被',
|
||||
// mymdy: '棉衣、棉大衣',
|
||||
// mjb: '毛巾被',
|
||||
// mt: '毛毯',
|
||||
// dgnsd: '睡袋',
|
||||
// zdc: '折叠床',
|
||||
// jycs: '简易厕所',
|
||||
// xpct: '橡皮船(艇)',
|
||||
// cfz: '冲锋舟',
|
||||
// jsc: '救生船',
|
||||
// jsy: '救生衣',
|
||||
// jsq: '救生圈',
|
||||
// bzd: '编织袋',
|
||||
// md: '麻袋',
|
||||
// csb: '抽水泵',
|
||||
// fdj: '发电机',
|
||||
// yjd: '应急灯',
|
||||
// jzzp: '救灾帐篷',
|
||||
// jzyb: '救灾衣被',
|
||||
// jygj: '救援工具'
|
||||
// }
|
||||
[]
|
||||
)
|
||||
|
||||
//获取物资类型
|
||||
const getResource = () => {
|
||||
let formData = new FormData()
|
||||
formData.append('pageNum', 1)
|
||||
formData.append('pageSize', 10000)
|
||||
formData.append('name', '')
|
||||
MaterialApi.getList(formData).then((res) => {
|
||||
shpTotalDict = res.data.data.map((item) => {
|
||||
return item.name
|
||||
})
|
||||
})
|
||||
}
|
||||
getResource()
|
||||
|
||||
var draw: any = reactive([])
|
||||
|
||||
@ -56,11 +81,10 @@ eventBus.on('goodsSearchCircleDialog', () => {
|
||||
// baseDialog.value?.open()
|
||||
draw = new YJ.Draw.DrawCircle(window.earth)
|
||||
draw.start((err, positions) => {
|
||||
console.log('err, positions', err, positions)
|
||||
if (!err && positions.center.lng) {
|
||||
show.value = true
|
||||
// show.value = true
|
||||
baseDialog.value?.open()
|
||||
let nodes = booleanOverlaps(positions)
|
||||
console.log('goodsSearchCircle', nodes)
|
||||
renderCanvas(nodes)
|
||||
}
|
||||
})
|
||||
@ -69,11 +93,10 @@ eventBus.on('goodsSearchCircleDialog', () => {
|
||||
const open = () => {
|
||||
draw = new YJ.Draw.DrawCircle(window.earth)
|
||||
draw.start((err, positions) => {
|
||||
console.log('err, positions', err, positions)
|
||||
if (!err && positions.center.lng) {
|
||||
show.value = true
|
||||
// show.value = true
|
||||
baseDialog.value?.open()
|
||||
let nodes = booleanOverlaps(positions)
|
||||
console.log('goodsSearchCircle', nodes)
|
||||
renderCanvas(nodes)
|
||||
}
|
||||
})
|
||||
@ -95,17 +118,14 @@ function booleanOverlaps(positions1, flag = 'circle') {
|
||||
let res = []
|
||||
types.forEach((type) => {
|
||||
let nodes = treeObj.getNodesByParam('sourceType', type, null)
|
||||
// console.log("nodes",nodes)
|
||||
res = res.concat(nodes)
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
//绘制的区域
|
||||
// console.log("[set3Array(positions1)]", [set3Array(positions1)])
|
||||
// 获取物资处(特定的标注类型)
|
||||
let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
|
||||
console.log('allNodes', allNodes)
|
||||
let itemInArea: any = [] //区域内的类型符合的标注
|
||||
|
||||
for (let i = 0; i < allNodes.length; i++) {
|
||||
@ -113,7 +133,7 @@ function booleanOverlaps(positions1, flag = 'circle') {
|
||||
let getAllItemInArea = (lng, lat) => {
|
||||
if (flag == 'circle') {
|
||||
let { center, radius } = positions1
|
||||
let distance = new YJ.Tools().randomString(center, { lng, lat })
|
||||
let distance = new YJ.Tools().pointDistance(center, { lng, lat })
|
||||
distance < radius && itemInArea.push(item)
|
||||
} else {
|
||||
let polygon1 = (window as any).turf.polygon([set3Array(positions1)])
|
||||
@ -121,13 +141,11 @@ function booleanOverlaps(positions1, flag = 'circle') {
|
||||
;(window as any).turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
|
||||
}
|
||||
}
|
||||
console.log(item, item.sourceType, 'ooooo')
|
||||
switch (item.sourceType) {
|
||||
case 'point':
|
||||
case 'vr':
|
||||
case 'picture':
|
||||
let params = JSON.parse(item.params)
|
||||
console.log('params', params)
|
||||
let lng = params.position.lng
|
||||
let lat = params.position.lat
|
||||
getAllItemInArea(lng, lat)
|
||||
@ -144,8 +162,6 @@ function booleanOverlaps(positions1, flag = 'circle') {
|
||||
return itemInArea
|
||||
}
|
||||
function renderCanvas(nodes) {
|
||||
console.log('nodes', nodes)
|
||||
|
||||
let x: any = []
|
||||
let y: any = []
|
||||
nodes.forEach((item) => {
|
||||
@ -154,8 +170,10 @@ function renderCanvas(nodes) {
|
||||
let obj = JSON.parse(JSON.stringify(item.detail.properties))
|
||||
for (const key in obj) {
|
||||
let name = key
|
||||
if (shpTotalDict[key]) {
|
||||
name = shpTotalDict[key]
|
||||
// if (shpTotalDict[key]) {
|
||||
// name = shpTotalDict[key]
|
||||
if (shpTotalDict.indexOf(key) != -1) {
|
||||
name = key
|
||||
// 把相同名称的物资数量相加,名称相同时,累加数据
|
||||
let index = x.findIndex((item) => item === name)
|
||||
if (index !== -1) {
|
||||
@ -170,7 +188,6 @@ function renderCanvas(nodes) {
|
||||
let params = JSON.parse(item.params)
|
||||
if (params.attribute && params.attribute.goods) {
|
||||
let goods = params.attribute.goods.content
|
||||
console.log('goods', goods)
|
||||
if (goods.length) {
|
||||
// $root_home_index.goodSearchDialog = false;
|
||||
goods.forEach((good) => {
|
||||
@ -187,9 +204,6 @@ function renderCanvas(nodes) {
|
||||
}
|
||||
})
|
||||
|
||||
console.log('x,y')
|
||||
console.log(x)
|
||||
console.log(y)
|
||||
let notZeroX: any = []
|
||||
let notZeroY: any = []
|
||||
for (let i = 0; i < y.length; i++) {
|
||||
@ -198,12 +212,10 @@ function renderCanvas(nodes) {
|
||||
notZeroY.push(y[i])
|
||||
}
|
||||
}
|
||||
console.log(notZeroX)
|
||||
console.log(notZeroY)
|
||||
x = notZeroX
|
||||
y = notZeroY
|
||||
if (!x.length) show.value = false
|
||||
if (show.value) {
|
||||
if (!x.length) baseDialog.value?.close()
|
||||
if (x.length) {
|
||||
nextTick(() => {
|
||||
let option: any = {
|
||||
grid: {
|
||||
|
||||
@ -1,17 +1,7 @@
|
||||
<template>
|
||||
<Dialog
|
||||
v-if="show"
|
||||
ref="baseDialog"
|
||||
title="物质统计"
|
||||
left="180px"
|
||||
top="100px"
|
||||
:closeCallback="closeCallBack"
|
||||
>
|
||||
<Dialog ref="baseDialog" title="物质统计" left="180px" top="100px" :closeCallback="closeCallBack">
|
||||
<template #content>
|
||||
<div id="goodSearchEchart2" style="width: 100%; height: 100%"></div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button>绘制</button>
|
||||
<div id="goodSearchEchart2" style="width: 650px; height: 400px"></div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
@ -56,7 +46,8 @@ eventBus.on('goodsSearchPolgonDialog', () => {
|
||||
draw = new YJ.Draw.DrawPolygon(window.earth)
|
||||
draw.start((err, params) => {
|
||||
if (!err && params.length > 2) {
|
||||
show.value = true
|
||||
// show.value = true
|
||||
baseDialog.value?.open()
|
||||
let nodes = booleanOverlaps(params, 'polygon')
|
||||
renderCanvas(nodes)
|
||||
}
|
||||
@ -67,7 +58,8 @@ const open = () => {
|
||||
draw = new YJ.Draw.DrawPolygon(window.earth)
|
||||
draw.start((err, params) => {
|
||||
if (!err && params.length > 2) {
|
||||
show.value = true
|
||||
// show.value = true
|
||||
baseDialog.value?.open()
|
||||
let nodes = booleanOverlaps(params, 'polygon')
|
||||
renderCanvas(nodes)
|
||||
}
|
||||
@ -174,9 +166,6 @@ function renderCanvas(nodes) {
|
||||
}
|
||||
})
|
||||
|
||||
console.log('x,y')
|
||||
console.log(x)
|
||||
console.log(y)
|
||||
let notZeroX: any = []
|
||||
let notZeroY: any = []
|
||||
for (let i = 0; i < y.length; i++) {
|
||||
@ -185,12 +174,10 @@ function renderCanvas(nodes) {
|
||||
notZeroY.push(y[i])
|
||||
}
|
||||
}
|
||||
console.log(notZeroX)
|
||||
console.log(notZeroY)
|
||||
x = notZeroX
|
||||
y = notZeroY
|
||||
if (!x.length) show.value = false
|
||||
if (show.value) {
|
||||
if (!x.length) baseDialog.value?.close()
|
||||
if (x.length) {
|
||||
nextTick(() => {
|
||||
let option: any = {
|
||||
grid: {
|
||||
|
||||
@ -7,6 +7,7 @@ import { GisApi } from '@/api/gisApi'
|
||||
import {addMapSource} from '@/common/addMapSource'
|
||||
import {getNamefromPath} from '@/utils/index'
|
||||
import {renderVector} from './renderVector'
|
||||
|
||||
const {cusAddNodes} = useTreeNode()
|
||||
|
||||
export const useRightOperate = () => {
|
||||
@ -32,8 +33,7 @@ export const useRightOperate = () => {
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
@ -49,10 +49,6 @@ export const useRightOperate = () => {
|
||||
if (typeof filePaths[0] !== 'string' || filePaths[0].trim() === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let item = filePaths[0]
|
||||
|
||||
//@ts-ignore
|
||||
@ -103,8 +99,7 @@ export const useRightOperate = () => {
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
let entityObject = renderVector(params, true);
|
||||
(window as any)._entityMap.set(id, entityObject)
|
||||
}
|
||||
else if (["geojson"].includes(sourceType)) {
|
||||
} else if (["geojson"].includes(sourceType)) {
|
||||
let baseURL = localStorage.getItem('ip')
|
||||
await addMapSource({
|
||||
type: 'geojson',
|
||||
@ -119,8 +114,7 @@ export const useRightOperate = () => {
|
||||
color: "rgb(239, 6, 6, 1)",
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 获取最后一个点的位置
|
||||
const lastDotIndex = filePaths[0].lastIndexOf('.');
|
||||
|
||||
@ -170,7 +164,8 @@ export const useRightOperate = () => {
|
||||
await initMapData(res.data.sourceType, mapParams, (entity) => {
|
||||
entity.flyTo()
|
||||
})
|
||||
if (res.data.sourceType) { }
|
||||
if (res.data.sourceType) {
|
||||
}
|
||||
|
||||
res.data.params = JSON.stringify(res.data.params)
|
||||
res.data.detail = JSON.stringify(res.data.detail)
|
||||
@ -188,8 +183,7 @@ export const useRightOperate = () => {
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
@ -211,8 +205,7 @@ export const useRightOperate = () => {
|
||||
const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
const dataTransfer = new DataTransfer();
|
||||
handleFileImgInput(files, parentId, 'vrImage')
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = '.jpg'
|
||||
@ -232,8 +225,7 @@ export const useRightOperate = () => {
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
@ -255,8 +247,7 @@ export const useRightOperate = () => {
|
||||
const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
const dataTransfer = new DataTransfer();
|
||||
handleFileImgInput(files, parentId, 'linkImage')
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = '.jpg'
|
||||
@ -332,9 +323,11 @@ export const useRightOperate = () => {
|
||||
});
|
||||
}
|
||||
//导入模型
|
||||
const addXlsxs = () => { }
|
||||
const addXlsxs = () => {
|
||||
}
|
||||
//导入模型
|
||||
const addTrajectory = () => { }
|
||||
const addTrajectory = () => {
|
||||
}
|
||||
//编辑
|
||||
const editNode = (eventBus, node) => {
|
||||
if (!node) {
|
||||
@ -390,11 +383,14 @@ export const useRightOperate = () => {
|
||||
})
|
||||
}
|
||||
//添加BIM
|
||||
const addBIM = () => { }
|
||||
const addBIM = () => {
|
||||
}
|
||||
//重置透视
|
||||
const resetPerspective = () => { }
|
||||
const resetPerspective = () => {
|
||||
}
|
||||
|
||||
const pressModel = () => { }
|
||||
const pressModel = () => {
|
||||
}
|
||||
|
||||
//设置视图
|
||||
const setView = () => {
|
||||
@ -463,7 +459,8 @@ export const useRightOperate = () => {
|
||||
layerIndex("layerToBottom");
|
||||
}
|
||||
//切片
|
||||
const tilesetClipping = () => { }
|
||||
const tilesetClipping = () => {
|
||||
}
|
||||
const rightMenus: any = reactive({
|
||||
addDirectory: {
|
||||
key: 'addDirectory',
|
||||
@ -686,7 +683,6 @@ export const useRightOperate = () => {
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getLastPathComponent(path, extensionsToRemove = []) {
|
||||
// 处理路径分隔符
|
||||
const normalizedPath = path.replace(/\\/g, '/');
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import {renderMethods} from "./renderTreeNode";
|
||||
|
||||
const {ipcRenderer, BrowserWindow} = require('electron')
|
||||
export const useTreeNode = () => {
|
||||
//定义树形节点的属性
|
||||
@ -168,6 +169,12 @@ export const useTreeNode = () => {
|
||||
// detailFun: get_detail_layer,
|
||||
// allowChildren: false,
|
||||
},
|
||||
picture: {
|
||||
rightMenus: ['edit', 'del']
|
||||
// render: renderPicture,
|
||||
// detailFun: get_detail_picture,
|
||||
// allowChildren: false,
|
||||
},
|
||||
model: {
|
||||
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
||||
// detailFun: get_detail_glb,
|
||||
@ -260,22 +267,22 @@ export const useTreeNode = () => {
|
||||
// detailFun: get_detail_czml,
|
||||
// allowChildren: true,
|
||||
},
|
||||
arcgisWximagery: {
|
||||
ArcgisWXImagery: {
|
||||
// render: renderArcgisWXImagery,
|
||||
rightMenus: ['edit', 'del', 'layerRaise', 'layerLower', 'layerToTop', 'layerToBottom']
|
||||
// detailFun: get_detail_null,
|
||||
},
|
||||
arcgisBlueImagery: {
|
||||
ArcgisBLUEImagery: {
|
||||
// render: renderArcgisBLUEImagery,
|
||||
rightMenus: ['edit', 'del', 'layerRaise', 'layerLower', 'layerToTop', 'layerToBottom']
|
||||
// detailFun: get_detail_null,
|
||||
},
|
||||
gdlwImagery: {
|
||||
GDLWImagery: {
|
||||
// render: renderGDLWImagery,
|
||||
rightMenus: ['edit', 'del', 'layerRaise', 'layerLower', 'layerToTop', 'layerToBottom']
|
||||
// detailFun: get_detail_null,
|
||||
},
|
||||
gdslImagery: {
|
||||
GDSLImagery: {
|
||||
// render: renderGDSLImagery,
|
||||
rightMenus: ['edit', 'del', 'layerRaise', 'layerLower', 'layerToTop', 'layerToBottom']
|
||||
// detailFun: get_detail_null,
|
||||
@ -401,17 +408,6 @@ export const useTreeNode = () => {
|
||||
// render: renderFlyLine,
|
||||
// detailFun: get_detail_flyLine,
|
||||
// allowChildren: false,
|
||||
},
|
||||
folder: {
|
||||
rightMenus: [
|
||||
'edit',
|
||||
'del',
|
||||
'setView',
|
||||
'resetView'
|
||||
]
|
||||
// render: renderFlyLine,
|
||||
// detailFun: get_detail_flyLine,
|
||||
// allowChildren: false,
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -462,34 +458,22 @@ export const useTreeNode = () => {
|
||||
// 提取后缀并转换为小写进行比较
|
||||
const extension = path.slice(lastDotIndex + 1).toLowerCase();
|
||||
type = extension
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
type = node.sourceType || node.type;
|
||||
}
|
||||
console.log("----------", type);
|
||||
let name = [
|
||||
"gdslImagery",
|
||||
"gdlwImagery",
|
||||
"arcgisBlueImagery",
|
||||
"arcgisWximagery",
|
||||
"GDSLImagery",
|
||||
"GDLWImagery",
|
||||
"ArcgisBLUEImagery",
|
||||
"ArcgisWXImagery",
|
||||
].includes(type)
|
||||
? "layer"
|
||||
: type;
|
||||
if (type == "Terrain") name = "terrain";
|
||||
if (type == "road" && node.detail.imageType == "arrowRoad")
|
||||
name = "lineDrawing";
|
||||
|
||||
let strokeWidth = 0.1
|
||||
if (type === 'ellipse') {
|
||||
strokeWidth = 1.5;
|
||||
}
|
||||
|
||||
// return (type === 'directory' || type === 'FeatureCollection') ? undefined : `http://localhost:${availablePort}/icon/${name}.png`;
|
||||
return (type === 'directory' || type === 'FeatureCollection') ? undefined : `
|
||||
<svg class="svg-icon" style="color: rgba(var(--color-base2), 1);margin-top: 1px;width:100%;height:100%;fill: currentColor !important;stroke: currentColor !important;stroke-width: ${strokeWidth} !important;shape-rendering: geometricPrecision;">
|
||||
<use xlink:href="#icon-${name}" />
|
||||
</svg>
|
||||
`;
|
||||
return (type === 'directory' || type === 'FeatureCollection') ? undefined : `http://localhost:${availablePort}/icon/${name}.png`;
|
||||
};
|
||||
/**
|
||||
* 获取选中节点
|
||||
@ -520,7 +504,7 @@ export const useTreeNode = () => {
|
||||
const cusAddNodes = async (treeObj: any, parentNodeId: any, newNodes: any, isSilent?: any) => {
|
||||
for (let i = 0; i < newNodes.length; i++) {
|
||||
if (newNodes[i].sourceType != "directory") {
|
||||
newNodes[i].svg = await cusNodeIcon(newNodes[i]);
|
||||
newNodes[i].icon = await cusNodeIcon(newNodes[i]);
|
||||
YJ.Global.splitScreen.setActiveId([newNodes[i].id]);
|
||||
}
|
||||
}
|
||||
@ -651,6 +635,7 @@ export const useTreeNode = () => {
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
function findParentId(treeObj: any) {
|
||||
if (!treeObj) {
|
||||
return -1;
|
||||
@ -668,6 +653,7 @@ export const useTreeNode = () => {
|
||||
}
|
||||
return selectedNode.id;
|
||||
}
|
||||
|
||||
function findTreeIndex(treeObj: any) {
|
||||
if (!treeObj) {
|
||||
return 0;
|
||||
|
||||
@ -186,7 +186,7 @@
|
||||
style="width: 50px"
|
||||
id="keyword"
|
||||
type="text"
|
||||
:placeholder="t('btn.treePlaceholder')"
|
||||
:placeholder="select == 'poi' ? t('btn.treePlaceholder') : t('btn.treeLayerholder')"
|
||||
@input="clearResult"
|
||||
@change="searchPlace"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user