联调补招日志功能

This commit is contained in:
guanj
2025-08-26 09:45:01 +08:00
parent d6c494bd96
commit e277fd01a3
10 changed files with 5431 additions and 5416 deletions

View File

@@ -1,23 +1,25 @@
<template> <template>
<el-config-provider :locale="zhCn"> <el-config-provider :locale="zhCn">
<router-view></router-view> <router-view></router-view>
</el-config-provider> </el-config-provider>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import zhCn from 'element-plus/dist/locale/zh-cn.mjs' import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import useSetTheme from '@/utils/setTheme' import useSetTheme from '@/utils/setTheme'
import { onMounted } from 'vue' import { onMounted } from 'vue'
useSetTheme() useSetTheme()
onMounted(async () => { onMounted(async () => {
const response = await fetch('/') const response = await fetch('/')
const WebSocketUrl:any = response.headers.get('X-WebSocket-Url') const WebSocketUrl:any = response.headers.get('X-WebSocket-Url')
const MqttUrl:any = response.headers.get('X-MqttUrl-Url') const WebSocketUrl2:any = response.headers.get('X-WebSocket-Url2')
localStorage.setItem('WebSocketUrl', WebSocketUrl) const MqttUrl:any = response.headers.get('X-MqttUrl-Url')
localStorage.setItem('MqttUrl', MqttUrl) localStorage.setItem('WebSocketUrl2', WebSocketUrl2)
}) localStorage.setItem('WebSocketUrl', WebSocketUrl)
</script> localStorage.setItem('MqttUrl', MqttUrl)
})
<style lang="scss"> </script>
/* Your SCSS styles here */
</style> <style lang="scss">
/* Your SCSS styles here */
</style>

View File

