前置管理 新增重置功能

前置交互日志 新增详情查询功能
This commit is contained in:
guanj
2025-09-03 20:57:28 +08:00
parent 0067b63536
commit f251ad3fe6
20 changed files with 3425 additions and 3062 deletions

BIN
public/favicon2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -16,6 +16,14 @@ export function uploadUserData(data: any) {
data
})
}
//删除用采数据
export function deleteUserDataByIds(data: any) {
return createAxios({
url: '/advance-boot/responsibility/deleteUserDataByIds',
method: 'post',
data
})
}
//负荷数据
export function userDataList(data: any) {
return createAxios({

View File

@@ -34,6 +34,14 @@ export function getTerminalTree() {
method: 'get'
})
}
//请求前置重启进程
export function askRestartProcess(data: any) {
return createAxios({
url: '/device-boot/device/askRestartProcess',
method: 'post',
data
})
}
/**
* 总计出3层提供给表单选择具体的终端、母线、监测点

View File

@@ -1,5 +1,5 @@
<template>
<div :style="{ height: tableStore.table.height }">
<div :style="{ height:props.height?props.height: tableStore.table.height }">
<vxe-table
ref="tableRef"
height="auto"
@@ -80,11 +80,13 @@ const key = ref(0)
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> {
isGroup?: boolean
showOverflow?: boolean
height?: string | boolean
}
const props = withDefaults(defineProps<Props>(), {
isGroup: false,
showOverflow: true
showOverflow: true,
height: false
})
onMounted(() => {
tableStore.table.ref = tableRef.value as VxeTableInstance

View File

@@ -10,9 +10,7 @@
</div>
<span class="nav-bar-title">
{{ getTheme.name }}
<span style="font-size: 14px">
({{ Version||'v1.0.0' }})
</span>
<span style="font-size: 14px">({{ Version || 'v1.0.0' }})</span>
<!-- <span style="font-size: 14px;" v-if="Version?.versionName">
({{ Version?.versionName }})
</span> -->
@@ -28,7 +26,7 @@ import NavMenus from '../navMenus.vue'
import { showShade } from '@/utils/pageShade'
import { getLastData } from '@/api/systerm'
const Version: any = ref('')
const Version: any = ref(null)
const config = useConfig()
const getTheme = JSON.parse(window.localStorage.getItem('getTheme') as string)

View File

@@ -174,7 +174,7 @@ export const adminBaseRoute = {
path: 'aListOfLoadData',
component: () =>
import('@/views/pqs/harmonicMonitoring/detailed/division/components/aListOfLoadData.vue'),
name: '负荷数据列表页面',
name: '用采数据列表页面',
meta: {
title: pageTitle('router.aListOfLoadData')
}
@@ -199,7 +199,7 @@ export const adminBaseRoute = {
},
{
path: 'runManage',
name: '谐波责任划分页面',
name: '二级评估',
meta: {
title: pageTitle('runManage'),
icon: 'ep:management',

View File

@@ -0,0 +1,82 @@
<template>
<!-- 新增 -->
<el-dialog draggable title="详情" v-model="dialogVisible" width="1200px">
<TableHeader datePicker showExport :showReset="false">
<template v-slot:select>
<el-form-item label="筛选数据">
<el-input v-model="tableStore.table.params.searchValue" placeholder="请输入筛选数据" clearable />
</el-form-item>
</template>
</TableHeader>
<div :key="key">
<Table ref="tableRef" :height="'49vh'"></Table>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, onMounted, provide, reactive, nextTick } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { useDictData } from '@/stores/dictData'
import { ElMessage, ElMessageBox } from 'element-plus'
import { mainHeight } from '@/utils/layout'
defineOptions({
name: 'frontLog'
})
const key = ref(0)
const dialogVisible = ref(false)
const tableStore = new TableStore({
url: '/system-boot/frontLog/queryLogCHild',
method: 'POST',
column: [
{
field: 'index',
title: '序号',
width: '80',
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{
title: '发生时间',
field: 'updateTime',
width: '150',
sortable: true
},
{
title: '日志等级',
field: 'grade',
width: '100'
},
{
title: '日志详情',
field: 'log',
formatter: (row: any) => {
return row.cellValue || '/'
}
}
]
})
tableStore.table.params.type = ''
tableStore.table.params.searchValue = ''
provide('tableStore', tableStore)
const open = (row: any) => {
dialogVisible.value = true
tableStore.table.params.mainId = row.id
setTimeout(() => {
tableStore.index()
}, 0)
}
defineExpose({ open })
</script>
<style lang="scss" scoped></style>

View File

@@ -8,6 +8,8 @@
</template>
</TableHeader>
<Table ref="tableRef"></Table>
<!-- 详情 -->
<Detail ref="detailRef"/>
</div>
</template>
<script setup lang="ts">
@@ -17,15 +19,13 @@ import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { useDictData } from '@/stores/dictData'
import Detail from './detail.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
defineOptions({
name: 'frontLog'
})
const pushDisplayRef = ref()
const dictData = useDictData()
const fontdveoption = dictData.getBasicData('Dev_Ops')
const detailRef = ref()
const tableStore = new TableStore({
url: '/system-boot/frontLog/query',
method: 'POST',
@@ -48,33 +48,56 @@ const tableStore = new TableStore({
{
title: '业务名称',
field: 'businessName',
width: '250'
minWidth: '250'
},
{
title: '日志层级',
field: 'level',
width: '100'
minWidth: '100'
},
{
title: '前置业务类型',
field: 'frontType',
width: '120'
minWidth: '120'
},
{
title: '更改时间',
field: 'updateTime',
width: '180',
minWidth: '180',
sortable: true
},
{ title: '日志详情', field: 'log' }
{
title: '日志错误码',
field: 'codeName',
minWidth: '180',
formatter: (row: any) => {
return row.cellValue || '/'
}
},
{
title: '操作',
width: '180',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '详情',
type: 'primary',
icon: 'el-icon-Plus',
render: 'basicButton',
click: row => {
detailRef.value.open(row)
}
}
]
}
],
beforeSearchFun: () => {}
})
const tableRef = ref()
provide('tableRef', tableRef)
tableStore.table.params.type = ''
tableStore.table.params.searchValue = ''
provide('tableStore', tableStore)

View File

@@ -78,6 +78,30 @@
@click="edit(data)"
link
></el-button>
<el-popconfirm
v-else
class="box-item"
title="确定重启吗?"
placement="bottom"
@confirm="restart(data)"
>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button type="warning" size="small" @click="confirm">确认</el-button>
</template>
<template #reference>
<el-button
style="margin-left: 4px"
icon="el-icon-Refresh"
type="warning"
link
@click.stop
></el-button>
<!-- @click.stop="restart(data)" -->
</template>
</el-popconfirm>
</div>
</div>
</template>
@@ -94,7 +118,13 @@
>
<el-form :model="formData" label-width="120px" :rules="rules" ref="ruleFormRef">
<el-form-item label="名称:" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称" maxlength="32" show-word-limit @input="handleInput"></el-input>
<el-input
v-model="formData.name"
placeholder="请输入名称"
maxlength="32"
show-word-limit
@input="handleInput"
></el-input>
</el-form-item>
<el-form-item label="IP:" prop="ip" class="top">
<el-input v-model="formData.ip" placeholder="请输入Ip"></el-input>
@@ -173,7 +203,14 @@
</template>
<script setup lang="ts">
import { ref, onMounted, provide, reactive, nextTick } from 'vue'
import { addNode, delNode, updateNode, nodeDeviceTree, updateDeviceProcess } from '@/api/device-boot/Business'
import {
addNode,
delNode,
updateNode,
nodeDeviceTree,
updateDeviceProcess,
askRestartProcess
} from '@/api/device-boot/Business'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
@@ -295,6 +332,29 @@ const tableStore = new TableStore({
formData.value = JSON.parse(JSON.stringify(row))
}
},
{
name: 'edit',
title: '重启',
type: 'warning',
icon: 'el-icon-Delete',
render: 'confirmButton',
popconfirm: {
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonType: 'warning',
title: '确定重启吗?'
},
click: row => {
askRestartProcess({
deviceRebootType: null,
nodeId: row.id,
processNo: 1
}).then(res => {
ElMessage.success('重启成功')
tableStore.index()
})
}
},
{
name: 'del',
@@ -330,20 +390,23 @@ const tableStore = new TableStore({
currentChangeEvent()
}
})
const nodeId = ref('')
// 点击行
const currentChangeEvent = () => {
// 确保 tableRef 和当前记录存在
if (!tableRef.value || !tableRef.value.getRef().getCurrentRecord()) {
loading.value = false;
dataSource.value = [];
return;
loading.value = false
dataSource.value = []
return
}
loading.value = true
dataSource.value = []
nodeDeviceTree({
nodeId: tableRef.value.getRef().getCurrentRecord().id
}).then(res => {
})
.then(res => {
nodeId.value = tableRef.value.getRef().getCurrentRecord().id
// 检查返回的数据是否存在且不为空
if (res.data && res.data.processDeviceList) {
dataSource.value = res.data.processDeviceList.filter(item => (item.name = item.processNo + ''))
@@ -351,7 +414,8 @@ const currentChangeEvent = () => {
dataSource.value = []
}
loading.value = false
}).catch(() => {
})
.catch(() => {
// 添加错误处理,确保 loading 状态也能关闭
dataSource.value = []
loading.value = false
@@ -359,6 +423,19 @@ const currentChangeEvent = () => {
// const row = tableRef.value.getRef().getCurrentRecord()
}
// 重启进程
const restart = (data: any) => {
console.log('🚀 ~ restart ~ data:', data)
askRestartProcess({
deviceRebootType: data.processNo,
nodeId: nodeId.value,
processNo: 2
}).then(res => {
ElMessage.success('重启成功')
currentChangeEvent()
})
}
const treeRef = ref()
// 树过滤
const change = val => {

View File

@@ -13,7 +13,7 @@
checkStrictly :props="cascaderProps" @change="change" />
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="名称" maxlength="20" show-word-limit @input="handleInput"/>
<el-input v-model="form.name" placeholder="名称" maxlength="40" show-word-limit @input="handleInput"/>
</el-form-item>
<el-form-item label="标准" v-if="title == '新增' && form.pid?.length > 0">

View File

@@ -1,10 +1,9 @@
<!-- 负荷数据列表 -->
<!-- 用采数据列表 -->
<template>
<div class="default-main" :style="height">
<div class="title">
负荷数据列表
用采数据列表
<back-component />
</div>
<TableHeader :showReset="false" ref="TableHeaderRef">
<template #select>
@@ -14,31 +13,32 @@
</template>
<template #operation>
<el-button type="primary" icon="el-icon-Plus" @click="dialogVisible = true">新增</el-button>
</template>
</TableHeader>
<Table ref="tableRef"></Table>
<!-- 详情 -->
<completenessDetails ref="completenessDetailsRef" />
<el-dialog v-model="dialogVisible" title="上传数据" width="500" :before-close="handleClose">
<el-upload ref="upload" action="" v-model:file-list="fileList" accept=".xlsx,.xls" :auto-upload="false"
:on-change="choose" :limit="2">
<el-dialog v-model="dialogVisible" draggable title="上传数据" width="500" :before-close="handleClose">
<el-upload
ref="upload"
action=""
v-model:file-list="fileList"
accept=".xlsx,.xls"
:auto-upload="false"
:on-change="choose"
:limit="2"
>
<el-button type="primary" class="ml10" icon="el-icon-Upload">上传文件</el-button>
</el-upload>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="submitupload">
确认
</el-button>
<el-button type="primary" @click="submitupload" :loading="loading">确认</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang='ts'>
<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { mainHeight } from '@/utils/layout'
import TableStore from '@/utils/tableStore'
@@ -47,8 +47,12 @@ import Table from '@/components/table/index.vue'
import BackComponent from '@/components/icon/back/index.vue'
import completenessDetails from './completenessDetails.vue'
import { genFileId, ElMessage } from 'element-plus'
import { uploadUserData } from '@/api/advance-boot/division'
import type { UploadInstance, UploadProps, UploadRawFile, } from 'element-plus'
import { uploadUserData ,deleteUserDataByIds} from '@/api/advance-boot/division'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
defineOptions({
name: 'division/aListOfLoadData'
})
const loading = ref(false)
const height = mainHeight(20)
const completenessDetailsRef = ref()
const dialogVisible = ref(false)
@@ -64,13 +68,11 @@ const tableStore = new TableStore({
{ title: '截止时间', field: 'endTime' },
{ title: '更新时间', field: 'updateTime' },
{
title: '操作',
width: '180',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '完整性详情',
@@ -94,10 +96,10 @@ const tableStore = new TableStore({
title: '确定删除吗?'
},
click: row => {
// deleteByIds([row.id]).then(() => {
// ElMessage.success('删除成功')
// tableStore.index()
// })
deleteUserDataByIds([row.id]).then(() => {
ElMessage.success('删除成功')
tableStore.index()
})
}
}
]
@@ -119,7 +121,6 @@ const choose = (e: any) => {
ElMessage.warning('请上传Excel文件')
}
}, 0)
}
// 上传
@@ -128,16 +129,20 @@ const submitupload = () => {
ElMessage.warning('请上传文件!')
return
}
ElMessage.info('上传中,请稍等...')
const formData = new FormData()
formData.append('file', fileList.value[0].raw)
uploadUserData(formData).then(res => {
loading.value = true
uploadUserData(formData)
.then(res => {
ElMessage.success('上传成功')
loading.value = false
handleClose()
tableStore.index()
})
.catch(err => {
loading.value = false
})
}
provide('tableStore', tableStore)
tableStore.table.params.searchValue = ''

View File

@@ -1,6 +1,6 @@
<template>
<el-dialog v-model="dialogVisible" title="完整性不足详情" width="1000">
<el-dialog v-model="dialogVisible" draggable title="完整性不足详情" width="1000">
<TableHeader :showReset="false" ref="TableHeaderRef">
<template #select>
<el-form-item label="关键字">

View File

@@ -3,18 +3,21 @@
<div class="default-main" :style="height">
<div class="title">
贡献度计算
<div style="font-size: 14px;font-weight: 500;">
<div style="font-size: 14px; font-weight: 500">
{{ dotList.alias || '' }}
<back-component />
</div>
</div>
<splitpanes :style='heightB' class='default-theme' id='navigation-splitpanes'>
<pane :size='size'>
<PointTree :showSelect="false" :default-expand-all='false' @node-click='handleNodeClick'
@init='handleNodeClick'>
</PointTree>
<splitpanes :style="heightB" class="default-theme" id="navigation-splitpanes">
<pane :size="size">
<PointTree
:showSelect="false"
:default-expand-all="false"
@node-click="handleNodeClick"
@init="handleNodeClick"
></PointTree>
</pane>
<pane style='background: #fff' :style='heightB' :size="100 - size">
<pane style="background: #fff" :style="heightB" :size="100 - size">
<el-form :model="form" inline label-width="auto">
<el-form-item label="谐波类型:">
<el-radio-group v-model="form.type">
@@ -23,21 +26,38 @@
</el-radio-group>
</el-form-item>
<el-form-item label="谐波次数:">
<el-select v-model="form.index" filterable multiple :multiple-limit="5" collapse-tags
collapse-tags-tooltip clearable placeholder="请选择次数">
<el-option v-for="item in harmonic" :key="item.value" :label="item.label"
:value="item.value"> </el-option>
<el-select
v-model="form.index"
filterable
multiple
:multiple-limit="5"
collapse-tags
collapse-tags-tooltip
clearable
placeholder="请选择次数"
>
<el-option
v-for="item in harmonic"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="负荷数据:">
<el-select v-model="form.loadData" clearable filterable placeholder="请选择负荷数据">
<el-option v-for="item in loadDataOptions" :key="item.id" :label="item.name"
:value="item.id"></el-option>
<el-option
v-for="item in loadDataOptions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-Plus"
@click="push('/admin/division/aListOfLoadData')">新增</el-button>
<el-button type="primary" icon="el-icon-Plus" @click="push('/admin/division/aListOfLoadData')">
新增
</el-button>
<el-button type="primary" icon="el-icon-Select" @click="submit">确定</el-button>
</el-form-item>
</el-form>
@@ -45,60 +65,64 @@
<el-tab-pane v-for="(item, index) in tabList" :key="item" :label="item.label" :name="index">
<div class="pd10">
<div>
<span style="color: var(--el-text-color-regular);">时间范围:</span>
<el-date-picker v-model="item.time" class="mr10 ml10" type="daterange"
start-placeholder="起始时间" end-placeholder="结束时间" format="YYYY-MM-DD"
date-format="YYYY-MM-DD" time-format="YYYY-MM-DD" />
<el-button type="primary" icon="el-icon-CaretRight" @click="execute(item,index)">执行</el-button>
<span style="color: var(--el-text-color-regular)">时间范围:</span>
<el-date-picker
v-model="item.time"
class="mr10 ml10"
type="daterange"
start-placeholder="起始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD"
date-format="YYYY-MM-DD"
time-format="YYYY-MM-DD"
:disabled-date="handleDisabledDate"
/>
<el-button type="primary" icon="el-icon-CaretRight" @click="execute(item, index)">
执行
</el-button>
</div>
<div v-if="item.showExecute">
<el-form :inline="true" v-model="item.form" class="mt10">
<el-form-item label="限值:">
<el-input v-model="item.form.limit" placeholder="请输入限值" />
</el-form-item>
<el-form-item label="时间点一:"> <el-input v-model="item.form.time1"
placeholder="请输入时间点一" /></el-form-item>
<el-form-item label="时间点二:"> <el-input v-model="item.form.time2"
placeholder="请输入时间点二" /></el-form-item>
<el-form-item label="时间点一:">
<el-input v-model="item.form.time1" placeholder="请输入时间点一" />
</el-form-item>
<el-form-item label="时间点二:">
<el-input v-model="item.form.time2" placeholder="请输入时间点二" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-Document">
生成动态谐波责任数据
</el-button>
<el-button type="primary" icon="el-icon-Document">
生成谐波责任指标
</el-button>
<el-button type="primary" icon="el-icon-Document">生成谐波责任指标</el-button>
</el-form-item>
</el-form>
</div>
</div>
</el-tab-pane>
</el-tabs>
</pane>
</splitpanes>
</div>
</template>
<script setup lang='ts'>
<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { mainHeight } from '@/utils/layout'
import 'splitpanes/dist/splitpanes.css'
import { Splitpanes, Pane } from 'splitpanes'
import PointTree from '@/components/tree/pqs/pointTree.vue'
import BackComponent from '@/components/icon/back/index.vue'
import { harmonicOptions, } from '@/utils/dictionary'
import { harmonicOptions } from '@/utils/dictionary'
import { userDataList } from '@/api/advance-boot/division'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { formatDate } from '@/utils/formatTime'
import {getHistoryHarmData} from '@/api/advance-boot/division';
import { getHistoryHarmData } from '@/api/advance-boot/division'
defineOptions({
name: 'division/compute'
})
const { push } = useRouter()
const dotList: any = ref({})
const height = mainHeight(20)
@@ -119,6 +143,19 @@ const handleNodeClick = (data: any, node: any) => {
dotList.value = data
}
}
// 设置时间
// 处理日期禁用逻辑
const handleDisabledDate = date => {
// 定义时间边界
const startLimit = new Date(tabList.value[0].time[0]).getTime()
const endLimit = new Date(tabList.value[0].time[1]).setHours(23, 59, 59, 999)
// 如果日期不存在(选择今天时可能出现),不禁用
if (!date) return false
// 禁用 2025-08-01 之前和 2025-08-31 之后的日期
return date.getTime() < startLimit || date.getTime() > endLimit
}
// 确定
const submit = () => {
if (form.loadData == '') {
@@ -148,7 +185,6 @@ const submit = () => {
// tabList.value =
activeName.value = 0
}
}
// 执行
const execute = (item: any, index: number) => {
@@ -159,9 +195,7 @@ const execute = (item: any, index: number) => {
time: item.key,
// userDataId:form.loadData,
lineId: dotList.value.id
}).then((res: any) => {
})
}).then((res: any) => {})
tabList.value[index].showExecute = true
}
@@ -173,7 +207,7 @@ onMounted(() => {
userDataList({
pageNum: 1,
pageSize: 10000,
searchValue: ""
searchValue: ''
}).then((res: any) => {
loadDataOptions.value = res.data.records
})

View File

@@ -11,7 +11,7 @@
<el-button type="primary" icon="el-icon-CreditCard"
@click="push('/admin/division/compute')">谐波贡献度计算</el-button>
<el-button type="primary" icon="el-icon-Tickets"
@click="push('/admin/division/aListOfLoadData')">负荷数据列表</el-button>
@click="push('/admin/division/aListOfLoadData')">用采数据列表</el-button>
</template>
</TableHeader>
<Table ref="tableRef"></Table>
@@ -29,7 +29,7 @@ import { deleteByIds } from '@/api/advance-boot/division'
import { useRouter } from 'vue-router'
const { push } = useRouter()
defineOptions({
name: 'liabiiyty'
name: 'harmonic-boot/detailedAnalysis/responsibility'
})
const TableHeaderRef = ref()

View File

@@ -3,8 +3,12 @@
<DatePicker ref="datePickerRef" theCurrentTime style="display: none" />
<!-- 搜索框 -->
<div class="query-box-wrap">
<el-input v-model.trim="inputQuery" style="height: 46px; width: 334px" @keyup.enter="DeviceQ"
placeholder="请输入终端名称">
<el-input
v-model.trim="inputQuery"
style="height: 46px; width: 334px"
@keyup.enter="DeviceQ"
placeholder="请输入终端名称"
>
<template #prefix>
<div class="Icon"></div>
</template>
@@ -26,9 +30,12 @@
<span class="ml10" style="color: #0d867f">{{ item.count }}</span>
</template>
<div class="collapseBox">
<div class="group-list__item"
<div
class="group-list__item"
:style="colorKey == k.coordinate ? 'background-color: #009ea81a;' : ''"
v-for="k in item.psrList" @click="flyTo(k)">
v-for="k in item.psrList"
@click="flyTo(k)"
>
<p>{{ k.psrName }}</p>
<p>{{ k.vlevelName }}|{{ k.maintOrgName }}</p>
</div>
@@ -36,112 +43,167 @@
</el-collapse-item>
</el-collapse>
<div v-if="QueryList.length > 0 && !showCollapse" class="collapse_none" style="color: #009ea8"
@click="showCollapse = true">
<div
v-if="QueryList.length > 0 && !showCollapse"
class="collapse_none"
style="color: #009ea8"
@click="showCollapse = true"
>
展开搜索结果
</div>
<div class="collapse_none" style="color: red; cursor: pointer" @click="showWrap = false">关闭</div>
</div>
<baidu-map class="map" :style="height" @ready="initMap" @zoomend='syncCenterAndZoom' :center="center"
:zoom="zoomMap" :scroll-wheel-zoom='true' >
<baidu-map
class="map"
:style="height"
@ready="initMap"
@zoomend="syncCenterAndZoom"
:center="center"
:zoom="zoomMap"
:scroll-wheel-zoom="true"
>
<!-- 线-->
<div v-if='zoom > 13'>
<bm-polyline :path='path' v-for='(path, index) in polyline' :key='index'></bm-polyline>
<div v-if="zoom > 13">
<bm-polyline :path="path" v-for="(path, index) in polyline" :key="index"></bm-polyline>
</div>
<!-- 变电站-->
<template v-if='zoom > 13'>
<bm-marker :position='path' v-for='path in siteList' :key='path.subId' :icon='path.icon'
@click='markerClick(path)'></bm-marker>
<template v-if="zoom > 13">
<bm-marker
:position="path"
v-for="path in siteList"
:key="path.subId"
:icon="path.icon"
@click="markerClick(path)"
></bm-marker>
</template>
<!-- -->
<div :maxZoom='12' v-if='zoom > 9'>
<bm-marker :position='path' v-for='path in areaLineInfo' :key='path.lineId' :icon='path.icon'
@click='markerClick(path)' :zIndex="1">
<bm-label v-if='zoom > 14' :content="path.lineName"
:labelStyle="{ color: '#fff', border: '0px solid #fff', backgroundColor: 'rgba(0, 0, 0, 0.5)', borderRadius: '10px', padding: '2px 5px', fontSize: '12px', lineHeight: '15px', transform: 'translateX(-30%)' }"
:offset="{ height: 33 }" />
<div :maxZoom="12" v-if="zoom > 9">
<bm-marker
:position="path"
v-for="path in areaLineInfo"
:key="path.lineId"
:icon="path.icon"
@click="markerClick(path)"
:zIndex="1"
>
<bm-label
v-if="zoom > 14"
:content="path.lineName"
:labelStyle="{
color: '#fff',
border: '0px solid #fff',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
borderRadius: '10px',
padding: '2px 5px',
fontSize: '12px',
lineHeight: '15px',
transform: 'translateX(-30%)'
}"
:offset="{ height: 33 }"
/>
</bm-marker>
</div>
<!-- 详情 -->
<bm-marker :position='infoWindowPoint' :icon="{ url: '1', size: { width: 0, height: 0 } }">
<bm-info-window :show='infoWindowPoint.show' @close='infoWindowPoint.show = false'>
<el-descriptions :title='infoWindowPoint.lineName' :column='1' v-if='infoWindowPoint.lineId'>
<el-descriptions-item label='供电公司'>{{ infoWindowPoint.gdName }}</el-descriptions-item>
<el-descriptions-item label='变电站'>{{ infoWindowPoint.subName }}</el-descriptions-item>
<el-descriptions-item label='母线'>{{ infoWindowPoint.voltageName }}</el-descriptions-item>
<el-descriptions-item label='网络参数'>
<bm-marker :position="infoWindowPoint" :icon="{ url: '1', size: { width: 0, height: 0 } }">
<bm-info-window :show="infoWindowPoint.show" @close="infoWindowPoint.show = false">
<el-descriptions :title="infoWindowPoint.lineName" :column="1" v-if="infoWindowPoint.lineId">
<el-descriptions-item label="供电公司">{{ infoWindowPoint.gdName }}</el-descriptions-item>
<el-descriptions-item label="变电站(场站)">{{ infoWindowPoint.subName }}</el-descriptions-item>
<el-descriptions-item label="母线">{{ infoWindowPoint.voltageName }}</el-descriptions-item>
<el-descriptions-item label="网络参数">
{{ infoWindowPoint.ip }}
</el-descriptions-item>
<el-descriptions-item label='PT变化'>{{ infoWindowPoint.pt2 }}</el-descriptions-item>
<el-descriptions-item label='CT变化'>{{ infoWindowPoint.ct2 }}</el-descriptions-item>
<el-descriptions-item label='生产厂家'>
<el-descriptions-item label="PT变化">{{ infoWindowPoint.pt2 }}</el-descriptions-item>
<el-descriptions-item label="CT变化">{{ infoWindowPoint.ct2 }}</el-descriptions-item>
<el-descriptions-item label="生产厂家">
{{ infoWindowPoint.manufacturer }}
</el-descriptions-item>
<el-descriptions-item label='终端状态'>
{{
infoWindowPoint.runFlag == 0 ? '投运' : infoWindowPoint.runFlag == 1 ? '热备用' : '停运'
}}
<el-descriptions-item label="终端状态">
{{ infoWindowPoint.runFlag == 0 ? '投运' : infoWindowPoint.runFlag == 1 ? '检修' : '停运' }}
</el-descriptions-item>
<el-descriptions-item label='通讯状态'>
<el-descriptions-item label="通讯状态">
{{ infoWindowPoint.comFlag == 0 ? '中断' : '正常' }}
</el-descriptions-item>
<el-descriptions-item>
<el-button type='primary' size='small' @click='lookPoint(infoWindowPoint)'>查看详情</el-button>
<el-button type="primary" size="small" @click="lookPoint(infoWindowPoint)">
查看详情
</el-button>
</el-descriptions-item>
</el-descriptions>
<el-descriptions :title='infoWindowPoint.subName' :column='1' v-else-if='infoWindowPoint.subId'
style='padding-top: 10px'></el-descriptions>
<el-descriptions
:title="infoWindowPoint.subName"
:column="1"
v-else-if="infoWindowPoint.subId"
style="padding-top: 10px"
></el-descriptions>
</bm-info-window>
</bm-marker>
<!-- 行政区划 -->
<div v-if='zoom <= 11'>
<div v-if="zoom <= 11">
<div v-for="item in AreaData">
<bm-polygon v-for="timeK in item.boundary" :path="timeK" :strokeWeight="2" strokeColor="#fff"
:strokeOpacity="1" :fillColor="item.background || ''" :fillOpacity="0.5"></bm-polygon>
<bm-polygon
v-for="timeK in item.boundary"
:path="timeK"
:strokeWeight="2"
strokeColor="#0e8780"
:strokeOpacity="1"
:fillColor="item.background || ''"
:fillOpacity="0.5"
></bm-polygon>
</div>
</div>
<!-- 信息弹框 -->
<div v-if='zoom <= 9'>
<bm-overlay v-for="item in AreaData" pane="labelPane" :class="{ sample: true, }"
@draw="draw($event, item.LngLat)">
<div v-if="zoom <= 9">
<bm-overlay
v-for="item in AreaData"
pane="labelPane"
:class="{ sample: true }"
@draw="draw($event, item.LngLat)"
>
<div class="my-radiusPop" :style="{ background: item.background }">
<img :src="PopKey == 2 ? imgUrl2 : PopKey == 1 ? imgUrl1 : PopKey == 0 ? imgUrl0 : ''" />
<div class="infoBox">
<div>
总数<br />{{ PopKey == 2 ? item.lineNum : PopKey == 1 ? item.deviceNum : PopKey == 0 ?
item.subNum :
'/' }}
总数
<br />
{{
PopKey == 2
? item.lineNum
: PopKey == 1
? item.deviceNum
: PopKey == 0
? item.subNum
: '/'
}}
</div>
<div>
{{ PopKey == 2 ? '在线' : PopKey == 1 ? '在运' : '告警' }}<br />{{ PopKey == 2 ?
item.onlineNum :
PopKey
== 1
?
item.alarmSubNum : PopKey == 0 ?
item.onDevice : '/' }}
{{ PopKey == 2 ? '在线' : PopKey == 1 ? '在运' : '告警' }}
<br />
{{
PopKey == 2
? item.onlineNum
: PopKey == 1
? item.alarmSubNum
: PopKey == 0
? item.onDevice
: '/'
}}
</div>
<div v-if="PopKey == 2">
告警<br />{{ PopKey == 2 ? item.alarm : PopKey == 1 ? item.xx : PopKey == 0 ? item.xx :
'/' }}
告警
<br />
{{ PopKey == 2 ? item.alarm : PopKey == 1 ? item.xx : PopKey == 0 ? item.xx : '/' }}
</div>
</div>
</div>
</bm-overlay>
</div>
</baidu-map>
</div>
</template>
<script setup lang='ts'>
<script setup lang="ts">
import { mainHeight } from '@/utils/layout'
import { getAreaLineInfo } from '@/api/event-boot/areaInfo'
import { ref, reactive, onMounted } from 'vue'
@@ -152,7 +214,7 @@ import { BaiduMap, BmOverlay } from 'vue-baidu-map-3x'
import { getAssessOverview } from '@/api/device-boot/panorama'
import { getGridDiagramAreaData } from '@/api/device-boot/panorama'
const emit = defineEmits(['changeValue', 'drop', 'show'])
import mapJson from './boundary';
import mapJson from './boundary'
const datePickerRef = ref()
const height = mainHeight(20)
// 页面中直接引入就可以
@@ -161,7 +223,7 @@ const inputQuery: any = ref('')
const QueryList: any = ref([])
const activeName: any = ref(0)
const zoomMap = ref(8.8)
const zoomMap = ref(8.9)
const colorKey = ref('')
const showCollapse: any = ref(true)
const showWrap: any = ref(false)
@@ -173,30 +235,100 @@ const imgUrl0 = new URL('@/assets/img/BDZ-ZS.png', import.meta.url).href
const imgUrl1 = new URL('@/assets/img/ZD-ZS.png', import.meta.url).href
const imgUrl2 = new URL('@/assets/img/JCD-ZS.png', import.meta.url).href
const boundaryList: any = ref([
// {
// orgName: '唐山',
// LngLat: [118.335849137, 39.7513593355],
// boundary: mapJson.tsJSON
// },
// {
// orgName: '张家口',
// LngLat: [115.032504679, 40.8951549951],
// boundary: mapJson.zjkJSON
// },
// {
// orgName: '秦皇岛',
// LngLat: [119.185113833, 40.1179119754],
// boundary: mapJson.qhdJSON
// },
// {
// orgName: '承德',
// LngLat: [117.548498365, 41.3775890632],
// boundary: mapJson.cdJSON
// },
// {
// orgName: '廊坊',
// LngLat: [116.628004129, 39.0589378611],
// boundary: mapJson.lfJSON
// }
{
orgName: '唐山',
LngLat: [118.335849137, 39.7513593355],
boundary: mapJson.tsJSON
orgName: '大连',
LngLat: [122.060077, 39.635794],
boundary: mapJson['大连']
},
{
orgName: '张家口',
LngLat: [115.032504679, 40.8951549951],
boundary: mapJson.zjkJSON
orgName: '抚顺',
LngLat: [124.354599, 41.88962],
boundary: mapJson['抚顺']
},
{
orgName: '秦皇岛',
LngLat: [119.185113833, 40.1179119754],
boundary: mapJson.qhdJSON
orgName: '沈阳',
LngLat: [123.0389, 41.992993],
boundary: mapJson['沈阳']
},
{
orgName: '承德',
LngLat: [117.548498365, 41.3775890632],
boundary: mapJson.cdJSON
orgName: '丹东',
LngLat: [124.585661, 40.645967],
boundary: mapJson['丹东']
},
{
orgName: '廊坊',
LngLat: [116.628004129, 39.0589378611],
boundary: mapJson.lfJSON
orgName: '营口',
LngLat: [122.225226, 40.433551],
boundary: mapJson['营口']
},
{
orgName: '盘锦',
LngLat: [121.875362, 41.075416],
boundary: mapJson['盘锦']
},
{
orgName: '铁岭',
LngLat: [124.229492, 42.731873],
boundary: mapJson['铁岭']
},
{
orgName: '朝阳',
LngLat: [119.640944, 41.39657],
boundary: mapJson['朝阳']
},
{
orgName: '葫芦岛',
LngLat: [119.850873, 40.728517],
boundary: mapJson['葫芦岛']
},
{
orgName: '锦州',
LngLat: [121.42, 41.58],
boundary: mapJson['锦州']
},
{
orgName: '阜新',
LngLat: [121.658585, 42.350951],
boundary: mapJson['阜新']
},
{
orgName: '本溪',
LngLat: [124.390785, 41.197021],
boundary: mapJson['本溪']
},
{
orgName: '辽阳',
LngLat: [123.090785, 41.297021],
boundary: mapJson['辽阳']
},
{
orgName: '鞍山',
LngLat: [122.808845, 40.840049],
boundary: mapJson['鞍山']
}
])
@@ -206,7 +338,8 @@ const siteList = ref<any>([])
const polyline = ref<any>([])
const lineId = ref('')
const center = ref({
lng: 116.84428600000001, lat: 40.57707185292256
lng: 122.42588,
lat: 40.810977
})
const infoWindowPoint = ref<anyObj>({
lng: 0,
@@ -214,11 +347,9 @@ const infoWindowPoint = ref<anyObj>({
show: false
})
// 地图实例
const initMap = async ({ BMap, map }: any) => {
}
const initMap = async ({ BMap, map }: any) => {}
// 加载点
const addMarkers = async (row?: any, key?: any, num?: any) => {
let params = {
deptIndex: deptIndex.value,
monitorFlag: 2,
@@ -309,15 +440,12 @@ const addMarkers = async (row?: any, key?: any, num?: any) => {
siteList.value = list
// center.value.lng = areaLineInfo.value[0].lng
// center.value.lat = areaLineInfo.value[0].lat
}
// 获取zoom
const syncCenterAndZoom = (e: any) => {
zoom.value = e.target.getZoom()
}
const locatePositions = (e: any) => {
deptIndex.value = e.data.id
// 加载点
addMarkers()
@@ -338,20 +466,18 @@ const markerClick = (e: any) => {
const lookPoint = (e: any) => {
emit('drop', e.lineId)
emit('show', true)
}
// 搜索
const DeviceQ = () => {
showCollapse.value = true
if (inputQuery.value.length == 0) return
let list = []
let regex = new RegExp(inputQuery.value, 'i')
let data = areaLineInfo.value.filter((item: any) => regex.test(item.lineName))
let data = areaLineInfo.value
.filter((item: any) => regex.test(item.lineName))
.map((item: any) => {
return {
psrName: item.lineName,
vlevelName: item.voltageScale,
maintOrgName: item.gdName,
@@ -360,7 +486,6 @@ const DeviceQ = () => {
})
// data.replace(//s/g,',')
if (data.length > 0) {
list.push({
count: data.length,
@@ -374,21 +499,18 @@ const DeviceQ = () => {
// 定位
const flyTo = (e: any, zoom?: number) => {
let regex = new RegExp(e.psrName, 'i')
center.value.lng = e.coordinate[0]
center.value.lat = e.coordinate[1]
if (zoom) { zoomMap.value = zoom }
else {
if (zoom) {
zoomMap.value = zoom
} else {
zoomMap.value = 15
let data = areaLineInfo.value.filter((item: any) => regex.test(item.lineName))[0]
if (data) {
markerClick(data)
}
}
}
// 市级统计数据
const grids = (row: any) => {
@@ -416,15 +538,14 @@ const grids = (row: any) => {
})
}
const radiusPop = (k: any) => {
console.log("🚀 ~ radiusPop ~ k:", k)
console.log('🚀 ~ radiusPop ~ k:', k)
if (k != undefined) PopKey.value = k
}
const GridDiagramArea = () => {
boundaryList.value.forEach((item: any) => {
assessList.value &&
assessList.value.forEach((y: any) => {
if (item.orgName == y.name) {
if (y.score == 3.14159) {
} else if (y.score > 4.5) {
item.background = '#33996699'
@@ -453,7 +574,7 @@ const GridDiagramArea = () => {
}, 0)
}
// 市级统计
const draw = ({ el, BMap, map }, val) => {
const draw = ({ el, BMap, map }, val = [0, 0]) => {
const pixel = map.pointToOverlayPixel(new BMap.Point(val[0], val[1]))
el.style.left = pixel.x - 60 + 'px'
el.style.top = pixel.y - 20 + 'px'
@@ -463,8 +584,7 @@ const reset = () => {
inputQuery.value = ''
showWrap.value = false
}
onMounted(() => {
})
onMounted(() => {})
defineExpose({ addMarkers, locatePositions, reset, grids, radiusPop, flyTo })
</script>
<style lang="scss" scoped>
@@ -472,7 +592,6 @@ defineExpose({ addMarkers, locatePositions, reset, grids, radiusPop, flyTo })
.map {
width: 100%;
}
.query-box-wrap {
@@ -514,7 +633,8 @@ defineExpose({ addMarkers, locatePositions, reset, grids, radiusPop, flyTo })
}
}
}
}
:deep(.el-descriptions__cell) {
white-space: nowrap;
}
</style>
./cds.js./boundary

View File

@@ -40,7 +40,7 @@
<!-- v-if="hackReset" -->
<baidu-map
class="bm-view"
v-if="hackReset"
:zoom="zoom"
:map-click="false"
:scroll-wheel-zoom="true"
@@ -278,7 +278,7 @@ onMounted(() => {
if (siteList.value.length == 0) {
setTimeout(() => {
hackReset.value = false
}, 500)
}, 100)
setTimeout(() => {
hackReset.value = true
}, 1000)

View File

@@ -54,7 +54,7 @@
<!-- v-if="hackReset" -->
<baidu-map
class="bm-view"
v-if="hackReset"
:zoom="zoom"
:map-click="false"
:scroll-wheel-zoom="true"
@@ -331,7 +331,7 @@ onMounted(() => {
if (window.localStorage.getItem('BMAP_SECKEY') == null) {
hackReset.value = false
}
}, 500)
}, 100)
setTimeout(() => {
hackReset.value = true
}, 1000)

View File

@@ -1,5 +1,5 @@
<template>
<el-dialog draggable class="cn-operate-dialog" v-model="dialogVisible" title="修改密码">
<el-dialog draggable width="500px" v-model="dialogVisible" title="修改密码">
<el-scrollbar>
<el-form :inline="false" :model="form" label-width="120px" :rules="rules" ref="formRef">
<el-form-item label="新密码" prop="newPwd">

View File

@@ -43,7 +43,13 @@ const tableStore: any = new TableStore({
{ field: 'updateBy', title: '操作用户' },
{ field: 'createTime', title: '创建时间' },
{ field: 'updateTime', title: '更新时间' },
{ field: 'activation', title: '状态' },
{
field: 'activation',
title: '状态',
formatter(row) {
return row.cellValue == 1 ? '激活' : '未激活'
}
},
{
title: '操作',
width: '220',