变频器功能页面
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:model-value="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
:width="dialogWidth"
|
||||
:style="dialogStyle"
|
||||
:close-on-click-modal="dialogBig.closeOnClickModal"
|
||||
:draggable="dialogBig.draggable"
|
||||
:class="dialogBig.class"
|
||||
:show-close="true"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClose"
|
||||
destroy-on-close
|
||||
align-center
|
||||
>
|
||||
<div class="freq-converter-test-popup">
|
||||
<el-steps :active="currentStep - 1" finish-status="success" simple>
|
||||
<el-step title="准备" />
|
||||
<el-step title="检测" />
|
||||
</el-steps>
|
||||
|
||||
<FreqConverterDetectChannelPairing
|
||||
v-if="dialogVisible && currentStep === 1"
|
||||
ref="channelPairingRef"
|
||||
:freq-converter="currentFreqConverter"
|
||||
/>
|
||||
|
||||
<FreqConverterDipChart
|
||||
v-else-if="dialogVisible && currentStep === 2"
|
||||
:selected-mapping="selectedMapping"
|
||||
:web-msg-send="webSocketMessage"
|
||||
:result-data="historyResultData"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button
|
||||
v-if="!startDetectSuccess"
|
||||
type="primary"
|
||||
:disabled="currentStep !== 1 || startLoading"
|
||||
:loading="startLoading"
|
||||
@click="handleStart"
|
||||
>
|
||||
开始检测
|
||||
</el-button>
|
||||
<el-button type="danger" plain @click="handleExit">退出检测</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import {computed, onBeforeUnmount, onMounted, ref} from 'vue'
|
||||
import {dialogBig} from '@/utils/elementBind'
|
||||
import {type FreqConverter} from '@/api/device/interface/freqConverter'
|
||||
import {getFreqConverterResult, startFreqConverterDetect, stopFreqConverterDetect} from '@/api/device/freqConverter'
|
||||
import {JwtUtil} from '@/utils/jwtUtil'
|
||||
import FreqConverterDetectChannelPairing from '@/views/machine/freqConverter/components/freqConverterDetectChannelPairing.vue'
|
||||
import FreqConverterDipChart from '@/views/machine/freqConverter/components/freqConverterDipChart.vue'
|
||||
import socketClient from '@/utils/webSocketClient'
|
||||
|
||||
const SOCKET_CALLBACK_KEY = 'aaa'
|
||||
|
||||
const props = defineProps<{
|
||||
refreshTable?: (() => Promise<void>) | (() => void) | undefined;
|
||||
}>()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const currentStep = ref(1)
|
||||
const currentFreqConverter = ref<FreqConverter.ResFreqConverter | null>(null)
|
||||
const channelPairingRef = ref<InstanceType<typeof FreqConverterDetectChannelPairing>>()
|
||||
const webSocketMessage = ref<any>(null)
|
||||
const historyResultData = ref<any>(null)
|
||||
const socketServe = ref<typeof socketClient.Instance | null>(null)
|
||||
const selectedMapping = ref<Record<string, any> | null>(null)
|
||||
const startLoading = ref(false)
|
||||
const startDetectSuccess = ref(false)
|
||||
const hasSocketError = ref(false)
|
||||
const viewportWidth = ref(typeof window === 'undefined' ? 1280 : window.innerWidth)
|
||||
|
||||
const dialogTitle = computed(() => '变频器检测')
|
||||
const dialogWidth = computed(() => (viewportWidth.value < 820 ? 'calc(100vw - 24px)' : dialogBig.width))
|
||||
const dialogStyle = computed(() => ({
|
||||
maxWidth: dialogBig.maxWidth,
|
||||
minWidth: viewportWidth.value < 820 ? '320px' : dialogBig.minWidth
|
||||
}))
|
||||
|
||||
const SOCKET_ERROR_MESSAGE_MAP: Record<number, string> = {
|
||||
10550: '设备连接异常',
|
||||
10551: '设备触发报告异常',
|
||||
10552: '重复的初始化操作',
|
||||
10553: '通讯模块通讯异常',
|
||||
10554: '报文解析异常',
|
||||
10556: '不存在上线的设备'
|
||||
}
|
||||
|
||||
const normalizeFormalRealPayload = (payload: any) => {
|
||||
if (!payload || typeof payload !== 'object') {
|
||||
return payload
|
||||
}
|
||||
|
||||
if (typeof payload.data !== 'string') {
|
||||
return payload
|
||||
}
|
||||
|
||||
try {
|
||||
return {
|
||||
...payload,
|
||||
data: JSON.parse(payload.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('formal_real 数据解析失败:', error, payload.data)
|
||||
return payload
|
||||
}
|
||||
}
|
||||
|
||||
const handleSocketMessage = (payload: any) => {
|
||||
const requestId = `${payload?.requestId ?? ''}`
|
||||
const normalizedRequestId = requestId.trim().toLowerCase()
|
||||
const code = Number(payload?.code)
|
||||
|
||||
if (requestId === 'yjc_sbtxjy' && code !== 10200) {
|
||||
hasSocketError.value = true
|
||||
ElMessage.error(SOCKET_ERROR_MESSAGE_MAP[code] || `检测异常,错误码:${code}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (normalizedRequestId.startsWith('formal_real')) {
|
||||
webSocketMessage.value = normalizeFormalRealPayload(payload)
|
||||
}
|
||||
}
|
||||
|
||||
const updateViewportWidth = () => {
|
||||
viewportWidth.value = window.innerWidth
|
||||
}
|
||||
|
||||
const connectWebSocket = () => {
|
||||
try {
|
||||
if (socketServe.value) {
|
||||
socketServe.value.unRegisterCallBack?.(SOCKET_CALLBACK_KEY)
|
||||
if (socketServe.value.connected) {
|
||||
socketServe.value.closeWs()
|
||||
}
|
||||
}
|
||||
|
||||
socketClient.Instance.connect()
|
||||
socketServe.value = socketClient.Instance
|
||||
socketServe.value.registerCallBack(SOCKET_CALLBACK_KEY, handleSocketMessage)
|
||||
} catch (error) {
|
||||
console.error('WebSocket连接处理失败:', error)
|
||||
ElMessage.error('WebSocket连接建立失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
const closeWebSocket = () => {
|
||||
try {
|
||||
if (socketServe.value) {
|
||||
socketServe.value.unRegisterCallBack?.(SOCKET_CALLBACK_KEY)
|
||||
if (socketServe.value.connected) {
|
||||
socketServe.value.closeWs()
|
||||
}
|
||||
socketServe.value = null
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('WebSocket关闭失败:', error)
|
||||
socketServe.value = null
|
||||
}
|
||||
}
|
||||
|
||||
const resetState = () => {
|
||||
currentStep.value = 1
|
||||
webSocketMessage.value = null
|
||||
historyResultData.value = null
|
||||
currentFreqConverter.value = null
|
||||
selectedMapping.value = null
|
||||
startLoading.value = false
|
||||
startDetectSuccess.value = false
|
||||
hasSocketError.value = false
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
dialogVisible.value = false
|
||||
closeWebSocket()
|
||||
resetState()
|
||||
}
|
||||
|
||||
const stopDetect = async () => {
|
||||
if (!startDetectSuccess.value) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await stopFreqConverterDetect({
|
||||
userId: JwtUtil.getLoginName()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('停止变频器检测失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const confirmExit = async () => {
|
||||
await ElMessageBox.confirm(
|
||||
'检测未完成,是否退出当前检测流程?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const isFreqConverterDetected = () => {
|
||||
return Number(currentFreqConverter.value?.testStatus) === 1
|
||||
}
|
||||
|
||||
const confirmResetLastDetectData = async () => {
|
||||
if (!isFreqConverterDetected()) {
|
||||
return true
|
||||
}
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'是否覆盖上次检测数据',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '是',
|
||||
cancelButtonText: '否',
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
return true
|
||||
} catch (action) {
|
||||
if (action === 'cancel') {
|
||||
return false
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const handleBeforeClose = async (done: () => void) => {
|
||||
if (hasSocketError.value) {
|
||||
await stopDetect()
|
||||
closeDialog()
|
||||
await props.refreshTable?.()
|
||||
done()
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await confirmExit()
|
||||
await stopDetect()
|
||||
closeDialog()
|
||||
await props.refreshTable?.()
|
||||
done()
|
||||
} catch {
|
||||
// 用户取消关闭
|
||||
}
|
||||
}
|
||||
|
||||
const handleStart = async () => {
|
||||
if (currentStep.value === 1) {
|
||||
const mapping = channelPairingRef.value?.getChannelMapping()
|
||||
if (!mapping || !channelPairingRef.value?.hasValidConnection()) {
|
||||
ElMessage.warning('请先选择设备通道并完成连线')
|
||||
return
|
||||
}
|
||||
|
||||
const reset = await confirmResetLastDetectData()
|
||||
if (reset === null) {
|
||||
return
|
||||
}
|
||||
|
||||
startLoading.value = true
|
||||
|
||||
try {
|
||||
if (reset === false) {
|
||||
const historyResult = await getFreqConverterResult({
|
||||
converterId: mapping.freqConverterId
|
||||
})
|
||||
historyResultData.value = historyResult?.data ?? historyResult
|
||||
} else {
|
||||
historyResultData.value = null
|
||||
}
|
||||
|
||||
const res = await startFreqConverterDetect({
|
||||
converterId: mapping.freqConverterId,
|
||||
monitorId: `${mapping.deviceId}_${mapping.deviceChannel}`,
|
||||
userId: JwtUtil.getLoginName(),
|
||||
reset
|
||||
})
|
||||
|
||||
if (res.code === 'A0000') {
|
||||
selectedMapping.value = mapping
|
||||
currentStep.value = 2
|
||||
startDetectSuccess.value = true
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('开始变频器检测失败:', error)
|
||||
ElMessage.error('开始检测失败')
|
||||
} finally {
|
||||
startLoading.value = false
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const handleExit = async () => {
|
||||
if (!hasSocketError.value) {
|
||||
try {
|
||||
await confirmExit()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
await stopDetect()
|
||||
closeDialog()
|
||||
await props.refreshTable?.()
|
||||
}
|
||||
|
||||
const open = (row: FreqConverter.ResFreqConverter) => {
|
||||
resetState()
|
||||
currentFreqConverter.value = {...row}
|
||||
dialogVisible.value = true
|
||||
connectWebSocket()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', updateViewportWidth)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', updateViewportWidth)
|
||||
closeWebSocket()
|
||||
})
|
||||
|
||||
defineExpose({open, channelPairingRef})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.freq-converter-test-popup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.section-card {
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.section-tip {
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user