@@ -1,200 +1,205 @@
import { ElMessage, EVENT_CODE } from 'element-plus' import { ElMessage, EVENT_CODE } from 'element-plus'
// 定义消息类型,用于类型检查 // 定义消息类型,用于类型检查
type MessageType = { type MessageType = {
[key: string]: any [key: string]: any
} }
export default class SocketService { export default class SocketService {
// 单例模式实例 // 单例模式实例
private static instance: SocketService | null = null private static instance: SocketService | null = null
// 和服务端连接的socket对象 // 和服务端连接的socket对象
private ws: WebSocket | null = null private ws: WebSocket | null = null
// 存储回调函数 // 存储回调函数
private callBackMapping: { [key: string]: ((message: MessageType) => void) | null } = {} private callBackMapping: { [key: string]: ((message: MessageType) => void) | null } = {}
// 标识是否连接成功 // 标识是否连接成功
private connected: boolean = false private connected: boolean = false
// 记录重试的次数 // 记录重试的次数
private sendRetryCount: number = 0 private sendRetryCount: number = 0
// 重新连接尝试的次数 // 重新连接尝试的次数
private connectRetryCount: number = 0 private connectRetryCount: number = 0
// Web Worker 实例 // Web Worker 实例
private work: Worker | null = null private work: Worker | null = null
// 临时的 Blob URL // 临时的 Blob URL
private workerBlobUrl: string | null = null private workerBlobUrl: string | null = null
// 上次活动时间戳 // 上次活动时间戳
private lastActivityTime: number = 0 private lastActivityTime: number = 0
// 最后一次收到心跳回复时间 // 最后一次收到心跳回复时间
private lastResponseHeartTime: number = Date.now() private lastResponseHeartTime: number = Date.now()
// 重新连接延迟,单位毫秒 // 重新连接延迟,单位毫秒
private reconnectDelay: number = 5000 private reconnectDelay: number = 5000
// 单例模式获取实例 // 单例模式获取实例
public static get Instance(): SocketService { public static get Instance(): SocketService {
if (!this.instance) { if (!this.instance) {
this.instance = new SocketService() this.instance = new SocketService()
} }
return this.instance return this.instance
} }
// 定义连接服务器的方法 // 定义连接服务器的方法
public async connect(id: string) { public async connect(url: string) {
if (!window.WebSocket) { if (!window.WebSocket) {
console.log('您的浏览器不支持WebSocket') console.log('您的浏览器不支持WebSocket')
return return
} }
setTimeout(() => { setTimeout(() => {
// ws://192.168.1.69:10407/mgtt/api/pushMessage/ // ws://192.168.1.69:10407/mgtt
const url = (localStorage.getItem('WebSocketUrl') || 'ws://192.168.1.68:10407/api/pushMessage/') + id // const url =
this.ws = new WebSocket(url) // (localStorage.getItem('WebSocketUrl') == 'null'
// ? 'ws://192.168.1.130:10405'
this.ws.onopen = () => this.handleOpen() // : localStorage.getItem('WebSocketUrl')) + id
this.ws.onclose = () => this.handleClose() this.ws = new WebSocket(url)
this.ws.onerror = () => this.handleError()
this.ws.onmessage = event => this.handleMessage(event) this.ws.onopen = () => this.handleOpen()
}, 0) this.ws.onclose = () => this.handleClose()
} this.ws.onerror = () => this.handleError()
this.ws.onmessage = event => this.handleMessage(event)
// 处理连接成功事件 }, 0)
private handleOpen(): void { }
ElMessage.success('webSocket连接服务端成功了')
console.log('连接服务端成功了') // 处理连接成功事件
this.connected = true private handleOpen(): void {
this.connectRetryCount = 0 ElMessage.success('webSocket连接服务端成功了')
this.updateLastActivityTime() console.log('连接服务端成功了')
this.startHeartbeat() this.connected = true
} this.connectRetryCount = 0
this.updateLastActivityTime()
// 处理连接关闭事件 this.startHeartbeat()
private handleClose(): void { }
console.log('连接webSocket服务端关闭')
this.connected = false // 处理连接关闭事件
this.connectRetryCount++ private handleClose(): void {
this.clearHeartbeat() console.log('连接webSocket服务端关闭')
// 可根据需要添加重连逻辑 this.connected = false
// setTimeout(() => this.connect(), 500 * this.connectRetryCount); this.connectRetryCount++
} this.clearHeartbeat()
// 可根据需要添加重连逻辑
// 处理连接错误事件 // setTimeout(() => this.connect(), 500 * this.connectRetryCount);
private handleError(): void { }
ElMessage.error('webSocket连接异常')
} // 处理连接错误事件
private handleError(): void {
// 处理服务端发送过来的数据 ElMessage.error('webSocket连接异常')
private handleMessage(event: MessageEvent): void { }
// console.log('🚀 ~ SocketService ~ handleMessage ~ event.data:', event.data)
// 处理服务端发送过来的数据
if (event.data == '连接成功') { private handleMessage(event: MessageEvent): void {
this.sendHeartbeat() // console.log('🚀 ~ SocketService ~ handleMessage ~ event.data:', event.data)
} else if (event.data.length > 10) {
let message: MessageType if (event.data == '连接成功') {
try { this.sendHeartbeat()
// console.log('Received message:', event.data) } else if (event.data == 'connect') {
message = JSON.parse(event.data) } else if (event.data.length > 10) {
} catch (e) { let message: MessageType
console.error('消息解析失败', event.data, e) try {
return // console.log('Received message:', event.data)
} message = JSON.parse(event.data)
// console.log("🚀 ~ SocketService ~ handleMessage ~ message:", message) } catch (e) {
console.error('消息解析失败', event.data, e)
// 通过接受服务端发送的type字段来回调函数 return
if (message.key && this.callBackMapping['message']) { }
this.callBackMapping['message']!(message) // console.log("🚀 ~ SocketService ~ handleMessage ~ message:", message)
} else {
console.log('抛弃====>') // 通过接受服务端发送的type字段来回调函数
// console.log(event.data)
// 丢弃或继续写你的逻辑 if ((message.key || message.code) && this.callBackMapping['message']) {
} this.callBackMapping['message']!(message)
} else { } else {
ElMessage.error(event.data) console.log('抛弃====>')
} // console.log(event.data)
} // 丢弃或继续写你的逻辑
}
// 启动心跳检测 } else {
private startHeartbeat(): void { ElMessage.error(event.data)
this.lastResponseHeartTime = Date.now() }
const url = window.URL.createObjectURL( }
new Blob(['(function(e){setInterval(function(){this.postMessage(null)},30000)})()'])
) // 启动心跳检测
this.workerBlobUrl = url private startHeartbeat(): void {
this.work = new Worker(url) this.lastResponseHeartTime = Date.now()
this.work.onmessage = e => this.handleWorkerMessage(e) const url = window.URL.createObjectURL(
} new Blob(['(function(e){setInterval(function(){this.postMessage(null)},30000)})()'])
)
// 处理 Web Worker 消息 this.workerBlobUrl = url
private handleWorkerMessage(e: MessageEvent): void { this.work = new Worker(url)
// if (this.lastActivityTime - this.lastResponseHeartTime > 30000) { this.work.onmessage = e => this.handleWorkerMessage(e)
// // 说明已经三轮心跳没收到回复了,关闭检测,提示用户。 }
// // ElMessage.error('业务主体模块发生未知异常,请尝试重新启动!')
// this.clearHeartbeat() // 处理 Web Worker 消息
// return private handleWorkerMessage(e: MessageEvent): void {
// } // if (this.lastActivityTime - this.lastResponseHeartTime > 30000) {
// console.log(123); // // 说明已经三轮心跳没收到回复了,关闭检测,提示用户。
// // ElMessage.error('业务主体模块发生未知异常,请尝试重新启动!')
this.sendHeartbeat() // this.clearHeartbeat()
} // return
// }
// 发送心跳消息 // console.log(123);
private sendHeartbeat(): void {
// console.log(new Date() + '进入心跳消息发送。。。。。。。。。。。。。') this.sendHeartbeat()
if (this.ws) { }
this.ws.send('alive')
this.updateLastActivityTime() // 发送心跳消息
} private sendHeartbeat(): void {
} // console.log(new Date() + '进入心跳消息发送。。。。。。。。。。。。。')
if (this.ws) {
// 更新活动时间 this.ws.send('alive')
private updateLastActivityTime(): void { this.updateLastActivityTime()
this.lastActivityTime = Date.now() }
} }
// 清除心跳检测 // 更新活动时间
private clearHeartbeat(): void { private updateLastActivityTime(): void {
if (this.work) { this.lastActivityTime = Date.now()
this.work.terminate() }
this.work = null
} // 清除心跳检测
if (this.workerBlobUrl) { private clearHeartbeat(): void {
window.URL.revokeObjectURL(this.workerBlobUrl) if (this.work) {
this.workerBlobUrl = null this.work.terminate()
} this.work = null
} }
if (this.workerBlobUrl) {
// 回调函数的注册 window.URL.revokeObjectURL(this.workerBlobUrl)
public registerCallBack(socketType: string, callBack: (message: MessageType) => void): void { this.workerBlobUrl = null
this.callBackMapping[socketType] = callBack }
} }
// 取消某一个回调函数 // 回调函数的注册
public unRegisterCallBack(socketType: string): void { public registerCallBack(socketType: string, callBack: (message: MessageType) => void): void {
this.callBackMapping[socketType] = null this.callBackMapping[socketType] = callBack
} }
// 发送数据的方法 // 取消某一个回调函数
public send(data: any): void { public unRegisterCallBack(socketType: string): void {
if (this.connected) { this.callBackMapping[socketType] = null
this.sendRetryCount = 0 }
try {
if (this.ws) { // 发送数据的方法
this.ws.send(JSON.stringify(data)) public send(data: any): void {
} if (this.connected) {
} catch (e) { this.sendRetryCount = 0
if (this.ws) { try {
this.ws.send(data) if (this.ws) {
} this.ws.send(JSON.stringify(data))
} }
} else { } catch (e) {
this.sendRetryCount++ if (this.ws) {
setTimeout(() => this.send(data), this.sendRetryCount * 500) this.ws.send(data)
} }
} }
} else {
// 断开方法 this.sendRetryCount++
public closeWs(): void { setTimeout(() => this.send(data), this.sendRetryCount * 500)
if (this.connected && this.ws) { }
this.ws.close() }
}
console.log('执行WS关闭命令..') // 断开方法
} public closeWs(): void {
} if (this.connected && this.ws) {
this.ws.close()
}
console.log('执行WS关闭命令..')
}
}

View File

@@ -1,346 +1,346 @@
<template> <template>
<el-dialog v-model="Views" draggable title="评估策略配置" width="1000" :before-close="handleClose"> <el-dialog v-model="Views" draggable title="评估策略配置" width="1000" :before-close="handleClose">
<div style="display: flex; justify-content: end"> <div style="display: flex; justify-content: end">
<el-button icon="el-icon-Refresh" type="primary" @click="restores">一键还原</el-button> <el-button icon="el-icon-Refresh" type="primary" @click="restores">一键还原</el-button>
</div> </div>
<el-divider content-position="left">光伏电站评估策略配置</el-divider> <el-divider content-position="left">光伏电站评估策略配置</el-divider>
<vxe-table v-bind="defaultAttribute" :loading="loading" :data="photovoltaicData" :span-method="mergeRowMethod"> <vxe-table v-bind="defaultAttribute" :loading="loading" :data="photovoltaicData" :span-method="mergeRowMethod">
<vxe-colgroup field="group0" title="等级"> <vxe-colgroup field="group0" title="等级">
<vxe-column field="name" width="180" title="结果"></vxe-column> <vxe-column field="name" width="180" title="结果"></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-column field="comparisonOperators1" title="安全(个)"> <vxe-column field="comparisonOperators1" title="安全(个)">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators1, row.row.count1, 0)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators1, row.row.count1, 0)">
{{ symbolJudgment(row.row.comparisonOperators1) {{ symbolJudgment(row.row.comparisonOperators1)
}}{{ row.row.comparisonOperators1 == '/' ? '' : row.row.count1 }} }}{{ row.row.comparisonOperators1 == '/' ? '' : row.row.count1 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="comparisonOperators2" title="III级预警(个)"> <vxe-column field="comparisonOperators2" title="III级预警(个)">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators2, row.row.count2, 0)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators2, row.row.count2, 0)">
{{ symbolJudgment(row.row.comparisonOperators2) {{ symbolJudgment(row.row.comparisonOperators2)
}}{{ row.row.comparisonOperators2 == '/' ? '' : row.row.count2 }} }}{{ row.row.comparisonOperators2 == '/' ? '' : row.row.count2 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="comparisonOperators3" title="II级预警(个)"> <vxe-column field="comparisonOperators3" title="II级预警(个)">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators3, row.row.count3, 0)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators3, row.row.count3, 0)">
{{ symbolJudgment(row.row.comparisonOperators3) {{ symbolJudgment(row.row.comparisonOperators3)
}}{{ row.row.comparisonOperators3 == '/' ? '' : row.row.count3 }} }}{{ row.row.comparisonOperators3 == '/' ? '' : row.row.count3 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="comparisonOperators4" title="I级预警(个)"> <vxe-column field="comparisonOperators4" title="I级预警(个)">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators4, row.row.count4, 0)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators4, row.row.count4, 0)">
{{ symbolJudgment(row.row.comparisonOperators4) {{ symbolJudgment(row.row.comparisonOperators4)
}}{{ row.row.comparisonOperators4 == '/' ? '' : row.row.count4 }} }}{{ row.row.comparisonOperators4 == '/' ? '' : row.row.count4 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
<el-divider content-position="left">充电站电加热负荷电气化铁路评估策略配置</el-divider> <el-divider content-position="left">充电站电加热负荷电气化铁路评估策略配置</el-divider>
<vxe-table v-bind="defaultAttribute" ref="xTable" :loading="loading" :data="tableData"> <vxe-table v-bind="defaultAttribute" ref="xTable" :loading="loading" :data="tableData">
<vxe-colgroup field="group0" title="等级"> <vxe-colgroup field="group0" title="等级">
<vxe-column field="name" width="180" title="结果"></vxe-column> <vxe-column field="name" width="180" title="结果"></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-column field="comparisonOperators1" title="THD(%)"> <vxe-column field="comparisonOperators1" title="THD(%)">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators1, row.row.count1, 1)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators1, row.row.count1, 1)">
{{ symbolJudgment(row.row.comparisonOperators1) {{ symbolJudgment(row.row.comparisonOperators1)
}}{{ row.row.comparisonOperators1 == '/' ? '' : row.row.count1 }} }}{{ row.row.comparisonOperators1 == '/' ? '' : row.row.count1 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="comparisonOperators2" title="2~25次谐波合格个数"> <vxe-column field="comparisonOperators2" title="2~25次谐波合格个数">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators2, row.row.count2, 2)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators2, row.row.count2, 2)">
{{ symbolJudgment(row.row.comparisonOperators2) {{ symbolJudgment(row.row.comparisonOperators2)
}}{{ row.row.comparisonOperators2 == '/' ? '' : row.row.count2 }} }}{{ row.row.comparisonOperators2 == '/' ? '' : row.row.count2 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="comparisonOperators3" title="次谐波合格个数"> <vxe-column field="comparisonOperators3" title="次谐波合格个数">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators3, row.row.count3, 3)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators3, row.row.count3, 3)">
{{ symbolJudgment(row.row.comparisonOperators3) {{ symbolJudgment(row.row.comparisonOperators3)
}}{{ row.row.comparisonOperators3 == '/' ? '' : row.row.count3 }} }}{{ row.row.comparisonOperators3 == '/' ? '' : row.row.count3 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="comparisonOperators4" title="偶次谐波合格个数"> <vxe-column field="comparisonOperators4" title="偶次谐波合格个数">
<template #default="row"> <template #default="row">
<div class="cellBox" @click="cells(row, row.row.comparisonOperators4, row.row.count4, 4)"> <div class="cellBox" @click="cells(row, row.row.comparisonOperators4, row.row.count4, 4)">
{{ symbolJudgment(row.row.comparisonOperators4) {{ symbolJudgment(row.row.comparisonOperators4)
}}{{ row.row.comparisonOperators4 == '/' ? '' : row.row.count4 }} }}{{ row.row.comparisonOperators4 == '/' ? '' : row.row.count4 }}
</div> </div>
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
<!-- 修改 --> <!-- 修改 -->
<el-dialog class="dialogBox" draggable v-model="dialogVisible" title="安全等级配置" width="500"> <el-dialog class="dialogBox" draggable v-model="dialogVisible" title="安全等级配置" width="500">
<el-form :model="form" label-width="auto"> <el-form :model="form" label-width="auto">
<el-form-item label="运算符号:"> <el-form-item label="运算符号:">
<el-radio-group v-model="form.comparisonOperators" @change="groupChang"> <el-radio-group v-model="form.comparisonOperators" @change="groupChang">
<el-radio v-for="item in sign" :label="item.name">{{ item.name }}</el-radio> <el-radio v-for="item in sign" :label="item.name">{{ item.name }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="数量:"> <el-form-item label="数量:">
<el-input-number <el-input-number
v-model="form.count" v-model="form.count"
:disabled="disabled" :disabled="disabled"
:min="0" :min="0"
:precision="0" :precision="0"
:max="10000000" :max="10000000"
style="width: 200px" style="width: 200px"
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button> <el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="add">确定</el-button> <el-button type="primary" @click="add">确定</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
</el-dialog> </el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, provide, reactive } from 'vue' import { ref, onMounted, provide, reactive } from 'vue'
import { defaultAttribute } from '@/components/table/defaultAttribute' import { defaultAttribute } from '@/components/table/defaultAttribute'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { queyDetail, addCarryc, restore, queyDetailDhl, adddhl } from '@/api/advance-boot/bearingCapacity' import { queyDetail, addCarryc, restore, queyDetailDhl, adddhl } from '@/api/advance-boot/bearingCapacity'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { VxeTablePropTypes } from 'vxe-table' import { VxeTablePropTypes } from 'vxe-table'
defineOptions({ defineOptions({
name: 'Advancedanalysis/eventcorrelation' name: 'Advancedanalysis/eventcorrelation'
}) })
const emit = defineEmits(['View']) const emit = defineEmits(['View'])
const Views = ref(true) const Views = ref(true)
const xTable = ref() const xTable = ref()
const loading = ref(false) const loading = ref(false)
const photovoltaicData: any = ref([]) const photovoltaicData: any = ref([])
const sum = ref(0) const sum = ref(0)
const tableData: any = ref([]) const tableData: any = ref([])
const list: any = ref({}) const list: any = ref({})
const form: any = ref({ const form: any = ref({
comparisonOperators: '', comparisonOperators: '',
count: '' count: ''
}) })
const sign = ref([ const sign = ref([
{ {
name: '>' name: '>'
}, },
{ {
name: '<' name: '<'
}, },
{ {
name: '>=' name: '>='
}, },
{ {
name: '<=' name: '<='
}, },
{ {
name: '==' name: '=='
}, },
{ {
name: '/' name: '/'
} }
]) ])
const dialogVisible = ref(false) const dialogVisible = ref(false)
const disabled = ref(false) const disabled = ref(false)
const info = () => { const info = () => {
// 光伏 // 光伏
queyDetail().then(res => { queyDetail().then(res => {
photovoltaicData.value = [] photovoltaicData.value = []
let title = ['安全', 'III级预警', 'II级预警', 'I级预警'] let title = ['安全', 'III级预警', 'II级预警', 'I级预警']
let p = 0 let p = 0
res.data.forEach((item: any, i: any) => { res.data.forEach((item: any, i: any) => {
item.capacityStrategysingleVOList.forEach((item1: any, i1: any) => { item.capacityStrategysingleVOList.forEach((item1: any, i1: any) => {
photovoltaicData.value.push({ photovoltaicData.value.push({
name: title[i], name: title[i],
id: item1.id, id: item1.id,
result: item.result result: item.result
}) })
p++ p++
item1.carryCapacityStrategyIndexVOList.forEach((item2: any) => { item1.carryCapacityStrategyIndexVOList.forEach((item2: any) => {
photovoltaicData.value[p - 1]['comparisonOperators' + item2.indexResult] = item2.comparisonOperators photovoltaicData.value[p - 1]['comparisonOperators' + item2.indexResult] = item2.comparisonOperators
photovoltaicData.value[p - 1]['count' + item2.indexResult] = item2.count photovoltaicData.value[p - 1]['count' + item2.indexResult] = item2.count
}) })
}) })
}) })
console.log('🚀 ~ queyDetail ~ photovoltaicData.value:', photovoltaicData.value) console.log('🚀 ~ queyDetail ~ photovoltaicData.value:', photovoltaicData.value)
}) })
// 电弧炉 // 电弧炉
queyDetailDhl().then(res => { queyDetailDhl().then(res => {
tableData.value = res.data tableData.value = res.data
tableData.value[0].name = '电弧炉' tableData.value[0].name = '电弧炉'
tableData.value[1].name = '充电桩' tableData.value[1].name = '充电桩'
tableData.value[2].name = '电气化铁路' tableData.value[2].name = '电气化铁路'
}) })
} }
// <span @click="cells(row,comparisonOperators2,count2)"> // <span @click="cells(row,comparisonOperators2,count2)">
const cells = (row: any, comparisonOperators: any, count: any, num: number) => { const cells = (row: any, comparisonOperators: any, count: any, num: number) => {
form.value = { form.value = {
comparisonOperators: comparisonOperators, comparisonOperators: comparisonOperators,
count: count, count: count,
result: row.row.result, result: row.row.result,
id: row.row.id, id: row.row.id,
indexResult: row.columnIndex indexResult: row.columnIndex
} }
sum.value = num sum.value = num
if (num != 0) { if (num != 0) {
list.value = JSON.parse(JSON.stringify(row.row)) list.value = JSON.parse(JSON.stringify(row.row))
} }
groupChang(comparisonOperators) groupChang(comparisonOperators)
dialogVisible.value = true dialogVisible.value = true
} }
// 运算符变化 // 运算符变化
const groupChang = e => { const groupChang = e => {
if (e == '/') { if (e == '/') {
form.value.count = 0 form.value.count = 0
disabled.value = true disabled.value = true
} else { } else {
disabled.value = false disabled.value = false
} }
} }
// 安全等级配置确认 // 安全等级配置确认
const add = () => { const add = () => {
if (sum.value == 0) { if (sum.value == 0) {
addCarryc(form.value).then(res => { addCarryc(form.value).then(res => {
ElMessage.success('修改成功!') ElMessage.success('修改成功!')
dialogVisible.value = false dialogVisible.value = false
info() info()
}) })
} else { } else {
// sum.value = num // sum.value = num
// list.value = row // list.value = row
list.value['comparisonOperators' + sum.value] = form.value.comparisonOperators list.value['comparisonOperators' + sum.value] = form.value.comparisonOperators
list.value['count' + sum.value] = form.value.count list.value['count' + sum.value] = form.value.count
list.value.userFlag = 0 list.value.userFlag = 0
list.value.protoFlag = 0 list.value.protoFlag = 0
adddhl(list.value).then(res => { adddhl(list.value).then(res => {
ElMessage.success('修改成功!') ElMessage.success('修改成功!')
dialogVisible.value = false dialogVisible.value = false
info() info()
}) })
} }
} }
// 还原 // 还原
const restores = () => { const restores = () => {
restore().then(res => { restore().then(res => {
ElMessage.success('还原成功!') ElMessage.success('还原成功!')
info() info()
}) })
} }
// 通用行合并函数(将相同多列数据合并为一行) // 通用行合并函数(将相同多列数据合并为一行)
const mergeRowMethod = ({ row, _rowIndex, column, visibleData }) => { const mergeRowMethod = ({ row, _rowIndex, column, visibleData }) => {
const fields = ['name'] const fields = ['name']
const cellValue = row[column.field] const cellValue = row[column.field]
if (cellValue && fields.includes(column.field)) { if (cellValue && fields.includes(column.field)) {
const prevRow = visibleData[_rowIndex - 1] const prevRow = visibleData[_rowIndex - 1]
let nextRow = visibleData[_rowIndex + 1] let nextRow = visibleData[_rowIndex + 1]
if (prevRow && prevRow[column.field] === cellValue) { if (prevRow && prevRow[column.field] === cellValue) {
return { rowspan: 0, colspan: 0 } return { rowspan: 0, colspan: 0 }
} else { } else {
let countRowspan = 1 let countRowspan = 1
while (nextRow && nextRow[column.field] === cellValue) { while (nextRow && nextRow[column.field] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex] nextRow = visibleData[++countRowspan + _rowIndex]
} }
if (countRowspan > 1) { if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 } return { rowspan: countRowspan, colspan: 1 }
} }
} }
} }
} }
const symbolJudgment = (value: string) => { const symbolJudgment = (value: string) => {
if (value == '==') { if (value == '==') {
return '=' return '='
} else { } else {
return value return value
} }
} }
onMounted(() => { onMounted(() => {
info() info()
}) })
// 取消 // 取消
const handleClose = () => { const handleClose = () => {
emit('View') emit('View')
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.vxe-table--header thead tr:first-of-type th:first-of-type) { :deep(.vxe-table--header thead tr:first-of-type th:first-of-type) {
// background: var(--vxe-table-header-background-color); // background: var(--vxe-table-header-background-color);
background-image: linear-gradient(var(--vxe-table-border-color), var(--vxe-table-border-color)), background-image: linear-gradient(var(--vxe-table-border-color), var(--vxe-table-border-color)),
linear-gradient(#e8eaec00, #e8eaec00); linear-gradient(#e8eaec00, #e8eaec00);
} }
:deep(.vxe-table--header thead tr:first-of-type th:first-of-type:before) { :deep(.vxe-table--header thead tr:first-of-type th:first-of-type:before) {
content: ''; content: '';
position: absolute; position: absolute;
width: 1px; width: 1px;
height: 98px; /*这里需要自己调整根据td的宽度和高度*/ height: 98px; /*这里需要自己调整根据td的宽度和高度*/
top: 0; top: 0;
left: 0; left: 0;
background-color: grey; background-color: grey;
opacity: 0.3; opacity: 0.3;
display: block; display: block;
transform: rotate(-66deg); /*这里需要自己调整,根据线的位置*/ transform: rotate(-66deg); /*这里需要自己调整,根据线的位置*/
transform-origin: top; transform-origin: top;
} }
:deep(.vxe-table--header thead tr:last-of-type th:first-of-type:before) { :deep(.vxe-table--header thead tr:last-of-type th:first-of-type:before) {
content: ''; content: '';
position: absolute; position: absolute;
width: 1px; width: 1px;
height: 98px; /*这里需要自己调整根据td的宽度和高度*/ height: 98px; /*这里需要自己调整根据td的宽度和高度*/
bottom: 0; bottom: 0;
right: 0; right: 0;
background-color: grey; background-color: grey;
opacity: 0.3; opacity: 0.3;
display: block; display: block;
transform: rotate(-66deg); /*这里需要自己调整,根据线的位置*/ transform: rotate(-66deg); /*这里需要自己调整,根据线的位置*/
transform-origin: bottom; transform-origin: bottom;
} }
.cellBox { .cellBox {
cursor: pointer; cursor: pointer;
color: var(--el-color-primary); color: var(--el-color-primary);
font-weight: 600; font-weight: 600;
text-decoration: underline; text-decoration: underline;
} }
</style> </style>
<style lang="scss"> <style lang="scss">
.el-dialog__body { .el-dialog__body {
max-height: none !important; max-height: none !important;
} }
.dialogBox { .dialogBox {
margin-top: calc(15vh + 200px) !important; margin-top: calc(15vh + 200px) !important;
} }
/* 确保对话框在页面居中 */ /* 确保对话框在页面居中 */
// .el-dialog { // .el-dialog {
// display: flex; // display: flex;
// flex-direction: column; // flex-direction: column;
// margin: 0 !important; // margin: 0 !important;
// position: absolute; // position: absolute;
// top: 50%; // top: 50%;
// left: 50%; // left: 50%;
// transform: translate(-50%, -50%); // transform: translate(-50%, -50%);
// max-height: calc(100% - 30px); // max-height: calc(100% - 30px);
// max-width: calc(100% - 30px); // max-width: calc(100% - 30px);
// } // }
// /* 确保遮罩层全屏显示 */ // /* 确保遮罩层全屏显示 */
// .el-dialog__wrapper { // .el-dialog__wrapper {
// display: flex; // display: flex;
// align-items: center; // align-items: center;
// justify-content: center; // justify-content: center;
// } // }
</style> </style>

View File

@@ -1,211 +1,211 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<div v-show="addedShow"> <div v-show="addedShow">
<TableHeader datePicker showExport ref="TableHeaderRef"> <TableHeader datePicker showExport ref="TableHeaderRef">
<template #select> <template #select>
<el-form-item label="评估类型"> <el-form-item label="评估类型">
<el-select <el-select
v-model="tableStore.table.params.evaluateType" v-model="tableStore.table.params.evaluateType"
clearable clearable
placeholder="请选择评估类型" placeholder="请选择评估类型"
> >
<el-option v-for="item in uesrList" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in uesrList" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</template> </template>
<template #operation> <template #operation>
<el-button icon="el-icon-Setting" type="primary" @click="configuration">评估策略配置</el-button> <el-button icon="el-icon-Setting" type="primary" @click="configuration">评估策略配置</el-button>
<el-button icon="el-icon-Plus" type="primary" @click="addAssess">新增评估</el-button> <el-button icon="el-icon-Plus" type="primary" @click="addAssess">新增评估</el-button>
</template> </template>
</TableHeader> </TableHeader>
<Table ref="tableRef" /> <Table ref="tableRef" />
<policy v-if="policyView" @View="policyView = false" /> <policy v-if="policyView" @View="policyView = false" />
</div> </div>
<!-- <Added v-if="!addedShow" @quit="addedShow = true" /> --> <!-- <Added v-if="!addedShow" @quit="addedShow = true" /> -->
<div v-if="!addedShow" style="position: relative"> <div v-if="!addedShow" style="position: relative">
<el-tabs v-model="activeName" type="border-card" :style="{ height: height }"> <el-tabs v-model="activeName" type="border-card" :style="{ height: height }">
<el-tab-pane label="光伏电站承载能力评估" name="1" v-if="code == null || code == 1"> <el-tab-pane label="光伏电站承载能力评估" name="1" v-if="code == null || code == 1">
<photovoltaic :rowList="rowList" /> <photovoltaic :rowList="rowList" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane <el-tab-pane
label="充电站、电加热负荷、电气化铁路承载能力评估" label="充电站、电加热负荷、电气化铁路承载能力评估"
name="2" name="2"
v-if="code == null || code == 2" v-if="code == null || code == 2"
> >
<charge :rowList="rowList" /> <charge :rowList="rowList" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-button class="quit" icon="el-icon-Back" @click="quit">返回</el-button> <el-button class="quit" icon="el-icon-Back" @click="quit">返回</el-button>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, provide, reactive } from 'vue' import { ref, onMounted, provide, reactive } from 'vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import Area from '@/components/form/area/index.vue' import Area from '@/components/form/area/index.vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import policy from './components/policy.vue' import policy from './components/policy.vue'
import photovoltaic from './components/photovoltaic.vue' import photovoltaic from './components/photovoltaic.vue'
import charge from './components/charge.vue' import charge from './components/charge.vue'
import { remove } from '@/api/advance-boot/bearingCapacity' import { remove } from '@/api/advance-boot/bearingCapacity'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
defineOptions({ defineOptions({
name: 'estimate/evaluationList' name: 'estimate/evaluationList'
}) })
const height = mainHeight(20).height const height = mainHeight(20).height
const dictData = useDictData() const dictData = useDictData()
const levelList = dictData.getBasicData('Dev_Voltage_Stand') const levelList = dictData.getBasicData('Dev_Voltage_Stand')
const uesrList = dictData.getBasicData('CARRY_CAPCITY_USER_TYPE') const uesrList = dictData.getBasicData('CARRY_CAPCITY_USER_TYPE')
const activeName = ref('1') const activeName = ref('1')
const policyView = ref(false) const policyView = ref(false)
const addedShow = ref(true) const addedShow = ref(true)
const code = ref(null) const code = ref(null)
const rowList = ref({}) const rowList = ref({})
const TableHeaderRef = ref() const TableHeaderRef = ref()
const tableStore: any = new TableStore({ const tableStore: any = new TableStore({
url: '/advance-boot/result/queryResultList', url: '/advance-boot/result/queryResultList',
method: 'POST', method: 'POST',
column: [ column: [
{ {
title: '序号', title: '序号',
width: '80', width: '80',
formatter: (row: any) => { formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ field: 'userName', title: '用户名称' }, { field: 'userName', title: '用户名称' },
{ {
field: 'evaluateType', field: 'evaluateType',
title: '评估类型', title: '评估类型',
formatter: (row: any) => { formatter: (row: any) => {
return uesrList.filter(item => item.id == row.cellValue)[0].name return uesrList.filter(item => item.id == row.cellValue)[0].name
} }
}, },
{ {
field: 'lineName', field: 'lineName',
title: '配变台区', title: '配变台区',
width: '500', width: '500',
formatter: (row: any) => { formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/' return row.cellValue ? row.cellValue : '/'
} }
}, },
{ {
field: 'reslutLevel', field: 'reslutLevel',
title: '评估结果', title: '评估结果',
type: 'html', type: 'html',
formatter: (row: any) => { formatter: (row: any) => {
// 1-安全2-III级预警3-II级预警4-I 级预警,5-禁止接入 // 1-安全2-III级预警3-II级预警4-I 级预警,5-禁止接入
return `<span style="color: ${ return `<span style="color: ${
row.cellValue == 1 row.cellValue == 1
? '#2E7D32' // 深绿色 - 安全 ? '#2E7D32' // 深绿色 - 安全
: row.cellValue == 2 : row.cellValue == 2
? '#0288D1' // 深蓝色 - III级预警 ? '#0288D1' // 深蓝色 - III级预警
: row.cellValue == 3 : row.cellValue == 3
? '#F57C00' // 橙色 - II级预警 ? '#F57C00' // 橙色 - II级预警
: row.cellValue == 4 : row.cellValue == 4
? '#E64A19' // 深橙色 - I级预警 ? '#E64A19' // 深橙色 - I级预警
: row.cellValue == 5 : row.cellValue == 5
? '#C62828' // 深红色 - 禁止接入 ? '#C62828' // 深红色 - 禁止接入
: row.cellValue == 6 : row.cellValue == 6
? '#00897B' // 深青色 - 允许接入 ? '#00897B' // 深青色 - 允许接入
: '' : ''
}">${ }">${
row.cellValue == 1 row.cellValue == 1
? '安全' ? '安全'
: row.cellValue == 2 : row.cellValue == 2
? 'III级预警' ? 'III级预警'
: row.cellValue == 3 : row.cellValue == 3
? 'II级预警' ? 'II级预警'
: row.cellValue == 4 : row.cellValue == 4
? 'I 级预警' ? 'I 级预警'
: row.cellValue == 5 : row.cellValue == 5
? '禁止接入' ? '禁止接入'
: row.cellValue == 6 : row.cellValue == 6
? '允许接入' ? '允许接入'
: '' : ''
}</span>` }</span>`
} }
}, },
{ field: 'evaluateDate', title: '评估日期' }, { field: 'evaluateDate', title: '评估日期' },
{ {
title: '操作', title: '操作',
width: '180', width: '180',
render: 'buttons', render: 'buttons',
buttons: [ buttons: [
{ {
name: 'edit', name: 'edit',
title: '查看', title: '查看',
type: 'primary', type: 'primary',
icon: 'el-icon-Plus', icon: 'el-icon-Plus',
render: 'basicButton', render: 'basicButton',
click: row => { click: row => {
rowList.value = row rowList.value = row
let data = uesrList.filter(item => item.id == row.evaluateType)[0].code let data = uesrList.filter(item => item.id == row.evaluateType)[0].code
data == 'Power_Station_Users' data == 'Power_Station_Users'
? ((code.value = 1), (activeName.value = '1')) ? ((code.value = 1), (activeName.value = '1'))
: ((code.value = 2), (activeName.value = '2')) : ((code.value = 2), (activeName.value = '2'))
addedShow.value = false addedShow.value = false
} }
}, },
{ {
name: 'del', name: 'del',
text: '禁止接入', text: '禁止接入',
type: 'danger', type: 'danger',
icon: 'el-icon-Delete', icon: 'el-icon-Delete',
render: 'confirmButton', render: 'confirmButton',
popconfirm: { popconfirm: {
confirmButtonText: '确认', confirmButtonText: '确认',
cancelButtonText: '取消', cancelButtonText: '取消',
confirmButtonType: 'danger', confirmButtonType: 'danger',
title: '确定删除' title: '确定禁止接入'
}, },
click: row => { click: row => {
remove({ ids: row.id }).then(() => { remove({ ids: row.id }).then(() => {
ElMessage.success('删除成功') ElMessage.success('禁止接入成功')
tableStore.index() tableStore.index()
}) })
} }
} }
] ]
} }
], ],
loadCallback: () => {} loadCallback: () => {}
}) })
tableStore.table.params.evaluateType = '' tableStore.table.params.evaluateType = ''
tableStore.table.params.id = dictData.state.area[0].id tableStore.table.params.id = dictData.state.area[0].id
provide('tableStore', tableStore) provide('tableStore', tableStore)
const quit = () => { const quit = () => {
addedShow.value = true addedShow.value = true
tableStore.index() tableStore.index()
rowList.value = {} rowList.value = {}
} }
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
const addAssess = () => { const addAssess = () => {
addedShow.value = false addedShow.value = false
code.value = null code.value = null
activeName.value = '1' activeName.value = '1'
} }
// 配置 // 配置
const configuration = () => { const configuration = () => {
policyView.value = true policyView.value = true
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.quit { .quit {
position: absolute; position: absolute;
top: 5px; top: 5px;
right: 10px; right: 10px;
} }
</style> </style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff