feat: v0.8.x 功能更新与数据维护优化
- MAC地址格式统一为小写 xxxx-xxxx-xxxx,支持三种格式输入 - 更换设备MAC时自动清理OLT新发现列表中的冲突ONU记录 - 设备编辑新增场所类型字段(手动输入),区域改为下拉快速填充 - 编辑/更换设备时自动移除new_devices中同MAC的待入库记录 - 新增登录过期自动跳转(401拦截 + 过期提示) - 新增关于页面(/about),支持Markdown渲染,管理员可在设置中编辑内容 - 新增device_status_history每日自动清理任务(保留30天) - 更新README.md和about.md
This commit is contained in:
@@ -361,7 +361,7 @@
|
||||
</div>
|
||||
<el-form :model="replaceForm" label-width="80px">
|
||||
<el-form-item label="新 MAC 地址" required>
|
||||
<el-input v-model="replaceForm.new_mac" placeholder="例:AABBCCDDEEFF 或 AA:BB:CC:DD:EE:FF" clearable />
|
||||
<el-input v-model="replaceForm.new_mac" placeholder="例:AABB-CCDD-EEFF" clearable @input="formatMacInput" />
|
||||
</el-form-item>
|
||||
<el-form-item label="更换原因">
|
||||
<el-input v-model="replaceForm.reason" type="textarea" :rows="2" placeholder="可选,填写更换原因" />
|
||||
@@ -385,10 +385,23 @@
|
||||
<!-- 编辑对话框 -->
|
||||
<el-dialog v-model="editVisible" title="编辑设备信息" width="460px" destroy-on-close>
|
||||
<el-form :model="editForm" label-width="70px">
|
||||
<el-form-item label="区域"><el-input v-model="editForm.region" /></el-form-item>
|
||||
<el-form-item label="区域">
|
||||
<el-select
|
||||
v-model="editForm.region"
|
||||
filterable
|
||||
allow-create
|
||||
placeholder="选择或输入区域"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="r in regionOptions" :key="r" :label="r" :value="r" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学校"><el-input v-model="editForm.school_name" /></el-form-item>
|
||||
<el-form-item label="楼宇"><el-input v-model="editForm.building" /></el-form-item>
|
||||
<el-form-item label="房间号"><el-input v-model="editForm.room_number" /></el-form-item>
|
||||
<el-form-item label="场所类型">
|
||||
<el-input v-model="editForm.place_type" placeholder="如:宿舍、教室、办公室…" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="editForm.notes" type="textarea" :rows="2" /></el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -526,7 +539,8 @@ let cooldownTimer = null
|
||||
const clearing = ref(false)
|
||||
|
||||
const editVisible = ref(false)
|
||||
const editForm = ref({ region: '', school_name: '', building: '', room_number: '', notes: '' })
|
||||
const editForm = ref({ region: '', school_name: '', building: '', room_number: '', place_type: '', notes: '' })
|
||||
const regionOptions = ref([])
|
||||
const editSaving = ref(false)
|
||||
|
||||
const replaceVisible = ref(false)
|
||||
@@ -602,8 +616,10 @@ const openEditFromCard = (device) => {
|
||||
school_name: device.school_name || '',
|
||||
building: device.building || '',
|
||||
room_number: device.room_number || '',
|
||||
place_type: device.place_type || '',
|
||||
notes: device.notes || '',
|
||||
}
|
||||
loadRegionOptions()
|
||||
editVisible.value = true
|
||||
}
|
||||
|
||||
@@ -727,6 +743,18 @@ const openReplace = async () => {
|
||||
replaceVisible.value = true
|
||||
}
|
||||
|
||||
// 输入时自动格式化为 xxxx-xxxx-xxxx(小写)
|
||||
const formatMacInput = () => {
|
||||
const raw = replaceForm.value.new_mac.toLowerCase().replace(/[^0-9a-f]/g, '')
|
||||
if (raw.length <= 4) {
|
||||
replaceForm.value.new_mac = raw
|
||||
} else if (raw.length <= 8) {
|
||||
replaceForm.value.new_mac = raw.slice(0, 4) + '-' + raw.slice(4)
|
||||
} else {
|
||||
replaceForm.value.new_mac = raw.slice(0, 4) + '-' + raw.slice(4, 8) + '-' + raw.slice(8, 12)
|
||||
}
|
||||
}
|
||||
|
||||
const doReplace = async () => {
|
||||
if (!replaceForm.value.new_mac.trim()) {
|
||||
ElMessage.warning('请输入新 MAC 地址')
|
||||
@@ -753,12 +781,21 @@ const openEdit = () => {
|
||||
school_name: selectedDevice.value.school_name || '',
|
||||
building: selectedDevice.value.building || '',
|
||||
room_number: selectedDevice.value.room_number || '',
|
||||
place_type: selectedDevice.value.place_type || '',
|
||||
notes: selectedDevice.value.notes || '',
|
||||
}
|
||||
loadRegionOptions()
|
||||
detailVisible.value = false
|
||||
editVisible.value = true
|
||||
}
|
||||
|
||||
const loadRegionOptions = async () => {
|
||||
try {
|
||||
const { data } = await deviceApi.getRegions()
|
||||
regionOptions.value = data
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const saveEdit = async () => {
|
||||
editSaving.value = true
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user