态势列表页面

This commit is contained in:
zyl
2025-10-15 14:06:08 +08:00
parent 3d5e82a054
commit 1253aa1ceb
17 changed files with 953 additions and 31 deletions

5
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

12
.idea/electron-4.iml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/electron-4.iml" filepath="$PROJECT_DIR$/.idea/electron-4.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View 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: 8808,
// proxy: {
// '/api': {
// target: localStorage.getItem('ip') || 'http://127.0.0.1:8808',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '')
// }
// }
// }
}
});
export {
electron_vite_config_default as default
};

7
package-lock.json generated
View File

@ -25,6 +25,7 @@
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"scss": "^0.2.4",
"three": "^0.180.0",
"verror": "^1.10.1",
"vue-clipboard3": "^2.0.0",
"vue-i18n": "^9.14.5",
@ -12775,6 +12776,12 @@
"node": ">= 10.0.0"
}
},
"node_modules/three": {
"version": "0.180.0",
"resolved": "https://registry.npmmirror.com/three/-/three-0.180.0.tgz",
"integrity": "sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==",
"license": "MIT"
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",

View File

@ -1,13 +1,13 @@
import { app, shell, BrowserWindow, ipcMain, globalShortcut, dialog } from 'electron'
import path, { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import {app, shell, BrowserWindow, ipcMain, globalShortcut, dialog} from 'electron'
import path, {join} from 'path'
import {electronApp, optimizer, is} from '@electron-toolkit/utils'
import icon from '../../resources/earth.png?asset'
import { Recorder } from "../preload/recorder";
import {Recorder} from "../preload/recorder";
import fs from 'fs'
import { exec } from 'child_process'
import {exec} from 'child_process'
import dayjs from 'dayjs'
import { GetHomeDir } from './config'
import { start, getServer } from "./app";
import {GetHomeDir} from './config'
import {start, getServer} from "./app";
// 开发环境路径处理 - 确保添加正确的file协议
@ -67,6 +67,7 @@ stopBatPath = process.platform === 'win32' ? stopBatPath.replace(/^(\w:)/, '/$1'
// ? `${join(app.getAppPath(), 'src/renderer/public/startUp/startUp.html')}`
// : `file://${join(app.getAppPath(), 'resources/app.asar/out/renderer/startUp/startUp.html')}`
let isRestart = false
function createWindow(): void {
// Create the browser window.
@ -102,7 +103,7 @@ function createWindow(): void {
useContentSize: true, // 窗口尺寸包含内容区域而非边框
simpleFullscreen: true, // 使用简单全屏模式(仅macOS有效)
backgroundColor: '#00000000', // 添加这行设置透明背景
...(process.platform === 'linux' ? { icon } : {}),
...(process.platform === 'linux' ? {icon} : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
@ -116,7 +117,7 @@ function createWindow(): void {
ipcMain.on("restart", () => {
// app.relaunch();
// app.quit();
// cleanupProcess.kill();
// cleanupProcess.kill();
// app.relaunch();
isRestart = true
windowAllClosed()
@ -162,7 +163,7 @@ function createWindow(): void {
event.sender.send("selectedItem", arr);
});
});
ipcMain.on("saveFile", (event, { title, filename, filters }) => {
ipcMain.on("saveFile", (event, {title, filename, filters}) => {
dialog
.showSaveDialog({
title,
@ -180,9 +181,13 @@ function createWindow(): void {
ipcMain.handle('getIsFullScreen', () => {
return mainWindow.isFullScreen()
});
ipcMain.on('toggle-fullscreen', (event) => {
ipcMain.on('toggle-fullscreen', (event, flag = null) => {
const win = BrowserWindow.fromWebContents(event.sender);
win!.setFullScreen(!win!.isFullScreen());
let full = !win!.isFullScreen()
if (flag != null) {
full = flag
}
win!.setFullScreen(full);
});
mainWindow.on('enter-full-screen', () => {
mainWindow.webContents.send('fullscreen-status-changed', true)
@ -209,7 +214,7 @@ function createWindow(): void {
let path = dialog.showSaveDialogSync({
title: "保存视频文件",
defaultPath: dayjs().format("YYYYMMDDHHmmss") + "视频录制.mp4",
filters: [{ name: "文件类型", extensions: ["mp4"] }],
filters: [{name: "文件类型", extensions: ["mp4"]}],
});
if (path != undefined) {
recorder.move(path, () => {
@ -292,7 +297,7 @@ function createWindow(): void {
// 设置窗口标题和图标
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
return {action: 'deny'}
})
// 注册 F5 快捷键刷新
globalShortcut.register('CommandOrControl+F5', () => {

View File

@ -11,11 +11,13 @@ 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']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
@ -29,6 +31,7 @@ declare module 'vue' {
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']
ElTree: typeof import('element-plus/es')['ElTree']

View File

@ -8,7 +8,6 @@ export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const ElMessage: typeof import('element-plus/es')['ElMessage']
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']

View File

@ -1,17 +1,19 @@
import './assets/main.css'
import { createApp } from 'vue'
import {createApp} from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 引入中文语言包
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import App from './App.vue'
import router from './router'
import { createI18n } from 'vue-i18n'
import { setupStore } from './store'
import {createI18n} from 'vue-i18n'
import {setupStore} from './store'
import zhCN from './I18n/zh-CN'
import zhTW from './I18n/zh-TW'
import zhEN from './I18n/zh-EN'
import 'virtual:svg-icons-register'
import { setupSvgIcon } from './icons'
import { EventBusPlugin } from './utils/bus'
import {setupSvgIcon} from './icons'
import {EventBusPlugin} from './utils/bus'
import './assets/styles/font.css'
import './assets/iconfont/font_4587902_y4fhjyq8fxn'
// import './assets/styles/dhtmlxgantt.css'
@ -51,6 +53,8 @@ setupStore(setApp)
setupSvgIcon(setApp)
setApp.use(EventBusPlugin)
setApp.use(router)
setApp.use(ElementPlus)
setApp.use(ElementPlus, {
locale: zhCn
})
setApp.use(i18n)
setApp.mount('#app')

View File

@ -1,4 +1,4 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import {createRouter, createWebHashHistory} from 'vue-router'
import homeIndex from '@/views/home/index.vue'
const routes = [
@ -7,7 +7,9 @@ const routes = [
component: () => import('@/views/login/index.vue'),
hidden: true
},
{ path: '/404', component: () => import('@/views/404.vue'), hidden: true },
{path: '/ts', component: () => import('@/views/TS/index.vue'), hidden: true},
{path: '/tsEdit', component: () => import('@/views/TS/edit.vue'), hidden: true},
{path: '/404', component: () => import('@/views/404.vue'), hidden: true},
{
path: '/home',
@ -16,7 +18,7 @@ const routes = [
hidden: true
},
{ path: '/:pathMatch(.*)*', redirect: '/404', hidden: true }
{path: '/:pathMatch(.*)*', redirect: '/404', hidden: true}
]
const router = createRouter({
@ -28,10 +30,10 @@ router.beforeEach((to, from, next) => {
if (to.path === '/') {
next()
} else {
if(localStorage.getItem('Authorization')) {
if (localStorage.getItem('Authorization')) {
next()
}else
next("/")
} else
next("/")
}
})

View File

@ -0,0 +1,113 @@
<template>
<div class="cabin">
<div>
<span>仿真演练图层指挥舱</span>
</div>
<div>
<el-input
v-model="input2"
class="responsive-input"
placeholder="搜索"
:prefix-icon="Search"
/>
</div>
<div class="treeBox">
<ul id="treeDemos" class="ztree" :setting="setting"></ul>
</div>
</div>
</template>
<script setup lang="ts">
import {onMounted, ref} from 'vue'
import {Search} from '@element-plus/icons-vue'
const setting = {
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag: {
isMove: true,
isCopy: false,
},
},
check: {
enable: true,
nocheckInherit: false,
chkboxType: {Y: "s", N: "s"},
},
view: {
selectedMulti: true,
dblClickExpand: false,
// autoCancelSelected: true
},
data: {
key: {
//zdatas数据中表示节点name的属性key
name: "name",
checked: "is_show",
},
simpleData: {
enable: true,
idKey: "id",
pIdKey: "p_id",
nameKey: "name",
},
},
callback: {
/*onRightClick: this.rightClick,
onClick: this.onClick,
onDblClick: this.onDblClick,
onCheck: this.onCheck,
onDrop: this.onDrop,*/
/*
onDrop: this.onDrop,
beforeRemove: this.beforeRemove,
beforeDrop: this.beforeDrop,
// beforeCollapse: this.beforeCollapse,
onRemove: this.onRemove,
onMouseDown: this.onMouseDown,
onClick: this.onClick,
onDblClick: this.onDblClick,
beforeClick: this.zTreeBeforeClick,
onCheck: this.onCheck*/
},
}
let input2 = ref('')
onMounted(() => {
let data = [
{name: "88"}
]
$.fn.zTree.init($(`#treeDemos`), setting, data)
})
</script>
<style lang="scss" scoped>
.cabin {
width: 16.3vw;
height: 59.6vh;
position: absolute;
z-index: 99;
top: 13.4259259259vh;
right: 1.5625vw;
border: 0.078125vw solid rgb(0, 255, 255);
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.5);
color: #fff;
padding: 0 5px;
display: flex;
flex-direction: column;
.treeBox {
border: 1px solid red;
flex: auto;
}
}
:deep(.el-input__wrapper), :deep(.el-input__inner ) {
background: transparent;
--el-input-placeholder-color: #fff;
color: #fff;
//border: 1px solid #0ff;
}
</style>

View File

@ -0,0 +1,49 @@
<template>
<div class="edit">
<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>
</div>
</template>
<script setup lang="ts">
import {ref, onMounted} from "vue";
import {useRouter} from "vue-router";
import cabin from "./cabin.vue"
import element from "./element.vue"
const router = useRouter()
const closeSituationEdit = () => {
router.back()
}
const createEarth = async () => {
window.earth_ts = await new YJ.YJEarth('earthContainer', {navigationHelpButton: false})
YJ.Global.CesiumContainer(earth_ts, {compass: false, legend: false});
setTimeout(() => {
new YJ.Tools(window.earth_ts).flyHome()
}, 1000)
}
onMounted(async () => {
let baseURL = localStorage.getItem('service')
// getAuthInfo()
await YJ.on({host: baseURL})
createEarth()
})
</script>
<style lang="scss" scoped>
.edit {
.icon-tuichu {
position: absolute;
top: 0.462962963vh;
right: 0.2604166667vw;
z-index: 999;
width: 1.25vw !important;
height: 2.2222222222vh !important;
cursor: pointer;
}
}
</style>

View File

@ -0,0 +1,261 @@
<template>
<div class="element">
<div class="title">
<span>元素库</span>
</div>
<!-- <div>
<el-input
v-model="input2"
class="responsive-input"
placeholder="搜索"
:prefix-icon="Search"
/>
</div>-->
<div class="tabsBox">
<div class="tabs">
<div v-for="(item,index) in tabs" @click="handleTabClick(item,index)" :class="index==activIndex?'active':''">
{{ item.name }}
</div>
</div>
<div class="panel">
<div class="treeOrList">
<template v-if="dataType=='tree'">
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
/>
</template>
<template v-if="dataType=='list'">
<div v-for="item in lists">
{{ item.name }}
</div>
</template>
</div>
<div class="list" v-if="showList">
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue";
import {Search} from '@element-plus/icons-vue'
interface Tree {
label: string
children?: Tree[]
}
const activIndex = ref(0)
const tabs = [
{name: "人工模型", dataType: 'tree',},
{name: "军事标绘", dataType: 'tree',},
{
name: "基础标绘", dataType: 'list', children:
[
{name: "点"},
{name: "线"},
{name: "面"},
{name: "圆"}
]
},
{name: "特效", dataType: 'list', children: [{name: "火焰"}]},
]
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([])
let input2 = ref('')
// 显示某类型下的元素
const showList = ref(false)
// 是否为树结构
const dataType = ref('tree')
// 树形结构节点点击
const handleTabClick = (item, index) => {
activIndex.value = index
console.log(item)
dataType.value = item.dataType
if (item.children) {
lists.value = item.children
}
}
const handleNodeClick = (data: Tree) => {
console.log(data)
showList.value = true
}
</script>
<style lang="scss" scoped>
.element {
width: 16.3vw;
height: 59.6vh;
position: absolute;
z-index: 99;
top: 13.4259259259vh;
left: 1.5625vw;
border: 0.078125vw solid rgb(0, 255, 255);
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.5);
color: #fff;
padding: 0 5px;
//display: flex;
//flex-direction: column;
.title {
height: 30px;
line-height: 30px;
}
.tabsBox {
//flex: auto;
height: calc(100% - 30px);
//display: flex;
//flex-direction: column;
.tabs {
height: 30px;
line-height: 30px;
display: flex;
//justify-content: space-between;
//border-bottom: 1px solid #eee;
cursor: pointer;
& > div {
width: 25%;
border-bottom: 1px solid rgba(238, 238, 238, 0.36);
text-align: center;
}
.active {
border-bottom: 2px solid #0ff;
}
}
.panel {
flex: auto;
display: flex;
flex-direction: column;
height: calc(100% - 30px);
.treeOrList {
//flex: auto;
height: calc(100% - 300px);
overflow-y: auto;
.el-tree {
background: transparent;
width: 100%;
}
}
.list {
border: 1px solid #eee;
height: 300px;
overflow-y: auto;
}
}
}
}
:deep(.el-input__wrapper), :deep(.el-input__inner ) {
background: transparent;
--el-input-placeholder-color: #fff;
color: #fff;
//border: 1px solid #0ff;
}
:deep(.el-tree-node__content:hover ) {
--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 {
.is-current {
background-color: linear-gradient(90deg, rgba(0, 255, 255, 0.5) 0%, rgba(0, 255, 255, 0) 100%);
}
}*/
//--el-tree-expand-icon-color: #fff;
}
:deep(.el-tree-node.is-current ) {
& > .el-tree-node__content {
background: linear-gradient(90deg, rgba(0, 255, 255, 0.5) 0%, rgba(0, 255, 255, 0) 100%);
& > .el-tree-node__label {
color: #0ff;
}
}
}
:deep(.el-text ) {
--el-text-color: #fff !important;
}
</style>

View File

@ -0,0 +1,367 @@
<template>
<div class="index">
<!--<span @click="back">态势</span>-->
<div class="titles">实景三维态势推演系统</div>
<svg class="icon icon-top" aria-hidden="true">
<use xlink:href="#icon-top"></use>
</svg>
<svg class="icon icon-tuichudenglu" @click="back" aria-hidden="true">
<use xlink:href="#icon-tuichudenglu"></use>
</svg>
<div class="list-container">
<div class="sub-title">
<span>历史推演</span>
<svg class="icon icon-title" aria-hidden="true">
<use xlink:href="#icon-title"></use>
</svg>
</div>
<div class="search">
<span>推演名称 <el-input
v-model="searchParams.name"
style="width: 240px"
placeholder="请输入推演名称"
clearable
/></span>
<span>创建人 <el-input
v-model="searchParams.create_by"
style="width: 240px"
placeholder="请输入创建人姓名"
clearable
/></span>
<span>创建时间 <el-date-picker
v-model="searchParams.datetime"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY-MM-DD ddd"
time-format="A hh:mm:ss"
value-format="x"
/></span>
<el-button @click="search">搜索</el-button>
<el-button @click="reset">重置</el-button>
</div>
<div class="option">
<el-button :icon="CirclePlus">新建推演</el-button>
<el-button :icon="Download">导入</el-button>
<el-button :icon="Upload">导出</el-button>
</div>
<div class="tableBox">
<el-table
:data="tableData"
:default-sort="{ prop: 'date', order: 'descending' }"
style="width: 100%"
>
<el-table-column align="center" prop="name" label="推演名称"/>
<el-table-column align="center" prop="description" label="推演描述"/>
<el-table-column align="center" prop="create_by" label="创建人"/>
<el-table-column align="center" prop="date" label="创建日期" sortable/>
<el-table-column align="center" 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="Delete">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- <el-auto-resizer>
<template #default="{ height, width }">
<el-table-v2
:sort-by="sortState"
:columns="columns"
:data="data"
:width="width"
:height="height"
fixed
@column-sort="onSort"
/>
</template>
</el-auto-resizer>-->
</div>
<!-- <div class="pageBox">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum"
:page-sizes="[5, 10, 50, 100]" :page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>-->
</div>
</div>
</template>
<script setup lang="ts">
import {ref} from "vue";
import {useRouter} from "vue-router";
import {Delete, Edit, CirclePlus, Download, Upload} from '@element-plus/icons-vue'
import {TableV2SortOrder} from 'element-plus'
import type {SortBy} from 'element-plus'
const {ipcRenderer} = require('electron')
const router = useRouter()
let searchParams = ref({
name: "",
create_by: "",
datetime: "",
})
let pageSize = ref(5)
let pageNum = ref(1)
let total = ref(0)
const back = () => {
ipcRenderer.send('toggle-fullscreen', false)
router.push({path: '/home'})
}
const handleSizeChange = (val) => {
pageSize = val
getList();
}
const handleCurrentChange = (val) => {
pageNum = val
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 search = () => {
console.log(searchParams)
}
const reset = () => {
searchParams.value = {name: "", create_by: "", datetime: ""}
}
const toTSEdit = () => {
router.push({path: '/tsEdit'})
}
/*
const generateData = (
columns: ReturnType<typeof generateColumns>,
length = 200,
prefix = 'row-'
) =>
Array.from({length}).map((_, rowIndex) => {
return columns.reduce(
(rowData, column, columnIndex) => {
rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
return rowData
},
{
id: `${prefix}${rowIndex}`,
parentId: null,
}
)
})
const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
Array.from({length}).map((_, columnIndex) => ({
...props,
key: `${prefix}${columnIndex}`,
dataKey: `${prefix}${columnIndex}`,
title: `Column ${columnIndex}`,
width: 150,
}))
const columns = generateColumns(3)
const sortState = ref<SortBy>({
key: 'column-0',
order: TableV2SortOrder.ASC,
})
let data = generateData(columns, 10)
console.log(data)
console.log(columns)
columns[0].sortable = true
const onSort = (sortBy: SortBy) => {
console.log(sortBy)
data = data.reverse()
sortState.value = sortBy
}
*/
</script>
<style lang="scss" scoped>
.index {
background: url("../../assets/img/bkgif@3x.gif") no-repeat;
background-size: 100% 100%;
width: 100vw;
height: 100vh !important;
position: relative;
.titles {
left: 50%;
transform: translateX(-50%);
font-size: 40px;
top: 19px;
line-height: 50px;
font-family: "alimamashuheiti";
z-index: 999;
position: absolute;
color: #fff;
}
.icon-top {
width: 100%;
height: 95px;
top: 0;
left: 0;
z-index: 99;
position: absolute;
}
.icon-tuichudenglu {
cursor: pointer;
position: absolute;
z-index: 999;
width: 26px;
height: 26px;
right: 8px;
top: 8px;
}
.list-container {
border: 1px solid #0ff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80vw;
height: 72vh;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.6);
border-image: linear-gradient(137.95deg, rgba(0, 255, 255, 1) 6.25%, rgba(0, 200, 255, 1) 100%) 2;
backdrop-filter: blur(2px);
& > div {
padding: 10px 0;
margin: 0 auto;
width: 95%;
//border: 1px solid;
box-sizing: content-box;
}
.sub-title {
font-size: 32px;
width: 15.4350566864vw;
height: 4.0740740741vh;
//padding: vh(20);
position: relative;
span {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
//font-family: W7;
user-select: none;
}
.icon-title {
width: 15.4350566864vw;
height: 4.0740740741vh;
}
}
.search {
span {
margin-right: 10px;
}
}
.tableBox {
flex: auto;
}
}
}
//将表格所有的背景色都改为透明色,字体改为白色
: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(0, 255, 255, 0.2);
}
: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;
}
:deep(.el-input__wrapper), :deep(.el-range-input), :deep(.el-range-separator) {
background: transparent;
--el-input-placeholder-color: #fff;
--el-text-color-placeholder: #fff;
color: #fff;
}
:deep(.el-input__inner:focus) {
border-color: #f00;
}
:deep(.el-table__inner-wrapper:before) {
background: transparent;
}
:deep(.el-table__header-wrapper .el-table__cell) {
border-bottom: none !important;
}
:deep(.el-table__row .el-table__cell) {
border-bottom: 1px solid rgba(152, 152, 152, 0.5);
}
/*
表格V2
:deep(.el-table-v2__main) {
background-color: transparent;
}
:deep(.el-table-v2__header-cell) {
background-color: transparent;
color: #fff;
}
:deep(.el-table-v2__header-wrapper) {
background-color: rgba(0, 255, 255, 0.2);
}*/
</style>

View File

@ -33,13 +33,16 @@
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import {useI18n} from 'vue-i18n'
import {useRouter} from 'vue-router'
import { bus } from '@/utils/bus'
import {bus} from '@/utils/bus'
import leftSideSecond from '@/views/components/leftSide/leftSideSecond.vue'
import { ElMessage, ElLoading } from 'element-plus'
import {ElMessage, ElLoading} from 'element-plus'
const { t } = useI18n()
const {ipcRenderer} = require('electron')
const router = useRouter() // 路由实例
const {t} = useI18n()
const eventBus: any = inject('bus')
const menuList: any = ref([
// 方案推演
@ -194,6 +197,19 @@ const handleClick = (item: any, e) => {
if (item.children.length) {
$('.leftSideSecond')[0].style.display = 'block'
leftSideSecondRef.value.initList(item)
} else if (item.key === 'situation') {
//态势推演
if ((window as any).checkAuthIsValid) {
console.log('打开态势推演')
ipcRenderer.send('toggle-fullscreen', true)
router.push({path: '/ts'})
} else {
ElMessage({
message: '您没有该功能的权限',
type: 'warning'
})
}
} else if (item.key === 'model') {
//模型库
if ((window as any).checkAuthIsValid) {

View File

@ -6154,6 +6154,11 @@ temp-file@^3.4.0:
async-exit-hook "^2.0.1"
fs-extra "^10.0.0"
three@^0.180.0:
version "0.180.0"
resolved "https://registry.npmmirror.com/three/-/three-0.180.0.tgz"
integrity sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz"