mac地址,推送调整
This commit is contained in:
@@ -1,25 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mac-address-input" :class="{ disabled: disabled }">
|
<div class="mac-address-input" :class="{ disabled: disabled }">
|
||||||
<template v-for="n in 6" :key="n">
|
|
||||||
<el-input
|
<el-input
|
||||||
ref="inputRefs"
|
ref="inputRef"
|
||||||
v-model="segments[n - 1]"
|
v-model="macValue"
|
||||||
type="text"
|
type="text"
|
||||||
maxlength="2"
|
maxlength="17"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@input="handleInput(n - 1)"
|
@input="handleInput"
|
||||||
@keydown="handleKeydown(n - 1,$event)"
|
@keydown="handleKeydown"
|
||||||
@focus="handleFocus(n - 1)"
|
@focus="handleFocus"
|
||||||
@blur="handleBlur"
|
@blur="handleBlur"
|
||||||
@paste="handlePaste(n - 1, $event)"
|
@paste="handlePaste"
|
||||||
/>
|
/>
|
||||||
<span v-if="n < 6" class="separator">:</span>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, nextTick } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue?: string
|
modelValue?: string
|
||||||
@@ -37,117 +34,85 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
|
|
||||||
const emit = defineEmits<Emits>()
|
const emit = defineEmits<Emits>()
|
||||||
|
|
||||||
// 创建6个输入框的引用
|
// 创建单个输入框的引用
|
||||||
const inputRefs = ref<InstanceType<typeof import('element-plus').ElInput>[]>([])
|
const inputRef = ref<InstanceType<typeof import('element-plus').ElInput> | null>(null)
|
||||||
|
|
||||||
// MAC地址的6个段
|
// MAC地址值
|
||||||
const segments = ref<string[]>(Array(6).fill(''))
|
const macValue = ref<string>('')
|
||||||
|
|
||||||
// 解析传入的MAC地址
|
// 解析传入的MAC地址
|
||||||
const parseMacAddress = (mac: string): string[] => {
|
const parseMacAddress = (mac: string): string => {
|
||||||
if (!mac) return Array(6).fill('')
|
if (!mac) return ''
|
||||||
|
|
||||||
// 移除非十六进制字符并转为大写
|
// 移除非十六进制字符并转为大写
|
||||||
const cleanMac = mac.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
|
const cleanMac = mac.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
|
||||||
|
|
||||||
// 分割成6段,每段2个字符
|
// 按每2个字符分割并用冒号连接
|
||||||
const result: string[] = []
|
let result = ''
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < cleanMac.length; i += 2) {
|
||||||
result.push(cleanMac.substr(i * 2, 2))
|
if (i > 0) result += ':'
|
||||||
|
result += cleanMac.substr(i, 2)
|
||||||
}
|
}
|
||||||
return result
|
return result.substring(0, 17) // 最多17个字符 (12个数字+5个冒号)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化MAC地址段
|
// 格式化MAC地址 - 改进版
|
||||||
const formatSegment = (value: string): string => {
|
const formatMac = (value: string): string => {
|
||||||
// 只保留前两个十六进制字符并转为大写
|
// 移除所有冒号
|
||||||
return value.replace(/[^0-9a-fA-F]/g, '').toUpperCase().substr(0, 2)
|
const cleanValue = value.replace(/:/g, '')
|
||||||
|
// 只保留十六进制字符并转为大写
|
||||||
|
const hexOnly = cleanValue.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
|
||||||
|
|
||||||
|
// 按每两个字符添加冒号,最多6段
|
||||||
|
let formatted = ''
|
||||||
|
for (let i = 0; i < Math.min(hexOnly.length, 12); i += 2) {
|
||||||
|
if (i > 0) formatted += ':'
|
||||||
|
formatted += hexOnly.substr(i, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatted
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前聚焦的输入框索引
|
// 当前聚焦的输入框索引
|
||||||
const focusedIndex = ref<number | null>(null)
|
const focusedIndex = ref<number | null>(null)
|
||||||
|
|
||||||
// 处理输入事件
|
// 处理输入事件
|
||||||
const handleInput = (index: number) => {
|
const handleInput = (value: string) => {
|
||||||
// 格式化输入值
|
const formatted = formatMac(value)
|
||||||
const formatted = formatSegment(segments.value[index])
|
macValue.value = formatted
|
||||||
segments.value[index] = formatted
|
// 发出不带冒号的纯净值
|
||||||
|
emit('update:modelValue', formatted.replace(/:/g, ''))
|
||||||
// 如果当前段已满2个字符且不是最后一段,自动跳转到下一个输入框
|
|
||||||
if (formatted.length === 2 && index < 5) {
|
|
||||||
// 获取下一个输入框的DOM元素
|
|
||||||
setTimeout(() => {
|
|
||||||
const nextInput = inputRefs.value[index + 1]
|
|
||||||
if (nextInput) {
|
|
||||||
const inputEl = nextInput.$el.querySelector('input')
|
|
||||||
if (inputEl) {
|
|
||||||
inputEl.focus()
|
|
||||||
inputEl.select()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新v-model值
|
|
||||||
updateModelValue()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理键盘事件
|
// 处理键盘事件
|
||||||
const handleKeydown = (index: number, event: KeyboardEvent) => {
|
const handleKeydown = (event: KeyboardEvent) => {
|
||||||
const target = event.target as HTMLInputElement
|
const target = event.target as HTMLInputElement
|
||||||
|
|
||||||
// 处理退格键
|
// 处理退格键
|
||||||
if (event.key === 'Backspace' && target.selectionStart === 0 && target.selectionEnd === 0) {
|
if (event.key === 'Backspace') {
|
||||||
if (segments.value[index] === '' && index > 0) {
|
// 处理在冒号前删除的情况
|
||||||
// 如果当前段为空,跳转到前一个输入框
|
const cursorPos = target.selectionStart || 0
|
||||||
|
if (cursorPos > 0 && macValue.value[cursorPos - 1] === ':' &&
|
||||||
|
target.selectionStart === target.selectionEnd) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const prevInput = inputRefs.value[index - 1]
|
// 删除冒号前的两个字符
|
||||||
if (prevInput) {
|
const newValue = macValue.value.substring(0, cursorPos - 3) +
|
||||||
const inputEl = prevInput.$el.querySelector('input')
|
macValue.value.substring(cursorPos)
|
||||||
if (inputEl) {
|
macValue.value = newValue
|
||||||
inputEl.focus()
|
// 设置光标位置
|
||||||
// 将光标移到末尾
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inputEl.selectionStart = inputEl.value.length
|
if (target.setSelectionRange) {
|
||||||
inputEl.selectionEnd = inputEl.value.length
|
target.setSelectionRange(cursorPos - 3, cursorPos - 3)
|
||||||
|
}
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
emit('update:modelValue', newValue.replace(/:/g, ''))
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理左箭头键
|
|
||||||
if (event.key === 'ArrowLeft' && target.selectionStart === 0) {
|
|
||||||
if (index > 0) {
|
|
||||||
event.preventDefault()
|
|
||||||
const prevInput = inputRefs.value[index - 1]
|
|
||||||
if (prevInput) {
|
|
||||||
const inputEl = prevInput.$el.querySelector('input')
|
|
||||||
if (inputEl) {
|
|
||||||
inputEl.focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理右箭头键和制表符
|
|
||||||
if ((event.key === 'ArrowRight' && target.selectionStart === target.value.length) || event.key === 'Tab') {
|
|
||||||
if (index < 5) {
|
|
||||||
event.preventDefault()
|
|
||||||
const nextInput = inputRefs.value[index + 1]
|
|
||||||
if (nextInput) {
|
|
||||||
const inputEl = nextInput.$el.querySelector('input')
|
|
||||||
if (inputEl) {
|
|
||||||
inputEl.focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理焦点事件
|
// 处理焦点事件
|
||||||
const handleFocus = (index: number) => {
|
const handleFocus = () => {
|
||||||
focusedIndex.value = index
|
focusedIndex.value = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理失焦事件
|
// 处理失焦事件
|
||||||
@@ -156,56 +121,26 @@ const handleBlur = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理粘贴事件
|
// 处理粘贴事件
|
||||||
const handlePaste = (index: number, event: ClipboardEvent) => {
|
const handlePaste = (event: ClipboardEvent) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const pastedText = event.clipboardData?.getData('text') || ''
|
const pastedText = event.clipboardData?.getData('text') || ''
|
||||||
|
|
||||||
// 清理粘贴的文本
|
// 清理粘贴的文本
|
||||||
const cleanText = parseMacAddress(pastedText)
|
const cleanPastedText = pastedText.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
|
||||||
|
const formatted = formatMac(cleanPastedText)
|
||||||
// 填充各段
|
macValue.value = formatted
|
||||||
for (let i = 0; i < 6; i++) {
|
emit('update:modelValue', formatted.replace(/:/g, ''))
|
||||||
segments.value[i] = cleanText[i] || ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新v-model值
|
|
||||||
updateModelValue()
|
|
||||||
|
|
||||||
// 聚焦到最后一个非空段或最后一个段
|
|
||||||
setTimeout(() => {
|
|
||||||
let focusIndex = 5
|
|
||||||
for (let i = 5; i >= 0; i--) {
|
|
||||||
if (segments.value[i] !== '') {
|
|
||||||
focusIndex = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputToFocus = inputRefs.value[focusIndex]
|
|
||||||
if (inputToFocus) {
|
|
||||||
const inputEl = inputToFocus.$el.querySelector('input')
|
|
||||||
if (inputEl) {
|
|
||||||
inputEl.focus()
|
|
||||||
inputEl.select()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新v-model值
|
|
||||||
const updateModelValue = () => {
|
|
||||||
// 过滤掉空段,然后用冒号连接
|
|
||||||
const nonEmptySegments = segments.value.filter(s => s !== '')
|
|
||||||
const mac = nonEmptySegments.join(':')
|
|
||||||
emit('update:modelValue', mac)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听modelValue变化
|
// 监听modelValue变化
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal !== segments.value.filter(s => s !== '').join(':')) {
|
const cleanNewVal = (newVal || '').replace(/[^0-9a-fA-F]/g, '').toUpperCase()
|
||||||
segments.value = parseMacAddress(newVal || '')
|
const currentCleanValue = macValue.value.replace(/:/g, '')
|
||||||
|
|
||||||
|
if (cleanNewVal !== currentCleanValue) {
|
||||||
|
macValue.value = parseMacAddress(cleanNewVal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
@@ -214,37 +149,17 @@ watch(
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.mac-address-input {
|
.mac-address-input {
|
||||||
display: flex;
|
width: 100%;
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
input {
|
input {
|
||||||
width: 40px;
|
|
||||||
height: 32px;
|
|
||||||
text-align: center;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
border-radius: 4px;
|
|
||||||
outline: none;
|
|
||||||
font-size: 14px;
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
font-family: inherit; // 使用继承的字体而不是等宽字体
|
||||||
&:focus {
|
|
||||||
border-color: #409eff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.separator {
|
|
||||||
user-select: none;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -309,6 +309,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
||||||
class="form-item"
|
class="form-item"
|
||||||
label="装置mac地址:"
|
label="装置mac地址:"
|
||||||
:rules="{ required: true, message: '请输入装置mac地址', trigger: 'blur' }"
|
:rules="{ required: true, message: '请输入装置mac地址', trigger: 'blur' }"
|
||||||
@@ -694,7 +695,7 @@ interface DeviceInfo {
|
|||||||
nodeId: string
|
nodeId: string
|
||||||
cntractNo: string
|
cntractNo: string
|
||||||
sort: number
|
sort: number
|
||||||
nodeProcess:number
|
nodeProcess:string
|
||||||
}
|
}
|
||||||
// 设备信息列表
|
// 设备信息列表
|
||||||
const deviceInfoList = ref<DeviceInfo[]>([])
|
const deviceInfoList = ref<DeviceInfo[]>([])
|
||||||
@@ -841,7 +842,6 @@ const handleDialogClose = () => {
|
|||||||
countdown.value = 0
|
countdown.value = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
//台账推送
|
|
||||||
const onAdd = async () => {
|
const onAdd = async () => {
|
||||||
resultDialogVisible.value = true
|
resultDialogVisible.value = true
|
||||||
pushResult.value = null
|
pushResult.value = null
|
||||||
@@ -859,8 +859,23 @@ const onAdd = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 调用推送日志接口
|
// 调用推送日志接口
|
||||||
await pushLog()
|
const pushLogResponse = await pushLog()
|
||||||
|
|
||||||
|
// 检查返回的data是否为"暂无需要推送的数据"
|
||||||
|
if (pushLogResponse.data != "成功") {
|
||||||
|
// 直接提示用户没有数据推送
|
||||||
|
pushResult.value = {
|
||||||
|
success: false,
|
||||||
|
message: '暂无需要推送的数据',
|
||||||
|
logs: [{
|
||||||
|
message: '暂无需要推送的数据'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果data不是"暂无需要推送的数据",则继续执行
|
||||||
|
if (pushLogResponse.data === "成功") {
|
||||||
// 等待30秒
|
// 等待30秒
|
||||||
await new Promise(resolve => setTimeout(resolve, 30000))
|
await new Promise(resolve => setTimeout(resolve, 30000))
|
||||||
|
|
||||||
@@ -878,6 +893,7 @@ const onAdd = async () => {
|
|||||||
message: item.message || JSON.stringify(item)
|
message: item.message || JSON.stringify(item)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
pushResult.value = {
|
pushResult.value = {
|
||||||
success: false,
|
success: false,
|
||||||
@@ -1028,7 +1044,7 @@ const add = () => {
|
|||||||
nodeId: '',
|
nodeId: '',
|
||||||
cntractNo: '',
|
cntractNo: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
nodeProcess: 1,
|
nodeProcess: '自动分配',
|
||||||
})
|
})
|
||||||
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
||||||
// 清理监测点数据
|
// 清理监测点数据
|
||||||
@@ -1381,7 +1397,7 @@ const next = async () => {
|
|||||||
nodeId: '',
|
nodeId: '',
|
||||||
cntractNo: '',
|
cntractNo: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
nodeProcess: 1,
|
nodeProcess: '自动分配',
|
||||||
})
|
})
|
||||||
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
||||||
nextfalg.value = false
|
nextfalg.value = false
|
||||||
@@ -2080,7 +2096,7 @@ const handleBusBarTabsEdit = (targetName: any, action: any) => {
|
|||||||
nodeId: '',
|
nodeId: '',
|
||||||
cntractNo: '',
|
cntractNo: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
nodeProcess: 1,
|
nodeProcess: '自动分配',
|
||||||
})
|
})
|
||||||
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
||||||
} else if (action === 'remove') {
|
} else if (action === 'remove') {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
<span v-if="data.processState != null">
|
<span v-if="data.processState != null">
|
||||||
{{ node.label }}
|
{{ node.label }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>{{ data.subName }}_{{ data.name }}</span>
|
<span v-else>{{ data.name }}</span>
|
||||||
<span
|
<span
|
||||||
v-if="data.processState != null"
|
v-if="data.processState != null"
|
||||||
class="iconSpan"
|
class="iconSpan"
|
||||||
|
|||||||
Reference in New Issue
Block a user