feat(aiot): 摄像头管理 - 应用名场景化和流ID自动编号

- 应用名提示优化:"场景分类,如:大堂、停车场、入口"
- 流ID提示优化:"在当前场景下的唯一标识,如:001(系统会自动编号)"
- 新增摄像头时,流ID自动填充为场景下的顺序编号(001, 002, 003...)
- 监听应用名变化,动态更新流ID编号
- 自动编号逻辑:查找当前场景下已用的纯数字编号,填充下一个可用编号
- 用户可手动修改自动填充的编号(支持语义化命名)

实现:
- autoFillStreamId() 函数:根据应用名计算下一个可用编号
- watch监听 editForm.app 变化,触发自动编号
- handleAdd() 时自动填充流ID

示例:
- 应用名=大堂,已有001、002 → 自动填充003
- 应用名=停车场,首次创建 → 自动填充001
- 用户可修改为语义化名称:B1_entrance
This commit is contained in:
2026-02-25 13:27:02 +08:00
parent d6d7549df4
commit dc71da002e

View File

@@ -7,7 +7,7 @@
*/
import type { AiotDeviceApi } from '#/api/aiot/device';
import { onMounted, reactive, ref } from 'vue';
import { onMounted, reactive, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
@@ -157,11 +157,45 @@ function resetForm() {
});
}
/**
* 自动填充流ID编号
* 根据当前应用名,自动计算下一个可用的编号
*/
function autoFillStreamId() {
const app = editForm.app;
if (!app || editForm.id) return; // 编辑模式不自动填充
// 过滤出同一应用下的摄像头
const sameAppCameras = cameraList.value.filter((c) => c.app === app);
// 获取已用的纯数字编号
const usedNumbers = sameAppCameras
.map((c) => c.stream)
.filter((s) => /^\d+$/.test(s))
.map((s) => parseInt(s, 10))
.sort((a, b) => a - b);
// 找到第一个未使用的编号
let nextNum = 1;
for (const num of usedNumbers) {
if (num === nextNum) {
nextNum++;
} else {
break;
}
}
// 自动填充3位数字前导零
editForm.stream = String(nextNum).padStart(3, '0');
}
function handleAdd() {
resetForm();
editModalTitle.value = '添加摄像头';
editModalOpen.value = true;
loadMediaServers();
// 自动填充流ID
autoFillStreamId();
}
function handleEdit(row: AiotDeviceApi.Camera) {
@@ -311,6 +345,14 @@ function handlePageChange(p: number, size: number) {
// ==================== 初始化 ====================
// 监听应用名变化自动填充流ID
watch(
() => editForm.app,
() => {
autoFillStreamId();
},
);
onMounted(() => {
loadData();
});
@@ -446,16 +488,22 @@ onMounted(() => {
<Form.Item label="应用名" required>
<Input
v-model:value="editForm.app"
placeholder="如: live、大堂、停车场"
placeholder="场景分类,如:大堂、停车场、入口"
:disabled="!!editForm.id"
/>
<div style="margin-top: 4px; font-size: 12px; color: #999">
场景名称同一场景下可有多个摄像头
</div>
</Form.Item>
<Form.Item label="流ID" required>
<Input
v-model:value="editForm.stream"
placeholder="唯一标识,如: camera01"
placeholder="在当前场景下的唯一标识001系统会自动编号"
:disabled="!!editForm.id"
/>
<div style="margin-top: 4px; font-size: 12px; color: #999">
在当前场景下唯一系统会根据应用名自动编号
</div>
</Form.Item>
<Form.Item label="拉流地址" required>
<Input