代码提交

dev_0.0.1_xq
刘政 2 weeks ago
parent 6311b3ff8d
commit 9bbb67637c

@ -0,0 +1,12 @@
import http from '@/api';
import {ADMIN_MODULE} from '@/api/helper/prefix';
import type {ComputerRoomRow} from "@/api/types/computerRoom/computerRoom";
/**
*
* @param params
* @returns {*}
*/
export const getListApi = (params: { substationId: number }) => {
return http.get<ComputerRoomRow[]>(ADMIN_MODULE + `/computerRoom/list`, params);
};

@ -8,3 +8,6 @@ export const getTreeData = () => {
export const getTreePreview=()=>{
return http.get<TreeNode[]>(ADMIN_MODULE + '/tree/preview');
}
export const getTreeSubstation=()=>{
return http.get<TreeNode[]>(ADMIN_MODULE + '/tree/substation');
}

@ -8,7 +8,7 @@ import type { AxiosRequestConfig } from 'axios';
export const File_Url = 'http://127.0.0.1:9991/api'
//http://localhost:8080/data/model/getModelData
export const getModelData = (params: {menuType:string}) => {
export const getModelData = (params: any) => {
return http.post(ADMIN_MODULE + `/data/model/getModelData`, params);
};

@ -0,0 +1,7 @@
// list或detail返回结构
export type ComputerRoomRow = {
id?: number;
substationId?: number;
name?: string;
description?: string;
};

@ -0,0 +1,108 @@
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { Picture } from '@element-plus/icons-vue'; //
import type { ComputerRoomRow } from "@/api/types/computerRoom/computerRoom";
import {useRouter} from "vue-router";
const drawer = ref(false);
const paramsProps = ref();
const computerRoomList = ref<ComputerRoomRow[]>([]);
const router = useRouter();
//
const acceptParams = async (params: any) => {
paramsProps.value = params;
const res = await paramsProps.value.getListApi({
substationId: paramsProps.value.data.id
});
if (res.code === '0000') {
computerRoomList.value = res.data;
}
drawer.value = true;
}
//
const handleViewPlan = (room: ComputerRoomRow) => {
router.push({
path:'/teacher/teacher-preview',
query: {
roomId: room.id
}
})
}
defineExpose({
acceptParams
})
</script>
<template>
<el-drawer v-model="drawer" title="机房列表" size="400px">
<div class="room-list-container">
<template v-if="computerRoomList.length > 0">
<div v-for="room in computerRoomList" :key="room.id" class="room-item">
<div class="room-info">
<div class="room-name">{{ room.name }}</div>
<div class="room-desc" v-if="room.description">{{ room.description }}</div>
</div>
<div class="room-action">
<el-button type="primary" plain :icon="Picture" size="small" @click="handleViewPlan(room)">
查看平面图
</el-button>
</div>
</div>
</template>
<el-empty v-else description="暂无绑定平面图的机房" />
</div>
</el-drawer>
</template>
<style scoped lang="scss">
.room-list-container {
padding: 0 5px;
.room-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 14px;
margin-bottom: 12px;
border: 1px solid #efefef;
border-radius: 6px;
transition: all 0.3s ease;
/* 悬浮时的交互反馈 */
&:hover {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
border-color: #c6e2ff;
}
.room-info {
flex: 1;
overflow: hidden; /* 防止文字过长挤压按钮 */
margin-right: 15px;
.room-name {
font-size: 15px;
font-weight: 600;
color: #303133;
margin-bottom: 6px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.room-desc {
font-size: 13px;
color: #909399;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.room-action {
flex-shrink: 0; /* 保证按钮不会被压缩 */
}
}
}
</style>

@ -23,11 +23,16 @@
<template #default="{ node, data }">
<span class="custom-tree-node">
<el-icon v-if="data.type === 0"><OfficeBuilding /></el-icon>
<el-icon v-else-if="data.type === 1"><School /></el-icon>
<div v-else-if="data.type===1">
<el-icon ><School /></el-icon>
</div>
<el-icon v-else-if="data.type === 2"><VideoCamera /></el-icon>
<span class="node-label" :class="{ 'ehv-text': data.type === 'STATION_EHV' }">
{{ node.label }}
</span>
<div v-if="data.type===1" style="margin-left: 5px;">
<el-button link type="primary" @click="showComputeRoom(data)"></el-button>
</div>
</span>
</template>
</el-tree>
@ -387,6 +392,8 @@
:curCamera="controlDialogObj.curCamera"
/>
</el-dialog>
<!-- 机房平面图列表组件-->
<compute-room-model-list ref="computeRoomRef"/>
</div>
</template>
@ -415,6 +422,8 @@ import {getAlgorithmTaskByCameraId} from "@/api/modules/monitor/algorithmTask";
import type {AlgorithmTaskVO, AlgTaskConfigDto} from "@/api/types/edgebox/EdgeBox";
import DataSync from "@/views/sysmonitortree/sysMonitorTree/components/DataSync.vue";
import {fa} from "element-plus/es/locale";
import ComputeRoomModelList from "@/views/sysmonitortree/sysMonitorTree/components/ComputeRoomModelList.vue";
import {getListApi} from "@/api/modules/computerRoom/computerRoom";
const refreshLoading=ref(false);
const playLoading = ref(false);
const filterText = ref('');
@ -465,6 +474,16 @@ const rules = reactive({
type: [{ required: true, message: '请填写类型' }],
channelDriver: [{ required: true, message: '请填写品牌' }],
});
const computeRoomRef=ref();
//
const showComputeRoom=(data:any)=>{
console.log(data)
const params={
data,
getListApi
}
computeRoomRef.value.acceptParams(params)
}
//
const ALGORITHM_MAP: Record<number, string> = {
8: "明烟明火检测",

@ -1,4 +1,5 @@
<template>
<div class="mt-preview">
<mt-preview ref="MtPreviewRef" @on-event-call-back="onEventCallBack"></mt-preview>
<!-- 数据模型 -->
<el-drawer v-model="drawerVisible" :modal="false" title="数据模型文件" modal-penetrable>
@ -9,6 +10,8 @@
</el-radio>
</el-radio-group>
</el-drawer>
</div>
</template>
<script setup lang="ts">
@ -29,6 +32,7 @@ import { modelApi } from '@/views/teacher/teacherStatistics/utils/request';
import vueSignalGaudy from "@/views/teacher/teacherStatistics/components/vue-xq-test/vue-signal-gaudy.vue";
import VueImg from "../teacherStatistics/components/vue-xq-test/vue-img.vue";
import VueCamera from "@/views/teacher/teacherStatistics/components/vue-xq-test/vue-camera.vue";
import {useRoute} from "vue-router";
const instance = getCurrentInstance();
instance?.appContext.app.component('vue-my-signal-gaudy', vueSignalGaudy);
instance?.appContext.app.component('vue-my-img', VueImg);
@ -169,23 +173,27 @@ function initLoad() {
MtPreviewRef.value?.setImportJson(endJson);
}
const route=useRoute();
async function newLoadModel() {
// let endJson = {
// menuType: route.query.screen
// };
let endJson = {
menuType: ''
};
try {
const response = await modelApi.model_getModelData_post(endJson);
const response = await modelApi.model_getModelData_post({
...endJson,
roomId: route.query.roomId
});
if (response.code == '0000') {
const result = response.data;
const { canvasCfg, gridCfg, importDoneJson } = useExportJsonToDoneJson(result);
// 1
const scaleX = window.innerWidth / canvasCfg.width;
const scaleY = window.innerHeight / canvasCfg.height;
canvasCfg.scale = Math.min(scaleX, scaleY); // canvasCfg
// importDoneJson props 使 reactive
const processedImportDoneJson = importDoneJson.map((item) => {
if (item.props) {
@ -199,21 +207,10 @@ async function newLoadModel() {
props: reactive(item.props || {})
};
});
console.log('processedImportDoneJson:', processedImportDoneJson);
MtPreviewRef.value?.setNewImportJson({ canvasCfg, gridCfg, json: processedImportDoneJson });
console.log('globalStore:', globalStore);
console.log('MtPreviewRef.value', MtPreviewRef.value);
// if (globalStore.group_ids.has(route.query.screen as string)) {
// globalStore.group_ids.delete(route.query.screen as string);
// }
// globalStore.group_ids.set(
// route.query.screen as string,
// processedImportDoneJson.map((item) => item.id)
// );
ElMessage.success('数据模型加载成功');
} else {
ElMessage.error(`数据模型加载失败: ${response.code} - ${response.message}`);
}
@ -224,42 +221,12 @@ async function newLoadModel() {
}
onUnmounted(() => {
console.log('view卸载完毕');
});
onMounted(() => {
console.log('view挂载完毕');
newLoadModel();
});
//
function loadModel() {
console.log('选中:', radio.value, radio);
if (!radio.value || radio.value == '-1') {
ElMessage.warning('请先选择一个模型文件');
}
fileNames.forEach((item) => {
if (item.id == radio.value) {
fetch(`/dataModes/${item.name}`)
.then((response) => response.json())
.then((data) => {
console.log('文件内容:', data);
const { canvasCfg, gridCfg, importDoneJson } = useExportJsonToDoneJson(data);
globalStore.canvasCfg = canvasCfg;
globalStore.gridCfg = gridCfg;
globalStore.setGlobalStoreDoneJson(importDoneJson);
initLoad();
})
.catch((error) => {
ElMessage.error('获取文件错误:', error);
});
}
});
}
function test2() {
console.log('test3', globalStore);
}
</script>
<style scoped>
@ -269,4 +236,5 @@ function test2() {
gap: 5px;
align-items: flex-start;
}
</style>

@ -0,0 +1,108 @@
<template>
<div class="room-select-container">
<!-- <div class="tree-header">请选择要绑定模型的机房</div>-->
<slot></slot>
<el-scrollbar max-height="50vh">
<el-tree
ref="roomTreeRef"
:data="treeData"
:props="treeProps"
node-key="id"
highlight-current
default-expand-all
@node-click="handleNodeClick"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<el-icon v-if="data.type === 'station'" color="#409EFC"><OfficeBuilding /></el-icon>
<el-icon v-else color="#67C23A"><Monitor /></el-icon>
<span style="margin-left: 5px">{{ node.label }}</span>
</span>
</template>
</el-tree>
</el-scrollbar>
<div class="selection-footer" v-if="selectedRoom">
已选机房<el-tag type="success">{{ selectedRoom.name }}</el-tag>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { OfficeBuilding, Monitor } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import {getTreeSubstation} from "@/api/modules/monitor/Tree.js";
//
const emit = defineEmits(['room-selected'])
const roomTreeRef = ref(null)
const selectedRoom = ref(null)
//
const treeProps = {
children: 'children',
label: 'name'
}
// ()
const treeData = ref([])
//
const fetchTreeData =async () => {
// ry_computer_room
const res=await getTreeSubstation();
if(res.code==='0000')
{
treeData.value=res.data;
}
}
//
const handleNodeClick = (data, node) => {
//
if (data.type === 1) {
ElMessage.warning('请选择具体的机房,而不是变电站')
roomTreeRef.value.setCurrentKey(selectedRoom.value?.id || null) //
return
}
//
selectedRoom.value = data
// ID ID
emit('room-selected', {
roomId: data.id,
substationId: data.substationId,
roomName: data.name
})
}
onMounted(() => {
fetchTreeData()
})
</script>
<style scoped>
.room-select-container {
border-radius: 4px;
padding: 10px;
}
.tree-header {
font-size: 14px;
font-weight: bold;
margin-bottom: 15px;
color: #606266;
padding-bottom: 8px;
}
.custom-tree-node {
display: flex;
align-items: center;
font-size: 14px;
}
.selection-footer {
margin-top: 15px;
padding-top: 10px;
}
</style>

@ -101,6 +101,10 @@
<!-- 数据文件存储 -->
<el-button type="primary" size="small" @click="emits('onRightDrawer')">
保存模型
</el-button>
<el-button type="primary" size="small" @click="emits('onModelList')">
模型文件
</el-button>
@ -177,6 +181,7 @@ const emits = defineEmits([
'onDrawLineClick',
'onThumbnailClick',
'onRightDrawer',
'onModelList',
'onImageDialog'
]);
const isDark = useDark({

@ -36,6 +36,7 @@
@on-thumbnail-click="onThumbnailClick"
@on-draw-line-click="onDrawLineClick"
@on-right-drawer="onRightDrawer"
@on-model-list="onModelList"
@on-image-dialog="onImageDialog"
>
</header-panel>
@ -108,28 +109,43 @@
></done-tree>
</el-drawer>
<!-- xxxx -->
<el-dialog v-model="drawerVisible" title="数据模型" width="35%">
<span>注意保存后会覆盖之前的模型文件</span>
<!-- 选择机房的弹框 -->
<el-dialog v-model="drawerVisible" title="保存模型" width="50%"
draggable
destroy-on-close
@close="drawerVisible = false"
align-center>
<RoomSelectTree @roomSelected="handleRoomSelected">
<div class="tree-header">
请选择要绑定模型的机房
</div>
</RoomSelectTree>
<template #footer>
<div class="dialog-footer">
<el-button @click="doSaveModel"></el-button>
<el-button @click="loadModel" type="primary"> 加载</el-button>
<el-button @click="drawerVisible = false">取消</el-button>
</div>
</template>
</el-dialog>
<!-- end -->
<!-- 数据保存弹框 -->
<el-dialog v-model="dialogFormVisible" title="数据模型保存" width="500">
<span>确定保存或者覆盖 {{ fileName }} 模型文件</span>
<!-- 选择模型文件的弹框 -->
<el-dialog v-model="modelListDialogVisible" title="模型文件列表" width="50%"
draggable
destroy-on-close
@close="modelListDialogVisible = false"
align-center>
<RoomSelectTree @roomSelected="handleRoomSelected">
<div class="tree-header">
请选择机房模型
</div>
</RoomSelectTree>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" v-loading.fullscreen.lock="fullscreenLoading"> 确定 </el-button>
<el-button @click="loadModel"></el-button>
<el-button @click="modelListDialogVisible = false">取消</el-button>
</div>
</template>
</el-dialog>
<!-- end -->
<!-- 图片模型 -->
<imageModel
v-if="dialogImageVisible"
@ -162,6 +178,7 @@ import { genExportJson, useExportJsonToDoneJson } from './composables';
import type { IExportJson } from './components/types';
import imageModel from '@/views/teacher/teacherStatistics/components/mt-edit/components/layout/base-panel/imageModel.vue';
import { saveOrUpdateModelData, getModelData } from '@/api/modules/teacher/teacherStatistics';
import RoomSelectTree from "@/views/teacher/teacherStatistics/components/custom-componet/RoomSelectTree.vue";
interface Tree {
id: string;
@ -170,14 +187,7 @@ interface Tree {
children?: Tree[];
}
const props = {
value: 'id',
label: 'label',
children: 'children',
disabled: 'disabled'
};
let treeData: Tree[] = [];
function updateDialogImageVisible() {
dialogImageVisible.value = false;
@ -191,7 +201,7 @@ const onImageDialog = () => {
let drawerVisible = ref(false);
let dialogFormVisible = ref(false);
let dialogImageVisible = ref(false);
let fileName = ref('');
let menuType = ref('');
type MtEditProps = {
@ -289,22 +299,37 @@ const onImportYes = async () => {
ElMessage.error('导入失败,请检查数据格式');
}
};
const roomData=ref();
const handleRoomSelected=(data:any)=>{
roomData.value=data;
}
//
async function doSaveModel() {
fullscreenLoading.value = true;
if(!roomData.value)
{
ElMessage.error('请选择机房');
return;
}
const { exportJson } = genExportJson(globalStore.canvasCfg, globalStore.gridCfg, globalStore.done_json);
console.log('保存数据',exportJson.json)
let endJson = {
menuType: menuType.value,
canvasCfg: exportJson.canvasCfg,
gridCfg: exportJson.gridCfg,
json: exportJson.json
};
if (endJson.json.length == 0)
{
ElMessage.error('请添加模型');
return;
}
try {
const response = await saveOrUpdateModelData(endJson);
// const response = await modelApi.saveOrUpdate_modelData_post(endJson);
const response = await saveOrUpdateModelData({
...endJson,
roomId: roomData.value.roomId,
substationId:roomData.value.substationId
});
if (response.code == '0000') {
fullscreenLoading.value = false;
dialogFormVisible.value = false;
@ -328,17 +353,7 @@ async function doSaveModel() {
}
}
function saveModel() {
let nodes = treeRef.value?.getCheckedNodes();
console.log(nodes?.length);
if (nodes?.length === 0) {
ElMessage.warning('请至少选择一个模型文件');
} else {
dialogFormVisible.value = true;
fileName.value = nodes?.[0].label;
menuType.value = nodes?.[0].id;
}
}
async function loadModel() {
fullscreenLoading.value = false;
@ -346,9 +361,11 @@ async function loadModel() {
menuType: ''
};
console.log('请求数据类型:', typeof JSON.stringify(endJson));
try {
const response = await getModelData(endJson);
const response = await getModelData({
...endJson,
roomId: roomData.value.roomId,
});
// const response = await modelApi.model_getModelData_post(endJson);
console.log('响应状态:', typeof response);
if (response.code == '0000') {
@ -392,16 +409,17 @@ const onDrawLineClick = (val: boolean) => {
line_append_enable.value = val;
};
let fileNames: Array<{ id: string; name: string }> = reactive([]);
let radio = ref('-1');
//
const fullscreenLoading = ref(false);
const modelListDialogVisible = ref(false);
const onRightDrawer = () => {
drawerVisible.value = true;
// fileRead();
};
const onModelList=()=>{
modelListDialogVisible.value=true;
}
onMounted(() => {
// fileRead();
@ -433,7 +451,6 @@ const setImportJson = (exportJson: IExportJson) => {
return true;
};
const treeRef = ref<InstanceType<typeof ElTreeV2> | null>();
defineExpose({
setImportJson
});
@ -463,4 +480,11 @@ defineExpose({
gap: 5px;
align-items: flex-start;
}
.tree-header {
font-size: 14px;
font-weight: bold;
margin-bottom: 15px;
color: #606266;
padding-bottom: 8px;
}
</style>

@ -14,9 +14,7 @@ export const leftAsideStore: ILeftAside = reactive({
ElMessage.info(`title:${title}已被系统占用,请更换名称!`);
return;
}
if (leftAsideStore.config.has(title)) {
ElMessage.info(`title:${title}已存在,已经将其配置覆盖`);
}
// 已存在时静默覆盖,不再提示
const cfg: ILeftAsideConfigItem[] = config.map((m) => {
if (m.type == 'svg') {
const { symbol_str, width, height } = svgToSymbol(m.svg!, m.id);

Loading…
Cancel
Save