左侧二级菜单
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
build
|
||||||
out
|
out
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
4
.vscode/settings.json
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||||
},
|
},
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
@ -13,4 +13,4 @@
|
|||||||
"src/renderer/src/assets/i18n/lang"
|
"src/renderer/src/assets/i18n/lang"
|
||||||
],
|
],
|
||||||
"liveServer.settings.port": 5501
|
"liveServer.settings.port": 5501
|
||||||
}
|
}
|
6
package-lock.json
generated
@ -15,6 +15,7 @@
|
|||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"electron-updater": "^6.3.9",
|
"electron-updater": "^6.3.9",
|
||||||
"element-plus": "^2.10.4",
|
"element-plus": "^2.10.4",
|
||||||
|
"js-md5": "^0.8.3",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"pinia-plugin-persistedstate": "^4.4.1",
|
"pinia-plugin-persistedstate": "^4.4.1",
|
||||||
@ -8452,6 +8453,11 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/js-md5": {
|
||||||
|
"version": "0.8.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
|
||||||
|
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Electron</title>
|
<title>Electron</title>
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
<meta http-equiv="Content-Security-Policy"
|
|
||||||
content="default-src 'self'; connect-src 'self' http://127.0.0.1:8808; script-src 'self' 'unsafe-eval' 'unsafe-inline'; worker-src 'self' blob:; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:;" />
|
|
||||||
<style src="/sdk/custom/css/index.css"></style>
|
<style src="/sdk/custom/css/index.css"></style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -64,6 +64,71 @@ export default {
|
|||||||
ersanwei: '二三维',
|
ersanwei: '二三维',
|
||||||
junbiao3d: '三维军标'
|
junbiao3d: '三维军标'
|
||||||
},
|
},
|
||||||
|
effect: {
|
||||||
|
trajectoryMotion:"轨迹运动",
|
||||||
|
electronicFence: "电子围墙",
|
||||||
|
// nightVision: '实体墙',
|
||||||
|
radarLightWave: "扩散光波",
|
||||||
|
diffusedLightWave: "雷达光波",
|
||||||
|
scanStereoscopic: "立体雷达",
|
||||||
|
multilateralBody: "多边体",
|
||||||
|
waterSurface: "水面",
|
||||||
|
fountain: '喷泉',
|
||||||
|
waterL: '水柱',
|
||||||
|
fire: "火焰",
|
||||||
|
explosion: "爆炸",
|
||||||
|
smoke: "烟雾",
|
||||||
|
nightVision: '夜视',
|
||||||
|
// nightVision: '飞线',
|
||||||
|
},
|
||||||
|
analysis:{
|
||||||
|
inundationAnalysis: "淹没分析",
|
||||||
|
profileAnalysis: "剖面分析",
|
||||||
|
sightAnalysis: "视线分析",
|
||||||
|
kenAnalysis: "视域分析",
|
||||||
|
circleKen: "圆形视域",
|
||||||
|
slopeDirection: "坡度坡向",
|
||||||
|
cutFill: "土方分析",
|
||||||
|
globalContour: "全局等高线",
|
||||||
|
contour: "等高线",
|
||||||
|
clear: "清除",
|
||||||
|
},
|
||||||
|
measure:{
|
||||||
|
projectionArea: "投影面积",
|
||||||
|
projectionDistanceMeasure: '投影距离',
|
||||||
|
areaMeasure: "贴地面积",
|
||||||
|
distanceMeasure: "贴地距离",
|
||||||
|
heightMeasure: "垂直高度",
|
||||||
|
triangleMeasure: "空间三角",
|
||||||
|
MeasureAzimuth: '方位角',
|
||||||
|
MeasureAngle: "夹角",
|
||||||
|
lopeDistanceMeasures: '坡度',
|
||||||
|
coorMeasure: "坐标",
|
||||||
|
clear: "清除测量",
|
||||||
|
|
||||||
|
},
|
||||||
|
tool:{
|
||||||
|
routePlan: "路径规划",
|
||||||
|
//清除轨迹
|
||||||
|
graffiti: "涂鸦",
|
||||||
|
// stopGraffiti: "结束涂鸦",
|
||||||
|
clearGraffiti: "清除涂鸦",
|
||||||
|
path: "飞行漫游",
|
||||||
|
coorLocation: "坐标定位",
|
||||||
|
mouseLocation: "鼠标定位",
|
||||||
|
annotationAggregation: "标注点聚合",
|
||||||
|
// 卷帘对比
|
||||||
|
// 屏幕截图
|
||||||
|
// 高清出图
|
||||||
|
// 视频录制
|
||||||
|
pressModel: "模型压平",
|
||||||
|
terrainDig: "地形开挖",
|
||||||
|
tilesetClipping: "剖切",
|
||||||
|
clearTilesetClipping: "清除剖切",
|
||||||
|
projConvert: '度分秒',
|
||||||
|
projectionConvert: '投影转换',
|
||||||
|
gdbImport: "gdb导入"
|
||||||
|
},
|
||||||
bottomMenu: {
|
bottomMenu: {
|
||||||
groundText: '贴地文字',
|
groundText: '贴地文字',
|
||||||
standText: '立体文字',
|
standText: '立体文字',
|
||||||
|
@ -4,8 +4,14 @@ export const LoginApi = {
|
|||||||
// 查询活动分页
|
// 查询活动分页
|
||||||
login: async (data: any) => {
|
login: async (data: any) => {
|
||||||
return await request.post({
|
return await request.post({
|
||||||
url: `/api/v1/system/login`,
|
url: `/user/login`,
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
logout: async () => {
|
||||||
|
return await request.post({
|
||||||
|
url: `/user/logout`,
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,18 @@ export const TreeApi = {
|
|||||||
// 查询树的所有节点
|
// 查询树的所有节点
|
||||||
getTreeList: async () => {
|
getTreeList: async () => {
|
||||||
return await request.get({
|
return await request.get({
|
||||||
url: `/yjearth4/api/v1/source/list`
|
url: `/source/list`
|
||||||
|
// url: `/yjearth4/api/v1/source/list`
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 新增其他资源 /source/addOtherSource
|
||||||
|
addOtherSource: async (data: any) => {
|
||||||
|
return await request.post({
|
||||||
|
url: `/source/addOtherSource`,
|
||||||
|
data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
//新增节点
|
//新增节点
|
||||||
addDirectory: async (data: any) => {
|
addDirectory: async (data: any) => {
|
||||||
return await request.post({
|
return await request.post({
|
||||||
|
BIN
src/renderer/src/assets/images/second/MeasureAngle.png
Normal file
After Width: | Height: | Size: 613 B |
BIN
src/renderer/src/assets/images/second/MeasureAzimuth.png
Normal file
After Width: | Height: | Size: 596 B |
BIN
src/renderer/src/assets/images/second/annotationAggregation.png
Normal file
After Width: | Height: | Size: 892 B |
BIN
src/renderer/src/assets/images/second/areaMeasure.png
Normal file
After Width: | Height: | Size: 400 B |
BIN
src/renderer/src/assets/images/second/circleKen.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/renderer/src/assets/images/second/clear.png
Normal file
After Width: | Height: | Size: 844 B |
BIN
src/renderer/src/assets/images/second/clearGraffiti.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/renderer/src/assets/images/second/clearTilesetClipping.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/renderer/src/assets/images/second/contour.png
Normal file
After Width: | Height: | Size: 951 B |
BIN
src/renderer/src/assets/images/second/coorLocation.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/renderer/src/assets/images/second/coorMeasure.png
Normal file
After Width: | Height: | Size: 811 B |
BIN
src/renderer/src/assets/images/second/cutFill.png
Normal file
After Width: | Height: | Size: 788 B |
BIN
src/renderer/src/assets/images/second/diffusedLightWave.png
Normal file
After Width: | Height: | Size: 934 B |
BIN
src/renderer/src/assets/images/second/distanceMeasure.png
Normal file
After Width: | Height: | Size: 872 B |
BIN
src/renderer/src/assets/images/second/electronicFence.png
Normal file
After Width: | Height: | Size: 629 B |
BIN
src/renderer/src/assets/images/second/explosion.png
Normal file
After Width: | Height: | Size: 937 B |
BIN
src/renderer/src/assets/images/second/fire.png
Normal file
After Width: | Height: | Size: 801 B |
BIN
src/renderer/src/assets/images/second/fountain.png
Normal file
After Width: | Height: | Size: 644 B |
BIN
src/renderer/src/assets/images/second/gdbImport.png
Normal file
After Width: | Height: | Size: 704 B |
BIN
src/renderer/src/assets/images/second/globalContour.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/renderer/src/assets/images/second/graffiti.png
Normal file
After Width: | Height: | Size: 597 B |
BIN
src/renderer/src/assets/images/second/heightMeasure.png
Normal file
After Width: | Height: | Size: 567 B |
BIN
src/renderer/src/assets/images/second/inundationAnalysis.png
Normal file
After Width: | Height: | Size: 626 B |
BIN
src/renderer/src/assets/images/second/kenAnalysis.png
Normal file
After Width: | Height: | Size: 920 B |
BIN
src/renderer/src/assets/images/second/lopeDistanceMeasures.png
Normal file
After Width: | Height: | Size: 620 B |
BIN
src/renderer/src/assets/images/second/mouseLocation.png
Normal file
After Width: | Height: | Size: 710 B |
BIN
src/renderer/src/assets/images/second/multilateralBody.png
Normal file
After Width: | Height: | Size: 681 B |
BIN
src/renderer/src/assets/images/second/nightVision.png
Normal file
After Width: | Height: | Size: 796 B |
BIN
src/renderer/src/assets/images/second/path.png
Normal file
After Width: | Height: | Size: 534 B |
BIN
src/renderer/src/assets/images/second/pressModel.png
Normal file
After Width: | Height: | Size: 499 B |
BIN
src/renderer/src/assets/images/second/profileAnalysis.png
Normal file
After Width: | Height: | Size: 749 B |
BIN
src/renderer/src/assets/images/second/projConvert.png
Normal file
After Width: | Height: | Size: 911 B |
BIN
src/renderer/src/assets/images/second/projectionArea.png
Normal file
After Width: | Height: | Size: 712 B |
BIN
src/renderer/src/assets/images/second/projectionConvert.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 668 B |
BIN
src/renderer/src/assets/images/second/radarLightWave.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/renderer/src/assets/images/second/routePlan.png
Normal file
After Width: | Height: | Size: 773 B |
BIN
src/renderer/src/assets/images/second/scanStereoscopic.png
Normal file
After Width: | Height: | Size: 900 B |
BIN
src/renderer/src/assets/images/second/sightAnalysis.png
Normal file
After Width: | Height: | Size: 686 B |
BIN
src/renderer/src/assets/images/second/slopeDirection.png
Normal file
After Width: | Height: | Size: 815 B |
BIN
src/renderer/src/assets/images/second/smoke.png
Normal file
After Width: | Height: | Size: 581 B |
BIN
src/renderer/src/assets/images/second/terrainDig.png
Normal file
After Width: | Height: | Size: 696 B |
BIN
src/renderer/src/assets/images/second/tilesetClipping.png
Normal file
After Width: | Height: | Size: 754 B |
BIN
src/renderer/src/assets/images/second/trajectoryMotion.png
Normal file
After Width: | Height: | Size: 727 B |
BIN
src/renderer/src/assets/images/second/triangleMeasure.png
Normal file
After Width: | Height: | Size: 546 B |
BIN
src/renderer/src/assets/images/second/waterSurface.png
Normal file
After Width: | Height: | Size: 673 B |
BIN
src/renderer/src/assets/images/secondBj.png
Normal file
After Width: | Height: | Size: 12 KiB |
@ -1,3 +1,4 @@
|
|||||||
|
import router from '@renderer/router'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import type {
|
import type {
|
||||||
AxiosInstance,
|
AxiosInstance,
|
||||||
@ -9,14 +10,14 @@ import type {
|
|||||||
const pendingRequests = new Map<string, AbortController>()
|
const pendingRequests = new Map<string, AbortController>()
|
||||||
let baseURL: any
|
let baseURL: any
|
||||||
if (window && window.process && window.process.type === 'renderer') {
|
if (window && window.process && window.process.type === 'renderer') {
|
||||||
baseURL = localStorage.getItem('ip') || 'http://127.0.0.1:8808'
|
baseURL = localStorage.getItem('ip') ||'http://192.168.110.25:8848'|| 'http://127.0.0.1:8808'
|
||||||
} else {
|
} else {
|
||||||
baseURL = ''
|
baseURL = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建自定义配置的axios实例
|
// 创建自定义配置的axios实例
|
||||||
const service: AxiosInstance = axios.create({
|
const service: AxiosInstance = axios.create({
|
||||||
baseURL,
|
baseURL:'http://192.168.110.25:8848',
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@ -47,9 +48,12 @@ service.interceptors.request.use(
|
|||||||
pendingRequests.set(key, controller)
|
pendingRequests.set(key, controller)
|
||||||
|
|
||||||
// 在这里添加认证token
|
// 在这里添加认证token
|
||||||
const token = localStorage.getItem('access_token')
|
const token = localStorage.getItem('Authorization')
|
||||||
|
console.log("localStorage.getItem('Authorization')",token);
|
||||||
|
|
||||||
if (token && config.headers) {
|
if (token && config.headers) {
|
||||||
config.headers.Authorization = `Bearer ${token}`
|
// Bearer
|
||||||
|
config.headers.Authorization = `${token}`
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
@ -63,18 +67,24 @@ service.interceptors.response.use(
|
|||||||
(response: AxiosResponse) => {
|
(response: AxiosResponse) => {
|
||||||
const key = getRequestKey(response.config)
|
const key = getRequestKey(response.config)
|
||||||
pendingRequests.delete(key)
|
pendingRequests.delete(key)
|
||||||
|
console.log(response);
|
||||||
|
|
||||||
// 统一处理HTTP状态码
|
// 统一处理HTTP状态码
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
if (response.data.code == 0) {
|
if ([0,200].includes(response.data.code)) {
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
if (response.data.code != 0) {
|
if (response.data.code==401) {
|
||||||
|
router.push('/')
|
||||||
|
localStorage.removeItem('Authorization')
|
||||||
|
}
|
||||||
|
if (![0,200].includes(response.data.code)) {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: response.data.msg || response.data.message,
|
message: response.data.msg || response.data.message,
|
||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return Promise.reject(new Error('Error'))
|
return Promise.reject(new Error('Error'))
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ import '../public/tree/jquery.ztree.exhide.js'
|
|||||||
import '../public/tree/fuzzysearch.js'
|
import '../public/tree/fuzzysearch.js'
|
||||||
import '../public/tree/newFuzzySearch'
|
import '../public/tree/newFuzzySearch'
|
||||||
import Pagination from './components/Pagination/index.vue'
|
import Pagination from './components/Pagination/index.vue'
|
||||||
|
process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
legacy: false,
|
legacy: false,
|
||||||
locale: 'zh-CN',
|
locale: 'zh-CN',
|
||||||
@ -38,6 +38,9 @@ const i18n = createI18n({
|
|||||||
// 注册全局指令
|
// 注册全局指令
|
||||||
|
|
||||||
const setApp = createApp(App)
|
const setApp = createApp(App)
|
||||||
|
// 定义全局方法
|
||||||
|
|
||||||
|
// setApp.config.globalProperties.$md5 = md5
|
||||||
setApp.component('Pagination', Pagination)
|
setApp.component('Pagination', Pagination)
|
||||||
setupStore(setApp)
|
setupStore(setApp)
|
||||||
setupSvgIcon(setApp)
|
setupSvgIcon(setApp)
|
||||||
|
@ -23,5 +23,16 @@ const router = createRouter({
|
|||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes
|
routes
|
||||||
})
|
})
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 去登录,放行
|
||||||
|
if (to.path === '/') {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
if(localStorage.getItem('Authorization')) {
|
||||||
|
next()
|
||||||
|
}else
|
||||||
|
next("/")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
@ -13,14 +13,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div
|
<div class="set_item" :title="t('iconTitle.' + item.name)" v-for="(item, i) of setList" :key="item.id"
|
||||||
class="set_item"
|
:class="{ 'last-item': i === setList.length - 1 }" @click="item.callback">
|
||||||
:title="t('iconTitle.' + item.name)"
|
|
||||||
v-for="(item, i) of setList"
|
|
||||||
:key="item.id"
|
|
||||||
:class="{ 'last-item': i === setList.length - 1 }"
|
|
||||||
@click="item.callback"
|
|
||||||
>
|
|
||||||
<svg-icon :name="item.icon" :size="20"></svg-icon>
|
<svg-icon :name="item.icon" :size="20"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<setPup ref="setPupRef"></setPup>
|
<setPup ref="setPupRef"></setPup>
|
||||||
@ -28,14 +22,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import setPup from '../setPup/setPup.vue'
|
import setPup from '../setPup/setPup.vue'
|
||||||
|
const router = useRouter() // 路由实例
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
import { uesSetTool } from './hooks'
|
import { uesSetTool } from './hooks'
|
||||||
|
import { LoginApi } from '@renderer/api/login'
|
||||||
const setPupRef = ref()
|
const setPupRef = ref()
|
||||||
const { setShow } = uesSetTool(setPupRef)
|
const { setShow } = uesSetTool(setPupRef)
|
||||||
|
const logout = async () => {
|
||||||
|
let res = await LoginApi.logout()
|
||||||
|
console.log(res);
|
||||||
|
if (res.code === 200) {
|
||||||
|
router.push({ path: '/' })
|
||||||
|
localStorage.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
const setList = ref([
|
const setList = ref([
|
||||||
// 标准版本
|
// 标准版本
|
||||||
{
|
{
|
||||||
@ -81,8 +84,8 @@ const setList = ref([
|
|||||||
icon: 'out_login',
|
icon: 'out_login',
|
||||||
name: 'logout',
|
name: 'logout',
|
||||||
className: 'header_public',
|
className: 'header_public',
|
||||||
dbcallback: null
|
dbcallback: null,
|
||||||
// callback: this.logout,
|
callback: logout,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
@ -110,6 +113,7 @@ const setList = ref([
|
|||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.set_item::after {
|
.set_item::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -117,17 +121,16 @@ const setList = ref([
|
|||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
background: linear-gradient(
|
background: linear-gradient(180deg,
|
||||||
180deg,
|
rgba(0, 255, 255, 0),
|
||||||
rgba(0, 255, 255, 0),
|
rgba(0, 255, 255, 1),
|
||||||
rgba(0, 255, 255, 1),
|
rgba(204, 204, 204, 0));
|
||||||
rgba(204, 204, 204, 0)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.set_item.last-item::after {
|
.set_item.last-item::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-dialog__body {
|
::v-deep .el-dialog__body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,19 @@
|
|||||||
<div class="leftBox">
|
<div class="leftBox">
|
||||||
<div class="left animate__animated">
|
<div class="left animate__animated">
|
||||||
<div class="menus">
|
<div class="menus">
|
||||||
<div
|
<div class="menus_itemBox" v-for="(item, index) in menuList" :title="t(`firstMenu.${item.name}`)">
|
||||||
class="menus_itemBox"
|
<div class="item_icon" @click="(e) => { handleClick(item, e) }">
|
||||||
v-for="(item, index) in menuList"
|
|
||||||
:title="t(`firstMenu.${item.name}`)"
|
|
||||||
>
|
|
||||||
<div class="item_icon">
|
|
||||||
<!-- <svg-icon :class-name="['absolute', 'zIndex-1', 'left_item_bg']" icon-class="bg2"></svg-icon> -->
|
<!-- <svg-icon :class-name="['absolute', 'zIndex-1', 'left_item_bg']" icon-class="bg2"></svg-icon> -->
|
||||||
<svg-icon :name="item.svg" :size="16" color="rgba(0, 255, 255, 1)"></svg-icon>
|
<svg-icon :name="item.svg" :size="16" color="rgba(0, 255, 255, 1)"></svg-icon>
|
||||||
<div class="item_text">
|
<div class="item_text">
|
||||||
{{ t(`firstMenu.${item.name}`) }}
|
{{ t(`firstMenu.${item.name}`) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<leftSideSecond class="absolute zIndex99 leftSideSecond" ref="leftSideSecondRef"></leftSideSecond>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="left_bottom" @click="fold"></div>
|
<div class="left_bottom" @click="fold"></div>
|
||||||
@ -24,43 +24,88 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { bus } from '@/utils/bus'
|
import { bus } from '@/utils/bus'
|
||||||
|
import leftSideSecond from '@/views/components/leftSide/leftSideSecond.vue'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const menuList = ref([
|
const menuList = ref([
|
||||||
// 模型库
|
// 方案推演
|
||||||
{
|
{
|
||||||
name: 'situation',
|
name: 'situation',
|
||||||
svg: 'situation',
|
svg: 'situation',
|
||||||
// fun: this.openModel,
|
// fun: this.openModel,
|
||||||
key: 'situation'
|
key: 'situation',
|
||||||
|
children: []
|
||||||
},
|
},
|
||||||
// 模型库
|
// 模型库
|
||||||
{
|
{
|
||||||
name: 'modelLibrary',
|
name: 'modelLibrary',
|
||||||
svg: 'model',
|
svg: 'model',
|
||||||
// fun: this.openModel,
|
// fun: this.openModel,
|
||||||
key: 'model'
|
key: 'model',
|
||||||
|
children: []
|
||||||
},
|
},
|
||||||
// 特效库
|
// 特效库
|
||||||
{
|
{
|
||||||
name: 'effect',
|
name: 'effect',
|
||||||
svg: 'special',
|
svg: 'special',
|
||||||
// fun: this.showSecondMenu,
|
// fun: this.showSecondMenu,
|
||||||
key: 'effect'
|
key: 'effect',
|
||||||
|
children: [
|
||||||
|
"trajectoryMotion",
|
||||||
|
"electronicFence",
|
||||||
|
// "nightVision",
|
||||||
|
"radarLightWave",
|
||||||
|
"diffusedLightWave",
|
||||||
|
"scanStereoscopic",
|
||||||
|
"multilateralBody",
|
||||||
|
"waterSurface",
|
||||||
|
"fountain",
|
||||||
|
"waterL",
|
||||||
|
"fire",
|
||||||
|
"explosion",
|
||||||
|
"smoke",
|
||||||
|
"nightVision",
|
||||||
|
// "nightVision",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// 分析
|
// 分析
|
||||||
{
|
{
|
||||||
name: 'analysis',
|
name: 'analysis',
|
||||||
svg: 'analysis',
|
svg: 'analysis',
|
||||||
// fun: this.showSecondMenu,
|
// fun: this.showSecondMenu,
|
||||||
key: 'analysis'
|
key: 'analysis',
|
||||||
|
children: [
|
||||||
|
"inundationAnalysis",
|
||||||
|
"profileAnalysis",
|
||||||
|
"sightAnalysis",
|
||||||
|
"kenAnalysis",
|
||||||
|
"circleKen",
|
||||||
|
"slopeDirection",
|
||||||
|
"cutFill",
|
||||||
|
"contour",
|
||||||
|
"globalContour",
|
||||||
|
"clear",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// 测量
|
// 测量
|
||||||
{
|
{
|
||||||
name: 'measure',
|
name: 'measure',
|
||||||
svg: 'measure',
|
svg: 'measure',
|
||||||
// fun: this.showSecondMenu,
|
// fun: this.showSecondMenu,
|
||||||
key: 'measure'
|
key: 'measure',
|
||||||
|
children: [
|
||||||
|
"projectionArea",
|
||||||
|
"projectionDistanceMeasure",
|
||||||
|
"areaMeasure",
|
||||||
|
"distanceMeasure",
|
||||||
|
"heightMeasure",
|
||||||
|
"triangleMeasure",
|
||||||
|
"MeasureAzimuth",
|
||||||
|
"MeasureAngle",
|
||||||
|
"lopeDistanceMeasures",
|
||||||
|
"coorMeasure",
|
||||||
|
"clear",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
// 工具
|
// 工具
|
||||||
@ -68,21 +113,44 @@ const menuList = ref([
|
|||||||
name: 'tool',
|
name: 'tool',
|
||||||
svg: 'tool',
|
svg: 'tool',
|
||||||
// fun: this.showSecondMenu,
|
// fun: this.showSecondMenu,
|
||||||
key: 'tool'
|
key: 'tool',
|
||||||
|
children: [
|
||||||
|
"routePlan",
|
||||||
|
//清除轨迹
|
||||||
|
"graffiti",
|
||||||
|
// stopGraffiti: "结束涂鸦",
|
||||||
|
"clearGraffiti",
|
||||||
|
"path",
|
||||||
|
"coorLocation",
|
||||||
|
"mouseLocation",
|
||||||
|
"annotationAggregation",
|
||||||
|
// 卷帘对比
|
||||||
|
// 屏幕截图
|
||||||
|
// 高清出图
|
||||||
|
// 视频录制
|
||||||
|
"pressModel",
|
||||||
|
"terrainDig",
|
||||||
|
"tilesetClipping",
|
||||||
|
"clearTilesetClipping",
|
||||||
|
"projConvert",
|
||||||
|
"projectionConvert",
|
||||||
|
"gdbImport",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// 工具
|
|
||||||
{
|
{
|
||||||
name: 'militaryMark',
|
name: 'militaryMark',
|
||||||
svg: 'military',
|
svg: 'military',
|
||||||
// fun: this.showSecondMenu,
|
// fun: this.showSecondMenu,
|
||||||
key: 'military'
|
key: 'military',
|
||||||
|
children: []
|
||||||
},
|
},
|
||||||
//二三维
|
//二三维
|
||||||
{
|
{
|
||||||
name: 'ersanwei',
|
name: 'ersanwei',
|
||||||
// fun: this.map2d,
|
// fun: this.map2d,
|
||||||
svg: 'dimension',
|
svg: 'dimension',
|
||||||
key: 'ersanwei'
|
key: 'ersanwei',
|
||||||
|
children: []
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const isFolded: any = ref(false) // 添加折叠状态
|
const isFolded: any = ref(false) // 添加折叠状态
|
||||||
@ -99,7 +167,17 @@ onMounted(() => {
|
|||||||
initialPositions.value[index] = item.style.transform || 'translateX(0)'
|
initialPositions.value[index] = item.style.transform || 'translateX(0)'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
const leftSideSecondRef = ref()
|
||||||
|
const handleClick = (item: any, e) => {
|
||||||
|
console.log("点击了", item, e);
|
||||||
|
$(".leftSideSecond")[0].style.left = "100%";
|
||||||
|
$(".leftSideSecond")[0].style.top = e.layerY - 120 + "px"
|
||||||
|
$(".leftSideSecond")[0].style.display = "none"
|
||||||
|
if (item.children.length) {
|
||||||
|
$(".leftSideSecond")[0].style.display = "block"
|
||||||
|
leftSideSecondRef.value.initList(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
const fold = () => {
|
const fold = () => {
|
||||||
// 如果正在动画中,直接返回
|
// 如果正在动画中,直接返回
|
||||||
if (isAnimating.value) return
|
if (isAnimating.value) return
|
||||||
@ -193,6 +271,8 @@ const fold = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0 8px 0 5px;
|
padding: 0 8px 0 5px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
// margin-top: 20px;
|
// margin-top: 20px;
|
||||||
.menus_itemBox {
|
.menus_itemBox {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -215,6 +295,15 @@ const fold = () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item_icon:hover .item_text {
|
||||||
|
color: rgba(0, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item_icon:hover {
|
||||||
|
background: url('../../../assets/images/hongse/left1.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.item_text {
|
.item_text {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
@ -232,14 +321,9 @@ const fold = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menus_itemBox:hover .item_icon {
|
|
||||||
background: url('../../../assets/images/hongse/left1.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menus_itemBox:hover .item_text {
|
|
||||||
color: rgba(0, 255, 255, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
162
src/renderer/src/views/components/leftSide/leftSideSecond.vue
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
<template>
|
||||||
|
<div class="leftSideSecond">
|
||||||
|
<div class="leftSideSecondBox">
|
||||||
|
|
||||||
|
<template v-if="obj">
|
||||||
|
<div class="menuItem" v-for="value in obj.children" @click="handleClick(value)">
|
||||||
|
<img :src="'src/assets/images/second/' + `${value}` + '.png'" alt="">
|
||||||
|
<span>{{ t(`${obj.key}.${value}`) }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { ref, reactive, getCurrentInstance } from "vue"
|
||||||
|
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||||
|
import { TreeApi } from '@/api/tree'
|
||||||
|
import { renderMethods } from '../tree/hooks/renderTreeNode'
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
const { t } = useI18n()
|
||||||
|
const { findParentId, findTreeIndex } = useTreeNode()
|
||||||
|
const obj = ref(null)
|
||||||
|
const initList = (value) => {
|
||||||
|
obj.value = value
|
||||||
|
}
|
||||||
|
const methodMap = {
|
||||||
|
// 电子围墙
|
||||||
|
electronicFence: () => {
|
||||||
|
let draw = new YJ.Draw.DrawPolyline(window.earth);
|
||||||
|
draw.start((err, positions) => {
|
||||||
|
if (positions.length > 1) {
|
||||||
|
let alt = positions[0].alt;
|
||||||
|
positions.forEach((item) => {
|
||||||
|
if (item.alt < alt) alt = item.alt;
|
||||||
|
});
|
||||||
|
let id = proxy.$md5(new Date().getTime() + "围墙");
|
||||||
|
let params = {
|
||||||
|
sourceName: "电子围墙",
|
||||||
|
id,
|
||||||
|
sourceType: "wallStereoscopic",
|
||||||
|
parentId: findParentId(window.treeObj),
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
positions,
|
||||||
|
color: "#fff",
|
||||||
|
cornerType: undefined,
|
||||||
|
extrudedHeight: 2.4,
|
||||||
|
width: 0.24,
|
||||||
|
},
|
||||||
|
treeIndex: findTreeIndex(window.treeObj)
|
||||||
|
}
|
||||||
|
// console.log(params);
|
||||||
|
// 渲染电子围墙
|
||||||
|
renderMethods.renderWallStereoscopic(params)
|
||||||
|
// 存入数据库
|
||||||
|
let res = TreeApi.addOtherSource(params)
|
||||||
|
console.log("addOtherSource", res);
|
||||||
|
// 上树
|
||||||
|
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
// 扩散光波
|
||||||
|
radarLightWave: () => {
|
||||||
|
let draw = new YJ.Draw.DrawCircle(window.earth);
|
||||||
|
draw.start((err, params) => {
|
||||||
|
console.log(params);
|
||||||
|
if (params) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//投影面积
|
||||||
|
projectionArea: () => {
|
||||||
|
new YJ.Measure.MeasureTyArea(window.earth).start();
|
||||||
|
},
|
||||||
|
//投影距离测量
|
||||||
|
projectionDistanceMeasure: () => {
|
||||||
|
new YJ.Measure.MeasureProjectionDistance(window.earth).start();
|
||||||
|
},
|
||||||
|
areaMeasure: () => {
|
||||||
|
new YJ.Measure.MeasureTdArea(window.earth).start();
|
||||||
|
},
|
||||||
|
//距离测量
|
||||||
|
distanceMeasure: () => {
|
||||||
|
new YJ.Measure.MeasureDistance(window.earth).start();
|
||||||
|
},
|
||||||
|
//高度测量
|
||||||
|
heightMeasure: () => {
|
||||||
|
new YJ.Measure.MeasureHeight(window.earth).start();
|
||||||
|
},
|
||||||
|
//三角测量
|
||||||
|
triangleMeasure: () => {
|
||||||
|
new YJ.Measure.MeasureTriangle(window.earth).start();
|
||||||
|
},
|
||||||
|
// 方位角
|
||||||
|
MeasureAzimuth() {
|
||||||
|
new YJ.Measure.MeasureAzimuth(window.earth).start();
|
||||||
|
},
|
||||||
|
//夹角测量
|
||||||
|
MeasureAngle() {
|
||||||
|
new YJ.Measure.MeasureAngle(window.earth).start();
|
||||||
|
},
|
||||||
|
// 坡度测量
|
||||||
|
lopeDistanceMeasures() {
|
||||||
|
new YJ.Measure.MeasureSlopeDistance(window.earth).start();
|
||||||
|
},
|
||||||
|
//坐标测量
|
||||||
|
coorMeasure() {
|
||||||
|
new YJ.Measure.MeasureLocation(window.earth).start();
|
||||||
|
},
|
||||||
|
//清除测量
|
||||||
|
clear() {
|
||||||
|
YJ.Measure.Clear();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = (value = 'projectionDistanceMeasure') => {
|
||||||
|
methodMap[value]()
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
initList
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.leftSideSecond {
|
||||||
|
display: none;
|
||||||
|
height: 365px;
|
||||||
|
width: 275px;
|
||||||
|
background: url("@/assets/images/secondBj.png") no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
padding: 13px 4px 13px 11px;
|
||||||
|
|
||||||
|
.leftSideSecondBox {
|
||||||
|
border: 1px solid red;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.menuItem {
|
||||||
|
width: 25%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: 5px 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,10 @@
|
|||||||
|
export const renderMethods = {
|
||||||
|
renderWallStereoscopic: (node: any) => {
|
||||||
|
console.log("renderWallStereoscopic", node);
|
||||||
|
let option = {
|
||||||
|
name: node.sourceName,
|
||||||
|
...node.params
|
||||||
|
}
|
||||||
|
let WallStereoscopic = new YJ.Obj.WallStereoscopic(window.earth, option);
|
||||||
|
}
|
||||||
|
}
|
@ -350,14 +350,14 @@ export const useTree = () => {
|
|||||||
data: {
|
data: {
|
||||||
key: {
|
key: {
|
||||||
//zdatas数据中表示节点name的属性key
|
//zdatas数据中表示节点name的属性key
|
||||||
name: 'source_name',
|
name: 'sourceName',
|
||||||
checked: 'is_show'
|
checked: 'isShow'
|
||||||
},
|
},
|
||||||
simpleData: {
|
simpleData: {
|
||||||
enable: true,
|
enable: true,
|
||||||
idKey: 'source_id',
|
idKey: 'id',
|
||||||
pIdKey: 'p_id',
|
pIdKey: 'parentId',
|
||||||
nameKey: 'source_name'
|
nameKey: 'sourceName'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
callback: {
|
callback: {
|
||||||
@ -398,11 +398,13 @@ export const useTree = () => {
|
|||||||
// 初始化树的方法
|
// 初始化树的方法
|
||||||
const initTree = async (selector: string = '#treeDemo') => {
|
const initTree = async (selector: string = '#treeDemo') => {
|
||||||
let res = await TreeApi.getTreeList()
|
let res = await TreeApi.getTreeList()
|
||||||
if (res.code == 0) {
|
console.log('res', res)
|
||||||
res.data.list.sort((a: any, b: any) => {
|
if ([0,200].includes(res.code)) {
|
||||||
return a.tree_index - b.tree_index
|
res.data.sort((a: any, b: any) => {
|
||||||
|
if(a.treeIndex&&b.treeIndex)
|
||||||
|
return a.treeIndex - b.treeIndex
|
||||||
})
|
})
|
||||||
zNodes.value = res.data.list
|
zNodes.value = res.data
|
||||||
treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value)
|
treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value)
|
||||||
window.treeObj = treeObj.value
|
window.treeObj = treeObj.value
|
||||||
window.AllNodes = treeObj.value.getNodes()
|
window.AllNodes = treeObj.value.getNodes()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { renderMethods } from "./renderTreeNode";
|
||||||
export const useTreeNode = () => {
|
export const useTreeNode = () => {
|
||||||
//定义树形节点的属性
|
//定义树形节点的属性
|
||||||
const nodeType = {
|
const nodeType = {
|
||||||
@ -85,10 +86,10 @@ export const useTreeNode = () => {
|
|||||||
'importPanorama',
|
'importPanorama',
|
||||||
'edit',
|
'edit',
|
||||||
'del'
|
'del'
|
||||||
]
|
],
|
||||||
// detailFun: get_detail_null,
|
// detailFun: get_detail_null,
|
||||||
// render: () => {},
|
// render: () => {},
|
||||||
// allowChildren: true,
|
allowChildren: true,
|
||||||
},
|
},
|
||||||
tileset: {
|
tileset: {
|
||||||
rightMenus: [
|
rightMenus: [
|
||||||
@ -166,9 +167,9 @@ export const useTreeNode = () => {
|
|||||||
// render: renderScanStereoscopic,
|
// render: renderScanStereoscopic,
|
||||||
},
|
},
|
||||||
wallStereoscopic: {
|
wallStereoscopic: {
|
||||||
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
rightMenus: ['edit', 'del', 'setView', 'resetView'],
|
||||||
// detailFun: get_detail_wallStereoscopic,
|
// detailFun: get_detail_wallStereoscopic,
|
||||||
// render: renderWallStereoscopic,
|
render: renderMethods.renderWallStereoscopic,
|
||||||
},
|
},
|
||||||
entityWall: {
|
entityWall: {
|
||||||
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
||||||
@ -542,6 +543,47 @@ export const useTreeNode = () => {
|
|||||||
|
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
function findParentId(treeObj: any) {
|
||||||
|
if (!treeObj) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
let selectedNode = getSelectedNode(treeObj);
|
||||||
|
|
||||||
|
if (!selectedNode) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while (!nodeType[selectedNode.sourceType].allowChildren) {
|
||||||
|
selectedNode = treeObj.getNodeByParam("id", selectedNode.parentId, null);
|
||||||
|
if (!selectedNode) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedNode.id;
|
||||||
|
}
|
||||||
|
function findTreeIndex(treeObj: any) {
|
||||||
|
if (!treeObj) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let selectedNode = getSelectedNode(treeObj);
|
||||||
|
|
||||||
|
if (!selectedNode) {
|
||||||
|
return treeObj.getNodes().length;
|
||||||
|
} else {
|
||||||
|
// 有选中的节点后添加节点
|
||||||
|
// 选中的节点允许添加子节点,则返回该节点下children的长度
|
||||||
|
if (nodeType[selectedNode.sourceType].allowChildren) {
|
||||||
|
let nodes = treeObj.getNodesByParam("parentId", selectedNode.id, null)
|
||||||
|
return nodes.length
|
||||||
|
} else {
|
||||||
|
// 否则返回该节点父节点的children的长度
|
||||||
|
let parentNode = treeObj.getNodesByParam("id", selectedNode.parentId, null);
|
||||||
|
if (parentNode) {
|
||||||
|
return parentNode.children.length
|
||||||
|
} else
|
||||||
|
return treeObj.getNodes().length; // 如果没有父节点,则返回根节点的长度
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
showRightMenu,
|
showRightMenu,
|
||||||
@ -551,6 +593,8 @@ export const useTreeNode = () => {
|
|||||||
getSelectedNode,
|
getSelectedNode,
|
||||||
cusAddNodes,
|
cusAddNodes,
|
||||||
getSameLevel,
|
getSameLevel,
|
||||||
cusRemoveNode
|
cusRemoveNode,
|
||||||
|
findParentId,
|
||||||
|
findTreeIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ onMounted(async () => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.adddirectoryBox {
|
.adddirectoryBox {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="login-container" style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0">
|
||||||
class="login-container"
|
<transition name="video-fade" mode="out-in"
|
||||||
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0"
|
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover">
|
||||||
>
|
|
||||||
<transition
|
|
||||||
name="video-fade"
|
|
||||||
mode="out-in"
|
|
||||||
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"
|
|
||||||
>
|
|
||||||
<!-- 第一个视频,播放一次 -->
|
<!-- 第一个视频,播放一次 -->
|
||||||
<video
|
<video v-if="!isFirstVideoPlayed" ref="firstVideoRef" key="first-video" muted @ended="onFirstVideoEnded"
|
||||||
v-if="!isFirstVideoPlayed"
|
|
||||||
ref="firstVideoRef"
|
|
||||||
key="first-video"
|
|
||||||
muted
|
|
||||||
@ended="onFirstVideoEnded"
|
|
||||||
src="../../assets/video/login_front.mp4"
|
src="../../assets/video/login_front.mp4"
|
||||||
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"
|
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"></video>
|
||||||
></video>
|
|
||||||
<!-- 第二个视频,循环播放 -->
|
<!-- 第二个视频,循环播放 -->
|
||||||
<video
|
<video v-else key="second-video" autoplay loop muted src="../../assets/video/login_feature.mp4"
|
||||||
v-else
|
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"></video>
|
||||||
key="second-video"
|
|
||||||
autoplay
|
|
||||||
loop
|
|
||||||
muted
|
|
||||||
src="../../assets/video/login_feature.mp4"
|
|
||||||
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"
|
|
||||||
></video>
|
|
||||||
</transition>
|
</transition>
|
||||||
<div class="rightBox" v-if="isDesktop">
|
<div class="rightBox" v-if="isDesktop">
|
||||||
<el-button size="small" :icon="Setting" @click="serviceDialog = true"> </el-button>
|
<el-button size="small" :icon="Setting" @click="serviceDialog = true"> </el-button>
|
||||||
<el-button size="small" :icon="SwitchButton" @click="goExit"> </el-button>
|
<el-button size="small" :icon="SwitchButton" @click="goExit"> </el-button>
|
||||||
</div>
|
</div>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-show="showContent" class="content">
|
<div v-show="true" class="content">
|
||||||
<div class="titleBox">
|
<div class="titleBox">
|
||||||
<div class="titleItem">
|
<div class="titleItem">
|
||||||
<div>
|
<div>
|
||||||
@ -43,45 +24,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-form
|
<el-form class="login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginFormRef"
|
||||||
class="login-form"
|
label-position="left">
|
||||||
autoComplete="on"
|
|
||||||
:model="loginForm"
|
|
||||||
:rules="loginRules"
|
|
||||||
ref="loginFormRef"
|
|
||||||
label-position="left"
|
|
||||||
>
|
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input
|
<el-input name="username" type="text" v-model="loginForm.username" autoComplete="on" placeholder="请输入用户名"
|
||||||
name="username"
|
:prefix-icon="User" />
|
||||||
type="text"
|
|
||||||
v-model="loginForm.username"
|
|
||||||
autoComplete="on"
|
|
||||||
placeholder="请输入用户名"
|
|
||||||
:prefix-icon="User"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
<el-input
|
<el-input type="password" @keyup.enter.native="handleLogin(loginFormRef)" v-model="loginForm.password"
|
||||||
type="password"
|
autoComplete="on" placeholder="请输入密码" :prefix-icon="Unlock" show-password></el-input>
|
||||||
@keyup.enter.native="handleLogin(loginFormRef)"
|
|
||||||
v-model="loginForm.password"
|
|
||||||
autoComplete="on"
|
|
||||||
placeholder="请输入密码"
|
|
||||||
:prefix-icon="Unlock"
|
|
||||||
show-password
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item class="rememberForget">
|
<el-form-item class="rememberForget">
|
||||||
<!-- justify-content: space-around;align-items: center; -->
|
<!-- justify-content: space-around;align-items: center; -->
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<el-checkbox
|
<el-checkbox :disabled="loading" v-model="checkboxVModel" @change="rememberpwd"
|
||||||
:disabled="loading"
|
label="string">记住密码</el-checkbox>
|
||||||
v-model="checkboxVModel"
|
|
||||||
@change="rememberpwd"
|
|
||||||
label="string"
|
|
||||||
>记住密码</el-checkbox
|
|
||||||
>
|
|
||||||
<!-- <div style="cursor: pointer;">忘记密码?</div> -->
|
<!-- <div style="cursor: pointer;">忘记密码?</div> -->
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -105,11 +62,8 @@
|
|||||||
<div class="serviceContent">
|
<div class="serviceContent">
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<template v-for="item in serviceOptions">
|
<template v-for="item in serviceOptions">
|
||||||
<span
|
<span :class="['tab-item', selectedService == item.name ? 'activeService' : '']"
|
||||||
:class="['tab-item', selectedService == item.name ? 'activeService' : '']"
|
@click="selectedService = item.name">{{ item.name }}</span>
|
||||||
@click="selectedService = item.name"
|
|
||||||
>{{ item.name }}</span
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="tabPanel">
|
<div class="tabPanel">
|
||||||
@ -117,19 +71,13 @@
|
|||||||
<div class="item">
|
<div class="item">
|
||||||
<span class="itemLabel">服务选择:</span>
|
<span class="itemLabel">服务选择:</span>
|
||||||
<el-select class="select" v-model="servVal">
|
<el-select class="select" v-model="servVal">
|
||||||
<el-option
|
<el-option size="mini" v-for="item in servOptions" :key="item.value" :label="item.name"
|
||||||
size="mini"
|
:value="item.name">
|
||||||
v-for="item in servOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.name"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="prototype" v-if="servVal == '网络'">
|
<div class="prototype" v-if="servVal == '网络'">
|
||||||
<span class="itemLabel">协议:</span
|
<span class="itemLabel">协议:</span><el-input style="width: 200px" v-model="prototype"></el-input>
|
||||||
><el-input style="width: 200px" v-model="prototype"></el-input>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="item ip">
|
<div class="item ip">
|
||||||
<template v-if="servVal == '单机'">
|
<template v-if="servVal == '单机'">
|
||||||
@ -155,13 +103,8 @@
|
|||||||
<div class="item">
|
<div class="item">
|
||||||
<span class="itemLabel">串口选择:</span>
|
<span class="itemLabel">串口选择:</span>
|
||||||
<el-select class="select" v-model="gpsVal">
|
<el-select class="select" v-model="gpsVal">
|
||||||
<el-option
|
<el-option size="mini" v-for="item in gpsOptions" :key="item.value" :label="item.Product"
|
||||||
size="mini"
|
:value="item.Name">
|
||||||
v-for="item in gpsOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.Product"
|
|
||||||
:value="item.Name"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@ -245,44 +188,58 @@ onMounted(() => {
|
|||||||
.fade-leave-to {
|
.fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
.el-input__wrapper {
|
.el-input__wrapper {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 0.2px solid #00ffff;
|
border: 0.2px solid #00ffff;
|
||||||
box-shadow: 0 0 0 0.2px #00ffff inset !important; /* 新增此行 */
|
box-shadow: 0 0 0 0.2px #00ffff inset !important;
|
||||||
|
/* 新增此行 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 新增图标颜色控制 */
|
/* 新增图标颜色控制 */
|
||||||
.el-input__prefix,
|
.el-input__prefix,
|
||||||
.el-input__suffix {
|
.el-input__suffix {
|
||||||
.el-icon {
|
.el-icon {
|
||||||
color: #00ffff; /* 将#00ffff替换为你想用的颜色 */
|
color: #00ffff;
|
||||||
font-size: 18px; /* 可选:调整图标大小 */
|
/* 将#00ffff替换为你想用的颜色 */
|
||||||
|
font-size: 18px;
|
||||||
|
/* 可选:调整图标大小 */
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover .el-icon {
|
&:hover .el-icon {
|
||||||
color: #00ffff; /* 悬停颜色保持一致 */
|
color: #00ffff;
|
||||||
|
/* 悬停颜色保持一致 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-checkbox__label {
|
.el-checkbox__label {
|
||||||
color: #fff; // 使用与边框一致的青蓝色
|
color: #fff; // 使用与边框一致的青蓝色
|
||||||
font-size: 1rem; // 可选字体大小调整
|
font-size: 1rem; // 可选字体大小调整
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 保持悬停状态颜色一致
|
// // 保持悬停状态颜色一致
|
||||||
// .el-checkbox:hover .el-checkbox__label {
|
// .el-checkbox:hover .el-checkbox__label {
|
||||||
// color: #fff;
|
// color: #fff;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
.service {
|
.service {
|
||||||
.el-input__wrapper {
|
.el-input__wrapper {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 0.2px solid #00ffff;
|
border: 0.2px solid #00ffff;
|
||||||
box-shadow: 0 0 0 0.2px #00ffff inset !important; /* 新增此行 */
|
box-shadow: 0 0 0 0.2px #00ffff inset !important;
|
||||||
|
/* 新增此行 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .el-checkbox__label {
|
// .el-checkbox__label {
|
||||||
// color: #fff; // 使用与边框一致的青蓝色
|
// color: #fff; // 使用与边框一致的青蓝色
|
||||||
// // font-size: 0.8rem; // 可选字体大小调整
|
// // font-size: 0.8rem; // 可选字体大小调整
|
||||||
@ -294,8 +251,10 @@ onMounted(() => {
|
|||||||
.el-select__wrapper {
|
.el-select__wrapper {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 0.2px solid #00ffff;
|
border: 0.2px solid #00ffff;
|
||||||
box-shadow: 0 0 0 0.2px #00ffff inset !important; /* 新增此行 */
|
box-shadow: 0 0 0 0.2px #00ffff inset !important;
|
||||||
|
/* 新增此行 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select__placeholder,
|
.el-select__placeholder,
|
||||||
.el-select__tags-text {
|
.el-select__tags-text {
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
@ -388,6 +347,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.rightBox {
|
.rightBox {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
@ -400,6 +360,7 @@ onMounted(() => {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.service {
|
.service {
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@ -441,7 +402,7 @@ onMounted(() => {
|
|||||||
border-radius: 0 0 0 90%;
|
border-radius: 0 0 0 90%;
|
||||||
background: #00ffff;
|
background: #00ffff;
|
||||||
|
|
||||||
& > span {
|
&>span {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
@ -521,8 +482,10 @@ onMounted(() => {
|
|||||||
clip-path: polygon(0 0, calc(100% - 3px) 0, 100% 6px, 0 6px);
|
clip-path: polygon(0 0, calc(100% - 3px) 0, 100% 6px, 0 6px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border: 1px solid rgba(0, 255, 255, 0.5) !important;
|
border: 1px solid rgba(0, 255, 255, 0.5) !important;
|
||||||
background: rgba(0, 255, 255, 0.2) !important;
|
background: rgba(0, 255, 255, 0.2) !important;
|
||||||
|
@ -14,18 +14,18 @@ export const useLogin = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 新增监听逻辑
|
// 新增监听逻辑
|
||||||
watch(isFirstVideoPlayed, (newVal) => {
|
// watch(isFirstVideoPlayed, (newVal) => {
|
||||||
if (newVal) {
|
// if (newVal) {
|
||||||
if (newVal) {
|
// if (newVal) {
|
||||||
// 延迟一秒显示
|
// // 延迟一秒显示
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
showContent.value = true
|
// showContent.value = true
|
||||||
}, 800)
|
// }, 800)
|
||||||
} else {
|
// } else {
|
||||||
showContent.value = false
|
// showContent.value = false
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
const firstVideoRef = ref<HTMLVideoElement | null>(null) // 引用第一个视频元素
|
const firstVideoRef = ref<HTMLVideoElement | null>(null) // 引用第一个视频元素
|
||||||
// 登录表单引用
|
// 登录表单引用
|
||||||
const loginFormRef = ref<FormInstance>() // 用于获取表单实例
|
const loginFormRef = ref<FormInstance>() // 用于获取表单实例
|
||||||
@ -70,13 +70,15 @@ export const useLogin = () => {
|
|||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await LoginApi.login(loginForm.value)
|
const res = await LoginApi.login(loginForm.value)
|
||||||
if (res.code === 0) {
|
console.log(res);
|
||||||
|
|
||||||
|
if ([0,200].includes(res.code) ) {
|
||||||
checkboxVModel.value = true
|
checkboxVModel.value = true
|
||||||
localStorage.setItem('access_token', res.data.token)
|
localStorage.setItem(res.data.header, res.data.token)
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'userInfo',
|
'userInfo',
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
...res.data.userInfo,
|
// ...res.data.userInfo,
|
||||||
...loginForm.value,
|
...loginForm.value,
|
||||||
checkboxVModel: checkboxVModel.value
|
checkboxVModel: checkboxVModel.value
|
||||||
})
|
})
|
||||||
|