调整台账

This commit is contained in:
guanj
2026-04-03 14:47:36 +08:00
parent 0b9aafc1b5
commit 3ffb11defa
5 changed files with 183 additions and 149 deletions

View File

@@ -1,35 +1,36 @@
<template>
<div class="mac-address-input" :class="{ disabled: disabled }">
<el-input
ref="inputRef"
v-model="macValue"
type="text"
maxlength="17"
:disabled="disabled"
@input="handleInput"
@keydown="handleKeydown"
@focus="handleFocus"
@blur="handleBlur"
@paste="handlePaste"
/>
</div>
<div class="mac-address-input" :class="{ disabled: disabled }">
<el-input
ref="inputRef"
placeholder="请输入设备mac地址"
v-model="macValue"
type="text"
maxlength="17"
:disabled="disabled"
@input="handleInput"
@keydown="handleKeydown"
@focus="handleFocus"
@blur="handleBlur"
@paste="handlePaste"
/>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
interface Props {
modelValue?: string
disabled?: boolean
modelValue?: string
disabled?: boolean
}
interface Emits {
(e: 'update:modelValue', value: string): void
(e: 'update:modelValue', value: string): void
}
const props = withDefaults(defineProps<Props>(), {
modelValue: '',
disabled: false
modelValue: '',
disabled: false
})
const emit = defineEmits<Emits>()
@@ -42,35 +43,35 @@ const macValue = ref<string>('')
// 解析传入的MAC地址
const parseMacAddress = (mac: string): string => {
if (!mac) return ''
// 移除非十六进制字符并转为大写
const cleanMac = mac.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
// 按每2个字符分割并用冒号连接
let result = ''
for (let i = 0; i < cleanMac.length; i += 2) {
if (i > 0) result += ':'
result += cleanMac.substr(i, 2)
}
return result.substring(0, 17) // 最多17个字符 (12个数字+5个冒号)
if (!mac) return ''
// 移除非十六进制字符并转为大写
const cleanMac = mac.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
// 按每2个字符分割并用冒号连接
let result = ''
for (let i = 0; i < cleanMac.length; i += 2) {
if (i > 0) result += ':'
result += cleanMac.substr(i, 2)
}
return result.substring(0, 17) // 最多17个字符 (12个数字+5个冒号)
}
// 格式化MAC地址 - 改进版
const formatMac = (value: string): string => {
// 移除所有冒号
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 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
}
// 当前聚焦的输入框索引
@@ -78,88 +79,86 @@ const focusedIndex = ref<number | null>(null)
// 处理输入事件
const handleInput = (value: string) => {
const formatted = formatMac(value)
macValue.value = formatted
// 发出不带冒号的纯净值
emit('update:modelValue', formatted.replace(/:/g, ''))
const formatted = formatMac(value)
macValue.value = formatted
// 发出不带冒号的纯净值
emit('update:modelValue', formatted.replace(/:/g, ''))
}
// 处理键盘事件
const handleKeydown = (event: KeyboardEvent) => {
const target = event.target as HTMLInputElement
// 处理退格键
if (event.key === 'Backspace') {
// 处理在冒号前删除的情况
const cursorPos = target.selectionStart || 0
if (cursorPos > 0 && macValue.value[cursorPos - 1] === ':' &&
target.selectionStart === target.selectionEnd) {
event.preventDefault()
// 删除冒号前的两个字符
const newValue = macValue.value.substring(0, cursorPos - 3) +
macValue.value.substring(cursorPos)
macValue.value = newValue
// 设置光标位置
setTimeout(() => {
if (target.setSelectionRange) {
target.setSelectionRange(cursorPos - 3, cursorPos - 3)
const target = event.target as HTMLInputElement
// 处理退格键
if (event.key === 'Backspace') {
// 处理在冒号前删除的情况
const cursorPos = target.selectionStart || 0
if (cursorPos > 0 && macValue.value[cursorPos - 1] === ':' && target.selectionStart === target.selectionEnd) {
event.preventDefault()
// 删除冒号前的两个字符
const newValue = macValue.value.substring(0, cursorPos - 3) + macValue.value.substring(cursorPos)
macValue.value = newValue
// 设置光标位置
setTimeout(() => {
if (target.setSelectionRange) {
target.setSelectionRange(cursorPos - 3, cursorPos - 3)
}
}, 0)
emit('update:modelValue', newValue.replace(/:/g, ''))
}
}, 0)
emit('update:modelValue', newValue.replace(/:/g, ''))
}
}
}
// 处理焦点事件
const handleFocus = () => {
focusedIndex.value = 0
focusedIndex.value = 0
}
// 处理失焦事件
const handleBlur = () => {
focusedIndex.value = null
focusedIndex.value = null
}
// 处理粘贴事件
const handlePaste = (event: ClipboardEvent) => {
event.preventDefault()
const pastedText = event.clipboardData?.getData('text') || ''
// 清理粘贴的文本
const cleanPastedText = pastedText.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
const formatted = formatMac(cleanPastedText)
macValue.value = formatted
emit('update:modelValue', formatted.replace(/:/g, ''))
event.preventDefault()
const pastedText = event.clipboardData?.getData('text') || ''
// 清理粘贴的文本
const cleanPastedText = pastedText.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
const formatted = formatMac(cleanPastedText)
macValue.value = formatted
emit('update:modelValue', formatted.replace(/:/g, ''))
}
// 监听modelValue变化
watch(
() => props.modelValue,
(newVal) => {
const cleanNewVal = (newVal || '').replace(/[^0-9a-fA-F]/g, '').toUpperCase()
const currentCleanValue = macValue.value.replace(/:/g, '')
if (cleanNewVal !== currentCleanValue) {
macValue.value = parseMacAddress(cleanNewVal)
}
},
{ immediate: true }
() => props.modelValue,
newVal => {
const cleanNewVal = (newVal || '').replace(/[^0-9a-fA-F]/g, '').toUpperCase()
const currentCleanValue = macValue.value.replace(/:/g, '')
if (cleanNewVal !== currentCleanValue) {
macValue.value = parseMacAddress(cleanNewVal)
}
},
{ immediate: true }
)
</script>
<style scoped lang="scss">
.mac-address-input {
width: 100%;
&.disabled {
opacity: 0.7;
}
:deep(.el-input__wrapper) {
input {
text-transform: uppercase;
font-family: inherit; // 使用继承的字体而不是等宽字体
width: 100%;
&.disabled {
opacity: 0.7;
}
:deep(.el-input__wrapper) {
input {
text-transform: uppercase;
font-family: inherit; // 使用继承的字体而不是等宽字体
}
}
}
}
</style>
</style>