From f0e5de9a0f113c253e474c53cdd11a9134ba3d08 Mon Sep 17 00:00:00 2001
From: hx <190679152@qq.com>
Date: Tue, 28 Apr 2026 17:47:15 +0800
Subject: [PATCH] =?UTF-8?q?b=E7=AB=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/brand.js | 9 +
src/api/device/device.js | 17 +-
.../device/PendingActivateDialog.vue | 255 +++++++++
src/lang/fence-messages.js | 8 +-
src/lang/profile-messages.js | 12 +
src/layout/components/Navbar.vue | 21 +-
src/layout/components/Sidebar/Logo.vue | 54 +-
src/main.js | 91 ++-
src/permission.js | 26 +-
src/router/index.js | 58 +-
src/store/getters.js | 4 +-
src/store/index.js | 4 +-
src/store/modules/brand.js | 64 +++
src/utils/brand.js | 125 ++++
src/utils/dynamicTitle.js | 20 +-
src/utils/request.js | 72 +--
src/utils/validate.js | 73 +--
src/views/device/device/index.vue | 29 +-
src/views/fence/device/index.vue | 327 ++++++++++-
src/views/login.vue | 541 +++++++++---------
.../user/components/ProfileSettingsCard.vue | 25 +-
21 files changed, 1250 insertions(+), 585 deletions(-)
create mode 100644 src/api/brand.js
create mode 100644 src/components/device/PendingActivateDialog.vue
create mode 100644 src/store/modules/brand.js
create mode 100644 src/utils/brand.js
diff --git a/src/api/brand.js b/src/api/brand.js
new file mode 100644
index 0000000..10933f5
--- /dev/null
+++ b/src/api/brand.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getBrandConfig(businessNo) {
+ return request({
+ url: "/system/info/brand",
+ method: "get",
+ params: businessNo ? { businessNo } : {}
+ });
+}
diff --git a/src/api/device/device.js b/src/api/device/device.js
index bf9aed6..f3462ed 100644
--- a/src/api/device/device.js
+++ b/src/api/device/device.js
@@ -8,6 +8,14 @@ export function listDevice(query) {
})
}
+export function listPendingActivateDevice(query) {
+ return request({
+ url: '/device/device/pending-activate/list',
+ method: 'get',
+ params: query
+ })
+}
+
export function getDevice(id) {
return request({
url: '/device/device/' + id,
@@ -124,13 +132,14 @@ export function getBatchNo() {
})
}
-export function batchActivateDevice(ids) {
+export function batchActivateDevice(payload) {
+ const requestPayload = Array.isArray(payload)
+ ? { ids: payload }
+ : (payload || { ids: [] })
return request({
url: '/device/device/activate/batch',
method: 'put',
- data: {
- ids: ids
- }
+ data: requestPayload
})
}
diff --git a/src/components/device/PendingActivateDialog.vue b/src/components/device/PendingActivateDialog.vue
new file mode 100644
index 0000000..e1562f5
--- /dev/null
+++ b/src/components/device/PendingActivateDialog.vue
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t("common.search") }}
+
+ {{ $t("common.reset") }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lang/fence-messages.js b/src/lang/fence-messages.js
index 211ec83..cac839a 100644
--- a/src/lang/fence-messages.js
+++ b/src/lang/fence-messages.js
@@ -136,7 +136,7 @@ const fenceZh = {
overview: { online: '监控设备', normalDevice: '正常设备', alertDevice: '告警设备', activeFence: '启用围栏', openAlarm: '未处理告警', todayAlarm: '今日告警' },
query: { keyword: '关键字', fenceName: '围栏名称', status: '状态', shapeType: '图形类型', alarmType: '告警类型', handleStatus: '处理状态', alarmLevel: '告警级别', alarmTime: '告警时间' },
placeholder: { keyword: '请输入围栏名称或备注', fenceName: '请输入围栏名称', monitorKeyword: '请输入设备 SN / 名称 / 地址', alarmKeyword: '请输入告警内容', alarmSn: '请输入设备 SN', alarmFenceName: '请输入围栏名称', alarmDeviceName: '请输入设备名称', alarmTimeStart: '开始时间', alarmTimeEnd: '结束时间' },
- button: { add: '新增围栏', edit: '编辑', remove: '删除', scan: '执行扫描', refresh: '刷新', refreshAll: '刷新全局', save: '保存', handle: '处理告警', locate: '定位', more: '更多', preview: '预览', resetEditor: '重置编辑器', selectDevice: '选择设备', markNormal: '设为正常', expandMap: '放大地图', restoreMap: '还原地图' },
+ button: { add: '新增围栏', addLocateTip: '新增围栏前点击可定位', edit: '编辑', remove: '删除', scan: '执行扫描', refresh: '刷新', refreshAll: '刷新全局', save: '保存', handle: '处理告警', locate: '定位', more: '更多', preview: '预览', resetEditor: '重置编辑器', selectDevice: '选择设备', markNormal: '设为正常', expandMap: '放大地图', restoreMap: '还原地图' },
status: { enabled: '启用', disabled: '停用' },
shape: { circle: '圆形', rect: '矩形', polygon: '多边形' },
alarmRule: { enter: '进入', exit: '离开', inside: '范围内', outside: '范围外', boundary: '边界', exitRecommended: '离开告警(防丢推荐)', enterExit: '进入+离开', enterOnly: '仅进入' },
@@ -150,7 +150,7 @@ const fenceZh = {
form: { addTitle: '新增围栏', editTitle: '编辑围栏', name: '围栏名称', shapeType: '几何类型', alarmRules: '告警策略', scheduleType: '生效时间', scheduleStart: '开始时间', scheduleEnd: '结束时间', alarmCountdownMinutes: '告警倒计时(小时)', remark: '围栏备注', centerLat: '中心纬度', centerLng: '中心经度', radiusMeter: '半径(米)', geomWkt: '几何 WKT', shapeDataJson: '图形 JSON', deviceIds: '绑定设备', devicePlaceholder: '请选择需要监控的设备', deviceSearchPlaceholder: '搜索 SN / 设备名称 / 地址', timePlaceholder: 'HH:mm:ss' },
dialog: { deviceTitle: '选择绑定设备', deviceHint: '仅显示当前企业下已启用的设备,双击行可快速选择。', selectedCount: '已选择 {count} 台设备', alarmLocateTitle: '设备位置定位' },
table: { name: '围栏名称', shape: '图形', rules: '告警策略', status: '状态', actions: '操作', sn: '设备 SN', alias: '设备名称', lat: '纬度', lng: '经度', coordinates: '经纬度', address: '位置地址', locationTime: '更新时间', fenceStatus: '围栏状态', lastAlarm: '最近告警', alarmMessage: '告警内容', alarmTime: '告警时间', alarmType: '告警类型', alarmLevel: '告警级别' },
- message: { loadFailed: '围栏工作台加载失败', mapConfigLoadFailed: '地图配置加载失败', nameRequired: '请先填写围栏名称', ruleRequired: '请至少选择一项告警规则', circleRequired: '圆形围栏需要中心点和半径', shapeRequired: '请先在地图上绘制围栏图形', shapeSynced: '图形已同步到表单', saveSuccess: '保存成功', removeSuccess: '删除成功', confirmRemove: '确认删除选中的围栏吗?', selectFence: '请先选择围栏', handleSuccess: '告警处理成功', markNormalSuccess: '设备状态已设为正常', markNormalFailed: '当前状态无法设为正常', noMonitorDevice: '当前没有可监控设备', noFenceData: '当前没有围栏数据', noAlarmData: '当前没有告警数据', scanSuccessDetail: '扫描完成,设备 {deviceCount} 个,判定 {evaluatedCount} 条,新增告警 {alarmCount} 条。', alarmLocationMissing: '当前告警缺少经纬度,无法定位。', devicePointLoadFailed: '设备坐标加载失败,已先展示围栏' }
+ message: { loadFailed: '围栏工作台加载失败', mapConfigLoadFailed: '地图配置加载失败', nameRequired: '请先填写围栏名称', ruleRequired: '请至少选择一项告警规则', deviceRequired: '请至少选择一台绑定设备', circleRequired: '圆形围栏需要中心点和半径', shapeRequired: '请先在地图上绘制围栏图形', shapeSynced: '图形已同步到表单', saveSuccess: '保存成功', removeSuccess: '删除成功', confirmRemove: '确认删除选中的围栏吗?', selectFence: '请先选择围栏', handleSuccess: '告警处理成功', markNormalSuccess: '设备状态已设为正常', markNormalFailed: '当前状态无法设为正常', noMonitorDevice: '当前没有可监控设备', noFenceData: '当前没有围栏数据', noAlarmData: '当前没有告警数据', scanSuccessDetail: '扫描完成,设备 {deviceCount} 个,判定 {evaluatedCount} 条,新增告警 {alarmCount} 条。', alarmLocationMissing: '当前告警缺少经纬度,无法定位。', devicePointLoadFailed: '设备坐标加载失败,已先展示围栏' }
}
const fenceEn = {
@@ -172,7 +172,7 @@ const fenceEn = {
overview: { online: 'Monitored Devices', normalDevice: 'Normal Devices', alertDevice: 'Alert Devices', activeFence: 'Active Fences', openAlarm: 'Open Alarms', todayAlarm: 'Today Alarms' },
query: { keyword: 'Keyword', fenceName: 'Fence Name', status: 'Status', shapeType: 'Shape', alarmType: 'Alarm Type', handleStatus: 'Handle Status', alarmLevel: 'Alarm Level', alarmTime: 'Alarm Time' },
placeholder: { keyword: 'Enter fence name or remark', fenceName: 'Enter fence name', monitorKeyword: 'Enter device SN / name / address', alarmKeyword: 'Enter alarm content', alarmSn: 'Enter device SN', alarmFenceName: 'Enter fence name', alarmDeviceName: 'Enter device name', alarmTimeStart: 'Start time', alarmTimeEnd: 'End time' },
- button: { add: 'Add Fence', edit: 'Edit', remove: 'Delete', scan: 'Run Scan', refresh: 'Refresh', refreshAll: 'Refresh All', save: 'Save', handle: 'Handle', locate: 'Locate', more: 'More', preview: 'Preview', resetEditor: 'Reset Editor', selectDevice: 'Select Devices', markNormal: 'Set Normal', expandMap: 'Expand Map', restoreMap: 'Restore Map' },
+ button: { add: 'Add Fence', addLocateTip: 'Click to locate before adding a fence', edit: 'Edit', remove: 'Delete', scan: 'Run Scan', refresh: 'Refresh', refreshAll: 'Refresh All', save: 'Save', handle: 'Handle', locate: 'Locate', more: 'More', preview: 'Preview', resetEditor: 'Reset Editor', selectDevice: 'Select Devices', markNormal: 'Set Normal', expandMap: 'Expand Map', restoreMap: 'Restore Map' },
status: { enabled: 'Enabled', disabled: 'Disabled' },
shape: { circle: 'Circle', rect: 'Rectangle', polygon: 'Polygon' },
alarmRule: { enter: 'Enter', exit: 'Exit', inside: 'Inside', outside: 'Outside', boundary: 'Boundary', exitRecommended: 'Exit Alert (Recommended)', enterExit: 'Enter + Exit', enterOnly: 'Enter Only' },
@@ -186,7 +186,7 @@ const fenceEn = {
form: { addTitle: 'Add Fence', editTitle: 'Edit Fence', name: 'Fence Name', shapeType: 'Geometry Type', alarmRules: 'Alarm Rules', scheduleType: 'Schedule', scheduleStart: 'Start Time', scheduleEnd: 'End Time', alarmCountdownMinutes: 'Alarm Countdown (hour)', remark: 'Fence Remark', centerLat: 'Center Lat', centerLng: 'Center Lng', radiusMeter: 'Radius (m)', geomWkt: 'Geometry WKT', shapeDataJson: 'Shape JSON', deviceIds: 'Bind Devices', devicePlaceholder: 'Select devices', deviceSearchPlaceholder: 'Search SN / device name / address', timePlaceholder: 'HH:mm:ss' },
dialog: { deviceTitle: 'Select Devices', deviceHint: 'Only active devices in the current business are shown. Double-click a row to select it quickly.', selectedCount: '{count} devices selected', alarmLocateTitle: 'Device Location' },
table: { name: 'Fence Name', shape: 'Shape', rules: 'Rules', status: 'Status', actions: 'Actions', sn: 'Device SN', alias: 'Device Name', lat: 'Latitude', lng: 'Longitude', coordinates: 'Coordinates', address: 'Address', locationTime: 'Update Time', fenceStatus: 'Fence Status', lastAlarm: 'Last Alarm', alarmMessage: 'Alarm Message', alarmTime: 'Alarm Time', alarmType: 'Alarm Type', alarmLevel: 'Alarm Level' },
- message: { loadFailed: 'Failed to load fence workspace', mapConfigLoadFailed: 'Failed to load map config', nameRequired: 'Fence name is required', ruleRequired: 'Select at least one alarm rule', circleRequired: 'Circle fence needs center and radius', shapeRequired: 'Draw the fence shape on the map first', shapeSynced: 'The shape has been synced to the form', saveSuccess: 'Saved successfully', removeSuccess: 'Deleted successfully', confirmRemove: 'Delete the selected fences?', selectFence: 'Select fences first', handleSuccess: 'Alarm handled successfully', markNormalSuccess: 'State has been set to normal', markNormalFailed: 'Unable to set current state to normal', noMonitorDevice: 'No device available', noFenceData: 'No fence data', noAlarmData: 'No alarm data', scanSuccessDetail: 'Scan finished: {deviceCount} devices, {evaluatedCount} evaluations, {alarmCount} new alarms.', alarmLocationMissing: 'This alarm has no coordinates and cannot be located.', devicePointLoadFailed: 'Failed to load device coordinates, fence is shown first.' }
+ message: { loadFailed: 'Failed to load fence workspace', mapConfigLoadFailed: 'Failed to load map config', nameRequired: 'Fence name is required', ruleRequired: 'Select at least one alarm rule', deviceRequired: 'Select at least one bound device', circleRequired: 'Circle fence needs center and radius', shapeRequired: 'Draw the fence shape on the map first', shapeSynced: 'The shape has been synced to the form', saveSuccess: 'Saved successfully', removeSuccess: 'Deleted successfully', confirmRemove: 'Delete the selected fences?', selectFence: 'Select fences first', handleSuccess: 'Alarm handled successfully', markNormalSuccess: 'State has been set to normal', markNormalFailed: 'Unable to set current state to normal', noMonitorDevice: 'No device available', noFenceData: 'No fence data', noAlarmData: 'No alarm data', scanSuccessDetail: 'Scan finished: {deviceCount} devices, {evaluatedCount} evaluations, {alarmCount} new alarms.', alarmLocationMissing: 'This alarm has no coordinates and cannot be located.', devicePointLoadFailed: 'Failed to load device coordinates, fence is shown first.' }
}
diff --git a/src/lang/profile-messages.js b/src/lang/profile-messages.js
index a891b74..b205ec7 100644
--- a/src/lang/profile-messages.js
+++ b/src/lang/profile-messages.js
@@ -12,6 +12,7 @@ const profileMessages = {
nickName: "昵称",
googleKey: "谷歌地图 Key",
gaodeKey: "高德地图 Key",
+ maptilerKey: "MapTiler Key",
gaodeSecurityKey: "高德安全密钥",
oldPassword: "旧密码",
newPassword: "新密码",
@@ -20,6 +21,7 @@ const profileMessages = {
placeholder: {
googleKey: "请输入谷歌地图 Key",
gaodeKey: "请输入高德地图 Key",
+ maptilerKey: "Enter MapTiler Key",
gaodeSecurityKey: "请输入高德安全密钥",
oldPassword: "请输入旧密码",
newPassword: "请输入新密码",
@@ -60,6 +62,7 @@ const profileMessages = {
nickName: "Nickname",
googleKey: "Google Maps Key",
gaodeKey: "Amap Key",
+ maptilerKey: "MapTiler Key",
gaodeSecurityKey: "Amap Security Key",
oldPassword: "Old Password",
newPassword: "New Password",
@@ -68,6 +71,7 @@ const profileMessages = {
placeholder: {
googleKey: "Enter Google Maps Key",
gaodeKey: "Enter Amap Key",
+ maptilerKey: "Enter MapTiler Key",
gaodeSecurityKey: "Enter Amap Security Key",
oldPassword: "Enter old password",
newPassword: "Enter new password",
@@ -108,6 +112,7 @@ const profileMessages = {
nickName: "Псевдоним",
googleKey: "Ключ Google Maps",
gaodeKey: "Ключ Amap",
+ maptilerKey: "MapTiler Key",
gaodeSecurityKey: "Ключ безопасности Amap",
oldPassword: "Старый пароль",
newPassword: "Новый пароль",
@@ -116,6 +121,7 @@ const profileMessages = {
placeholder: {
googleKey: "Введите ключ Google Maps",
gaodeKey: "Введите ключ Amap",
+ maptilerKey: "Enter MapTiler Key",
gaodeSecurityKey: "Введите ключ безопасности Amap",
oldPassword: "Введите старый пароль",
newPassword: "Введите новый пароль",
@@ -156,6 +162,7 @@ const profileMessages = {
nickName: "Surnom",
googleKey: "Cle Google Maps",
gaodeKey: "Cle Amap",
+ maptilerKey: "MapTiler Key",
gaodeSecurityKey: "Cle de securite Amap",
oldPassword: "Ancien mot de passe",
newPassword: "Nouveau mot de passe",
@@ -164,6 +171,7 @@ const profileMessages = {
placeholder: {
googleKey: "Saisissez la cle Google Maps",
gaodeKey: "Saisissez la cle Amap",
+ maptilerKey: "Enter MapTiler Key",
gaodeSecurityKey: "Saisissez la cle de securite Amap",
oldPassword: "Saisissez l'ancien mot de passe",
newPassword: "Saisissez le nouveau mot de passe",
@@ -204,6 +212,7 @@ const profileMessages = {
nickName: "Apodo",
googleKey: "Clave de Google Maps",
gaodeKey: "Clave de Amap",
+ maptilerKey: "MapTiler Key",
gaodeSecurityKey: "Clave de seguridad de Amap",
oldPassword: "Contrasena anterior",
newPassword: "Nueva contrasena",
@@ -212,6 +221,7 @@ const profileMessages = {
placeholder: {
googleKey: "Ingrese la clave de Google Maps",
gaodeKey: "Ingrese la clave de Amap",
+ maptilerKey: "Enter MapTiler Key",
gaodeSecurityKey: "Ingrese la clave de seguridad de Amap",
oldPassword: "Ingrese la contrasena anterior",
newPassword: "Ingrese la nueva contrasena",
@@ -252,6 +262,7 @@ const profileMessages = {
nickName: "Apelido",
googleKey: "Chave do Google Maps",
gaodeKey: "Chave da Amap",
+ maptilerKey: "MapTiler Key",
gaodeSecurityKey: "Chave de seguranca da Amap",
oldPassword: "Senha antiga",
newPassword: "Nova senha",
@@ -260,6 +271,7 @@ const profileMessages = {
placeholder: {
googleKey: "Digite a chave do Google Maps",
gaodeKey: "Digite a chave da Amap",
+ maptilerKey: "Enter MapTiler Key",
gaodeSecurityKey: "Digite a chave de seguranca da Amap",
oldPassword: "Digite a senha antiga",
newPassword: "Digite a nova senha",
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 3447e90..1b6dcae 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,4 +1,4 @@
-
+
@@ -6,15 +6,11 @@