<template>
|
|
<CardBox
|
|
class="card-page page-content"
|
|
:showTitle="false"
|
|
>
|
|
<div class="sec-left point-layout app-container card-page" style="height: 100%">
|
|
<!-- 左侧可拖拽区域 - 只影响左侧树 -->
|
|
<div class="resize-container" :style="{ width: leftPanelWidth + 'px' }">
|
|
<div class="sec-line">
|
|
<div class="search">
|
|
<el-input
|
|
placeholder="搜索设备类型、设备部位"
|
|
icon="el-icon-search"
|
|
v-model="inputSearch1"
|
|
></el-input>
|
|
<el-button
|
|
class="button task-toolbar-btn"
|
|
type="primary"
|
|
icon="el-icon-search"
|
|
@click="searchTree"
|
|
></el-button>
|
|
</div>
|
|
<div class="sec-a2">
|
|
<el-tree
|
|
node-key="areaid"
|
|
class="xg_tree"
|
|
@current-change="handleAreaTreeCurrentNodeChange"
|
|
ref="areaTree"
|
|
:data="areaList"
|
|
:props="defaultPropsArea"
|
|
@node-click="handleAreaList"
|
|
>
|
|
<span class="custom-tree-node" slot-scope="{ data }">
|
|
<span class="node-content">{{ getNodeLabel(data) }}</span>
|
|
<span v-if="shouldShowCount(data)" class="child-count">
|
|
({{ data.pointNum || 0 }})
|
|
</span>
|
|
</span>
|
|
</el-tree>
|
|
</div>
|
|
<div
|
|
class="resize-handle"
|
|
@mousedown="startResize"
|
|
:class="{ resizing: isResizing }"
|
|
>
|
|
<div class="handle-line"></div>
|
|
<div class="handle-dots">
|
|
<span></span>
|
|
<span></span>
|
|
<span></span>
|
|
</div>
|
|
</div>
|
|
<!-- 添加重置宽度按钮 -->
|
|
<div
|
|
class="reset-width-btn"
|
|
@click="resetLeftPanelWidth"
|
|
title="重置面板宽度"
|
|
>
|
|
<i class="el-icon-refresh"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 中间内容区域 - 保持原有结构,不受拖拽影响 -->
|
|
<div
|
|
class="wid"
|
|
:class="{ 'has-right-panel': showRightPanel }"
|
|
:style="{ left: leftPanelWidth + 10 + 'px' }"
|
|
>
|
|
<div class="form" style="padding-top: 10px" ref="form">
|
|
<div class="line">
|
|
<div class="left-buttons">
|
|
<!-- 添加点位按钮(汇聚门户进入的只读视图下隐藏) -->
|
|
<el-button
|
|
v-if="!$store.getters.fromPortal"
|
|
type="primary"
|
|
class="task-toolbar-btn"
|
|
@click="addAlertShow1"
|
|
:disabled="
|
|
currentTreeNode === null ||
|
|
currentTreeNode.deviceId === null ||
|
|
batchDeleteMode
|
|
"
|
|
size="small"
|
|
icon="el-icon-plus"
|
|
>添加</el-button
|
|
>
|
|
<!-- 批量删除模式切换按钮(汇聚门户进入的只读视图下隐藏) -->
|
|
<el-button
|
|
v-if="!$store.getters.fromPortal"
|
|
class="task-toolbar-btn"
|
|
:type="batchDeleteMode ? 'info' : 'danger'"
|
|
@click="toggleBatchDeleteMode"
|
|
size="small"
|
|
:icon="batchDeleteMode ? 'el-icon-close' : 'el-icon-delete'"
|
|
>
|
|
{{ batchDeleteMode ? "取消批量删除" : "批量删除" }}
|
|
</el-button>
|
|
<!-- 确认删除按钮 - 仅在批量删除模式下显示 -->
|
|
<el-button
|
|
v-if="batchDeleteMode && !$store.getters.fromPortal"
|
|
type="danger"
|
|
class="task-toolbar-btn"
|
|
@click="confirmBatchDelete"
|
|
size="small"
|
|
icon="el-icon-check"
|
|
:disabled="batchSelectList.length === 0"
|
|
>
|
|
确认删除({{ batchSelectList.length }})
|
|
</el-button>
|
|
</div>
|
|
<div class="search-group right-filters">
|
|
<!-- 算法分类筛选下拉框 - 使用接口返回数据 -->
|
|
<el-select
|
|
v-model="selectedAlgorithmCategory"
|
|
placeholder="全部算法分类"
|
|
clearable
|
|
@change="filterByAlgorithmCategory"
|
|
class="algorithm-filter"
|
|
size="small"
|
|
>
|
|
<el-option
|
|
v-for="item in algorithmCategoryOptions"
|
|
:key="item.dictCode"
|
|
:label="item.dictLabel"
|
|
:value="item.dictValue"
|
|
>
|
|
<span>{{ item.dictLabel }}</span>
|
|
<span
|
|
style="
|
|
float: right;
|
|
color: #8492a6;
|
|
font-size: 12px;
|
|
margin-left: 10px;
|
|
"
|
|
>
|
|
{{ getAlgorithmCategoryCount(item) }}
|
|
</span>
|
|
</el-option>
|
|
</el-select>
|
|
|
|
<!-- 设备类型筛选下拉框 -->
|
|
<el-select
|
|
v-model="selectedDeviceType"
|
|
placeholder="全部设备类型"
|
|
clearable
|
|
@change="filterByDeviceType"
|
|
class="device-type-filter"
|
|
size="small"
|
|
>
|
|
<el-option
|
|
v-for="item in deviceTypeOptions"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value"
|
|
>
|
|
<span>{{ item.label }}</span>
|
|
<span
|
|
style="
|
|
float: right;
|
|
color: #8492a6;
|
|
font-size: 12px;
|
|
margin-left: 10px;
|
|
"
|
|
>
|
|
{{ item.count }}
|
|
</span>
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
</div>
|
|
|
|
<el-table
|
|
v-loading="loading"
|
|
element-loading-background="rgba(34, 47, 61, 0.92)"
|
|
ref="multipleTable"
|
|
:row-key="getRowKey"
|
|
@selection-change="handleSelectionChange"
|
|
@row-click="handleRowClick"
|
|
highlight-current-row
|
|
stripe
|
|
:fit="false"
|
|
:height="tableHeight"
|
|
:data="filteredTableData"
|
|
tooltip-effect="dark"
|
|
style="width: 100%"
|
|
class="custom-table resizable-table"
|
|
:header-cell-style="{
|
|
background: '#012773',
|
|
color: '#ffffff',
|
|
fontWeight: 'bold',
|
|
borderBottom: '2px solid #0b374e',
|
|
}"
|
|
:cell-style="{
|
|
color: '#e0e0e0',
|
|
borderBottom: '1px solid #1e3a4a',
|
|
}"
|
|
>
|
|
<!-- 序号/复选框列 - 根据模式动态显示,使用key强制重新渲染 -->
|
|
<el-table-column
|
|
v-if="batchDeleteMode"
|
|
:key="'selection-' + batchDeleteMode"
|
|
type="selection"
|
|
align="center"
|
|
width="55"
|
|
:selectable="checkSelectable"
|
|
>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-else
|
|
:key="'index-' + batchDeleteMode"
|
|
align="center"
|
|
label="序号"
|
|
width="55"
|
|
>
|
|
<template slot-scope="scope">
|
|
<span>{{ getRowIndex(scope.$index) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column
|
|
prop="patrolpointName"
|
|
header-align="center"
|
|
label="点位名称"
|
|
width="400"
|
|
>
|
|
<template #header>
|
|
<span>点位名称 <span style="color: red">*</span> </span>
|
|
</template>
|
|
<template slot-scope="scope">
|
|
<!-- 汇聚门户只读视图:点位名称展示纯文本,不允许修改 -->
|
|
<span
|
|
v-if="$store.getters.fromPortal"
|
|
class="point-name-text"
|
|
>{{ scope.row.patrolpointName || "-" }}</span>
|
|
<el-input
|
|
v-else
|
|
v-model="scope.row.patrolpointName"
|
|
@change="handleChangePointCode(scope.row)"
|
|
@input="handlePatrolpointNameInput($event, scope.row)"
|
|
placeholder="请输入点位名称"
|
|
class="table-input"
|
|
:disabled="batchDeleteMode"
|
|
></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<!-- 站名列:汇聚门户聚合数据下展示 -->
|
|
<el-table-column
|
|
v-if="$store.getters.fromPortal"
|
|
label="站名"
|
|
align="center"
|
|
header-align="center"
|
|
class-name="station-name-col"
|
|
prop="stationName"
|
|
min-width="100"
|
|
>
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
prop="algSubtypeName"
|
|
label="算法类型"
|
|
align="center"
|
|
width="150"
|
|
>
|
|
<template slot-scope="scope">
|
|
<a
|
|
:class="[
|
|
'nowarp',
|
|
'algorithm-setting-link',
|
|
{ 'is-disabled': batchDeleteMode || $store.getters.fromPortal },
|
|
]"
|
|
@click="!batchDeleteMode && !$store.getters.fromPortal && chooseAlgorithm(scope.row)"
|
|
:title="scope.row.algSubtypeName"
|
|
>
|
|
{{
|
|
scope.row.algSubtypeName ? scope.row.algSubtypeName : "设置"
|
|
}}
|
|
</a>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
v-if="!$store.getters.fromPortal"
|
|
prop="pointTypeName"
|
|
header-align="center"
|
|
align="center"
|
|
label="设备类型"
|
|
width="150"
|
|
>
|
|
<template slot-scope="scope">
|
|
<span>{{ scope.row.pointTypeName || "-" }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-if="!$store.getters.fromPortal"
|
|
align="center"
|
|
prop="patrolContent"
|
|
header-align="center"
|
|
label="预置位选择"
|
|
width="150"
|
|
>
|
|
<template slot-scope="">
|
|
<el-button
|
|
class="task-row-btn"
|
|
style="
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
"
|
|
@click="pointConfiguration"
|
|
type="text"
|
|
size="small"
|
|
:disabled="batchDeleteMode"
|
|
>选择</el-button
|
|
>
|
|
</template>
|
|
</el-table-column>
|
|
<!-- <el-table-column prop="code" width="220" align="center">
|
|
<template #header>
|
|
<span>重要等级 <span style="color: red">*</span> </span>
|
|
</template>
|
|
<template slot-scope="scope">
|
|
<el-select
|
|
v-model="scope.row.pointImptLevel"
|
|
@change="handleChangePointCode(scope.row)"
|
|
class="table-select"
|
|
:disabled="batchDeleteMode"
|
|
>
|
|
<el-option
|
|
v-for="dict in dict.type.point_impt_level"
|
|
:key="dict.value"
|
|
:label="dict.label"
|
|
:value="dict.value"
|
|
/>
|
|
</el-select>
|
|
</template>
|
|
</el-table-column> -->
|
|
<el-table-column
|
|
v-if="!$store.getters.fromPortal"
|
|
label="操作"
|
|
align="center"
|
|
width="150"
|
|
>
|
|
<template slot-scope="scope">
|
|
<el-button
|
|
class="task-row-btn"
|
|
style="
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
"
|
|
@click.native.prevent="editRows1(scope.$index, scope.row)"
|
|
:disabled="
|
|
scope.row.stdparolPointId != null || batchDeleteMode
|
|
"
|
|
type="text"
|
|
size="small"
|
|
>修改</el-button
|
|
>
|
|
<el-button
|
|
class="task-row-btn"
|
|
style="
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
"
|
|
@click.native.prevent="deleteRows1(scope.$index, scope.row)"
|
|
:disabled="
|
|
scope.row.stdparolPointId != null || batchDeleteMode
|
|
"
|
|
type="text"
|
|
size="small"
|
|
>移除</el-button
|
|
>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 添加点位弹窗 -->
|
|
<el-dialog
|
|
class="card-dialog"
|
|
custom-class="site-point-add-dialog"
|
|
:title="titleAlert"
|
|
:visible.sync="showAdd"
|
|
width="60%"
|
|
append-to-body
|
|
:close-on-click-modal="false"
|
|
:lock-scroll="false"
|
|
>
|
|
<el-form
|
|
ref="formAdd"
|
|
class="card-page"
|
|
:model="formAdd"
|
|
:rules="formAddRules"
|
|
label-width="120px"
|
|
>
|
|
<el-form-item label="点位名称" prop="patrolpointName">
|
|
<el-input
|
|
v-model="formAdd.patrolpointName"
|
|
@input="handlePatrolpointNameInput($event, formAdd)"
|
|
placeholder="请输入点位名称"
|
|
></el-input>
|
|
</el-form-item>
|
|
<!-- <el-form-item label="监控点位编号" prop="patrolpointCode">
|
|
<el-input
|
|
v-model="formAdd.patrolpointCode"
|
|
placeholder="请输入监控编号"
|
|
></el-input>
|
|
</el-form-item> -->
|
|
<el-form-item label="监控内容" prop="patrolContent">
|
|
<!-- resize="none"
|
|
type
|
|
show-word-limit -->
|
|
<el-input
|
|
placeholder="请输入监控内容"
|
|
v-model="formAdd.patrolContent"
|
|
maxlength="200"
|
|
></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="巡检类型" prop="patrolTypeId">
|
|
<treeselect
|
|
:zIndex="110000"
|
|
:append-to-body="true"
|
|
:defaultExpandLevel="2"
|
|
:limit="100"
|
|
:disable-branch-nodes="true"
|
|
:limitText="(count) => `+${count}`"
|
|
multiple
|
|
flat
|
|
v-model="formAdd.patrolTypeId"
|
|
:options="listPatroltype"
|
|
:show-count="true"
|
|
:no-results-text="'\u65e0\u5339\u914d\u7ed3\u679c'"
|
|
placeholder="请选择巡检类型"
|
|
/>
|
|
</el-form-item>
|
|
<!-- <el-form-item label="重要等级" prop="pointImptLevel">
|
|
<el-select v-model="formAdd.pointImptLevel">
|
|
<el-option
|
|
v-for="dict in dict.type.point_impt_level"
|
|
:key="dict.value"
|
|
:label="dict.label"
|
|
:value="dict.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="读数单位">
|
|
<el-input
|
|
placeholder="请输入单位"
|
|
v-model="formAdd.purpose"
|
|
show-word-limit
|
|
></el-input>
|
|
</el-form-item>如:℃、mm、kPa -->
|
|
<el-form-item label="重要等级" prop="pointImptLevel">
|
|
<el-select
|
|
v-model="formAdd.pointImptLevel"
|
|
placeholder="请选择重要等级"
|
|
style="width: 50%"
|
|
>
|
|
<el-option
|
|
v-for="dict in dict.type.point_impt_level"
|
|
:key="dict.value"
|
|
:label="dict.label"
|
|
:value="dict.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="读数单位">
|
|
<el-input
|
|
placeholder="请输入单位"
|
|
v-model="formAdd.purpose"
|
|
show-word-limit
|
|
style="width: 50%"
|
|
></el-input>
|
|
</el-form-item>
|
|
<div
|
|
class="dialog-footer"
|
|
style="
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-top: 20px;
|
|
padding-top: 20px;
|
|
"
|
|
>
|
|
<el-button
|
|
class="site-point-cancel-btn"
|
|
@click="alertCancel1"
|
|
>取消</el-button
|
|
>
|
|
<el-button
|
|
type="primary"
|
|
:loading="formAddLoading"
|
|
@click="alertConfirm1"
|
|
>确定</el-button
|
|
>
|
|
</div>
|
|
</el-form>
|
|
</el-dialog>
|
|
</div>
|
|
|
|
<!-- 右侧配置面板 - 完全独立,不受左侧拖拽影响 -->
|
|
<div
|
|
class="right"
|
|
:style="{ display: showRightPanel ? 'inline-block' : 'none' }"
|
|
ref="right"
|
|
>
|
|
<div class="eq">
|
|
<img class="eq-img" src="@/assets/images/eq.png" />
|
|
<div class="eq-a1">
|
|
<div class="eq-a1-d1">请选中左点位查看监控点或监测设备</div>
|
|
</div>
|
|
<img
|
|
class="collect"
|
|
@click="collectPoint"
|
|
src="../assets/collect.png"
|
|
/>
|
|
<el-tabs v-model="activeTab" :stretch="true" class="right-tabs">
|
|
<el-tab-pane label="视频设备预置点" name="first">
|
|
<div class="eq-a2">
|
|
<!-- 绑定入口(汇聚门户进入的只读视图下隐藏) -->
|
|
<el-button
|
|
v-if="!$store.getters.fromPortal"
|
|
class="task-toolbar-btn"
|
|
@click="visibleShow1"
|
|
title="一个监控点位只允许绑定一个预置点"
|
|
:disabled="
|
|
currentRow != null && currentRow.bindPoints.length > 0
|
|
"
|
|
>绑定可见光监测点</el-button
|
|
>
|
|
<el-button
|
|
v-if="!$store.getters.fromPortal"
|
|
class="task-toolbar-btn"
|
|
@click="infraredShow1"
|
|
title="一个监控点位只允许绑定一个预置点"
|
|
:disabled="
|
|
currentRow != null && currentRow.bindPoints.length > 0
|
|
"
|
|
>绑定热成像监控点</el-button
|
|
>
|
|
</div>
|
|
<el-table
|
|
v-loading="pointLoading"
|
|
element-loading-background="rgba(34, 47, 61, 0.92)"
|
|
v-if="currentRow != null"
|
|
:height="533"
|
|
:data="currentRow.bindPoints"
|
|
class="right-table"
|
|
:header-cell-style="{
|
|
background: '#012773',
|
|
color: '#ffffff',
|
|
borderBottom: '2px solid #0b374e',
|
|
}"
|
|
:cell-style="{
|
|
color: '#e0e0e0',
|
|
borderBottom: '1px solid #1e3a4a',
|
|
}"
|
|
>
|
|
<el-table-column
|
|
label="设备名称"
|
|
align="center"
|
|
min-width="100"
|
|
prop="patrolDeviceName"
|
|
show-overflow-tooltip
|
|
></el-table-column>
|
|
<el-table-column
|
|
label="预置点名称"
|
|
align="center"
|
|
min-width="120"
|
|
prop="presetPosName"
|
|
show-overflow-tooltip
|
|
></el-table-column>
|
|
<el-table-column
|
|
v-if="!$store.getters.fromPortal"
|
|
label="操作"
|
|
width="150"
|
|
fixed="right"
|
|
class-name="operation-column"
|
|
align="center"
|
|
>
|
|
<template slot-scope="scope">
|
|
<el-button
|
|
class="task-row-btn"
|
|
style="
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
"
|
|
type="text"
|
|
size="small"
|
|
@click="handleUnbindPoint(scope.row, scope.$index)"
|
|
>解绑</el-button
|
|
>
|
|
<el-button
|
|
class="task-row-btn"
|
|
style="
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
"
|
|
type="text"
|
|
size="small"
|
|
:loading="scope.row.loading"
|
|
v-if="
|
|
scope.row.channelImg &&
|
|
scope.row.channelImg.length > 0
|
|
"
|
|
@click="handleViewImages(scope.row, scope.$index)"
|
|
>查看快照</el-button
|
|
>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 上传组件 -->
|
|
<UploadDialog
|
|
class="card-dialog"
|
|
:show.sync="showUploader"
|
|
@confirm="handleUploaderConfirm"
|
|
:filePath="currentRow != null ? currentRow.disRefPicturePath : ''"
|
|
/>
|
|
<UploadDialog
|
|
class="card-dialog"
|
|
:showConfirmBtn="false"
|
|
:updata="updata"
|
|
:accept="'.xml'"
|
|
:action="rebotUploadUrl"
|
|
:title="'机器人离线点位文件上传'"
|
|
:show.sync="showRebotUploader"
|
|
@confirm="handleRebotUploaderConfirm"
|
|
:filePath="''"
|
|
/>
|
|
|
|
<!-- 图片预览 -->
|
|
<AsyncImage
|
|
ref="asyncImage"
|
|
errorTips=""
|
|
class="xg_image_viewer"
|
|
@imgload="handleImageLoad"
|
|
@imgloaderror="handleImageLoadError"
|
|
:src="currentSrc"
|
|
:srcList="currentSrcList"
|
|
/>
|
|
|
|
<!-- 监控配置弹窗 -->
|
|
<el-dialog
|
|
class="monitor-config-dialog-wrap"
|
|
custom-class="card-dialog card-page monitor-config-dialog"
|
|
:title="titleLightTitle"
|
|
:close-on-click-modal="false"
|
|
:visible.sync="monitorShow"
|
|
width="1200px"
|
|
top="4vh"
|
|
@close="handleCloseVL"
|
|
append-to-body
|
|
:lock-scroll="false"
|
|
>
|
|
<div class="horizontal-tabs-container">
|
|
<el-tabs v-model="activeName" @tab-click="handleClick">
|
|
<el-tab-pane label="摄像头" name="home">
|
|
<!-- 修改为上下结构:上方视频和云台分开,下方动作列表 -->
|
|
<div
|
|
class="card-page"
|
|
style="display: flex; flex-direction: column; gap: 20px"
|
|
>
|
|
<!-- 上方区域:左侧树 + 中间视频 + 右侧云台(完全独立) -->
|
|
<div style="display: flex; gap: 10px; height: 400px">
|
|
<!-- 左侧树 -->
|
|
<div
|
|
class="left"
|
|
style="
|
|
width: 300px;
|
|
height: 390px;
|
|
margin-right: 0;
|
|
overflow: scroll;
|
|
"
|
|
>
|
|
<el-tree
|
|
:data="monitorList"
|
|
:props="defaultPropsMonitor"
|
|
@node-click="handleMonitor"
|
|
></el-tree>
|
|
</div>
|
|
|
|
<!-- 中间视频区域 - 独立带边框 -->
|
|
<div style="flex: 1; height: 390px; overflow: hidden">
|
|
<VideoPlayerPlatform
|
|
ref="playerPlayform"
|
|
@changeIndex="handleChangeIndex"
|
|
:showBottomToolBar="false"
|
|
:defaultLayout="'1x1'"
|
|
>
|
|
<template slot-scope="scope">
|
|
<DrawShape
|
|
@drawComplete="
|
|
(shape) => {
|
|
handleDrawComplete(scope, shape);
|
|
}
|
|
"
|
|
/>
|
|
</template>
|
|
</VideoPlayerPlatform>
|
|
</div>
|
|
|
|
<!-- 右侧云台区域 - 独立无边框 -->
|
|
<div style="width: 290px; height: 390px">
|
|
<div class="r-ti1">云台</div>
|
|
<div class="r-box">
|
|
<div class="r-ti2">
|
|
<img src="@/assets/images/yuntai1.png" />
|
|
<div class="r-ti2-pos">
|
|
<div
|
|
@mousedown="controlEquip1('UP')"
|
|
@mouseup="controlEquip1('UP_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('UP_RIGHT')"
|
|
@mouseup="controlEquip1('UP_RIGHT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('RIGHT')"
|
|
@mouseup="controlEquip1('RIGHT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('DOWN_RIGHT')"
|
|
@mouseup="controlEquip1('DOWN_RIGHT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('DOWN')"
|
|
@mouseup="controlEquip1('DOWN_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('DOWN_LEFT')"
|
|
@mouseup="controlEquip1('DOWN_LEFT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('LEFT')"
|
|
@mouseup="controlEquip1('LEFT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('UP_LEFT')"
|
|
@mouseup="controlEquip1('UP_LEFT_STOP')"
|
|
></div>
|
|
<div @mousedown="controlEquip1('UP_LEFT')"></div>
|
|
</div>
|
|
</div>
|
|
<div class="r-ti3">
|
|
<div class="r-ti3-d1">
|
|
<img src="@/assets/images/r1.png" />
|
|
<div class="r-ti3-d2">
|
|
<div
|
|
@mousedown="controlEquip1('ZOOM_OUT')"
|
|
@mouseup="controlEquip1('ZOOM_OUT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('ZOOM_IN')"
|
|
@mouseup="controlEquip1('ZOOM_IN_STOP')"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
<div class="r-ti3-d1">
|
|
<img src="@/assets/images/r2.png" />
|
|
<div class="r-ti3-d2">
|
|
<div
|
|
@mousedown="controlEquip2('nearfocus')"
|
|
@mouseup="controlEquip2('nearfocusstop')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip2('farfocus')"
|
|
@mouseup="controlEquip2('farfocusstop')"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
<div class="r-ti3-d1">
|
|
<img src="@/assets/images/r3.png" />
|
|
<div class="r-ti3-d2">
|
|
<div
|
|
@mousedown="controlEquip2('apertureoff')"
|
|
@mouseup="controlEquip2('apertureoffstop')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip2('apertureon')"
|
|
@mouseup="controlEquip2('apertureonstop')"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
<div class="r-ti3-d1">
|
|
<img src="@/assets/images/r4.png" />
|
|
<div class="r-ti3-d2">
|
|
<div
|
|
@mousedown="controlEquip1('ZOOM_OUT')"
|
|
@mouseup="controlEquip1('ZOOM_OUT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('ZOOM_IN')"
|
|
@mouseup="controlEquip1('ZOOM_IN_STOP')"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
<div class="r-ti3-d1">
|
|
<img src="@/assets/images/r5.png" />
|
|
<div class="r-ti3-d2">
|
|
<div
|
|
@mousedown="controlEquip1('ZOOM_OUT')"
|
|
@mouseup="controlEquip1('ZOOM_OUT_STOP')"
|
|
></div>
|
|
<div
|
|
@mousedown="controlEquip1('ZOOM_IN')"
|
|
@mouseup="controlEquip1('ZOOM_IN_STOP')"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="r-ti4">
|
|
<div style="display: flex">
|
|
<el-select
|
|
v-model="presetDotNum"
|
|
placeholder="请选择预置点"
|
|
@change="presetDotChange1"
|
|
:disabled="presetDotDis"
|
|
>
|
|
<el-option
|
|
v-for="item in presetArr"
|
|
:key="item.dictValue"
|
|
:label="item.dictLabel"
|
|
:value="item.dictValue"
|
|
></el-option>
|
|
</el-select>
|
|
<img
|
|
class="alert1_img1"
|
|
@click="convertPresetDot1"
|
|
src="@/assets/images/r6.png"
|
|
title="转到预置点"
|
|
/>
|
|
<el-popover
|
|
placement="top"
|
|
width="300"
|
|
v-model="popovervisible"
|
|
trigger="click"
|
|
popper-class="monitor-config-popover"
|
|
>
|
|
<el-input
|
|
v-model="newpresetName"
|
|
placeholder="请输入内容"
|
|
style="background-color: #222f3d"
|
|
:disabled="presetDotDis"
|
|
></el-input>
|
|
<div
|
|
style="text-align: right; margin-top: 10px"
|
|
class="card-page"
|
|
>
|
|
<el-button
|
|
size="mini"
|
|
type="primary"
|
|
@click="popovervisible = false"
|
|
>取消</el-button
|
|
>
|
|
<el-button
|
|
type="primary"
|
|
size="mini"
|
|
@click="setPresetDot1"
|
|
>确定</el-button
|
|
>
|
|
</div>
|
|
<img
|
|
v-if="!$store.getters.fromPortal"
|
|
slot="reference"
|
|
class="alert1_img1"
|
|
src="@/assets/images/r7.png"
|
|
title="添加预置点"
|
|
/>
|
|
</el-popover>
|
|
</div>
|
|
<div style="display: flex">
|
|
<el-input
|
|
v-model="presetName"
|
|
placeholder="请输入内容"
|
|
></el-input>
|
|
<img
|
|
v-if="!$store.getters.fromPortal"
|
|
class="alert1_img1"
|
|
@click="editPresetDot1"
|
|
src="@/assets/images/r8.png"
|
|
title="编辑预置点名称"
|
|
/>
|
|
</div>
|
|
<div
|
|
style="display: flex; margin: 10px 0px; width: 92%"
|
|
>
|
|
<el-input
|
|
v-model="presetNumber"
|
|
placeholder="预置位编号"
|
|
></el-input>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 下方区域:动作列表 -->
|
|
<div>
|
|
<div>动作列表</div>
|
|
<div class="card-page">
|
|
<el-table
|
|
:data="presetData.presetActionList"
|
|
style="margin-top: 10px; width: 100%"
|
|
height="200px"
|
|
border
|
|
>
|
|
<el-table-column
|
|
align="center"
|
|
label="动作类型"
|
|
min-width="100"
|
|
>
|
|
<template slot-scope="scope">
|
|
<el-select v-model="scope.row.actionType">
|
|
<el-option
|
|
v-for="dict in dict.type.video_action_type"
|
|
:key="dict.value"
|
|
:label="dict.label"
|
|
:value="dict.value"
|
|
/>
|
|
</el-select>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
align="center"
|
|
label="录像时长(秒)"
|
|
min-width="100"
|
|
>
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.videoTime"
|
|
v-if="scope.row.actionType == 2"
|
|
class="centered-input"
|
|
></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
align="center"
|
|
label="拍照次数"
|
|
min-width="100"
|
|
>
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.photoCount"
|
|
v-if="scope.row.actionType == 1"
|
|
type="number"
|
|
min="0"
|
|
step="1"
|
|
class="centered-input"
|
|
></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
align="center"
|
|
label="拍照间隔(秒)"
|
|
min-width="100"
|
|
>
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.photoSeper"
|
|
v-if="scope.row.actionType == 1"
|
|
type="number"
|
|
min="0"
|
|
step="1"
|
|
class="centered-input"
|
|
></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
align="center"
|
|
label="操作"
|
|
width="100"
|
|
>
|
|
<template #header>
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
@click="addAction"
|
|
>添加</el-button
|
|
>
|
|
</template>
|
|
<template slot-scope="scope">
|
|
<el-button
|
|
type="text"
|
|
size="small"
|
|
@click="removeAction(scope.$index)"
|
|
>移除</el-button
|
|
>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-tab-pane>
|
|
<!-- 移动设备绑定暂时停用,保留此代码供后续恢复。 -->
|
|
<el-tab-pane
|
|
label="移动设备"
|
|
name="solutions"
|
|
v-if="false && monitorType == 'ir'"
|
|
>
|
|
<div class="box card-page" style="height: 570px">
|
|
<div class="middle">
|
|
<div>
|
|
<ImageAnnotation
|
|
:image-src="
|
|
'/app/htjc6/htjcImage/' +
|
|
imageUrl
|
|
"
|
|
ref="checkItemSetRef"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
|
|
<template #footer>
|
|
<div
|
|
class="add-btn add-bth1 card-page"
|
|
v-if="activeName !== 'solutions'"
|
|
>
|
|
<el-button
|
|
type="primary"
|
|
v-if="monitorType == 'vl'"
|
|
:loading="loadingBind"
|
|
@click="saveDot1"
|
|
>确定</el-button
|
|
>
|
|
<el-button type="primary" v-else @click="nextStep1"
|
|
>下一步,配置测温位</el-button
|
|
>
|
|
<el-button @click="monitorShow = false">取消</el-button>
|
|
</div>
|
|
<div
|
|
class="add-btn add-bth1 card-page"
|
|
v-if="activeName == 'solutions'"
|
|
>
|
|
<el-button type="primary" @click="uavComplete()">完成</el-button>
|
|
<el-button @click="monitorShow = false">取消</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
<!-- 测温配置弹窗 -->
|
|
<el-dialog
|
|
:visible.sync="monitorSecShow"
|
|
:close-on-click-modal="false"
|
|
custom-class="bind-thermal-dialog"
|
|
width="1200px"
|
|
append-to-body
|
|
@close="handleCloseIR"
|
|
:lock-scroll="false"
|
|
>
|
|
<div class="sec-left card-page">
|
|
<div class="fl">
|
|
<div class="toollist1-a1">
|
|
<div
|
|
:class="drawShapIndex == 3 ? 'on1' : ''"
|
|
@click="chooseDrawShape1(3, ShapeEnum['rect'])"
|
|
>
|
|
<img src="@/assets/images/ic04.png" />
|
|
</div>
|
|
<div
|
|
:class="drawShapIndex == 2 ? 'on1' : ''"
|
|
@click="chooseDrawShape1(2, ShapeEnum['polygon'])"
|
|
>
|
|
<img src="@/assets/images/ic03.png" />
|
|
</div>
|
|
<div
|
|
:class="drawShapIndex == 1 ? 'on1' : ''"
|
|
@click="chooseDrawShape1(1, ShapeEnum['brokenline'])"
|
|
>
|
|
<img src="@/assets/images/ic02.png" />
|
|
</div>
|
|
<div
|
|
:class="drawShapIndex == 0 ? 'on1' : ''"
|
|
@click="chooseDrawShape1(0, ShapeEnum['point'])"
|
|
>
|
|
<img src="@/assets/images/ic01.png" />
|
|
</div>
|
|
</div>
|
|
<VideoPlayerPlatform
|
|
ref="playerPlayform2"
|
|
@changeIndex="handleChangeIndex"
|
|
:showBottomToolBar="false"
|
|
:defaultLayout="'1x1'"
|
|
>
|
|
<template slot-scope="scope">
|
|
<DrawShape
|
|
@drawComplete="
|
|
(shape) => {
|
|
handleDrawComplete(scope, shape);
|
|
}
|
|
"
|
|
/>
|
|
</template>
|
|
</VideoPlayerPlatform>
|
|
</div>
|
|
<div class="fr">
|
|
<div class="fr-ti1">
|
|
<span>{{ patroldeviceName }}</span>
|
|
<span v-if="monitorType == 'vl'">可见光</span>
|
|
<span v-else>热成像</span>
|
|
<span>/{{ presetName }}</span>
|
|
<span v-if="monitorType == 'vl'">位置</span>
|
|
<span v-else>测温位</span>
|
|
<span>配置</span>
|
|
</div>
|
|
<div class="fr-ti2">
|
|
点击画面右上方按钮配置测温位,最多配置10个测温点、1条测温线、10个测温框
|
|
</div>
|
|
<el-table
|
|
:data="presetData.presetParamList"
|
|
style="width: 100%"
|
|
max-height="250"
|
|
>
|
|
<el-table-column
|
|
fixed
|
|
prop="measureName"
|
|
:label="monitorType == 'vl' ? '位置' : '测温位'"
|
|
width="150"
|
|
>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="measureAreaType"
|
|
label="类型"
|
|
width="120"
|
|
></el-table-column>
|
|
<el-table-column fixed="right" label="操作" width="80">
|
|
<template slot-scope="scope">
|
|
<i
|
|
class="el-icon-delete fss"
|
|
title="删除"
|
|
@click.prevent="deleteDot1(scope.$index, scope.row)"
|
|
></i>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
<span slot="footer" class="dialog-footer card-page">
|
|
<el-button type="primary" :loading="loadingBind" @click="saveDot1"
|
|
>保存</el-button
|
|
>
|
|
<el-button class="bind-thermal-secondary-btn" @click="prevStep"
|
|
>上一步</el-button
|
|
>
|
|
<el-button
|
|
class="bind-thermal-secondary-btn"
|
|
@click="monitorSecShow = false"
|
|
>取消</el-button
|
|
>
|
|
</span>
|
|
</el-dialog>
|
|
|
|
<!-- 测温参数配置弹窗 -->
|
|
<el-dialog
|
|
:title="title2"
|
|
:close-on-click-modal="false"
|
|
:visible.sync="presetDataShow"
|
|
@close="handleCloseTemptrueModel"
|
|
width="65%"
|
|
append-to-body
|
|
:lock-scroll="false"
|
|
>
|
|
<el-form
|
|
ref="formTemptrue"
|
|
class="card-page"
|
|
:model="testobj"
|
|
:rules="formTemptrueRules"
|
|
label-width="120px"
|
|
>
|
|
<el-row>
|
|
<el-col :span="24">基本信息</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="6">
|
|
<el-form-item label="名称" prop="measureName">
|
|
<el-input
|
|
v-model="testobj.measureName"
|
|
placeholder="请输入名称"
|
|
></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="规则编号" prop="presetParamCode">
|
|
<el-input
|
|
v-model="testobj.presetParamCode"
|
|
placeholder="请输入编号"
|
|
></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="测温距离" prop="measureDistance">
|
|
<el-input v-model="testobj.measureDistance"
|
|
><i slot="suffix" class="input_slot_a1">m</i></el-input
|
|
>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="辐射系数" prop="radioRate">
|
|
<el-input v-model="testobj.radioRate"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="反射温度" prop="reflexTemp">
|
|
<el-input v-model="testobj.reflexTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="状态" prop="reflexTemp">
|
|
<el-checkbox
|
|
v-model="testobj.isEnable"
|
|
:true-label="1"
|
|
:false-label="0"
|
|
>
|
|
{{ testobj.isEnable == "1" ? "已启用" : "已停用" }}
|
|
</el-checkbox>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="24">预警配置</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="6">
|
|
<el-form-item label="最高温度" prop="warnMaxTemp">
|
|
<el-input v-model="testobj.warnMaxTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="最低温度" prop="warnMinTemp">
|
|
<el-input v-model="testobj.warnMinTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="平均温度" prop="warnAverageTemp">
|
|
<el-input v-model="testobj.warnAverageTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="温差" prop="warnDifferenceTemp">
|
|
<el-input v-model="testobj.warnDifferenceTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="24">告警配置</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="6">
|
|
<el-form-item label="最高温度" prop="alarmMaxTemp">
|
|
<el-input v-model="testobj.alarmMaxTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="最低温度" prop="alarmMinTemp">
|
|
<el-input v-model="testobj.alarmMinTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="平均温度" prop="alarmAverageTemp">
|
|
<el-input v-model="testobj.alarmAverageTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="温差" prop="alarmDifferenceTemp">
|
|
<el-input v-model="testobj.alarmDifferenceTemp"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
<div class="add-bth add-bth1 card-page" slot="footer">
|
|
<el-button type="primary" @click="aletrSecConfirm1">确定</el-button>
|
|
<el-button @click="aletrSecCancel1">取消</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
|
|
<!-- 算法选择组件 -->
|
|
<ChooseAlg
|
|
:algSubtypeIds="currentRow != null ? currentRow.algSubtypeIds : ''"
|
|
:algSubtypeName="currentRow != null ? currentRow.algSubtypeName : ''"
|
|
:alarmThreshold="currentRow != null ? currentRow.alarmThreshold : ''"
|
|
:show.sync="showChooseAlg"
|
|
@confirm="handleChooseAlgOk"
|
|
/>
|
|
|
|
<!-- 设备选择组件 -->
|
|
<ChooseDevices
|
|
:show.sync="showChooseDevices"
|
|
@confirm="handleChooseDevicesOk"
|
|
></ChooseDevices>
|
|
|
|
<!-- 算法配置弹窗 -->
|
|
<el-dialog
|
|
class="card-dialog"
|
|
title="算法配置"
|
|
:visible.sync="algorithmShow"
|
|
width="1200px"
|
|
style="height: 95%"
|
|
:lock-scroll="false"
|
|
>
|
|
<Algorith></Algorith>
|
|
</el-dialog>
|
|
|
|
<!-- 图片预览弹窗 -->
|
|
<el-dialog
|
|
title="图片预览"
|
|
:visible.sync="showPreviewImages"
|
|
:close-on-click-modal="false"
|
|
:close-on-press-escape="false"
|
|
:destroy-on-close="true"
|
|
custom-class="card-dialog card-page image-preview-dialog"
|
|
width="70%"
|
|
append-to-body
|
|
:lock-scroll="false"
|
|
>
|
|
<div v-if="showPreviewImages" class="image-preview-stage">
|
|
<ImagePreview
|
|
:imageUrls="currentSrcList"
|
|
:selectImgPosition="previewImagePos"
|
|
:showTemperatureTool="false"
|
|
/>
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
</CardBox>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
listPatrolpointpreset,
|
|
addPatrolpointpreset,
|
|
delPatrolpointpreset,
|
|
} from "@/api/basedata/patrolpointmnt/patrolpointpreset.js";
|
|
import ChooseDevices from "./components/chooseDevices.vue";
|
|
import UploadDialog from "./components/uploadDialog.vue";
|
|
import Treeselect from "@riophae/vue-treeselect";
|
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
|
import CardBox from "../components/cardBox.vue";
|
|
import ImagePreview from "@/views/cards/components/ImagePreview/index.vue";
|
|
import {
|
|
proDotManTable,
|
|
proDotTableDeleteSin,
|
|
proDotTableAddSin,
|
|
proDotTableEditSin,
|
|
bindingMonitorDotList,
|
|
presetDotDistribute,
|
|
convertPresetDot,
|
|
cloudControl,
|
|
focalAperture,
|
|
bindingPreset,
|
|
issueUpdate,
|
|
proDotManTableRelation, //(右侧新的点位列表)
|
|
} from "@/api/basedata/area/area";
|
|
import VideoPlayerPlatform from "@/components/VideoPlayerPlatform";
|
|
import DrawShape, {
|
|
toTargetRect,
|
|
ShapeEnum,
|
|
} from "@/components/Canvas/DrawShape.vue";
|
|
import linq from "linq";
|
|
import { listData } from "@/api/system/dict/data";
|
|
import { normalizePatrolName } from "@/utils/patrolName";
|
|
|
|
import {
|
|
listPatroltype,
|
|
getDeviceList,
|
|
} from "@/api/basedata/patrolpointmnt/patroltype";
|
|
import {
|
|
getAreaDeviceTree,
|
|
getPatroPointDevicePoints,
|
|
unbindPoint,
|
|
getBdconfigMainsystem,
|
|
treeAreaDeviceSelectFilterByPreset,
|
|
treeAreaDeviceSelectFilterByPresetRelation,
|
|
} from "@/api/basedata/patrolpointmnt/patrolpoint";
|
|
import AsyncImage from "@/components/AsyncImage";
|
|
import lodash from "lodash";
|
|
import { editPoint } from "@/api/basedata/patrolpointmnt/patrolpointpreset";
|
|
import {
|
|
capturePicture,
|
|
irUavImg,
|
|
} from "@/api/basedata/patrolpointmnt/patrolpointpreset";
|
|
import ChooseAlg from "./components/chooseAlg.vue";
|
|
import Algorith from "@/views/cards/site_management/algorithm.vue";
|
|
import ImageAnnotation from "./components/ImageAnnotation.vue";
|
|
|
|
// 设备树面板默认宽度(收窄后);存储 key 带 v2,避免老用户 localStorage 里的旧宽度盖住新默认
|
|
const DEFAULT_LEFT_PANEL_WIDTH = 200;
|
|
const LEFT_PANEL_WIDTH_STORAGE_KEY = "leftPanelWidthV2";
|
|
|
|
export default {
|
|
name: "site_management",
|
|
dicts: ["video_action_type", "point_impt_level", "system_type"],
|
|
components: {
|
|
Algorith,
|
|
CardBox,
|
|
ChooseDevices,
|
|
UploadDialog,
|
|
VideoPlayerPlatform,
|
|
DrawShape,
|
|
Treeselect,
|
|
AsyncImage,
|
|
ChooseAlg,
|
|
ImagePreview,
|
|
ImageAnnotation,
|
|
},
|
|
data() {
|
|
return {
|
|
// 图片标注
|
|
imageUrl: "",
|
|
imagePath: "",
|
|
// 图片标注结束
|
|
activeName: "home", //tab切换
|
|
algorithmShow: false,
|
|
activeTab: "first",
|
|
showChooseDevices: false,
|
|
showChooseAlg: false,
|
|
showUploader: false,
|
|
showRebotUploader: false,
|
|
rebotUploadUrl:
|
|
process.env.VUE_APP_BASE_API +
|
|
"/basedata/patrolpointmnt/patrolpoint/uploadXml",
|
|
updata: {},
|
|
showPreviewImages: false,
|
|
previewImagePos: 0,
|
|
currentSrc: "",
|
|
currentSrcList: [],
|
|
currentImageRow: {},
|
|
formAddLoading: false,
|
|
currentTreeNode: null,
|
|
currentRow: null,
|
|
loading: false,
|
|
pointLoading: false,
|
|
loadingBind: false,
|
|
treeobj: null /* 左侧列表树点击后获取相关信息的暂存区 */,
|
|
areaList: [] /* 左侧数据列表 */,
|
|
defaultPropsArea: {
|
|
children: "children",
|
|
label: "deviceName",
|
|
} /* 左侧数据列表对应字段设置 */,
|
|
monitorList: [] /* 中间数据列表 */,
|
|
defaultPropsMonitor: {
|
|
children: "children",
|
|
label: "name",
|
|
} /* 中间数据列表对应字段设置 */,
|
|
description:
|
|
"一个监控对象(区域、主设备),最多支持绑定16个不同摄像头;一个监控对象(区域、主设备),最多添加200个监控点位;一个监控点位绑定监控点不超过9个预置位(无论是否同一监控点);" /* 警告提示的文案 */,
|
|
showAdd: false /* 添加、修改弹窗控制开关 */,
|
|
titleAlert: "" /* 添加、修改弹窗标题 */,
|
|
tableData: [] /* 监控点位数据数组 */,
|
|
filters: [{ "filter-multiple": false }] /* 数据是否多选 */,
|
|
mulSelect: [] /* 监控点位多选数据数组 */,
|
|
inputSearch: "" /* 监控点位数据搜索框输入值 */,
|
|
inputSearch1: "" /* 树形据搜索框输入值 */,
|
|
bindingStyle: 1 /* 选择手动、平台 手动1、平台2 */,
|
|
monitorShow: false /* 可见光、热成像弹窗显示状态值 */,
|
|
titleLightTitle: "" /* 可见光、热成像弹窗标题 */,
|
|
monitorType: "" /* 绑定监控点位类型 可见光值为:vl,热成像值为:ir */,
|
|
equipobj: {} /* 监控设备相应的数据 */,
|
|
patroldeviceName: "" /* 绑定监控设备名称 */,
|
|
presetDotNum: "" /* 当前选择的预置点 */,
|
|
presetDotDis: "" /* 预置点是否可选 */,
|
|
presetArr: [] /* 预置点下拉点位数组 0——255 */,
|
|
presetName: "" /* 选到的预置点名字 */,
|
|
presetNumber: "", //预置位编号
|
|
is_convert: false /* 是否转到预置点 */,
|
|
is_set: false /* 是否设置预置点 */,
|
|
monitorSecShow: false /* 下一步弹窗显示状态 */,
|
|
formTemptrueRules: {
|
|
measureName: [{ required: true, message: "必填", trigger: "blur" }], //区域名称
|
|
measureDistance: [{ required: true, message: "必填", trigger: "blur" }], //距离
|
|
radioRate: [{ required: true, message: "必填", trigger: "blur" }], //辐射率
|
|
reflexTemp: [{ required: true, message: "必填", trigger: "blur" }], //反射温度
|
|
warnMaxTemp: [{ required: true, message: "必填", trigger: "blur" }], //预警最高温度
|
|
warnMinTemp: [{ required: true, message: "必填", trigger: "blur" }], //预警最低温度
|
|
alarmMaxTemp: [{ required: true, message: "必填", trigger: "blur" }], //告警最高温度
|
|
alarmMinTemp: [{ require: true, message: "必填", trigger: "blur" }], //告警最低温度
|
|
warnAverageTemp: [{ required: true, message: "必填", trigger: "blur" }], //预警平均温度
|
|
alarmAverageTemp: [
|
|
{ required: true, message: "必填", trigger: "blur" },
|
|
], // 告警平均温度
|
|
warnDifferenceTemp: [
|
|
{ required: true, message: "必填", trigger: "blur" },
|
|
], //预警温差
|
|
alarmDifferenceTemp: [
|
|
{ required: true, message: "必填", trigger: "blur" },
|
|
], //告警温差
|
|
presetParamCode: [{ required: true, message: "必填", trigger: "blur" }], //测温编号
|
|
},
|
|
|
|
presetData: {
|
|
presetPosCode: "",
|
|
channelId: "",
|
|
eqpbookId: "",
|
|
patrolpointId: "",
|
|
stdparolPointId: "",
|
|
deviceId: "",
|
|
presetPosName: "",
|
|
stopTime: "",
|
|
channelImg: "",
|
|
description: "",
|
|
presetActionList: [],
|
|
presetParamList: [],
|
|
presetPointList: [],
|
|
} /* 预置点相关参数 */,
|
|
presetDataShow: false /* 监控区域温度弹窗状态值 */,
|
|
drawShapIndex: -1 /* 选择绘制类型索引值 */,
|
|
ShapeEnum: {
|
|
rect: "Rectangle",
|
|
brokenline: "BrokenLine",
|
|
polygon: "Polygon",
|
|
point: "Point",
|
|
} /* 绘制方式 */,
|
|
testobj: {
|
|
measureAreaType: "", //区域类型
|
|
measureName: "", //区域名称
|
|
measureDistance: "", //距离
|
|
radioRate: "", //辐射率
|
|
warnMaxTemp: "", //预警最高温度
|
|
warnMinTemp: "", //预警最低温度
|
|
alarmMaxTemp: "", //告警最高温度
|
|
alarmMinTemp: "", //告警最低温度
|
|
warnAverageTemp: "", //预警平均温度
|
|
alarmAverageTemp: "", // 告警平均温度
|
|
warnDifferenceTemp: "", //预警温差
|
|
alarmDifferenceTemp: "", //告警温差
|
|
coordinate: "", //坐标
|
|
reflexTemp: "",
|
|
presetParamCode: "", //测温编号
|
|
isEnable: 1, //启用停用
|
|
} /* 测温参数,和画框数据 */,
|
|
popovervisible: false,
|
|
newpresetName: "",
|
|
title2: "测温位配置",
|
|
show1: true,
|
|
value: "",
|
|
formAdd: {
|
|
patrolpointName: "",
|
|
patrolContent: "",
|
|
purpose: "",
|
|
areaId: "",
|
|
mainDeviceId: "",
|
|
deviceId: "",
|
|
patrolpointCode: "",
|
|
patrolTypeId: null,
|
|
pointImptLevel: null,
|
|
positionX: null,
|
|
positionY: null,
|
|
positionZ: null,
|
|
},
|
|
formAddRules: {
|
|
patrolpointName: [
|
|
{
|
|
required: true,
|
|
message: "必填",
|
|
trigger: "blur",
|
|
},
|
|
],
|
|
patrolContent: [
|
|
{
|
|
required: false,
|
|
message: "必填",
|
|
trigger: "blur",
|
|
},
|
|
],
|
|
patrolpointCode: [
|
|
{
|
|
required: true,
|
|
message: "必填",
|
|
trigger: "blur",
|
|
},
|
|
],
|
|
patrolTypeId: [
|
|
{
|
|
required: false,
|
|
message: "必填",
|
|
trigger: "blur",
|
|
},
|
|
],
|
|
pointImptLevel: [
|
|
{
|
|
required: false,
|
|
message: "必填",
|
|
trigger: "blur",
|
|
},
|
|
],
|
|
purpose: [
|
|
{
|
|
required: true,
|
|
message: "必填",
|
|
trigger: "blur",
|
|
},
|
|
],
|
|
areaId: "",
|
|
mainDeviceId: "",
|
|
deviceId: "",
|
|
},
|
|
listPatroltype: [],
|
|
patroldeviceCode: null,
|
|
channelCode: null,
|
|
cssClass: false,
|
|
|
|
// 新增列宽相关属性
|
|
columnWidths: {}, // 列宽缓存
|
|
defaultColumnWidths: [55, 400, 150, 150, 150, 220, 125], // 默认列宽,增加了序号列
|
|
|
|
// 算法分类筛选相关属性 - 使用接口返回数据
|
|
selectedAlgorithmCategory: "", // 选中的算法分类(dictValue)
|
|
algorithmCategoryOptions: [], // 算法分类选项列表(接口返回数据)
|
|
selectedAlgorithmCategoryLabel: "", // 选中的算法分类标签
|
|
|
|
// 设备类型筛选相关属性
|
|
selectedDeviceType: "", // 选中的设备类型
|
|
deviceTypeOptions: [], // 设备类型选项列表
|
|
selectedDeviceTypeLabel: "", // 选中的设备类型标签
|
|
|
|
// 新增的拖拽相关属性 - 只影响左侧树
|
|
leftPanelWidth: DEFAULT_LEFT_PANEL_WIDTH, // 左侧面板默认宽度
|
|
minLeftWidth: 200, // 左侧面板最小宽度
|
|
maxLeftWidth: 600, // 左侧面板最大宽度
|
|
tableLayoutFrame: null,
|
|
tableHeight: 560,
|
|
isResizing: false, // 是否正在拖拽
|
|
startX: 0, // 拖拽起始X坐标
|
|
startWidth: 0, // 拖拽起始宽度
|
|
|
|
// 右侧面板显示控制
|
|
showRightPanel: false,
|
|
|
|
// 批量删除模式相关属性
|
|
batchDeleteMode: false, // 是否处于批量删除模式
|
|
batchSelectList: [], // 批量删除选中的行
|
|
};
|
|
},
|
|
computed: {
|
|
// 根据选中的算法分类和设备类型过滤表格数据
|
|
filteredTableData() {
|
|
let filtered = this.tableData;
|
|
|
|
if (this.selectedAlgorithmCategory) {
|
|
// 根据算法分类的值过滤
|
|
const selectedCategory = this.algorithmCategoryOptions.find(
|
|
(item) => item.dictValue === this.selectedAlgorithmCategory
|
|
);
|
|
|
|
if (selectedCategory) {
|
|
// 获取该分类下的所有算法ID
|
|
const algIdsInCategory = selectedCategory.dictValue
|
|
.split(",")
|
|
.map((id) => id.trim());
|
|
|
|
filtered = filtered.filter((row) => {
|
|
if (!row.algSubtypeIds) return false;
|
|
|
|
// 检查行的algSubtypeIds是否包含该分类下的任一算法ID
|
|
const rowAlgIds = row.algSubtypeIds
|
|
.split(",")
|
|
.map((id) => id.trim());
|
|
return algIdsInCategory.some((id) => rowAlgIds.includes(id));
|
|
});
|
|
}
|
|
}
|
|
|
|
if (this.selectedDeviceType) {
|
|
filtered = filtered.filter(
|
|
(row) => row.pointTypeName === this.selectedDeviceType
|
|
);
|
|
}
|
|
|
|
return filtered;
|
|
},
|
|
},
|
|
created() {
|
|
this.testobjBackup = lodash.cloneDeep(this.testobj);
|
|
this.presetDataBackup = lodash.cloneDeep(this.presetData);
|
|
listPatroltype().then((res) => {
|
|
const list = [];
|
|
let childs = [];
|
|
let ptype = {};
|
|
linq
|
|
.from(res.rows)
|
|
.where((x) => x.parentId === 0)
|
|
.toArray()
|
|
.forEach((node) => {
|
|
childs = linq
|
|
.from(res.rows)
|
|
.where((c) => c.parentId === node.patrolTypeId)
|
|
.select((q) => {
|
|
return {
|
|
id: q.patrolTypeId,
|
|
label: normalizePatrolName(q.patrolTypeName),
|
|
};
|
|
})
|
|
.toArray();
|
|
ptype = {
|
|
id: node.patrolTypeId,
|
|
isOpen: true,
|
|
label: normalizePatrolName(node.patrolTypeName),
|
|
};
|
|
if (childs.length > 0) {
|
|
ptype.children = childs;
|
|
}
|
|
list.push(ptype);
|
|
});
|
|
this.listPatroltype = list;
|
|
});
|
|
this.getAreaList1();
|
|
this.getAlgCategory();
|
|
|
|
getBdconfigMainsystem().then((res) => {
|
|
const config = res.data.find((x) => x.systemType.includes("xsxt"));
|
|
if (config) {
|
|
this.updata = {
|
|
sendCode: config.mainSystemCode,
|
|
};
|
|
}
|
|
});
|
|
|
|
// 从localStorage加载保存的宽度
|
|
this.loadLeftPanelWidth();
|
|
},
|
|
mounted() {
|
|
this.updateTableHeight();
|
|
this.$nextTick(() => {
|
|
this.initColumnResize();
|
|
this.loadColumnWidths();
|
|
});
|
|
|
|
// 添加窗口大小变化监听
|
|
window.addEventListener("resize", this.handleResize);
|
|
},
|
|
beforeDestroy() {
|
|
// 移除窗口大小变化监听
|
|
window.removeEventListener("resize", this.handleResize);
|
|
|
|
// 清理拖拽遮罩
|
|
const mask = document.getElementById("resize-mask");
|
|
if (mask) mask.remove();
|
|
|
|
// 移除全局事件监听
|
|
document.removeEventListener("mousemove", this.onResize);
|
|
document.removeEventListener("mouseup", this.stopResize);
|
|
if (this.tableLayoutFrame) {
|
|
cancelAnimationFrame(this.tableLayoutFrame);
|
|
}
|
|
},
|
|
methods: {
|
|
handlePatrolpointNameInput(value, target) {
|
|
const name = String(value || "");
|
|
if (name.length > 200) {
|
|
target.patrolpointName = name.slice(0, 200);
|
|
this.$message.warning("\u70b9\u4f4d\u540d\u79f0\u4e0d\u80fd\u8d85\u8fc7200\u4e2a\u5b57\u7b26");
|
|
}
|
|
},
|
|
// 获取行的唯一key(用于表格多选)
|
|
getRowKey(row) {
|
|
return row.patrolpointId;
|
|
},
|
|
|
|
// 判断行是否可选(过滤标准点位)
|
|
checkSelectable(row) {
|
|
// 标准点位不可选
|
|
return !row.stdparolPointId;
|
|
},
|
|
|
|
// 获取行序号(基于过滤后的数据)
|
|
getRowIndex(index) {
|
|
return index + 1;
|
|
},
|
|
|
|
// 切换批量删除模式
|
|
toggleBatchDeleteMode() {
|
|
if (this.batchDeleteMode) {
|
|
// 退出批量删除模式,清空选中
|
|
this.batchDeleteMode = false;
|
|
this.batchSelectList = [];
|
|
// 清除表格的选中状态
|
|
if (this.$refs.multipleTable) {
|
|
this.$refs.multipleTable.clearSelection();
|
|
}
|
|
} else {
|
|
// 进入批量删除模式
|
|
this.batchDeleteMode = true;
|
|
this.batchSelectList = [];
|
|
// 清除表格的选中状态
|
|
if (this.$refs.multipleTable) {
|
|
this.$refs.multipleTable.clearSelection();
|
|
}
|
|
// 强制刷新表格,确保复选框正确显示
|
|
this.$nextTick(() => {
|
|
if (this.$refs.multipleTable) {
|
|
this.$refs.multipleTable.doLayout();
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
// 处理表格选中变化(批量删除模式下)
|
|
handleSelectionChange(val) {
|
|
if (this.batchDeleteMode) {
|
|
this.batchSelectList = val;
|
|
} else {
|
|
// 非批量删除模式下,不处理多选,但保留原有功能
|
|
this.mulSelect = val;
|
|
}
|
|
},
|
|
|
|
// 处理行点击(非批量删除模式下,用于选中行;批量删除模式下,不处理)
|
|
handleRowClick(row) {
|
|
if (!this.batchDeleteMode) {
|
|
this.handleCurrentChange(row);
|
|
}
|
|
},
|
|
|
|
// 确认批量删除
|
|
confirmBatchDelete() {
|
|
if (this.batchSelectList.length === 0) {
|
|
this.$message.warning("请选择要删除的点位");
|
|
return;
|
|
}
|
|
|
|
// batchSelectList 已经通过 checkSelectable 过滤了标准点位,所以不需要再次过滤
|
|
const deletableList = this.batchSelectList;
|
|
|
|
const pointNames = deletableList
|
|
.map((item) => item.patrolpointName)
|
|
.join("、");
|
|
const message =
|
|
deletableList.length === 1
|
|
? `确定要删除点位 "${pointNames}" 吗?`
|
|
: `确定要删除选中的 ${deletableList.length} 个点位吗?\n${pointNames}`;
|
|
|
|
this.$confirm(message, "批量删除确认", {
|
|
confirmButtonText: "确定删除",
|
|
cancelButtonText: "取消",
|
|
type: "warning",
|
|
}).then(() => {
|
|
const ids = deletableList.map((item) => item.patrolpointId).join(",");
|
|
proDotTableDeleteSin(ids).then((res) => {
|
|
this.$message.success(`成功删除 ${deletableList.length} 个点位`);
|
|
// 退出批量删除模式
|
|
this.batchDeleteMode = false;
|
|
this.batchSelectList = [];
|
|
// 重新加载数据
|
|
this.loadList();
|
|
});
|
|
});
|
|
},
|
|
|
|
// 获取算法分类(点位类型)
|
|
getAlgCategory() {
|
|
var data = { dictType: "point_alg_category" };
|
|
listData(data).then((res) => {
|
|
this.algorithmCategoryOptions = res.rows || [];
|
|
});
|
|
},
|
|
|
|
// 获取算法分类中该分类下的记录数量
|
|
getAlgorithmCategoryCount(category) {
|
|
if (!this.tableData || !category || !category.dictValue) return 0;
|
|
|
|
const algIdsInCategory = category.dictValue
|
|
.split(",")
|
|
.map((id) => id.trim());
|
|
|
|
const count = this.tableData.filter((row) => {
|
|
if (!row.algSubtypeIds) return false;
|
|
const rowAlgIds = row.algSubtypeIds.split(",").map((id) => id.trim());
|
|
return algIdsInCategory.some((id) => rowAlgIds.includes(id));
|
|
}).length;
|
|
|
|
return count;
|
|
},
|
|
|
|
// 获取选中的算法分类标签
|
|
getSelectedAlgorithmCategoryLabel() {
|
|
const selected = this.algorithmCategoryOptions.find(
|
|
(item) => item.dictValue === this.selectedAlgorithmCategory
|
|
);
|
|
return selected ? selected.dictLabel : "";
|
|
},
|
|
|
|
// 更新设备类型选项
|
|
updateDeviceTypeOptions() {
|
|
const deviceTypeMap = new Map();
|
|
|
|
this.tableData.forEach((row) => {
|
|
if (row.pointTypeName) {
|
|
const typeName = row.pointTypeName;
|
|
if (deviceTypeMap.has(typeName)) {
|
|
deviceTypeMap.set(typeName, deviceTypeMap.get(typeName) + 1);
|
|
} else {
|
|
deviceTypeMap.set(typeName, 1);
|
|
}
|
|
}
|
|
});
|
|
|
|
this.deviceTypeOptions = Array.from(deviceTypeMap.entries()).map(
|
|
([label, count]) => ({
|
|
value: label,
|
|
label: label,
|
|
count: count,
|
|
})
|
|
);
|
|
},
|
|
|
|
// 按算法分类筛选
|
|
filterByAlgorithmCategory(value) {
|
|
this.selectedAlgorithmCategory = value;
|
|
this.selectedAlgorithmCategoryLabel =
|
|
this.getSelectedAlgorithmCategoryLabel();
|
|
},
|
|
|
|
// 按设备类型筛选
|
|
filterByDeviceType(value) {
|
|
this.selectedDeviceType = value;
|
|
const selectedOption = this.deviceTypeOptions.find(
|
|
(opt) => opt.value === value
|
|
);
|
|
this.selectedDeviceTypeLabel = selectedOption ? selectedOption.label : "";
|
|
},
|
|
|
|
// 清除所有筛选
|
|
clearAllFilters() {
|
|
this.selectedAlgorithmCategory = "";
|
|
this.selectedAlgorithmCategoryLabel = "";
|
|
this.selectedDeviceType = "";
|
|
this.selectedDeviceTypeLabel = "";
|
|
},
|
|
|
|
getNodeLabel(data) {
|
|
return data.deviceName || data.areaName || "未知节点";
|
|
},
|
|
|
|
shouldShowCount(data) {
|
|
// return data.children && data.children.length > 0;
|
|
return true;
|
|
},
|
|
|
|
getChildCount(data) {
|
|
return data.children ? data.children.length : 0;
|
|
},
|
|
getNodeCount(data) {
|
|
return data.pointNum || 0;
|
|
},
|
|
|
|
// 递归处理树数据,确保每个节点都有pointNum字段
|
|
getTreeData(response) {
|
|
const findArray = (value, depth = 0) => {
|
|
if (Array.isArray(value)) {
|
|
return value;
|
|
}
|
|
if (!value || typeof value !== "object" || depth > 4) {
|
|
return [];
|
|
}
|
|
if (
|
|
Array.isArray(value.children) &&
|
|
(value.areaId ||
|
|
value.areaid ||
|
|
value.deviceId ||
|
|
value.deviceName ||
|
|
value.areaName)
|
|
) {
|
|
return [value];
|
|
}
|
|
|
|
const keys = ["data", "rows", "list", "records", "result", "items"];
|
|
for (const key of keys) {
|
|
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
const result = findArray(value[key], depth + 1);
|
|
if (result.length > 0 || Array.isArray(value[key])) {
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
return [];
|
|
};
|
|
|
|
return findArray(response);
|
|
},
|
|
|
|
mapTree(nodes) {
|
|
if (!Array.isArray(nodes)) {
|
|
return;
|
|
}
|
|
nodes.forEach((node) => {
|
|
if (!node.deviceName) {
|
|
node.deviceName = node.areaName;
|
|
}
|
|
// 确保pointNum字段存在,如果没有则默认为0
|
|
if (node.pointNum === undefined || node.pointNum === null) {
|
|
node.pointNum = 0;
|
|
}
|
|
if (node.children && node.children.length > 0) {
|
|
this.mapTree(node.children);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 初始化列拖拽功能
|
|
initColumnResize() {
|
|
this.$nextTick(() => {
|
|
const table = this.$refs.multipleTable;
|
|
if (!table || !table.$el) return;
|
|
|
|
const tableWrapper = table.$el;
|
|
const headers = tableWrapper.querySelectorAll(".el-table__header th");
|
|
const tableBody = tableWrapper.querySelector(".el-table__body");
|
|
|
|
if (!headers.length) return;
|
|
|
|
headers.forEach((header, index) => {
|
|
// 清除可能存在的旧拖拽手柄
|
|
const oldResizer = header.querySelector(".column-resizer");
|
|
if (oldResizer) oldResizer.remove();
|
|
|
|
// 设置表头样式
|
|
header.style.position = "relative";
|
|
header.style.userSelect = "none";
|
|
|
|
// 创建拖拽手柄
|
|
const resizer = document.createElement("div");
|
|
resizer.className = "column-resizer";
|
|
|
|
// 创建视觉反馈线条
|
|
const resizerLine = document.createElement("div");
|
|
resizerLine.className = "column-resizer-line";
|
|
resizer.appendChild(resizerLine);
|
|
|
|
header.appendChild(resizer);
|
|
|
|
let startX = 0;
|
|
let startWidth = 0;
|
|
let isDragging = false;
|
|
|
|
const onMouseDown = (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
startX = e.pageX;
|
|
startWidth = header.offsetWidth;
|
|
isDragging = true;
|
|
|
|
// 添加拖拽时的样式
|
|
header.classList.add("dragging");
|
|
document.body.style.cursor = "col-resize";
|
|
document.body.style.userSelect = "none";
|
|
|
|
// 添加全局遮罩
|
|
const mask = document.createElement("div");
|
|
mask.id = "resize-mask";
|
|
document.body.appendChild(mask);
|
|
|
|
document.addEventListener("mousemove", onMouseMove);
|
|
document.addEventListener("mouseup", onMouseUp);
|
|
};
|
|
|
|
const onMouseMove = (e) => {
|
|
if (!isDragging) return;
|
|
|
|
// 计算新宽度
|
|
const diffX = e.pageX - startX;
|
|
const newWidth = Math.max(80, Math.min(800, startWidth + diffX)); // 限制最小80px,最大800px
|
|
|
|
// 更新表头宽度
|
|
header.style.width = newWidth + "px";
|
|
header.style.minWidth = newWidth + "px";
|
|
header.style.maxWidth = newWidth + "px";
|
|
|
|
// 更新对应的列单元格
|
|
if (tableBody) {
|
|
const rows = tableBody.querySelectorAll("tr");
|
|
rows.forEach((row) => {
|
|
const cell = row.children[index];
|
|
if (cell) {
|
|
cell.style.width = newWidth + "px";
|
|
cell.style.minWidth = newWidth + "px";
|
|
cell.style.maxWidth = newWidth + "px";
|
|
}
|
|
});
|
|
}
|
|
|
|
// 更新列宽缓存
|
|
this.columnWidths[index] = newWidth;
|
|
};
|
|
|
|
const onMouseUp = () => {
|
|
if (!isDragging) return;
|
|
|
|
isDragging = false;
|
|
header.classList.remove("dragging");
|
|
|
|
// 移除全局遮罩
|
|
const mask = document.getElementById("resize-mask");
|
|
if (mask) mask.remove();
|
|
|
|
// 恢复鼠标样式
|
|
document.body.style.cursor = "default";
|
|
document.body.style.userSelect = "";
|
|
|
|
document.removeEventListener("mousemove", onMouseMove);
|
|
document.removeEventListener("mouseup", onMouseUp);
|
|
|
|
// 保存列宽
|
|
this.saveColumnWidths();
|
|
};
|
|
|
|
// 添加鼠标事件
|
|
resizer.addEventListener("mousedown", onMouseDown);
|
|
|
|
// 添加双击重置
|
|
resizer.addEventListener("dblclick", (e) => {
|
|
e.stopPropagation();
|
|
this.resetColumnWidth(index);
|
|
});
|
|
|
|
// 添加悬停提示
|
|
resizer.title = "双击重置列宽";
|
|
});
|
|
});
|
|
},
|
|
|
|
// 保存列宽到 localStorage
|
|
saveColumnWidths() {
|
|
try {
|
|
const tableData = {
|
|
widths: this.columnWidths,
|
|
timestamp: Date.now(),
|
|
};
|
|
localStorage.setItem("tableColumnWidths", JSON.stringify(tableData));
|
|
} catch (e) {
|
|
console.warn("保存列宽失败:", e);
|
|
}
|
|
},
|
|
|
|
// 加载保存的列宽
|
|
loadColumnWidths() {
|
|
try {
|
|
const saved = localStorage.getItem("tableColumnWidths");
|
|
if (!saved) return;
|
|
|
|
const { widths, timestamp } = JSON.parse(saved);
|
|
|
|
// 检查保存时间,只保留最近7天的配置
|
|
const oneWeek = 7 * 24 * 60 * 60 * 1000;
|
|
if (Date.now() - timestamp > oneWeek) {
|
|
localStorage.removeItem("tableColumnWidths");
|
|
return;
|
|
}
|
|
|
|
this.columnWidths = widths || {};
|
|
|
|
this.$nextTick(() => {
|
|
this.applyColumnWidths();
|
|
});
|
|
} catch (e) {
|
|
console.warn("加载列宽失败:", e);
|
|
}
|
|
},
|
|
|
|
// 应用列宽
|
|
applyColumnWidths() {
|
|
const table = this.$refs.multipleTable;
|
|
if (!table || !table.$el) return;
|
|
|
|
const tableWrapper = table.$el;
|
|
const headers = tableWrapper.querySelectorAll(".el-table__header th");
|
|
const tableBody = tableWrapper.querySelector(".el-table__body");
|
|
|
|
if (!headers.length || Object.keys(this.columnWidths).length === 0)
|
|
return;
|
|
|
|
headers.forEach((header, index) => {
|
|
const savedWidth = this.columnWidths[index];
|
|
if (savedWidth) {
|
|
header.style.width = savedWidth + "px";
|
|
header.style.minWidth = savedWidth + "px";
|
|
header.style.maxWidth = savedWidth + "px";
|
|
|
|
if (tableBody) {
|
|
const rows = tableBody.querySelectorAll("tr");
|
|
rows.forEach((row) => {
|
|
const cell = row.children[index];
|
|
if (cell) {
|
|
cell.style.width = savedWidth + "px";
|
|
cell.style.minWidth = savedWidth + "px";
|
|
cell.style.maxWidth = savedWidth + "px";
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
// 重置列宽
|
|
resetColumnWidth(index) {
|
|
const defaultWidth = this.defaultColumnWidths[index] || 100;
|
|
|
|
// 更新缓存
|
|
this.columnWidths[index] = defaultWidth;
|
|
|
|
// 应用新宽度
|
|
const table = this.$refs.multipleTable;
|
|
if (!table || !table.$el) return;
|
|
|
|
const tableWrapper = table.$el;
|
|
const headers = tableWrapper.querySelectorAll(".el-table__header th");
|
|
const tableBody = tableWrapper.querySelector(".el-table__body");
|
|
|
|
const header = headers[index];
|
|
if (header) {
|
|
header.style.width = defaultWidth + "px";
|
|
header.style.minWidth = defaultWidth + "px";
|
|
header.style.maxWidth = defaultWidth + "px";
|
|
|
|
if (tableBody) {
|
|
const rows = tableBody.querySelectorAll("tr");
|
|
rows.forEach((row) => {
|
|
const cell = row.children[index];
|
|
if (cell) {
|
|
cell.style.width = defaultWidth + "px";
|
|
cell.style.minWidth = defaultWidth + "px";
|
|
cell.style.maxWidth = defaultWidth + "px";
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// 保存设置
|
|
this.saveColumnWidths();
|
|
|
|
this.$message.success("列宽已重置");
|
|
},
|
|
|
|
// 重置所有列宽
|
|
resetAllColumnWidths() {
|
|
this.columnWidths = {};
|
|
localStorage.removeItem("tableColumnWidths");
|
|
|
|
const table = this.$refs.multipleTable;
|
|
if (!table || !table.$el) return;
|
|
|
|
const tableWrapper = table.$el;
|
|
const headers = tableWrapper.querySelectorAll(".el-table__header th");
|
|
const tableBody = tableWrapper.querySelector(".el-table__body");
|
|
|
|
headers.forEach((header, index) => {
|
|
const defaultWidth = this.defaultColumnWidths[index] || 100;
|
|
header.style.width = "";
|
|
header.style.minWidth = "";
|
|
header.style.maxWidth = "";
|
|
|
|
if (tableBody) {
|
|
const rows = tableBody.querySelectorAll("tr");
|
|
rows.forEach((row) => {
|
|
const cell = row.children[index];
|
|
if (cell) {
|
|
cell.style.width = "";
|
|
cell.style.minWidth = "";
|
|
cell.style.maxWidth = "";
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
this.$message.success("所有列宽已重置");
|
|
},
|
|
|
|
// 处理窗口大小变化
|
|
handleResize() {
|
|
this.updateTableHeight();
|
|
this.$nextTick(() => {
|
|
this.initColumnResize();
|
|
this.applyColumnWidths();
|
|
});
|
|
|
|
// 窗口大小变化时,检查左侧面板宽度是否超出最大限制
|
|
const containerWidth = this.$el?.clientWidth || window.innerWidth;
|
|
const maxAllowedWidth = containerWidth * 0.4; // 最大不超过容器宽度的40%
|
|
|
|
if (this.leftPanelWidth > maxAllowedWidth) {
|
|
this.leftPanelWidth = Math.max(
|
|
this.minLeftWidth,
|
|
Math.min(maxAllowedWidth, this.leftPanelWidth)
|
|
);
|
|
}
|
|
|
|
// 触发表格重新布局
|
|
this.$nextTick(() => {
|
|
if (this.$refs.multipleTable) {
|
|
this.$refs.multipleTable.doLayout();
|
|
}
|
|
});
|
|
},
|
|
|
|
updateTableHeight() {
|
|
const viewportHeight = window.innerHeight || 800;
|
|
this.tableHeight = Math.max(420, Math.min(620, viewportHeight - 230));
|
|
},
|
|
|
|
// 新增的拖拽相关方法 - 只影响左侧树
|
|
startResize(event) {
|
|
this.isResizing = true;
|
|
this.startX = event.clientX;
|
|
this.startWidth = this.leftPanelWidth;
|
|
|
|
// 添加全局事件监听
|
|
document.addEventListener("mousemove", this.onResize);
|
|
document.addEventListener("mouseup", this.stopResize);
|
|
|
|
// 添加拖拽时的样式
|
|
document.body.style.cursor = "col-resize";
|
|
document.body.style.userSelect = "none";
|
|
|
|
// 添加拖拽遮罩
|
|
const mask = document.createElement("div");
|
|
mask.id = "resize-mask";
|
|
mask.style.position = "fixed";
|
|
mask.style.top = "0";
|
|
mask.style.left = "0";
|
|
mask.style.width = "100%";
|
|
mask.style.height = "100%";
|
|
mask.style.zIndex = "9999";
|
|
mask.style.cursor = "col-resize";
|
|
document.body.appendChild(mask);
|
|
},
|
|
|
|
onResize(event) {
|
|
if (!this.isResizing) return;
|
|
|
|
// 计算新的宽度
|
|
const diffX = event.clientX - this.startX;
|
|
let newWidth = this.startWidth + diffX;
|
|
|
|
// 限制最小最大宽度
|
|
newWidth = Math.max(
|
|
this.minLeftWidth,
|
|
Math.min(this.maxLeftWidth, newWidth)
|
|
);
|
|
|
|
this.leftPanelWidth = newWidth;
|
|
|
|
// Element UI does not observe this absolutely positioned container, so
|
|
// recalculate its header/body widths while the tree is being resized.
|
|
this.$nextTick(() => {
|
|
if (this.$refs.areaTree) {
|
|
this.$refs.areaTree.$el.style.width = "100%";
|
|
}
|
|
this.scheduleMainTableLayout();
|
|
});
|
|
},
|
|
|
|
stopResize() {
|
|
if (!this.isResizing) return;
|
|
|
|
this.isResizing = false;
|
|
|
|
// 移除全局事件监听
|
|
document.removeEventListener("mousemove", this.onResize);
|
|
document.removeEventListener("mouseup", this.stopResize);
|
|
|
|
// 恢复鼠标样式
|
|
document.body.style.cursor = "";
|
|
document.body.style.userSelect = "";
|
|
|
|
// 移除拖拽遮罩
|
|
const mask = document.getElementById("resize-mask");
|
|
if (mask) mask.remove();
|
|
|
|
// 保存宽度到localStorage
|
|
this.saveLeftPanelWidth();
|
|
this.$nextTick(this.scheduleMainTableLayout);
|
|
},
|
|
|
|
scheduleMainTableLayout() {
|
|
if (this.tableLayoutFrame) {
|
|
cancelAnimationFrame(this.tableLayoutFrame);
|
|
}
|
|
|
|
this.tableLayoutFrame = requestAnimationFrame(() => {
|
|
this.tableLayoutFrame = null;
|
|
if (this.$refs.multipleTable) {
|
|
this.$refs.multipleTable.doLayout();
|
|
}
|
|
});
|
|
},
|
|
|
|
// 保存左侧面板宽度
|
|
saveLeftPanelWidth() {
|
|
try {
|
|
localStorage.setItem(LEFT_PANEL_WIDTH_STORAGE_KEY, this.leftPanelWidth);
|
|
} catch (e) {
|
|
// console.warn('保存左侧面板宽度失败:', e);
|
|
}
|
|
},
|
|
|
|
// 加载左侧面板宽度
|
|
loadLeftPanelWidth() {
|
|
try {
|
|
const savedWidth = localStorage.getItem(LEFT_PANEL_WIDTH_STORAGE_KEY);
|
|
if (savedWidth) {
|
|
this.leftPanelWidth = parseInt(savedWidth, 10);
|
|
}
|
|
} catch (e) {
|
|
// console.warn('加载左侧面板宽度失败:', e);
|
|
}
|
|
},
|
|
|
|
// 重置左侧面板宽度
|
|
resetLeftPanelWidth() {
|
|
this.leftPanelWidth = DEFAULT_LEFT_PANEL_WIDTH;
|
|
this.saveLeftPanelWidth();
|
|
// 更新树布局
|
|
this.$nextTick(() => {
|
|
if (this.$refs.areaTree) {
|
|
this.$refs.areaTree.$el.style.width = "100%";
|
|
}
|
|
});
|
|
},
|
|
|
|
//获取无人机图片
|
|
getUavImg() {
|
|
var data = {
|
|
patrolPointId: this.currentRow.patrolpointId,
|
|
};
|
|
irUavImg(data)
|
|
.then((response) => {
|
|
this.imageUrl = response.data;
|
|
this.imagePath = response.data;
|
|
})
|
|
.catch(() => {
|
|
item.loading = false;
|
|
});
|
|
},
|
|
|
|
// 无人机画框完成
|
|
uavComplete() {
|
|
var all_data = JSON.parse(localStorage.getItem("drawData"));
|
|
var imgElement = JSON.parse(localStorage.getItem("imgElement"));
|
|
const data = {
|
|
coordinates: all_data,
|
|
filePath: this.imagePath,
|
|
imgWidth: imgElement.width,
|
|
imgHeight: imgElement.height,
|
|
imgType: "infra_yu3",
|
|
patrolPointCode: this.currentRow.patrolpointCode,
|
|
patrolPointId: this.currentRow.patrolpointId,
|
|
};
|
|
capturePicture(data)
|
|
.then((response) => {
|
|
if (response.code == 200) {
|
|
this.monitorShow = false;
|
|
}
|
|
})
|
|
.catch(() => {
|
|
item.loading = false;
|
|
});
|
|
},
|
|
|
|
// tab切换
|
|
handleClick(tab, event) {
|
|
if (tab.name != "home") {
|
|
this.$refs.checkItemSetRef.clearAll();
|
|
}
|
|
this.activeName = tab.name;
|
|
},
|
|
|
|
algorithmClick() {
|
|
this.algorithmShow = true;
|
|
},
|
|
|
|
//选择完设备后调用
|
|
handleChooseDevicesOk(device) {
|
|
addPatrolpointpreset({
|
|
patroldeviceCode: device.patroldeviceCode,
|
|
eqpbookId: device.eqpbookId,
|
|
patrolpointId: this.currentRow.patrolpointId,
|
|
}).then(() => {
|
|
this.$message.success("绑定成功");
|
|
this.loadPointDevices();
|
|
});
|
|
},
|
|
|
|
//显示上传
|
|
eventUpload() {
|
|
this.showRebotUploader = true;
|
|
},
|
|
|
|
handleRebotUploaderConfirm() {},
|
|
|
|
// 选择算法完毕
|
|
handleChooseAlgOk(result) {
|
|
const selectedAlgs = result;
|
|
|
|
// 提取选中的算法ID和名称
|
|
const algSubtypeIds = selectedAlgs.map((item) => item.id).join(",");
|
|
const algSubtypeNames = selectedAlgs.map((item) => item.name).join(",");
|
|
|
|
this.currentRow.algSubtypeIds = algSubtypeIds;
|
|
this.currentRow.algSubtypeName = algSubtypeNames;
|
|
this.currentRow.alarmThreshold = JSON.stringify(selectedAlgs);
|
|
|
|
// 调用保存到后端的方法
|
|
this.handleChangePointCode(this.currentRow);
|
|
|
|
this.$message.success("算法配置已更新");
|
|
// setTimeout(() => {
|
|
// this.loadList();
|
|
// }, 500);
|
|
},
|
|
saveAlgorithmConfig(row) {
|
|
const postData = {
|
|
patrolpointId: row.patrolpointId,
|
|
algSubtypeIds: row.algSubtypeIds,
|
|
algSubtypeName: row.algSubtypeName,
|
|
alarmThreshold: row.alarmThreshold,
|
|
};
|
|
|
|
// 调用专门的API保存算法配置
|
|
// 假设有一个 updateAlgorithm 的 API
|
|
// updateAlgorithm(postData).then(res => {
|
|
// console.log("算法配置保存成功");
|
|
// }).catch(err => {
|
|
// console.error("保存失败:", err);
|
|
// this.$message.error("保存失败");
|
|
// });
|
|
|
|
// 或者使用现有的 handleChangePointCode
|
|
this.handleChangePointCode(row);
|
|
},
|
|
|
|
//点位列表,更换智能识别类型
|
|
chooseAlgorithm(row) {
|
|
if (this.batchDeleteMode) {
|
|
this.$message.warning("请先退出批量删除模式");
|
|
return;
|
|
}
|
|
this.currentRow = row;
|
|
this.showChooseAlg = true;
|
|
},
|
|
|
|
//点击图片上传按钮
|
|
handleUploadPicture(row) {
|
|
this.currentRow = row;
|
|
this.$nextTick(() => {
|
|
this.showUploader = true;
|
|
});
|
|
},
|
|
|
|
// 显示基准判别图片数量
|
|
rowPicCount(row) {
|
|
if (row.disRefPicturePath && row.disRefPicturePath.length > 0) {
|
|
return row.disRefPicturePath.split(",").length;
|
|
}
|
|
return 0;
|
|
},
|
|
|
|
// 图片上传弹窗,点击确定
|
|
handleUploaderConfirm(fileList) {
|
|
if (fileList.length > 0) {
|
|
this.currentRow.disRefPicturePath = linq
|
|
.from(fileList)
|
|
.select((x) => x.url)
|
|
.toArray()
|
|
.join(",");
|
|
} else {
|
|
this.currentRow.disRefPicturePath = "";
|
|
}
|
|
this.handleChangePointCode(this.currentRow);
|
|
},
|
|
|
|
handleCloseTemptrueModel() {
|
|
this.resetForm("formTemptrue");
|
|
const drawRefs = linq
|
|
.from(this.$refs.playerPlayform2.$children)
|
|
.where((x) => x.$vnode.componentOptions.tag === "DrawShape")
|
|
.toArray();
|
|
const drawRef = drawRefs[0];
|
|
drawRef.clearShapes();
|
|
},
|
|
|
|
handleCloseVL() {
|
|
this.$refs.playerPlayform.handleCloseAllChannel();
|
|
},
|
|
|
|
handleCloseIR() {
|
|
this.$refs.playerPlayform2.handleCloseAllChannel();
|
|
},
|
|
|
|
handleLoading(isLoading) {
|
|
this.currentImageRow.loading = isLoading;
|
|
},
|
|
|
|
handleImageLoad() {
|
|
this.currentImageRow.loading = false;
|
|
this.$refs.asyncImage.$el.querySelector("img").click();
|
|
},
|
|
|
|
handleImageLoadError() {
|
|
this.currentImageRow.loading = false;
|
|
},
|
|
|
|
handleViewImages(row) {
|
|
this.currentSrc = "";
|
|
this.currentSrcList = [];
|
|
this.showPreviewImages = false;
|
|
|
|
this.$nextTick(() => {
|
|
this.currentImageRow = row;
|
|
const srcs = row.channelImg.split(",");
|
|
this.currentSrc = srcs[0];
|
|
this.currentSrcList = srcs;
|
|
this.showPreviewImages = true;
|
|
});
|
|
},
|
|
|
|
handleAreaTreeCurrentNodeChange(data) {
|
|
this.currentTreeNode = data;
|
|
},
|
|
|
|
handleChangePointCode(row) {
|
|
const postData = lodash.cloneDeep(row);
|
|
postData.areaId = this.currentTreeNode.areaId;
|
|
postData.deviceId = this.currentTreeNode.deviceId;
|
|
|
|
if (postData.patrolTypeId && postData.patrolTypeId.length > 0) {
|
|
postData.patrolTypeId = postData.patrolTypeId.join(",");
|
|
} else {
|
|
postData.patrolTypeId = "";
|
|
}
|
|
|
|
if (row.patrolpointId) {
|
|
proDotTableEditSin(postData);
|
|
} else {
|
|
proDotTableAddSin(postData).then((res) => {
|
|
row.patrolpointId = res.data;
|
|
});
|
|
}
|
|
},
|
|
|
|
handleSelectPointCode(node, row) {
|
|
row.patrolTypeId.push(node.id);
|
|
this.handleChangePointCode(row);
|
|
},
|
|
|
|
handleDeSelectPointCode(node, row) {
|
|
if (row.patrolTypeId.indexOf(node.id) != -1) {
|
|
row.patrolTypeId.splice(row.patrolTypeId.indexOf(node.id), 1);
|
|
this.handleChangePointCode(row);
|
|
}
|
|
},
|
|
|
|
addAction() {
|
|
this.presetData.presetActionList.push({
|
|
actionType: "",
|
|
videoTime: "",
|
|
photoCount: "1",
|
|
photoSeper: "",
|
|
});
|
|
},
|
|
|
|
removeAction(index) {
|
|
this.presetData.presetActionList.splice(index, 1);
|
|
},
|
|
|
|
getTreeNodeQuery(node = {}, patrolpointName = "") {
|
|
const areaId = node.areaId || node.areaid || node.id || "";
|
|
return {
|
|
deviceId: node.deviceId || node.deviceid || "",
|
|
mainDeviceId: node.mainDeviceId || node.mainDeviceID || node.mainDeviceid || "",
|
|
areaId,
|
|
areaid: areaId,
|
|
patrolpointName: patrolpointName || node.patrolpointName || "",
|
|
pageNum: "",
|
|
pageSize: "",
|
|
};
|
|
},
|
|
|
|
/* 初始化左侧列表数据 */
|
|
getAreaList1() {
|
|
treeAreaDeviceSelectFilterByPresetRelation().then((res) => {
|
|
const treeData = this.getTreeData(res);
|
|
this.mapTree(treeData);
|
|
this.areaList = treeData;
|
|
if (treeData.length === 0) {
|
|
this.treeobj = null;
|
|
this.currentTreeNode = null;
|
|
this.tableData = [];
|
|
this.loading = false;
|
|
return;
|
|
}
|
|
let data = this.getTreeNodeQuery(treeData[0]);
|
|
this.treeobj = data;
|
|
this.loadList();
|
|
}).catch(() => {
|
|
this.areaList = [];
|
|
this.treeobj = null;
|
|
this.currentTreeNode = null;
|
|
this.tableData = [];
|
|
});
|
|
},
|
|
|
|
/* 点击左侧获取响应节点数据 */
|
|
handleAreaList(e) {
|
|
this.clearAllFilters();
|
|
this.currentTreeNode = e;
|
|
this.treeobj = this.getTreeNodeQuery(e);
|
|
this.formAdd.deviceId = this.treeobj.deviceId;
|
|
this.formAdd.mainDeviceId = this.treeobj.mainDeviceId;
|
|
this.formAdd.areaId = this.treeobj.areaId;
|
|
this.currentRow = null;
|
|
this.loadList();
|
|
},
|
|
|
|
loadList(data) {
|
|
this.loading = true;
|
|
const query = data || this.treeobj || {};
|
|
const getRows = (response) => {
|
|
if (Array.isArray(response && response.rows)) {
|
|
return response.rows;
|
|
}
|
|
if (Array.isArray(response && response.list)) {
|
|
return response.list;
|
|
}
|
|
if (Array.isArray(response && response.records)) {
|
|
return response.records;
|
|
}
|
|
if (response && response.data && Array.isArray(response.data.rows)) {
|
|
return response.data.rows;
|
|
}
|
|
if (response && response.data && Array.isArray(response.data.list)) {
|
|
return response.data.list;
|
|
}
|
|
if (response && response.data && Array.isArray(response.data.records)) {
|
|
return response.data.records;
|
|
}
|
|
if (response && Array.isArray(response.data)) {
|
|
return response.data;
|
|
}
|
|
if (
|
|
response &&
|
|
response.data &&
|
|
response.data.data &&
|
|
Array.isArray(response.data.data.rows)
|
|
) {
|
|
return response.data.data.rows;
|
|
}
|
|
if (
|
|
response &&
|
|
response.data &&
|
|
response.data.data &&
|
|
Array.isArray(response.data.data.list)
|
|
) {
|
|
return response.data.data.list;
|
|
}
|
|
if (
|
|
response &&
|
|
response.data &&
|
|
response.data.data &&
|
|
Array.isArray(response.data.data.records)
|
|
) {
|
|
return response.data.data.records;
|
|
}
|
|
if (response && response.data && Array.isArray(response.data.data)) {
|
|
return response.data.data;
|
|
}
|
|
return [];
|
|
};
|
|
const loadRelationList = () =>
|
|
proDotManTableRelation(query)
|
|
.then((response) => {
|
|
return getRows(response).length > 0
|
|
? response
|
|
: proDotManTable(query);
|
|
})
|
|
.catch(() => proDotManTable(query));
|
|
|
|
loadRelationList()
|
|
.then((res) => {
|
|
this.loading = false;
|
|
const rows = getRows(res);
|
|
rows.forEach((row) => {
|
|
row.bindPoints = [];
|
|
row.bindDevices = [];
|
|
if (row.patrolTypeId && /^\d/.test(row.patrolTypeId) == false) {
|
|
var id = row.patrolTypeId;
|
|
row.patrolTypeId = id.substring(1);
|
|
}
|
|
if (row.patrolTypeId && row.patrolTypeId.length > 0) {
|
|
row.patrolTypeId = linq
|
|
.from(row.patrolTypeId.split(","))
|
|
.select((x) => {
|
|
return parseInt(x);
|
|
})
|
|
.toArray();
|
|
} else {
|
|
row.patrolTypeId = [];
|
|
}
|
|
|
|
// 调试:打印 alarmThreshold
|
|
// if (row.alarmThreshold) {
|
|
// console.log(
|
|
// "点位",
|
|
// row.patrolpointName,
|
|
// "的 alarmThreshold:",
|
|
// row.alarmThreshold
|
|
// );
|
|
// }
|
|
});
|
|
this.tableData = rows;
|
|
this.updateDeviceTypeOptions();
|
|
|
|
this.$nextTick(() => {
|
|
if (this.$refs.multipleTable) {
|
|
this.$refs.multipleTable.doLayout();
|
|
}
|
|
this.initColumnResize();
|
|
this.loadColumnWidths();
|
|
});
|
|
})
|
|
.catch(() => {
|
|
this.loading = false;
|
|
});
|
|
},
|
|
|
|
/* 修改单条监控点位数据 */
|
|
editRows1(index, row) {
|
|
// 批量删除模式下不允许编辑
|
|
if (this.batchDeleteMode) {
|
|
this.$message.warning("请先退出批量删除模式");
|
|
return;
|
|
}
|
|
this.showAdd = true;
|
|
this.titleAlert = "修改监控点位";
|
|
// 深拷贝数据用于修改
|
|
this.formAdd = lodash.cloneDeep(row);
|
|
|
|
// 确保 patrolTypeId 是数组格式(如果是字符串则转换)
|
|
if (
|
|
this.formAdd.patrolTypeId &&
|
|
typeof this.formAdd.patrolTypeId === "string"
|
|
) {
|
|
this.formAdd.patrolTypeId = this.formAdd.patrolTypeId
|
|
.split(",")
|
|
.map((id) => parseInt(id));
|
|
}
|
|
|
|
// 确保 pointImptLevel 正确处理
|
|
if (
|
|
this.formAdd.pointImptLevel === undefined ||
|
|
this.formAdd.pointImptLevel === null
|
|
) {
|
|
this.formAdd.pointImptLevel = null;
|
|
}
|
|
|
|
// 确保 purpose 正确处理
|
|
if (this.formAdd.purpose === undefined) {
|
|
this.formAdd.purpose = "";
|
|
}
|
|
|
|
// 清除表单验证状态
|
|
this.$nextTick(() => {
|
|
if (this.$refs.formAdd) {
|
|
this.$refs.formAdd.clearValidate();
|
|
}
|
|
});
|
|
},
|
|
|
|
/* 删除单条监控点位数据 */
|
|
deleteRows1(index, row) {
|
|
// 批量删除模式下不允许删除
|
|
if (this.batchDeleteMode) {
|
|
this.$message.warning("请先退出批量删除模式");
|
|
return;
|
|
}
|
|
this.$confirm("确定要删除数据吗?").then((res) => {
|
|
proDotTableDeleteSin(row.patrolpointId).then((res) => {
|
|
this.loadList();
|
|
});
|
|
});
|
|
},
|
|
|
|
/* 新增单条监控点位数据t弹窗展示 */
|
|
addAlertShow1() {
|
|
// 批量删除模式下不允许新增
|
|
if (this.batchDeleteMode) {
|
|
this.$message.warning("请先退出批量删除模式");
|
|
return;
|
|
}
|
|
this.showAdd = true;
|
|
this.titleAlert = "添加监控点位";
|
|
// 完全重置formAdd对象,清空所有输入字段
|
|
this.formAdd = {
|
|
patrolpointName: "",
|
|
patrolContent: "",
|
|
purpose: "", // 清空读数单位
|
|
areaId: this.currentTreeNode ? this.currentTreeNode.areaId : "",
|
|
mainDeviceId: this.currentTreeNode
|
|
? this.currentTreeNode.mainDeviceId
|
|
: "",
|
|
deviceId: this.currentTreeNode ? this.currentTreeNode.deviceId : "",
|
|
patrolpointCode: "",
|
|
patrolTypeId: null, // 关键:清空巡检类型
|
|
pointImptLevel: null, // 关键:清空重要等级
|
|
positionX: null,
|
|
positionY: null,
|
|
positionZ: null,
|
|
};
|
|
|
|
// 清除表单验证状态
|
|
this.$nextTick(() => {
|
|
if (this.$refs.formAdd) {
|
|
this.$refs.formAdd.clearValidate();
|
|
}
|
|
});
|
|
},
|
|
|
|
/* 新增、修改单条监控点位数据取消 */
|
|
alertCancel1() {
|
|
this.showAdd = false;
|
|
this.formAdd = {
|
|
patrolpointName: "",
|
|
patrolContent: "",
|
|
purpose: "",
|
|
areaId: this.currentTreeNode ? this.currentTreeNode.areaId : "",
|
|
mainDeviceId: this.currentTreeNode
|
|
? this.currentTreeNode.mainDeviceId
|
|
: "",
|
|
deviceId: this.currentTreeNode ? this.currentTreeNode.deviceId : "",
|
|
patrolpointCode: "",
|
|
patrolTypeId: null,
|
|
pointImptLevel: null,
|
|
positionX: null,
|
|
positionY: null,
|
|
positionZ: null,
|
|
};
|
|
// 清除验证
|
|
this.$nextTick(() => {
|
|
if (this.$refs.formAdd) {
|
|
this.$refs.formAdd.clearValidate();
|
|
}
|
|
});
|
|
},
|
|
|
|
/* 新增、修改单条监控点位数据确认 */
|
|
alertConfirm1() {
|
|
this.$refs.formAdd.validate((valid) => {
|
|
if (valid) {
|
|
this.formAddLoading = true;
|
|
const postData = lodash.cloneDeep(this.formAdd);
|
|
postData.areaId = this.currentTreeNode.areaId;
|
|
postData.deviceId = this.currentTreeNode.deviceId;
|
|
if (postData.patrolTypeId && postData.patrolTypeId.length > 0) {
|
|
postData.patrolTypeId = postData.patrolTypeId.join(",");
|
|
} else {
|
|
postData.patrolTypeId = "";
|
|
}
|
|
if (this.titleAlert == "添加监控点位") {
|
|
proDotTableAddSin(postData)
|
|
.then(() => {
|
|
this.showAdd = false;
|
|
this.resetForm("formAdd");
|
|
this.formAddLoading = false;
|
|
this.loadList();
|
|
})
|
|
.catch(() => {
|
|
this.formAddLoading = false;
|
|
});
|
|
} else {
|
|
proDotTableEditSin(postData)
|
|
.then((res) => {
|
|
this.showAdd = false;
|
|
this.resetForm("formAdd");
|
|
this.formAddLoading = false;
|
|
this.loadList();
|
|
})
|
|
.catch(() => {
|
|
this.formAddLoading = false;
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
//选中一条巡检点位
|
|
handleCurrentChange(row) {
|
|
this.currentRow = row;
|
|
this.loadDevicePoints();
|
|
this.loadPointDevices();
|
|
},
|
|
|
|
// 加载巡检点位绑定的巡检设备 (机器人或者无人机)
|
|
loadPointDevices() {
|
|
if (!this.currentRow.patrolpointId) {
|
|
return;
|
|
}
|
|
this.pointLoading = true;
|
|
listPatrolpointpreset({
|
|
patrolpointId: this.currentRow.patrolpointId,
|
|
noVideo: true,
|
|
})
|
|
.then((res) => {
|
|
this.pointLoading = false;
|
|
this.currentRow.bindDevices = res.rows;
|
|
})
|
|
.catch(() => {
|
|
this.pointLoading = false;
|
|
});
|
|
},
|
|
|
|
//加载巡检点位绑定的预置点
|
|
loadDevicePoints() {
|
|
this.pointLoading = true;
|
|
getPatroPointDevicePoints(this.currentRow.patrolpointId)
|
|
.then((res) => {
|
|
this.pointLoading = false;
|
|
res.data.forEach((row) => {
|
|
row.currentSrc = "";
|
|
row.currentSrcList = [];
|
|
row.loading = false;
|
|
});
|
|
this.currentRow.bindPoints = res.data;
|
|
})
|
|
.catch(() => {
|
|
this.pointLoading = false;
|
|
});
|
|
},
|
|
|
|
handleEnablePoint(item, index) {
|
|
item.loading = true;
|
|
const postData = lodash.cloneDeep(item);
|
|
postData.isEnable = postData.isEnable == 1 ? 0 : 1;
|
|
editPoint(postData)
|
|
.then(() => {
|
|
item.loading = false;
|
|
item.isEnable = item.isEnable == 1 ? 0 : 1;
|
|
this.$message.success(
|
|
"操作成功:点位已" + (item.isEnable ? "启用" : "停用")
|
|
);
|
|
})
|
|
.catch(() => {
|
|
item.loading = false;
|
|
});
|
|
},
|
|
|
|
//解绑预置点
|
|
handleUnbindPoint(item, index) {
|
|
this.$confirm("确定解绑预置点吗?").then((res) => {
|
|
unbindPoint(item.presetPosId).then(() => {
|
|
this.$message.success("解绑预置点成功");
|
|
this.currentRow.bindPoints.splice(index, 1);
|
|
});
|
|
});
|
|
},
|
|
|
|
//解绑巡检设备
|
|
handleUnbindDevice(item, index) {
|
|
this.$confirm("确定解绑巡检设备吗?").then((res) => {
|
|
delPatrolpointpreset(item.patrolpointPresetId).then(() => {
|
|
this.$message.success("解设巡检设备绑成功");
|
|
this.currentRow.bindDevices.splice(index, 1);
|
|
});
|
|
});
|
|
},
|
|
|
|
/* 删除多条监控点位数据 - 已废弃,改用批量删除模式 */
|
|
deleteMul1() {
|
|
// 此方法已废弃,改用批量删除模式
|
|
this.toggleBatchDeleteMode();
|
|
},
|
|
|
|
// 搜索左侧的树
|
|
searchTree() {
|
|
const searchText = this.inputSearch1.trim();
|
|
if (!searchText) {
|
|
this.getAreaList1();
|
|
return;
|
|
}
|
|
|
|
const searchNodes = (nodes) => {
|
|
const result = [];
|
|
nodes.forEach((node) => {
|
|
const nodeName = node.areaName || node.deviceName || "";
|
|
const isMatch = nodeName.includes(searchText);
|
|
|
|
if (isMatch) {
|
|
result.push(node);
|
|
} else {
|
|
if (node.children && node.children.length > 0) {
|
|
const matchedChildren = searchNodes(node.children);
|
|
if (matchedChildren.length > 0) {
|
|
const newNode = {
|
|
...node,
|
|
children: matchedChildren,
|
|
pointNum: node.pointNum,
|
|
};
|
|
result.push(newNode);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
return result;
|
|
};
|
|
|
|
const originalData = this.areaList;
|
|
const filteredData = searchNodes(originalData);
|
|
this.areaList = filteredData;
|
|
|
|
if (filteredData.length === 0) {
|
|
this.$message.warning("未找到匹配的区域");
|
|
}
|
|
},
|
|
|
|
/* 搜索相关名称的监控点位数据 */
|
|
searchTable1() {
|
|
let data = {
|
|
...(this.treeobj || this.getTreeNodeQuery(this.currentTreeNode || {})),
|
|
patrolpointName: this.inputSearch,
|
|
};
|
|
this.loadList(data);
|
|
},
|
|
|
|
// 点位配置,弹出框
|
|
pointConfiguration() {
|
|
this.$refs.form.style.width = "72%";
|
|
this.showRightPanel = true;
|
|
},
|
|
|
|
// 点位配置收起
|
|
collectPoint() {
|
|
this.$refs.form.style.width = "100%";
|
|
this.showRightPanel = false;
|
|
},
|
|
|
|
// 可见光弹窗展示
|
|
visibleShow1() {
|
|
if (this.currentRow === null) {
|
|
this.$modal.msgWarning("请先选择在列表中点击一条点位数据!");
|
|
return;
|
|
}
|
|
// 重置预置点相关数据
|
|
this.presetDotNum = "";
|
|
this.presetName = "";
|
|
this.presetNumber = "";
|
|
this.is_convert = false;
|
|
this.is_set = false;
|
|
// 重置 presetData 中的预置点名称
|
|
this.presetData.presetPosName = "";
|
|
this.presetData.presetPosCode = "";
|
|
|
|
this.monitorShow = true;
|
|
this.monitorType = "vl";
|
|
this.titleLightTitle = "预置位配置";
|
|
bindingMonitorDotList(this.monitorType).then((res) => {
|
|
this.monitorList = res.data;
|
|
});
|
|
},
|
|
|
|
// 红外光弹窗展示
|
|
infraredShow1() {
|
|
// 重置预置点相关数据
|
|
this.presetDotNum = "";
|
|
this.presetName = "";
|
|
this.presetNumber = "";
|
|
this.is_set = false;
|
|
// 重置 presetData 中的预置点名称
|
|
this.presetData.presetPosName = "";
|
|
this.presetData.presetPosCode = "";
|
|
|
|
// 移动设备绑定暂时停用,避免调用无人机图片接口。
|
|
this.monitorShow = true;
|
|
this.monitorType = "ir";
|
|
this.titleLightTitle = "绑定热成像监控点";
|
|
bindingMonitorDotList(this.monitorType).then((res) => {
|
|
this.monitorList = res.data;
|
|
});
|
|
},
|
|
|
|
// 监控点位弹窗获取左侧点位数据
|
|
handleMonitor(e) {
|
|
this.presetDotNum = "";
|
|
this.presetDotDis = true;
|
|
if (e.eqpbookId) {
|
|
this.presetDotDis = false;
|
|
this.equipobj = {
|
|
eqpbookId: e.eqpbookId,
|
|
channelCode: e.channelCode,
|
|
patroldeviceCode: e.patroldeviceCode,
|
|
channelId: e.channelId,
|
|
};
|
|
this.patroldeviceName = e.patroldeviceName;
|
|
let data = {
|
|
patroldeviceCode: e.patroldeviceCode,
|
|
channelId: e.channelId,
|
|
channelCode: e.channelCode,
|
|
};
|
|
this.presetData.patrolpointId = this.currentRow.patrolpointId;
|
|
this.presetData.stdparolPointId = this.currentRow.stdparolPointId;
|
|
this.presetData.deviceId = this.currentRow.deviceId;
|
|
this.presetData.eqpbookId = e.eqpbookId;
|
|
this.presetData.channelId = e.channelId;
|
|
|
|
// 获取该设备的预置点列表并填充 presetArr
|
|
getDeviceList(e.patroldeviceCode, e.channelCode).then(({ data }) => {
|
|
this.presetArr = data;
|
|
// 如果有预置点,默认选中第一个
|
|
if (data && data.length > 0) {
|
|
this.presetDotNum = data[0].dictValue;
|
|
this.presetName = data[0].dictLabel;
|
|
this.presetNumber = data[0].dictValue;
|
|
// 将预置点名称赋值给 presetData
|
|
this.presetData.presetPosName = this.presetName;
|
|
this.presetData.presetPosCode = this.presetDotNum;
|
|
} else {
|
|
this.presetName = "";
|
|
this.presetNumber = "";
|
|
this.presetData.presetPosName = "";
|
|
this.presetData.presetPosCode = "";
|
|
}
|
|
});
|
|
|
|
this.handleOpenChannel(data);
|
|
}
|
|
},
|
|
|
|
// 云台控制
|
|
controlEquip1(a1) {
|
|
let data = {
|
|
patroldeviceCode: this.equipobj.patroldeviceCode,
|
|
channelCode: this.equipobj.channelCode,
|
|
speed: 5,
|
|
ptzControlType: a1,
|
|
};
|
|
cloudControl(data).then((res) => {});
|
|
},
|
|
|
|
controlEquip2(a1) {
|
|
let data = {
|
|
patroldeviceCode: this.equipobj.patroldeviceCode,
|
|
channelCode: this.equipobj.channelCode,
|
|
speed: 5,
|
|
ptzControlType: a1,
|
|
};
|
|
focalAperture(data).then((res) => {});
|
|
},
|
|
|
|
// 选择预置点 0——255
|
|
presetDotChange1(e) {
|
|
this.cssClass = false;
|
|
this.presetData.presetPosCode = e;
|
|
var obj = this.presetArr.find((item) => {
|
|
return item.dictValue == e;
|
|
});
|
|
if (obj) {
|
|
this.presetName = obj.dictLabel;
|
|
this.presetNumber = obj.dictValue;
|
|
// 选择预置点时更新 presetData 中的预置点名称
|
|
this.presetData.presetPosName = this.presetName;
|
|
if (obj.cssClass == 1) {
|
|
this.cssClass = true;
|
|
}
|
|
} else {
|
|
this.presetName = "";
|
|
this.presetNumber = "";
|
|
this.presetData.presetPosName = "";
|
|
}
|
|
},
|
|
|
|
// 转换预置点
|
|
convertPresetDot1() {
|
|
convertPresetDot({
|
|
patroldeviceCode: this.equipobj.patroldeviceCode,
|
|
channelCode: this.equipobj.channelCode,
|
|
presetCode: this.presetDotNum,
|
|
name: this.presetDotNum,
|
|
}).then((res) => {
|
|
this.is_convert = true;
|
|
this.$modal.msgSuccess("转到预置点成功!");
|
|
});
|
|
},
|
|
|
|
// 设置预置点
|
|
setPresetDot1() {
|
|
if (this.presetDotDis) {
|
|
this.$modal.msgWarning("请选择通道!");
|
|
return;
|
|
}
|
|
if (this.newpresetName.trim().length === 0) {
|
|
this.$modal.msgWarning("请先输入预置点名称!");
|
|
return;
|
|
}
|
|
var obj = this.presetArr.find((item) => {
|
|
return item.dictLabel == this.newpresetName.trim();
|
|
});
|
|
if (obj) {
|
|
this.$modal.msgWarning("预置点名称重复!");
|
|
return;
|
|
}
|
|
presetDotDistribute({
|
|
patroldeviceCode: this.equipobj.patroldeviceCode,
|
|
channelCode: this.equipobj.channelCode,
|
|
presetCode: this.presetDotNum,
|
|
name: this.newpresetName,
|
|
}).then((res) => {
|
|
this.is_set = true;
|
|
this.$modal.msgSuccess("设置预置点成功!");
|
|
this.popovervisible = false;
|
|
// 重新获取预置点列表,并更新当前选中的预置点信息
|
|
getDeviceList(this.equipobj.patroldeviceCode, this.equipobj.channelCode).then(({ data }) => {
|
|
this.presetArr = data;
|
|
// 找到新添加的预置点并选中
|
|
const newPreset = data.find(item => item.dictLabel === this.newpresetName.trim());
|
|
if (newPreset) {
|
|
this.presetDotNum = newPreset.dictValue;
|
|
this.presetName = newPreset.dictLabel;
|
|
this.presetNumber = newPreset.dictValue;
|
|
// 更新 presetData 中的预置点名称
|
|
this.presetData.presetPosName = this.presetName;
|
|
this.presetData.presetPosCode = this.presetDotNum;
|
|
}
|
|
this.newpresetName = "";
|
|
});
|
|
});
|
|
},
|
|
|
|
//删除预置点
|
|
delPresetDot1() {
|
|
if (this.presetDotNum) {
|
|
this.$confirm("此操作将永久删除该预置点, 是否继续?", "提示", {
|
|
confirmButtonText: "确定",
|
|
cancelButtonText: "取消",
|
|
type: "warning",
|
|
})
|
|
.then(() => {
|
|
this.$message({
|
|
type: "success",
|
|
message: "删除成功!",
|
|
});
|
|
this.popovervisible = false;
|
|
this.getDeviceList();
|
|
})
|
|
.catch(() => {});
|
|
} else {
|
|
this.$modal.msgWarning("请选择预置点!");
|
|
}
|
|
},
|
|
|
|
//编辑预置点
|
|
editPresetDot1() {
|
|
if (this.presetName.trim().length === 0) {
|
|
this.$modal.msgWarning("请先输入预置点名称!");
|
|
return;
|
|
}
|
|
var obj = this.presetArr.find((item) => {
|
|
return item.dictLabel == this.presetName.trim();
|
|
});
|
|
if (obj && obj.dictValue != this.presetDotNum) {
|
|
this.$modal.msgWarning("预置点名称重复!");
|
|
return;
|
|
}
|
|
issueUpdate({
|
|
patrolDeviceCode: this.equipobj.patroldeviceCode,
|
|
channelCode: this.equipobj.channelCode,
|
|
presetCode: this.presetDotNum,
|
|
name: this.presetName,
|
|
}).then((res) => {
|
|
this.is_set = true;
|
|
// 编辑后更新 presetData 中的预置点名称
|
|
this.presetData.presetPosName = this.presetName;
|
|
getDeviceList(this.equipobj.patroldeviceCode, this.equipobj.channelCode).then(({ data }) => {
|
|
this.presetArr = data;
|
|
});
|
|
this.$modal.msgSuccess("设置预置点成功!");
|
|
});
|
|
},
|
|
|
|
//上一步
|
|
prevStep() {
|
|
this.monitorShow = true;
|
|
this.monitorSecShow = false;
|
|
},
|
|
|
|
// 下一步弹窗显示
|
|
nextStep1() {
|
|
this.monitorShow = false;
|
|
this.monitorSecShow = true;
|
|
this.drawShapIndex = 0;
|
|
this.presetData.presetPosName = this.presetName;
|
|
this.handleOpenChannel(this.equipobj, true);
|
|
},
|
|
|
|
// 选择绘制方式
|
|
chooseDrawShape1(a1, a2) {
|
|
this.drawShapIndex = a1;
|
|
this.startDraw(0, a2);
|
|
},
|
|
|
|
// 追加点位数据
|
|
addDot1(shape) {
|
|
this.testobj = lodash.cloneDeep(this.testobjBackup);
|
|
this.testobj.measureAreaType = shape.type;
|
|
this.testobj.coordinate = shape.getData().data;
|
|
this.presetDataShow = true;
|
|
},
|
|
|
|
// 删除点位数据
|
|
deleteDot1(index) {
|
|
this.presetData.presetParamList.splice(index, 1);
|
|
},
|
|
|
|
// 保存点位数据
|
|
saveDot1() {
|
|
const invalidPhotoCount = this.presetData.presetActionList.some(
|
|
(item) =>
|
|
item.photoCount !== null &&
|
|
item.photoCount !== undefined &&
|
|
String(item.photoCount).trim() !== "" &&
|
|
!/^\d+$/.test(String(item.photoCount).trim())
|
|
);
|
|
const invalidPhotoInterval = this.presetData.presetActionList.some(
|
|
(item) =>
|
|
item.photoSeper !== null &&
|
|
item.photoSeper !== undefined &&
|
|
String(item.photoSeper).trim() !== "" &&
|
|
!/^\d+$/.test(String(item.photoSeper).trim())
|
|
);
|
|
if (invalidPhotoCount || invalidPhotoInterval) {
|
|
this.$message.error("\u62cd\u7167\u6b21\u6570\u548c\u62cd\u7167\u95f4\u9694\u53ea\u80fd\u8f93\u5165\u975e\u8d1f\u6574\u6570");
|
|
return;
|
|
}
|
|
// 确保 presetPosName 有值
|
|
if (!this.presetData.presetPosName) {
|
|
this.presetData.presetPosName = this.presetName || this.presetData.presetPosName || '';
|
|
}
|
|
|
|
// 如果是热成像模式,确保预置点名称正确传递
|
|
if (this.monitorType === 'ir' && !this.presetData.presetPosName) {
|
|
// 从 presetArr 中查找当前选中的预置点
|
|
const selectedPreset = this.presetArr.find(
|
|
item => item.dictValue === this.presetDotNum
|
|
);
|
|
if (selectedPreset) {
|
|
this.presetData.presetPosName = selectedPreset.dictLabel;
|
|
}
|
|
}
|
|
|
|
// 调试日志 - 测试完成后可以删除
|
|
console.log('保存预置点数据:', {
|
|
monitorType: this.monitorType,
|
|
presetPosName: this.presetData.presetPosName,
|
|
presetDotNum: this.presetDotNum,
|
|
presetName: this.presetName,
|
|
});
|
|
|
|
this.loadingBind = true;
|
|
bindingPreset(Object.assign({}, this.presetData))
|
|
.then((res) => {
|
|
this.presetData = {
|
|
presetPosCode: "",
|
|
channelId: "",
|
|
eqpbookId: "",
|
|
patrolpointId: "",
|
|
stdparolPointId: "",
|
|
deviceId: "",
|
|
presetPosName: "",
|
|
stopTime: "",
|
|
channelImg: "",
|
|
description: "",
|
|
presetActionList: [],
|
|
presetParamList: [],
|
|
};
|
|
this.testobj = lodash.cloneDeep(this.testobjBackup);
|
|
this.loadingBind = false;
|
|
this.currentRow.patrolpointId = res.data;
|
|
this.monitorSecShow = false;
|
|
this.monitorShow = false;
|
|
this.$message.success("绑定成功");
|
|
this.loadDevicePoints();
|
|
})
|
|
.catch(() => {
|
|
this.loadingBind = false;
|
|
});
|
|
},
|
|
|
|
// 下一步弹窗确定
|
|
aletrSecConfirm1() {
|
|
const me = this;
|
|
this.$refs.formTemptrue.validate((valid) => {
|
|
if (valid) {
|
|
me.presetData.presetParamList.push(lodash.cloneDeep(me.testobj));
|
|
me.presetDataShow = false;
|
|
}
|
|
});
|
|
},
|
|
|
|
// 下一步弹窗取消
|
|
aletrSecCancel1() {
|
|
this.measureName = "";
|
|
this.measureDistance = "";
|
|
this.radioRate = "";
|
|
this.warnMaxTemp = "";
|
|
this.warnMinTemp = "";
|
|
this.warnAverageTemp = "";
|
|
this.warnDifferenceTemp = "";
|
|
this.alarmMaxTemp = "";
|
|
this.alarmMinTemp = "";
|
|
this.alarmAverageTemp = "";
|
|
this.alarmDifferenceTemp = "";
|
|
this.presetDataShow = false;
|
|
},
|
|
|
|
// 绘板框和录像
|
|
startDraw(index, type) {
|
|
const drawRefs = linq
|
|
.from(this.$refs.playerPlayform2.$children)
|
|
.where((x) => x.$vnode.componentOptions.tag === "DrawShape")
|
|
.toArray();
|
|
const drawRef = drawRefs[index];
|
|
drawRef.show();
|
|
this.$nextTick(() => {
|
|
drawRef.init();
|
|
drawRef.startDraw(type || ShapeEnum.rect);
|
|
});
|
|
},
|
|
|
|
handleDrawComplete(scope, shape) {
|
|
setTimeout(() => {
|
|
this.addDot1(shape);
|
|
}, 100);
|
|
},
|
|
|
|
handleChangeIndex(e) {
|
|
this.currentPlayer = e.player;
|
|
},
|
|
|
|
getDeviceList() {
|
|
getDeviceList(this.patroldeviceCode, this.channelCode).then(
|
|
({ data }) => {
|
|
this.presetArr = data;
|
|
}
|
|
);
|
|
},
|
|
|
|
handleOpenChannel(row, next) {
|
|
this.patroldeviceCode = row.patroldeviceCode;
|
|
this.channelCode = row.channelCode;
|
|
this.presetName = "";
|
|
this.presetNumber = "";
|
|
this.getDeviceList();
|
|
this.$nextTick(() => {
|
|
this.$refs[next ? "playerPlayform2" : "playerPlayform"]
|
|
.openChannel({
|
|
deviceId: 1,
|
|
deviceCode: row.patroldeviceCode,
|
|
channelId: row.channelId,
|
|
channelCode: row.channelCode,
|
|
playerType: "zl",
|
|
})
|
|
.then(() => {});
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
/* 原有样式保持不变 - 树结构相关样式 */
|
|
.vue-treeselect__menu-container .vue-treeselect__menu {
|
|
background: #274a58;
|
|
}
|
|
|
|
.vue-treeselect__option--highlight {
|
|
background: #222f3d;
|
|
}
|
|
|
|
.el-select-dropdown {
|
|
background-color: #274a58;
|
|
}
|
|
|
|
.el-picker-panel,
|
|
.el-select-dropdown,
|
|
.el-select .el-input__inner:focus,
|
|
.el-select .el-input.is-focus .el-input__inner {
|
|
border-color: #40486a;
|
|
}
|
|
|
|
.el-input__inner,
|
|
.el-textarea__inner,
|
|
.el-range-input {
|
|
border-color: #40486a;
|
|
}
|
|
|
|
.el-input.is-disabled .el-input__inner {
|
|
background-color: transparent;
|
|
}
|
|
|
|
.el-input-number--medium .el-input-number__increase,
|
|
.el-input-number--medium .el-input-number__decrease {
|
|
background-color: transparent;
|
|
}
|
|
|
|
.el-popover {
|
|
background-color: #222f3d;
|
|
border-color: #222f3dff;
|
|
}
|
|
|
|
/* 表格样式优化 */
|
|
.custom-table {
|
|
width: 100%;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
margin-top: 10px;
|
|
background: transparent !important;
|
|
}
|
|
|
|
/* 表格拖拽相关样式 */
|
|
.resizable-table .el-table__header th {
|
|
position: relative;
|
|
user-select: none;
|
|
}
|
|
|
|
.resizable-table .column-resizer {
|
|
position: absolute;
|
|
right: 0;
|
|
top: 0;
|
|
width: 16px;
|
|
height: 100%;
|
|
cursor: col-resize;
|
|
z-index: 100;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
}
|
|
|
|
.resizable-table .column-resizer-line {
|
|
width: 3px;
|
|
height: 60%;
|
|
background-color: #1890ff;
|
|
opacity: 0;
|
|
transition: opacity 0.2s;
|
|
border-radius: 2px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.resizable-table .column-resizer:hover .column-resizer-line {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.resizable-table .column-resizer:active .column-resizer-line {
|
|
opacity: 1;
|
|
background-color: #40a9ff;
|
|
}
|
|
|
|
/* 拖拽时的全局遮罩 */
|
|
#resize-mask {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 9999;
|
|
cursor: col-resize;
|
|
background-color: transparent;
|
|
}
|
|
|
|
/* 表格列拖拽时的样式 */
|
|
.resizable-table .el-table__header th.dragging {
|
|
background-color: #012773 !important;
|
|
}
|
|
|
|
.resizable-table .el-table__header th.dragging::after {
|
|
content: "";
|
|
position: absolute;
|
|
right: 0;
|
|
top: 0;
|
|
width: 2px;
|
|
height: 100%;
|
|
background-color: #1890ff;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* 表格内输入框样式 */
|
|
.table-input .el-input__inner {
|
|
background-color: #1e3a4a;
|
|
border-color: #2a4a5a;
|
|
color: #ffffff;
|
|
height: 32px;
|
|
line-height: 32px;
|
|
width: 100%;
|
|
min-width: 80px;
|
|
}
|
|
|
|
.table-input .el-input__inner:focus {
|
|
border-color: #1890ff;
|
|
}
|
|
|
|
/* 表格内选择框样式 */
|
|
.table-select {
|
|
width: 100%;
|
|
min-width: 80px;
|
|
}
|
|
|
|
.table-select .el-input__inner {
|
|
background-color: #1e3a4a;
|
|
border-color: #2a4a5a;
|
|
color: #ffffff;
|
|
height: 32px;
|
|
line-height: 32px;
|
|
width: 100%;
|
|
}
|
|
|
|
.table-select .el-input__inner:focus {
|
|
border-color: #1890ff;
|
|
}
|
|
|
|
.table-select .el-input__suffix {
|
|
color: #ffffff;
|
|
}
|
|
|
|
/* 左侧树区域样式 - 修改为独立布局 */
|
|
.sec-left {
|
|
display: flex;
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.point-layout {
|
|
display: block;
|
|
position: relative;
|
|
padding: 10px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 左侧面板容器 - 独立宽度控制 */
|
|
.resize-container {
|
|
height: 100%;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: width 0.1s ease;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.point-layout > .resize-container {
|
|
height: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 左侧内容区域 */
|
|
.sec-line {
|
|
width: 100%;
|
|
height: 100%;
|
|
top: 0;
|
|
bottom: 0;
|
|
margin-top: 0;
|
|
padding: 0 10px 10px;
|
|
box-sizing: border-box;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: relative;
|
|
padding-right: 14px;
|
|
background: transparent;
|
|
border: 1px solid rgba(63, 127, 216, 0.72);
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.sec-a2 {
|
|
flex: 1;
|
|
min-height: 0;
|
|
position: relative;
|
|
box-sizing: border-box;
|
|
padding-right: 0;
|
|
overflow-y: auto;
|
|
overflow-x: auto;
|
|
background: transparent !important;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: #2f7fe8 rgba(6, 27, 79, 0.7);
|
|
|
|
&::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
&::-webkit-scrollbar-track {
|
|
background: rgba(6, 27, 79, 0.7);
|
|
}
|
|
|
|
&::-webkit-scrollbar-thumb {
|
|
background: #2f7fe8;
|
|
border-radius: 4px;
|
|
border: 1px solid #0d327d;
|
|
}
|
|
|
|
&::-webkit-scrollbar-thumb:hover {
|
|
background: #54a5ff;
|
|
}
|
|
|
|
::v-deep .el-tree {
|
|
display: inline-block;
|
|
width: max-content;
|
|
min-width: 100%;
|
|
background-color: transparent !important;
|
|
color: #e0e0e0;
|
|
}
|
|
|
|
::v-deep .el-tree-node__content {
|
|
width: 100%;
|
|
min-width: 0;
|
|
height: 24px;
|
|
line-height: 24px;
|
|
background-color: transparent !important;
|
|
color: #e0e0e0;
|
|
font-size: 14px;
|
|
|
|
&:hover {
|
|
background: #0c225c !important;
|
|
}
|
|
}
|
|
|
|
::v-deep .el-tree-node.is-current > .el-tree-node__content {
|
|
background: linear-gradient(180deg, #174d99 0%, #0c225c 50%, #174d99 100%) !important;
|
|
}
|
|
|
|
::v-deep .custom-tree-node {
|
|
min-width: 0;
|
|
width: max-content;
|
|
display: flex;
|
|
align-items: center;
|
|
padding-right: 8px;
|
|
}
|
|
|
|
// 叶子节点没有展开小三角,把隐形三角占位收窄一半,
|
|
// 名称略向左靠(约12px),让各行的间距节奏看起来接近一致。
|
|
::v-deep .xg_tree .el-tree-node__expand-icon.is-leaf {
|
|
display: inline-block;
|
|
width: 12px;
|
|
}
|
|
|
|
::v-deep .child-count {
|
|
color: #909399;
|
|
font-size: 14px;
|
|
flex-shrink: 0;
|
|
margin-left: 4px;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
/* 搜索框样式 */
|
|
.search {
|
|
width: 100%;
|
|
position: relative;
|
|
margin-top: 0;
|
|
margin-bottom: 10px;
|
|
|
|
.el-input__inner {
|
|
background-color: #1e3a4a;
|
|
border-color: #2a4a5a;
|
|
color: #ffffff;
|
|
height: 32px;
|
|
padding-right: 45px;
|
|
}
|
|
|
|
.button {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
height: 32px;
|
|
width: 40px;
|
|
padding: 0;
|
|
border-radius: 0 4px 4px 0;
|
|
background-color: #1890ff;
|
|
border-color: #1890ff;
|
|
|
|
&:hover {
|
|
background-color: #40a9ff;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 拖拽分隔条 */
|
|
.resize-handle {
|
|
position: absolute;
|
|
top: 46px;
|
|
right: 0;
|
|
width: 8px;
|
|
bottom: 10px;
|
|
height: auto;
|
|
background-color: transparent;
|
|
// border-right: 1px solid #3988ff;
|
|
border-left: 1px solid rgba(57, 136, 255, 0.45);
|
|
cursor: col-resize;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: background-color 0.2s;
|
|
flex-shrink: 0;
|
|
z-index: 10;
|
|
|
|
&:hover {
|
|
background-color: transparent;
|
|
|
|
.handle-line {
|
|
background-color: #1890ff;
|
|
}
|
|
|
|
.handle-dots span {
|
|
background-color: #1890ff;
|
|
}
|
|
}
|
|
|
|
&.resizing {
|
|
background-color: transparent;
|
|
|
|
.handle-line {
|
|
background-color: #40a9ff;
|
|
width: 4px;
|
|
}
|
|
|
|
.handle-dots span {
|
|
background-color: #40a9ff;
|
|
}
|
|
}
|
|
|
|
/* 垂直指示线 */
|
|
.handle-line {
|
|
width: 2px;
|
|
height: 60px;
|
|
background-color: #3a4a5a;
|
|
border-radius: 2px;
|
|
transition: all 0.2s;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
/* 三点指示器 */
|
|
.handle-dots {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
|
|
span {
|
|
width: 4px;
|
|
height: 4px;
|
|
background-color: #3a4a5a;
|
|
border-radius: 50%;
|
|
transition: background-color 0.2s;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 中间内容区域 - 保持独立布局 */
|
|
.wid {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-width: 0;
|
|
height: 100%;
|
|
z-index: 1;
|
|
box-sizing: border-box;
|
|
border: 1px solid rgba(63, 127, 216, 0.72);
|
|
background: rgba(8, 30, 86, 0.72);
|
|
}
|
|
|
|
.point-layout > .wid {
|
|
right: 10px;
|
|
margin-left: 10px;
|
|
width: auto;
|
|
top: 10px;
|
|
bottom: 10px;
|
|
height: auto;
|
|
min-width: 0;
|
|
}
|
|
|
|
.form {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
padding: 0 10px;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
padding-top: 0 !important;
|
|
}
|
|
|
|
/* Reserve the overlay's footprint so the main table never renders beneath it. */
|
|
.wid.has-right-panel .form {
|
|
width: auto;
|
|
margin-right: clamp(420px, 32%, 520px);
|
|
}
|
|
|
|
.line {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
flex-shrink: 0;
|
|
min-height: 34px;
|
|
padding-top: 3px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 右侧面板样式 - 完全独立不受影响 */
|
|
.right {
|
|
/* Keep the binding table wide enough for its columns when the tree is resized. */
|
|
width: clamp(420px, 32%, 520px);
|
|
min-width: 420px;
|
|
max-width: 52%;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
border: 2px solid #0b374e;
|
|
position: absolute;
|
|
right: 0;
|
|
top: 0;
|
|
height: 100%;
|
|
z-index: 20;
|
|
|
|
.collect {
|
|
position: absolute;
|
|
top: 40%;
|
|
left: 0;
|
|
cursor: pointer;
|
|
z-index: 30;
|
|
transform: none;
|
|
}
|
|
|
|
&::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
&::-webkit-scrollbar-track { background: #071b44; }
|
|
&::-webkit-scrollbar-thumb { background: #3988ff; border-radius: 4px; }
|
|
}
|
|
|
|
/* 添加重置按钮样式 */
|
|
.reset-width-btn {
|
|
display: flex;
|
|
position: absolute;
|
|
bottom: 10px;
|
|
right: 10px;
|
|
width: 24px;
|
|
height: 24px;
|
|
background-color: #1e3a4a;
|
|
border-radius: 4px;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
color: #ffffff;
|
|
z-index: 10;
|
|
transition: all 0.2s;
|
|
|
|
&:hover {
|
|
background-color: #1890ff;
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
i {
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
|
|
/* 确保表格在宽度变化时能正确调整 */
|
|
.el-table {
|
|
width: 100% !important;
|
|
background: transparent !important;
|
|
|
|
::v-deep .el-table__body-wrapper {
|
|
overflow-x: auto !important;
|
|
background: transparent !important;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: #3988ff #071b44;
|
|
}
|
|
|
|
::v-deep .el-table__body-wrapper::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
display: block;
|
|
}
|
|
|
|
::v-deep .el-table__header-wrapper {
|
|
overflow-x: hidden !important;
|
|
}
|
|
}
|
|
|
|
/* Keep the header and body at the same minimum width. The body wrapper then
|
|
* owns the single horizontal scrollbar and Element UI synchronizes header scrollLeft. */
|
|
.custom-table {
|
|
::v-deep .el-table__header,
|
|
::v-deep .el-table__body {
|
|
min-width: 1055px !important;
|
|
}
|
|
|
|
::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
|
|
background: #071b44;
|
|
}
|
|
|
|
::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
|
|
background: #3988ff;
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
|
|
/* 响应式处理 */
|
|
@media screen and (max-width: 1200px) {
|
|
.resize-container {
|
|
max-width: 400px !important;
|
|
}
|
|
|
|
.right {
|
|
width: 35%;
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
.resize-container {
|
|
max-width: 300px !important;
|
|
}
|
|
|
|
.right {
|
|
width: 45%;
|
|
}
|
|
}
|
|
|
|
/* 右侧面板样式 */
|
|
.eq {
|
|
min-width: 400px;
|
|
padding-top: 30px;
|
|
padding-left: 10px;
|
|
box-sizing: border-box;
|
|
background-color: #111452;
|
|
color: #e0e0e0;
|
|
height: 100%;
|
|
}
|
|
|
|
.eq-img {
|
|
display: block;
|
|
margin: 0 auto;
|
|
width: 110px;
|
|
}
|
|
|
|
.eq-a1 {
|
|
text-align: center;
|
|
padding-top: 30px;
|
|
}
|
|
|
|
.eq-a1 .eq-a1-d1 {
|
|
font-size: 16px;
|
|
margin-bottom: 10px;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.eq-a2 {
|
|
text-align: center;
|
|
margin-bottom: 10px;
|
|
|
|
.el-button {
|
|
display: inline-block;
|
|
background-color: #1e3a4a;
|
|
border-color: #2a4a5a;
|
|
color: #e0e0e0;
|
|
|
|
&:hover {
|
|
background-color: #2a4a5a;
|
|
border-color: #3a5a6a;
|
|
color: #ffffff;
|
|
}
|
|
|
|
&:disabled {
|
|
background-color: #1a2a3a;
|
|
border-color: #2a3a4a;
|
|
color: #808080;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 右侧表格样式 */
|
|
.right-table {
|
|
width: 100%;
|
|
min-width: 400px;
|
|
table-layout: fixed;
|
|
overflow: visible;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif !important;
|
|
|
|
::v-deep .el-table__header th {
|
|
background-color: #012773 !important;
|
|
color: #ffffff !important;
|
|
border-bottom: 2px solid #0b374e !important;
|
|
font-weight: 600 !important;
|
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif !important;
|
|
white-space: nowrap !important;
|
|
}
|
|
|
|
::v-deep .el-table__header th .cell {
|
|
white-space: nowrap !important;
|
|
word-break: keep-all;
|
|
}
|
|
|
|
::v-deep .el-table__row td {
|
|
background-color: #E0EAFF !important;
|
|
color: #000000 !important;
|
|
border-bottom: 1px solid #acb5e3 !important;
|
|
font-weight: 400 !important;
|
|
}
|
|
|
|
::v-deep .el-table__row--striped td {
|
|
background-color: #EBF1FF !important;
|
|
}
|
|
|
|
::v-deep .el-table__row td .cell {
|
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif !important;
|
|
font-weight: 400 !important;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* 站名列强制居中(覆盖可能的对齐/宽度冲突样式) */
|
|
::v-deep .el-table th.station-name-col .cell,
|
|
::v-deep .el-table td.station-name-col .cell {
|
|
text-align: center !important;
|
|
}
|
|
|
|
::v-deep .el-table__row td.operation-column .cell,
|
|
::v-deep .el-table__fixed-right td.operation-column .cell {
|
|
overflow: visible;
|
|
text-overflow: clip;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
::v-deep td.operation-column .el-button {
|
|
flex: 0 0 auto;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
::v-deep td.operation-column .cell {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-wrap: nowrap;
|
|
gap: 6px;
|
|
}
|
|
|
|
::v-deep .el-table__fixed-right td.operation-column .cell {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-wrap: nowrap;
|
|
gap: 6px;
|
|
overflow: visible;
|
|
}
|
|
|
|
::v-deep .el-table__row:hover td {
|
|
background-color: #d6e4ff !important;
|
|
}
|
|
|
|
::v-deep .el-button--text {
|
|
color: #1890ff;
|
|
|
|
&:hover {
|
|
color: #40a9ff;
|
|
}
|
|
|
|
&:disabled {
|
|
color: #808080;
|
|
}
|
|
}
|
|
|
|
::v-deep .el-loading-mask {
|
|
background: rgba(34, 47, 61, 0.92) !important;
|
|
}
|
|
|
|
::v-deep .el-loading-spinner .circular {
|
|
stroke: #3988ff !important;
|
|
}
|
|
|
|
::v-deep .el-loading-spinner .el-loading-text {
|
|
color: #43c0ff !important;
|
|
}
|
|
|
|
/* Allow narrow panels to scroll horizontally instead of clipping columns. */
|
|
::v-deep .el-table__body-wrapper {
|
|
overflow-x: auto !important;
|
|
overflow-y: hidden !important;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: #3988ff #071b44;
|
|
}
|
|
|
|
::v-deep .el-table__header-wrapper {
|
|
overflow-x: auto !important;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: #3988ff #071b44;
|
|
}
|
|
|
|
::v-deep .el-table__header-wrapper::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
display: block;
|
|
}
|
|
|
|
::v-deep .el-table__body-wrapper::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
display: block;
|
|
}
|
|
|
|
::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
|
|
background: #071b44;
|
|
}
|
|
|
|
::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
|
|
background: #3988ff;
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
|
|
/* Keep the image preview stage proportional to the viewport. */
|
|
.image-preview-dialog {
|
|
::v-deep .el-dialog__body {
|
|
height: calc(100vh - 180px) !important;
|
|
min-height: 420px;
|
|
padding: 12px 18px;
|
|
box-sizing: border-box;
|
|
overflow: hidden;
|
|
}
|
|
|
|
::v-deep .flex-row {
|
|
height: 100%;
|
|
min-height: 0;
|
|
}
|
|
|
|
.image-preview-stage {
|
|
height: 100%;
|
|
min-height: 420px;
|
|
}
|
|
}
|
|
|
|
/* 右侧选项卡样式 */
|
|
.right-tabs {
|
|
::v-deep .el-tabs__item {
|
|
color: #e0e0e0;
|
|
|
|
&:hover {
|
|
color: #1890ff;
|
|
}
|
|
|
|
&.is-active {
|
|
color: #1890ff;
|
|
}
|
|
}
|
|
|
|
::v-deep .el-tabs__active-bar {
|
|
background-color: #1890ff;
|
|
}
|
|
|
|
::v-deep .el-tabs__nav-wrap::after {
|
|
background-color: #1e3a4a;
|
|
}
|
|
}
|
|
|
|
/* 弹窗样式 */
|
|
.el-dialog__body {
|
|
height: 500px;
|
|
}
|
|
|
|
.el-dialog__body .video-box-warp {
|
|
height: 390px;
|
|
}
|
|
|
|
.alert1_img1 {
|
|
width: 24px;
|
|
height: 24px;
|
|
position: relative;
|
|
top: 6px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.input_slot_a1 {
|
|
line-height: 36px;
|
|
color: #999;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.card-page .el-table td {
|
|
text-align: center !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table,
|
|
.card-page ::v-deep .card-table {
|
|
width: 100% !important;
|
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif !important;
|
|
background: transparent !important;
|
|
color: #000000;
|
|
border-color: transparent !important;
|
|
}
|
|
|
|
.card-page ::v-deep .custom-table.el-table::before,
|
|
.card-page ::v-deep .custom-table.el-table::after,
|
|
.card-page ::v-deep .custom-table.el-table--border::after,
|
|
.card-page ::v-deep .custom-table.el-table--group::after {
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__header-wrapper,
|
|
.card-page ::v-deep .el-table__fixed-header-wrapper {
|
|
background: #012773 !important;
|
|
border: 0 !important;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__body-wrapper,
|
|
.card-page ::v-deep .el-table__fixed,
|
|
.card-page ::v-deep .el-table__fixed-right {
|
|
background: transparent !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table th.el-table__cell {
|
|
background: #012773 !important;
|
|
border-top: 0 !important;
|
|
border-bottom: 0 !important;
|
|
border-left: 0 !important;
|
|
border-right: 1px solid #acb5e3 !important;
|
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif !important;
|
|
font-weight: 700 !important;
|
|
color: #ffffff !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table th.el-table__cell .cell {
|
|
color: #ffffff !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__header-wrapper th.el-table__cell:last-child,
|
|
.card-page ::v-deep .el-table__fixed-header-wrapper th.el-table__cell:last-child {
|
|
border-right: 0 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__resize-proxy {
|
|
border-left: 2px solid #acb5e3 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table td.el-table__cell {
|
|
background: transparent !important;
|
|
border-bottom: 1px solid #c7d7f4 !important;
|
|
border-right-color: #c7d7f4 !important;
|
|
color: #000000 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table td.el-table__cell .cell {
|
|
color: #000000 !important;
|
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif !important;
|
|
font-weight: 400 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__row {
|
|
background: #E0EAFF !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__body tbody tr:nth-child(odd) td.el-table__cell {
|
|
background: #E0EAFF !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__body tbody tr:nth-child(even) td.el-table__cell {
|
|
background: #EBF1FF !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__row--striped td.el-table__cell {
|
|
background: #EBF1FF !important;
|
|
}
|
|
|
|
.card-page ::v-deep .custom-table.el-table,
|
|
.card-page ::v-deep .custom-table .el-table__body-wrapper,
|
|
.card-page ::v-deep .custom-table .el-table__fixed-body-wrapper,
|
|
.card-page ::v-deep .custom-table .el-table__body,
|
|
.card-page ::v-deep .custom-table .el-table__body tbody,
|
|
.card-page ::v-deep .custom-table .el-table__empty-block,
|
|
.card-page ::v-deep .custom-table .el-table__append-wrapper {
|
|
background: transparent !important;
|
|
background-color: transparent !important;
|
|
min-height: 0 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .custom-table > .el-loading-mask {
|
|
background: rgba(34, 47, 61, 0.92) !important;
|
|
background-color: rgba(34, 47, 61, 0.92) !important;
|
|
}
|
|
|
|
.card-page ::v-deep .custom-table > .el-loading-mask .circular {
|
|
stroke: #3988ff !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__empty-text {
|
|
color: #5f7394 !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog {
|
|
height: 88vh;
|
|
max-height: 88vh;
|
|
margin-bottom: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-dialog__body {
|
|
height: calc(88vh - 135px) !important;
|
|
flex: 1 1 auto;
|
|
overflow: auto;
|
|
padding: 24px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog,
|
|
::v-deep .monitor-config-dialog * {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog::-webkit-scrollbar,
|
|
::v-deep .monitor-config-dialog *::-webkit-scrollbar {
|
|
width: 0;
|
|
height: 0;
|
|
display: none;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .horizontal-tabs-container {
|
|
min-height: 650px;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-dialog__footer {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-button {
|
|
border: 1px solid #3988ff !important;
|
|
background: rgba(3, 81, 198, 0.78) !important;
|
|
color: #43c0ff !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-button:hover,
|
|
::v-deep .monitor-config-dialog .el-button:focus {
|
|
border-color: #43c0ff !important;
|
|
background: rgba(57, 136, 255, 0.86) !important;
|
|
color: #ffffff !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-button--text {
|
|
border-color: transparent !important;
|
|
background: transparent !important;
|
|
color: #43c0ff !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-button--text:hover,
|
|
::v-deep .monitor-config-dialog .el-button--text:focus {
|
|
background: rgba(57, 136, 255, 0.14) !important;
|
|
color: #43c0ff !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-dialog .el-button.is-disabled,
|
|
::v-deep .monitor-config-dialog .el-button.is-disabled:hover,
|
|
::v-deep .monitor-config-dialog .el-button.is-disabled:focus {
|
|
border-color: rgba(57, 136, 255, 0.35) !important;
|
|
background: rgba(3, 81, 198, 0.28) !important;
|
|
color: rgba(67, 192, 255, 0.45) !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-popover,
|
|
::v-deep .monitor-config-popover * {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
|
|
::v-deep .monitor-config-popover::-webkit-scrollbar,
|
|
::v-deep .monitor-config-popover *::-webkit-scrollbar {
|
|
width: 0;
|
|
height: 0;
|
|
display: none;
|
|
}
|
|
|
|
::v-deep .monitor-config-popover .el-button {
|
|
border: 1px solid #3988ff !important;
|
|
background: rgba(3, 81, 198, 0.78) !important;
|
|
color: #43c0ff !important;
|
|
}
|
|
|
|
::v-deep .monitor-config-popover .el-button:hover,
|
|
::v-deep .monitor-config-popover .el-button:focus {
|
|
border-color: #43c0ff !important;
|
|
background: rgba(57, 136, 255, 0.86) !important;
|
|
color: #ffffff !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__body tr:hover > td.el-table__cell {
|
|
background: #c5d9f6 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__body tr.current-row > td.el-table__cell {
|
|
background-color: #c5d9f6 !important;
|
|
color: #000000 !important;
|
|
}
|
|
|
|
.card-page ::v-deep .el-table__body tr.current-row > td.el-table__cell .el-button.is-disabled {
|
|
color: #808080;
|
|
}
|
|
|
|
.task-toolbar-btn,
|
|
.card-page ::v-deep .el-table .task-row-btn {
|
|
border: 1px solid transparent !important;
|
|
background:
|
|
linear-gradient(#01016b, #01016b) padding-box,
|
|
linear-gradient(135deg, #3988ff, #0351c6) border-box !important;
|
|
color: #43c0ff !important;
|
|
}
|
|
|
|
.task-toolbar-btn:hover,
|
|
.task-toolbar-btn:focus,
|
|
.card-page ::v-deep .el-table .task-row-btn:hover,
|
|
.card-page ::v-deep .el-table .task-row-btn:focus {
|
|
border: 1px solid transparent !important;
|
|
background:
|
|
linear-gradient(#01016b, #01016b) padding-box,
|
|
linear-gradient(135deg, #3988ff, #0351c6) border-box !important;
|
|
color: #43c0ff !important;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.task-toolbar-btn.is-disabled,
|
|
.task-toolbar-btn.is-disabled:hover,
|
|
.task-toolbar-btn.is-disabled:focus {
|
|
border: 1px solid transparent !important;
|
|
background:
|
|
linear-gradient(#01016b, #01016b) padding-box,
|
|
linear-gradient(135deg, #3988ff, #0351c6) border-box !important;
|
|
color: #43c0ff !important;
|
|
opacity: 0.45;
|
|
}
|
|
|
|
::v-deep .vue-treeselect__control {
|
|
background: #274a58;
|
|
}
|
|
|
|
::v-deep .vue-treeselect__multi-value-item {
|
|
background: #274a58;
|
|
}
|
|
|
|
::v-deep .vue-treeselect__menu-container .vue-treeselect__menu {
|
|
background: #274a58;
|
|
}
|
|
|
|
.xg_image_viewer {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 50px;
|
|
height: 50px;
|
|
}
|
|
|
|
.input_group_position {
|
|
display: flex;
|
|
width: 100%;
|
|
|
|
.input_group_item {
|
|
flex: 1;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
.page-content {
|
|
width: 100%;
|
|
height: 100%;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
::v-deep .el-table__fixed::before {
|
|
height: 0;
|
|
}
|
|
|
|
::v-deep .el-table__fixed-right::before {
|
|
height: 0;
|
|
}
|
|
|
|
::v-deep .el-tabs__item {
|
|
color: #ffffff;
|
|
}
|
|
|
|
::v-deep .el-tabs__item.is-active {
|
|
color: #1890ff;
|
|
}
|
|
|
|
::v-deep .el-input__count {
|
|
background: none;
|
|
}
|
|
|
|
.centered-input ::v-deep.el-input__inner {
|
|
text-align: center;
|
|
}
|
|
|
|
// 修改添加监控点位行的间隔
|
|
.el-form-item {
|
|
margin-bottom: 40px;
|
|
}
|
|
|
|
/* 云台控制样式 */
|
|
.r-ti1 {
|
|
line-height: 30px;
|
|
padding: 0 20px;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.r-box {
|
|
// padding: 10px 5px;
|
|
// padding-bottom: 32px;
|
|
height: calc(100% - 30px); /* 让r-box占满剩余高度 */
|
|
// overflow-y: auto; /* 内容过多时滚动 */
|
|
}
|
|
|
|
.r-ti2 {
|
|
width: 170px;
|
|
position: relative;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.r-ti2 img {
|
|
width: 100%;
|
|
}
|
|
|
|
.r-ti2-pos {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.r-ti2-pos div {
|
|
width: 20px;
|
|
height: 15px;
|
|
position: absolute;
|
|
cursor: pointer;
|
|
z-index: 2;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(1) {
|
|
top: 45px;
|
|
left: 75px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(2) {
|
|
top: 57px;
|
|
left: 99px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(3) {
|
|
top: 79px;
|
|
right: 42px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(4) {
|
|
bottom: 59px;
|
|
left: 99px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(5) {
|
|
bottom: 47px;
|
|
left: 75px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(6) {
|
|
bottom: 59px;
|
|
right: 99px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(7) {
|
|
bottom: 80px;
|
|
left: 42px;
|
|
}
|
|
|
|
.r-ti2-pos div:nth-child(8) {
|
|
top: 57px;
|
|
right: 99px;
|
|
}
|
|
.r-ti2-pos div:nth-child(9) {
|
|
width: 28px;
|
|
height: 28px;
|
|
top: 71px;
|
|
right: 72px;
|
|
}
|
|
|
|
.r-ti3 {
|
|
width: 100%;
|
|
display: flex;
|
|
padding-top: 20px;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.r-ti3 .r-ti3-d1 {
|
|
width: 34;
|
|
position: relative;
|
|
}
|
|
|
|
.r-ti3 .r-ti3-d1 img {
|
|
width: 100%;
|
|
}
|
|
|
|
.r-ti3-d2 {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 97%;
|
|
height: 83%;
|
|
}
|
|
|
|
.r-ti3-d2 div:nth-child(1) {
|
|
width: 50%;
|
|
height: 100%;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.r-ti3-d2 div:nth-child(2) {
|
|
width: 50%;
|
|
height: 100%;
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.r-ti4 {
|
|
padding-top: 5px;
|
|
}
|
|
|
|
.r-ti4 .el-select {
|
|
width: 82%;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.r-ti4 span {
|
|
font-size: 22px;
|
|
margin-left: 3px;
|
|
color: #999;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.right .add-bth1 {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.fr .add-bth1 {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.fl {
|
|
width: 68%;
|
|
}
|
|
|
|
.fr {
|
|
width: 30%;
|
|
margin-left: 2%;
|
|
}
|
|
|
|
.fr-ti1 {
|
|
color: #e0e0e0;
|
|
font-size: 16px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.fr-ti2 {
|
|
color: #999;
|
|
font-size: 14px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.fss {
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
margin-right: 10px;
|
|
color: #e0e0e0;
|
|
|
|
&:hover {
|
|
color: #ff6b6b;
|
|
}
|
|
}
|
|
|
|
.position {
|
|
width: 100%;
|
|
}
|
|
|
|
.position .position-a1 {
|
|
width: 30%;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.position .position-a1:last-child {
|
|
margin-right: 0;
|
|
}
|
|
|
|
.position-ti1 {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.position-a1 {
|
|
font-size: 16px;
|
|
color: #e0e0e0;
|
|
}
|
|
|
|
.position-a1 div {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.position-a1 div span {
|
|
color: #fa3239;
|
|
}
|
|
|
|
.el-form-item__label {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.toollist1-a1 {
|
|
width: 100%;
|
|
height: 40px;
|
|
background: rgb(68, 68, 68);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.toollist1-a1 > div {
|
|
width: 60px;
|
|
height: 40px;
|
|
float: right;
|
|
position: relative;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
background-color: black;
|
|
}
|
|
}
|
|
|
|
.toollist1-a1 img {
|
|
max-width: 16px;
|
|
max-height: 16px;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
margin: auto;
|
|
}
|
|
|
|
/* 新增筛选相关样式 - 保持原有位置 */
|
|
.search-group {
|
|
display: flex;
|
|
gap: 10px;
|
|
align-items: center;
|
|
}
|
|
|
|
.algorithm-filter,
|
|
.device-type-filter {
|
|
width: 200px;
|
|
|
|
::v-deep .el-input__inner {
|
|
background-color: #1e3a4a;
|
|
border-color: #2a4a5a;
|
|
color: #ffffff;
|
|
height: 32px;
|
|
line-height: 32px;
|
|
}
|
|
|
|
::v-deep .el-input__suffix {
|
|
color: #ffffff;
|
|
}
|
|
|
|
::v-deep .el-select-dropdown__item {
|
|
color: #ffffff;
|
|
|
|
&.selected {
|
|
color: #1890ff;
|
|
}
|
|
|
|
&:hover {
|
|
background-color: #1e3a4a;
|
|
}
|
|
}
|
|
}
|
|
|
|
.filter-stats {
|
|
color: #1890ff;
|
|
font-size: 12px;
|
|
margin-bottom: 10px;
|
|
padding-left: 5px;
|
|
|
|
.el-button--text {
|
|
color: #1890ff;
|
|
font-size: 12px;
|
|
margin-left: 10px;
|
|
|
|
&:hover {
|
|
color: #40a9ff;
|
|
}
|
|
}
|
|
}
|
|
.left-buttons {
|
|
display: flex;
|
|
gap: 8px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.right-filters {
|
|
display: flex;
|
|
gap: 10px;
|
|
align-items: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.nowarp.is-disabled {
|
|
color: #000000 !important;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.algorithm-setting-link {
|
|
color: #1890ff;
|
|
}
|
|
</style>
|
|
|
|
<style lang="scss">
|
|
/* The dialog is appended to body, so these sizing rules must be global. */
|
|
.image-preview-dialog {
|
|
height: 90vh;
|
|
margin-top: 5vh !important;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
|
|
.el-dialog__header {
|
|
flex: 0 0 42px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.el-dialog__body {
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
height: auto !important;
|
|
padding: 12px 18px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.image-preview-stage,
|
|
.image-preview-stage > .flex-row {
|
|
width: 100%;
|
|
height: 100%;
|
|
min-height: 0;
|
|
}
|
|
}
|
|
|
|
/* 添加/修改监控点位弹窗(append-to-body):整屏水平垂直居中。
|
|
选择器带 .el-dialog 提高优先级,覆盖全局 ruoyi.scss 的 margin-top:6vh!important
|
|
与 element-ui.scss 的 transform:none/left:0/position:relative */
|
|
.el-dialog.site-point-add-dialog:not(.is-fullscreen) {
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
margin: 0 !important;
|
|
max-height: calc(100vh - 40px);
|
|
overflow: hidden;
|
|
|
|
.el-dialog__body {
|
|
max-height: calc(100vh - 160px);
|
|
overflow-y: auto;
|
|
}
|
|
}
|
|
</style>
|