548 lines
16 KiB
Vue
548 lines
16 KiB
Vue
<script setup lang="ts">
|
||
import { getCurrentInstance } from 'vue';
|
||
import { getModelList, getModelTypeList, addOtherSource } from '@/views/largeScreen/components/api';
|
||
import { useTreeNode } from '../treeNode';
|
||
const isShowPup = ref(false);
|
||
const categories = ref<any[]>([]);
|
||
const loading = ref(false);
|
||
const { cusAddNodes } = useTreeNode();
|
||
//-----------类型树-----------
|
||
|
||
interface TypeNode {
|
||
id: string;
|
||
label: string;
|
||
parentId: string | null;
|
||
children?: TypeNode[];
|
||
}
|
||
let typeArr = {
|
||
point: '点',
|
||
line: '线',
|
||
area: '面'
|
||
};
|
||
const currentTypeId = ref<string>('');
|
||
const typeTreeData = ref<TypeNode[]>([]);
|
||
|
||
let activeIndex: any = ref(null);
|
||
// 获取组件实例
|
||
const instance = getCurrentInstance();
|
||
instance.proxy['$recvChanel']('open-model', () => {
|
||
console.log('open-model');
|
||
isShowPup.value = true;
|
||
typeList();
|
||
});
|
||
const typeList = async () => {
|
||
const res: any = await getModelTypeList();
|
||
if (res.code == 0 || res.code == 200) {
|
||
console.log('typeList', res);
|
||
let data = transformNestedJson(res.data, 'name', 'label');
|
||
typeTreeData.value = data;
|
||
}
|
||
};
|
||
const transformNestedJson = (data, oldKey, newKey) => {
|
||
if (Array.isArray(data)) {
|
||
return data.map((item) => transformNestedJson(item, oldKey, newKey));
|
||
} else if (data && typeof data === 'object') {
|
||
const newObj = {};
|
||
for (const key in data) {
|
||
// 替换键名
|
||
const currentKey = key === oldKey ? newKey : key;
|
||
// 递归处理子元素
|
||
newObj[currentKey] = transformNestedJson(data[key], oldKey, newKey);
|
||
}
|
||
return newObj;
|
||
}
|
||
return data;
|
||
};
|
||
const handleTypeClick = (row: TypeNode) => {
|
||
getModelListByType(row.id);
|
||
currentTypeId.value = row['$treeNodeId'];
|
||
};
|
||
const getModelListByType = (id) => {
|
||
let formData = new FormData();
|
||
formData.append('modelTypeId', id);
|
||
console.log('formData', formData.get('modelTypeId'));
|
||
getModelList(formData).then((res) => {
|
||
categories.value = res.data;
|
||
});
|
||
};
|
||
const filterNode: any = (value, data) => {
|
||
if (!value) return true;
|
||
return data.label.includes(value);
|
||
};
|
||
const modelClick = (index, row) => {
|
||
activeIndex.value = index;
|
||
console.log('modelClick', row);
|
||
|
||
// 轨迹运动选择模型
|
||
// if (selectCallback && typeof selectCallback === 'function' && addType.value === 'trajectoryMotion') {
|
||
// selectCallback('http://127.0.0.1:8848' + row.data);
|
||
// close();
|
||
// return;
|
||
// }
|
||
|
||
// if (!isSetting) {
|
||
// ElMessage.warning('请先设置模型默认参数');
|
||
// return;
|
||
// }
|
||
|
||
isShowPup.value = false;
|
||
let id = new window['YJ'].Tools().randomString();
|
||
new window['YJ'].Obj.BatchModel(window['Earth1'], { id, type: typeArr['point'] }, function (data) {
|
||
console.log(data);
|
||
renderModel(data, row);
|
||
});
|
||
const renderModel = async (option, model) => {
|
||
let selectedNode = window['treeObj'].getSelectedNodes()[0];
|
||
// 存在坐标
|
||
if (option.positions.length > 0) {
|
||
let id = new window['YJ'].Tools().randomString();
|
||
let params = {
|
||
id: id,
|
||
position: option.positions[0],
|
||
name: model.modelName,
|
||
show: true,
|
||
scale: { x: 1, y: 1, z: 1 },
|
||
url: getURL(model.modelDataUrl),
|
||
maximumScale: 1,
|
||
rotate: {
|
||
x: 0,
|
||
y: 0,
|
||
z: 0
|
||
}
|
||
};
|
||
await new window['YJ'].Obj.Model(window['Earth1'], params);
|
||
let DbOption: any = {
|
||
params,
|
||
id,
|
||
sourceName: model.modelName,
|
||
sourceType: 'model',
|
||
parentId: selectedNode ? (selectedNode.sourceType == 'directory' ? selectedNode.id : selectedNode.parentId) : undefined
|
||
};
|
||
|
||
addOtherSource(DbOption);
|
||
DbOption.params = JSON.stringify(DbOption.params);
|
||
DbOption.isShow = true;
|
||
cusAddNodes(window['treeObj'], DbOption.parentId, [DbOption]);
|
||
}
|
||
};
|
||
};
|
||
const getURL = (url) => {
|
||
// 'http://192.168.110.2:3456';
|
||
return import.meta.env.VITE_APP_MAP_API + url;
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<div class="set_pup">
|
||
<el-dialog :close-on-click-modal="false" v-model="isShowPup" :modal="false" draggable>
|
||
<template #header>
|
||
<div class="set_pup_header">
|
||
<div class="system_title">模型选择</div>
|
||
</div>
|
||
</template>
|
||
<div class="set_detail">
|
||
<!-- 搜索和参数设置-->
|
||
<!-- <div class="top">
|
||
<el-input v-model="modelName" class="w-50 m-2" placeholder="请输入模型名称进行搜索" :suffix-icon="Search" />
|
||
<button @click="setting" class="btn">
|
||
<svg-icon name="sys_set" class="setIcon" :size="12" color="rgba(255,255,255, 1)" style="margin-right: 5px"></svg-icon>默认模型参数设置
|
||
</button>
|
||
</div>-->
|
||
<div class="content">
|
||
<!-- 左侧Tab导航 -->
|
||
<div class="treeCon">
|
||
<el-tree
|
||
style="max-width: 600px"
|
||
:data="typeTreeData"
|
||
ref="treeRef"
|
||
node-key="id"
|
||
@node-click="handleTypeClick"
|
||
:filter-node-method="filterNode"
|
||
>
|
||
<template #default="{ node, data }">
|
||
<!-- <span> {{ node.label }}</span> -->
|
||
<!-- @click.stop="toggleExpand(node)" @click.stop="toggleExpand(node)" -->
|
||
<span
|
||
:class="{
|
||
'primary-type': !(node.childNodes.length != 0),
|
||
'selected-text': node.id === currentTypeId
|
||
}"
|
||
|
||
class="allowDrag"
|
||
>
|
||
<svg-icon
|
||
:name="node.expanded ? 'arrow' : 'more'"
|
||
:size="12"
|
||
color="rgba(0, 255, 255, 1)"
|
||
style="margin-right: 5px; margin-left: 5px"
|
||
v-if="node.childNodes.length != 0"
|
||
|
||
></svg-icon>
|
||
{{ node.label }}</span
|
||
>
|
||
</template>
|
||
</el-tree>
|
||
</div>
|
||
|
||
<div class="model-gallery" ref="galleryRef">
|
||
<div class="model-section">
|
||
<!-- <h2 class="section-title">{{ categories[Number(currentTypeId)].name }}</h2> -->
|
||
<div class="model-grid">
|
||
<div v-for="(model, mIndex) in categories" :key="mIndex" class="model-item" @click="modelClick(mIndex, model)">
|
||
<div class="imgbg">
|
||
<el-image :src="getURL(model.posterDataUrl)" fit="cover" class="thumbnail">
|
||
<!-- <template #error>-->
|
||
<!-- <div class="image-error">加载失败</div>-->
|
||
<!-- </template>-->
|
||
</el-image>
|
||
</div>
|
||
|
||
<div class="model-name" :class="{ isactive: activeIndex == mIndex }">
|
||
{{ model.modelName }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-show="loading" class="loading-more">加载中...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
:root {
|
||
--color-sdk-base-rgb: 0, 255, 255;
|
||
--color-sdk-auxiliary: 0, 66, 66;
|
||
--color-sdk-auxiliary-public: #ffffff;
|
||
--color-sdk-warning-0: #1bf8c3;
|
||
--color-sdk-warning-1: #f16c55;
|
||
--color-sdk-warning-2: #ffa145;
|
||
--color-sdk-warning-3: #ffdf53;
|
||
--color-sdk-text-head: #ffffff;
|
||
--color-sdk-text-head-1: #e6f7ff;
|
||
--color-sdk-text-head-2: #adf1ff;
|
||
--color-sdk-gradual: rgb(0, 255, 255) 6.25%, rgb(0, 200, 255) 100%;
|
||
--color-sdk-bg-gradual: #00ffff33 0%, #00ffff00 100%;
|
||
--color-sdk-text-shadow: rgba(20, 118, 255, 1);
|
||
}
|
||
.set_pup {
|
||
position: fixed;
|
||
width: 40vw;
|
||
height: 50vh;
|
||
: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-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: #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/map/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;
|
||
}
|
||
}
|
||
.set_detail {
|
||
box-sizing: border-box;
|
||
// height: 50vh;
|
||
:deep(
|
||
.el-tabs--left .el-tabs__active-bar.is-left,
|
||
.el-tabs--left .el-tabs__active-bar.is-right,
|
||
.el-tabs--right .el-tabs__active-bar.is-left,
|
||
.el-tabs--right .el-tabs__active-bar.is-right
|
||
) {
|
||
width: 3px;
|
||
background: rgba(0, 255, 255, 1);
|
||
height: 40px !important;
|
||
}
|
||
|
||
:deep(
|
||
.el-tabs--left .el-tabs__nav-wrap.is-left::after,
|
||
.el-tabs--left .el-tabs__nav-wrap.is-right::after,
|
||
.el-tabs--right .el-tabs__nav-wrap.is-left::after,
|
||
.el-tabs--right .el-tabs__nav-wrap.is-right::after
|
||
) {
|
||
width: 3px;
|
||
}
|
||
|
||
:deep(.el-tabs__nav-wrap::after) {
|
||
background: rgba(204, 204, 204, 0.5);
|
||
border-radius: 4px;
|
||
}
|
||
|
||
// .switchmy {
|
||
// display: flex;
|
||
// flex-wrap: wrap;
|
||
// margin-top: 15px;
|
||
|
||
// .center {
|
||
// width: 33%;
|
||
// margin-bottom: 15px;
|
||
// }
|
||
// }
|
||
:deep(.el-tabs__content) {
|
||
height: 50vh;
|
||
width: 80%;
|
||
padding: 0 10px;
|
||
overflow: hidden;
|
||
overflow-y: scroll;
|
||
color: #fff;
|
||
}
|
||
|
||
// 美化滚动条
|
||
:deep(.el-tabs__content::-webkit-scrollbar) {
|
||
width: 5px;
|
||
height: 5px;
|
||
}
|
||
:deep(.el-tabs__content::-webkit-scrollbar-thumb) {
|
||
background-color: #0ff;
|
||
border-radius: 5px;
|
||
}
|
||
:deep(.el-tabs__content::-webkit-scrollbar-track) {
|
||
background-color: rgba(0, 255, 255, 0.2);
|
||
}
|
||
:deep(.el-tabs__item) {
|
||
width: 8vw;
|
||
color: #fff !important;
|
||
font-size: 1.1rem;
|
||
font-family: 黑体;
|
||
font-weight: 500;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 3px;
|
||
box-sizing: border-box;
|
||
}
|
||
:deep(.el-tabs__item:hover) {
|
||
background: linear-gradient(90deg, rgba(0, 255, 255, 0) 0%, rgba(0, 255, 255, 0.5) 48.91%, rgba(0, 255, 255, 0) 100%);
|
||
border: 1px solid;
|
||
box-sizing: border-box;
|
||
border-image: linear-gradient(90deg, rgba(0, 255, 255, 0) 0%, rgba(0, 255, 255, 1) 55.55%, rgba(0, 255, 255, 0) 100%) 1;
|
||
}
|
||
:deep(.el-tabs__item.is-active) {
|
||
background: linear-gradient(90deg, rgba(0, 255, 255, 0) 0%, rgba(0, 255, 255, 0.5) 48.91%, rgba(0, 255, 255, 0) 100%) !important;
|
||
border: 0.1px solid;
|
||
// box-sizing: border-box;
|
||
border-image: linear-gradient(90deg, rgba(0, 255, 255, 0) 0%, rgba(0, 255, 255, 1) 55.55%, rgba(0, 255, 255, 0) 100%) 1 !important;
|
||
}
|
||
:deep(.el-tabs__header) {
|
||
height: 50vh !important;
|
||
width: 8vw;
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
}
|
||
:deep(.el-tabs__nav-next, .el-tabs__nav-prev) {
|
||
color: #fff;
|
||
}
|
||
}
|
||
.el-input {
|
||
width: 300px;
|
||
margin-left: 30px;
|
||
|
||
--el-input-placeholder-color: rgba(173, 241, 255, 1) !important;
|
||
--el-input-placeholder-font-size: 14px;
|
||
--el-input-text-color: #fff;
|
||
--el-input-border-color: rgba(var(--color-sdk-base-rgb), 0.5) !important;
|
||
--el-input-hover-border-color: rgba(var(--color-sdk-base-rgb), 0.5) !important;
|
||
--el-input-focus-border-color: rgba(var(--color-sdk-base-rgb), 0.5) !important;
|
||
}
|
||
::v-deep .el-input__wrapper {
|
||
background-color: rgba(0, 0, 0, 0.5) !important;
|
||
}
|
||
.btn {
|
||
float: right;
|
||
height: 32px;
|
||
line-height: 32px;
|
||
background: rgba(var(--color-sdk-base-rgb), 0.2) !important;
|
||
border: 1px solid rgba(var(--color-sdk-base-rgb), 0.5) !important;
|
||
border-radius: 4px;
|
||
color: #fff !important;
|
||
padding: 0 15px;
|
||
}
|
||
.btn:hover {
|
||
color: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
border: 1px solid rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
.setIcon {
|
||
color: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
}
|
||
}
|
||
|
||
.content {
|
||
margin-top: 20px;
|
||
height: 400px;
|
||
}
|
||
}
|
||
.model-container {
|
||
display: flex;
|
||
height: 100vh;
|
||
}
|
||
.model-tabs {
|
||
width: 130px;
|
||
height: 100%;
|
||
float: left;
|
||
}
|
||
.treeCon {
|
||
width: 140px;
|
||
height: 100%;
|
||
float: left;
|
||
border-right: 1px solid rgba(204, 204, 204, 0.2);
|
||
}
|
||
.model-gallery {
|
||
flex: 1;
|
||
/* padding: 20px; */
|
||
overflow-y: auto;
|
||
height: 100%;
|
||
width: calc(100% - 160px);
|
||
float: left;
|
||
margin-left: 10px;
|
||
}
|
||
.model-section {
|
||
min-height: 10vh;
|
||
margin-bottom: 40px;
|
||
}
|
||
.model-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
/* justify-content: space-around; */
|
||
//justify-content: space-between;
|
||
gap: 10px;
|
||
}
|
||
.model-name {
|
||
width: 100%;
|
||
//height: 30px;
|
||
//line-height: 30px;
|
||
text-align: center;
|
||
word-break: break-all;
|
||
/* overflow-wrap: break-word; */
|
||
overflow-wrap: break-word;
|
||
color: rgba(255, 255, 255, 1);
|
||
}
|
||
.isactive {
|
||
color: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
}
|
||
.model-item {
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
width: 18%;
|
||
/* box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); */
|
||
}
|
||
.model-item:hover {
|
||
cursor: pointer !important;
|
||
color: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
.model-name {
|
||
color: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
}
|
||
}
|
||
|
||
.imgbg {
|
||
//width: 70px;
|
||
//height: 70px;
|
||
width: 100%;
|
||
margin: 0 auto;
|
||
background: url('@/assets/images/map/model-bg.png') no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
.thumbnail {
|
||
width: 100%;
|
||
//width: 66px;
|
||
//height: 66px;
|
||
//margin-left: 2px;
|
||
//margin-top: 2px;
|
||
}
|
||
.loading-more {
|
||
text-align: center;
|
||
padding: 20px;
|
||
}
|
||
|
||
::v-deep .el-tabs__content {
|
||
display: none !important;
|
||
}
|
||
/* 修改滚动条轨道的颜色 */
|
||
::v-deep ::-webkit-scrollbar-track {
|
||
background: rgba(var(--color-sdk-base-rgb), 0.1) !important;
|
||
}
|
||
/* 修改滚动条滑块的样式 */
|
||
::v-deep ::-webkit-scrollbar-thumb {
|
||
background: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
/* 当滑块被激活(用户点击或拖动时) */
|
||
::v-deep ::-webkit-scrollbar-thumb:hover {
|
||
background: rgba(var(--color-sdk-base-rgb), 1) !important;
|
||
}
|
||
</style>
|
||
<style>
|
||
::-webkit-scrollbar {
|
||
width: 5px;
|
||
height: 5px;
|
||
}
|
||
/* 定义背景颜色和圆角 */
|
||
::-webkit-scrollbar-thumb {
|
||
border-radius: 1em;
|
||
background-color: rgba(50, 50, 50, 0.3);
|
||
}
|
||
/* //定义滚动条轨道 内阴影+圆角 */
|
||
::-webkit-scrollbar-track {
|
||
border-radius: 1em;
|
||
background-color: rgba(50, 50, 50, 0.1);
|
||
}
|
||
|
||
/* tree */
|
||
.el-tree-node__content > .el-tree-node__expand-icon {
|
||
display: none !important;
|
||
}
|
||
.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;
|
||
}
|
||
::v-deep .el-text {
|
||
color: rgba(255, 255, 255, 1) !important;
|
||
font-size: 12px !important;
|
||
}
|
||
.selected-text {
|
||
color: rgba(var(--color-sdk-base-rgb), 1) !important; /* Element UI主色,可自定义 */
|
||
}
|
||
::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
|
||
border-right: 1px solid rgba(var(--color-sdk-base-rgb), 0.2) !important;
|
||
}
|
||
</style>
|